From e01f898f29c0551d6d10aba079930b1d672b4230 Mon Sep 17 00:00:00 2001 From: Awoyalejohn Date: Fri, 5 Aug 2022 17:14:26 +0100 Subject: [PATCH] Add checkout form data caching in payment intent and remove unused stripe javascript on checkout success template --- cart/views.py | 1 - .../static/checkout/js/stripe_elements.js | 107 +++++++++++++++--- .../templates/checkout/checkout_success.html | 7 -- checkout/urls.py | 5 +- checkout/views.py | 33 +++++- checkout/webhook_handler.py | 2 + 6 files changed, 127 insertions(+), 28 deletions(-) diff --git a/cart/views.py b/cart/views.py index b2ca26d..b380a21 100644 --- a/cart/views.py +++ b/cart/views.py @@ -34,7 +34,6 @@ def post(self, request, slug): #Adds the amount of that item to its value in the dictionary request.session['cart'] = cart - print(request.session['cart']) return redirect(redirect_url) diff --git a/checkout/static/checkout/js/stripe_elements.js b/checkout/static/checkout/js/stripe_elements.js index aec5043..11bf525 100644 --- a/checkout/static/checkout/js/stripe_elements.js +++ b/checkout/static/checkout/js/stripe_elements.js @@ -47,30 +47,103 @@ card.addEventListener('change', (event) => { const form = document.querySelector('#payment-form'); form.addEventListener('submit', (event) => { + // Prevents form from submitting event.preventDefault(); + //disables card element card.disabled = true; document.querySelector('#submit-button').disabled = true; - stripe.confirmCardPayment(clientSecret, { - payment_method: { - card: card, + // Checks the checkbox if its checked + let saveInfo = document.querySelector('#id-save-info') + if (typeof (saveInfo) != 'undefined' && saveInfo != null) { + saveInfo = saveInfo.checked; + } else { + saveInfo = false; + } + console.log(saveInfo); + + // Gets CSRF Token from using {% csrf_token %} in the form + const csrftoken = document.querySelector('[name=csrfmiddlewaretoken]').value; + + // Url that the data will be posted to + const url = '/checkout/cache_checkout_data/'; + + //headers + headerInfo = { + 'Content-Type': 'application/json', + 'X-CSRFToken': csrftoken, + }; + + // Data to post + const postData = { + "client_secret": clientSecret, + "save_info": saveInfo + }; + + // Django docs implementation of posting data with CSRF token + const request = new Request( + url, + { + method: 'POST', + headers: headerInfo, + body: JSON.stringify(postData), + mode: 'same-origin' // Do not send CSRF token to another domain. } - }).then(function (result) { - if (result.error) { - let errorDiv = document.querySelector('#card-errors'); - let html = ` + ); + + fetch(request) + .then(function (data) { + console.log('Success:', data); + stripe.confirmCardPayment(clientSecret, { + payment_method: { + card: card, + billing_details: { + name: form.full_name.value.trim(), + phone: form.phone_number.value.trim(), + email: form.email.value.trim(), + address: { + line1: form.street_address1.value.trim(), + line2: form.street_address2.value.trim(), + city: form.town_or_city.value.trim(), + country: form.country.value.trim(), + state: form.county.value.trim(), + } + } + }, + shipping: { + name: form.full_name.value.trim(), + phone: form.phone_number.value.trim(), + address: { + line1: form.street_address1.value.trim(), + line2: form.street_address2.value.trim(), + city: form.town_or_city.value.trim(), + country: form.country.value.trim(), + postal_code: form.postcode.value.trim(), + state: form.county.value.trim(), + } + }, + }).then(function (result) { + if (result.error) { + let errorDiv = document.querySelector('#card-errors'); + let html = ` ${result.error.message}Thank You {% endblock %} - -{% block postloadjs %} - {{ block.super }} - {{ stripe_public_key|json_script:"id_stripe_public_key" }} - {{ client_secret|json_script:"id_client_secret" }} - -{% endblock %} \ No newline at end of file diff --git a/checkout/urls.py b/checkout/urls.py index 6123907..cefb858 100644 --- a/checkout/urls.py +++ b/checkout/urls.py @@ -1,9 +1,10 @@ from django.urls import path -from checkout.views import Checkout, CheckoutSuccess +from checkout.views import Checkout, CheckoutSuccess, cache_checkout_data from .webhooks import webhook urlpatterns = [ path('', Checkout.as_view(), name='checkout'), path('checkout_success/', CheckoutSuccess.as_view(), name='checkout_success'), - path('wh/>', webhook, name='webhook'), + path('cache_checkout_data/', cache_checkout_data, name='cache_checkout_data'), + path('wh/', webhook, name='webhook'), ] \ No newline at end of file diff --git a/checkout/views.py b/checkout/views.py index 99cac91..a89788a 100644 --- a/checkout/views.py +++ b/checkout/views.py @@ -1,4 +1,5 @@ -from django.shortcuts import get_object_or_404, render, redirect, reverse +from django.shortcuts import get_object_or_404, render, redirect, reverse, HttpResponse +from django.views.decorators.http import require_POST from django.contrib import messages from django.conf import settings from django.views.generic import View @@ -8,6 +9,36 @@ from cart.contexts import cart_contents import stripe +from django.http import JsonResponse +import json + + + + + + + +@require_POST +def cache_checkout_data(request): + try: + req_json = json.loads(request.body) + pid = req_json['client_secret'].split('_secret')[0] + print(pid) + stripe.api_key = settings.STRIPE_SECRET_KEY + stripe.PaymentIntent.modify(pid, metadata={ + 'cart': json.dumps(request.session.get('cart', {})), + 'save_info': req_json['save_info'], + 'username': request.user, + }) + return HttpResponse(status=200) + except Exception as e: + messages.error(request, 'Sorry, your payment cannot be \ + processed right now. Please try again later.') + print(e) + print(e) + return HttpResponse(content=e, status=400) + + # Create your views here. class Checkout(View): diff --git a/checkout/webhook_handler.py b/checkout/webhook_handler.py index 2584cca..2733b60 100644 --- a/checkout/webhook_handler.py +++ b/checkout/webhook_handler.py @@ -19,6 +19,8 @@ def handle_payment_intent_succeeded(self, event): """ Handle the payment_intent.succeeded webhook from Stripe """ + intent = event.data.object + print(intent) return HttpResponse( content=f'Webhook received: {event["type"]}', status=200)