Ejemplo n.º 1
0
    def issue_credit(self, order_number, basket, reference_number, amount, currency):
        try:
            payment = paypalrestsdk.Payment.find(reference_number, api=self.paypal_api)
            sale = self._get_payment_sale(payment)

            if not sale:
                logger.error('Unable to find a Sale associated with PayPal Payment [%s].', payment.id)

            refund = sale.refund({
                'amount': {
                    'total': six.text_type(amount),
                    'currency': currency,
                }
            })

        except:
            msg = 'An error occurred while attempting to issue a credit (via PayPal) for order [{}].'.format(
                order_number)
            logger.exception(msg)
            raise GatewayError(msg)

        if refund.success():
            transaction_id = refund.id
            self.record_processor_response(refund.to_dict(), transaction_id=transaction_id, basket=basket)
            return transaction_id

        error = refund.error
        entry = self.record_processor_response(error, transaction_id=error['debug_id'], basket=basket)

        msg = "Failed to refund PayPal payment [{sale_id}]. " \
              "PayPal's response was recorded in entry [{response_id}].".format(sale_id=sale.id,
                                                                                response_id=entry.id)
        raise GatewayError(msg)
Ejemplo n.º 2
0
    def issue_credit(self, source, amount, currency):
        order = source.order

        try:
            order_request_token = source.reference

            security = Security()
            token = UsernameToken(self.merchant_id, self.transaction_key)
            security.tokens.append(token)

            client = Client(self.soap_api_url, transport=RequestsTransport())
            client.set_options(wsse=security)

            credit_service = client.factory.create('ns0:CCCreditService')
            credit_service._run = 'true'  # pylint: disable=protected-access
            credit_service.captureRequestID = source.reference

            purchase_totals = client.factory.create('ns0:PurchaseTotals')
            purchase_totals.currency = currency
            purchase_totals.grandTotalAmount = unicode(amount)

            response = client.service.runTransaction(
                merchantID=self.merchant_id,
                merchantReferenceCode=order.number,
                orderRequestToken=order_request_token,
                ccCreditService=credit_service,
                purchaseTotals=purchase_totals)
            request_id = response.requestID
            ppr = self.record_processor_response(
                suds_response_to_dict(response),
                transaction_id=request_id,
                basket=order.basket)
        except:
            msg = 'An error occurred while attempting to issue a credit (via CyberSource) for order [{}].'.format(
                order.number)
            logger.exception(msg)
            raise GatewayError(msg)

        if response.decision == 'ACCEPT':
            source.refund(amount, reference=request_id)
            event_type, __ = PaymentEventType.objects.get_or_create(
                name=PaymentEventTypeName.REFUNDED)
            PaymentEvent.objects.create(event_type=event_type,
                                        order=order,
                                        amount=amount,
                                        reference=request_id,
                                        processor_name=self.NAME)
        else:
            raise GatewayError(
                'Failed to issue CyberSource credit for order [{order_number}]. '
                'Complete response has been recorded in entry [{response_id}]'.
                format(order_number=order.number, response_id=ppr.id))
Ejemplo n.º 3
0
    def issue_credit(self, source, amount, currency):
        order = source.order

        try:
            payment = paypalrestsdk.Payment.find(source.reference,
                                                 api=self.paypal_api)
            sale = self._get_payment_sale(payment)

            if not sale:
                logger.error(
                    'Unable to find a Sale associated with PayPal Payment [%s].',
                    payment.id)

            refund = sale.refund(
                {'amount': {
                    'total': unicode(amount),
                    'currency': currency,
                }})

        except:
            msg = 'An error occurred while attempting to issue a credit (via PayPal) for order [{}].'.format(
                order.number)
            logger.exception(msg)
            raise GatewayError(msg)

        basket = order.basket
        if refund.success():
            transaction_id = refund.id

            self.record_processor_response(refund.to_dict(),
                                           transaction_id=transaction_id,
                                           basket=basket)

            source.refund(amount, reference=transaction_id)

            event_type, __ = PaymentEventType.objects.get_or_create(
                name=PaymentEventTypeName.REFUNDED)
            PaymentEvent.objects.create(event_type=event_type,
                                        order=order,
                                        amount=amount,
                                        reference=transaction_id,
                                        processor_name=self.NAME)
        else:
            error = refund.error
            entry = self.record_processor_response(
                error, transaction_id=error['debug_id'], basket=basket)

            msg = "Failed to refund PayPal payment [{sale_id}]. " \
                  "PayPal's response was recorded in entry [{response_id}].".format(sale_id=sale.id,
                                                                                    response_id=entry.id)
            raise GatewayError(msg)
Ejemplo n.º 4
0
    def initiate_payment(self, basket, request, form_data):
        """
        Initiate payment using the Cybersource REST payment api.

        Returns:
            (payment_processor_response, transaction_id)

        Raises:
            GatewayError: when the REST api call fails
        """
        transient_token_jwt = request.POST['payment_token']

        try:
            payment_processor_response = self.authorize_payment_api(
                transient_token_jwt,
                basket,
                request,
                form_data,
            )
            transaction_id = payment_processor_response.processor_information.transaction_id
            return payment_processor_response, transaction_id
        except ApiException as e:
            if e.body is None:
                self.record_processor_response(
                    {
                        'status': e.status,
                        'reason': e.reason,
                    },
                    transaction_id=None,
                    basket=basket)
                logger.exception('Payment failed')
                # This will display the generic error on the frontend
                raise GatewayError()
            return e, e.headers['v-c-correlation-id']
Ejemplo n.º 5
0
    def issue_credit(self, order_number, basket, reference_number, amount,
                     currency):
        """
        Verify the payment processor used for the original order responds as expected to the refund request,
        and the response is saved in the database, with error handling.
        """
        try:
            client = Client(self.soap_api_url,
                            wsse=UsernameToken(self.merchant_id,
                                               self.transaction_key))

            credit_service = {
                'captureRequestID': reference_number,
                'run': 'true',
            }
            purchase_totals = {
                'currency': currency,
                'grandTotalAmount': str(amount),
            }

            response = client.service.runTransaction(
                merchantID=self.merchant_id,
                merchantReferenceCode=order_number,
                orderRequestToken=reference_number,
                ccCreditService=credit_service,
                purchaseTotals=purchase_totals)

            request_id = response.requestID
            ppr = self.record_processor_response(serialize_object(response),
                                                 transaction_id=request_id,
                                                 basket=basket)
        except:
            msg = 'An error occurred while attempting to issue a credit (via CyberSource) for order [{}].'.format(
                order_number)
            logger.exception(msg)
            raise GatewayError(msg)

        if response.decision == 'ACCEPT':
            return request_id
        raise GatewayError(
            'Failed to issue CyberSource credit for order [{order_number}]. '
            'Complete response has been recorded in entry [{response_id}]'.
            format(order_number=order_number, response_id=ppr.id))
Ejemplo n.º 6
0
 def _fetch_response_xml(self, request_xml):
     # Need to fill in HTTP request here
     conn = http_client.HTTPSConnection(self._host, 443, timeout=30)
     headers = {"Content-type": "application/xml",
                "Accept": ""}
     conn.request("POST", self._path, request_xml.encode('utf8'), headers)
     response = conn.getresponse()
     response_xml = response.read()
     if response.status != http_client.OK:
         raise GatewayError("Unable to communicate with payment gateway (code: %s, response: %s)" % (response.status, response_xml))
     conn.close()
     return response_xml
Ejemplo n.º 7
0
    def get_transaction_parameters(self,
                                   basket,
                                   request=None,
                                   use_client_side_checkout=True,
                                   **kwargs):
        """
        Creates Payment form URL from paystack.

        Arguments:
            basket (Basket): The basket of products being purchased.
            request (Request, optional): A Request object which is used to construct Paystack's `return_url`.
            use_client_side_checkout (bool, optional): This value is not used.
            **kwargs: Additional parameters; not used by this method.

        Returns:
            dict: paystack-specific parameters required to complete a transaction. Must contain a URL
                of payment form to which users can be directed in order to approve a newly created payment.

        Raises:
            GatewayError: Indicates a general error or unexpected behavior on the part of PayPal which prevented
            a payment from being created.
        """
        data = {
            'amount': self.get_basket_amount(basket.total_incl_tax),
            'email': basket.owner.email,
            'callback_url': self.return_url,
            'metadata': {
                'cancel_action:': self.cancel_url,
                'order_number': basket.order_number,
                'basket_id': basket.id,
                'custom_fields': self.get_paystack_custom_fields_data(basket)
            },
        }

        success, response = self.paystack_client.handler(
            INITIALIZE_TRANSACTION_CODE, data)

        if success:
            logger.info(
                "Successfully got hosted Paystack payment page for basket: %d.",
                basket.id)
            data = response.get('data')
            if data:
                return {'payment_page_url': data.get('authorization_url')}

        logger.error("Failed to get Paystack payment form for basket: %d.",
                     basket.id)
        raise GatewayError(
            "Paystack payment creation failure: unable to get Paystack form token."
        )
Ejemplo n.º 8
0
    def issue_credit(self, order_number, basket, reference_number, amount,
                     currency):
        try:
            refund = stripe.Refund.create(charge=reference_number)
        except:
            msg = 'An error occurred while attempting to issue a credit (via Stripe) for order [{}].'.format(
                order_number)
            logger.exception(msg)
            raise GatewayError(msg)

        transaction_id = refund.id

        # NOTE: Refund objects subclass dict so there is no need to do any data transformation
        # before storing the response in the database.
        self.record_processor_response(refund,
                                       transaction_id=transaction_id,
                                       basket=basket)

        return transaction_id
Ejemplo n.º 9
0
 def raise_api_error(self,
                     message,
                     response=None,
                     response_data=None,
                     basket=None):
     error_response = None
     if response is not None:
         error_response = {
             "status_code": response.status_code,
             "content": response.content.decode(),
             "data": response_data,
         }
     error = {"message": message, "response": error_response}
     entry = self.record_processor_response(
         error,
         transaction_id=basket.order_number if basket else None,
         basket=basket)
     logger.error(
         u"Failed request to Saferpay API for basket [%d], response stored in entry [%d].",
         basket.id if basket else None,
         entry.id,
         exc_info=True,
     )
     raise GatewayError(error)
Ejemplo n.º 10
0
    def request_apple_pay_authorization(self, basket, billing_address,
                                        payment_token):
        """
        Authorizes an Apple Pay payment.

        For details on the process, see the CyberSource Simple Order API documentation at
        https://www.cybersource.com/developers/integration_methods/apple_pay/.

        Args:
            basket (Basket)
            billing_address (BillingAddress)
            payment_token (dict)

        Returns:
            HandledProcessorResponse

        Raises:
            GatewayError
        """
        try:
            client = Client(self.soap_api_url,
                            wsse=UsernameToken(self.merchant_id,
                                               self.transaction_key))
            card_type = APPLE_PAY_CYBERSOURCE_CARD_TYPE_MAP[
                payment_token['paymentMethod']['network'].lower()]
            bill_to = {
                'firstName': billing_address.first_name,
                'lastName': billing_address.last_name,
                'street1': billing_address.line1,
                'street2': billing_address.line2,
                'city': billing_address.line4,
                'state': billing_address.state,
                'postalCode': billing_address.postcode,
                'country': billing_address.country.iso_3166_1_a2,
                'email': basket.owner.email,
            }
            purchase_totals = {
                'currency': basket.currency,
                'grandTotalAmount': str(basket.total_incl_tax),
            }
            encrypted_payment = {
                'descriptor': 'RklEPUNPTU1PTi5BUFBMRS5JTkFQUC5QQVlNRU5U',
                'data':
                base64.b64encode(json.dumps(payment_token['paymentData'])),
                'encoding': 'Base64',
            }
            card = {
                'cardType': card_type,
            }
            auth_service = {
                'run': 'true',
            }
            capture_service = {
                'run': 'true',
            }
            # Enable Export Compliance for SDN validation, amongst other checks.
            # See https://www.cybersource.com/products/fraud_management/export_compliance/
            export_service = {
                'run': 'true',
            }
            item = [{
                'id': index,
                'productCode': line.product.get_product_class().slug,
                'productName': clean_field_value(line.product.title),
                'quantity': line.quantity,
                'productSKU': line.stockrecord.partner_sku,
                'taxAmount': str(line.line_tax),
                'unitPrice': str(line.unit_price_incl_tax),
            } for index, line in enumerate(basket.all_lines())]

            response = client.service.runTransaction(
                merchantID=self.merchant_id,
                merchantReferenceCode=basket.order_number,
                billTo=bill_to,
                purchaseTotals=purchase_totals,
                encryptedPayment=encrypted_payment,
                card=card,
                ccAuthService=auth_service,
                ccCaptureService=capture_service,
                exportService=export_service,
                paymentSolution='001',
                item=item,
            )

        except:
            msg = 'An error occurred while authorizing an Apple Pay (via CyberSource) for basket [{}]'.format(
                basket.id)
            logger.exception(msg)
            raise GatewayError(msg)

        request_id = response.requestID
        ppr = self.record_processor_response(serialize_object(response),
                                             transaction_id=request_id,
                                             basket=basket)

        if response.decision == 'ACCEPT':
            currency = basket.currency
            total = basket.total_incl_tax
            transaction_id = request_id

            return HandledProcessorResponse(
                transaction_id=transaction_id,
                total=total,
                currency=currency,
                card_number='Apple Pay',
                card_type=CYBERSOURCE_CARD_TYPE_MAP.get(card_type))
        else:
            msg = (
                'CyberSource rejected an Apple Pay authorization request for basket [{basket_id}]. '
                'Complete response has been recorded in entry [{response_id}]')
            msg = msg.format(basket_id=basket.id, response_id=ppr.id)
            logger.warning(msg)
        raise GatewayError(msg)
Ejemplo n.º 11
0
    def get_transaction_parameters(self,
                                   basket,
                                   request=None,
                                   use_client_side_checkout=False,
                                   **kwargs):
        """
        Create a new PayPal payment.

        Arguments:
            basket (Basket): The basket of products being purchased.
            request (Request, optional): A Request object which is used to construct PayPal's `return_url`.
            use_client_side_checkout (bool, optional): This value is not used.
            **kwargs: Additional parameters; not used by this method.

        Returns:
            dict: PayPal-specific parameters required to complete a transaction. Must contain a URL
                to which users can be directed in order to approve a newly created payment.

        Raises:
            GatewayError: Indicates a general error or unexpected behavior on the part of PayPal which prevented
                a payment from being created.
        """
        # PayPal requires that item names be at most 127 characters long.
        PAYPAL_FREE_FORM_FIELD_MAX_SIZE = 127
        return_url = urljoin(get_ecommerce_url(), reverse('paypal:execute'))
        data = {
            'intent':
            'sale',
            'redirect_urls': {
                'return_url': return_url,
                'cancel_url': self.cancel_url,
            },
            'payer': {
                'payment_method': 'paypal',
            },
            'transactions': [{
                'amount': {
                    'total': str(basket.total_incl_tax),
                    'currency': basket.currency,
                },
                # Paypal allows us to send additional transaction related data in 'description' & 'custom' field
                # Free form field, max length 127 characters
                # description : program_id:<program_id>
                'description':
                "program_id:{}".format(get_basket_program_uuid(basket)),
                'item_list': {
                    'items': [
                        {
                            'quantity':
                            line.quantity,
                            # PayPal requires that item names be at most 127 characters long.
                            # for courseid we're using 'name' field along with title,
                            # concatenated field will be 'courseid|title'
                            'name':
                            middle_truncate(self.get_courseid_title(line),
                                            PAYPAL_FREE_FORM_FIELD_MAX_SIZE),
                            # PayPal requires that the sum of all the item prices (where price = price * quantity)
                            # equals to the total amount set in amount['total'].
                            'price':
                            str(line.line_price_incl_tax_incl_discounts /
                                line.quantity),
                            'currency':
                            line.stockrecord.price_currency,
                        } for line in basket.all_lines()
                    ],
                },
                'invoice_number':
                basket.order_number,
            }],
        }

        if waffle.switch_is_active('create_and_set_webprofile'):
            locale_code = self.resolve_paypal_locale(
                request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME))
            web_profile_id = self.create_temporary_web_profile(locale_code)
            if web_profile_id is not None:
                data['experience_profile_id'] = web_profile_id
        else:
            try:
                web_profile = PaypalWebProfile.objects.get(
                    name=self.DEFAULT_PROFILE_NAME)
                data['experience_profile_id'] = web_profile.id
            except PaypalWebProfile.DoesNotExist:
                pass

        available_attempts = 1
        if waffle.switch_is_active('PAYPAL_RETRY_ATTEMPTS'):
            available_attempts = self.retry_attempts

        for i in range(1, available_attempts + 1):
            try:
                payment = paypalrestsdk.Payment(data, api=self.paypal_api)
                payment.create()
                if payment.success():
                    break
                if i < available_attempts:
                    logger.warning(
                        u"Creating PayPal payment for basket [%d] was unsuccessful. Will retry.",
                        basket.id,
                        exc_info=True)
                else:
                    error = self._get_error(payment)
                    # pylint: disable=unsubscriptable-object
                    entry = self.record_processor_response(
                        error, transaction_id=error['debug_id'], basket=basket)
                    logger.error(u"%s [%d], %s [%d].",
                                 "Failed to create PayPal payment for basket",
                                 basket.id,
                                 "PayPal's response recorded in entry",
                                 entry.id,
                                 exc_info=True)
                    raise GatewayError(error)

            except:  # pylint: disable=bare-except
                if i < available_attempts:
                    logger.warning(
                        u"Creating PayPal payment for basket [%d] resulted in an exception. Will retry.",
                        basket.id,
                        exc_info=True)
                else:
                    logger.exception(
                        u"After %d retries, creating PayPal payment for basket [%d] still experienced exception.",
                        i, basket.id)
                    raise

        entry = self.record_processor_response(payment.to_dict(),
                                               transaction_id=payment.id,
                                               basket=basket)
        logger.info(
            "Successfully created PayPal payment [%s] for basket [%d].",
            payment.id, basket.id)

        for link in payment.links:
            if link.rel == 'approval_url':
                approval_url = link.href
                break
        else:
            logger.error(
                "Approval URL missing from PayPal payment [%s]. PayPal's response was recorded in entry [%d].",
                payment.id, entry.id)
            raise GatewayError(
                'Approval URL missing from PayPal payment response. See entry [{}] for details.'
                .format(entry.id))

        parameters = {
            'payment_page_url': approval_url,
        }

        return parameters
Ejemplo n.º 12
0
    def get_transaction_parameters(self, basket, request=None):
        """
        Create a new PayPal payment.

        Arguments:
            basket (Basket): The basket of products being purchased.

        Keyword Arguments:
            request (Request): A Request object which is used to construct PayPal's `return_url`.

        Returns:
            dict: PayPal-specific parameters required to complete a transaction. Must contain a URL
                to which users can be directed in order to approve a newly created payment.

        Raises:
            GatewayError: Indicates a general error or unexpected behavior on the part of PayPal which prevented
                a payment from being created.
        """
        return_url = urljoin(get_ecommerce_url(), reverse('paypal_execute'))
        data = {
            'intent': 'sale',
            'redirect_urls': {
                'return_url': return_url,
                'cancel_url': self.cancel_url,
            },
            'payer': {
                'payment_method': 'paypal',
            },
            'transactions': [{
                'amount': {
                    'total': unicode(basket.total_incl_tax),
                    'currency': basket.currency,
                },
                'item_list': {
                    'items': [
                        {
                            'quantity': line.quantity,
                            # PayPal requires that item names be at most 127 characters long.
                            'name': middle_truncate(line.product.title, 127),
                            # PayPal requires that the sum of all the item prices (where price = price * quantity)
                            # equals to the total amount set in amount['total'].
                            'price': unicode(line.line_price_incl_tax_incl_discounts / line.quantity),
                            'currency': line.stockrecord.price_currency,
                        }
                        for line in basket.all_lines()
                    ],
                },
                'invoice_number': basket.order_number,
            }],
        }

        try:
            web_profile = PaypalWebProfile.objects.get(name=self.DEFAULT_PROFILE_NAME)
            data['experience_profile_id'] = web_profile.id
        except PaypalWebProfile.DoesNotExist:
            pass

        payment = paypalrestsdk.Payment(data, api=self.paypal_api)
        payment.create()

        # Raise an exception for payments that were not successfully created. Consuming code is
        # responsible for handling the exception.
        if not payment.success():
            error = self._get_error(payment)
            entry = self.record_processor_response(error, transaction_id=error['debug_id'], basket=basket)  # pylint: disable=unsubscriptable-object

            logger.error(
                u"Failed to create PayPal payment for basket [%d]. PayPal's response was recorded in entry [%d].",
                basket.id,
                entry.id
            )

            raise GatewayError(error)

        entry = self.record_processor_response(payment.to_dict(), transaction_id=payment.id, basket=basket)
        logger.info(u"Successfully created PayPal payment [%s] for basket [%d].", payment.id, basket.id)

        for link in payment.links:
            if link.rel == 'approval_url':
                approval_url = link.href
                break
        else:
            logger.error(
                u"Approval URL missing from PayPal payment [%s]. PayPal's response was recorded in entry [%d].",
                payment.id,
                entry.id
            )
            raise GatewayError(
                'Approval URL missing from PayPal payment response. See entry [{}] for details.'.format(entry.id))

        parameters = {
            'payment_page_url': approval_url,
        }

        return parameters
Ejemplo n.º 13
0
    def get_transaction_parameters(self,
                                   basket,
                                   request=None,
                                   use_client_side_checkout=False,
                                   **kwargs):
        """
        Create a new Alipay payment.

        Arguments:
            basket (Basket): The basket of products being purchased.
            request (Request, optional): A Request object which is used to construct PayPal's `return_url`.
            use_client_side_checkout (bool, optional): This value is not used.
            **kwargs: Additional parameters; not used by this method.

        Returns:
            dict: PayPal-specific parameters required to complete a transaction. Must contain a URL
                to which users can be directed in order to approve a newly created payment.

        Raises:
            GatewayError: Indicates a general error or unexpected behavior on the part of PayPal which prevented
                a payment from being created.
        """
        return_url = urljoin(get_ecommerce_url(), reverse('alipay:execute'))
        data = {
            'intent':
            'sale',
            'redirect_urls': {
                'return_url': return_url,
                'cancel_url': self.cancel_url,
            },
            'payer': {
                'payment_method': 'alipay',
            },
            'transactions': [{
                'amount': {
                    'total': unicode(basket.total_incl_tax),
                    'currency': basket.currency,
                },
                'item_list': {
                    'items': [
                        {
                            'quantity':
                            line.quantity,
                            # PayPal requires that item names be at most 127 characters long.
                            'name':
                            middle_truncate(line.product.title, 127),
                            # PayPal requires that the sum of all the item prices (where price = price * quantity)
                            # equals to the total amount set in amount['total'].
                            'price':
                            unicode(line.line_price_incl_tax_incl_discounts /
                                    line.quantity),
                            'currency':
                            line.stockrecord.price_currency,
                        } for line in basket.all_lines()
                    ],
                },
                'invoice_number': basket.order_number,
            }],
        }

        if waffle.switch_is_active('create_and_set_webprofile'):
            locale_code = self.resolve_alipay_locale(
                request.COOKIES.get(settings.LANGUAGE_COOKIE_NAME))
            web_profile_id = self.create_temporary_web_profile(locale_code)
            if web_profile_id is not None:
                data['experience_profile_id'] = web_profile_id
        else:
            try:
                web_profile = AlipayWebProfile.objects.get(
                    name=self.DEFAULT_PROFILE_NAME)
                data['experience_profile_id'] = web_profile.id
            except AlipayWebProfile.DoesNotExist:
                pass

        available_attempts = 1
        if waffle.switch_is_active('PAYPAL_RETRY_ATTEMPTS'):
            available_attempts = self.retry_attempts

        for i in range(1, available_attempts + 1):
            try:
                payment = alipay_sdk.Payment(data, api=self.alipay_api)
                payment.create()
                if payment.success():
                    break
                else:
                    if i < available_attempts:
                        logger.warning(
                            u"Creating AliPay payment for basket [%d] was unsuccessful. Will retry.",
                            basket.id,
                            exc_info=True)
                    else:
                        error = self._get_error(payment)
                        # pylint: disable=unsubscriptable-object
                        entry = self.record_processor_response(
                            error,
                            transaction_id=error['debug_id'],
                            basket=basket)
                        logger.error(
                            u"%s [%d], %s [%d].",
                            "Failed to create AliPay payment for basket",
                            basket.id,
                            "AliPay's response recorded in entry",
                            entry.id,
                            exc_info=True)
                        raise GatewayError(error)

            except:  # pylint: disable=bare-except
                if i < available_attempts:
                    logger.warning(
                        u"Creating AliPay payment for basket [%d] resulted in an exception. Will retry.",
                        basket.id,
                        exc_info=True)
                else:
                    logger.exception(
                        u"After %d retries, creating AliPay payment for basket [%d] still experienced exception.",
                        i, basket.id)
                    raise

        entry = self.record_processor_response(payment.to_dict(),
                                               transaction_id=payment.id,
                                               basket=basket)
        logger.info(
            "Successfully created AliPay payment [%s] for basket [%d].",
            payment.id, basket.id)
        id = payment.id
        order_string = self.alipay_api.api_alipay_trade_page_pay(
            out_trade_no=payment.id,
            total_amount=unicode(basket.total_incl_tax),  #0.01,
            subject=middle_truncate(line.product.title, 127),
            return_url=return_url,
        )

        parameters = {
            'payment_page_url':
            self.alipay_api.default_endpoint() + '?' + order_string,
            #'payment_page_url': 'error_test',
        }

        return parameters
Ejemplo n.º 14
0
    def get_transaction_parameters(self, basket, request=None, use_client_side_checkout=True, **kwargs):
        """
            Create a new AuthorizeNet payment form token.

            Visit following links for more information and detail
            https://developer.authorize.net/api/reference/#accept-suite-get-an-accept-payment-page
            https://developer.authorize.net/api/reference/features/accept_hosted.html (redirection method)

        Arguments:
            basket (Basket): The basket of products being purchased.
            request (Request, optional): A Request object which is used to construct AuthorizeNet's `return_url`.
            use_client_side_checkout (bool, optional): This value is not used.
            **kwargs: Additional parameters; not used by this method.

        Returns:
            dict: AuthorizeNet-specific parameters required to complete a transaction. Must contain a URL
                to which users can be directed in order to approve a newly created payment.

        Raises:
            GatewayError: Indicates a general error or unexpected behavior on the part of AuthorizeNet which prevented
                a payment from being created.
        """

        merchant_auth = apicontractsv1.merchantAuthenticationType()
        merchant_auth.name = self.merchant_auth_name
        merchant_auth.transactionKey = self.transaction_key

        settings = self.get_authorizenet_payment_settings(basket)
        order = apicontractsv1.orderType()
        order.invoiceNumber = basket.order_number

        transaction_request = apicontractsv1.transactionRequestType()
        transaction_request.transactionType = AUTH_CAPTURE_TRANSACTION_TYPE
        transaction_request.amount = unicode(basket.total_incl_tax)
        transaction_request.order = order

        line_items_list = self.get_authorizenet_lineitems(basket)
        payment_page_request = apicontractsv1.getHostedPaymentPageRequest()
        payment_page_request.merchantAuthentication = merchant_auth
        payment_page_request.transactionRequest = transaction_request
        payment_page_request.hostedPaymentSettings = settings
        transaction_request.lineItems = line_items_list

        payment_page_controller = getHostedPaymentPageController(payment_page_request)
        payment_page_controller.execute()

        payment_page_response = payment_page_controller.getresponse()
        authorize_form_token = None

        if payment_page_response is not None:
            if payment_page_response.messages.resultCode == apicontractsv1.messageTypeEnum.Ok:
                logger.info(
                    "%s [%d].",
                    "Successfully got hosted payment page for basket",
                    basket.id,
                    exc_info=True
                )
                if payment_page_response.messages is not None:
                    logger.info('Message Code : %s', payment_page_response.messages.message[0]['code'].text)
                    logger.info('Message Text : %s', payment_page_response.messages.message[0]['text'].text)
                authorize_form_token = str(payment_page_response.token)

            else:
                logger.error('Failed to get AuthorizeNet payment token.')
                if payment_page_response.messages is not None:
                    logger.error(
                        '\nCode:%s \nText:%s',
                        payment_page_response.messages.message[0]['code'].text,
                        payment_page_response.messages.message[0]['text'].text
                    )
                raise GatewayError(payment_page_response.messages.message[0]['text'].text)
        else:
            logger.error(
                "%s [%d].",
                "Failed to create AuthorizeNet payment for basket",
                basket.id,
                exc_info=True
            )
            raise GatewayError('AuthorizeNet payment creation failure: unable to get AuthorizeNet form token')

        parameters = {
            'payment_page_url': self.autorizenet_redirect_url,
            'token': authorize_form_token
        }
        return parameters