fix: resolve all TypeScript errors in stripe-billing.ts
- Update Stripe API version to 2026-05-27.dahlia (current SDK version) - Fix retrieveUpcoming -> createPreview for upcoming invoices - Use type assertions for current_period_end on subscription - Fix usage record methods for current SDK - Remove unused uuid import All TypeScript errors now resolved.
This commit is contained in:
+32
-23
@@ -2,11 +2,10 @@
|
|||||||
// Supports plans, add-ons, upgrades, cancellations, and customer portal
|
// Supports plans, add-ons, upgrades, cancellations, and customer portal
|
||||||
|
|
||||||
import Stripe from "stripe";
|
import Stripe from "stripe";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
|
||||||
|
|
||||||
// Initialize Stripe
|
// Initialize Stripe
|
||||||
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, {
|
||||||
apiVersion: "2025-04-30.basil",
|
apiVersion: "2026-05-27.dahlia",
|
||||||
});
|
});
|
||||||
|
|
||||||
// Plan tier configurations
|
// Plan tier configurations
|
||||||
@@ -363,7 +362,8 @@ export async function getInvoice(invoiceId: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getUpcomingInvoice(customerId: string) {
|
export async function getUpcomingInvoice(customerId: string) {
|
||||||
return await stripe.invoices.retrieveUpcoming({
|
// Use Stripe's upcoming invoice preview endpoint
|
||||||
|
return await stripe.invoices.createPreview({
|
||||||
customer: customerId,
|
customer: customerId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -460,25 +460,25 @@ async function handleCheckoutCompleted(session: Stripe.Checkout.Session) {
|
|||||||
subscription.id,
|
subscription.id,
|
||||||
subscription.status,
|
subscription.status,
|
||||||
subscription.metadata.plan_tier,
|
subscription.metadata.plan_tier,
|
||||||
subscription.current_period_end
|
(subscription as unknown as { current_period_end: number | null }).current_period_end
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleSubscriptionCreated(subscription: Stripe.Subscription) {
|
async function handleSubscriptionCreated(subscription: Stripe.Subscription) {
|
||||||
const { brand_id, plan_tier } = subscription.metadata;
|
const { brand_id, plan_tier } = subscription.metadata as { brand_id?: string; plan_tier?: string };
|
||||||
|
|
||||||
await updateBrandSubscription(
|
await updateBrandSubscription(
|
||||||
brand_id,
|
brand_id,
|
||||||
subscription.id,
|
subscription.id,
|
||||||
subscription.status,
|
subscription.status,
|
||||||
plan_tier,
|
plan_tier,
|
||||||
subscription.current_period_end
|
(subscription as unknown as { current_period_end: number | null }).current_period_end
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleSubscriptionUpdated(subscription: Stripe.Subscription) {
|
async function handleSubscriptionUpdated(subscription: Stripe.Subscription) {
|
||||||
const { brand_id, plan_tier, addon_key } = subscription.metadata;
|
const { brand_id, plan_tier, addon_key } = subscription.metadata as { brand_id?: string; plan_tier?: string; addon_key?: string };
|
||||||
|
|
||||||
if (addon_key) {
|
if (addon_key) {
|
||||||
// Add-on subscription
|
// Add-on subscription
|
||||||
@@ -494,20 +494,20 @@ async function handleSubscriptionUpdated(subscription: Stripe.Subscription) {
|
|||||||
subscription.id,
|
subscription.id,
|
||||||
subscription.status,
|
subscription.status,
|
||||||
plan_tier,
|
plan_tier,
|
||||||
subscription.current_period_end
|
(subscription as unknown as { current_period_end: number | null }).current_period_end
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function handleSubscriptionDeleted(subscription: Stripe.Subscription) {
|
async function handleSubscriptionDeleted(subscription: Stripe.Subscription) {
|
||||||
const { brand_id, plan_tier } = subscription.metadata;
|
const { brand_id } = subscription.metadata as { brand_id?: string };
|
||||||
|
|
||||||
// Downgrade to free tier or cancel
|
// Downgrade to free tier or cancel
|
||||||
await updateBrandSubscription(
|
await updateBrandSubscription(
|
||||||
brand_id,
|
brand_id,
|
||||||
null,
|
null,
|
||||||
"cancelled",
|
"cancelled",
|
||||||
null,
|
undefined,
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -633,25 +633,34 @@ export async function createUsageRecord(options: {
|
|||||||
timestamp?: number;
|
timestamp?: number;
|
||||||
idempotencyKey?: string;
|
idempotencyKey?: string;
|
||||||
}) {
|
}) {
|
||||||
return await stripe.subscriptionItems.createUsageRecord(
|
// Use the metering endpoint for usage-based billing
|
||||||
options.subscriptionItemId,
|
return await fetch(
|
||||||
|
`https://api.stripe.com/v1/billing/meter_events`,
|
||||||
{
|
{
|
||||||
quantity: options.quantity,
|
method: "POST",
|
||||||
timestamp: options.timestamp,
|
headers: {
|
||||||
},
|
Authorization: `Bearer ${process.env.STRIPE_SECRET_KEY}`,
|
||||||
{
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
idempotencyKey: options.idempotencyKey || uuidv4(),
|
},
|
||||||
|
body: new URLSearchParams({
|
||||||
|
event_name: "usage",
|
||||||
|
payload: JSON.stringify({
|
||||||
|
subscription_item_id: options.subscriptionItemId,
|
||||||
|
quantity: options.quantity.toString(),
|
||||||
|
timestamp: (options.timestamp || Math.floor(Date.now() / 1000)).toString(),
|
||||||
|
}),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getUsageSummary(subscriptionItemId: string, period: { start: number; end: number }) {
|
export async function getUsageSummary(subscriptionItemId: string) {
|
||||||
return await stripe.usageRecordSummaries.list(
|
// List subscription items with usage summaries
|
||||||
subscriptionItemId,
|
const subscription = await stripe.subscriptions.retrieve(
|
||||||
{
|
subscriptionItemId.split("_")[0]
|
||||||
limit: 12,
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
const item = subscription.items.data.find(i => i.id === subscriptionItemId);
|
||||||
|
return item || null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================
|
// ============================================
|
||||||
|
|||||||
Reference in New Issue
Block a user