diff options
| author | Fuwn <[email protected]> | 2026-02-08 08:09:04 -0800 |
|---|---|---|
| committer | Fuwn <[email protected]> | 2026-02-08 08:09:04 -0800 |
| commit | 2bbe11a56b3df971bcc15b56da4988cfe624fd6e (patch) | |
| tree | a8962a4bc3967d9eaa88bbf813de1d5f679e7018 /apps/web/app/api/billing | |
| parent | debug: add webhook signature verification logging (diff) | |
| download | asa.news-2bbe11a56b3df971bcc15b56da4988cfe624fd6e.tar.xz asa.news-2bbe11a56b3df971bcc15b56da4988cfe624fd6e.zip | |
fix: invoice.paid handler now retrieves subscription for correct tier resolution
Diffstat (limited to 'apps/web/app/api/billing')
| -rw-r--r-- | apps/web/app/api/billing/webhook/route.ts | 29 |
1 files changed, 13 insertions, 16 deletions
diff --git a/apps/web/app/api/billing/webhook/route.ts b/apps/web/app/api/billing/webhook/route.ts index dc87249..37944c2 100644 --- a/apps/web/app/api/billing/webhook/route.ts +++ b/apps/web/app/api/billing/webhook/route.ts @@ -116,19 +116,20 @@ async function handleInvoicePaymentFailed(invoice: Stripe.Invoice) { async function handleInvoicePaid(invoice: Stripe.Invoice) { const stripeCustomerIdentifier = invoice.customer as string - const lineItem = invoice.lines?.data?.[0] - const priceIdentifier = (lineItem as unknown as { price?: { id?: string } } | undefined)?.price?.id - const developerPriceIdentifiers = [ - process.env.STRIPE_DEVELOPER_MONTHLY_PRICE_IDENTIFIER, - process.env.STRIPE_DEVELOPER_YEARLY_PRICE_IDENTIFIER, - ] - const tier = - priceIdentifier && developerPriceIdentifiers.includes(priceIdentifier) - ? "developer" - : "pro" + const invoiceRecord = invoice as unknown as Record<string, unknown> + const subscriptionIdentifier = + typeof invoiceRecord.subscription === "string" + ? invoiceRecord.subscription + : (invoiceRecord.subscription as { id?: string } | null)?.id + + if (!subscriptionIdentifier) return + + const subscription = await getStripe().subscriptions.retrieve( + subscriptionIdentifier + ) await updateBillingState(stripeCustomerIdentifier, { - tier, + tier: determineTierFromSubscription(subscription), stripe_subscription_status: "active", }) } @@ -144,7 +145,6 @@ export async function POST(request: Request) { const signature = request.headers.get("stripe-signature") if (!signature) { - console.error("webhook: missing stripe-signature header") return NextResponse.json({ error: "missing signature" }, { status: 400 }) } @@ -156,10 +156,7 @@ export async function POST(request: Request) { signature, process.env.STRIPE_WEBHOOK_SECRET! ) - } catch (verificationError) { - console.error("webhook: signature verification failed:", verificationError) - console.error("webhook: secret defined:", !!process.env.STRIPE_WEBHOOK_SECRET) - console.error("webhook: body length:", body.length) + } catch { return NextResponse.json({ error: "invalid signature" }, { status: 400 }) } |