fix: Stripe IDs and admin overrides
All checks were successful
Deploy to Staging / Build Images (push) Successful in 3m38s
Deploy to Staging / Deploy to Staging (push) Successful in 53s
Deploy to Staging / Verify Staging (push) Successful in 9s
Deploy to Staging / Notify Staging Ready (push) Successful in 8s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
All checks were successful
Deploy to Staging / Build Images (push) Successful in 3m38s
Deploy to Staging / Deploy to Staging (push) Successful in 53s
Deploy to Staging / Verify Staging (push) Successful in 9s
Deploy to Staging / Notify Staging Ready (push) Successful in 8s
Deploy to Staging / Notify Staging Failure (push) Has been skipped
This commit is contained in:
@@ -165,6 +165,38 @@ export class SubscriptionsService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve admin_override_ placeholder customer IDs to real Stripe customers.
|
||||
* When an admin overrides a user's tier without Stripe, a placeholder ID is stored.
|
||||
* This method creates a real Stripe customer and updates the subscription record.
|
||||
*/
|
||||
private async resolveStripeCustomerId(
|
||||
subscription: Subscription,
|
||||
email: string
|
||||
): Promise<string> {
|
||||
if (!subscription.stripeCustomerId.startsWith('admin_override_')) {
|
||||
return subscription.stripeCustomerId;
|
||||
}
|
||||
|
||||
logger.info('Replacing admin_override_ placeholder with real Stripe customer', {
|
||||
subscriptionId: subscription.id,
|
||||
userId: subscription.userId,
|
||||
});
|
||||
|
||||
const stripeCustomer = await this.stripeClient.createCustomer(email);
|
||||
|
||||
await this.repository.update(subscription.id, {
|
||||
stripeCustomerId: stripeCustomer.id,
|
||||
});
|
||||
|
||||
logger.info('Stripe customer created for admin-overridden subscription', {
|
||||
subscriptionId: subscription.id,
|
||||
stripeCustomerId: stripeCustomer.id,
|
||||
});
|
||||
|
||||
return stripeCustomer.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrade from current tier to new tier
|
||||
*/
|
||||
@@ -172,7 +204,8 @@ export class SubscriptionsService {
|
||||
userId: string,
|
||||
newTier: 'pro' | 'enterprise',
|
||||
billingCycle: 'monthly' | 'yearly',
|
||||
paymentMethodId: string
|
||||
paymentMethodId: string,
|
||||
email: string
|
||||
): Promise<Subscription> {
|
||||
try {
|
||||
logger.info('Upgrading subscription', { userId, newTier, billingCycle });
|
||||
@@ -183,12 +216,15 @@ export class SubscriptionsService {
|
||||
throw new Error('No subscription found for user');
|
||||
}
|
||||
|
||||
// Resolve admin_override_ placeholder to real Stripe customer if needed
|
||||
const stripeCustomerId = await this.resolveStripeCustomerId(currentSubscription, email);
|
||||
|
||||
// Determine price ID from environment variables
|
||||
const priceId = this.getPriceId(newTier, billingCycle);
|
||||
|
||||
// Create or update Stripe subscription
|
||||
const stripeSubscription = await this.stripeClient.createSubscription(
|
||||
currentSubscription.stripeCustomerId,
|
||||
stripeCustomerId,
|
||||
priceId,
|
||||
paymentMethodId
|
||||
);
|
||||
@@ -923,6 +959,19 @@ export class SubscriptionsService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update payment method for a user's subscription
|
||||
*/
|
||||
async updatePaymentMethod(userId: string, paymentMethodId: string, email: string): Promise<void> {
|
||||
const subscription = await this.repository.findByUserId(userId);
|
||||
if (!subscription) {
|
||||
throw new Error('No subscription found for user');
|
||||
}
|
||||
|
||||
const stripeCustomerId = await this.resolveStripeCustomerId(subscription, email);
|
||||
await this.stripeClient.updatePaymentMethod(stripeCustomerId, paymentMethodId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get invoices for a user's subscription
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user