MCPcopy
hub / github.com/simstudioai/sim / handleSubscriptionDeleted

Function handleSubscriptionDeleted

apps/sim/lib/billing/webhooks/subscription.ts:280–470  ·  view source on GitHub ↗
(
  subscription: {
    id: string
    plan: string | null
    referenceId: string
    stripeSubscriptionId: string | null
    seats?: number | null
    periodStart?: Date | null
    periodEnd?: Date | null
  },
  stripeEventId?: string
)

Source from the content-addressed store, hash-verified

278 * webhook retries from scratch.
279 */
280export async function handleSubscriptionDeleted(
281 subscription: {
282 id: string
283 plan: string | null
284 referenceId: string
285 stripeSubscriptionId: string | null
286 seats?: number | null
287 periodStart?: Date | null
288 periodEnd?: Date | null
289 },
290 stripeEventId?: string
291) {
292 const stripeSubscriptionId = subscription.stripeSubscriptionId || ''
293
294 logger.info('Processing subscription deletion', {
295 stripeEventId,
296 stripeSubscriptionId,
297 subscriptionId: subscription.id,
298 })
299
300 // Fall back to the subscription DB id when we don't have an event id
301 // (e.g. called outside the Stripe webhook context). Still dedupes a
302 // single subscription's deletion, just not event-granular.
303 const idempotencyIdentifier = stripeEventId ?? `sub:${subscription.id}`
304
305 try {
306 await stripeWebhookIdempotency.executeWithIdempotency(
307 'subscription-deleted',
308 idempotencyIdentifier,
309 async () => {
310 const totalOverage = await calculateSubscriptionOverage(subscription)
311 const stripe = requireStripeClient()
312
313 if (isEnterprise(subscription.plan)) {
314 await resetUsageForSubscription({
315 plan: subscription.plan,
316 referenceId: subscription.referenceId,
317 periodStart: subscription.periodStart ?? null,
318 periodEnd: subscription.periodEnd ?? null,
319 })
320
321 const dormantResult = await transitionOrganizationToDormantState(
322 subscription.referenceId,
323 subscription.id
324 )
325
326 logger.info('Successfully processed enterprise subscription cancellation', {
327 subscriptionId: subscription.id,
328 stripeSubscriptionId,
329 ...dormantResult,
330 })
331
332 captureServerEvent(subscription.referenceId, 'subscription_cancelled', {
333 plan: subscription.plan ?? 'unknown',
334 reference_id: subscription.referenceId,
335 })
336
337 return { totalOverage: 0, kind: 'enterprise' as const }

Callers 1

auth.tsFile · 0.90

Calls 14

requireStripeClientFunction · 0.90
isEnterpriseFunction · 0.90
captureServerEventFunction · 0.90
isSubscriptionOrgScopedFunction · 0.90
isProFunction · 0.90
infoMethod · 0.80

Tested by

no test coverage detected