When I first started integrating payment gateways into Django projects, I realized it wasn’t as easy as just plugging in an API key. I’ve come to appreciate how clean, secure, and efficient payment integration is for any business, especially in the market where compliance and user experience are paramount.
In this guide, I’ll walk you through how to integrate a payment gateway into your Django application with clear, actionable steps and full code examples. Whether you’re building an e-commerce store, a subscription service, or simply want to accept payments online, this tutorial will help you get it done right.
Understand Payment Gateway Integration in Django
A payment gateway acts as the bridge between your Django app and the financial institutions that process payments. It handles sensitive data like credit card information securely, ensuring transactions are smooth and compliant with regulations such as PCI DSS.
There are multiple ways to integrate payment gateways with Django:
- Using third-party SDKs (like Stripe or PayPal SDKs)
- Using REST APIs with requests to communicate with the payment provider
- Leveraging Django packages built specifically for payment processing
I’ll cover the Stripe integration method here, as Stripe is widely used across the USA for its developer-friendly API and robust features.
Read Build a To-Do List API in Django Rest Framework
Method 1: Integrate Stripe Payment Gateway with Django
Stripe offers a clean API and excellent Python support, making it a favorite among Django developers.
Step 1: Set up your Stripe account
- Sign up for a Stripe account at stripe.com.
- Get your Publishable Key and Secret Key from the dashboard.
Step 2: Install required packages
Install Stripe’s Python package and Django:
pip install django stripeStep 3: Create a new Django project and app
django-admin startproject payment_project
cd payment_project
python manage.py startapp paymentsCheck out the Use Django Built-In Login System
Step 4: Configure your Django settings
Add payments to your INSTALLED_APPS in settings.py. Also, add your Stripe keys:
# payment_project/settings.py
INSTALLED_APPS = [
# other apps
'payments',
]
# Stripe keys (use environment variables for production)
STRIPE_PUBLISHABLE_KEY = 'pk_test_your_publishable_key'
STRIPE_SECRET_KEY = 'sk_test_your_secret_key'Step 5: Create payment models (optional)
If you want to keep track of payments:
# payments/models.py
from django.db import models
class Payment(models.Model):
stripe_charge_id = models.CharField(max_length=50)
amount = models.DecimalField(decimal_places=2, max_digits=10)
timestamp = models.DateTimeField(auto_now_add=True)
def __str__(self):
return f"Payment {self.stripe_charge_id} - ${self.amount}"Run migrations:
python manage.py makemigrations
python manage.py migrateStep 6: Create views to handle payment
Create a view to render the payment page and handle the payment process:
# payments/views.py
from django.conf import settings
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
import stripe
stripe.api_key = settings.STRIPE_SECRET_KEY
def payment_page(request):
context = {
'stripe_publishable_key': settings.STRIPE_PUBLISHABLE_KEY
}
return render(request, 'payments/payment.html', context)
@csrf_exempt
def create_payment(request):
if request.method == 'POST':
data = request.POST
try:
# Amount in cents
amount = int(float(data.get('amount', '0')) * 100)
# Create a charge: this will charge the user's card
charge = stripe.Charge.create(
amount=amount,
currency='usd',
description='Example charge',
source=data.get('stripeToken')
)
# You can save charge.id and amount to your database here if needed
return JsonResponse({'status': 'success'})
except stripe.error.CardError as e:
return JsonResponse({'status': 'error', 'message': str(e)})
return JsonResponse({'status': 'error', 'message': 'Invalid request'})Read Google Authentication in Django
Step 7: Create the payment template
Create a simple HTML page to collect payment info:
<!-- payments/templates/payments/payment.html -->
<!DOCTYPE html>
<html>
<head>
<title>Make a Payment</title>
<script src="https://js.stripe.com/v3/"></script>
</head>
<body>
<h2>Pay with Card</h2>
<form id="payment-form">
<label for="amount">Amount (USD):</label>
<input type="number" id="amount" name="amount" min="1" step="0.01" required>
<div id="card-element"></div>
<button type="submit">Pay</button>
<div id="payment-message"></div>
</form>
<script>
var stripe = Stripe('{{ stripe_publishable_key }}');
var elements = stripe.elements();
var card = elements.create('card');
card.mount('#card-element');
var form = document.getElementById('payment-form');
form.addEventListener('submit', function(event) {
event.preventDefault();
stripe.createToken(card).then(function(result) {
if (result.error) {
document.getElementById('payment-message').textContent = result.error.message;
} else {
fetch("{% url 'create_payment' %}", {
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'X-CSRFToken': '{{ csrf_token }}'
},
body: new URLSearchParams({
'stripeToken': result.token.id,
'amount': document.getElementById('amount').value
})
}).then(response => response.json())
.then(data => {
if (data.status === 'success') {
document.getElementById('payment-message').textContent = 'Payment successful!';
} else {
document.getElementById('payment-message').textContent = data.message;
}
});
}
});
});
</script>
</body>
</html>Step 8: Configure URLs
# payments/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.payment_page, name='payment_page'),
path('create-payment/', views.create_payment, name='create_payment'),
]Include this in the main project URLs:
# payment_project/urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('payments/', include('payments.urls')),
]Check out Print Django Environment Variables
Step 9: Run your server and test
python manage.py runserverVisit http://localhost:8000/payments/ and try making a test payment using Stripe’s test card numbers (e.g., 4242 4242 4242 4242).
You can refer to the screenshot to see the output.

Method 2: Use Django Packages for Payment Integration
If you prefer a more plug-and-play approach, Django packages like django-payments or dj-stripe can simplify integration by abstracting many details.
- django-payments supports multiple gateways and standardizes payment models.
- dj-stripe syncs Stripe data directly into your Django models.
From my experience, these packages are great for larger projects needing advanced features like subscriptions or webhooks, but they can add complexity if you only need simple one-time payments.
Read Pyramid vs. Django
Tips for a Smooth Payment Integration Experience
- Always use HTTPS in production to secure sensitive data.
- Store API keys securely using environment variables or secret management tools.
- Test thoroughly using sandbox/test modes provided by payment gateways.
- Implement webhook handlers to track payment status updates.
- Keep user experience in mind; a smooth checkout process improves conversion.
Integrating payment gateways with Django doesn’t have to be intimidating. With Stripe’s developer-friendly API and Django’s flexibility, you can build a secure, reliable payment system tailored for your US-based customers.
If you want to dive deeper or explore other gateways like PayPal or Square, the approach is similar: get API keys, install SDKs, create views and templates, and handle the payment flow securely.
Happy coding, and may your payments flow smoothly!
For more Django tutorials and Python guides, check out the comprehensive resources available at PythonGuides.com. This tutorial is designed to give you a solid foundation for payment integration that you can build upon for any project.
You may read other articles:

I am Bijay Kumar, a Microsoft MVP in SharePoint. Apart from SharePoint, I started working on Python, Machine learning, and artificial intelligence for the last 5 years. During this time I got expertise in various Python libraries also like Tkinter, Pandas, NumPy, Turtle, Django, Matplotlib, Tensorflow, Scipy, Scikit-Learn, etc… for various clients in the United States, Canada, the United Kingdom, Australia, New Zealand, etc. Check out my profile.