fix stripe failing webhook (#1102)

<!--

Make sure you've read the CONTRIBUTING.md guidelines:
https://github.com/stack-auth/stack-auth/blob/dev/CONTRIBUTING.md

-->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved support for legacy Stripe subscription data handling with
fallback mechanisms.
* Enhanced error handling for missing or invalid subscription metadata
to prevent processing failures.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
BilalG1 2026-01-13 12:24:12 -08:00 committed by GitHub
parent 6f66b04914
commit ea6a8cb34f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -6,6 +6,7 @@ import { getEnvVariable, getNodeEnvironment } from "@stackframe/stack-shared/dis
import { StackAssertionError, throwErr } from "@stackframe/stack-shared/dist/utils/errors";
import Stripe from "stripe";
import { createStripeProxy, type StripeOverridesMap } from "./stripe-proxy";
import { InputJsonValue } from "@prisma/client/runtime/client";
const stripeSecretKey = getEnvVariable("STACK_STRIPE_SECRET_KEY", "");
const useStripeMock = stripeSecretKey === "sk_test_mockstripekey" && ["development", "test"].includes(getNodeEnvironment());
@ -92,6 +93,18 @@ export async function syncStripeSubscriptions(stripe: Stripe, stripeAccountId: s
}
const item = subscription.items.data[0];
const priceId = subscription.metadata.priceId as string | undefined;
// old subscriptions were created with offer metadata instead of product metadata
const productString = subscription.metadata.product as string | undefined ?? subscription.metadata.offer as string | undefined;
if (!productString) {
throw new StackAssertionError("Stripe subscription metadata missing product or offer", { subscriptionId: subscription.id });
}
let productJson: InputJsonValue;
try {
productJson = JSON.parse(productString);
} catch (error) {
throw new StackAssertionError("Invalid JSON in Stripe subscription metadata", { subscriptionId: subscription.id, productString, error });
}
await prisma.subscription.upsert({
where: {
tenancyId_stripeSubscriptionId: {
@ -101,7 +114,7 @@ export async function syncStripeSubscriptions(stripe: Stripe, stripeAccountId: s
},
update: {
status: subscription.status,
product: JSON.parse(subscription.metadata.product),
product: productJson,
quantity: item.quantity ?? 1,
currentPeriodEnd: new Date(item.current_period_end * 1000),
currentPeriodStart: new Date(item.current_period_start * 1000),
@ -112,9 +125,9 @@ export async function syncStripeSubscriptions(stripe: Stripe, stripeAccountId: s
tenancyId: tenancy.id,
customerId,
customerType,
productId: subscription.metadata.productId,
productId: subscription.metadata.productId as string | undefined ?? subscription.metadata.offerId,
priceId: priceId ?? null,
product: JSON.parse(subscription.metadata.product),
product: productJson,
quantity: item.quantity ?? 1,
stripeSubscriptionId: subscription.id,
status: subscription.status,