payment-kit 1.13.111 → 1.13.113

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/api/src/libs/notification/template/subscription-trial-will-end.ts +1 -1
  2. package/api/src/libs/notification/template/subscription-will-renew.ts +1 -1
  3. package/api/src/routes/products.ts +1 -0
  4. package/api/src/routes/subscriptions.ts +2 -0
  5. package/blocklet.yml +1 -1
  6. package/package.json +6 -6
  7. package/src/components/actions.tsx +1 -2
  8. package/src/components/blockchain/tx.tsx +1 -1
  9. package/src/components/click-boundary.tsx +1 -2
  10. package/src/components/customer/actions.tsx +2 -3
  11. package/src/components/customer/edit.tsx +3 -3
  12. package/src/components/customer/form.tsx +22 -24
  13. package/src/components/drawer-form.tsx +2 -4
  14. package/src/components/event/list.tsx +2 -3
  15. package/src/components/invoice/action.tsx +2 -3
  16. package/src/components/invoice/list.tsx +3 -4
  17. package/src/components/invoice/table.tsx +7 -7
  18. package/src/components/metadata/form.tsx +3 -4
  19. package/src/components/passport/actions.tsx +1 -2
  20. package/src/components/passport/assign.tsx +1 -1
  21. package/src/components/payment-intent/actions.tsx +2 -3
  22. package/src/components/payment-intent/list.tsx +3 -4
  23. package/src/components/payment-link/actions.tsx +2 -3
  24. package/src/components/payment-link/item.tsx +3 -5
  25. package/src/components/payment-link/product-select.tsx +3 -4
  26. package/src/components/payment-link/rename.tsx +3 -4
  27. package/src/components/payment-method/arcblock.tsx +1 -2
  28. package/src/components/payment-method/bitcoin.tsx +1 -2
  29. package/src/components/payment-method/ethereum.tsx +1 -2
  30. package/src/components/payment-method/stripe.tsx +1 -2
  31. package/src/components/portal/invoice/list.tsx +4 -5
  32. package/src/components/portal/subscription/actions.tsx +7 -8
  33. package/src/components/portal/subscription/cancel.tsx +13 -12
  34. package/src/components/portal/subscription/list.tsx +4 -10
  35. package/src/components/price/currency-select.tsx +2 -2
  36. package/src/components/price/form.tsx +3 -4
  37. package/src/components/price/upsell-select.tsx +2 -3
  38. package/src/components/price/upsell.tsx +3 -5
  39. package/src/components/pricing-table/actions.tsx +2 -3
  40. package/src/components/pricing-table/payment-settings.tsx +4 -4
  41. package/src/components/pricing-table/price-item.tsx +4 -7
  42. package/src/components/pricing-table/product-item.tsx +3 -3
  43. package/src/components/pricing-table/rename.tsx +3 -4
  44. package/src/components/product/actions.tsx +2 -3
  45. package/src/components/product/add-price.tsx +2 -2
  46. package/src/components/product/create.tsx +2 -4
  47. package/src/components/product/cross-sell-select.tsx +3 -3
  48. package/src/components/product/cross-sell.tsx +4 -5
  49. package/src/components/product/edit.tsx +1 -1
  50. package/src/components/product/form.tsx +6 -6
  51. package/src/components/relative-time.tsx +1 -2
  52. package/src/components/subscription/actions/cancel.tsx +2 -3
  53. package/src/components/subscription/actions/index.tsx +2 -3
  54. package/src/components/subscription/items/actions.tsx +1 -1
  55. package/src/components/subscription/items/index.tsx +2 -2
  56. package/src/components/subscription/items/usage-records.tsx +2 -3
  57. package/src/components/subscription/list.tsx +3 -4
  58. package/src/components/subscription/metrics.tsx +2 -2
  59. package/src/components/subscription/status.tsx +3 -3
  60. package/src/components/webhook/attempts.tsx +3 -3
  61. package/src/contexts/products.tsx +2 -3
  62. package/src/libs/api.ts +2 -19
  63. package/src/libs/dayjs.ts +1 -15
  64. package/src/libs/util.ts +24 -555
  65. package/src/locales/en.tsx +0 -139
  66. package/src/locales/index.tsx +5 -23
  67. package/src/locales/zh.tsx +0 -136
  68. package/src/pages/admin/billing/index.tsx +4 -2
  69. package/src/pages/admin/billing/invoices/detail.tsx +3 -4
  70. package/src/pages/admin/billing/subscriptions/detail.tsx +3 -3
  71. package/src/pages/admin/customers/customers/detail.tsx +3 -5
  72. package/src/pages/admin/customers/customers/index.tsx +2 -3
  73. package/src/pages/admin/customers/index.tsx +4 -2
  74. package/src/pages/admin/developers/events/detail.tsx +2 -3
  75. package/src/pages/admin/developers/index.tsx +4 -2
  76. package/src/pages/admin/developers/webhooks/detail.tsx +3 -4
  77. package/src/pages/admin/developers/webhooks/index.tsx +3 -4
  78. package/src/pages/admin/index.tsx +10 -7
  79. package/src/pages/admin/payments/index.tsx +4 -2
  80. package/src/pages/admin/payments/intents/detail.tsx +4 -6
  81. package/src/pages/admin/payments/links/create.tsx +3 -5
  82. package/src/pages/admin/payments/links/detail.tsx +4 -5
  83. package/src/pages/admin/payments/links/index.tsx +4 -6
  84. package/src/pages/admin/products/passports/index.tsx +1 -1
  85. package/src/pages/admin/products/prices/actions.tsx +2 -3
  86. package/src/pages/admin/products/prices/detail.tsx +2 -3
  87. package/src/pages/admin/products/prices/list.tsx +2 -4
  88. package/src/pages/admin/products/pricing-tables/create.tsx +2 -3
  89. package/src/pages/admin/products/pricing-tables/detail.tsx +4 -5
  90. package/src/pages/admin/products/pricing-tables/index.tsx +2 -4
  91. package/src/pages/admin/products/products/create.tsx +2 -4
  92. package/src/pages/admin/products/products/detail.tsx +4 -5
  93. package/src/pages/admin/products/products/index.tsx +4 -6
  94. package/src/pages/admin/settings/index.tsx +4 -2
  95. package/src/pages/admin/settings/payment-methods/create.tsx +3 -5
  96. package/src/pages/admin/settings/payment-methods/index.tsx +2 -3
  97. package/src/pages/checkout/index.tsx +6 -3
  98. package/src/pages/checkout/pay.tsx +5 -69
  99. package/src/pages/checkout/pricing-table.tsx +3 -7
  100. package/src/pages/customer/index.tsx +7 -7
  101. package/src/pages/customer/invoice.tsx +10 -11
  102. package/src/pages/customer/subscription/detail.tsx +4 -4
  103. package/src/pages/customer/subscription/update.tsx +19 -19
  104. package/src/components/checkout/amount.tsx +0 -24
  105. package/src/components/checkout/error.tsx +0 -30
  106. package/src/components/checkout/footer.tsx +0 -12
  107. package/src/components/checkout/form/address.tsx +0 -119
  108. package/src/components/checkout/form/index.tsx +0 -400
  109. package/src/components/checkout/form/phone.tsx +0 -103
  110. package/src/components/checkout/form/stripe.tsx +0 -195
  111. package/src/components/checkout/form/user-buttons.tsx +0 -24
  112. package/src/components/checkout/header.tsx +0 -40
  113. package/src/components/checkout/pay.tsx +0 -385
  114. package/src/components/checkout/pricing-table.tsx +0 -205
  115. package/src/components/checkout/product-card.tsx +0 -52
  116. package/src/components/checkout/product-item.tsx +0 -111
  117. package/src/components/checkout/skeleton/overview.tsx +0 -21
  118. package/src/components/checkout/skeleton/payment.tsx +0 -35
  119. package/src/components/checkout/success.tsx +0 -183
  120. package/src/components/checkout/summary.tsx +0 -198
  121. package/src/components/input.tsx +0 -58
  122. package/src/components/livemode.tsx +0 -23
  123. package/src/components/pricing-table/product-skeleton.tsx +0 -39
  124. package/src/components/status.tsx +0 -19
  125. package/src/components/switch.tsx +0 -48
  126. package/src/contexts/settings.tsx +0 -54
package/src/libs/util.ts CHANGED
@@ -1,125 +1,27 @@
1
1
  /* eslint-disable no-nested-ternary */
2
2
  /* eslint-disable @typescript-eslint/indent */
3
+ import {
4
+ formatCheckoutHeadlines,
5
+ formatPrice,
6
+ getCheckoutAmount,
7
+ getPriceCurrencyOptions,
8
+ } from '@blocklet/payment-react';
3
9
  import type {
4
10
  LineItem,
5
- PriceCurrency,
6
- PriceRecurring,
7
- TCheckoutSessionExpanded,
8
11
  TLineItemExpanded,
9
12
  TPaymentCurrency,
10
13
  TPaymentLinkExpanded,
11
14
  TPaymentMethodExpanded,
12
15
  TPrice,
13
16
  TProductExpanded,
14
- TSubscriptionExpanded,
15
17
  TSubscriptionItemExpanded,
16
- } from '@did-pay/types';
17
- import { BN, fromUnitToToken } from '@ocap/util';
18
+ } from '@blocklet/payment-types';
18
19
  import cloneDeep from 'lodash/cloneDeep';
19
20
  import isEqual from 'lodash/isEqual';
20
- import { defaultCountries } from 'react-international-phone';
21
21
 
22
22
  import { t } from '../locales/index';
23
23
  import dayjs from './dayjs';
24
24
 
25
- export function getExplorerLink(chainHost: string, did: string, type: string) {
26
- if (!chainHost) return undefined;
27
- try {
28
- const chainUrl = new URL(chainHost);
29
- switch (type) {
30
- case 'asset':
31
- chainUrl.pathname = `/explorer/assets/${did}`;
32
- break;
33
- case 'account':
34
- chainUrl.pathname = `/explorer/accounts/${did}`;
35
- break;
36
- case 'tx':
37
- chainUrl.pathname = `/explorer/txs/${did}`;
38
- break;
39
- case 'token':
40
- chainUrl.pathname = `/explorer/tokens/${did}`;
41
- break;
42
- case 'factory':
43
- chainUrl.pathname = `/explorer/factories/${did}`;
44
- break;
45
- case 'bridge':
46
- chainUrl.pathname = `/explorer/bridges/${did}`;
47
- break;
48
- default:
49
- chainUrl.pathname = '/';
50
- }
51
-
52
- return chainUrl.href;
53
- } catch {
54
- return undefined;
55
- }
56
- }
57
-
58
- export function formatToDate(date: Date | string | number, locale = 'en') {
59
- if (!date) {
60
- return '-';
61
- }
62
-
63
- return dayjs(date).locale(formatLocale(locale)).format('YYYY-MM-DD HH:mm:ss');
64
- }
65
-
66
- export function formatToDatetime(date: Date | string | number, locale = 'en') {
67
- if (!date) {
68
- return '-';
69
- }
70
-
71
- return dayjs(date).locale(formatLocale(locale)).format('lll');
72
- }
73
-
74
- export function formatTime(date: Date | string | number, format = 'YYYY-MM-DD HH:mm:ss', locale = 'en') {
75
- if (!date) {
76
- return '-';
77
- }
78
-
79
- return dayjs(date).locale(formatLocale(locale)).format(format);
80
- }
81
-
82
- export function formatDateTime(date: Date | string | number, locale = 'en') {
83
- return dayjs(date).locale(formatLocale(locale)).format('YYYY-MM-DD HH:mm');
84
- }
85
-
86
- export const formatLocale = (locale = 'en') => {
87
- if (locale === 'tw') {
88
- return 'zh';
89
- }
90
-
91
- return locale;
92
- };
93
-
94
- export const formatPrettyMsLocale = (locale: string) => (locale === 'zh' ? 'zh_CN' : 'en_US');
95
-
96
- export const formatError = (err: any) => {
97
- const { details, errors, response } = err;
98
-
99
- // graphql error
100
- if (Array.isArray(errors)) {
101
- return errors.map((x) => x.message).join('\n');
102
- }
103
-
104
- // joi validate error
105
- if (Array.isArray(details)) {
106
- const formatted = details.map((e) => {
107
- const errorMessage = e.message.replace(/["]/g, "'");
108
- const errorPath = e.path.join('.');
109
- return `${errorPath}: ${errorMessage}`;
110
- });
111
-
112
- return `Validate failed: ${formatted.join(';')}`;
113
- }
114
-
115
- // axios error
116
- if (response) {
117
- return response.data.error || `${err.message}: ${JSON.stringify(response.data)}`;
118
- }
119
-
120
- return err.message;
121
- };
122
-
123
25
  export const formatProductPrice = (
124
26
  { prices, unit_label }: { prices: TPrice[]; unit_label: string },
125
27
  currency: TPaymentCurrency,
@@ -136,59 +38,6 @@ export const formatProductPrice = (
136
38
  return t('admin.price.empty', locale);
137
39
  };
138
40
 
139
- export const formatPrice = (
140
- price: TPrice,
141
- currency: TPaymentCurrency,
142
- unit_label?: string,
143
- quantity: number = 1,
144
- bn: boolean = true,
145
- locale: string = 'en'
146
- ) => {
147
- const unit = getPriceUintAmountByCurrency(price, currency);
148
- const amount = bn
149
- ? fromUnitToToken(new BN(unit).mul(new BN(quantity)), currency.decimal).toString()
150
- : +unit * quantity;
151
- if (price?.type === 'recurring' && price.recurring) {
152
- const recurring = formatRecurring(price.recurring, false, 'slash', locale);
153
-
154
- if (unit_label) {
155
- return `${amount} ${currency.symbol} / ${unit_label} ${recurring}`;
156
- }
157
- if (price.recurring.usage_type === 'metered') {
158
- return `${amount} ${currency.symbol} / unit ${recurring}`;
159
- }
160
-
161
- return `${amount} ${currency.symbol} ${recurring}`;
162
- }
163
-
164
- return `${amount} ${currency.symbol}`;
165
- };
166
-
167
- export const formatPriceAmount = (
168
- price: TPrice,
169
- currency: TPaymentCurrency,
170
- unit_label?: string,
171
- quantity: number = 1,
172
- bn: boolean = true
173
- ) => {
174
- const unit = getPriceUintAmountByCurrency(price, currency);
175
- const amount = bn
176
- ? fromUnitToToken(new BN(unit).mul(new BN(quantity)), currency.decimal).toString()
177
- : +unit * quantity;
178
- if (price?.type === 'recurring' && price.recurring) {
179
- if (unit_label) {
180
- return `${amount} ${currency.symbol} / ${unit_label}`;
181
- }
182
- if (price.recurring.usage_type === 'metered') {
183
- return `${amount} ${currency.symbol} / unit`;
184
- }
185
-
186
- return `${amount} ${currency.symbol}`;
187
- }
188
-
189
- return `${amount} ${currency.symbol}`;
190
- };
191
-
192
41
  export function getPricingModel(price: TPrice) {
193
42
  if (price.billing_scheme === 'tiered') {
194
43
  return price.tiers_mode;
@@ -214,141 +63,6 @@ export function getPriceFromProducts(products: TProductExpanded[], priceId: stri
214
63
  return product?.prices.find((x) => x.id === priceId);
215
64
  }
216
65
 
217
- export function getStatementDescriptor(items: any[]) {
218
- for (const item of items) {
219
- if (item.price?.product?.statement_descriptor) {
220
- return item.price?.product?.statement_descriptor;
221
- }
222
- }
223
-
224
- return window.blocklet.appName;
225
- }
226
-
227
- export function formatRecurring(
228
- recurring: PriceRecurring,
229
- translate: boolean = true,
230
- separator: string = 'per',
231
- locale: string = 'en'
232
- ) {
233
- const intervals = {
234
- hour: 'hourly',
235
- day: 'daily',
236
- week: 'weekly',
237
- month: 'monthly',
238
- year: 'yearly',
239
- };
240
-
241
- if (+recurring.interval_count === 1) {
242
- const interval = t(`common.${recurring.interval}`, locale);
243
- // @ts-ignore
244
- return translate ? t(`common.${intervals[recurring.interval]}`, locale) : separator ? t(`common.${separator}`, locale, { interval }) : interval; // prettier-ignore
245
- }
246
-
247
- return t('common.recurring', locale, {
248
- count: recurring.interval_count,
249
- interval: t(`common.${recurring.interval}s`, locale),
250
- });
251
- }
252
-
253
- export function getPriceUintAmountByCurrency(price: TPrice, currency: TPaymentCurrency) {
254
- const options = getPriceCurrencyOptions(price);
255
- const option = options.find((x) => x.currency_id === currency.id);
256
- if (option) {
257
- return option.unit_amount;
258
- }
259
-
260
- return price.unit_amount;
261
- }
262
-
263
- export function getPriceCurrencyOptions(price: TPrice): PriceCurrency[] {
264
- if (Array.isArray(price.currency_options)) {
265
- return price.currency_options;
266
- }
267
-
268
- return [{ currency_id: price.currency_id, unit_amount: price.unit_amount, tiers: null, custom_unit_amount: null }];
269
- }
270
-
271
- export function formatLineItemPricing(
272
- item: TLineItemExpanded,
273
- currency: TPaymentCurrency,
274
- trial: number,
275
- locale: string = 'en'
276
- ): { primary: string; secondary?: string; quantity: string } {
277
- const price = item.upsell_price || item.price;
278
-
279
- let quantity = t('common.qty', locale, { count: item.quantity });
280
- if (price.recurring?.usage_type === 'metered' || +item.quantity === 1) {
281
- quantity = '';
282
- }
283
-
284
- const total = `${fromUnitToToken(
285
- new BN(getPriceUintAmountByCurrency(price, currency)).mul(new BN(item.quantity)),
286
- currency.decimal
287
- )} ${currency.symbol}`;
288
- const unit = `${fromUnitToToken(getPriceUintAmountByCurrency(price, currency))} ${currency.symbol}`;
289
-
290
- const appendUnit = (v: string, alt: string) => {
291
- if (price.product.unit_label) {
292
- return `${v}/${price.product.unit_label}`;
293
- }
294
- if (price.recurring?.usage_type === 'metered' || item.quantity === 1) {
295
- return alt;
296
- }
297
-
298
- return quantity ? t('common.each', locale, { unit }) : '';
299
- };
300
-
301
- if (price.type === 'recurring' && price.recurring) {
302
- if (trial > 0) {
303
- return {
304
- primary: t('common.trial', locale, { count: trial }),
305
- secondary: `${appendUnit(total, total)} ${formatRecurring(price.recurring, false, 'slash', locale)}`,
306
- quantity,
307
- };
308
- }
309
-
310
- return {
311
- primary: total,
312
- secondary: appendUnit(total, ''),
313
- quantity,
314
- };
315
- }
316
-
317
- return {
318
- primary: total,
319
- secondary: appendUnit(total, ''),
320
- quantity,
321
- };
322
- }
323
-
324
- export function getCheckoutAmount(
325
- items: TLineItemExpanded[],
326
- currency: TPaymentCurrency,
327
- includeFreeTrial = false,
328
- upsell = true
329
- ) {
330
- let renew = new BN(0);
331
-
332
- const total = items
333
- .reduce((acc, x) => {
334
- const price = upsell ? x.upsell_price || x.price : x.price;
335
- if (price.type === 'recurring') {
336
- renew = renew.add(new BN(getPriceUintAmountByCurrency(price, currency)).mul(new BN(x.quantity)));
337
-
338
- if (includeFreeTrial) {
339
- return acc;
340
- }
341
- if (price.recurring?.usage_type === 'metered') {
342
- return acc;
343
- }
344
- }
345
- return acc.add(new BN(getPriceUintAmountByCurrency(price, currency)).mul(new BN(x.quantity)));
346
- }, new BN(0))
347
- .toString();
348
-
349
- return { subtotal: total, total, renew: renew.toString(), discount: '0', shipping: '0', tax: '0' };
350
- }
351
-
352
66
  export function formatPaymentLinkPricing(link: TPaymentLinkExpanded, currency: TPaymentCurrency) {
353
67
  const amount = getCheckoutAmount(link.line_items, currency, !!link.subscription_data?.trial_period_days);
354
68
  return formatCheckoutHeadlines(
@@ -365,176 +79,6 @@ export function formatPaymentLinkPricing(link: TPaymentLinkExpanded, currency: T
365
79
  currency
366
80
  );
367
81
  }
368
- export function getRecurringPeriod(recurring: PriceRecurring) {
369
- const { interval } = recurring;
370
- const count = +recurring.interval_count || 1;
371
- const dayInMs = 24 * 60 * 60 * 1000;
372
-
373
- switch (interval) {
374
- case 'hour':
375
- return 60 * 60 * 1000;
376
- case 'day':
377
- return count * dayInMs;
378
- case 'week':
379
- return count * 7 * dayInMs;
380
- case 'month':
381
- return count * 30 * dayInMs;
382
- case 'year':
383
- return count * 365 * dayInMs;
384
- default:
385
- throw new Error(`Unsupported recurring interval: ${interval}`);
386
- }
387
- }
388
-
389
- export function formatUpsellSaving(session: TCheckoutSessionExpanded, currency: TPaymentCurrency) {
390
- const items = session.line_items as TLineItemExpanded[];
391
- if (items[0]?.upsell_price_id) {
392
- return '0';
393
- }
394
- if (!items[0]?.price.upsell?.upsells_to) {
395
- return '0';
396
- }
397
-
398
- const from = getCheckoutAmount(items, currency, false, false);
399
- const to = getCheckoutAmount(
400
- items.map((x) => ({
401
- ...x,
402
- upsell_price_id: x.price.upsell?.upsells_to_id,
403
- upsell_price: x.price.upsell?.upsells_to,
404
- })) as TLineItemExpanded[],
405
- currency,
406
- false,
407
- true
408
- );
409
-
410
- const fromRecurring = items[0].price?.recurring as PriceRecurring;
411
- const toRecurring = items[0].price?.upsell?.upsells_to?.recurring as PriceRecurring;
412
- if (!fromRecurring || !toRecurring) {
413
- return '0';
414
- }
415
-
416
- const factor = Math.floor(getRecurringPeriod(toRecurring) / getRecurringPeriod(fromRecurring));
417
-
418
- const before = new BN(from.total).mul(new BN(factor));
419
- const after = new BN(to.total);
420
-
421
- return Number(before.sub(after).mul(new BN(100)).div(before).toString()).toFixed(0);
422
- }
423
-
424
- export function formatCheckoutHeadlines(
425
- session: TCheckoutSessionExpanded,
426
- currency: TPaymentCurrency,
427
- locale: string = 'en'
428
- ): {
429
- action: string;
430
- amount: string;
431
- then?: string;
432
- secondary?: string;
433
- } {
434
- const items = session.line_items as TLineItemExpanded[];
435
- const trial = session.subscription_data?.trial_period_days || 0;
436
-
437
- const brand = getStatementDescriptor(items);
438
- const { total } = getCheckoutAmount(items, currency, !!trial);
439
- const amount = `${fromUnitToToken(total, currency.decimal)} ${currency.symbol}`;
440
-
441
- // empty
442
- if (items.length === 0) {
443
- return {
444
- action: t('checkout.empty', locale),
445
- amount: '0',
446
- then: '',
447
- };
448
- }
449
-
450
- const { name } = items[0]?.price.product || { name: '' };
451
-
452
- // all one time
453
- if (items.every((x) => x.price.type === 'one_time')) {
454
- const action = t('checkout.pay', locale, { payee: brand });
455
- if (items.length > 1) {
456
- return { action, amount };
457
- }
458
-
459
- return { action, amount, then: '' };
460
- }
461
-
462
- const item = items.find((x) => x.price.type === 'recurring');
463
- const recurring = formatRecurring(
464
- (item?.upsell_price || item?.price)?.recurring as PriceRecurring,
465
- false,
466
- 'per',
467
- locale
468
- );
469
-
470
- // all recurring
471
- if (items.every((x) => x.price.type === 'recurring')) {
472
- const hasMetered = items.some((x) => x.price.type === 'recurring' && x.price.recurring?.usage_type === 'metered');
473
- const subscription = [
474
- hasMetered ? t('checkout.least', locale) : '',
475
- fromUnitToToken(
476
- items.reduce((acc, x) => {
477
- if (x.price.recurring?.usage_type === 'metered') {
478
- return acc;
479
- }
480
- return acc.add(new BN(getPriceUintAmountByCurrency(x.price, currency)).mul(new BN(x.quantity)));
481
- }, new BN(0)),
482
- currency.decimal
483
- ),
484
- currency.symbol,
485
- ]
486
- .filter(Boolean)
487
- .join(' ');
488
- if (items.length > 1) {
489
- if (trial > 0) {
490
- return {
491
- action: t('checkout.try2', locale, { name, count: items.length - 1 }),
492
- amount: t('checkout.free', locale, { count: trial }),
493
- then: t('checkout.then', locale, { subscription, recurring }),
494
- };
495
- }
496
-
497
- return {
498
- action: t('checkout.sub2', locale, { name, count: items.length - 1 }),
499
- amount,
500
- then: recurring,
501
- };
502
- }
503
-
504
- if (trial > 0) {
505
- return {
506
- action: t('checkout.try1', locale, { name }),
507
- amount: t('checkout.free', locale, { count: trial }),
508
- then: t('checkout.then', locale, { subscription, recurring }),
509
- };
510
- }
511
-
512
- return {
513
- action: t('checkout.sub1', locale, { name }),
514
- amount,
515
- then: recurring,
516
- };
517
- }
518
-
519
- // mixed
520
- const subscription = fromUnitToToken(
521
- items
522
- .filter((x) => x.price.type === 'recurring')
523
- .reduce((acc, x) => {
524
- if (x.price.recurring?.usage_type === 'metered') {
525
- return acc;
526
- }
527
- return acc.add(new BN(getPriceUintAmountByCurrency(x.price, currency)).mul(new BN(x.quantity)));
528
- }, new BN(0)),
529
- currency.decimal
530
- );
531
-
532
- return {
533
- action: t('checkout.pay', locale, { payee: brand }),
534
- amount,
535
- then: t('checkout.then', locale, { subscription: `${subscription} ${currency.symbol}`, recurring }),
536
- };
537
- }
538
82
 
539
83
  export function getSubscriptionStatusColor(status: string) {
540
84
  switch (status) {
@@ -666,53 +210,6 @@ export function formatSubscriptionProduct(items: TSubscriptionItemExpanded[], ma
666
210
  );
667
211
  }
668
212
 
669
- export function formatAmount(amount: string, decimals: number) {
670
- return fromUnitToToken(amount, decimals);
671
- }
672
-
673
- export function findCurrency(methods: TPaymentMethodExpanded[], currencyId: string) {
674
- for (const method of methods) {
675
- for (const currency of method.payment_currencies) {
676
- if (currency.id === currencyId) {
677
- return currency;
678
- }
679
- }
680
- }
681
-
682
- return null;
683
- }
684
-
685
- export function filterCurrencies(method: TPaymentMethodExpanded, hasSelected: (currency: any) => boolean) {
686
- method.payment_currencies = method.payment_currencies.filter((x) => !hasSelected(x));
687
- return method;
688
- }
689
-
690
- export function getSupportedPaymentMethods(methods: TPaymentMethodExpanded[], hasSelected: (currency: any) => boolean) {
691
- const filtered = cloneDeep(methods).map((x) => filterCurrencies(x, hasSelected));
692
- return filtered.filter((x) => x.payment_currencies.length);
693
- }
694
-
695
- export function getSupportedPaymentCurrencies(items: TLineItemExpanded[]) {
696
- const currencies = items.reduce((acc, x: any) => {
697
- return acc.concat(x.price.currency_options.map((c: any) => c.currency_id));
698
- }, []);
699
- return Array.from(new Set(currencies));
700
- }
701
-
702
- export function isValidCountry(code: string) {
703
- return defaultCountries.some((x) => x[1] === code);
704
- }
705
-
706
- export function stopEvent(e: React.SyntheticEvent<any>) {
707
- try {
708
- e.stopPropagation();
709
- e.preventDefault();
710
- // eslint-disable-next-line no-empty
711
- } catch {
712
- // Do nothing
713
- }
714
- }
715
-
716
213
  export function groupPricingTableItems(items: any[]) {
717
214
  const grouped: { [key: string]: any[] } = {};
718
215
  items.forEach((x: any, index) => {
@@ -726,54 +223,26 @@ export function groupPricingTableItems(items: any[]) {
726
223
  return Object.entries(grouped);
727
224
  }
728
225
 
729
- export function sleep(ms: number) {
730
- return new Promise((resolve) => {
731
- setTimeout(resolve, ms);
732
- });
733
- }
734
-
735
226
  export function isSuccessAttempt(code: number) {
736
227
  return code >= 200 && code < 300;
737
228
  }
738
229
 
739
- export const getSubscriptionTimeSummary = (subscription: TSubscriptionExpanded) => {
740
- const lines = [`Started on ${formatToDate(subscription.start_date * 1000)}`];
741
- if (subscription.status === 'active' || subscription.status === 'trialing') {
742
- if (subscription.cancel_at) {
743
- lines.push(`will cancel on ${formatToDate(subscription.cancel_at * 1000)}`);
744
- } else if (subscription.cancel_at_period_end) {
745
- lines.push(`will cancel on ${formatToDate(subscription.current_period_end * 1000)}`);
746
- } else {
747
- lines.push(`will renew on ${formatToDate(subscription.current_period_end * 1000)}`);
748
- }
749
- } else if (subscription.status === 'past_due') {
750
- lines.push(`will cancel on ${formatToDate(subscription.current_period_end * 1000)}`);
751
- } else if (subscription.status === 'canceled') {
752
- lines.push(`canceled on ${formatToDate(subscription.canceled_at * 1000)}`);
753
- }
754
-
755
- return lines.join(', ');
756
- };
757
-
758
- export const getSubscriptionAction = (subscription: TSubscriptionExpanded) => {
759
- if (subscription.status !== 'canceled' && subscription.cancel_at_period_end) {
760
- return { action: 'recover', variant: 'contained', color: 'primary' };
761
- }
762
-
763
- if (subscription.status === 'active' || subscription.status === 'trialing') {
764
- if (subscription.cancel_at) {
765
- return null;
766
- }
767
- if (subscription.cancel_at_period_end) {
768
- return { action: 'recover', variant: 'contained', color: 'primary' };
769
- }
770
-
771
- return { action: 'cancel', variant: 'outlined', color: 'inherit' };
772
- }
230
+ export function filterCurrencies(method: TPaymentMethodExpanded, hasSelected: (currency: TPaymentCurrency) => boolean) {
231
+ method.payment_currencies = method.payment_currencies.filter((x) => hasSelected(x));
232
+ return method;
233
+ }
773
234
 
774
- if (subscription.status === 'past_due') {
775
- return { action: 'pastDue', variant: 'contained', color: 'primary' };
776
- }
235
+ export function getSupportedPaymentMethods(
236
+ methods: TPaymentMethodExpanded[],
237
+ hasSelected: (currency: TPaymentCurrency) => boolean
238
+ ) {
239
+ const filtered = cloneDeep(methods).map((x) => filterCurrencies(x, hasSelected));
240
+ return filtered.filter((x) => x.payment_currencies.length);
241
+ }
777
242
 
778
- return null;
779
- };
243
+ export function getSupportedPaymentCurrencies(items: TLineItemExpanded[]) {
244
+ const currencies = items.reduce((acc: string[], x: any) => {
245
+ return acc.concat(getPriceCurrencyOptions(x.price).map((c: any) => c.currency_id));
246
+ }, []);
247
+ return Array.from(new Set(currencies));
248
+ }