Ejemplo n.º 1
0
    def setUp(self):
        super(PaypalPaymentExecutionViewTests, self).setUp()

        self.basket = create_basket(owner=factories.UserFactory(), site=self.site)
        self.basket.freeze()

        self.processor = Paypal(self.site)
        self.processor_name = self.processor.NAME

        # Dummy request from which an HTTP Host header can be extracted during
        # construction of absolute URLs
        self.request = RequestFactory().post('/')
Ejemplo n.º 2
0
    def setUp(self):
        super(PaypalPaymentExecutionViewTests, self).setUp()
        self.price = '100.0'
        self.user = self.create_user()
        self.seat_product_class, __ = ProductClass.objects.get_or_create(name=SEAT_PRODUCT_CLASS_NAME)
        self.basket = create_basket(
            owner=self.user, site=self.site, price=self.price, product_class=self.seat_product_class
        )
        self.basket.freeze()

        self.processor = Paypal(self.site)
        self.processor_name = self.processor.NAME

        # Dummy request from which an HTTP Host header can be extracted during
        # construction of absolute URLs
        self.request = RequestFactory().post('/')
Ejemplo n.º 3
0
class PaypalPaymentExecutionView(EdxOrderPlacementMixin, View):
    """Execute an approved PayPal payment and place an order for paid products as appropriate."""
    payment_processor = Paypal()

    def _get_basket(self, payment_id):
        """
        Retrieve a basket using a payment ID.

        Arguments:
            payment_id: payment_id received from PayPal.

        Returns:
            It will return related basket or log exception and return None if
            duplicate payment_id received or any other exception occurred.

        """
        try:
            basket = PaymentProcessorResponse.objects.get(
                processor_name=self.payment_processor.NAME,
                transaction_id=payment_id).basket
            basket.strategy = strategy.Default()
            return basket
        except MultipleObjectsReturned:
            logger.exception(
                u"Duplicate payment ID [%s] received from PayPal.", payment_id)
            return None
        except Exception:  # pylint: disable=broad-except
            logger.exception(
                u"Unexpected error during basket retrieval while executing PayPal payment."
            )
            return None

    @transaction.non_atomic_requests
    def get(self, request):
        """Handle an incoming user returned to us by PayPal after approving payment."""
        payment_id = request.GET.get('paymentId')
        payer_id = request.GET.get('PayerID')
        logger.info(u"Payment [%s] approved by payer [%s]", payment_id,
                    payer_id)

        paypal_response = request.GET.dict()
        basket = self._get_basket(payment_id)

        if not basket:
            return redirect(self.payment_processor.error_url)

        receipt_url = u'{}?orderNum={}'.format(
            self.payment_processor.receipt_url, basket.order_number)

        try:
            with transaction.atomic():
                try:
                    self.handle_payment(paypal_response, basket)
                except PaymentError:
                    return redirect(receipt_url)
        except:  # pylint: disable=bare-except
            logger.exception(
                'Attempts to handle payment for basket [%d] failed.',
                basket.id)
            return redirect(receipt_url)

        try:
            shipping_method = NoShippingRequired()
            shipping_charge = shipping_method.calculate(basket)
            order_total = OrderTotalCalculator().calculate(
                basket, shipping_charge)

            user = basket.owner
            # Given a basket, order number generation is idempotent. Although we've already
            # generated this order number once before, it's faster to generate it again
            # than to retrieve an invoice number from PayPal.
            order_number = basket.order_number

            self.handle_order_placement(order_number=order_number,
                                        user=user,
                                        basket=basket,
                                        shipping_address=None,
                                        shipping_method=shipping_method,
                                        shipping_charge=shipping_charge,
                                        billing_address=None,
                                        order_total=order_total)

            return redirect(receipt_url)
        except:  # pylint: disable=bare-except
            logger.exception(self.order_placement_failure_msg, basket.id)
            return redirect(receipt_url)
Ejemplo n.º 4
0
 def payment_processor(self):
     return Paypal(self.request.site)
Ejemplo n.º 5
0
 def payment_processor(self):
     return Paypal()