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

Function handleDisputeClosed

apps/sim/lib/billing/webhooks/disputes.ts:81–139  ·  view source on GitHub ↗
(event: Stripe.Event)

Source from the content-addressed store, hash-verified

79 * - 'warning_closed': Pre-dispute inquiry closed without chargeback → unblock (false alarm)
80 */
81export async function handleDisputeClosed(event: Stripe.Event): Promise<void> {
82 const dispute = event.data.object as Stripe.Dispute
83
84 // Only unblock if we won or the warning was closed without a full dispute
85 const shouldUnblock = dispute.status === 'won' || dispute.status === 'warning_closed'
86
87 if (!shouldUnblock) {
88 logger.info('Dispute resolved against us, user remains blocked', {
89 disputeId: dispute.id,
90 status: dispute.status,
91 })
92 return
93 }
94
95 const customerId = await getCustomerIdFromDispute(dispute)
96 if (!customerId) {
97 return
98 }
99
100 // Find and unblock user (Pro plans) - only if blocked for dispute, not other reasons
101 const users = await db
102 .select({ id: user.id })
103 .from(user)
104 .where(eq(user.stripeCustomerId, customerId))
105 .limit(1)
106
107 if (users.length > 0) {
108 await db
109 .update(userStats)
110 .set({ billingBlocked: false, billingBlockedReason: null })
111 .where(and(eq(userStats.userId, users[0].id), eq(userStats.billingBlockedReason, 'dispute')))
112
113 logger.info('Unblocked user after dispute resolved in our favor', {
114 disputeId: dispute.id,
115 userId: users[0].id,
116 status: dispute.status,
117 })
118 return
119 }
120
121 // Find and unblock all org members (Team/Enterprise) - consistent with payment success
122 const subs = await db
123 .select({ referenceId: subscription.referenceId })
124 .from(subscription)
125 .where(eq(subscription.stripeCustomerId, customerId))
126 .limit(1)
127
128 if (subs.length > 0) {
129 const orgId = subs[0].referenceId
130 const memberCount = await unblockOrgMembers(orgId, 'dispute')
131
132 logger.info('Unblocked all org members after dispute resolved in our favor', {
133 disputeId: dispute.id,
134 organizationId: orgId,
135 memberCount,
136 status: dispute.status,
137 })
138 }

Callers 1

auth.tsFile · 0.90

Calls 5

unblockOrgMembersFunction · 0.90
getCustomerIdFromDisputeFunction · 0.85
infoMethod · 0.80
setMethod · 0.65
eqFunction · 0.50

Tested by

no test coverage detected