(event: Stripe.Event)
| 21 | * Handles charge.dispute.created - blocks the responsible user |
| 22 | */ |
| 23 | export async function handleChargeDispute(event: Stripe.Event): Promise<void> { |
| 24 | const dispute = event.data.object as Stripe.Dispute |
| 25 | |
| 26 | const customerId = await getCustomerIdFromDispute(dispute) |
| 27 | if (!customerId) { |
| 28 | logger.warn('No customer ID found in dispute', { disputeId: dispute.id }) |
| 29 | return |
| 30 | } |
| 31 | |
| 32 | // Find user by stripeCustomerId (Pro plans) |
| 33 | const users = await db |
| 34 | .select({ id: user.id }) |
| 35 | .from(user) |
| 36 | .where(eq(user.stripeCustomerId, customerId)) |
| 37 | .limit(1) |
| 38 | |
| 39 | if (users.length > 0) { |
| 40 | await db |
| 41 | .update(userStats) |
| 42 | .set({ billingBlocked: true, billingBlockedReason: 'dispute' }) |
| 43 | .where(eq(userStats.userId, users[0].id)) |
| 44 | |
| 45 | logger.warn('Blocked user due to dispute', { |
| 46 | disputeId: dispute.id, |
| 47 | userId: users[0].id, |
| 48 | }) |
| 49 | return |
| 50 | } |
| 51 | |
| 52 | // Find subscription by stripeCustomerId (Team/Enterprise) |
| 53 | const subs = await db |
| 54 | .select({ referenceId: subscription.referenceId }) |
| 55 | .from(subscription) |
| 56 | .where(eq(subscription.stripeCustomerId, customerId)) |
| 57 | .limit(1) |
| 58 | |
| 59 | if (subs.length > 0) { |
| 60 | const orgId = subs[0].referenceId |
| 61 | const memberCount = await blockOrgMembers(orgId, 'dispute') |
| 62 | |
| 63 | if (memberCount > 0) { |
| 64 | logger.warn('Blocked all org members due to dispute', { |
| 65 | disputeId: dispute.id, |
| 66 | organizationId: orgId, |
| 67 | memberCount, |
| 68 | }) |
| 69 | } |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | /** |
| 74 | * Handles charge.dispute.closed - unblocks user if dispute was won or warning closed |
no test coverage detected