diff --git a/backend/app/routes/billing.py b/backend/app/routes/billing.py index 5764bf41..1a52124f 100644 --- a/backend/app/routes/billing.py +++ b/backend/app/routes/billing.py @@ -147,11 +147,11 @@ async def stripe_webhook(): logger.info("Skipping unpaid checkout session %s", session.id) return jsonify({"status": "ok"}), 200 - # metadata is a plain dict in the Stripe SDK - meta = dict(session.metadata) if session.metadata else {} - user_id = meta.get("user_id") - credits = int(meta.get("credits", 0)) - pack_id = meta.get("pack_id", "") + # metadata is a StripeObject in SDK v5 — use attribute access + meta = session.metadata + user_id = getattr(meta, "user_id", None) if meta else None + credits = int(getattr(meta, "credits", 0) or 0) if meta else 0 + pack_id = getattr(meta, "pack_id", "") if meta else "" # `or` so explicit null payment_intent falls through to session id payment_id = session.payment_intent or session.id