Skip to content

Commit 7f6c5d0

Browse files
jankeromnesroboquat
authored andcommitted
[payment] Implement a pro-ration helper method
1 parent a2b2283 commit 7f6c5d0

File tree

1 file changed

+68
-16
lines changed

1 file changed

+68
-16
lines changed

components/ee/payment-endpoint/src/chargebee/upgrade-helper.ts

Lines changed: 68 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import { injectable, inject } from "inversify";
88
import { ChargebeeProvider } from "./chargebee-provider";
9+
import { Chargebee as chargebee } from "./chargebee-types";
910
import { LogContext, log } from "@gitpod/gitpod-protocol/lib/util/logging";
1011

1112
@injectable()
@@ -22,24 +23,75 @@ export class UpgradeHelper {
2223
* @param description
2324
* @param upgradeTimestamp
2425
*/
25-
async chargeForUpgrade(userId: string, chargebeeSubscriptionId: string, amountInCents: number, description: string, upgradeTimestamp: string) {
26+
async chargeForUpgrade(
27+
userId: string,
28+
chargebeeSubscriptionId: string,
29+
amountInCents: number,
30+
description: string,
31+
upgradeTimestamp: string,
32+
) {
2633
const logContext: LogContext = { userId };
27-
const logPayload = { chargebeeSubscriptionId: chargebeeSubscriptionId, amountInCents, description, upgradeTimestamp };
34+
const logPayload = {
35+
chargebeeSubscriptionId: chargebeeSubscriptionId,
36+
amountInCents,
37+
description,
38+
upgradeTimestamp,
39+
};
2840

2941
await new Promise<void>((resolve, reject) => {
30-
log.info(logContext, 'Charge on Upgrade: Upgrade detected.', logPayload);
31-
this.chargebeeProvider.subscription.add_charge_at_term_end(chargebeeSubscriptionId, {
32-
amount: amountInCents,
33-
description
34-
}).request(function (error: any, result: any) {
35-
if (error) {
36-
log.error(logContext, 'Charge on Upgrade: error', error, logPayload);
37-
reject(error);
38-
} else {
39-
log.info(logContext, 'Charge on Upgrade: successful', logPayload);
40-
resolve();
41-
}
42-
});
42+
log.info(logContext, "Charge on Upgrade: Upgrade detected.", logPayload);
43+
this.chargebeeProvider.subscription
44+
.add_charge_at_term_end(chargebeeSubscriptionId, {
45+
amount: amountInCents,
46+
description,
47+
})
48+
.request(function (error: any, result: any) {
49+
if (error) {
50+
log.error(logContext, "Charge on Upgrade: error", error, logPayload);
51+
reject(error);
52+
} else {
53+
log.info(logContext, "Charge on Upgrade: successful", logPayload);
54+
resolve();
55+
}
56+
});
4357
});
4458
}
45-
}
59+
60+
// Returns a ratio between 0 and 1:
61+
// 0 means we've just finished the term
62+
// 1 means we still have the entire term left
63+
getCurrentTermRemainingRatio(chargebeeSubscription: chargebee.Subscription): number {
64+
if (!chargebeeSubscription.next_billing_at) {
65+
throw new Error("subscription.next_billing_at must be set.");
66+
}
67+
const now = new Date();
68+
const nextBilling = new Date(chargebeeSubscription.next_billing_at * 1000);
69+
const remainingMs = nextBilling.getTime() - now.getTime();
70+
71+
const getBillingCycleMs = (unit: chargebee.BillingPeriodUnit): number => {
72+
const previousBilling = new Date(nextBilling.getTime());
73+
switch (unit) {
74+
case "day":
75+
previousBilling.setDate(nextBilling.getDate() - 1);
76+
break;
77+
case "week":
78+
previousBilling.setDate(nextBilling.getDate() - 7);
79+
break;
80+
case "month":
81+
previousBilling.setMonth(nextBilling.getMonth() - 1);
82+
break;
83+
case "year":
84+
previousBilling.setFullYear(nextBilling.getFullYear() - 1);
85+
break;
86+
}
87+
return nextBilling.getTime() - previousBilling.getTime();
88+
};
89+
90+
const billingCycleMs =
91+
typeof chargebeeSubscription.billing_period === "number" && chargebeeSubscription.billing_period_unit
92+
? chargebeeSubscription.billing_period * getBillingCycleMs(chargebeeSubscription.billing_period_unit)
93+
: 1 * getBillingCycleMs("month");
94+
95+
return remainingMs / billingCycleMs;
96+
}
97+
}

0 commit comments

Comments
 (0)