Пример #1
0
 def get_context_data(self, **kwargs):
     # Override method so the bankcard and billing address forms can be
     # added to the context.
     ctx = super(PaymentDetailsView, self).get_context_data(**kwargs)
     ctx['bankcard_form'] = kwargs.get('bankcard_form',
                                       forms.BankcardForm())
     ctx['billing_address_form'] = kwargs.get('billing_address_form',
                                              forms.BillingAddressForm())
     return ctx
Пример #2
0
 def test_requires_4_digit_ccv_for_amex(self):
     today = datetime.date.today()
     data = {
         'number': '378282246310005',
         'ccv': '123',
         'expiry_month_0': '01',
         'expiry_month_1': today.year + 1,
     }
     form = forms.BankcardForm(data)
     self.assertFalse(form.is_valid())
Пример #3
0
 def setUp(self):
     today = datetime.date.today()
     data = {
         'number': '1000010000000007',
         'ccv': '123',
         'expiry_month_0': '01',
         'expiry_month_1': today.year + 1
     }
     self.form = forms.BankcardForm(data)
     self.assertTrue(self.form.is_valid())
Пример #4
0
    def handle_payment_details_submission(self, request):
        """Overriding method to handle initial payment data entry.

            If valid data is entered, proceed to preview page,
            otherwise re-render payment form with errors.
        """
        token_id = request.POST.get('token-id', None)

        # Token present - validate and return preview
        if token_id:
            token_instance = HelcimToken.objects.filter(id=token_id).first()

            # If no instance, this is invalid
            if not token_instance:
                self.preview = False

                # Reload the payment page with the errors
                messages.warning(
                    request,
                    ('There was an issue retrieving the saved credit card '
                     'information. You may retry the card again or '
                     're-enter the details below.'))
                return self.render_to_response(self.get_context_data)

            # Instance found - can move to preview
            return self.render_preview(
                request,
                token_id=token_id,
            )

        # No token present - validate credit card information
        bankcard_form = oscar_payment_forms.BankcardForm(request.POST)
        address_form = custom_forms.BillingAddressForm(request.POST)

        # Check that bank card data is valid
        if not (bankcard_form.is_valid() and address_form.is_valid()):
            self.preview = False

            # Reload the payment page with the errors
            context = self.get_context_data(
                bankcard_form=bankcard_form,
                billing_address_form=address_form,
            )

            return self.render_to_response(context)

        # Render the preview page
        return self.render_preview(
            request,
            bankcard_form=bankcard_form,
            billing_address_form=address_form,
        )
Пример #5
0
 def get_context_data(self, **kwargs):
     """
     Add data for Paypal Express flow.
     """
     # Override method so the bankcard and billing address forms can be
     # added to the context.
     ctx = super(PaymentDetailsView, self).get_context_data(**kwargs)
     ctx['bankcard_form'] = kwargs.get(
         'bankcard_form', forms.BankcardForm())
     ctx['billing_address_form'] = kwargs.get(
         'billing_address_form', forms.BillingAddressForm())
     ctx['PAYPAL_CLIENT_ID'] = settings.PAYPAL_API_CLIENT_ID
     return ctx
Пример #6
0
    def do_place_order(self, request):
        # Helper method to check that the hidden forms wasn't tinkered
        # with.
        bankcard_form = forms.BankcardForm(request.POST)
        billing_address_form = forms.BillingAddressForm(request.POST)
        if not all([bankcard_form.is_valid(), billing_address_form.is_valid()]):
            messages.error(request, "Invalid submission")
            return HttpResponseRedirect(reverse('checkout:payment-details'))
        bankcard = bankcard_form.get_bankcard_obj()

        # Attempt to submit the order, passing the bankcard object so that it
        # gets passed back to the 'handle_payment' method below.
        return self.submit(
            request.basket,
            payment_kwargs={'bankcard': bankcard,
                            'billing_address': billing_address_form.cleaned_data})
Пример #7
0
    def do_place_order(self, request):
        # Helper method to check that the hidden forms wasn't tinkered
        # with.
        bankcard_form = forms.BankcardForm(request.POST)
        billing_address_form = forms.BillingAddressForm(request.POST)
        if not all([bankcard_form.is_valid(),
                    billing_address_form.is_valid()]):
            messages.error(request, "Invalid submission")
            return redirect('checkout:payment-details')

        # Attempt to submit the order, passing the bankcard object so that it
        # gets passed back to the 'handle_payment' method below.
        submission = self.build_submission()
        submission['payment_kwargs']['bankcard'] = bankcard_form.bankcard
        submission['payment_kwargs'][
            'billing_address'] = billing_address_form.cleaned_data
        return self.submit(**submission)
Пример #8
0
    def get_context_data(self, **kwargs):
        """Add additional data for payment processing."""
        context = super(PaymentDetailsView, self).get_context_data(**kwargs)

        # Add the credit card data
        context['bankcard_form'] = kwargs.get(
            'bankcard_form', oscar_payment_forms.BankcardForm())

        # Add the billing address data
        context['billing_address_form'] = kwargs.get(
            'billing_address_form', custom_forms.BillingAddressForm())

        # Add details regarding saved credit card tokens
        context['token_vault'] = bridge_oscar.SETTINGS['enable_token_vault']
        context['saved_tokens'] = bridge_oscar.retrieve_saved_tokens(
            self.request.user)

        return context
Пример #9
0
    def get_context_data(self, **kwargs):
        # Override method so the bankcard and billing address forms can be added
        # to the context.
        ctx = super(PaymentDetailsView, self).get_context_data(**kwargs)

        ctx['bankcard_form'] = kwargs.get('bankcard_form', forms.BankcardForm())
        
        ctx['billing_address_form'] = kwargs.get('billing_address_form', forms.BillingAddressForm())

        if self.get_default_billing_address() is not None and kwargs.get('billing_address_form') is None:
            
            # initialize billing address form with user's address
            default_billing_address_form = forms.BillingAddressForm(initial=self.get_default_billing_address().__dict__)            
            
            # pass the updated form to the context
            ctx['billing_address_form'] = default_billing_address_form

        return ctx
Пример #10
0
    def handle_place_order_submission(self, request):
        """Overriding method to handle order submission.

            First, revalidates the payment information:
                - If valid, proceed with order submission
                - If invalid, re-render the payment form
        """
        token_id = request.POST.get('token-id', None)

        # Token takes precedence over any other payment methods
        if token_id:
            token_instance = HelcimToken.objects.filter(id=token_id).first()

            if not token_instance:
                # Issue with token now, return to payment page
                messages.error(request, 'Invalid submission')
                return HttpResponseRedirect(
                    reverse('checkout:payment-details'))

            # Add token_id to order details
            submission = self.build_submission()
            submission['payment_kwargs']['token_id'] = token_id
        else:
            bankcard_form = oscar_payment_forms.BankcardForm(request.POST)
            address_form = custom_forms.BillingAddressForm(request.POST)

            # Confirm no errors since payment page
            if not (bankcard_form.is_valid() and address_form.is_valid()):
                # Forms now have errors, return to payment page
                messages.error(request, 'Invalid submission')
                return HttpResponseRedirect(
                    reverse('checkout:payment-details'))

            # Add bank card information to order details
            submission = self.build_submission()
            submission['payment_kwargs']['bankcard'] = bankcard_form.bankcard
            submission['payment_kwargs']['billing_address'] = (
                address_form.cleaned_data)

        return self.submit(**submission)
Пример #11
0
    def do_place_order(self, request):
        """Re-validates payments details and sends for processing.

            Payment details are hidden on the preview page. They are
            re-validated to ensure no tampering and then added to the
            order details for actual payment processing.
        """
        token_id = request.POST.get('token-id', None)

        # Token takes precedence over any other payment methods
        if token_id:
            token_instance = HelcimToken.objects.filter(id=token_id).first()

            if not token_instance:
                # Issue with token now, return to payment page
                messages.error(request, 'Invalid submission')
                return HttpResponseRedirect(
                    reverse('checkout:payment-details'))

            # Add token_id to order details
            submission = self.build_submission()
            submission['payment_kwargs']['token_id'] = token_id
        else:
            bankcard_form = oscar_payment_forms.BankcardForm(request.POST)
            address_form = custom_forms.BillingAddressForm(request.POST)

            # Confirm no errors since payment page
            if not (bankcard_form.is_valid() and address_form.is_valid()):
                # Forms now have errors, return to payment page
                messages.error(request, 'Invalid submission')
                return HttpResponseRedirect(
                    reverse('checkout:payment-details'))

            # Add bank card information to order details
            submission = self.build_submission()
            submission['payment_kwargs']['bankcard'] = bankcard_form.bankcard
            submission['payment_kwargs']['billing_address'] = (
                address_form.cleaned_data)

        return self.submit(**submission)
Пример #12
0
    def post(self, request, *args, **kwargs):
        # Override so we can validate the bankcard/billingaddress submission. If
        # it is valid, we render the preview screen with the forms hidden within
        # it.  When the preview is submitted, we pick up the 'action' parameters
        # and actually place the order.
        if request.POST.get('action', '') == 'place_order':
            return self.do_place_order(request)

        bankcard_form = forms.BankcardForm(request.POST)
        billing_address_form = forms.BillingAddressForm(request.POST)

        if not all([bankcard_form.is_valid(), billing_address_form.is_valid()]):
            # Form validation failed, render page again with errors
            self.preview = False
            ctx = self.get_context_data(bankcard_form=bankcard_form,
                                        billing_address_form=billing_address_form)
            return self.render_to_response(ctx)

        # Render preview with bankcard and billing address details hidden
        return self.render_preview(request,
                                   bankcard_form=bankcard_form,
                                   billing_address_form=billing_address_form)
Пример #13
0
    def create(self, request):
        try:
            http_status = status.HTTP_200_OK
            #parse and validate data
            serializer = BpointPaymentSerializer(data=request.data)
            serializer.is_valid(raise_exception=True)
            txn, res, card, invoice_number, total, original_txn, reference = None, None, None, None, None, None, None
            # Get the optional paramters for the transaction
            if serializer.validated_data.get('amount'):
                total = serializer.validated_data['amount']
            if serializer.validated_data.get('original_txn'):
                original_txn = serializer.validated_data['original_txn']
            #Get card details if it is there
            if serializer.validated_data.get('card'):
                card_data = serializer.validated_data['card']
                card = self.Bankcard(card_data.get('number'),
                                     card_data.get('cvn'),
                                     card_data.get('expiry').strftime("%m%Y"))
            # Check if the invoice exists if action is payment,preauth
            try:
                inv = Invoice.objects.get(
                    reference=serializer.validated_data['invoice'])
                reference = inv.reference
            except Invoice.DoesNotExist:
                raise serializers.ValidationError("The invoice doesn't exist.")
            if not total and serializer.validated_data['action'] in [
                    'payment', 'preauth', 'unmatched_refund'
            ]:
                total = inv.amount
            # intialize the bpoint facade object
            facade = bpoint_facade

            if card:
                # Create card form data
                form_data = {
                    'expiry_month_0': card.expiry[:2],
                    'expiry_month_1': card.expiry[2:],
                    'ccv': card.cvn,
                    'number': card.number
                }
                # Validate card data using BankcardForm from oscar payments
                bankcard_form = forms.BankcardForm(form_data)
                if not bankcard_form.is_valid():
                    errors = bankcard_form.errors
                    for e in errors:
                        raise serializers.ValidationError(errors.get(e)[0])
                txn = facade.post_transaction(
                    serializer.validated_data['action'],
                    serializer.validated_data['type'],
                    serializer.validated_data['subtype'], inv.order_number,
                    reference, total, bankcard_form.bankcard, original_txn)
            elif serializer.validated_data.get('using_token'):
                # Get the token
                try:
                    token = BpointToken.objects.get(
                        id=serializer.validated_data.get('token'))
                except BpointToken.DoesNotExist:
                    raise serializers.ValidationError(
                        "The selected stored card doesn't exist.")
                txn = facade.pay_with_storedtoken(
                    serializer.validated_data['action'],
                    serializer.validated_data['type'],
                    serializer.validated_data['subtype'],
                    serializer.validated_data.get('token'), inv.order_number,
                    reference, total, original_txn)
            res = BpointTransactionSerializer(
                BpointTransaction.objects.get(txn_number=txn.txn_number))

            return Response(res.data)
        except serializers.ValidationError:
            raise
        except Exception as e:
            raise serializers.ValidationError(str(e))
Пример #14
0
    def post(self, request, *args, **kwargs):
        """Makes the POST request that moves between views.

            If POST has an 'action' of 'place_order' the payment
            processing can begin (call 'do_place_order').

            If POST has no 'action' this would be an attempt to move to
            thepreview screen. The payment details (token or credit
            card) must be valid to proceed. If not, return to the
            payment page to display any error messages and allow
            resubmission.
        """
        # Check if payment can be processed
        if request.POST.get('action', None) == 'place_order':
            return self.do_place_order(request)

        # Not a payment POST - will need to validate payment details
        token_id = request.POST.get('token-id', None)

        # Token present - validate and return preview
        if token_id:
            token_instance = HelcimToken.objects.filter(id=token_id).first()

            # If no instance, this is invalid
            if not token_instance:
                self.preview = False

                # Reload the payment page with the errors
                messages.warning(
                    request,
                    ('There was an issue retrieving the saved credit card '
                     'information. You may retry the card again or '
                     're-enter the details below.'))
                return self.render_to_response(self.get_context_data)

            # Instance found - can move to preview
            return self.render_preview(
                request,
                token_id=token_id,
            )

        # No token present - validate credit card information
        bankcard_form = oscar_payment_forms.BankcardForm(request.POST)
        address_form = custom_forms.BillingAddressForm(request.POST)

        # Check that bank card data is valid
        if not (bankcard_form.is_valid() and address_form.is_valid()):
            self.preview = False

            # Reload the payment page with the errors
            context = self.get_context_data(
                bankcard_form=bankcard_form,
                billing_address_form=address_form,
            )

            return self.render_to_response(context)

        # Render the preview page
        return self.render_preview(
            request,
            bankcard_form=bankcard_form,
            billing_address_form=address_form,
        )