Stripe is a powerful, developer-friendly payment gateway supporting all major card networks (Visa, Mastercard, Amex, and more). This guide walks you through integrating Stripe Checkout into your Django app to accept payments securely and efficiently.
1. Installation & Environment Setup
Install Stripe Python SDK
pip install stripe
Add Stripe API Keys to .env
Get your Publishable Key and Secret Key from the Stripe Dashboard → Developers → API Keys.
# .env
STRIPE_SECRET_KEY=sk_test_your_secret_key
STRIPE_PUBLISHABLE_KEY=pk_test_your_publishable_key
Load Keys Securely in settings.py
Use python-decouple
or os.environ
to keep keys safe:
# settings.py
import os
import stripe
stripe.api_key = os.getenv("STRIPE_SECRET_KEY")
STRIPE_PUBLISHABLE_KEY = os.getenv("STRIPE_PUBLISHABLE_KEY")
2. Key Stripe Concepts Explained
- Checkout Session: Stripe-hosted payment page handling all UX and security for you.
- PaymentIntent: Stripe object used for custom payment flows if you want to build your own UI.
- Webhooks: Stripe’s server-to-server notifications for events like payment success, refunds, disputes.
For most Django apps, Stripe Checkout is the easiest and safest integration.
3. Creating the Checkout Session
Example View in views.py
from django.shortcuts import redirect
from django.views.decorators.csrf import csrf_exempt
import stripe
import os
stripe.api_key = os.getenv("STRIPE_SECRET_KEY")
@csrf_exempt
def create_checkout_session(request):
try:
session = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=[{
'price_data': {
'currency': 'usd',
'product_data': {
'name': 'Premium Django Course',
},
'unit_amount': 2000, # amount in cents ($20.00)
},
'quantity': 1,
}],
mode='payment',
success_url=request.build_absolute_uri('/stripe-success/'),
cancel_url=request.build_absolute_uri('/stripe-cancel/'),
)
return redirect(session.url, code=303)
except Exception as e:
return str(e) # handle exceptions properly in production!
Add URL Pattern in urls.py
from django.urls import path
from .views import create_checkout_session
urlpatterns = [
path('create-checkout-session/', create_checkout_session, name='create-checkout-session'),
]
4. Success & Cancel Views
Stripe redirects the user to these after payment completion or cancellation.
Views in views.py
from django.http import HttpResponse
def stripe_success(request):
return HttpResponse("✅ Payment successful. Thank you!")
def stripe_cancel(request):
return HttpResponse("❌ Payment canceled. Please try again.")
Add URLs
urlpatterns += [
path('stripe-success/', stripe_success, name='stripe-success'),
path('stripe-cancel/', stripe_cancel, name='stripe-cancel'),
]
5. Frontend: Payment Button Template
Add a simple form with a payment button.
<!-- templates/checkout.html -->
<form action="{% url 'create-checkout-session' %}" method="POST">
{% csrf_token %}
<button type="submit" class="btn btn-primary">Pay with Card</button>
</form>
6. (Optional but Recommended) Stripe Webhook Setup
Webhooks let your backend confirm payment status independently, useful if users close the browser or network drops.
Webhook View in views.py
from django.views.decorators.csrf import csrf_exempt
from django.http import HttpResponse
import stripe
import os
@csrf_exempt
def stripe_webhook(request):
payload = request.body
sig_header = request.META.get('HTTP_STRIPE_SIGNATURE')
endpoint_secret = os.getenv("STRIPE_WEBHOOK_SECRET")
try:
event = stripe.Webhook.construct_event(payload, sig_header, endpoint_secret)
except (ValueError, stripe.error.SignatureVerificationError):
return HttpResponse(status=400)
# Handle the checkout.session.completed event
if event['type'] == 'checkout.session.completed':
session = event['data']['object']
# TODO: Fulfill the order (update your DB, send emails, etc.)
print(f"Payment successful for session ID: {session['id']}")
return HttpResponse(status=200)
Add Webhook URL
urlpatterns += [
path('stripe/webhook/', stripe_webhook, name='stripe-webhook'),
]
Register Webhook in Stripe Dashboard
Go to Developers → Webhooks, add your endpoint (e.g., http://localhost:8000/stripe/webhook/
), and subscribe to the checkout.session.completed
event.
Final Checklist
- API keys loaded securely from environment
- Created a checkout session view that redirects to Stripe
- Success and cancel URLs configured and routed
- (Optional) Webhook endpoint created for server-side payment confirmation
Security Best Practices
- Never expose your Secret Key on frontend.
- Always use HTTPS in production.
- Use Stripe’s test card for testing:
4242 4242 4242 4242
(any CVC and future expiry date).
Testing Tips
- Use Stripe's test environment for development.
- Try different test cards for simulating failures, disputes, or 3D Secure flows.
- Check Stripe Dashboard logs for detailed payment event info.
Next Steps & Advanced Topics
- Store payment status in your Django models for order tracking.
- Send email receipts using Django signals after successful payments.
- Upgrade to PaymentIntent API for advanced flows (e.g., subscriptions, saved cards).
- Add subscription and recurring billing.
- Implement client-side Stripe Elements for custom UI payment forms.
- Securely handle refunds and disputes through Stripe APIs.
If you want, I can guide you step-by-step on implementing any of these advanced topics or Django-specific best practices. Just ask!
Would you like me to help with a Django model example for saving payments or the webhook logic for marking orders paid?