2021-07-28 15:45:30 +00:00
|
|
|
import { getEndpoint, getPaymentsUrl } from 'utils/common/apiUtil';
|
2021-08-14 11:39:09 +00:00
|
|
|
import { getToken } from 'utils/common/key';
|
2021-05-30 16:56:48 +00:00
|
|
|
import { setData, LS_KEYS } from 'utils/storage/localStorage';
|
2021-07-18 16:10:11 +00:00
|
|
|
import { convertToHumanReadable } from 'utils/billingUtil';
|
2021-03-09 16:23:13 +00:00
|
|
|
import HTTPService from './HTTPService';
|
2021-06-12 17:14:21 +00:00
|
|
|
import { logError } from 'utils/sentry';
|
2021-07-28 15:45:30 +00:00
|
|
|
import { getPaymentToken } from './userService';
|
2021-05-29 06:27:52 +00:00
|
|
|
|
2021-03-09 16:23:13 +00:00
|
|
|
const ENDPOINT = getEndpoint();
|
2021-04-06 13:43:11 +00:00
|
|
|
|
2021-08-14 10:05:48 +00:00
|
|
|
enum PaymentActionType {
|
|
|
|
Buy = 'buy',
|
|
|
|
Update = 'update',
|
2021-07-28 15:45:30 +00:00
|
|
|
}
|
2021-03-11 16:31:20 +00:00
|
|
|
export interface Subscription {
|
|
|
|
id: number;
|
|
|
|
userID: number;
|
|
|
|
productID: string;
|
|
|
|
storage: number;
|
|
|
|
originalTransactionID: string;
|
|
|
|
expiryTime: number;
|
|
|
|
paymentProvider: string;
|
2021-04-21 16:45:50 +00:00
|
|
|
attributes: {
|
|
|
|
isCancelled: boolean;
|
|
|
|
};
|
2021-08-13 02:38:38 +00:00
|
|
|
price: string;
|
|
|
|
period: string;
|
2021-03-11 16:31:20 +00:00
|
|
|
}
|
2021-03-12 12:30:33 +00:00
|
|
|
export interface Plan {
|
2021-04-13 08:47:15 +00:00
|
|
|
id: string;
|
2021-03-12 12:30:33 +00:00
|
|
|
androidID: string;
|
|
|
|
iosID: string;
|
|
|
|
storage: number;
|
|
|
|
price: string;
|
|
|
|
period: string;
|
2021-03-12 15:09:17 +00:00
|
|
|
stripeID: string;
|
2021-03-12 12:30:33 +00:00
|
|
|
}
|
2021-03-21 04:49:37 +00:00
|
|
|
|
2021-03-17 07:21:55 +00:00
|
|
|
export const FREE_PLAN = 'free';
|
2021-03-18 15:22:34 +00:00
|
|
|
class billingService {
|
2021-08-13 02:38:38 +00:00
|
|
|
public async getPlans(): Promise<Plan[]> {
|
2021-03-12 12:30:33 +00:00
|
|
|
try {
|
2021-08-13 02:38:38 +00:00
|
|
|
const response = await HTTPService.get(
|
|
|
|
`${ENDPOINT}/billing/plans/v2`
|
|
|
|
);
|
2021-05-30 16:56:48 +00:00
|
|
|
const { plans } = response.data;
|
2021-08-01 11:59:35 +00:00
|
|
|
return plans;
|
2021-03-12 12:30:33 +00:00
|
|
|
} catch (e) {
|
2021-06-12 17:14:21 +00:00
|
|
|
logError(e, 'failed to get plans');
|
2021-03-12 12:30:33 +00:00
|
|
|
}
|
|
|
|
}
|
2021-05-29 06:27:52 +00:00
|
|
|
|
2021-03-17 07:21:55 +00:00
|
|
|
public async syncSubscription() {
|
2021-03-13 12:55:47 +00:00
|
|
|
try {
|
|
|
|
const response = await HTTPService.get(
|
|
|
|
`${ENDPOINT}/billing/subscription`,
|
|
|
|
null,
|
|
|
|
{
|
|
|
|
'X-Auth-Token': getToken(),
|
2021-08-13 02:38:38 +00:00
|
|
|
}
|
2021-03-13 12:55:47 +00:00
|
|
|
);
|
2021-05-30 16:56:48 +00:00
|
|
|
const { subscription } = response.data;
|
2021-03-13 12:55:47 +00:00
|
|
|
setData(LS_KEYS.SUBSCRIPTION, subscription);
|
|
|
|
} catch (e) {
|
2021-08-13 02:38:38 +00:00
|
|
|
logError(e, "failed to get user's subscription details");
|
2021-03-13 12:55:47 +00:00
|
|
|
}
|
|
|
|
}
|
2021-05-29 06:27:52 +00:00
|
|
|
|
2021-08-14 11:39:09 +00:00
|
|
|
public async buySubscription(productID: string) {
|
2021-03-09 16:23:13 +00:00
|
|
|
try {
|
2021-08-14 10:05:48 +00:00
|
|
|
const paymentToken = await getPaymentToken();
|
|
|
|
await this.redirectToPayments(
|
|
|
|
paymentToken,
|
|
|
|
productID,
|
|
|
|
PaymentActionType.Buy
|
|
|
|
);
|
2021-03-09 16:23:13 +00:00
|
|
|
} catch (e) {
|
2021-06-12 17:14:21 +00:00
|
|
|
logError(e, 'unable to buy subscription');
|
2021-03-17 07:21:55 +00:00
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-08-14 11:39:09 +00:00
|
|
|
public async updateSubscription(productID: string) {
|
2021-03-17 07:21:55 +00:00
|
|
|
try {
|
2021-08-14 10:05:48 +00:00
|
|
|
const paymentToken = await getPaymentToken();
|
|
|
|
await this.redirectToPayments(
|
|
|
|
paymentToken,
|
|
|
|
productID,
|
|
|
|
PaymentActionType.Update
|
2021-03-17 07:21:55 +00:00
|
|
|
);
|
|
|
|
} catch (e) {
|
2021-07-28 15:45:30 +00:00
|
|
|
logError(e, 'subscription update failed');
|
2021-03-18 13:48:44 +00:00
|
|
|
throw e;
|
2021-03-17 07:21:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public async cancelSubscription() {
|
|
|
|
try {
|
2021-04-21 16:42:27 +00:00
|
|
|
const response = await HTTPService.post(
|
2021-03-17 07:21:55 +00:00
|
|
|
`${ENDPOINT}/billing/stripe/cancel-subscription`,
|
|
|
|
null,
|
2021-04-21 16:42:27 +00:00
|
|
|
null,
|
2021-03-17 07:21:55 +00:00
|
|
|
{
|
|
|
|
'X-Auth-Token': getToken(),
|
2021-08-13 02:38:38 +00:00
|
|
|
}
|
2021-03-17 07:21:55 +00:00
|
|
|
);
|
2021-05-30 16:56:48 +00:00
|
|
|
const { subscription } = response.data;
|
2021-03-18 13:48:44 +00:00
|
|
|
setData(LS_KEYS.SUBSCRIPTION, subscription);
|
2021-03-17 07:21:55 +00:00
|
|
|
} catch (e) {
|
2021-06-12 17:14:21 +00:00
|
|
|
logError(e);
|
2021-03-17 12:07:20 +00:00
|
|
|
throw e;
|
2021-03-09 16:23:13 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-17 13:56:28 +00:00
|
|
|
public async activateSubscription() {
|
|
|
|
try {
|
2021-04-21 16:42:27 +00:00
|
|
|
const response = await HTTPService.post(
|
2021-04-17 13:56:28 +00:00
|
|
|
`${ENDPOINT}/billing/stripe/activate-subscription`,
|
|
|
|
null,
|
2021-04-21 16:42:27 +00:00
|
|
|
null,
|
2021-04-17 13:56:28 +00:00
|
|
|
{
|
|
|
|
'X-Auth-Token': getToken(),
|
2021-08-13 02:38:38 +00:00
|
|
|
}
|
2021-04-17 13:56:28 +00:00
|
|
|
);
|
2021-05-30 16:56:48 +00:00
|
|
|
const { subscription } = response.data;
|
2021-04-17 13:56:28 +00:00
|
|
|
setData(LS_KEYS.SUBSCRIPTION, subscription);
|
|
|
|
} catch (e) {
|
2021-06-12 17:14:21 +00:00
|
|
|
logError(e);
|
2021-04-17 13:56:28 +00:00
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-04-14 08:49:48 +00:00
|
|
|
public async verifySubscription(
|
2021-08-13 02:38:38 +00:00
|
|
|
sessionID: string = null
|
2021-04-14 08:49:48 +00:00
|
|
|
): Promise<Subscription> {
|
2021-03-10 03:25:00 +00:00
|
|
|
try {
|
2021-03-12 17:34:20 +00:00
|
|
|
const response = await HTTPService.post(
|
|
|
|
`${ENDPOINT}/billing/verify-subscription`,
|
2021-03-12 11:43:47 +00:00
|
|
|
{
|
2021-03-12 17:34:20 +00:00
|
|
|
paymentProvider: 'stripe',
|
2021-03-12 22:48:44 +00:00
|
|
|
productID: null,
|
2021-03-12 17:34:20 +00:00
|
|
|
VerificationData: sessionID,
|
|
|
|
},
|
|
|
|
null,
|
|
|
|
{
|
|
|
|
'X-Auth-Token': getToken(),
|
2021-08-13 02:38:38 +00:00
|
|
|
}
|
2021-03-10 03:25:00 +00:00
|
|
|
);
|
2021-05-30 16:56:48 +00:00
|
|
|
const { subscription } = response.data;
|
2021-03-13 12:55:47 +00:00
|
|
|
setData(LS_KEYS.SUBSCRIPTION, subscription);
|
|
|
|
return subscription;
|
2021-03-10 03:25:00 +00:00
|
|
|
} catch (err) {
|
2021-06-12 17:14:21 +00:00
|
|
|
logError(err, 'Error while verifying subscription');
|
2021-04-14 08:49:48 +00:00
|
|
|
throw err;
|
2021-03-10 03:25:00 +00:00
|
|
|
}
|
|
|
|
}
|
2021-03-12 17:34:20 +00:00
|
|
|
|
2021-08-14 10:05:48 +00:00
|
|
|
public async redirectToPayments(
|
|
|
|
paymentToken: string,
|
|
|
|
productID: string,
|
|
|
|
action: string
|
|
|
|
) {
|
2021-07-28 15:45:30 +00:00
|
|
|
try {
|
2021-08-18 09:20:53 +00:00
|
|
|
window.location.href = `${getPaymentsUrl()}?productID=${productID}&paymentToken=${paymentToken}&action=${action}&redirectURL=${
|
2021-08-14 10:02:57 +00:00
|
|
|
window.location.origin
|
2021-08-18 09:20:53 +00:00
|
|
|
}/gallery`;
|
2021-07-28 15:45:30 +00:00
|
|
|
} catch (e) {
|
|
|
|
logError(e, 'unable to get payments url');
|
|
|
|
throw e;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-12 17:34:20 +00:00
|
|
|
public async redirectToCustomerPortal() {
|
2021-03-12 23:42:19 +00:00
|
|
|
try {
|
|
|
|
const response = await HTTPService.get(
|
2021-04-08 04:56:37 +00:00
|
|
|
`${ENDPOINT}/billing/stripe/customer-portal`,
|
2021-03-12 23:42:19 +00:00
|
|
|
null,
|
|
|
|
{
|
|
|
|
'X-Auth-Token': getToken(),
|
2021-08-13 02:38:38 +00:00
|
|
|
}
|
2021-03-12 23:42:19 +00:00
|
|
|
);
|
2021-05-29 06:27:52 +00:00
|
|
|
window.location.href = response.data.url;
|
2021-03-12 23:42:19 +00:00
|
|
|
} catch (e) {
|
2021-06-12 17:14:21 +00:00
|
|
|
logError(e, 'unable to get customer portal url');
|
2021-04-08 05:08:15 +00:00
|
|
|
throw e;
|
2021-03-12 23:42:19 +00:00
|
|
|
}
|
2021-03-12 17:34:20 +00:00
|
|
|
}
|
2021-05-29 06:27:52 +00:00
|
|
|
|
2021-04-06 13:43:11 +00:00
|
|
|
public async getUsage() {
|
2021-03-11 16:04:52 +00:00
|
|
|
try {
|
|
|
|
const response = await HTTPService.get(
|
|
|
|
`${ENDPOINT}/billing/usage`,
|
2021-05-30 16:56:48 +00:00
|
|
|
{ startTime: 0, endTime: Date.now() * 1000 },
|
2021-03-11 16:04:52 +00:00
|
|
|
{
|
2021-03-12 03:16:35 +00:00
|
|
|
'X-Auth-Token': getToken(),
|
2021-08-13 02:38:38 +00:00
|
|
|
}
|
2021-03-11 16:04:52 +00:00
|
|
|
);
|
2021-07-18 16:10:11 +00:00
|
|
|
return convertToHumanReadable(response.data.usage);
|
2021-03-11 16:04:52 +00:00
|
|
|
} catch (e) {
|
2021-06-12 17:14:21 +00:00
|
|
|
logError(e, 'error getting usage');
|
2021-03-11 16:04:52 +00:00
|
|
|
}
|
|
|
|
}
|
2021-03-09 16:23:13 +00:00
|
|
|
}
|
|
|
|
|
2021-03-18 15:22:34 +00:00
|
|
|
export default new billingService();
|