feat(billing): sync catalog price edits to Stripe + re-price live customers
Editing a catalog amount now propagates beyond MongoDB. Stripe Prices are immutable, so each changed currency mints a fresh Stripe Price at the new amount, overwrites the cached stripePriceIds[currency] (which also fixes the stale-price bug for new subscriptions), and repoints every live subscription on that (row, currency) onto it with proration_behavior 'none' — the new amount takes effect at the customer's next billing cycle, no mid-cycle charge. The per-seat snapshot is refreshed so MRR reflects the go-forward rate. Before committing the edit, the operator sees a warning with the affected customer count, driven by a new GET /prices/:id/impact endpoint. Per-sub failures are logged, never fatal; Stripe-disabled rows still re-snapshot.
This commit is contained in:
@@ -114,6 +114,21 @@ export class StripeClient {
|
||||
await this.stripe.subscriptions.update(subscriptionId, { items: [{ id: itemId, quantity }] })
|
||||
}
|
||||
|
||||
// Repoint a subscription's line item at a different Price. Stripe Prices are
|
||||
// immutable, so a catalog "price change" means minting a new Price and moving
|
||||
// live subscriptions onto it. proration_behavior 'none' → no mid-cycle charge
|
||||
// or credit; the new amount takes effect at the next renewal. Quantity is
|
||||
// preserved (we only swap the price).
|
||||
async updateSubscriptionPrice(subscriptionId: string, priceId: string): Promise<void> {
|
||||
const sub = await this.stripe.subscriptions.retrieve(subscriptionId)
|
||||
const itemId = sub.items.data[0]?.id
|
||||
if (!itemId) throw new Error(`Stripe subscription ${subscriptionId} has no line items`)
|
||||
await this.stripe.subscriptions.update(subscriptionId, {
|
||||
items: [{ id: itemId, price: priceId }],
|
||||
proration_behavior: 'none',
|
||||
})
|
||||
}
|
||||
|
||||
async cancelSubscription(subscriptionId: string): Promise<void> {
|
||||
await this.stripe.subscriptions.cancel(subscriptionId)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user