feat: Sync Stripe subscription period end and cancellation status with local records.

This commit is contained in:
pradeepkumar
2026-03-14 23:44:06 +05:30
parent 4e602abf49
commit 2c0d0f0aeb
2 changed files with 75 additions and 16 deletions

View File

@@ -42,14 +42,19 @@ export class StripeController {
@Post('create-checkout-session')
@ApiBearerAuth()
@ApiOperation({ summary: 'Create a Stripe Checkout session for subscription' })
@ApiOperation({
summary: 'Create a Stripe Checkout session for subscription',
})
@HttpCode(HttpStatus.OK)
async createCheckoutSession(
@CurrentUser() user: any,
@Body() dto: CreateCheckoutDto,
) {
const frontendUrl = this.configService.get<string>('app.frontendUrl') || 'http://localhost:3000';
const successUrl = dto.successUrl || `${frontendUrl}/agent/settings/billings/confirmation`;
const frontendUrl =
this.configService.get<string>('app.frontendUrl') ||
'http://localhost:3000';
const successUrl =
dto.successUrl || `${frontendUrl}/agent/settings/billings/confirmation`;
const cancelUrl = dto.cancelUrl || `${frontendUrl}/agent/settings/billings`;
return this.stripeService.createCheckoutSession(
@@ -73,7 +78,9 @@ export class StripeController {
throw new BadRequestException('No active subscription found');
}
const returnUrl = dto.returnUrl || `${this.configService.get<string>('app.frontendUrl') || 'http://localhost:3000'}/agent/settings/billings`;
const returnUrl =
dto.returnUrl ||
`${this.configService.get<string>('app.frontendUrl') || 'http://localhost:3000'}/agent/settings/billings`;
return this.stripeService.createBillingPortalSession(
subscription.stripeCustomerId,
returnUrl,
@@ -85,7 +92,35 @@ export class StripeController {
@ApiOperation({ summary: 'Get current user subscription status' })
async getSubscription(@CurrentUser() user: any) {
const subscription = await this.subscriptionService.getActivePlan(user.id);
return subscription || null;
if (!subscription) return null;
// Sync from Stripe if key fields are missing
if (
subscription.stripeSubscriptionId &&
(!subscription.currentPeriodEnd ||
subscription.cancelAtPeriodEnd === null)
) {
try {
const stripeSub = await this.stripeService.getSubscription(
subscription.stripeSubscriptionId,
);
const updated = await this.subscriptionService.updateSubscriptionStatus(
subscription.stripeSubscriptionId,
subscription.status,
{
currentPeriodEnd: new Date(
stripeSub.items.data[0].current_period_end * 1000,
),
cancelAtPeriodEnd: stripeSub.cancel_at_period_end,
},
);
return updated;
} catch {
// Fall through to return existing data
}
}
return subscription;
}
@Post('cancel-subscription')
@@ -98,12 +133,20 @@ export class StripeController {
throw new BadRequestException('No active subscription found');
}
await this.stripeService.cancelSubscription(subscription.stripeSubscriptionId, true);
const stripeSubscription = await this.stripeService.cancelSubscription(
subscription.stripeSubscriptionId,
true,
);
return this.subscriptionService.updateSubscriptionStatus(
subscription.stripeSubscriptionId,
'ACTIVE',
{ cancelAtPeriodEnd: true },
{
cancelAtPeriodEnd: true,
currentPeriodEnd: new Date(
stripeSubscription.items.data[0].current_period_end * 1000,
),
},
);
}