def void(tx_id, order_number=None): """ Cancel an existing transaction """ try: authorise_txn = models.RequestResponse.objects.get( tx_id=tx_id, tx_type=gateway.TXTYPE_AUTHORISE, status='OK') except models.RequestResponse.DoesNotExist: raise oscar_exceptions.PaymentError( ("No successful AUTHORISE transaction found with " "ID %s") % tx_id) previous_txn = gateway.PreviousTxn( vendor_tx_code=authorise_txn.vendor_tx_code, tx_id=authorise_txn.tx_id, tx_auth_num=authorise_txn.tx_auth_num, security_key=authorise_txn.security_key) params = { 'previous_txn': previous_txn, } if order_number is not None: params['reference'] = order_number try: response = gateway.void(**params) except exceptions.GatewayError as e: raise oscar_exceptions.PaymentError(e.message) if not response.is_ok: raise oscar_exceptions.PaymentError(response.status_detail) return response.tx_id
def authorise(tx_id, amount=None, description=None, order_number=None): """ Perform an AUTHORISE request against a previous transaction """ try: txn = models.RequestResponse.objects.get(tx_id=tx_id) except models.RequestResponse.DoesNotExist: raise oscar_exceptions.PaymentError( "No historic transaction found with ID %s" % tx_id) # Marshall data for passing to gateway previous_txn = gateway.PreviousTxn(vendor_tx_code=txn.vendor_tx_code, tx_id=txn.tx_id, tx_auth_num=txn.tx_auth_num, security_key=txn.security_key) if amount is None: amount = txn.amount if description is None: description = "Authorise TX ID %s" % tx_id params = { 'previous_txn': previous_txn, 'amount': amount, 'currency': txn.currency, 'description': description, } if order_number is not None: params['reference'] = order_number try: response = gateway.authorise(**params) except exceptions.GatewayError as e: raise oscar_exceptions.PaymentError(e.message) if not response.is_ok: raise oscar_exceptions.PaymentError(response.status_detail) return response.tx_id
def credit(order_number, pnref=None, amt=None): """ Return funds that have been previously settled. :order_number: Order number :pnref: The PNREF of the authorization transaction to use. If not specified, the order number is used to retrieve the appropriate transaction. :amt: A custom amount to capture. If not specified, the entire transaction is refuneded. """ if pnref is None: # No PNREF specified, look-up the auth/sale transaction for this order number # to get the PNREF from there. try: auth_txn = models.PayflowTransaction.objects.get( comment1=order_number, trxtype__in=(codes.AUTHORIZATION, codes.SALE)) except models.PayflowTransaction.DoesNotExist: raise exceptions.UnableToTakePayment( "No authorization transaction found with PNREF=%s" % pnref) pnref = auth_txn txn = gateway.credit(order_number, pnref, amt) if not txn.is_approved: raise exceptions.PaymentError(txn.respmsg) return txn
def process(self): """Attempts to process Capture with transaction details. Returns the values of ``gateway.Capture.process``. Raises: GatewayError: An Oscar error raised when there was an error with the payment API. PaymentError: An Oscar error raised when there was an error processing the payment. """ capture_instance = gateway.Capture(**self.transaction_details) try: return capture_instance.process() except helcim_exceptions.ProcessingError as error: raise oscar_exceptions.GatewayError(str(error)) except helcim_exceptions.PaymentError as error: raise oscar_exceptions.PaymentError(str(error)) except helcim_exceptions.DjangoError: LOG.exception('Capture complete, but errors occured while saving ' 'transaction to database') return None except helcim_exceptions.HelcimError as error: raise oscar_exceptions.GatewayError(str(error))
def process(self): """Attempts to process Verification with transaction details. Returns the values of ``gateway.Verification.process``. Raises: GatewayError: An Oscar error raised when there was an error with the payment API. PaymentError: An Oscar error raised when there was an error processing the payment. """ verification_instance = gateway.Verification( save_token=self.save_token, django_user=self.django_user, **self.transaction_details) try: return verification_instance.process() except helcim_exceptions.ProcessingError as error: raise oscar_exceptions.GatewayError(str(error)) except helcim_exceptions.PaymentError as error: raise oscar_exceptions.PaymentError(str(error)) except helcim_exceptions.DjangoError: LOG.exception( 'Verification complete, but errors occured while saving ' 'transaction to database') except helcim_exceptions.HelcimError as error: raise oscar_exceptions.GatewayError(str(error))
def void(order_number, pnref): """ Void an authorisation transaction to prevent it from being settled :order_number: Order number :pnref: The PNREF of the transaction to void. """ txn = gateway.void(order_number, pnref) if not txn.is_approved: raise exceptions.PaymentError(txn.respmsg) return txn
def get_datacash_preauth(self, order): """ Return the (successful) pre-auth Datacash transaction for the passed order. """ transactions = models.OrderTransaction.objects.filter( order_number=order.number, method=gateway.PRE, status=1) if transactions.count() == 0: raise exceptions.PaymentError( "Unable to take payment as no PRE-AUTH " "transaction found for this order") return transactions[0]
def refund(tx_id, amount=None, description=None, order_number=None): """ Perform a REFUND request against a previous transaction. The passed tx_id should be from the AUTHORISE request that you want to refund against. """ try: authorise_txn = models.RequestResponse.objects.get( tx_id=tx_id, tx_type=gateway.TXTYPE_AUTHORISE, status='OK') except models.RequestResponse.DoesNotExist: raise oscar_exceptions.PaymentError( ("No successful AUTHORISE transaction found with " "ID %s") % tx_id) previous_txn = gateway.PreviousTxn( vendor_tx_code=authorise_txn.vendor_tx_code, tx_id=authorise_txn.tx_id, tx_auth_num=authorise_txn.tx_auth_num, security_key=authorise_txn.security_key) if amount is None: amount = authorise_txn.amount if description is None: description = "Refund TX ID %s" % tx_id params = { 'previous_txn': previous_txn, 'amount': amount, 'currency': authorise_txn.currency, 'description': description, } if order_number is not None: params['reference'] = order_number try: response = gateway.refund(**params) except exceptions.GatewayError as e: raise oscar_exceptions.PaymentError(e.message) if not response.is_ok: raise oscar_exceptions.PaymentError(response.status_detail) return response.tx_id
def authenticate(amount, currency, bankcard, shipping_address, billing_address, description=None, order_number=None): """ Perform an AUTHENTICATE request and return the TX ID if successful. """ # Requests require a non-empty description if description is None: description = "<no description>" # Decompose Oscar objects into a dict of data to pass to gateway params = { 'amount': amount, 'currency': currency, 'description': description, } params.update(_get_bankcard_params(bankcard)) if order_number is not None: params['reference'] = order_number if shipping_address: params.update({ 'delivery_surname': shipping_address.last_name, 'delivery_first_names': shipping_address.first_name, 'delivery_address1': shipping_address.line1, 'delivery_address2': shipping_address.line2, 'delivery_city': shipping_address.line4, 'delivery_postcode': shipping_address.postcode, 'delivery_country': _get_country_code(shipping_address.country), 'delivery_state': shipping_address.state, 'delivery_phone': shipping_address.phone_number, }) if billing_address: params.update({ 'billing_surname': billing_address.last_name, 'billing_first_names': billing_address.first_name, 'billing_address1': billing_address.line1, 'billing_address2': billing_address.line2, 'billing_city': billing_address.line4, 'billing_postcode': billing_address.postcode, 'billing_country': _get_country_code(billing_address.country), 'billing_state': billing_address.state, }) try: response = gateway.authenticate(**params) except exceptions.GatewayError as e: # Translate Sagepay gateway exceptions into Oscar checkout ones raise oscar_exceptions.PaymentError(e.message) # Check if the transaction was successful (need to distinguish between # customer errors and system errors). if not response.is_registered: raise oscar_exceptions.PaymentError(response.status_detail) return response.tx_id