We’ve built Stripe billing into Django and Flask apps for client stores and SaaS products, and the issues are nearly always the same. A working Stripe Python setup from scratch follows a clear order. You’ll install the library with pip install stripe, set up API keys safely, use the modern StripeClient, create a Payment Intent and a Checkout Session, verify webhooks, test with Stripe’s test cards and fix common errors. There’s also a short section on using Stripe with Python AI agent frameworks. The examples suit developers in the US, UK, Canada, Australia and Europe building stores, subscriptions or SaaS billing.
Quick answer: To integrate Stripe with Python, run
pip install stripe, store your secret key in an environment variable, create aStripeClientwith that key and call methods such asclient.v1.payment_intents.create()orclient.v1.checkout.sessions.create(). Use webhooks with signature verification to confirm payments, and test everything with Stripe’s test keys and test cards before going live.
Table of Contents
Before You Start: Stripe Account and API Keys
Before writing any Stripe Python code, you need a Stripe account, your test API keys and a Python environment. Stripe gives every account a sandbox with separate test keys, so you can build and test the whole integration without moving real money.
Create Your Stripe Account
Sign up on Stripe with your email, then add your business details when you’re ready to accept live payments. Our Stripe getting started checklist covers the account settings to finish before launch. If you’re outside Stripe’s supported countries, our guide to Stripe in Pakistan explains the options.
Find Your API Keys
In the Stripe Dashboard, open the Developers area and go to API keys. You’ll see a publishable key (starting with pk_) for front-end code and a secret key (starting with sk_) for your server. Test keys include test in the prefix. Never put the secret key in front-end code or a public repository.
Use Restricted Keys Where Possible
Stripe lets you create restricted keys that can only access certain resources. Use them for scripts and services that only need limited access, such as a reporting job that reads charges. Once you’re live, our guide to whether Stripe holds funds explains reserves and payout delays.
Installing the Stripe Python Library
Installing the Stripe Python library takes one command: pip install stripe. The package on PyPI is the official Stripe Python SDK, maintained by Stripe. Recent versions require Python 3.9 or later, so check your Python version first and install the library inside a virtual environment for each project.
Check Your Python Version
python3 --version
The stripe package on PyPI lists “Requires Python >=3.9” for recent releases. If your system Python is older, install a newer version before continuing.
Create a Virtual Environment and Install
python3 -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install --upgrade stripe
Add stripe to your requirements.txt so the version is pinned for deployments.
Verify the Installation
pip show stripe
python3 -c "import stripe; print(stripe.VERSION)"
If the second command prints a version number, the library is ready.
Configuring the Stripe Python Client
The current way to use the Stripe Python library is through StripeClient. You create one client with your secret key, then call resources through it, such as client.v1.customers.list(). Load the key from an environment variable rather than writing it in code, so it never ends up in version control.
Store Keys in Environment Variables
export STRIPE_SECRET_KEY="sk_test_..."
export STRIPE_WEBHOOK_SECRET="whsec_..."
In production, set these in your hosting platform’s secret settings or a .env file that’s excluded from Git.
Create a StripeClient
import os
from stripe import StripeClient
client = StripeClient(os.environ["STRIPE_SECRET_KEY"])
customers = client.v1.customers.list(params={"limit": 3})
for customer in customers.data:
print(customer.id, customer.email)
If this runs without an authentication error, your keys work.
Global API Key vs StripeClient
Older tutorials set stripe.api_key = "sk_..." and call stripe.PaymentIntent.create(). That style still works, but StripeClient keeps configuration in one object, makes testing easier and supports per-request options such as a specific API version or connected account.
Stripe Python Example: Create a Payment Intent
A Payment Intent tracks a payment from start to finish, including any authentication steps such as 3D Secure. In this Stripe Python example, your server creates the Payment Intent with an amount and currency, sends its client secret to the browser, and Stripe’s front-end tools collect card details securely.
Create the Payment Intent on Your Server
intent = client.v1.payment_intents.create(params={
"amount": 2000, # amount in the smallest currency unit, so 2000 = $20.00
"currency": "usd",
"automatic_payment_methods": {"enabled": True},
"metadata": {"order_id": "1042"},
})
print(intent.id, intent.client_secret)
Send only intent.client_secret to the front end. Use Stripe.js and the Payment Element to collect payment details, so card numbers never touch your server.
Retrieve and Check Status
intent = client.v1.payment_intents.retrieve("pi_123")
print(intent.status) # e.g. requires_payment_method, processing, succeeded
Don’t mark an order as paid just because the browser redirected back. Confirm it with a webhook, covered below.
Stripe Python Checkout Session Example
Stripe Checkout is the fastest way to accept payments from a Python app, because Stripe hosts the payment page. Your code creates a Checkout Session with line items and success and cancel URLs, then redirects the customer to the session URL. It supports cards, wallets and local payment methods without extra front-end work.
Flask Example
import os
from flask import Flask, redirect
from stripe import StripeClient
app = Flask(__name__)
client = StripeClient(os.environ["STRIPE_SECRET_KEY"])
@app.post("/create-checkout-session")
def create_checkout_session():
session = client.v1.checkout.sessions.create(params={
"mode": "payment",
"line_items": [{"price": "price_123", "quantity": 1}],
"success_url": "https://example.com/success?session_id={CHECKOUT_SESSION_ID}",
"cancel_url": "https://example.com/cancel",
})
return redirect(session.url, code=303)
Create the Product and Price in the Dashboard first and paste its price_ ID. For subscriptions, set "mode": "subscription" and use a recurring price.
Django and FastAPI
The same client.v1.checkout.sessions.create() call works in a Django view or a FastAPI route. Only the routing and redirect code changes. Our guide to Stripe Checkout single page setup covers the page side, and our Stripe API integration in PHP shows the same flow for PHP projects.
Handling Stripe Webhooks in Python
Webhooks tell your Python app when something happens in Stripe, such as a successful payment, a refund or a failed subscription renewal. Your endpoint must read the raw request body, verify the Stripe-Signature header with your webhook signing secret and return a 200 response quickly, then handle the work.
Webhook Endpoint With Signature Verification
import os
import stripe
from flask import Flask, request, jsonify
app = Flask(__name__)
endpoint_secret = os.environ["STRIPE_WEBHOOK_SECRET"]
@app.post("/webhook")
def stripe_webhook():
payload = request.get_data()
sig_header = request.headers.get("Stripe-Signature")
try:
event = stripe.Webhook.construct_event(payload, sig_header, endpoint_secret)
except ValueError:
return jsonify(error="Invalid payload"), 400
except stripe.SignatureVerificationError:
return jsonify(error="Invalid signature"), 400
if event["type"] == "payment_intent.succeeded":
payment_intent = event["data"]["object"]
# fulfil the order using payment_intent["metadata"]["order_id"]
elif event["type"] == "checkout.session.completed":
session = event["data"]["object"]
# mark the order as paid
return jsonify(success=True)
Always pass the raw body. Parsing it as JSON first changes the bytes and breaks the signature check.
Test Webhooks Locally With the Stripe CLI
Stripe’s webhook quickstart shows how to forward events to your local server with the Stripe CLI. Log in, start a listener and copy the whsec_ secret it prints into STRIPE_WEBHOOK_SECRET.
stripe login
stripe listen --forward-to localhost:4242/webhook
stripe trigger payment_intent.succeeded
Newer Stripe accounts can also use “thin” events, which send a reference to the changed object instead of the full object. The quickstart covers that format if you’re building on Stripe’s newer APIs.
Testing Your Stripe Python Integration
Testing your Stripe Python integration means running every important path in a sandbox before going live. Use test API keys, Stripe’s test card numbers and the Stripe CLI to simulate successful payments, declines, 3D Secure authentication and refunds, then confirm your database and emails update correctly for each case.
Useful Test Cards
| Card number | What it simulates |
|---|---|
| 4242 4242 4242 4242 | Successful payment |
| 4000 0000 0000 0002 | Card declined |
| 4000 0025 0000 3155 | Requires 3D Secure authentication |
Scenarios to Test
Test a successful payment, a decline, an authentication challenge, a refund from the Dashboard and a webhook that arrives twice. Webhooks can be retried, so your code should ignore events it has already processed.
Handle Errors Cleanly
Wrap API calls in try blocks and catch stripe.StripeError subclasses such as CardError and InvalidRequestError. Show customers a friendly message and log the error code for your team. Our guide to Stripe API exception handling goes deeper.
Common Stripe Python Errors and Fixes
Most Stripe Python problems come from setup rather than Stripe itself. The usual culprits are installing the package into the wrong environment, mixing old and new library syntax, using a test key with live objects or verifying webhooks against a parsed body instead of the raw request.
ModuleNotFoundError: No Module Named ‘stripe’
This means Python can’t find the package in the environment you’re running. Activate your virtual environment, run pip install stripe inside it and check that your IDE or server uses the same interpreter. On servers, confirm the package is in requirements.txt.
Old Tutorial Code Fails
Very old examples use stripe.Charge.create() with tokens. Stripe now recommends Payment Intents and Checkout Sessions, which handle authentication rules such as Strong Customer Authentication in the UK and Europe.
“No Such Customer” or “No Such Price”
You’re probably using a test key with a live object ID, or the reverse. Test and live data are completely separate in Stripe.
Using Stripe With Python AI Agents
Stripe also publishes tools for AI agents built in Python. The Stripe Agent Toolkit lets agents create payment links, customers and invoices through Stripe’s API, with permissions you control. It’s useful for support bots or internal assistants, but keep humans in the loop for anything that moves money.
Stripe Agent Toolkit
The stripe-agent-toolkit package says it works with OpenAI’s Agents SDK, LangChain and CrewAI and requires Python 3.11 or later. Install it with pip install stripe-agent-toolkit and give it a restricted API key.
Keep Agents on a Short Leash
Give agent tools a restricted key with only the permissions they need, log every action and require approval before refunds or payouts. For larger custom builds, some businesses work with python development services to design and maintain secure, custom-built integrations.
FAQs
Here are answers to common questions about integrating Stripe with Python.
How do I install the Stripe Python library?
Run pip install stripe inside your project’s own virtual environment. Recent versions of the package require Python 3.9 or later, so check your version with python3 --version first. After installing, run pip show stripe to confirm the version, then add stripe to your requirements.txt file so your server installs the same version every time you deploy the app to production.
What is the Stripe Python SDK?
The Stripe Python SDK is Stripe’s official library for calling the Stripe API from Python. It’s published on PyPI as stripe and maintained openly on GitHub as stripe-python. It handles authentication, retries, pagination and error types, so you can easily create customers, payments, subscriptions and refunds with short, readable method calls instead of building and signing raw HTTP requests yourself.
Should I use StripeClient or stripe.api_key?
Use StripeClient for all new projects. It keeps your key and settings in one object, makes testing easier and supports per-request options like a specific API version or connected account. The older global style with stripe.api_key and calls like stripe.PaymentIntent.create() still works, so existing code doesn’t need an urgent rewrite, but new examples and Stripe’s own docs use the client.
How do I accept a payment with Stripe in Python?
The simplest route for most apps is Stripe Checkout. Create a Checkout Session on your server with client.v1.checkout.sessions.create(), passing line items plus success and cancel URLs, then redirect the customer to the session URL. For a custom payment form, create a Payment Intent instead and collect details with Stripe.js and the Payment Element on the front end, then confirm with a webhook.
How do I verify Stripe webhooks in Python?
Read the raw request body and the Stripe-Signature header from the request, then pass both with your webhook signing secret to stripe.Webhook.construct_event(). If the signature doesn’t match, the library raises an error and you should return a 400 response. Never parse the body as JSON before verifying, because that changes the payload bytes and makes the signature check fail every time.
How do I fix “No module named stripe”?
This error means the package isn’t installed in the Python environment that’s running your code. Activate the correct virtual environment and run pip install stripe, then check that your editor, terminal and web server all point to the same interpreter. If you’re deploying, add stripe to requirements.txt or your Pipfile so the hosting platform installs it automatically during every build.
Can I use Stripe with Django or FastAPI?
Yes. The Stripe Python library works with any Python framework, including Django, Flask and FastAPI. You create a StripeClient once, call it from your views or routes to create Checkout Sessions or Payment Intents and add a webhook route that verifies signatures. Only the routing, request handling and response code differ between frameworks, while the Stripe calls stay the same.
How do I test Stripe payments in Python without real money?
Use your test secret key, which starts with sk_test_, and Stripe’s test card numbers such as 4242 4242 4242 4242 for success and 4000 0000 0000 0002 for a decline. Use the Stripe CLI to forward webhooks to your local machine and trigger events. Test data never touches real cards and stays completely separate from your live account and balance.
Can I connect Stripe to AI agent frameworks like CrewAI?
Yes. Stripe’s official Agent Toolkit for Python supports frameworks including the OpenAI Agents SDK, LangChain and CrewAI, and it needs Python 3.11 or later. It lets agents create payment links, customers and invoices through tools you configure. Always use a restricted API key, log actions and always require human approval for refunds, payouts or anything else that moves real money.
Conclusion
A solid Stripe Python integration comes down to a few steps done carefully. Install the official library with pip install stripe in a virtual environment, keep keys in environment variables and use StripeClient for clean, testable code. Create Checkout Sessions for the quickest launch or Payment Intents for a custom payment form, and let Stripe’s front-end tools handle card details.
Webhooks are what make the integration reliable. Verify every signature against the raw body, handle duplicate events and confirm orders only after Stripe tells you a payment succeeded. Test success, decline and authentication paths with test cards and the Stripe CLI before switching to live keys. When something breaks, check the environment, key mode and webhook body first, since those cause most errors. Follow these habits and your Stripe Python code will be secure, easy to maintain and ready to grow with your product. Which part of your Stripe integration are you building first, Checkout or a custom payment form?











