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
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())
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())
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, )
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
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})
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)
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
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
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)
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)
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)
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))
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, )