Skip to content

Commit 1bda477

Browse files
jankeromnesroboquat
authored andcommitted
[server] When deleting a user account, also cancel any individual Stripe subscription
1 parent fd9d1e8 commit 1bda477

File tree

1 file changed

+24
-7
lines changed

1 file changed

+24
-7
lines changed

components/server/ee/src/user/user-deletion-service.ts

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,16 @@ import { injectable, inject } from "inversify";
88
import { UserDeletionService } from "../../../src/user/user-deletion-service";
99
import { SubscriptionService } from "@gitpod/gitpod-payment-endpoint/lib/accounting/subscription-service";
1010
import { Plans } from "@gitpod/gitpod-protocol/lib/plans";
11+
import { AttributionId } from "@gitpod/gitpod-protocol/lib/attribution";
1112
import { ChargebeeService } from "./chargebee-service";
13+
import { StripeService } from "./stripe-service";
1214
import { TeamSubscriptionService } from "@gitpod/gitpod-payment-endpoint/lib/accounting";
1315
import { log } from "@gitpod/gitpod-protocol/lib/util/logging";
1416

1517
@injectable()
1618
export class UserDeletionServiceEE extends UserDeletionService {
1719
@inject(ChargebeeService) protected readonly chargebeeService: ChargebeeService;
20+
@inject(StripeService) protected readonly stripeService: StripeService;
1821
@inject(SubscriptionService) protected readonly subscriptionService: SubscriptionService;
1922
@inject(TeamSubscriptionService) protected readonly teamSubscriptionService: TeamSubscriptionService;
2023

@@ -27,14 +30,14 @@ export class UserDeletionServiceEE extends UserDeletionService {
2730
const errors = [];
2831
if (this.config.enablePayment) {
2932
const now = new Date();
30-
const subscriptions = await this.subscriptionService.getNotYetCancelledSubscriptions(
33+
const chargebeeSubscriptions = await this.subscriptionService.getNotYetCancelledSubscriptions(
3134
user,
3235
now.toISOString(),
3336
);
34-
for (const subscription of subscriptions) {
37+
for (const chargebeeSubscription of chargebeeSubscriptions) {
3538
try {
36-
const planId = subscription.planId!;
37-
const paymentReference = subscription.paymentReference;
39+
const planId = chargebeeSubscription.planId!;
40+
const paymentReference = chargebeeSubscription.paymentReference;
3841
if (Plans.isFreeNonTransientPlan(planId)) {
3942
// only delete those plans that are persisted in the DB
4043
await this.subscriptionService.unsubscribe(user.id, now.toISOString(), planId);
@@ -58,8 +61,8 @@ export class UserDeletionServiceEE extends UserDeletionService {
5861
throw new Error("Cannot delete user subscription from GitHub");
5962
} else {
6063
// cancel Chargebee subscriptions
61-
const subscriptionId = subscription.uid;
62-
const chargebeeSubscriptionId = subscription.paymentReference!;
64+
const subscriptionId = chargebeeSubscription.uid;
65+
const chargebeeSubscriptionId = chargebeeSubscription.paymentReference!;
6366
await this.chargebeeService.cancelSubscription(
6467
chargebeeSubscriptionId,
6568
{ userId: user.id },
@@ -69,9 +72,23 @@ export class UserDeletionServiceEE extends UserDeletionService {
6972
}
7073
} catch (error) {
7174
errors.push(error);
72-
log.error("Error cancelling subscription", error, { subscription });
75+
log.error("Error cancelling Chargebee user subscription", error, {
76+
subscription: chargebeeSubscription,
77+
});
7378
}
7479
}
80+
// Also cancel any usage-based (Stripe) subscription
81+
const subscriptionId = await this.stripeService.findUncancelledSubscriptionByAttributionId(
82+
AttributionId.render({ kind: "user", userId: user.id }),
83+
);
84+
try {
85+
if (subscriptionId) {
86+
await this.stripeService.cancelSubscription(subscriptionId);
87+
}
88+
} catch (error) {
89+
errors.push(error);
90+
log.error("Error cancelling Stripe user subscription", error, { subscriptionId });
91+
}
7592
}
7693

7794
await super.deleteUser(id);

0 commit comments

Comments
 (0)