Django/Payments/Stripe/

How to Integrate Stripe Payment Gateway in Django and React for the checkout use case?

Published on

How to Integrate Stripe Payment Gateway in Django and React for the checkout use case?
Stripe Checkout is a solution prepackaged from Stripe. Checkout session represents your customer's session as they pay for one-time purchases through Checkout or Payment links.  In this blog, we are provide a detailed steps on stripe payment gateway integration.

Introduction:

Stripe Checkout is a solution prepackaged from Stripe. Checkout is a low-code payment integration that creates a customizable payment page so you can quickly collect payments on desktop and mobile devices. Checkout supports one-time payments and subscriptions for your global customer base with coverage across over twenty local payment methods.

Flow diagram:


flow diagram

How it works:


how it works

Prerequisites :

Steps:

Step 1: Signup/Login to Stripe

If you don't have an Stripe account ( ), please proceed with the signup option. otherwise, log in with your existing credentials.

Step 2: Retrieve the Stripe API Keys

  • In the Stripe dashboard click Developers

  • Then, click API keys, In the API keys section, find the Publishable key and Secret key. Copy them and paste it into a local text file. These Key`s will be used to interact with Stripe.

:warning:

Your Secret key used in backend only . Don't use in frontend

api key

Step 3: Django Backend Creation

  • Create a django project named stripe_django using the following command.

1django-admin startproject stripe_django
  • Navigate to the project directory which you have created in the above step and create an app named checkout using the following command.

1cd stripe_django 2python manage.py startapp checkout
  • The project structure is given below



project structure


  • Install the stripe python package using pip

1pip install --upgrade stripe
  • Update the django settings.py file with following items.

    • In INSTALLED_APPS section add your app name (i.e. checkout)

    • Append STRIPE_SECRET_KEY(i.e. from Step 2: Retrieve the Stripe API Keys ) at end of settings.py file to allow django to access stripe.

1#settings.py 2 3INSTALLED_APPS = [ 4 ..... 5 'checkout' 6] 7. 8. 9. 10 11#stripe 12STRIPE_SECRET_KEY = <YOUR_STRIPE_SECRET_KEY>


installed app



secret key



A sample settings.py file can be found in the following git repository file.

  • Navigate to checkout django app directory, and create a CreateCheckoutSession class in views.py.

1class CreateCheckoutSession(APIView): 2 def post(self, request): 3 dataDict = dict(request.data) 4 price = dataDict['price'][0] 5 product_name = dataDict['product_name'][0] 6 try: 7 checkout_session = stripe.checkout.Session.create( 8 line_items =[{ 9 'price_data' :{ 10 'currency' : 'usd', 11 'product_data': { 12 'name': product_name, 13 }, 14 'unit_amount': price 15 }, 16 'quantity' : 1 17 }], 18 mode= 'payment', 19 success_url= FRONTEND_CHECKOUT_SUCCESS_URL, 20 cancel_url= FRONTEND_CHECKOUT_FAILED_URL, 21 ) 22 return redirect(checkout_session.url , code=303) 23 except Exception as e: 24 print(e) 25 return e

line_items – The line items purchased by the customer.

mode – The mode of the Checkout Session.

currency – Three-letter ISO currency code, in lowercase. Must be a supported currency.

success_url – The URL to which Stripe should send customers when payment is complete.

cancel_url – The URL the customer will be directed to if they decide to cancel payment and return to your website.

A sample views.py file can be found in the following git repository file.

  • After creating the class add urls.py file under your checkout django app.



project structure

  • In your core folder navigate to urls.py(core folder) and add your path with <appname> and <url_filename>(i.e. created in the above step) .Your core urls.py settings like below.

1from django.contrib import admin 2from django.urls import path , include 3 4urlpatterns = [ 5 path('admin/', admin.site.urls), 6 path('checkout/', include('<your_app_name>.<url_filename>')), 7]


project structure



A sample urls.py(core folder) file can be found in the following git repository file.

  • Now , In your checkout app urls.py add your path with the class CreateCheckoutSession

1from checkout import views 2from django.urls import path 3from .views import * 4 5 6urlpatterns = [ 7 path('create-checkout-session/' , CreateCheckoutSession.as_view()), 8]


create url path



A sample urls.py(checkout) file can be found in the following git repository file.

Step 4: Setup webhook to test locally

A webhook is an endpoint on your server that receives requests from Stripe, notifying you about events that happen on your account such as a customer disputing a charge or a successful recurring payment.

  • Navigate to checkout django app directory, and create a Webhook Class in views.py.

1class WebHook(APIView): 2 def post(self , request): 3 event = None 4 payload = request.body 5 sig_header = request.META['HTTP_STRIPE_SIGNATURE'] 6 7 try: 8 event = stripe.Webhook.construct_event( 9 payload ,sig_header , webhook_secret 10 ) 11 except ValueError as err: 12 # Invalid payload 13 raise err 14 except stripe.error.SignatureVerificationError as err: 15 # Invalid signature 16 raise err 17 18 # Handle the event 19 if event.type == 'payment_intent.succeeded': 20 payment_intent = event.data.object 21 print("--------payment_intent ---------->" , payment_intent) 22 elif event.type == 'payment_method.attached': 23 payment_method = event.data.object 24 print("--------payment_method ---------->" , payment_method) 25 # ... handle other event types 26 else: 27 print('Unhandled event type {}'.format(event.type)) 28 29 return JsonResponse(success=True, safe=False)

A sample views.py file can be found in the following git repository file.

  • Now , In your checkout app urls.py add your path with the class WebHook

1from checkout import views 2from django.urls import path 3from .views import * 4 5urlpatterns = [ 6 path('create-checkout-session/' , CreateCheckoutSession.as_view()), 7 path('webhook-test/' , WebHook.as_view()), 8]


add path



A sample urls.py(checkout) file can be found in the following git repository file.

  • In stripe dashboard click Developers > Webhooks > Test in a local environment button.



webhook

  • After clicking Test in local environment button, the following screen will appear, which will explain the steps needs to connect the django with stripe webhook.



wenhook steps

  • Follow the instructions mentioned in above screen.

    • Click the Download CLI from the above screen, Download the CLI. unzip it and run the executable file (i.e. In my case its windows system, therefore I am gonna run stripe.exe file)

    • Navigate to the CLI tool installation directory(i.e. stripe.exe file location)

    • Open the Windows Command prompt and proceed with the following steps

      • Log in Stripe account using the below command

        • 1stripe login
        • You will get a pairing code like below , press Enter



pairing key

        • After press Enter , It will redirect to stripe and ask to Verify that the pairing code screen like below. click Allow access



allow access

        • After clicking Allow access . you will get a screen like below



success

      • Forward events to your webhook

        • 1stripe listen --forward-to localhost:8000/<your_webhook_api_url> 2 3For example: 4stripe listen --forward-to localhost:8000/webhook-test/


webhook

        • After executing above command, webhook signing secret is generated .(i.e . for example <whsec_15441... >). Copy them and paste it in a text file. This key used to handle the webhook.

        • Also add your webhook signing secret in settings.py file.

          1#stripe 2STRIPE_SECRET_KEY = <YOUR_STRIPE_SECRET_KEY> 3STRIPE_WEBHOOK_SECRET = <YOUR_WEBHOOK_SECRET>


secret key



  • After completing the steps . Click Done



webhook

  • Complete Django example in the following github repo.

Step 4: React Frontend Creation

  • Run the following command to create a React project.

1npx create-react-app stripe_react
  • Navigate to the created project directory

1cd stripe_react
  • Add a .env file and add your Stripe Publishable key

1REACT_APP_STRIPE_KEY=pk_test_<YOUR_PUBSHICHABLE_KEY>

A sample .env file can be found in the following git repository file.

  • Under the src folder create a folder named Config .

  • Create Config.js file in Config folder . Add the <Backend_API_URL> and Stripe Publishable Key in config.js file.

1export const API_URL = process.env.REACT_APP_API_URL || 'http://localhost:8000' 2export const REACT_APP_STRIPE_KEY = process.env.REACT_APP_STRIPE_KEY || 'pk_test_<YOUR_PUBSHICHABLE_KEY>'

A sample config.js file can be found in the following git repository file.

  • Under the src folder create a folder named Component and then create Checkout.js, Success and failure redirect .js files in the same folder.

  • Final project structure is given below



project structure

  • In your package.json add the following dependencies

1{ 2 "name": "stripe-react", 3 "version": "0.1.0", 4 "private": true, 5 "dependencies": { 6 "@stripe/react-stripe-js": "^1.8.1", 7 "@stripe/stripe-js": "^1.31.0", 8 "@stripe/stripe-react-native": "^0.12.0", 9 ... 10 ... 11 "react-router-dom": "^6.3.0", 12 }

Module not found: Error: Can't resolve '@stripe/stripe-js/pure' – >npm install @stripe/stripe-js

Module not found: Error: Can't resolve 'react-router-dom' – > npm install react-router-dom

  • In Checkout.js and add a form having two input fields product name and price .These two inputs are hidden and these values are given to the django to proceed the checkout . In form action add your backend api URL(for example – http://localhost:8000/checkout/create-checkout-session/ )

  • Add a Checkout button.

1# src/Components/Checkout 2import { API_URL } from '../Config/config'; 3 4const Checkout = () => { 5 return ( 6 <> 7 <div className="container"> 8 <h1>Checkout</h1> 9 <img src="https://i.imgur.com/EHyR2nP.png" className='image'></img> 10 <h2>Price</h2> 11 <h3>25$</h3> 12 <form action={`${API_URL}/checkout/create-checkout-session/`} method="POST"> 13 <input type="hidden" name="product_name" value="test_product" /> 14 <input type="hidden" name="price" value={25 * 100} /> 15 <button className="btn-checkout" type="submit" >Checkout</button> 16 </form> 17 </div> 18 </> 19 ); 20} 21 22export default Checkout;

A sample Checkout.js file can be found in the following git repository file.

  • When you click the button it calls backend api. In backend performs stripe checkout session.

  • After completing your payment you need to redirect based on checkout session status. So , you have to add Success.js and Cancel.js

  • In success.js add some success message like Checkout successful.

1import { useSearchParams } from "react-router-dom"; 2 3const Success = () => { 4 5 const [searchParams, setSearchParams] = useSearchParams(); 6 let session_id = searchParams.get("session_id") 7 console.log(searchParams.get("session_id")) 8 9 return ( 10 <> 11 <section> 12 <div class="product Box-root"> 13 <div class="description Box-root"> 14 <h3>Checkout successful!</h3> 15 </div> 16 </div> 17 </section> 18 </> 19 ) 20} 21 22export default Success
  • In Cancel.js add some failure messages like checkout failed.

1const Cancel = () => { 2 return ( 3 <> 4 <section> 5 <p>Checkout Failed . back to pay!</p> 6 </section> 7 </> 8 ) 9} 10 11export default Cancel
  • In App.js add some routing for pages which you created in above steps.

1import './index.css' 2import React from 'react' 3import { Elements } from '@stripe/react-stripe-js' 4import { loadStripe } from "@stripe/stripe-js/pure" 5import Checkout from "./Component/Checkout" 6import CheckoutSuccess from './Component/Success' 7import CheckoutCancel from './Component/Cancel' 8import { BrowserRouter as Router, Routes, Route } from "react-router-dom" 9import { REACT_APP_STRIPE_KEY } from './Config/config'; 10 11const stripe_key = REACT_APP_STRIPE_KEY 12const stripePromise = loadStripe(stripe_key) 13 14function App() { 15 return ( 16 <> 17 <Elements stripe={stripePromise} > 18 <Router> 19 <Routes> 20 <Route exact path='checkout/' index element={<Checkout />} /> 21 <Route exact path='checkout/success/' element={<CheckoutSuccess/>} /> 22 <Route exact path='checkout/failed/' element={<CheckoutCancel/>} /> 23 </Routes> 24 </Router> 25 </Elements> 26 27 </> 28 ); 29} 30 31export default App;

loadStripe – It will load stripe payment pages in React.

  • run the project using following command.

1npm start
  • After running the command . It will redirect to the browser ( http://localhost:3000 )

  • In browser check url – http://localhost:3000/checkout/

  • Click checkout button , it will redirect to the stripe payment page

  • Complete React example in the following github repo.

Result:

After run both backend and frontend , If we click on the checkout button, it will redirect to the stripe payment page See the below image:



result



result


  • In Payment page give some testing data and click Pay



result


result

  • If payment success it will redirect the success page



result

Comments