Integrating FastAPI with Stripe offers a powerful combination of high-speed API development and robust payment processing capabilities. Here are the necessary details to get started.
1. Setting up stripe account
Before you can integrate Stripe with FastAPI, you need to set up a Stripe account. Here are the basic steps:
Go to the Stripe website (https://stripe.com) and sign up for an account.
In your Stripe dashboard, you will find your API keys. You will need these keys to make API requests. Stripe provides both a test mode and live mode. During development, use the test API keys to avoid real transactions.
2. Install the requirements:
We need to install the basic third party packages to start a fastapi app and to accept payment by stripe. Let's install the below packages with pip install -r requirements.txt
fastapi==0.101.1
uvicorn==0.23.2
python-dotenv==1.0.0
stripe==6.6.0
Let's keep the secrets in the .env file. This file should never be pushed to version control systems.
BASE_URL=http://127.0.0.1:8000
STRIPE_PUBLISHABLE_KEY=pk_test_51partyyy
STRIPE_SECRET_KEY=sk_test_51party-returns
Finally, let's have the code to interact with Stripe using FastAPI:
import os
import json
import stripe
from fastapi import FastAPI, responses, Request, HTTPException
from dotenv import load_dotenv
from pathlib import Path
env_path = Path(".") / ".env"
load_dotenv(dotenv_path=env_path)
app = FastAPI()
stripe.api_key = os.getenv("STRIPE_SECRET_KEY")
@app.get("/checkout/")
async def create_checkout_session(price: int = 10):
checkout_session = stripe.checkout.Session.create(
line_items=[
{
"price_data": {
"currency": "usd",
"product_data": {
"name": "FastAPI Stripe Checkout",
},
"unit_amount": price * 100,
},
"quantity": 1,
}
],
metadata={
"user_id": 3,
"email": "[email protected]",
"request_id": 1234567890
},
mode="payment",
success_url=os.getenv("BASE_URL") + "/success/",
cancel_url=os.getenv("BASE_URL") + "/cancel/",
customer_email="[email protected]",
)
return responses.RedirectResponse(checkout_session.url, status_code=303)
@app.post("/webhook/")
async def stripe_webhook(request: Request):
payload = await request.body()
event = None
try:
event = stripe.Event.construct_from(json.loads(payload), stripe.api_key)
except ValueError as e:
print("Invalid payload")
raise HTTPException(status_code=400, detail="Invalid payload")
except stripe.error.SignatureVerificationError as e:
print("Invalid signature")
raise HTTPException(status_code=400, detail="Invalid signature")
print("event received is", event)
if event["type"] == "checkout.session.completed":
payment = event["data"]["object"]
amount = payment["amount_total"]
currency = payment["currency"]
user_id = payment["metadata"]["user_id"] # get custom user id from metadata
user_email = payment["customer_details"]["email"]
user_name = payment["customer_details"]["name"]
order_id = payment["id"]
# save to db
# send email in background task
return {}
That's it, now you can visit: http://127.0.0.1:8000/checkout/?price=60 You can make the payment with the card id: 4242 4242 4242 4242 on any future date and any cvv. This is a test card btw. Once you complete the payment, you would get a webhook call at the webhook endpoint. To get webhook calls in local you can route them through ngrok. Watch the video to see it in action.
Brige the gap between Tutorial hell and Industry. We want to bring in the culture of Clean Code, Test Driven Development.
We know, we might make it hard for you but definitely worth the efforts.
© Copyright 2022-23 Team FastAPITutorial