Esempio n. 1
0
def delayed_capture(order_number, pnref=None, amt=None):
    """
    Capture funds that have been previously authorized.

    Notes:

    * It's possible to capture a lower amount than the original auth
      transaction - however...
    * ...only one delayed capture is allowed for a given PNREF...
    * ...If multiple captures are required, a 'reference transaction' needs to be
      used.
    * It's safe to retry captures if the first one fails or errors

    :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 pnref is None:
        # No PNREF specified, look-up the auth transaction for this order number
        # to get the PNREF from there.
        try:
            auth_txn = models.PayflowTransaction.objects.get(
                comment1=order_number, trxtype=codes.AUTHORIZATION)
        except models.PayflowTransaction.DoesNotExist:
            raise exceptions.UnableToTakePayment(
                "No authorization transaction found with PNREF=%s" % pnref)
        pnref = auth_txn

    txn = gateway.delayed_capture(order_number, pnref, amt)
    if not txn.is_approved:
        raise exceptions.UnableToTakePayment(txn.respmsg)
    return txn
Esempio n. 2
0
def _submit_payment_details(gateway_fn,
                            order_number,
                            amt,
                            bankcard,
                            billing_address=None):
    # Remap address fields if set.
    address_fields = {}
    if billing_address:
        address_fields.update({
            'first_name': billing_address['first_name'],
            'last_name': billing_address['first_name'],
            'street': billing_address['line1'],
            'city': billing_address['line4'],
            'state': billing_address['state'],
            'zip': billing_address['postcode'].strip(' ')
        })

    txn = gateway_fn(order_number,
                     card_number=bankcard.number,
                     cvv=bankcard.cvv,
                     expiry_date=bankcard.expiry_month("%m%y"),
                     amt=amt,
                     **address_fields)
    if not txn.is_approved:
        raise exceptions.UnableToTakePayment(txn.respmsg)
    return txn
Esempio n. 3
0
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
Esempio n. 4
0
def _submit_payment_details(gateway_fn,
                            order_number,
                            amt,
                            bankcard,
                            billing_address=None):
    # Oscar's bankcard class returns dates in form '01/02' - we strip the '/' to
    # conform to PayPal's conventions.
    exp_date = bankcard.expiry_date.replace('/', '')

    # Remap address fields if set
    address_fields = {}
    if billing_address:
        address_fields.update({
            'first_name': billing_address['first_name'],
            'last_name': billing_address['first_name'],
            'street': billing_address['line1'],
            'city': billing_address['line4'],
            'state': billing_address['state'],
            'zip': billing_address['postcode'].strip(' ')
        })

    txn = gateway_fn(order_number,
                     card_number=bankcard.card_number,
                     cvv=bankcard.cvv,
                     expiry_date=exp_date,
                     amt=amt,
                     **address_fields)
    if not txn.is_approved:
        raise exceptions.UnableToTakePayment(txn.respmsg)
    return txn
Esempio n. 5
0
 def handle_payment(self, order_number, total_incl_tax, **kwargs):
     # Make submission to PayPal.
     try:
         # Using authorization here (two-stage model).  You could use sale to
         # perform the auth and capture in one step.  The choice is dependent
         # on your business model.
         facade.authorize(order_number, total_incl_tax, kwargs['bankcard'],
                          kwargs['billing_address'])
     except facade.NotApproved, e:
         # Submission failed
         raise exceptions.UnableToTakePayment(e.message)
Esempio n. 6
0
    def handle_payment(self, order_number, total, **kwargs):
        # Override payment method to use accounts to pay for the order
        allocations = self.get_account_allocations()
        if allocations.total != total.incl_tax:
            raise exceptions.UnableToTakePayment(
                "Your account allocations do not cover the order total")

        try:
            gateway.redeem(order_number, self.request.user, allocations)
        except act_exceptions.AccountException:
            raise exceptions.UnableToTakePayment(
                "An error occurred with the account redemption")

        # If we get here, payment was successful.  We record the payment
        # sources and event to complete the audit trail for this order
        source_type, __ = SourceType.objects.get_or_create(name="Account")
        for code, amount in allocations.items():
            source = Source(source_type=source_type,
                            amount_debited=amount,
                            reference=code)
            self.add_payment_source(source)
        self.add_payment_event("Settle", total.incl_tax)
Esempio n. 7
0
    def handle_payment(self, order_number, total, **kwargs):
        # Override payment method to use accounts to pay for the order
        allocations = self.get_account_allocations()
        if allocations.total != total.incl_tax:
            raise exceptions.UnableToTakePayment(
                "SWAMAHANI, Vos moyens de paiement sont insuffisant")

        try:
            gateway.redeem(order_number, self.request.user, allocations)
        except act_exceptions.AccountException:
            raise exceptions.UnableToTakePayment(
                "Il y  a une erreur, reesayer plus tard")

        # If we get here, payment was successful.  We record the payment
        # sources and event to complete the audit trail for this order
        source_type, __ = SourceType.objects.get_or_create(name="Account")
        for code, amount in allocations.items():
            source = Source(source_type=source_type,
                            amount_debited=amount,
                            reference=code)
            self.add_payment_source(source)
            self.add_payment_event("Settle", total.incl_tax)
Esempio n. 8
0
def referenced_sale(order_number, pnref, amt):
    """
    Capture funds using the bank/address details of a previous transaction

    This is equivalent to a *sale* transaction but without the user having to
    enter their payment details.

    There are two main uses for this:

    1. This allows customers to checkout without having to re-enter their
       payment details.

    2. It allows an initial authorisation to be settled in multiple parts.  The
       first settle should use delayed_capture but any subsequent ones should
       use this method.

    :order_number: Order number.
    :pnref: PNREF of a previous transaction to use.
    :amt: The amount to settle for.
    """
    txn = gateway.reference_transaction(order_number, pnref, amt)
    if not txn.is_approved:
        raise exceptions.UnableToTakePayment(txn.respmsg)
    return txn