Before starting this tutorial, you’ll need:
- Python 3.10 or higher installed
- A Stripe account (sign up at stripe.com)
- Your Stripe test API keys from the Stripe Dashboard
FastStripe offers several advantages over the official Stripe Python SDK:
- Self-documenting: See available parameters with descriptions in your IDE
- Generated from Stripe’s OpenAPI spec: Endpoints are built from a pinned Stripe API snapshot
- Lightweight: Small runtime built on
fastcore,fastspec, andhttpx - Consistent API: Nested Stripe resources use HTTP verb methods
(
post,get) with visible parameters
First, install FastStripe using pip:
pip install faststripeOr install the latest development version:
pip install git+https://github.com/AnswerDotAI/faststripe.gitFastStripe versions follow Stripe’s API versioning scheme (e.g.,
2025.05.28.x). Each FastStripe release is pinned to a specific Stripe
API version, ensuring:
- Stability: Your code won’t break when Stripe updates their API
- Predictability: Same behavior across all environments
- Compatibility: Choose the Stripe API version that works for your application
When you install FastStripe, you get a specific snapshot of the Stripe API that’s been tested and validated. The minor version represents non-breaking changes we add such as better higher-level APIs.
For this tutorial, use your Stripe test API key from the Stripe
Dashboard. We’ll pass it explicitly with api_key= so the setup is
visible in the code.
Use a test key while following the tutorial. Test secret keys start with
sk_test_ and should still be treated as private.
Now let’s import FastStripe and initialize it with your API key:
from faststripe.core import *
# Initialize with your Stripe test API key
sapi = StripeApi(api_key='sk_test_your_test_key_here')sapi.v1.customers.postCreate a customer
Parameters: - address (, optional): The customer’s address. Learn about
country-specific requirements for calculating
tax. -
balance (int, optional): An integer amount in cents (or local
equivalent) that represents the customer’s current balance, which affect
the customer’s future invoices. A negative amount represents a credit
that decreases the amount due on an invoice; a positive amount increases
the amount due on an invoice. - business_name (str, optional): The
customer’s business name. This may be up to 150 characters. -
cash_balance (dict, optional): Balance information and default balance
settings for this customer. - description (str, optional): An arbitrary
string that you can attach to a customer object. It is displayed
alongside the customer in the dashboard. - email (str, optional):
Customer’s email address. It’s displayed alongside the customer in your
dashboard and can be useful for searching and tracking. This may be up
to 512 characters. - expand (list, optional): Specifies which fields
in the response should be expanded. - individual_name (str, optional):
The customer’s full name. This may be up to 150 characters. -
invoice_prefix (str, optional): The prefix for the customer used to
generate unique invoice numbers. Must be 3–12 uppercase letters or
numbers. - invoice_settings (dict, optional): Default invoice settings
for this customer. - metadata (, optional): Set of key-value
pairs that you can attach to an
object. This can be useful for storing additional information about the
object in a structured format. Individual keys can be unset by posting
an empty value to them. All keys can be unset by posting an empty value
to metadata. - name (str, optional): The customer’s full name or
business name. - next_invoice_sequence (int, optional): The sequence to
be used on the customer’s next invoice. Defaults to 1. - payment_method
(str, optional) - phone (str, optional): The customer’s phone number. -
preferred_locales (list, optional): Customer’s preferred languages,
ordered by preference. - shipping (, optional): The customer’s shipping
information. Appears on invoices emailed to this customer. - source
(str, optional) - tax (dict, optional): Tax details about the
customer. - tax_exempt (str, optional): The customer’s tax exemption.
One of none, exempt, or reverse. - tax_id_data (list, optional):
The customer’s tax IDs. - test_clock (str, optional): ID of the test
clock to attach to the customer.
# Create a customer
customer = await sapi.v1.customers.post(email='user@example.com', name='John Doe')
print(customer.id, customer.email)cus_UXABX4zNYeDcJ9 user@example.com
One of FastStripe’s key advantages is that all methods include parameter documentation directly in your IDE. You can see what parameters are available without checking external docs:
# Explore available methods and their parameters
sapi.v1.customers.post?def post(
address:Unset=UNSET, balance:int=UNSET, business_name:str=UNSET, cash_balance:dict=UNSET, description:str=UNSET,
email:str=UNSET, expand:list=UNSET, individual_name:str=UNSET, invoice_prefix:str=UNSET,
invoice_settings:dict=UNSET, metadata:Unset=UNSET, name:str=UNSET, next_invoice_sequence:int=UNSET,
payment_method:str=UNSET, phone:str=UNSET, preferred_locales:list=UNSET, shipping:Unset=UNSET, source:str=UNSET,
tax:dict=UNSET, tax_exempt:str=UNSET, tax_id_data:list=UNSET, test_clock:str=UNSET
):
Create a customer
Parameters: ...
It also supports tab completion when filling in parameters!
FastStripe provides access to Stripe’s API through nested OpenAPI groups generated from the pinned Stripe spec:
# Access any Stripe resource with consistent patterns
product = await sapi.v1.products.post(name='New Product')
print(f"Created product: {product.name} with ID: {product.id}")Created product: New Product with ID: prod_UXAC1jJuFtyOx2
# Fetch existing resources
customers = await sapi.v1.customers.get(limit=3)
print(f"Found {len(customers.data)} customers")Found 3 customers
# All responses are AttrDict objects for easy dot notation access
payment_intent = await sapi.v1.payment_intents.post(amount=1000, currency='usd')
print(f"Payment intent status: {payment_intent.status}, amount: ${payment_intent.amount/100}")Payment intent status: requires_payment_method, amount: $10.0
FastStripe includes built-in utilities for handling paginated API responses, making it easy to work with large requests.
async for p in paged(sapi.v1.coupons.get, limit=5): break
print(f"Got {len(p.data)} coupons")
print(f"Has more pages: {p.has_more}")Got 5 coupons
Has more pages: True
coupons = await pages(sapi.v1.coupons.get, limit=100)
len(coupons), coupons[0](588, Coupon(id=ioULYkUY))
The pagination utilities work with any Stripe resource that supports pagination:
paged(): Async generator that yields each page from a resource APIpages(): Fetches all pages and returns the collected items
This makes it easy to process large datasets without manually handling pagination tokens.
Stripe signs webhook payloads so your app can reject fake or modified
events. FastStripe provided the parse_webhook(req) helper for this
which returns a FastStripe Event object.
In a webhook route, parse_webhook() verifies the signature before
returning the event object:
# Example inside a FastHTML/FastAPI-style route
@rt
async def webhook(req):
'Handle incoming webhooks from stripe'
evt = await sapi.parse_webhook(req)
print(evt, evt.data)For lower-level integrations, use
verify_webhook()
directly with the raw payload, Stripe signature header, and webhook
secret. parse_webhook() is usually the nicer path because it verifies
the event and converts nested Stripe data into FastStripe objects.