MCPcopy Index your code
hub / github.com/simstudioai/sim / handleInvoicePaymentFailed

Function handleInvoicePaymentFailed

apps/sim/lib/billing/webhooks/invoices.ts:877–976  ·  view source on GitHub ↗
(event: Stripe.Event)

Source from the content-addressed store, hash-verified

875 * This is triggered when a user's payment fails for any invoice (subscription or overage)
876 */
877export async function handleInvoicePaymentFailed(event: Stripe.Event) {
878 try {
879 const invoice = event.data.object as Stripe.Invoice
880
881 await stripeWebhookIdempotency.executeWithIdempotency(
882 'invoice-payment-failed',
883 event.id,
884 async () => {
885 const resolvedInvoice = await resolveInvoiceSubscription(invoice, 'invoice.payment_failed')
886 if (!resolvedInvoice) {
887 return
888 }
889
890 const { invoiceType, resolutionSource, stripeSubscriptionId, sub } = resolvedInvoice
891
892 const customerId = invoice.customer
893 if (!customerId || typeof customerId !== 'string') {
894 logger.error('Invalid customer ID on invoice', {
895 invoiceId: invoice.id,
896 customer: invoice.customer,
897 })
898 return
899 }
900
901 const failedAmount = invoice.amount_due / 100
902 const billingPeriod = invoice.metadata?.billingPeriod || 'unknown'
903 const attemptCount = invoice.attempt_count ?? 1
904
905 logger.warn('Invoice payment failed', {
906 invoiceId: invoice.id,
907 customerId,
908 failedAmount,
909 billingPeriod,
910 attemptCount,
911 customerEmail: invoice.customer_email,
912 hostedInvoiceUrl: invoice.hosted_invoice_url,
913 invoiceType: invoiceType ?? 'subscription',
914 resolutionSource,
915 })
916
917 if (attemptCount >= 1) {
918 logger.error('Payment failure - blocking users', {
919 customerId,
920 attemptCount,
921 invoiceId: invoice.id,
922 invoiceType: invoiceType ?? 'subscription',
923 resolutionSource,
924 stripeSubscriptionId,
925 })
926
927 if (await isSubscriptionOrgScoped(sub)) {
928 const memberCount = await blockOrgMembers(sub.referenceId, 'payment_failed')
929 logger.info('Blocked org members due to payment failure', {
930 invoiceType: invoiceType ?? 'subscription',
931 memberCount,
932 organizationId: sub.referenceId,
933 })
934 } else {

Callers 2

auth.tsFile · 0.90
invoices.test.tsFile · 0.90

Calls 10

isSubscriptionOrgScopedFunction · 0.90
blockOrgMembersFunction · 0.90
sendPaymentFailureEmailsFunction · 0.85
errorMethod · 0.80
infoMethod · 0.80
warnMethod · 0.65
setMethod · 0.65
eqFunction · 0.50

Tested by

no test coverage detected