#diezler
1 messages · Page 1 of 1 (latest)
My webhook + models
@router.post("/webhook")
async def stripe_webhook(event: dict, request: Request, stripe_signature=Header(None)):
webhook_secret = os.getenv("WEBHOOK_SECRET")
raw_body = await request.body()
try:
event = stripe.Webhook.construct_event(
raw_body, stripe_signature, webhook_secret
)
except ValueError as e:
# Invalid payload
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid payload.")
except stripe.error.SignatureVerificationError as e:
# Invalid signature
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="Invalid signature.")
# Handle the checkout.session.completed event
if event["type"] == "checkout.session.completed":
session = event["data"]["object"]
# Fulfill the purchase...
handle_checkout_session(session)
return "Success"
class StripeCustomer(Base):
__tablename__ = "stripe_customers"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
user_id = Column(Integer, ForeignKey('users.id'))
stripeCustomerId = Column(String(255), nullable=False)
stripeSubscriptionId = Column(String(255), nullable=False)
user = relationship('User', back_populates='stripe_customer')
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True, autoincrement=True)
google_sub = Column(String, unique=True, nullable=True)
username = Column(String, unique=True)
email = Column(String, unique=True)
hashed_password = Column(String)
stripe_customer = relationship('StripeCustomer', back_populates='user')
Where should i create the stripe user or fetch an existing user? And how can i pass it into the checkout and check if a user subscription is active?
clueless how I would track the status of the subscription (creating stripe user / getting sub id)
What part of this are you having issues with specifically?
You configuration broadly seems to make sense, you'd track these new subscriptions using those checkout.session.completed events you're monitoring
Where should i create the stripe user or fetch an existing user?
For what purpose? WHat are you trying to do?
And how can i pass it into the checkout and check if a user subscription is active?
This suggests you're trying to create an additional subscription for an existing customer, which you'd provide while creating the checkout session usingcustomerand the stripe customer ID
I am clueless at which point I should create the stripe customer to listen for the subscription and how i later can check if a subscription is active or canceled
Would i create the stripe customer in the same turn that i create my regular db user?
If you don't already have a customer, Checkout will create one for your for the new subscription
Maybe, not necessarily, it depends on your business logic
how i later can check if a subscription is active or canceled
In what context? If you have the subscription ID you can retrieve it. If you have a customer ID, you can list their subscriptions and inspect those. WHat exactly are you trying to do?
You should be listening to webhooks to get notification about changes to subscriptions, though: https://stripe.com/docs/billing/subscriptions/webhooks
I know the webhooks, but what would be the best way to check for the status. Lets say I have an endpoint and i want the user only be able to use it if their subscription is active
Could this work?(just an outline)
from fastapi import FastAPI, HTTPException
from fastapi.responses import JSONResponse
from pydantic import BaseModel
import stripe
app = FastAPI()
# Replace with your Stripe secret key
stripe.api_key = "your_stripe_secret_key"
class CreateUserRequest(BaseModel):
username: str
email: str
class SubscriptionStatusResponse(BaseModel):
subscription_id: str
status: str
@app.post("/create_user")
def create_user(user_data: CreateUserRequest):
user_id = "123"
# Create a Stripe customer
stripe_customer = stripe.Customer.create(
email=user_data.email,
name=user_data.username,
description=f"App user ID: {user_id}"
)
link_stripe_customer_to_user(user_id, stripe_customer.id)
return {"message": "User created successfully", "user_id": user_id}
def link_stripe_customer_to_user(user_id: str, stripe_customer_id: str):
pass
@app.post("/check_subscription_status")
def check_subscription_status(user_id: str):
# Retrieve the Stripe customer ID associated with the app user
stripe_customer_id = get_stripe_customer_id(user_id)
if stripe_customer_id is None:
raise HTTPException(
status_code=404,
detail="Stripe customer not found for the given user ID"
)
# Retrieve the customer's subscriptions from Stripe
subscriptions = stripe.Subscription.list(customer=stripe_customer_id)
# For simplicity, we'll assume the user has only one subscription
if subscriptions.data:
subscription = subscriptions.data[0]
return SubscriptionStatusResponse(
subscription_id=subscription.id,
status=subscription.status
)
else:
return SubscriptionStatusResponse(
subscription_id=None,
status="No active subscription"
)
def get_stripe_customer_id(user_id: str):
return "stripe_customer_id_for_user_" + user_id
It could, depend on what you need to check in that subscription list response, yea
that seems to be looking at only the first list result (data[0]) and using that status, so consider whether you may have multiple subscriptions and how you'd handle that
Ok, then sure
Would it be unsafe to store the sub satus directly in the db, so I can avoid to fetch the stripe endpoint everytime? I would update the status with the webhook events.
You could cache it locally, sure!