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('/')
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('/')
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)
def payment_processor(self): return Paypal(self.request.site)
def payment_processor(self): return Paypal()