fix: prevent duplicate subscriptions by validating active status in webhook and cleaning up stale records during creation
This commit is contained in:
@@ -80,6 +80,34 @@ export class StripeService {
|
||||
throw new BadRequestException('You already have an active subscription');
|
||||
}
|
||||
|
||||
// Clean up any incomplete/failed subscriptions to prevent duplicates
|
||||
// when user retries payment after a previous failure
|
||||
const staleSubscriptions = await this.prisma.agentSubscription.findMany({
|
||||
where: {
|
||||
userId,
|
||||
status: { in: ['INCOMPLETE', 'UNPAID', 'PAST_DUE'] },
|
||||
},
|
||||
});
|
||||
|
||||
if (staleSubscriptions.length > 0) {
|
||||
// Cancel stale Stripe subscriptions before deleting DB records
|
||||
for (const sub of staleSubscriptions) {
|
||||
if (!sub.stripeSubscriptionId) continue;
|
||||
try {
|
||||
await this.getStripe().subscriptions.cancel(sub.stripeSubscriptionId);
|
||||
} catch (err: any) {
|
||||
this.logger.warn(`Could not cancel stale Stripe subscription ${sub.stripeSubscriptionId}: ${err.message}`);
|
||||
}
|
||||
}
|
||||
await this.prisma.agentSubscription.deleteMany({
|
||||
where: {
|
||||
userId,
|
||||
status: { in: ['INCOMPLETE', 'UNPAID', 'PAST_DUE'] },
|
||||
},
|
||||
});
|
||||
this.logger.log(`Cleaned up ${staleSubscriptions.length} stale subscription(s) for user ${userId}`);
|
||||
}
|
||||
|
||||
// Get or create Stripe customer
|
||||
const user = await this.prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
|
||||
Reference in New Issue
Block a user