Episyche
Django/Payments/Stripe/
2022-10-17T07:16:16.610792Z
Published on
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.
Stripe account
Stripe package
Python – Stripe ( stripe )
React – Stripe ( npm: @stripe/react-stripe-js )
If you don't have an Stripe account ( Stripe | Payment Processing Platform for the Internet ), please proceed with the signup option. otherwise, log in with your existing credentials.
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.
Your Secret key used in backend only . Don't use in frontend
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
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>
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.
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]
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]
A sample urls.py(checkout) file can be found in the following git repository file.
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]
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.
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.
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
After press Enter , It will redirect to stripe and ask to Verify that the pairing code screen like below. click Allow access
After clicking Allow access . you will get a screen like below
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/
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>
A sample settings.py file can be found in the following git repository file.
Trigger events with the CLI
1stripe trigger payment_intent.succeeded
After completing the steps . Click Done
Complete Django example in the following github repo.
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
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.
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:
In Payment page give some testing data and click Pay
If payment success it will redirect the success page
Comments