@blocklet/payment-react 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.
- package/LICENSE +13 -0
- package/README.md +29 -0
- package/babel.config.es.js +8 -0
- package/build.config.ts +29 -0
- package/es/api.d.ts +2 -0
- package/es/api.js +18 -0
- package/es/checkout/index.d.ts +15 -0
- package/es/checkout/index.js +61 -0
- package/es/components/input.d.ts +23 -0
- package/es/components/input.js +44 -0
- package/es/components/livemode.d.ts +2 -0
- package/es/components/livemode.js +24 -0
- package/es/components/pricing-table.d.ts +18 -0
- package/es/components/pricing-table.js +175 -0
- package/es/components/status.d.ts +3 -0
- package/es/components/status.js +20 -0
- package/es/components/switch.d.ts +6 -0
- package/es/components/switch.js +42 -0
- package/es/contexts/payment.d.ts +29 -0
- package/es/contexts/payment.js +45 -0
- package/es/dayjs.d.ts +2 -0
- package/es/dayjs.js +14 -0
- package/es/index.d.ts +16 -0
- package/es/index.js +29 -0
- package/es/locales/en.d.ts +2 -0
- package/es/locales/en.js +213 -0
- package/es/locales/index.d.ts +10 -0
- package/es/locales/index.js +20 -0
- package/es/locales/zh.d.ts +2 -0
- package/es/locales/zh.js +213 -0
- package/es/payment/amount.d.ts +12 -0
- package/es/payment/amount.js +22 -0
- package/es/payment/error.d.ts +13 -0
- package/es/payment/error.js +12 -0
- package/es/payment/footer.d.ts +4 -0
- package/es/payment/footer.js +9 -0
- package/es/payment/form/addon.d.ts +2 -0
- package/es/payment/form/addon.js +14 -0
- package/es/payment/form/address.d.ts +7 -0
- package/es/payment/form/address.js +119 -0
- package/es/payment/form/index.d.ts +9 -0
- package/es/payment/form/index.js +337 -0
- package/es/payment/form/phone.d.ts +4 -0
- package/es/payment/form/phone.js +97 -0
- package/es/payment/form/stripe.d.ts +13 -0
- package/es/payment/form/stripe.js +158 -0
- package/es/payment/header.d.ts +7 -0
- package/es/payment/header.js +29 -0
- package/es/payment/index.d.ts +28 -0
- package/es/payment/index.js +327 -0
- package/es/payment/product-card.d.ts +21 -0
- package/es/payment/product-card.js +34 -0
- package/es/payment/product-item.d.ts +19 -0
- package/es/payment/product-item.js +107 -0
- package/es/payment/product-skeleton.d.ts +4 -0
- package/es/payment/product-skeleton.js +34 -0
- package/es/payment/skeleton/overview.d.ts +2 -0
- package/es/payment/skeleton/overview.js +13 -0
- package/es/payment/skeleton/payment.d.ts +2 -0
- package/es/payment/skeleton/payment.js +19 -0
- package/es/payment/success.d.ts +8 -0
- package/es/payment/success.js +164 -0
- package/es/payment/summary.d.ts +12 -0
- package/es/payment/summary.js +178 -0
- package/es/theme.d.ts +1 -0
- package/es/theme.js +17 -0
- package/es/types/index.d.ts +19 -0
- package/es/types/index.js +0 -0
- package/es/types/shims.d.ts +18 -0
- package/es/util.d.ts +52 -0
- package/es/util.js +390 -0
- package/lib/api.d.ts +2 -0
- package/lib/api.js +26 -0
- package/lib/checkout/index.d.ts +15 -0
- package/lib/checkout/index.js +83 -0
- package/lib/components/input.d.ts +23 -0
- package/lib/components/input.js +72 -0
- package/lib/components/livemode.d.ts +2 -0
- package/lib/components/livemode.js +29 -0
- package/lib/components/pricing-table.d.ts +18 -0
- package/lib/components/pricing-table.js +232 -0
- package/lib/components/status.d.ts +3 -0
- package/lib/components/status.js +23 -0
- package/lib/components/switch.d.ts +6 -0
- package/lib/components/switch.js +51 -0
- package/lib/contexts/payment.d.ts +29 -0
- package/lib/contexts/payment.js +73 -0
- package/lib/dayjs.d.ts +2 -0
- package/lib/dayjs.js +21 -0
- package/lib/index.d.ts +16 -0
- package/lib/index.js +143 -0
- package/lib/locales/en.d.ts +2 -0
- package/lib/locales/en.js +220 -0
- package/lib/locales/index.d.ts +10 -0
- package/lib/locales/index.js +33 -0
- package/lib/locales/zh.d.ts +2 -0
- package/lib/locales/zh.js +220 -0
- package/lib/payment/amount.d.ts +12 -0
- package/lib/payment/amount.js +28 -0
- package/lib/payment/error.d.ts +13 -0
- package/lib/payment/error.js +52 -0
- package/lib/payment/footer.d.ts +4 -0
- package/lib/payment/footer.js +25 -0
- package/lib/payment/form/addon.d.ts +2 -0
- package/lib/payment/form/addon.js +37 -0
- package/lib/payment/form/address.d.ts +7 -0
- package/lib/payment/form/address.js +152 -0
- package/lib/payment/form/index.d.ts +9 -0
- package/lib/payment/form/index.js +464 -0
- package/lib/payment/form/phone.d.ts +4 -0
- package/lib/payment/form/phone.js +133 -0
- package/lib/payment/form/stripe.d.ts +13 -0
- package/lib/payment/form/stripe.js +213 -0
- package/lib/payment/header.d.ts +7 -0
- package/lib/payment/header.js +58 -0
- package/lib/payment/index.d.ts +28 -0
- package/lib/payment/index.js +382 -0
- package/lib/payment/product-card.d.ts +21 -0
- package/lib/payment/product-card.js +81 -0
- package/lib/payment/product-item.d.ts +19 -0
- package/lib/payment/product-item.js +160 -0
- package/lib/payment/product-skeleton.d.ts +4 -0
- package/lib/payment/product-skeleton.js +71 -0
- package/lib/payment/skeleton/overview.d.ts +2 -0
- package/lib/payment/skeleton/overview.js +48 -0
- package/lib/payment/skeleton/payment.d.ts +2 -0
- package/lib/payment/skeleton/payment.js +54 -0
- package/lib/payment/success.d.ts +8 -0
- package/lib/payment/success.js +215 -0
- package/lib/payment/summary.d.ts +12 -0
- package/lib/payment/summary.js +225 -0
- package/lib/theme.d.ts +1 -0
- package/lib/theme.js +19 -0
- package/lib/types/index.d.ts +19 -0
- package/lib/types/index.js +1 -0
- package/lib/types/shims.d.ts +18 -0
- package/lib/util.d.ts +52 -0
- package/lib/util.js +487 -0
- package/package.json +104 -0
- package/src/api.ts +24 -0
- package/src/checkout/index.tsx +74 -0
- package/src/components/input.tsx +58 -0
- package/src/components/livemode.tsx +23 -0
- package/src/components/pricing-table.tsx +207 -0
- package/src/components/status.tsx +19 -0
- package/src/components/switch.tsx +48 -0
- package/src/contexts/payment.tsx +74 -0
- package/src/dayjs.ts +17 -0
- package/src/index.ts +32 -0
- package/src/locales/en.tsx +218 -0
- package/src/locales/index.tsx +30 -0
- package/src/locales/zh.tsx +214 -0
- package/src/payment/amount.tsx +24 -0
- package/src/payment/error.tsx +29 -0
- package/src/payment/footer.tsx +12 -0
- package/src/payment/form/addon.tsx +24 -0
- package/src/payment/form/address.tsx +119 -0
- package/src/payment/form/index.tsx +401 -0
- package/src/payment/form/phone.tsx +103 -0
- package/src/payment/form/stripe.tsx +195 -0
- package/src/payment/header.tsx +40 -0
- package/src/payment/index.tsx +367 -0
- package/src/payment/product-card.tsx +55 -0
- package/src/payment/product-item.tsx +121 -0
- package/src/payment/product-skeleton.tsx +39 -0
- package/src/payment/skeleton/overview.tsx +21 -0
- package/src/payment/skeleton/payment.tsx +35 -0
- package/src/payment/success.tsx +186 -0
- package/src/payment/summary.tsx +198 -0
- package/src/theme.ts +18 -0
- package/src/types/index.ts +29 -0
- package/src/types/shims.d.ts +18 -0
- package/src/util.ts +543 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
declare module '@arcblock/ux/*';
|
|
2
|
+
declare module '@arcblock/did-connect/*';
|
|
3
|
+
|
|
4
|
+
declare module '*.png';
|
|
5
|
+
|
|
6
|
+
declare module 'google-libphonenumber';
|
|
7
|
+
|
|
8
|
+
declare module 'flat';
|
|
9
|
+
|
|
10
|
+
declare module '@arcblock/*';
|
|
11
|
+
|
|
12
|
+
declare module '@blocklet/*';
|
|
13
|
+
|
|
14
|
+
declare module 'pretty-ms-i18n';
|
|
15
|
+
|
|
16
|
+
declare interface Window {
|
|
17
|
+
blocklet: any;
|
|
18
|
+
}
|
package/lib/util.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import type { PriceCurrency, PriceRecurring, TCheckoutSessionExpanded, TLineItemExpanded, TPaymentCurrency, TPaymentMethodExpanded, TPrice, TSubscriptionExpanded } from '@blocklet/payment-types';
|
|
3
|
+
export declare const PAYMENT_KIT_DID = "z2qaCNvKMv5GjouKdcDWexv6WqtHbpNPQDnAk";
|
|
4
|
+
export declare const getPrefix: () => any;
|
|
5
|
+
export declare function formatToDate(date: Date | string | number, locale?: string): any;
|
|
6
|
+
export declare function formatToDatetime(date: Date | string | number, locale?: string): any;
|
|
7
|
+
export declare function formatTime(date: Date | string | number, format?: string, locale?: string): any;
|
|
8
|
+
export declare function formatDateTime(date: Date | string | number, locale?: string): any;
|
|
9
|
+
export declare const formatLocale: (locale?: string) => string;
|
|
10
|
+
export declare const formatPrettyMsLocale: (locale: string) => "zh_CN" | "en_US";
|
|
11
|
+
export declare const formatError: (err: any) => any;
|
|
12
|
+
export declare const formatPrice: (price: TPrice, currency: TPaymentCurrency, unit_label?: string, quantity?: number, bn?: boolean, locale?: string) => string;
|
|
13
|
+
export declare const formatPriceAmount: (price: TPrice, currency: TPaymentCurrency, unit_label?: string, quantity?: number, bn?: boolean) => string;
|
|
14
|
+
export declare function getStatementDescriptor(items: any[]): any;
|
|
15
|
+
export declare function formatRecurring(recurring: PriceRecurring, translate?: boolean, separator?: string, locale?: string): string;
|
|
16
|
+
export declare function getPriceUintAmountByCurrency(price: TPrice, currency: TPaymentCurrency): string;
|
|
17
|
+
export declare function getPriceCurrencyOptions(price: TPrice): PriceCurrency[];
|
|
18
|
+
export declare function formatLineItemPricing(item: TLineItemExpanded, currency: TPaymentCurrency, trial: number, locale?: string): {
|
|
19
|
+
primary: string;
|
|
20
|
+
secondary?: string;
|
|
21
|
+
quantity: string;
|
|
22
|
+
};
|
|
23
|
+
export declare function getCheckoutAmount(items: TLineItemExpanded[], currency: TPaymentCurrency, includeFreeTrial?: boolean, upsell?: boolean): {
|
|
24
|
+
subtotal: any;
|
|
25
|
+
total: any;
|
|
26
|
+
renew: any;
|
|
27
|
+
discount: string;
|
|
28
|
+
shipping: string;
|
|
29
|
+
tax: string;
|
|
30
|
+
};
|
|
31
|
+
export declare function getRecurringPeriod(recurring: PriceRecurring): number;
|
|
32
|
+
export declare function formatUpsellSaving(session: TCheckoutSessionExpanded, currency: TPaymentCurrency): string;
|
|
33
|
+
export declare function formatCheckoutHeadlines(session: TCheckoutSessionExpanded, currency: TPaymentCurrency, locale?: string): {
|
|
34
|
+
action: string;
|
|
35
|
+
amount: string;
|
|
36
|
+
then?: string;
|
|
37
|
+
secondary?: string;
|
|
38
|
+
};
|
|
39
|
+
export declare function formatAmount(amount: string, decimals: number): string;
|
|
40
|
+
export declare function findCurrency(methods: TPaymentMethodExpanded[], currencyId: string): import("sequelize").InferAttributes<import("@blocklet/payment-types").PaymentCurrency, {
|
|
41
|
+
omit: never;
|
|
42
|
+
}> | null;
|
|
43
|
+
export declare function isValidCountry(code: string): boolean;
|
|
44
|
+
export declare function stopEvent(e: React.SyntheticEvent<any>): void;
|
|
45
|
+
export declare function sleep(ms: number): Promise<unknown>;
|
|
46
|
+
export declare const getSubscriptionTimeSummary: (subscription: TSubscriptionExpanded) => string;
|
|
47
|
+
export declare const getSubscriptionAction: (subscription: TSubscriptionExpanded) => {
|
|
48
|
+
action: string;
|
|
49
|
+
variant: string;
|
|
50
|
+
color: string;
|
|
51
|
+
} | null;
|
|
52
|
+
export declare const mergeExtraParams: (extra?: Record<string, any>) => string;
|
package/lib/util.js
ADDED
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.PAYMENT_KIT_DID = void 0;
|
|
7
|
+
exports.findCurrency = findCurrency;
|
|
8
|
+
exports.formatAmount = formatAmount;
|
|
9
|
+
exports.formatCheckoutHeadlines = formatCheckoutHeadlines;
|
|
10
|
+
exports.formatDateTime = formatDateTime;
|
|
11
|
+
exports.formatError = void 0;
|
|
12
|
+
exports.formatLineItemPricing = formatLineItemPricing;
|
|
13
|
+
exports.formatPriceAmount = exports.formatPrice = exports.formatPrettyMsLocale = exports.formatLocale = void 0;
|
|
14
|
+
exports.formatRecurring = formatRecurring;
|
|
15
|
+
exports.formatTime = formatTime;
|
|
16
|
+
exports.formatToDate = formatToDate;
|
|
17
|
+
exports.formatToDatetime = formatToDatetime;
|
|
18
|
+
exports.formatUpsellSaving = formatUpsellSaving;
|
|
19
|
+
exports.getCheckoutAmount = getCheckoutAmount;
|
|
20
|
+
exports.getPrefix = void 0;
|
|
21
|
+
exports.getPriceCurrencyOptions = getPriceCurrencyOptions;
|
|
22
|
+
exports.getPriceUintAmountByCurrency = getPriceUintAmountByCurrency;
|
|
23
|
+
exports.getRecurringPeriod = getRecurringPeriod;
|
|
24
|
+
exports.getStatementDescriptor = getStatementDescriptor;
|
|
25
|
+
exports.getSubscriptionTimeSummary = exports.getSubscriptionAction = void 0;
|
|
26
|
+
exports.isValidCountry = isValidCountry;
|
|
27
|
+
exports.mergeExtraParams = void 0;
|
|
28
|
+
exports.sleep = sleep;
|
|
29
|
+
exports.stopEvent = stopEvent;
|
|
30
|
+
var _util = require("@ocap/util");
|
|
31
|
+
var _reactInternationalPhone = require("react-international-phone");
|
|
32
|
+
var _dayjs = _interopRequireDefault(require("./dayjs"));
|
|
33
|
+
var _index = require("./locales/index");
|
|
34
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
35
|
+
const PAYMENT_KIT_DID = exports.PAYMENT_KIT_DID = "z2qaCNvKMv5GjouKdcDWexv6WqtHbpNPQDnAk";
|
|
36
|
+
const getPrefix = () => {
|
|
37
|
+
const componentId = (window.blocklet.componentId || "").split("/").pop();
|
|
38
|
+
if (componentId === PAYMENT_KIT_DID) {
|
|
39
|
+
return window.blocklet.prefix;
|
|
40
|
+
}
|
|
41
|
+
const component = (window.blocklet.componentMountPoints || []).find(x => x.did === PAYMENT_KIT_DID);
|
|
42
|
+
if (component) {
|
|
43
|
+
return component.mountPoint;
|
|
44
|
+
}
|
|
45
|
+
return window.blocklet.prefix;
|
|
46
|
+
};
|
|
47
|
+
exports.getPrefix = getPrefix;
|
|
48
|
+
function formatToDate(date, locale = "en") {
|
|
49
|
+
if (!date) {
|
|
50
|
+
return "-";
|
|
51
|
+
}
|
|
52
|
+
return (0, _dayjs.default)(date).locale(formatLocale(locale)).format("YYYY-MM-DD HH:mm:ss");
|
|
53
|
+
}
|
|
54
|
+
function formatToDatetime(date, locale = "en") {
|
|
55
|
+
if (!date) {
|
|
56
|
+
return "-";
|
|
57
|
+
}
|
|
58
|
+
return (0, _dayjs.default)(date).locale(formatLocale(locale)).format("lll");
|
|
59
|
+
}
|
|
60
|
+
function formatTime(date, format = "YYYY-MM-DD HH:mm:ss", locale = "en") {
|
|
61
|
+
if (!date) {
|
|
62
|
+
return "-";
|
|
63
|
+
}
|
|
64
|
+
return (0, _dayjs.default)(date).locale(formatLocale(locale)).format(format);
|
|
65
|
+
}
|
|
66
|
+
function formatDateTime(date, locale = "en") {
|
|
67
|
+
return (0, _dayjs.default)(date).locale(formatLocale(locale)).format("YYYY-MM-DD HH:mm");
|
|
68
|
+
}
|
|
69
|
+
const formatLocale = (locale = "en") => {
|
|
70
|
+
if (locale === "tw") {
|
|
71
|
+
return "zh";
|
|
72
|
+
}
|
|
73
|
+
return locale;
|
|
74
|
+
};
|
|
75
|
+
exports.formatLocale = formatLocale;
|
|
76
|
+
const formatPrettyMsLocale = locale => locale === "zh" ? "zh_CN" : "en_US";
|
|
77
|
+
exports.formatPrettyMsLocale = formatPrettyMsLocale;
|
|
78
|
+
const formatError = err => {
|
|
79
|
+
const {
|
|
80
|
+
details,
|
|
81
|
+
errors,
|
|
82
|
+
response
|
|
83
|
+
} = err;
|
|
84
|
+
if (Array.isArray(errors)) {
|
|
85
|
+
return errors.map(x => x.message).join("\n");
|
|
86
|
+
}
|
|
87
|
+
if (Array.isArray(details)) {
|
|
88
|
+
const formatted = details.map(e => {
|
|
89
|
+
const errorMessage = e.message.replace(/["]/g, "'");
|
|
90
|
+
const errorPath = e.path.join(".");
|
|
91
|
+
return `${errorPath}: ${errorMessage}`;
|
|
92
|
+
});
|
|
93
|
+
return `Validate failed: ${formatted.join(";")}`;
|
|
94
|
+
}
|
|
95
|
+
if (response) {
|
|
96
|
+
return response.data.error || `${err.message}: ${JSON.stringify(response.data)}`;
|
|
97
|
+
}
|
|
98
|
+
return err.message;
|
|
99
|
+
};
|
|
100
|
+
exports.formatError = formatError;
|
|
101
|
+
const formatPrice = (price, currency, unit_label, quantity = 1, bn = true, locale = "en") => {
|
|
102
|
+
const unit = getPriceUintAmountByCurrency(price, currency);
|
|
103
|
+
const amount = bn ? (0, _util.fromUnitToToken)(new _util.BN(unit).mul(new _util.BN(quantity)), currency.decimal).toString() : +unit * quantity;
|
|
104
|
+
if (price?.type === "recurring" && price.recurring) {
|
|
105
|
+
const recurring = formatRecurring(price.recurring, false, "slash", locale);
|
|
106
|
+
if (unit_label) {
|
|
107
|
+
return `${amount} ${currency.symbol} / ${unit_label} ${recurring}`;
|
|
108
|
+
}
|
|
109
|
+
if (price.recurring.usage_type === "metered") {
|
|
110
|
+
return `${amount} ${currency.symbol} / unit ${recurring}`;
|
|
111
|
+
}
|
|
112
|
+
return `${amount} ${currency.symbol} ${recurring}`;
|
|
113
|
+
}
|
|
114
|
+
return `${amount} ${currency.symbol}`;
|
|
115
|
+
};
|
|
116
|
+
exports.formatPrice = formatPrice;
|
|
117
|
+
const formatPriceAmount = (price, currency, unit_label, quantity = 1, bn = true) => {
|
|
118
|
+
const unit = getPriceUintAmountByCurrency(price, currency);
|
|
119
|
+
const amount = bn ? (0, _util.fromUnitToToken)(new _util.BN(unit).mul(new _util.BN(quantity)), currency.decimal).toString() : +unit * quantity;
|
|
120
|
+
if (price?.type === "recurring" && price.recurring) {
|
|
121
|
+
if (unit_label) {
|
|
122
|
+
return `${amount} ${currency.symbol} / ${unit_label}`;
|
|
123
|
+
}
|
|
124
|
+
if (price.recurring.usage_type === "metered") {
|
|
125
|
+
return `${amount} ${currency.symbol} / unit`;
|
|
126
|
+
}
|
|
127
|
+
return `${amount} ${currency.symbol}`;
|
|
128
|
+
}
|
|
129
|
+
return `${amount} ${currency.symbol}`;
|
|
130
|
+
};
|
|
131
|
+
exports.formatPriceAmount = formatPriceAmount;
|
|
132
|
+
function getStatementDescriptor(items) {
|
|
133
|
+
for (const item of items) {
|
|
134
|
+
if (item.price?.product?.statement_descriptor) {
|
|
135
|
+
return item.price?.product?.statement_descriptor;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return window.blocklet.appName;
|
|
139
|
+
}
|
|
140
|
+
function formatRecurring(recurring, translate = true, separator = "per", locale = "en") {
|
|
141
|
+
const intervals = {
|
|
142
|
+
hour: "hourly",
|
|
143
|
+
day: "daily",
|
|
144
|
+
week: "weekly",
|
|
145
|
+
month: "monthly",
|
|
146
|
+
year: "yearly"
|
|
147
|
+
};
|
|
148
|
+
if (+recurring.interval_count === 1) {
|
|
149
|
+
const interval = (0, _index.t)(`common.${recurring.interval}`, locale);
|
|
150
|
+
return translate ? (0, _index.t)(`common.${intervals[recurring.interval]}`, locale) : separator ? (0, _index.t)(`common.${separator}`, locale, {
|
|
151
|
+
interval
|
|
152
|
+
}) : interval;
|
|
153
|
+
}
|
|
154
|
+
return (0, _index.t)("common.recurring", locale, {
|
|
155
|
+
count: recurring.interval_count,
|
|
156
|
+
interval: (0, _index.t)(`common.${recurring.interval}s`, locale)
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
function getPriceUintAmountByCurrency(price, currency) {
|
|
160
|
+
const options = getPriceCurrencyOptions(price);
|
|
161
|
+
const option = options.find(x => x.currency_id === currency.id);
|
|
162
|
+
if (option) {
|
|
163
|
+
return option.unit_amount;
|
|
164
|
+
}
|
|
165
|
+
return price.unit_amount;
|
|
166
|
+
}
|
|
167
|
+
function getPriceCurrencyOptions(price) {
|
|
168
|
+
if (Array.isArray(price.currency_options)) {
|
|
169
|
+
return price.currency_options;
|
|
170
|
+
}
|
|
171
|
+
return [{
|
|
172
|
+
currency_id: price.currency_id,
|
|
173
|
+
unit_amount: price.unit_amount,
|
|
174
|
+
tiers: null,
|
|
175
|
+
custom_unit_amount: null
|
|
176
|
+
}];
|
|
177
|
+
}
|
|
178
|
+
function formatLineItemPricing(item, currency, trial, locale = "en") {
|
|
179
|
+
const price = item.upsell_price || item.price;
|
|
180
|
+
let quantity = (0, _index.t)("common.qty", locale, {
|
|
181
|
+
count: item.quantity
|
|
182
|
+
});
|
|
183
|
+
if (price.recurring?.usage_type === "metered" || +item.quantity === 1) {
|
|
184
|
+
quantity = "";
|
|
185
|
+
}
|
|
186
|
+
const total = `${(0, _util.fromUnitToToken)(new _util.BN(getPriceUintAmountByCurrency(price, currency)).mul(new _util.BN(item.quantity)), currency.decimal)} ${currency.symbol}`;
|
|
187
|
+
const unit = `${(0, _util.fromUnitToToken)(getPriceUintAmountByCurrency(price, currency))} ${currency.symbol}`;
|
|
188
|
+
const appendUnit = (v, alt) => {
|
|
189
|
+
if (price.product.unit_label) {
|
|
190
|
+
return `${v}/${price.product.unit_label}`;
|
|
191
|
+
}
|
|
192
|
+
if (price.recurring?.usage_type === "metered" || item.quantity === 1) {
|
|
193
|
+
return alt;
|
|
194
|
+
}
|
|
195
|
+
return quantity ? (0, _index.t)("common.each", locale, {
|
|
196
|
+
unit
|
|
197
|
+
}) : "";
|
|
198
|
+
};
|
|
199
|
+
if (price.type === "recurring" && price.recurring) {
|
|
200
|
+
if (trial > 0) {
|
|
201
|
+
return {
|
|
202
|
+
primary: (0, _index.t)("common.trial", locale, {
|
|
203
|
+
count: trial
|
|
204
|
+
}),
|
|
205
|
+
secondary: `${appendUnit(total, total)} ${formatRecurring(price.recurring, false, "slash", locale)}`,
|
|
206
|
+
quantity
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
return {
|
|
210
|
+
primary: total,
|
|
211
|
+
secondary: appendUnit(total, ""),
|
|
212
|
+
quantity
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
primary: total,
|
|
217
|
+
secondary: appendUnit(total, ""),
|
|
218
|
+
quantity
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function getCheckoutAmount(items, currency, includeFreeTrial = false, upsell = true) {
|
|
222
|
+
let renew = new _util.BN(0);
|
|
223
|
+
const total = items.reduce((acc, x) => {
|
|
224
|
+
const price = upsell ? x.upsell_price || x.price : x.price;
|
|
225
|
+
if (price.type === "recurring") {
|
|
226
|
+
renew = renew.add(new _util.BN(getPriceUintAmountByCurrency(price, currency)).mul(new _util.BN(x.quantity)));
|
|
227
|
+
if (includeFreeTrial) {
|
|
228
|
+
return acc;
|
|
229
|
+
}
|
|
230
|
+
if (price.recurring?.usage_type === "metered") {
|
|
231
|
+
return acc;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
return acc.add(new _util.BN(getPriceUintAmountByCurrency(price, currency)).mul(new _util.BN(x.quantity)));
|
|
235
|
+
}, new _util.BN(0)).toString();
|
|
236
|
+
return {
|
|
237
|
+
subtotal: total,
|
|
238
|
+
total,
|
|
239
|
+
renew: renew.toString(),
|
|
240
|
+
discount: "0",
|
|
241
|
+
shipping: "0",
|
|
242
|
+
tax: "0"
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
function getRecurringPeriod(recurring) {
|
|
246
|
+
const {
|
|
247
|
+
interval
|
|
248
|
+
} = recurring;
|
|
249
|
+
const count = +recurring.interval_count || 1;
|
|
250
|
+
const dayInMs = 24 * 60 * 60 * 1e3;
|
|
251
|
+
switch (interval) {
|
|
252
|
+
case "hour":
|
|
253
|
+
return 60 * 60 * 1e3;
|
|
254
|
+
case "day":
|
|
255
|
+
return count * dayInMs;
|
|
256
|
+
case "week":
|
|
257
|
+
return count * 7 * dayInMs;
|
|
258
|
+
case "month":
|
|
259
|
+
return count * 30 * dayInMs;
|
|
260
|
+
case "year":
|
|
261
|
+
return count * 365 * dayInMs;
|
|
262
|
+
default:
|
|
263
|
+
throw new Error(`Unsupported recurring interval: ${interval}`);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
function formatUpsellSaving(session, currency) {
|
|
267
|
+
const items = session.line_items;
|
|
268
|
+
if (items[0]?.upsell_price_id) {
|
|
269
|
+
return "0";
|
|
270
|
+
}
|
|
271
|
+
if (!items[0]?.price.upsell?.upsells_to) {
|
|
272
|
+
return "0";
|
|
273
|
+
}
|
|
274
|
+
const from = getCheckoutAmount(items, currency, false, false);
|
|
275
|
+
const to = getCheckoutAmount(items.map(x => ({
|
|
276
|
+
...x,
|
|
277
|
+
upsell_price_id: x.price.upsell?.upsells_to_id,
|
|
278
|
+
upsell_price: x.price.upsell?.upsells_to
|
|
279
|
+
})), currency, false, true);
|
|
280
|
+
const fromRecurring = items[0].price?.recurring;
|
|
281
|
+
const toRecurring = items[0].price?.upsell?.upsells_to?.recurring;
|
|
282
|
+
if (!fromRecurring || !toRecurring) {
|
|
283
|
+
return "0";
|
|
284
|
+
}
|
|
285
|
+
const factor = Math.floor(getRecurringPeriod(toRecurring) / getRecurringPeriod(fromRecurring));
|
|
286
|
+
const before = new _util.BN(from.total).mul(new _util.BN(factor));
|
|
287
|
+
const after = new _util.BN(to.total);
|
|
288
|
+
return Number(before.sub(after).mul(new _util.BN(100)).div(before).toString()).toFixed(0);
|
|
289
|
+
}
|
|
290
|
+
function formatCheckoutHeadlines(session, currency, locale = "en") {
|
|
291
|
+
const items = session.line_items;
|
|
292
|
+
const trial = session.subscription_data?.trial_period_days || 0;
|
|
293
|
+
const brand = getStatementDescriptor(items);
|
|
294
|
+
const {
|
|
295
|
+
total
|
|
296
|
+
} = getCheckoutAmount(items, currency, !!trial);
|
|
297
|
+
const amount = `${(0, _util.fromUnitToToken)(total, currency.decimal)} ${currency.symbol}`;
|
|
298
|
+
if (items.length === 0) {
|
|
299
|
+
return {
|
|
300
|
+
action: (0, _index.t)("payment.checkout.empty", locale),
|
|
301
|
+
amount: "0",
|
|
302
|
+
then: ""
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
const {
|
|
306
|
+
name
|
|
307
|
+
} = items[0]?.price.product || {
|
|
308
|
+
name: ""
|
|
309
|
+
};
|
|
310
|
+
if (items.every(x => x.price.type === "one_time")) {
|
|
311
|
+
const action = (0, _index.t)("payment.checkout.pay", locale, {
|
|
312
|
+
payee: brand
|
|
313
|
+
});
|
|
314
|
+
if (items.length > 1) {
|
|
315
|
+
return {
|
|
316
|
+
action,
|
|
317
|
+
amount
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
return {
|
|
321
|
+
action,
|
|
322
|
+
amount,
|
|
323
|
+
then: ""
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
const item = items.find(x => x.price.type === "recurring");
|
|
327
|
+
const recurring = formatRecurring((item?.upsell_price || item?.price)?.recurring, false, "per", locale);
|
|
328
|
+
if (items.every(x => x.price.type === "recurring")) {
|
|
329
|
+
const hasMetered = items.some(x => x.price.type === "recurring" && x.price.recurring?.usage_type === "metered");
|
|
330
|
+
const subscription2 = [hasMetered ? (0, _index.t)("payment.checkout.least", locale) : "", (0, _util.fromUnitToToken)(items.reduce((acc, x) => {
|
|
331
|
+
if (x.price.recurring?.usage_type === "metered") {
|
|
332
|
+
return acc;
|
|
333
|
+
}
|
|
334
|
+
return acc.add(new _util.BN(getPriceUintAmountByCurrency(x.price, currency)).mul(new _util.BN(x.quantity)));
|
|
335
|
+
}, new _util.BN(0)), currency.decimal), currency.symbol].filter(Boolean).join(" ");
|
|
336
|
+
if (items.length > 1) {
|
|
337
|
+
if (trial > 0) {
|
|
338
|
+
return {
|
|
339
|
+
action: (0, _index.t)("payment.checkout.try2", locale, {
|
|
340
|
+
name,
|
|
341
|
+
count: items.length - 1
|
|
342
|
+
}),
|
|
343
|
+
amount: (0, _index.t)("payment.checkout.free", locale, {
|
|
344
|
+
count: trial
|
|
345
|
+
}),
|
|
346
|
+
then: (0, _index.t)("payment.checkout.then", locale, {
|
|
347
|
+
subscription: subscription2,
|
|
348
|
+
recurring
|
|
349
|
+
})
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
return {
|
|
353
|
+
action: (0, _index.t)("payment.checkout.sub2", locale, {
|
|
354
|
+
name,
|
|
355
|
+
count: items.length - 1
|
|
356
|
+
}),
|
|
357
|
+
amount,
|
|
358
|
+
then: recurring
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
if (trial > 0) {
|
|
362
|
+
return {
|
|
363
|
+
action: (0, _index.t)("payment.checkout.try1", locale, {
|
|
364
|
+
name
|
|
365
|
+
}),
|
|
366
|
+
amount: (0, _index.t)("payment.checkout.free", locale, {
|
|
367
|
+
count: trial
|
|
368
|
+
}),
|
|
369
|
+
then: (0, _index.t)("payment.checkout.then", locale, {
|
|
370
|
+
subscription: subscription2,
|
|
371
|
+
recurring
|
|
372
|
+
})
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
return {
|
|
376
|
+
action: (0, _index.t)("payment.checkout.sub1", locale, {
|
|
377
|
+
name
|
|
378
|
+
}),
|
|
379
|
+
amount,
|
|
380
|
+
then: recurring
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
const subscription = (0, _util.fromUnitToToken)(items.filter(x => x.price.type === "recurring").reduce((acc, x) => {
|
|
384
|
+
if (x.price.recurring?.usage_type === "metered") {
|
|
385
|
+
return acc;
|
|
386
|
+
}
|
|
387
|
+
return acc.add(new _util.BN(getPriceUintAmountByCurrency(x.price, currency)).mul(new _util.BN(x.quantity)));
|
|
388
|
+
}, new _util.BN(0)), currency.decimal);
|
|
389
|
+
return {
|
|
390
|
+
action: (0, _index.t)("payment.checkout.pay", locale, {
|
|
391
|
+
payee: brand
|
|
392
|
+
}),
|
|
393
|
+
amount,
|
|
394
|
+
then: (0, _index.t)("payment.checkout.then", locale, {
|
|
395
|
+
subscription: `${subscription} ${currency.symbol}`,
|
|
396
|
+
recurring
|
|
397
|
+
})
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
function formatAmount(amount, decimals) {
|
|
401
|
+
return (0, _util.fromUnitToToken)(amount, decimals);
|
|
402
|
+
}
|
|
403
|
+
function findCurrency(methods, currencyId) {
|
|
404
|
+
for (const method of methods) {
|
|
405
|
+
for (const currency of method.payment_currencies) {
|
|
406
|
+
if (currency.id === currencyId) {
|
|
407
|
+
return currency;
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
return null;
|
|
412
|
+
}
|
|
413
|
+
function isValidCountry(code) {
|
|
414
|
+
return _reactInternationalPhone.defaultCountries.some(x => x[1] === code);
|
|
415
|
+
}
|
|
416
|
+
function stopEvent(e) {
|
|
417
|
+
try {
|
|
418
|
+
e.stopPropagation();
|
|
419
|
+
e.preventDefault();
|
|
420
|
+
} catch {}
|
|
421
|
+
}
|
|
422
|
+
function sleep(ms) {
|
|
423
|
+
return new Promise(resolve => {
|
|
424
|
+
setTimeout(resolve, ms);
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
const getSubscriptionTimeSummary = subscription => {
|
|
428
|
+
const lines = [`Started on ${formatToDate(subscription.start_date * 1e3)}`];
|
|
429
|
+
if (subscription.status === "active" || subscription.status === "trialing") {
|
|
430
|
+
if (subscription.cancel_at) {
|
|
431
|
+
lines.push(`will cancel on ${formatToDate(subscription.cancel_at * 1e3)}`);
|
|
432
|
+
} else if (subscription.cancel_at_period_end) {
|
|
433
|
+
lines.push(`will cancel on ${formatToDate(subscription.current_period_end * 1e3)}`);
|
|
434
|
+
} else {
|
|
435
|
+
lines.push(`will renew on ${formatToDate(subscription.current_period_end * 1e3)}`);
|
|
436
|
+
}
|
|
437
|
+
} else if (subscription.status === "past_due") {
|
|
438
|
+
lines.push(`will cancel on ${formatToDate(subscription.current_period_end * 1e3)}`);
|
|
439
|
+
} else if (subscription.status === "canceled") {
|
|
440
|
+
lines.push(`canceled on ${formatToDate(subscription.canceled_at * 1e3)}`);
|
|
441
|
+
}
|
|
442
|
+
return lines.join(", ");
|
|
443
|
+
};
|
|
444
|
+
exports.getSubscriptionTimeSummary = getSubscriptionTimeSummary;
|
|
445
|
+
const getSubscriptionAction = subscription => {
|
|
446
|
+
if (subscription.status !== "canceled" && subscription.cancel_at_period_end) {
|
|
447
|
+
return {
|
|
448
|
+
action: "recover",
|
|
449
|
+
variant: "contained",
|
|
450
|
+
color: "primary"
|
|
451
|
+
};
|
|
452
|
+
}
|
|
453
|
+
if (subscription.status === "active" || subscription.status === "trialing") {
|
|
454
|
+
if (subscription.cancel_at) {
|
|
455
|
+
return null;
|
|
456
|
+
}
|
|
457
|
+
if (subscription.cancel_at_period_end) {
|
|
458
|
+
return {
|
|
459
|
+
action: "recover",
|
|
460
|
+
variant: "contained",
|
|
461
|
+
color: "primary"
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
return {
|
|
465
|
+
action: "cancel",
|
|
466
|
+
variant: "outlined",
|
|
467
|
+
color: "inherit"
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
if (subscription.status === "past_due") {
|
|
471
|
+
return {
|
|
472
|
+
action: "pastDue",
|
|
473
|
+
variant: "contained",
|
|
474
|
+
color: "primary"
|
|
475
|
+
};
|
|
476
|
+
}
|
|
477
|
+
return null;
|
|
478
|
+
};
|
|
479
|
+
exports.getSubscriptionAction = getSubscriptionAction;
|
|
480
|
+
const mergeExtraParams = (extra = {}) => {
|
|
481
|
+
const params = new URLSearchParams(window.location.search);
|
|
482
|
+
Object.keys(extra).forEach(key => {
|
|
483
|
+
params.set(key, extra[key]);
|
|
484
|
+
});
|
|
485
|
+
return params.toString();
|
|
486
|
+
};
|
|
487
|
+
exports.mergeExtraParams = mergeExtraParams;
|
package/package.json
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@blocklet/payment-react",
|
|
3
|
+
"version": "1.13.113",
|
|
4
|
+
"description": "Reusable react components for payment kit v2",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"react",
|
|
7
|
+
"payment"
|
|
8
|
+
],
|
|
9
|
+
"author": "wangshijun<wangshijun2010@gmail.com>",
|
|
10
|
+
"homepage": "https://github.com/blocklet/payment-kit#readme",
|
|
11
|
+
"license": "Apache-2.0",
|
|
12
|
+
"main": "lib/index.js",
|
|
13
|
+
"module": "es/index.js",
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/blocklet/payment-kit.git"
|
|
17
|
+
},
|
|
18
|
+
"scripts": {
|
|
19
|
+
"lint": "tsc --noEmit && eslint src tests --ext js --ext jsx --ext ts --ext tsx",
|
|
20
|
+
"lint:fix": "npm run lint -- --fix",
|
|
21
|
+
"build": "tsc --noEmit && unbuild && node tools/auto-exports.js",
|
|
22
|
+
"watch": "CONSOLA_LEVEL=1 nodemon -e .jsx,.js,.ts,.tsx -w src -x 'yalc publish --push'",
|
|
23
|
+
"precommit": "CI=1 npm run lint",
|
|
24
|
+
"prepush": "CI=1 npm run lint",
|
|
25
|
+
"prepublish": "npm run build",
|
|
26
|
+
"test": "node tools/jest.js",
|
|
27
|
+
"coverage": "npm run test -- --coverage"
|
|
28
|
+
},
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/blocklet/payment-kit/issues"
|
|
31
|
+
},
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"import": "./es/index.js",
|
|
35
|
+
"require": "./lib/index.js"
|
|
36
|
+
},
|
|
37
|
+
"./lib/": {
|
|
38
|
+
"import": "./es/",
|
|
39
|
+
"require": "./lib/"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
"importSort": {
|
|
43
|
+
".js, .jsx, .mjs": {
|
|
44
|
+
"parser": "babylon",
|
|
45
|
+
"style": "module"
|
|
46
|
+
},
|
|
47
|
+
".ts, .tsx": {
|
|
48
|
+
"style": "module",
|
|
49
|
+
"parser": "typescript"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"dependencies": {
|
|
53
|
+
"@arcblock/did-connect": "^2.9.15",
|
|
54
|
+
"@arcblock/ux": "^2.9.15",
|
|
55
|
+
"@mui/icons-material": "^5.15.6",
|
|
56
|
+
"@mui/lab": "^5.0.0-alpha.162",
|
|
57
|
+
"@mui/material": "^5.15.6",
|
|
58
|
+
"@mui/styles": "^5.15.6",
|
|
59
|
+
"@mui/system": "^5.15.6",
|
|
60
|
+
"@ocap/util": "^1.18.108",
|
|
61
|
+
"@stripe/react-stripe-js": "^2.4.0",
|
|
62
|
+
"@stripe/stripe-js": "^2.2.0",
|
|
63
|
+
"ahooks": "^3.7.8",
|
|
64
|
+
"axios": "^0.27.2",
|
|
65
|
+
"dayjs": "^1.11.10",
|
|
66
|
+
"flat": "^5.0.2",
|
|
67
|
+
"google-libphonenumber": "^3.2.33",
|
|
68
|
+
"lodash": "^4.17.21",
|
|
69
|
+
"p-wait-for": "3",
|
|
70
|
+
"react-error-boundary": "^4.0.11",
|
|
71
|
+
"react-hook-form": "^7.48.2",
|
|
72
|
+
"react-international-phone": "^3.1.2",
|
|
73
|
+
"ufo": "^1.3.2",
|
|
74
|
+
"use-bus": "^2.5.2",
|
|
75
|
+
"validator": "^13.11.0"
|
|
76
|
+
},
|
|
77
|
+
"peerDependencies": {
|
|
78
|
+
"react": ">=18.1.0"
|
|
79
|
+
},
|
|
80
|
+
"publishConfig": {
|
|
81
|
+
"access": "public"
|
|
82
|
+
},
|
|
83
|
+
"devDependencies": {
|
|
84
|
+
"@arcblock/eslint-config-ts": "^0.2.4",
|
|
85
|
+
"@babel/cli": "^7.19.3",
|
|
86
|
+
"@babel/core": "^7.19.3",
|
|
87
|
+
"@babel/preset-env": "^7.19.3",
|
|
88
|
+
"@babel/preset-react": "^7.18.6",
|
|
89
|
+
"@blocklet/payment-types": "1.13.113",
|
|
90
|
+
"@types/react": "^18.2.42",
|
|
91
|
+
"@types/react-dom": "^18.2.17",
|
|
92
|
+
"eslint": "^8.56.0",
|
|
93
|
+
"glob": "^10.3.3",
|
|
94
|
+
"import-sort-style-module": "^6.0.0",
|
|
95
|
+
"jest": "^29.7.0",
|
|
96
|
+
"prettier": "^2.8.8",
|
|
97
|
+
"prettier-plugin-import-sort": "^0.0.7",
|
|
98
|
+
"ts-jest": "^29.1.2",
|
|
99
|
+
"type-fest": "^4.8.3",
|
|
100
|
+
"typescript": "^4.9.5",
|
|
101
|
+
"unbuild": "^2.0.0"
|
|
102
|
+
},
|
|
103
|
+
"gitHead": "d1a99d9bbdb06d4e7742d7741ec511fa0fee4663"
|
|
104
|
+
}
|
package/src/api.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { getLocale } from '@arcblock/ux/lib/Locale/context';
|
|
2
|
+
import axios from 'axios';
|
|
3
|
+
import isNull from 'lodash/isNull';
|
|
4
|
+
|
|
5
|
+
import { getPrefix } from './util';
|
|
6
|
+
|
|
7
|
+
const api = axios.create();
|
|
8
|
+
|
|
9
|
+
api.interceptors.request.use(
|
|
10
|
+
(config) => {
|
|
11
|
+
const prefix = getPrefix();
|
|
12
|
+
config.baseURL = prefix || '';
|
|
13
|
+
config.timeout = 8000;
|
|
14
|
+
|
|
15
|
+
const livemode = localStorage.getItem('livemode');
|
|
16
|
+
const locale = getLocale(window.blocklet.languages);
|
|
17
|
+
config.params = { ...(config.params || {}), livemode: isNull(livemode) ? true : JSON.parse(livemode), locale };
|
|
18
|
+
|
|
19
|
+
return config;
|
|
20
|
+
},
|
|
21
|
+
(err) => Promise.reject(err)
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
export default api;
|