Ejemplo n.º 1
0
def confirm(request):
    if not check_ip(request):
        raise PaymentError("Error tracing origin point of callback")
    try:
        return gateway.confirm(request, settings.SECRET_KEY.encode("utf-8"))
    except ValueError as e:
        raise PaymentError(str(e))
Ejemplo n.º 2
0
    def create_payment(self,
                       order_number,
                       total,
                       user,
                       language=None,
                       description=None,
                       profile=None,
                       **kwargs):
        """
        Start a new payment session / container.
        Besides the overwritten parameters, also provide:

        :param total: The total price
        :type total: :class:`oscar.core.prices.Price`
        :param billingaddress: The shipping address.
        :type billingaddress: :class:`oscar.apps.order.models.BillingAddress`
        """
        if not profile:
            profile = appsettings.DOCDATA_PROFILE

        try:
            order_key = super(Facade,
                              self).create_payment(order_number,
                                                   total,
                                                   user,
                                                   language=language,
                                                   description=description,
                                                   profile=profile,
                                                   **kwargs)
        except DocdataCreateError as e:
            raise PaymentError(e.value, e)

        return order_key
Ejemplo n.º 3
0
    def handle_payment(self, order_number, total_incl_tax, **kwargs):
        """
        Complete payment with PayPal - this calls the 'DoExpressCheckout'
        method to capture the money from the initial transaction.
        """
        try:
            payer_id = self.request.POST['payer_id']
            token = self.request.POST['token']
        except KeyError:
            raise PaymentError(
                "Unable to determine PayPal transaction details")

        try:
            txn = confirm_transaction(payer_id,
                                      token,
                                      amount=self.txn.amount,
                                      currency=self.txn.currency)
        except PayPalError:
            raise UnableToTakePayment()
        if not txn.is_successful:
            raise UnableToTakePayment()

        # Record payment source and event
        source_type, is_created = SourceType.objects.get_or_create(
            name='PayPal')
        source = Source(source_type=source_type,
                        currency=txn.currency,
                        amount_allocated=txn.amount,
                        amount_debited=txn.amount)
        self.add_payment_source(source)
        self.add_payment_event('Settled', txn.amount)
Ejemplo n.º 4
0
    def create_payment(self, order_number, total, user, language=None, description=None, profile=None, merchant_name=None, **kwargs):
        """
        Start a new payment session / container.

        :param order_number: The order number generated by Oscar.
        :param total: The price object, including totals and currency.
        :type total: :class:`oscar.core.prices.Price`
        :type user: :class:`django.contrib.auth.models.User`

        Besides the overwritten parameters, also provide:

        :param billing_address: The billing address, used
        :type billing_address: :class:`oscar.apps.address.abstract_models.AbstractAddress`
        :param basket: The basket to submit, to generate the invoice.
        :type basket: :class:`~oscar.apps.basket.abstract_models.AbstractBasket`
        :param shipping_address: The shipping address for the invoice.
        :type shipping_address: :class:`~oscar.apps.address.abstract_models.AbstractAddress`
        :returns: The Docdata order reference ("order key").

        ..note::
            The Docdata API v1.3 has issues with passing the address fields to PayPal.
            It read the "billing_address.state" field as "status", and as hack they
            now pass the "shipping_address.state" to PayPal.
            Hence, the recommended action is to pass the billing address as shipping address too.
        """
        if not profile:
            profile = appsettings.DOCDATA_PROFILE

        try:
            order_key = super(Facade, self).create_payment(order_number, total, user, language=language, description=description, profile=profile, merchant_name=merchant_name, **kwargs)
        except DocdataCreateError as e:
            raise PaymentError(e.value, e)

        return order_key
Ejemplo n.º 5
0
 def __init__(self, *args, **kwargs):
     if self.name is None:
         raise PaymentError(
             "%s.%s: name property cannot be None" %
             (self.__class__.__module__, self.__class__.__name__))
     if self.preview_view is None:
         self.preview_view = self.root_view
     super(PaymentModule, self).__init__(*args, **kwargs)
    def get_form(self, type=None, *args, **kwargs):
        """
        Return the requested form with the given arguments

        :param type: REQUIRED: ('bankcard'|'billing_address')
        :param args: positional arguments for the form constructor
        :param kwargs: keyword arguments for the form constructor
        :return: The form instance
        """
        if type not in ('bankcard', 'billing_address'):
            raise PaymentError("Form type parameter is required")
        return getattr(self, '{}_form_class'.format(type))(*args, **kwargs)
Ejemplo n.º 7
0
            'number': bankcard.number, 
            'exp_month': bankcard.expiry_date.month, 
            'exp_year': bankcard.expiry_date.year, 
            'cvc': bankcard.ccv,
        }
        total_in_cents = int(total.incl_tax * 100)

        charge = gateway.charge( total_in_cents, currency=currency.lower(), card_info=card_info, metadata=metadata )


    except gateway.CardInfoError, e:
        raise UnableToTakePayment( e )

    except (stripe.error.CardError, stripe.error.InvalidRequestError) as e:
        body = e.json_body
        err  = body['error']
        raise UnableToTakePayment( err['message'] )

    except (stripe.error.AuthenticationError, stripe.error.APIConnectionError, stripe.error.StripeError) as e:
        # Authentication with Stripe's API failed
        # (maybe you changed API keys recently)
        logger.error('Stripe Error:', exc_info=sys.exc_info())
        raise PaymentError()
        

    except Exception, e:
        # Something else happened, completely unrelated to Stripe
        logger.error('Stripe Error:', exc_info=sys.exc_info())
        raise PaymentError()

    return charge
Ejemplo n.º 8
0
    def handle_payment(self, order_number, total, **kwargs):
        """
        Try to process the payment using the Square REST API
        """
        square_settings = SquareSettings.get_settings()
        squareconnect.configuration.access_token = \
            square_settings.access_token
        source_type, __ = SourceType.objects.get_or_create(name='Square')
        source = Source(source_type=source_type,
                        amount_allocated=total.incl_tax)
        nonce = self.get_card_nonce()

        if not nonce:
            raise PaymentError('No card nonce provided')

        #TODO: Currency should be a setting stored in the settings model
        # Set the total amount to charge, in US Cents
        amount = {
            'amount': int(100*float(total.incl_tax)),
            'currency': 'USD'
        }

        #TODO: Delayed capture can be stored in settings, instead of static
        # Start the request for authorization, including shipping address and
        # user email (if provided)
        body = {
            'idempotency_key': self.get_idempotency_key(order_number),
            'card_nonce': nonce,
            'amount_money': amount,
            'delay_capture': True,
        }

        # Add user information for chargeback protection
        if 'email' in kwargs:
            body['buyer_email_address'] = kwargs['email']

        for addr_type in 'shipping_address', 'billing_address':
            if addr_type in kwargs:
                addr_object = kwargs[addr_type]
                address = dict()

                address['address_line_1'] = addr_object.line1
                address['address_line_2'] = addr_object.line2
                address['address_line_3'] = addr_object.line3
                address['locality'] = addr_object.line4
                address['administrative_district_level_1'] = addr_object.state
                address['postal_code'] = addr_object.postcode
                address['country'] = addr_object.country.iso_3166_1_a2
                address['first_name'] = addr_object.first_name
                address['last_name'] = addr_object.last_name

                body[addr_type] = address

        try:
            # Charge
            api_response = api_instance.charge(square_settings.location_id,
                    body)

            # Save the response ID
            if not api_response.transaction:
                raise ApiException(', '.join(api_response.errors))

        except ApiException as e:
            msg = "Exception when calling TransactionApi->charge: {}".format(e)
            logger.info(msg)
            raise PaymentError(msg) from ApiException

        # Request was successful - record the "payment source".  As this
        # request was a 'pre-auth', we set the 'amount_allocated' - if we had
        # performed an 'auth' request, then we would set 'amount_debited'.
        self.add_payment_source(source)

        #TODO: Change payment event type depending on delay/immediate capture
        # Also record payment event
        self.add_payment_event('auth', total.incl_tax,
                reference=api_response.transaction.id)