Flask integration of Stripe Checkout.
Stripe Checkout allows you to quickly handle payments with minimal development. This Flask extension allows you to build a cart and launch Checkout sessions in less than 10 lines of code.
Check out the example folder for a full example.
Install:
$ pip install flask-stripe-checkout
Setup:
from flask import Flask
from flask_stripe_checkout import StripeCheckout
app = Flask(__name__)
StripeCheckout(app)
- Create a Stripe account
- Retrieve your API key
- Register your webhook (
https://yourdomain/stripe-webhook
) and retrieve your endpoint secret
To use webhooks locally:
- Download stripe-cli
- Login with
stripe login
- Run
stripe listen --forward-to localhost:5000/stripe-webhook
Configure your app before initializing StripeCheckout:
app.config.update({
"STRIPE_API_KEY": "sk_...",
"STRIPE_WEBHOOKS_ENDPOINT_SECRET": "whsec_..."
})
Flask-Stripe-Checkout provides a current_cart
object that allows you to add Stripe's "line items" to it.
Once your cart is ready, a Checkout session can be started. The cart is stored in the session.
Add an endpoint to add items to your cart:
from flask_stripe_checkout import current_cart
@app.post('/add-to-cart')
def add_to_cart():
product = Product.get(request.values["product_id"]) # your custom logic to find products
current_cart.add(product.name, product.amount)
Once ready, redirect to checkout:
@app.post('/checkout')
def checkout():
return current_cart.checkout(success_url="/success")
Check out the API section for all available current_cart
methods.
To process the order on successful payment, listen to the Stripe webhook event checkout.session.completed:
from flask_stripe_checkout import webhook
@webhook.checkout_session_completed()
def checkout_completed(event, session):
# process order
The cart blueprint is registered by default and provides endpoints to manage the cart.
When requested normally, the cart/cart.html
template is returned (feel free to override it).
When requested with application/json
, an array of line items is returned.
This makes it very easy to use with htmx or the standard js fetch()
function.
Endpoints may be accessible through 2 different URLs:
- a REST compatible one
- another one usable directly using html forms (only using POST)
For cart pages, you can edit the layout of the pages by overriding the cart/layout.html
template.
A cart_content
block must be used.
Show the cart content
GET /cart
Update an item's quantity
PUT /cart/<item_idx>
POST /cart/<item_idx>/update
Where item_idx
is the item index in the cart.
Provide the quantity
parameter (via query string or form values).
Remove an item from the cart
DELETE /cart/<item_idx>
POST /cart/<item_idx>/remove
Where item_idx
is the item index in the cart.
Empty the cart
DELETE /cart
POST /cart/clear
Redirect to the Stripe Checkout page
POST /cart/checkout
When received, signals will be sent. Connect to these signal using webhook()
:
from flask_stripe_checkout import webhook
@webhook("charge.succeeded")
def charge_succeeded(event):
# process event
You can also quickly retrieve a stripe object:
@webhook("charge.succeeded", retrieve=stripe.Charge)
def charge_succeeded(event, charge):
# process charge
Available configuration options:
Config key | Extension argument | Description | Default |
---|---|---|---|
STRIPE_API_KEY | set stripe.api_key |
||
STRIPE_CHECKOUT_CURRENCY | currency | default currency to use when adding items using amounts | USD |
STRIPE_CHECKOUT_SESSION_OPTIONS | session_options | a dict of options to use for the checkout session. See checkout api doc | {} |
STRIPE_WEBHOOKS_ENDPOINT | webhook_endpoint | the stripe webhook endpoint url (use None to disable) |
/stripe-webhooks |
STRIPE_WEBHOOKS_ENDPOINT_SECRET | webhook_endpoint_secret | your Stripe webhook endpoint secret to validate incoming hooks | app.secret_key |
STRIPE_REGISTER_CART_BLUEPRINT | register_cart_blueprint | whether to register the cart blueprint | True |
The current_cart
object is a session-backed Cart
instance.
Attribute | Description |
---|---|
Cart.add() |
add a new CartItem . See CartItem constructor for available parameters |
Cart.update(idx, quantity) |
update the quantity for item at index |
Cart.remove(idx) |
remove item at index |
Cart.clear() |
empty the cart |
Cart.line_items |
the list of items |
Cart.total |
total cart amount in cents |
Cart.formatted_total |
totgal cart amount formatted using format_amount() |
Cart.create_checkout_session(**session_options) |
create the stripe.checkout.Session object |
Cart.checkout(**session_options) |
create the checkout session and returns a redirect response to the checkout url |
CartItem
is a dict representing a Stripe line item object.
Add an item using a Price
:
current_cart.add(price=price_id, quantity=1)
Add an item using a Product
and a custom amount:
current_cart.add(product=product_id, amount=amount, quantity=1, currency=None)
Add a product on the fly:
current_cart.add(product_name, amount, quantity=1, currency=None)
currency
defaults to the one provided using STRIPE_CHECKOUT_CURRENCY
.
You can provide any other line items options.
Special properties on CartItem
objects:
Attribute | Description |
---|---|
CartItem.price |
retrieve the Price object associated to the line item or None |
CartItem.product |
retrieve the Product object associated to the line item or None |
CartItem.description |
retrieve the product description when associated to a product or the product name from price_data |
CartItem.currency |
either from the price or from the line item directly |
CartItem.quantity |
|
CartItem.unit_amount |
either from the price or from the line item directly |
CartItem.formatted_unit_amount |
the unit_amount formatted using format_amount() |
CartItem.amount |
the unit_amount multiplied by the quantity |
CartItem.formatted_amount |
the amount formatted using format_amount() |
Format an amount with the currency sign.
format_amount(amount, currency)
Available as a filter in templates:
{{ amount|format_amount(currency) }}
A limited number of currencies are supported. Add support for your own currency:
from flask_stripe_checkout import CURRENCIES
CURRENCIES["USD"] = lambda amount: f"US${amount:,.2f}"