@blocklet/payment-react 1.14.24 → 1.14.25
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/es/libs/util.d.ts +15 -2
- package/es/libs/util.js +44 -9
- package/es/locales/en.js +3 -2
- package/es/locales/zh.js +3 -2
- package/es/payment/form/currency.js +0 -10
- package/es/payment/index.js +1 -14
- package/es/payment/product-item.d.ts +3 -1
- package/es/payment/product-item.js +8 -4
- package/es/payment/summary.d.ts +3 -1
- package/es/payment/summary.js +6 -2
- package/lib/libs/util.d.ts +15 -2
- package/lib/libs/util.js +61 -9
- package/lib/locales/en.js +3 -2
- package/lib/locales/zh.js +3 -2
- package/lib/payment/form/currency.js +0 -10
- package/lib/payment/index.js +1 -14
- package/lib/payment/product-item.d.ts +3 -1
- package/lib/payment/product-item.js +11 -4
- package/lib/payment/summary.d.ts +3 -1
- package/lib/payment/summary.js +9 -2
- package/package.json +3 -3
- package/src/libs/util.ts +53 -10
- package/src/locales/en.tsx +3 -2
- package/src/locales/zh.tsx +3 -2
- package/src/payment/form/currency.tsx +0 -10
- package/src/payment/index.tsx +2 -14
- package/src/payment/product-item.tsx +8 -3
- package/src/payment/summary.tsx +6 -1
package/es/libs/util.d.ts
CHANGED
|
@@ -19,7 +19,10 @@ export declare function getStatementDescriptor(items: any[]): any;
|
|
|
19
19
|
export declare function formatRecurring(recurring: PriceRecurring, translate?: boolean, separator?: string, locale?: string): string;
|
|
20
20
|
export declare function getPriceUintAmountByCurrency(price: TPrice, currency: TPaymentCurrency): string;
|
|
21
21
|
export declare function getPriceCurrencyOptions(price: TPrice): PriceCurrency[];
|
|
22
|
-
export declare function formatLineItemPricing(item: TLineItemExpanded, currency: TPaymentCurrency,
|
|
22
|
+
export declare function formatLineItemPricing(item: TLineItemExpanded, currency: TPaymentCurrency, { trialEnd, trialInDays }: {
|
|
23
|
+
trialEnd: number;
|
|
24
|
+
trialInDays: number;
|
|
25
|
+
}, locale?: string): {
|
|
23
26
|
primary: string;
|
|
24
27
|
secondary?: string;
|
|
25
28
|
quantity: string;
|
|
@@ -47,7 +50,17 @@ export declare function formatPriceDisplay({ amount, then, actualAmount, showThe
|
|
|
47
50
|
actualAmount: string;
|
|
48
51
|
showThen?: boolean;
|
|
49
52
|
}, recurring: string, hasMetered: boolean, locale?: string): string;
|
|
50
|
-
export declare function
|
|
53
|
+
export declare function getFreeTrialTime({ trialInDays, trialEnd }: {
|
|
54
|
+
trialInDays: number;
|
|
55
|
+
trialEnd: number;
|
|
56
|
+
}, locale?: string): {
|
|
57
|
+
count: number;
|
|
58
|
+
interval: string;
|
|
59
|
+
};
|
|
60
|
+
export declare function formatCheckoutHeadlines(items: TLineItemExpanded[], currency: TPaymentCurrency, { trialInDays, trialEnd }: {
|
|
61
|
+
trialInDays: number;
|
|
62
|
+
trialEnd: number;
|
|
63
|
+
}, locale?: string): {
|
|
51
64
|
action: string;
|
|
52
65
|
amount: string;
|
|
53
66
|
then?: string;
|
package/es/libs/util.js
CHANGED
|
@@ -202,7 +202,7 @@ export function getPriceCurrencyOptions(price) {
|
|
|
202
202
|
}
|
|
203
203
|
];
|
|
204
204
|
}
|
|
205
|
-
export function formatLineItemPricing(item, currency,
|
|
205
|
+
export function formatLineItemPricing(item, currency, { trialEnd, trialInDays }, locale = "en") {
|
|
206
206
|
const price = item.upsell_price || item.price;
|
|
207
207
|
let quantity = t("common.qty", locale, { count: item.quantity });
|
|
208
208
|
if (price.recurring?.usage_type === "metered" || +item.quantity === 1) {
|
|
@@ -211,6 +211,7 @@ export function formatLineItemPricing(item, currency, trial, locale = "en") {
|
|
|
211
211
|
const unitValue = new BN(getPriceUintAmountByCurrency(price, currency));
|
|
212
212
|
const total = `${fromUnitToToken(unitValue.mul(new BN(item.quantity)), currency.decimal)} ${currency.symbol}`;
|
|
213
213
|
const unit = `${fromUnitToToken(unitValue, currency.decimal)} ${currency.symbol}`;
|
|
214
|
+
const trialResult = getFreeTrialTime({ trialInDays, trialEnd }, locale);
|
|
214
215
|
const appendUnit = (v, alt) => {
|
|
215
216
|
if (price.product.unit_label) {
|
|
216
217
|
return `${v}/${price.product.unit_label}`;
|
|
@@ -221,9 +222,9 @@ export function formatLineItemPricing(item, currency, trial, locale = "en") {
|
|
|
221
222
|
return quantity ? t("common.each", locale, { unit }) : "";
|
|
222
223
|
};
|
|
223
224
|
if (price.type === "recurring" && price.recurring) {
|
|
224
|
-
if (
|
|
225
|
+
if (trialResult.count > 0) {
|
|
225
226
|
return {
|
|
226
|
-
primary: t("common.trial", locale, { count:
|
|
227
|
+
primary: t("common.trial", locale, { count: trialResult.count, interval: trialResult.interval }),
|
|
227
228
|
secondary: `${appendUnit(total, total)} ${formatRecurring(price.recurring, false, "slash", locale)}`,
|
|
228
229
|
quantity
|
|
229
230
|
};
|
|
@@ -415,11 +416,43 @@ export function formatPriceDisplay({ amount, then, actualAmount, showThen }, rec
|
|
|
415
416
|
}
|
|
416
417
|
return [amount, then].filter(Boolean).join(" ");
|
|
417
418
|
}
|
|
418
|
-
export function
|
|
419
|
+
export function getFreeTrialTime({ trialInDays, trialEnd }, locale = "en") {
|
|
420
|
+
const now = dayjs().unix();
|
|
421
|
+
if (trialEnd > 0 && trialEnd > now) {
|
|
422
|
+
if (trialEnd - now < 3600) {
|
|
423
|
+
return {
|
|
424
|
+
count: Math.ceil((trialEnd - now) / 60),
|
|
425
|
+
interval: t("common.minute", locale)
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
if (trialEnd - now < 86400) {
|
|
429
|
+
return {
|
|
430
|
+
count: Math.ceil((trialEnd - now) / 3600),
|
|
431
|
+
interval: t("common.hour", locale)
|
|
432
|
+
};
|
|
433
|
+
}
|
|
434
|
+
return {
|
|
435
|
+
count: Math.ceil((trialEnd - now) / 86400),
|
|
436
|
+
interval: t("common.day", locale)
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
if (trialInDays > 0) {
|
|
440
|
+
return {
|
|
441
|
+
count: trialInDays,
|
|
442
|
+
interval: t("common.day", locale)
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
return {
|
|
446
|
+
count: 0,
|
|
447
|
+
interval: t("common.day", locale)
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
export function formatCheckoutHeadlines(items, currency, { trialInDays, trialEnd }, locale = "en") {
|
|
419
451
|
const brand = getStatementDescriptor(items);
|
|
420
452
|
const { total } = getCheckoutAmount(items, currency, trialInDays > 0);
|
|
421
453
|
const actualAmount = fromUnitToToken(total, currency.decimal);
|
|
422
454
|
const amount = `${fromUnitToToken(total, currency.decimal)} ${currency.symbol}`;
|
|
455
|
+
const trialResult = getFreeTrialTime({ trialInDays, trialEnd }, locale);
|
|
423
456
|
if (items.length === 0) {
|
|
424
457
|
return {
|
|
425
458
|
action: t("payment.checkout.empty", locale),
|
|
@@ -453,17 +486,19 @@ export function formatCheckoutHeadlines(items, currency, trialInDays, locale = "
|
|
|
453
486
|
if (x.price.recurring?.usage_type === "metered") {
|
|
454
487
|
return acc;
|
|
455
488
|
}
|
|
456
|
-
return acc.add(
|
|
489
|
+
return acc.add(
|
|
490
|
+
new BN(getPriceUintAmountByCurrency(x.upsell_price || x.price, currency)).mul(new BN(x.quantity))
|
|
491
|
+
);
|
|
457
492
|
}, new BN(0)),
|
|
458
493
|
currency.decimal
|
|
459
494
|
),
|
|
460
495
|
currency.symbol
|
|
461
496
|
].filter(Boolean).join(" ");
|
|
462
497
|
if (items.length > 1) {
|
|
463
|
-
if (
|
|
498
|
+
if (trialResult.count > 0) {
|
|
464
499
|
const result4 = {
|
|
465
500
|
action: t("payment.checkout.try2", locale, { name, count: items.length - 1 }),
|
|
466
|
-
amount: t("payment.checkout.free", locale, { count:
|
|
501
|
+
amount: t("payment.checkout.free", locale, { count: trialResult.count, interval: trialResult.interval }),
|
|
467
502
|
then: formatMeteredThen(subscription2, recurring, hasMetered && Number(subscription2) === 0, locale),
|
|
468
503
|
showThen: true,
|
|
469
504
|
actualAmount: "0"
|
|
@@ -485,10 +520,10 @@ export function formatCheckoutHeadlines(items, currency, trialInDays, locale = "
|
|
|
485
520
|
priceDisplay: formatPriceDisplay(result3, recurring, hasMetered, locale)
|
|
486
521
|
};
|
|
487
522
|
}
|
|
488
|
-
if (
|
|
523
|
+
if (trialResult.count > 0) {
|
|
489
524
|
const result3 = {
|
|
490
525
|
action: t("payment.checkout.try1", locale, { name }),
|
|
491
|
-
amount: t("payment.checkout.free", locale, { count:
|
|
526
|
+
amount: t("payment.checkout.free", locale, { count: trialResult.count, interval: trialResult.interval }),
|
|
492
527
|
then: formatMeteredThen(subscription2, recurring, hasMetered && Number(subscription2) === 0, locale),
|
|
493
528
|
showThen: true,
|
|
494
529
|
actualAmount: "0"
|
package/es/locales/en.js
CHANGED
|
@@ -60,9 +60,10 @@ export default flat({
|
|
|
60
60
|
continue: "Continue",
|
|
61
61
|
qty: "Qty {count}",
|
|
62
62
|
each: "{unit} each",
|
|
63
|
-
trial: "Free for {count}
|
|
63
|
+
trial: "Free for {count} {interval}{count > 1 ? 's' : ''}",
|
|
64
64
|
billed: "billed {rule}",
|
|
65
65
|
metered: "based on usage",
|
|
66
|
+
minute: "minute",
|
|
66
67
|
hour: "hour",
|
|
67
68
|
day: "day",
|
|
68
69
|
week: "week",
|
|
@@ -133,7 +134,7 @@ export default flat({
|
|
|
133
134
|
then: "Then {subscription} {recurring}",
|
|
134
135
|
meteredThen: "Then {recurring} based on usage",
|
|
135
136
|
metered: "{recurring} based on usage",
|
|
136
|
-
free: "{count}
|
|
137
|
+
free: "{count} {interval}{count > 1 ? 's' : ''} free",
|
|
137
138
|
least: "continue with at least",
|
|
138
139
|
completed: {
|
|
139
140
|
payment: "Thanks for your purchase",
|
package/es/locales/zh.js
CHANGED
|
@@ -60,9 +60,10 @@ export default flat({
|
|
|
60
60
|
continue: "\u7EE7\u7EED",
|
|
61
61
|
qty: "{count} \u4EF6",
|
|
62
62
|
each: "\u6BCF\u4EF6 {unit}",
|
|
63
|
-
trial: "\u514D\u8D39\u8BD5\u7528 {count}
|
|
63
|
+
trial: "\u514D\u8D39\u8BD5\u7528 {count} {interval}",
|
|
64
64
|
billed: "{rule}\u6536\u8D39",
|
|
65
65
|
metered: "\u6309\u7528\u91CF",
|
|
66
|
+
minute: "\u5206\u949F",
|
|
66
67
|
hour: "\u5C0F\u65F6",
|
|
67
68
|
day: "\u5929",
|
|
68
69
|
week: "\u5468",
|
|
@@ -133,7 +134,7 @@ export default flat({
|
|
|
133
134
|
then: "\u7136\u540E {subscription} {recurring}",
|
|
134
135
|
meteredThen: "\u7136\u540E{recurring}\u6309\u7528\u91CF\u8BA1\u8D39",
|
|
135
136
|
metered: "{recurring}\u6309\u7528\u91CF\u8BA1\u8D39",
|
|
136
|
-
free: "\u514D\u8D39\u8BD5\u7528 {count}
|
|
137
|
+
free: "\u514D\u8D39\u8BD5\u7528 {count} {interval}",
|
|
137
138
|
least: "\u81F3\u5C11",
|
|
138
139
|
completed: {
|
|
139
140
|
payment: "\u611F\u8C22\u60A8\u7684\u8D2D\u4E70",
|
|
@@ -61,16 +61,6 @@ const Root = styled("section")`
|
|
|
61
61
|
background: var(--backgrounds-bg-field, #f9fafb);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
// .cko-payment-card::before {
|
|
65
|
-
// content: '';
|
|
66
|
-
// position: absolute;
|
|
67
|
-
// right: 0;
|
|
68
|
-
// bottom: 0;
|
|
69
|
-
// border: 12px solid ${(props) => props.theme.palette.primary.main};
|
|
70
|
-
// border-top-color: transparent;
|
|
71
|
-
// border-left-color: transparent;
|
|
72
|
-
// }
|
|
73
|
-
|
|
74
64
|
.cko-payment-card-unselect {
|
|
75
65
|
border: 1px solid #ddd;
|
|
76
66
|
padding: 4px 8px;
|
package/es/payment/index.js
CHANGED
|
@@ -133,6 +133,7 @@ function PaymentInner({
|
|
|
133
133
|
{
|
|
134
134
|
items: state.checkoutSession.line_items,
|
|
135
135
|
trialInDays: state.checkoutSession.subscription_data?.trial_period_days || 0,
|
|
136
|
+
trialEnd: state.checkoutSession.subscription_data?.trial_end || 0,
|
|
136
137
|
billingThreshold: Math.max(
|
|
137
138
|
state.checkoutSession.subscription_data?.billing_threshold_amount || 0,
|
|
138
139
|
// @ts-ignore
|
|
@@ -321,23 +322,18 @@ export const Root = styled(Box)`
|
|
|
321
322
|
box-sizing: border-box;
|
|
322
323
|
display: flex;
|
|
323
324
|
flex-direction: column;
|
|
324
|
-
// justify-content: center;
|
|
325
325
|
align-items: center;
|
|
326
326
|
overflow: hidden;
|
|
327
|
-
// min-height: ${(props) => props.mode === "standalone" ? "100vh" : "auto"};
|
|
328
327
|
position: relative;
|
|
329
328
|
.cko-container {
|
|
330
329
|
overflow: hidden;
|
|
331
330
|
width: 100%;
|
|
332
|
-
// max-width: ${(props) => props.mode.endsWith("-minimal") ? "400px" : "1000px"};
|
|
333
331
|
display: flex;
|
|
334
332
|
flex-direction: row;
|
|
335
333
|
justify-content: center;
|
|
336
|
-
// gap: 4px;
|
|
337
334
|
position: relative;
|
|
338
335
|
flex: 1;
|
|
339
336
|
padding: 1px;
|
|
340
|
-
// padding: ${(props) => props.mode === "standalone" ? "0 16px" : "0"};
|
|
341
337
|
}
|
|
342
338
|
|
|
343
339
|
.base-card {
|
|
@@ -350,14 +346,11 @@ export const Root = styled(Box)`
|
|
|
350
346
|
}
|
|
351
347
|
|
|
352
348
|
.cko-overview {
|
|
353
|
-
// width: ${(props) => props.mode.endsWith("-minimal") ? "100%" : "400px"};
|
|
354
|
-
// min-height: ${(props) => props.mode === "standalone" ? "540px" : "auto"};
|
|
355
349
|
position: relative;
|
|
356
350
|
flex-direction: column;
|
|
357
351
|
display: ${(props) => props.mode.endsWith("-minimal") ? "none" : "flex"};
|
|
358
352
|
background: var(--backgrounds-bg-base);
|
|
359
353
|
min-height: 'auto';
|
|
360
|
-
// width: 502px;
|
|
361
354
|
}
|
|
362
355
|
.cko-header {
|
|
363
356
|
left: 0;
|
|
@@ -385,8 +378,6 @@ export const Root = styled(Box)`
|
|
|
385
378
|
|
|
386
379
|
.cko-payment {
|
|
387
380
|
width: 502px;
|
|
388
|
-
// width: ${(props) => props.mode.endsWith("-minimal") ? "100%" : "400px"};
|
|
389
|
-
// box-shadow: -4px 0px 8px 0px rgba(2, 7, 19, 0.04);
|
|
390
381
|
padding-left: ${(props) => props.mode === "standalone" ? "40px" : "20px"};
|
|
391
382
|
position: relative;
|
|
392
383
|
&:before {
|
|
@@ -411,10 +402,6 @@ export const Root = styled(Box)`
|
|
|
411
402
|
}
|
|
412
403
|
|
|
413
404
|
.cko-payment-form {
|
|
414
|
-
// .MuiInputAdornment-positionStart {
|
|
415
|
-
// width: 50px;
|
|
416
|
-
// }
|
|
417
|
-
|
|
418
405
|
.MuiFormLabel-root {
|
|
419
406
|
color: var(--foregrounds-fg-base, #010714);
|
|
420
407
|
font-weight: 500;
|
|
@@ -4,17 +4,19 @@ type Props = {
|
|
|
4
4
|
item: TLineItemExpanded;
|
|
5
5
|
items: TLineItemExpanded[];
|
|
6
6
|
trialInDays: number;
|
|
7
|
+
trialEnd?: number;
|
|
7
8
|
currency: TPaymentCurrency;
|
|
8
9
|
onUpsell: Function;
|
|
9
10
|
onDownsell: Function;
|
|
10
11
|
mode?: 'normal' | 'cross-sell';
|
|
11
12
|
children?: React.ReactNode;
|
|
12
13
|
};
|
|
13
|
-
declare function ProductItem({ item, items, trialInDays, currency, mode, children, onUpsell, onDownsell, }: Props): JSX.Element;
|
|
14
|
+
declare function ProductItem({ item, items, trialInDays, trialEnd, currency, mode, children, onUpsell, onDownsell, }: Props): JSX.Element;
|
|
14
15
|
declare namespace ProductItem {
|
|
15
16
|
var defaultProps: {
|
|
16
17
|
mode: string;
|
|
17
18
|
children: null;
|
|
19
|
+
trialEnd: number;
|
|
18
20
|
};
|
|
19
21
|
}
|
|
20
22
|
export default ProductItem;
|
|
@@ -12,14 +12,17 @@ import {
|
|
|
12
12
|
formatUpsellSaving
|
|
13
13
|
} from "../libs/util.js";
|
|
14
14
|
import ProductCard from "./product-card.js";
|
|
15
|
+
import dayjs from "../libs/dayjs.js";
|
|
15
16
|
ProductItem.defaultProps = {
|
|
16
17
|
mode: "normal",
|
|
17
|
-
children: null
|
|
18
|
+
children: null,
|
|
19
|
+
trialEnd: 0
|
|
18
20
|
};
|
|
19
21
|
export default function ProductItem({
|
|
20
22
|
item,
|
|
21
23
|
items,
|
|
22
24
|
trialInDays,
|
|
25
|
+
trialEnd = 0,
|
|
23
26
|
currency,
|
|
24
27
|
mode,
|
|
25
28
|
children,
|
|
@@ -27,18 +30,19 @@ export default function ProductItem({
|
|
|
27
30
|
onDownsell
|
|
28
31
|
}) {
|
|
29
32
|
const { t, locale } = useLocaleContext();
|
|
30
|
-
const pricing = formatLineItemPricing(item, currency, trialInDays, locale);
|
|
33
|
+
const pricing = formatLineItemPricing(item, currency, { trialEnd, trialInDays }, locale);
|
|
31
34
|
const saving = formatUpsellSaving(items, currency);
|
|
32
35
|
const metered = item.price?.recurring?.usage_type === "metered" ? t("common.metered") : "";
|
|
33
36
|
const canUpsell = mode === "normal" && items.length === 1;
|
|
34
37
|
const primaryText = useMemo(() => {
|
|
35
38
|
const price = item.upsell_price || item.price || {};
|
|
36
39
|
const isRecurring = price?.type === "recurring" && price?.recurring;
|
|
37
|
-
|
|
40
|
+
const trial = trialInDays > 0 || trialEnd > dayjs().unix();
|
|
41
|
+
if (isRecurring && !trial && price?.recurring?.usage_type !== "metered") {
|
|
38
42
|
return `${pricing.primary} ${price.recurring ? formatRecurring(price.recurring, false, "slash", locale) : ""}`;
|
|
39
43
|
}
|
|
40
44
|
return pricing.primary;
|
|
41
|
-
}, [trialInDays, pricing, item, locale]);
|
|
45
|
+
}, [trialInDays, trialEnd, pricing, item, locale]);
|
|
42
46
|
return /* @__PURE__ */ jsxs(Stack, { direction: "column", alignItems: "flex-start", spacing: 1, sx: { width: "100%" }, className: "product-item", children: [
|
|
43
47
|
/* @__PURE__ */ jsxs(Stack, { direction: "column", alignItems: "flex-start", sx: { width: "100%" }, className: "product-item-content", children: [
|
|
44
48
|
/* @__PURE__ */ jsxs(
|
package/es/payment/summary.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ type Props = {
|
|
|
4
4
|
items: TLineItemExpanded[];
|
|
5
5
|
currency: TPaymentCurrency;
|
|
6
6
|
trialInDays: number;
|
|
7
|
+
trialEnd?: number;
|
|
7
8
|
billingThreshold: number;
|
|
8
9
|
showStaking?: boolean;
|
|
9
10
|
onUpsell?: Function;
|
|
@@ -16,7 +17,7 @@ type Props = {
|
|
|
16
17
|
donationSettings?: DonationSettings;
|
|
17
18
|
action?: string;
|
|
18
19
|
};
|
|
19
|
-
declare function PaymentSummary({ items, currency, trialInDays, billingThreshold, onUpsell, onDownsell, onApplyCrossSell, onCancelCrossSell, onChangeAmount, checkoutSessionId, crossSellBehavior, showStaking, donationSettings, action, ...rest }: Props): import("react").JSX.Element;
|
|
20
|
+
declare function PaymentSummary({ items, currency, trialInDays, billingThreshold, onUpsell, onDownsell, onApplyCrossSell, onCancelCrossSell, onChangeAmount, checkoutSessionId, crossSellBehavior, showStaking, donationSettings, action, trialEnd, ...rest }: Props): import("react").JSX.Element;
|
|
20
21
|
declare namespace PaymentSummary {
|
|
21
22
|
var defaultProps: {
|
|
22
23
|
onUpsell: any;
|
|
@@ -29,6 +30,7 @@ declare namespace PaymentSummary {
|
|
|
29
30
|
showStaking: boolean;
|
|
30
31
|
donationSettings: null;
|
|
31
32
|
action: string;
|
|
33
|
+
trialEnd: number;
|
|
32
34
|
};
|
|
33
35
|
}
|
|
34
36
|
export default PaymentSummary;
|
package/es/payment/summary.js
CHANGED
|
@@ -83,7 +83,8 @@ PaymentSummary.defaultProps = {
|
|
|
83
83
|
crossSellBehavior: "",
|
|
84
84
|
showStaking: false,
|
|
85
85
|
donationSettings: null,
|
|
86
|
-
action: ""
|
|
86
|
+
action: "",
|
|
87
|
+
trialEnd: 0
|
|
87
88
|
};
|
|
88
89
|
export default function PaymentSummary({
|
|
89
90
|
items,
|
|
@@ -100,6 +101,7 @@ export default function PaymentSummary({
|
|
|
100
101
|
showStaking,
|
|
101
102
|
donationSettings,
|
|
102
103
|
action,
|
|
104
|
+
trialEnd = 0,
|
|
103
105
|
...rest
|
|
104
106
|
}) {
|
|
105
107
|
const { t, locale } = useLocaleContext();
|
|
@@ -109,7 +111,7 @@ export default function PaymentSummary({
|
|
|
109
111
|
const { data, runAsync } = useRequest(
|
|
110
112
|
() => checkoutSessionId ? fetchCrossSell(checkoutSessionId) : Promise.resolve(null)
|
|
111
113
|
);
|
|
112
|
-
const headlines = formatCheckoutHeadlines(items, currency, trialInDays, locale);
|
|
114
|
+
const headlines = formatCheckoutHeadlines(items, currency, { trialEnd, trialInDays }, locale);
|
|
113
115
|
const staking = showStaking ? getStakingSetup(items, currency, billingThreshold) : "0";
|
|
114
116
|
const totalAmount = fromUnitToToken(
|
|
115
117
|
new BN(fromTokenToUnit(headlines.actualAmount, currency?.decimal)).add(new BN(staking)).toString(),
|
|
@@ -180,6 +182,7 @@ export default function PaymentSummary({
|
|
|
180
182
|
item: x,
|
|
181
183
|
items,
|
|
182
184
|
trialInDays,
|
|
185
|
+
trialEnd,
|
|
183
186
|
currency,
|
|
184
187
|
onUpsell: handleUpsell,
|
|
185
188
|
onDownsell: handleDownsell,
|
|
@@ -209,6 +212,7 @@ export default function PaymentSummary({
|
|
|
209
212
|
items,
|
|
210
213
|
trialInDays,
|
|
211
214
|
currency,
|
|
215
|
+
trialEnd,
|
|
212
216
|
onUpsell: noop,
|
|
213
217
|
onDownsell: noop,
|
|
214
218
|
children: /* @__PURE__ */ jsxs(Stack, { direction: "row", alignItems: "center", justifyContent: "space-between", sx: { width: 1 }, children: [
|
package/lib/libs/util.d.ts
CHANGED
|
@@ -19,7 +19,10 @@ export declare function getStatementDescriptor(items: any[]): any;
|
|
|
19
19
|
export declare function formatRecurring(recurring: PriceRecurring, translate?: boolean, separator?: string, locale?: string): string;
|
|
20
20
|
export declare function getPriceUintAmountByCurrency(price: TPrice, currency: TPaymentCurrency): string;
|
|
21
21
|
export declare function getPriceCurrencyOptions(price: TPrice): PriceCurrency[];
|
|
22
|
-
export declare function formatLineItemPricing(item: TLineItemExpanded, currency: TPaymentCurrency,
|
|
22
|
+
export declare function formatLineItemPricing(item: TLineItemExpanded, currency: TPaymentCurrency, { trialEnd, trialInDays }: {
|
|
23
|
+
trialEnd: number;
|
|
24
|
+
trialInDays: number;
|
|
25
|
+
}, locale?: string): {
|
|
23
26
|
primary: string;
|
|
24
27
|
secondary?: string;
|
|
25
28
|
quantity: string;
|
|
@@ -47,7 +50,17 @@ export declare function formatPriceDisplay({ amount, then, actualAmount, showThe
|
|
|
47
50
|
actualAmount: string;
|
|
48
51
|
showThen?: boolean;
|
|
49
52
|
}, recurring: string, hasMetered: boolean, locale?: string): string;
|
|
50
|
-
export declare function
|
|
53
|
+
export declare function getFreeTrialTime({ trialInDays, trialEnd }: {
|
|
54
|
+
trialInDays: number;
|
|
55
|
+
trialEnd: number;
|
|
56
|
+
}, locale?: string): {
|
|
57
|
+
count: number;
|
|
58
|
+
interval: string;
|
|
59
|
+
};
|
|
60
|
+
export declare function formatCheckoutHeadlines(items: TLineItemExpanded[], currency: TPaymentCurrency, { trialInDays, trialEnd }: {
|
|
61
|
+
trialInDays: number;
|
|
62
|
+
trialEnd: number;
|
|
63
|
+
}, locale?: string): {
|
|
51
64
|
action: string;
|
|
52
65
|
amount: string;
|
|
53
66
|
then?: string;
|
package/lib/libs/util.js
CHANGED
|
@@ -28,6 +28,7 @@ exports.formatToDatetime = formatToDatetime;
|
|
|
28
28
|
exports.formatTotalPrice = formatTotalPrice;
|
|
29
29
|
exports.formatUpsellSaving = formatUpsellSaving;
|
|
30
30
|
exports.getCheckoutAmount = getCheckoutAmount;
|
|
31
|
+
exports.getFreeTrialTime = getFreeTrialTime;
|
|
31
32
|
exports.getInvoiceStatusColor = getInvoiceStatusColor;
|
|
32
33
|
exports.getPaymentIntentStatusColor = getPaymentIntentStatusColor;
|
|
33
34
|
exports.getPayoutStatusColor = getPayoutStatusColor;
|
|
@@ -266,7 +267,10 @@ function getPriceCurrencyOptions(price) {
|
|
|
266
267
|
tiers: null
|
|
267
268
|
}];
|
|
268
269
|
}
|
|
269
|
-
function formatLineItemPricing(item, currency,
|
|
270
|
+
function formatLineItemPricing(item, currency, {
|
|
271
|
+
trialEnd,
|
|
272
|
+
trialInDays
|
|
273
|
+
}, locale = "en") {
|
|
270
274
|
const price = item.upsell_price || item.price;
|
|
271
275
|
let quantity = (0, _locales.t)("common.qty", locale, {
|
|
272
276
|
count: item.quantity
|
|
@@ -277,6 +281,10 @@ function formatLineItemPricing(item, currency, trial, locale = "en") {
|
|
|
277
281
|
const unitValue = new _util.BN(getPriceUintAmountByCurrency(price, currency));
|
|
278
282
|
const total = `${(0, _util.fromUnitToToken)(unitValue.mul(new _util.BN(item.quantity)), currency.decimal)} ${currency.symbol}`;
|
|
279
283
|
const unit = `${(0, _util.fromUnitToToken)(unitValue, currency.decimal)} ${currency.symbol}`;
|
|
284
|
+
const trialResult = getFreeTrialTime({
|
|
285
|
+
trialInDays,
|
|
286
|
+
trialEnd
|
|
287
|
+
}, locale);
|
|
280
288
|
const appendUnit = (v, alt) => {
|
|
281
289
|
if (price.product.unit_label) {
|
|
282
290
|
return `${v}/${price.product.unit_label}`;
|
|
@@ -289,10 +297,11 @@ function formatLineItemPricing(item, currency, trial, locale = "en") {
|
|
|
289
297
|
}) : "";
|
|
290
298
|
};
|
|
291
299
|
if (price.type === "recurring" && price.recurring) {
|
|
292
|
-
if (
|
|
300
|
+
if (trialResult.count > 0) {
|
|
293
301
|
return {
|
|
294
302
|
primary: (0, _locales.t)("common.trial", locale, {
|
|
295
|
-
count:
|
|
303
|
+
count: trialResult.count,
|
|
304
|
+
interval: trialResult.interval
|
|
296
305
|
}),
|
|
297
306
|
secondary: `${appendUnit(total, total)} ${formatRecurring(price.recurring, false, "slash", locale)}`,
|
|
298
307
|
quantity
|
|
@@ -502,13 +511,54 @@ function formatPriceDisplay({
|
|
|
502
511
|
}
|
|
503
512
|
return [amount, then].filter(Boolean).join(" ");
|
|
504
513
|
}
|
|
505
|
-
function
|
|
514
|
+
function getFreeTrialTime({
|
|
515
|
+
trialInDays,
|
|
516
|
+
trialEnd
|
|
517
|
+
}, locale = "en") {
|
|
518
|
+
const now = (0, _dayjs.default)().unix();
|
|
519
|
+
if (trialEnd > 0 && trialEnd > now) {
|
|
520
|
+
if (trialEnd - now < 3600) {
|
|
521
|
+
return {
|
|
522
|
+
count: Math.ceil((trialEnd - now) / 60),
|
|
523
|
+
interval: (0, _locales.t)("common.minute", locale)
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
if (trialEnd - now < 86400) {
|
|
527
|
+
return {
|
|
528
|
+
count: Math.ceil((trialEnd - now) / 3600),
|
|
529
|
+
interval: (0, _locales.t)("common.hour", locale)
|
|
530
|
+
};
|
|
531
|
+
}
|
|
532
|
+
return {
|
|
533
|
+
count: Math.ceil((trialEnd - now) / 86400),
|
|
534
|
+
interval: (0, _locales.t)("common.day", locale)
|
|
535
|
+
};
|
|
536
|
+
}
|
|
537
|
+
if (trialInDays > 0) {
|
|
538
|
+
return {
|
|
539
|
+
count: trialInDays,
|
|
540
|
+
interval: (0, _locales.t)("common.day", locale)
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
return {
|
|
544
|
+
count: 0,
|
|
545
|
+
interval: (0, _locales.t)("common.day", locale)
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
function formatCheckoutHeadlines(items, currency, {
|
|
549
|
+
trialInDays,
|
|
550
|
+
trialEnd
|
|
551
|
+
}, locale = "en") {
|
|
506
552
|
const brand = getStatementDescriptor(items);
|
|
507
553
|
const {
|
|
508
554
|
total
|
|
509
555
|
} = getCheckoutAmount(items, currency, trialInDays > 0);
|
|
510
556
|
const actualAmount = (0, _util.fromUnitToToken)(total, currency.decimal);
|
|
511
557
|
const amount = `${(0, _util.fromUnitToToken)(total, currency.decimal)} ${currency.symbol}`;
|
|
558
|
+
const trialResult = getFreeTrialTime({
|
|
559
|
+
trialInDays,
|
|
560
|
+
trialEnd
|
|
561
|
+
}, locale);
|
|
512
562
|
if (items.length === 0) {
|
|
513
563
|
return {
|
|
514
564
|
action: (0, _locales.t)("payment.checkout.empty", locale),
|
|
@@ -551,17 +601,18 @@ function formatCheckoutHeadlines(items, currency, trialInDays, locale = "en") {
|
|
|
551
601
|
if (x.price.recurring?.usage_type === "metered") {
|
|
552
602
|
return acc;
|
|
553
603
|
}
|
|
554
|
-
return acc.add(new _util.BN(getPriceUintAmountByCurrency(x.price, currency)).mul(new _util.BN(x.quantity)));
|
|
604
|
+
return acc.add(new _util.BN(getPriceUintAmountByCurrency(x.upsell_price || x.price, currency)).mul(new _util.BN(x.quantity)));
|
|
555
605
|
}, new _util.BN(0)), currency.decimal), currency.symbol].filter(Boolean).join(" ");
|
|
556
606
|
if (items.length > 1) {
|
|
557
|
-
if (
|
|
607
|
+
if (trialResult.count > 0) {
|
|
558
608
|
const result4 = {
|
|
559
609
|
action: (0, _locales.t)("payment.checkout.try2", locale, {
|
|
560
610
|
name,
|
|
561
611
|
count: items.length - 1
|
|
562
612
|
}),
|
|
563
613
|
amount: (0, _locales.t)("payment.checkout.free", locale, {
|
|
564
|
-
count:
|
|
614
|
+
count: trialResult.count,
|
|
615
|
+
interval: trialResult.interval
|
|
565
616
|
}),
|
|
566
617
|
then: formatMeteredThen(subscription2, recurring, hasMetered && Number(subscription2) === 0, locale),
|
|
567
618
|
showThen: true,
|
|
@@ -589,13 +640,14 @@ function formatCheckoutHeadlines(items, currency, trialInDays, locale = "en") {
|
|
|
589
640
|
priceDisplay: formatPriceDisplay(result3, recurring, hasMetered, locale)
|
|
590
641
|
};
|
|
591
642
|
}
|
|
592
|
-
if (
|
|
643
|
+
if (trialResult.count > 0) {
|
|
593
644
|
const result3 = {
|
|
594
645
|
action: (0, _locales.t)("payment.checkout.try1", locale, {
|
|
595
646
|
name
|
|
596
647
|
}),
|
|
597
648
|
amount: (0, _locales.t)("payment.checkout.free", locale, {
|
|
598
|
-
count:
|
|
649
|
+
count: trialResult.count,
|
|
650
|
+
interval: trialResult.interval
|
|
599
651
|
}),
|
|
600
652
|
then: formatMeteredThen(subscription2, recurring, hasMetered && Number(subscription2) === 0, locale),
|
|
601
653
|
showThen: true,
|
package/lib/locales/en.js
CHANGED
|
@@ -67,9 +67,10 @@ module.exports = (0, _flat.default)({
|
|
|
67
67
|
continue: "Continue",
|
|
68
68
|
qty: "Qty {count}",
|
|
69
69
|
each: "{unit} each",
|
|
70
|
-
trial: "Free for {count}
|
|
70
|
+
trial: "Free for {count} {interval}{count > 1 ? 's' : ''}",
|
|
71
71
|
billed: "billed {rule}",
|
|
72
72
|
metered: "based on usage",
|
|
73
|
+
minute: "minute",
|
|
73
74
|
hour: "hour",
|
|
74
75
|
day: "day",
|
|
75
76
|
week: "week",
|
|
@@ -140,7 +141,7 @@ module.exports = (0, _flat.default)({
|
|
|
140
141
|
then: "Then {subscription} {recurring}",
|
|
141
142
|
meteredThen: "Then {recurring} based on usage",
|
|
142
143
|
metered: "{recurring} based on usage",
|
|
143
|
-
free: "{count}
|
|
144
|
+
free: "{count} {interval}{count > 1 ? 's' : ''} free",
|
|
144
145
|
least: "continue with at least",
|
|
145
146
|
completed: {
|
|
146
147
|
payment: "Thanks for your purchase",
|
package/lib/locales/zh.js
CHANGED
|
@@ -67,9 +67,10 @@ module.exports = (0, _flat.default)({
|
|
|
67
67
|
continue: "\u7EE7\u7EED",
|
|
68
68
|
qty: "{count} \u4EF6",
|
|
69
69
|
each: "\u6BCF\u4EF6 {unit}",
|
|
70
|
-
trial: "\u514D\u8D39\u8BD5\u7528 {count}
|
|
70
|
+
trial: "\u514D\u8D39\u8BD5\u7528 {count} {interval}",
|
|
71
71
|
billed: "{rule}\u6536\u8D39",
|
|
72
72
|
metered: "\u6309\u7528\u91CF",
|
|
73
|
+
minute: "\u5206\u949F",
|
|
73
74
|
hour: "\u5C0F\u65F6",
|
|
74
75
|
day: "\u5929",
|
|
75
76
|
week: "\u5468",
|
|
@@ -140,7 +141,7 @@ module.exports = (0, _flat.default)({
|
|
|
140
141
|
then: "\u7136\u540E {subscription} {recurring}",
|
|
141
142
|
meteredThen: "\u7136\u540E{recurring}\u6309\u7528\u91CF\u8BA1\u8D39",
|
|
142
143
|
metered: "{recurring}\u6309\u7528\u91CF\u8BA1\u8D39",
|
|
143
|
-
free: "\u514D\u8D39\u8BD5\u7528 {count}
|
|
144
|
+
free: "\u514D\u8D39\u8BD5\u7528 {count} {interval}",
|
|
144
145
|
least: "\u81F3\u5C11",
|
|
145
146
|
completed: {
|
|
146
147
|
payment: "\u611F\u8C22\u60A8\u7684\u8D2D\u4E70",
|
|
@@ -79,16 +79,6 @@ const Root = (0, _system.styled)("section")`
|
|
|
79
79
|
background: var(--backgrounds-bg-field, #f9fafb);
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
// .cko-payment-card::before {
|
|
83
|
-
// content: '';
|
|
84
|
-
// position: absolute;
|
|
85
|
-
// right: 0;
|
|
86
|
-
// bottom: 0;
|
|
87
|
-
// border: 12px solid ${props => props.theme.palette.primary.main};
|
|
88
|
-
// border-top-color: transparent;
|
|
89
|
-
// border-left-color: transparent;
|
|
90
|
-
// }
|
|
91
|
-
|
|
92
82
|
.cko-payment-card-unselect {
|
|
93
83
|
border: 1px solid #ddd;
|
|
94
84
|
padding: 4px 8px;
|
package/lib/payment/index.js
CHANGED
|
@@ -194,6 +194,7 @@ function PaymentInner({
|
|
|
194
194
|
children: [/* @__PURE__ */(0, _jsxRuntime.jsx)(_summary.default, {
|
|
195
195
|
items: state.checkoutSession.line_items,
|
|
196
196
|
trialInDays: state.checkoutSession.subscription_data?.trial_period_days || 0,
|
|
197
|
+
trialEnd: state.checkoutSession.subscription_data?.trial_end || 0,
|
|
197
198
|
billingThreshold: Math.max(state.checkoutSession.subscription_data?.billing_threshold_amount || 0,
|
|
198
199
|
// @ts-ignore
|
|
199
200
|
state.checkoutSession.subscription_data?.min_stake_amount || 0),
|
|
@@ -395,23 +396,18 @@ const Root = exports.Root = (0, _system.styled)(_material.Box)`
|
|
|
395
396
|
box-sizing: border-box;
|
|
396
397
|
display: flex;
|
|
397
398
|
flex-direction: column;
|
|
398
|
-
// justify-content: center;
|
|
399
399
|
align-items: center;
|
|
400
400
|
overflow: hidden;
|
|
401
|
-
// min-height: ${props => props.mode === "standalone" ? "100vh" : "auto"};
|
|
402
401
|
position: relative;
|
|
403
402
|
.cko-container {
|
|
404
403
|
overflow: hidden;
|
|
405
404
|
width: 100%;
|
|
406
|
-
// max-width: ${props => props.mode.endsWith("-minimal") ? "400px" : "1000px"};
|
|
407
405
|
display: flex;
|
|
408
406
|
flex-direction: row;
|
|
409
407
|
justify-content: center;
|
|
410
|
-
// gap: 4px;
|
|
411
408
|
position: relative;
|
|
412
409
|
flex: 1;
|
|
413
410
|
padding: 1px;
|
|
414
|
-
// padding: ${props => props.mode === "standalone" ? "0 16px" : "0"};
|
|
415
411
|
}
|
|
416
412
|
|
|
417
413
|
.base-card {
|
|
@@ -424,14 +420,11 @@ const Root = exports.Root = (0, _system.styled)(_material.Box)`
|
|
|
424
420
|
}
|
|
425
421
|
|
|
426
422
|
.cko-overview {
|
|
427
|
-
// width: ${props => props.mode.endsWith("-minimal") ? "100%" : "400px"};
|
|
428
|
-
// min-height: ${props => props.mode === "standalone" ? "540px" : "auto"};
|
|
429
423
|
position: relative;
|
|
430
424
|
flex-direction: column;
|
|
431
425
|
display: ${props => props.mode.endsWith("-minimal") ? "none" : "flex"};
|
|
432
426
|
background: var(--backgrounds-bg-base);
|
|
433
427
|
min-height: 'auto';
|
|
434
|
-
// width: 502px;
|
|
435
428
|
}
|
|
436
429
|
.cko-header {
|
|
437
430
|
left: 0;
|
|
@@ -459,8 +452,6 @@ const Root = exports.Root = (0, _system.styled)(_material.Box)`
|
|
|
459
452
|
|
|
460
453
|
.cko-payment {
|
|
461
454
|
width: 502px;
|
|
462
|
-
// width: ${props => props.mode.endsWith("-minimal") ? "100%" : "400px"};
|
|
463
|
-
// box-shadow: -4px 0px 8px 0px rgba(2, 7, 19, 0.04);
|
|
464
455
|
padding-left: ${props => props.mode === "standalone" ? "40px" : "20px"};
|
|
465
456
|
position: relative;
|
|
466
457
|
&:before {
|
|
@@ -485,10 +476,6 @@ const Root = exports.Root = (0, _system.styled)(_material.Box)`
|
|
|
485
476
|
}
|
|
486
477
|
|
|
487
478
|
.cko-payment-form {
|
|
488
|
-
// .MuiInputAdornment-positionStart {
|
|
489
|
-
// width: 50px;
|
|
490
|
-
// }
|
|
491
|
-
|
|
492
479
|
.MuiFormLabel-root {
|
|
493
480
|
color: var(--foregrounds-fg-base, #010714);
|
|
494
481
|
font-weight: 500;
|
|
@@ -4,17 +4,19 @@ type Props = {
|
|
|
4
4
|
item: TLineItemExpanded;
|
|
5
5
|
items: TLineItemExpanded[];
|
|
6
6
|
trialInDays: number;
|
|
7
|
+
trialEnd?: number;
|
|
7
8
|
currency: TPaymentCurrency;
|
|
8
9
|
onUpsell: Function;
|
|
9
10
|
onDownsell: Function;
|
|
10
11
|
mode?: 'normal' | 'cross-sell';
|
|
11
12
|
children?: React.ReactNode;
|
|
12
13
|
};
|
|
13
|
-
declare function ProductItem({ item, items, trialInDays, currency, mode, children, onUpsell, onDownsell, }: Props): JSX.Element;
|
|
14
|
+
declare function ProductItem({ item, items, trialInDays, trialEnd, currency, mode, children, onUpsell, onDownsell, }: Props): JSX.Element;
|
|
14
15
|
declare namespace ProductItem {
|
|
15
16
|
var defaultProps: {
|
|
16
17
|
mode: string;
|
|
17
18
|
children: null;
|
|
19
|
+
trialEnd: number;
|
|
18
20
|
};
|
|
19
21
|
}
|
|
20
22
|
export default ProductItem;
|
|
@@ -12,15 +12,18 @@ var _status = _interopRequireDefault(require("../components/status"));
|
|
|
12
12
|
var _switchButton = _interopRequireDefault(require("../components/switch-button"));
|
|
13
13
|
var _util = require("../libs/util");
|
|
14
14
|
var _productCard = _interopRequireDefault(require("./product-card"));
|
|
15
|
+
var _dayjs = _interopRequireDefault(require("../libs/dayjs"));
|
|
15
16
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
17
|
ProductItem.defaultProps = {
|
|
17
18
|
mode: "normal",
|
|
18
|
-
children: null
|
|
19
|
+
children: null,
|
|
20
|
+
trialEnd: 0
|
|
19
21
|
};
|
|
20
22
|
function ProductItem({
|
|
21
23
|
item,
|
|
22
24
|
items,
|
|
23
25
|
trialInDays,
|
|
26
|
+
trialEnd = 0,
|
|
24
27
|
currency,
|
|
25
28
|
mode,
|
|
26
29
|
children,
|
|
@@ -31,18 +34,22 @@ function ProductItem({
|
|
|
31
34
|
t,
|
|
32
35
|
locale
|
|
33
36
|
} = (0, _context.useLocaleContext)();
|
|
34
|
-
const pricing = (0, _util.formatLineItemPricing)(item, currency,
|
|
37
|
+
const pricing = (0, _util.formatLineItemPricing)(item, currency, {
|
|
38
|
+
trialEnd,
|
|
39
|
+
trialInDays
|
|
40
|
+
}, locale);
|
|
35
41
|
const saving = (0, _util.formatUpsellSaving)(items, currency);
|
|
36
42
|
const metered = item.price?.recurring?.usage_type === "metered" ? t("common.metered") : "";
|
|
37
43
|
const canUpsell = mode === "normal" && items.length === 1;
|
|
38
44
|
const primaryText = (0, _react.useMemo)(() => {
|
|
39
45
|
const price = item.upsell_price || item.price || {};
|
|
40
46
|
const isRecurring = price?.type === "recurring" && price?.recurring;
|
|
41
|
-
|
|
47
|
+
const trial = trialInDays > 0 || trialEnd > (0, _dayjs.default)().unix();
|
|
48
|
+
if (isRecurring && !trial && price?.recurring?.usage_type !== "metered") {
|
|
42
49
|
return `${pricing.primary} ${price.recurring ? (0, _util.formatRecurring)(price.recurring, false, "slash", locale) : ""}`;
|
|
43
50
|
}
|
|
44
51
|
return pricing.primary;
|
|
45
|
-
}, [trialInDays, pricing, item, locale]);
|
|
52
|
+
}, [trialInDays, trialEnd, pricing, item, locale]);
|
|
46
53
|
return /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, {
|
|
47
54
|
direction: "column",
|
|
48
55
|
alignItems: "flex-start",
|
package/lib/payment/summary.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ type Props = {
|
|
|
4
4
|
items: TLineItemExpanded[];
|
|
5
5
|
currency: TPaymentCurrency;
|
|
6
6
|
trialInDays: number;
|
|
7
|
+
trialEnd?: number;
|
|
7
8
|
billingThreshold: number;
|
|
8
9
|
showStaking?: boolean;
|
|
9
10
|
onUpsell?: Function;
|
|
@@ -16,7 +17,7 @@ type Props = {
|
|
|
16
17
|
donationSettings?: DonationSettings;
|
|
17
18
|
action?: string;
|
|
18
19
|
};
|
|
19
|
-
declare function PaymentSummary({ items, currency, trialInDays, billingThreshold, onUpsell, onDownsell, onApplyCrossSell, onCancelCrossSell, onChangeAmount, checkoutSessionId, crossSellBehavior, showStaking, donationSettings, action, ...rest }: Props): import("react").JSX.Element;
|
|
20
|
+
declare function PaymentSummary({ items, currency, trialInDays, billingThreshold, onUpsell, onDownsell, onApplyCrossSell, onCancelCrossSell, onChangeAmount, checkoutSessionId, crossSellBehavior, showStaking, donationSettings, action, trialEnd, ...rest }: Props): import("react").JSX.Element;
|
|
20
21
|
declare namespace PaymentSummary {
|
|
21
22
|
var defaultProps: {
|
|
22
23
|
onUpsell: any;
|
|
@@ -29,6 +30,7 @@ declare namespace PaymentSummary {
|
|
|
29
30
|
showStaking: boolean;
|
|
30
31
|
donationSettings: null;
|
|
31
32
|
action: string;
|
|
33
|
+
trialEnd: number;
|
|
32
34
|
};
|
|
33
35
|
}
|
|
34
36
|
export default PaymentSummary;
|
package/lib/payment/summary.js
CHANGED
|
@@ -90,7 +90,8 @@ PaymentSummary.defaultProps = {
|
|
|
90
90
|
crossSellBehavior: "",
|
|
91
91
|
showStaking: false,
|
|
92
92
|
donationSettings: null,
|
|
93
|
-
action: ""
|
|
93
|
+
action: "",
|
|
94
|
+
trialEnd: 0
|
|
94
95
|
};
|
|
95
96
|
function PaymentSummary({
|
|
96
97
|
items,
|
|
@@ -107,6 +108,7 @@ function PaymentSummary({
|
|
|
107
108
|
showStaking,
|
|
108
109
|
donationSettings,
|
|
109
110
|
action,
|
|
111
|
+
trialEnd = 0,
|
|
110
112
|
...rest
|
|
111
113
|
}) {
|
|
112
114
|
const {
|
|
@@ -126,7 +128,10 @@ function PaymentSummary({
|
|
|
126
128
|
data,
|
|
127
129
|
runAsync
|
|
128
130
|
} = (0, _ahooks.useRequest)(() => checkoutSessionId ? fetchCrossSell(checkoutSessionId) : Promise.resolve(null));
|
|
129
|
-
const headlines = (0, _util2.formatCheckoutHeadlines)(items, currency,
|
|
131
|
+
const headlines = (0, _util2.formatCheckoutHeadlines)(items, currency, {
|
|
132
|
+
trialEnd,
|
|
133
|
+
trialInDays
|
|
134
|
+
}, locale);
|
|
130
135
|
const staking = showStaking ? getStakingSetup(items, currency, billingThreshold) : "0";
|
|
131
136
|
const totalAmount = (0, _util.fromUnitToToken)(new _util.BN((0, _util.fromTokenToUnit)(headlines.actualAmount, currency?.decimal)).add(new _util.BN(staking)).toString(), currency?.decimal);
|
|
132
137
|
(0, _useBus.default)("error.REQUIRE_CROSS_SELL", () => {
|
|
@@ -197,6 +202,7 @@ function PaymentSummary({
|
|
|
197
202
|
item: x,
|
|
198
203
|
items,
|
|
199
204
|
trialInDays,
|
|
205
|
+
trialEnd,
|
|
200
206
|
currency,
|
|
201
207
|
onUpsell: handleUpsell,
|
|
202
208
|
onDownsell: handleDownsell,
|
|
@@ -232,6 +238,7 @@ function PaymentSummary({
|
|
|
232
238
|
items,
|
|
233
239
|
trialInDays,
|
|
234
240
|
currency,
|
|
241
|
+
trialEnd,
|
|
235
242
|
onUpsell: _noop.default,
|
|
236
243
|
onDownsell: _noop.default,
|
|
237
244
|
children: /* @__PURE__ */(0, _jsxRuntime.jsxs)(_material.Stack, {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/payment-react",
|
|
3
|
-
"version": "1.14.
|
|
3
|
+
"version": "1.14.25",
|
|
4
4
|
"description": "Reusable react components for payment kit v2",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"@babel/core": "^7.25.2",
|
|
94
94
|
"@babel/preset-env": "^7.25.2",
|
|
95
95
|
"@babel/preset-react": "^7.24.7",
|
|
96
|
-
"@blocklet/payment-types": "1.14.
|
|
96
|
+
"@blocklet/payment-types": "1.14.25",
|
|
97
97
|
"@storybook/addon-essentials": "^7.6.20",
|
|
98
98
|
"@storybook/addon-interactions": "^7.6.20",
|
|
99
99
|
"@storybook/addon-links": "^7.6.20",
|
|
@@ -123,5 +123,5 @@
|
|
|
123
123
|
"vite-plugin-babel": "^1.2.0",
|
|
124
124
|
"vite-plugin-node-polyfills": "^0.21.0"
|
|
125
125
|
},
|
|
126
|
-
"gitHead": "
|
|
126
|
+
"gitHead": "d326f7f50aeb5a0b727b1eb1f5b042f82e2e4059"
|
|
127
127
|
}
|
package/src/libs/util.ts
CHANGED
|
@@ -294,7 +294,7 @@ export function getPriceCurrencyOptions(price: TPrice): PriceCurrency[] {
|
|
|
294
294
|
export function formatLineItemPricing(
|
|
295
295
|
item: TLineItemExpanded,
|
|
296
296
|
currency: TPaymentCurrency,
|
|
297
|
-
|
|
297
|
+
{ trialEnd, trialInDays }: { trialEnd: number; trialInDays: number },
|
|
298
298
|
locale: string = 'en'
|
|
299
299
|
): { primary: string; secondary?: string; quantity: string } {
|
|
300
300
|
const price = item.upsell_price || item.price;
|
|
@@ -303,13 +303,14 @@ export function formatLineItemPricing(
|
|
|
303
303
|
if (price.recurring?.usage_type === 'metered' || +item.quantity === 1) {
|
|
304
304
|
quantity = '';
|
|
305
305
|
}
|
|
306
|
-
|
|
307
306
|
const unitValue = new BN(getPriceUintAmountByCurrency(price, currency));
|
|
308
307
|
|
|
309
308
|
const total = `${fromUnitToToken(unitValue.mul(new BN(item.quantity)), currency.decimal)} ${currency.symbol}`;
|
|
310
309
|
|
|
311
310
|
const unit = `${fromUnitToToken(unitValue, currency.decimal)} ${currency.symbol}`;
|
|
312
311
|
|
|
312
|
+
const trialResult = getFreeTrialTime({ trialInDays, trialEnd }, locale);
|
|
313
|
+
|
|
313
314
|
const appendUnit = (v: string, alt: string) => {
|
|
314
315
|
if (price.product.unit_label) {
|
|
315
316
|
return `${v}/${price.product.unit_label}`;
|
|
@@ -322,9 +323,9 @@ export function formatLineItemPricing(
|
|
|
322
323
|
};
|
|
323
324
|
|
|
324
325
|
if (price.type === 'recurring' && price.recurring) {
|
|
325
|
-
if (
|
|
326
|
+
if (trialResult.count > 0) {
|
|
326
327
|
return {
|
|
327
|
-
primary: t('common.trial', locale, { count:
|
|
328
|
+
primary: t('common.trial', locale, { count: trialResult.count, interval: trialResult.interval }),
|
|
328
329
|
secondary: `${appendUnit(total, total)} ${formatRecurring(price.recurring, false, 'slash', locale)}`,
|
|
329
330
|
quantity,
|
|
330
331
|
};
|
|
@@ -559,10 +560,48 @@ export function formatPriceDisplay(
|
|
|
559
560
|
}
|
|
560
561
|
return [amount, then].filter(Boolean).join(' ');
|
|
561
562
|
}
|
|
563
|
+
|
|
564
|
+
export function getFreeTrialTime(
|
|
565
|
+
{ trialInDays, trialEnd }: { trialInDays: number; trialEnd: number },
|
|
566
|
+
locale: string = 'en'
|
|
567
|
+
): {
|
|
568
|
+
count: number;
|
|
569
|
+
interval: string;
|
|
570
|
+
} {
|
|
571
|
+
const now = dayjs().unix();
|
|
572
|
+
if (trialEnd > 0 && trialEnd > now) {
|
|
573
|
+
if (trialEnd - now < 3600) {
|
|
574
|
+
return {
|
|
575
|
+
count: Math.ceil((trialEnd - now) / 60),
|
|
576
|
+
interval: t('common.minute', locale),
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
if (trialEnd - now < 86400) {
|
|
580
|
+
return {
|
|
581
|
+
count: Math.ceil((trialEnd - now) / 3600),
|
|
582
|
+
interval: t('common.hour', locale),
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
return {
|
|
586
|
+
count: Math.ceil((trialEnd - now) / 86400),
|
|
587
|
+
interval: t('common.day', locale),
|
|
588
|
+
};
|
|
589
|
+
}
|
|
590
|
+
if (trialInDays > 0) {
|
|
591
|
+
return {
|
|
592
|
+
count: trialInDays,
|
|
593
|
+
interval: t('common.day', locale),
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
return {
|
|
597
|
+
count: 0,
|
|
598
|
+
interval: t('common.day', locale),
|
|
599
|
+
};
|
|
600
|
+
}
|
|
562
601
|
export function formatCheckoutHeadlines(
|
|
563
602
|
items: TLineItemExpanded[],
|
|
564
603
|
currency: TPaymentCurrency,
|
|
565
|
-
trialInDays: number,
|
|
604
|
+
{ trialInDays, trialEnd }: { trialInDays: number; trialEnd: number },
|
|
566
605
|
locale: string = 'en'
|
|
567
606
|
): {
|
|
568
607
|
action: string;
|
|
@@ -577,6 +616,7 @@ export function formatCheckoutHeadlines(
|
|
|
577
616
|
const { total } = getCheckoutAmount(items, currency, trialInDays > 0);
|
|
578
617
|
const actualAmount = fromUnitToToken(total, currency.decimal);
|
|
579
618
|
const amount = `${fromUnitToToken(total, currency.decimal)} ${currency.symbol}`;
|
|
619
|
+
const trialResult = getFreeTrialTime({ trialInDays, trialEnd }, locale);
|
|
580
620
|
|
|
581
621
|
// empty
|
|
582
622
|
if (items.length === 0) {
|
|
@@ -618,7 +658,10 @@ export function formatCheckoutHeadlines(
|
|
|
618
658
|
if (x.price.recurring?.usage_type === 'metered') {
|
|
619
659
|
return acc;
|
|
620
660
|
}
|
|
621
|
-
|
|
661
|
+
|
|
662
|
+
return acc.add(
|
|
663
|
+
new BN(getPriceUintAmountByCurrency(x.upsell_price || x.price, currency)).mul(new BN(x.quantity))
|
|
664
|
+
);
|
|
622
665
|
}, new BN(0)),
|
|
623
666
|
currency.decimal
|
|
624
667
|
),
|
|
@@ -627,10 +670,10 @@ export function formatCheckoutHeadlines(
|
|
|
627
670
|
.filter(Boolean)
|
|
628
671
|
.join(' ');
|
|
629
672
|
if (items.length > 1) {
|
|
630
|
-
if (
|
|
673
|
+
if (trialResult.count > 0) {
|
|
631
674
|
const result = {
|
|
632
675
|
action: t('payment.checkout.try2', locale, { name, count: items.length - 1 }),
|
|
633
|
-
amount: t('payment.checkout.free', locale, { count:
|
|
676
|
+
amount: t('payment.checkout.free', locale, { count: trialResult.count, interval: trialResult.interval }),
|
|
634
677
|
then: formatMeteredThen(subscription, recurring, hasMetered && Number(subscription) === 0, locale),
|
|
635
678
|
showThen: true,
|
|
636
679
|
actualAmount: '0',
|
|
@@ -653,10 +696,10 @@ export function formatCheckoutHeadlines(
|
|
|
653
696
|
};
|
|
654
697
|
}
|
|
655
698
|
|
|
656
|
-
if (
|
|
699
|
+
if (trialResult.count > 0) {
|
|
657
700
|
const result = {
|
|
658
701
|
action: t('payment.checkout.try1', locale, { name }),
|
|
659
|
-
amount: t('payment.checkout.free', locale, { count:
|
|
702
|
+
amount: t('payment.checkout.free', locale, { count: trialResult.count, interval: trialResult.interval }),
|
|
660
703
|
then: formatMeteredThen(subscription, recurring, hasMetered && Number(subscription) === 0, locale),
|
|
661
704
|
showThen: true,
|
|
662
705
|
actualAmount: '0',
|
package/src/locales/en.tsx
CHANGED
|
@@ -62,9 +62,10 @@ export default flat({
|
|
|
62
62
|
continue: 'Continue',
|
|
63
63
|
qty: 'Qty {count}',
|
|
64
64
|
each: '{unit} each',
|
|
65
|
-
trial: "Free for {count}
|
|
65
|
+
trial: "Free for {count} {interval}{count > 1 ? 's' : ''}",
|
|
66
66
|
billed: 'billed {rule}',
|
|
67
67
|
metered: 'based on usage',
|
|
68
|
+
minute: 'minute',
|
|
68
69
|
hour: 'hour',
|
|
69
70
|
day: 'day',
|
|
70
71
|
week: 'week',
|
|
@@ -136,7 +137,7 @@ export default flat({
|
|
|
136
137
|
then: 'Then {subscription} {recurring}',
|
|
137
138
|
meteredThen: 'Then {recurring} based on usage',
|
|
138
139
|
metered: '{recurring} based on usage',
|
|
139
|
-
free: "{count}
|
|
140
|
+
free: "{count} {interval}{count > 1 ? 's' : ''} free",
|
|
140
141
|
least: 'continue with at least',
|
|
141
142
|
completed: {
|
|
142
143
|
payment: 'Thanks for your purchase',
|
package/src/locales/zh.tsx
CHANGED
|
@@ -62,9 +62,10 @@ export default flat({
|
|
|
62
62
|
continue: '继续',
|
|
63
63
|
qty: '{count} 件',
|
|
64
64
|
each: '每件 {unit}',
|
|
65
|
-
trial: '免费试用 {count}
|
|
65
|
+
trial: '免费试用 {count} {interval}',
|
|
66
66
|
billed: '{rule}收费',
|
|
67
67
|
metered: '按用量',
|
|
68
|
+
minute: '分钟',
|
|
68
69
|
hour: '小时',
|
|
69
70
|
day: '天',
|
|
70
71
|
week: '周',
|
|
@@ -135,7 +136,7 @@ export default flat({
|
|
|
135
136
|
then: '然后 {subscription} {recurring}',
|
|
136
137
|
meteredThen: '然后{recurring}按用量计费',
|
|
137
138
|
metered: '{recurring}按用量计费',
|
|
138
|
-
free: '免费试用 {count}
|
|
139
|
+
free: '免费试用 {count} {interval}',
|
|
139
140
|
least: '至少',
|
|
140
141
|
completed: {
|
|
141
142
|
payment: '感谢您的购买',
|
|
@@ -63,16 +63,6 @@ const Root = styled<any>('section')`
|
|
|
63
63
|
background: var(--backgrounds-bg-field, #f9fafb);
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
-
// .cko-payment-card::before {
|
|
67
|
-
// content: '';
|
|
68
|
-
// position: absolute;
|
|
69
|
-
// right: 0;
|
|
70
|
-
// bottom: 0;
|
|
71
|
-
// border: 12px solid ${(props) => props.theme.palette.primary.main};
|
|
72
|
-
// border-top-color: transparent;
|
|
73
|
-
// border-left-color: transparent;
|
|
74
|
-
// }
|
|
75
|
-
|
|
76
66
|
.cko-payment-card-unselect {
|
|
77
67
|
border: 1px solid #ddd;
|
|
78
68
|
padding: 4px 8px;
|
package/src/payment/index.tsx
CHANGED
|
@@ -155,6 +155,7 @@ function PaymentInner({
|
|
|
155
155
|
setState({ checkoutSession: result.checkoutSession });
|
|
156
156
|
onPaid(result);
|
|
157
157
|
};
|
|
158
|
+
|
|
158
159
|
return (
|
|
159
160
|
<FormProvider {...methods}>
|
|
160
161
|
<Stack className="cko-container" sx={{ gap: { sm: mode === 'standalone' ? 0 : mode === 'inline' ? 4 : 8 } }}>
|
|
@@ -164,6 +165,7 @@ function PaymentInner({
|
|
|
164
165
|
<PaymentSummary
|
|
165
166
|
items={state.checkoutSession.line_items}
|
|
166
167
|
trialInDays={state.checkoutSession.subscription_data?.trial_period_days || 0}
|
|
168
|
+
trialEnd={state.checkoutSession.subscription_data?.trial_end || 0}
|
|
167
169
|
billingThreshold={Math.max(
|
|
168
170
|
state.checkoutSession.subscription_data?.billing_threshold_amount || 0,
|
|
169
171
|
// @ts-ignore
|
|
@@ -376,23 +378,18 @@ export const Root = styled(Box)<{ mode: LiteralUnion<'standalone' | 'inline' | '
|
|
|
376
378
|
box-sizing: border-box;
|
|
377
379
|
display: flex;
|
|
378
380
|
flex-direction: column;
|
|
379
|
-
// justify-content: center;
|
|
380
381
|
align-items: center;
|
|
381
382
|
overflow: hidden;
|
|
382
|
-
// min-height: ${(props) => (props.mode === 'standalone' ? '100vh' : 'auto')};
|
|
383
383
|
position: relative;
|
|
384
384
|
.cko-container {
|
|
385
385
|
overflow: hidden;
|
|
386
386
|
width: 100%;
|
|
387
|
-
// max-width: ${(props) => (props.mode.endsWith('-minimal') ? '400px' : '1000px')};
|
|
388
387
|
display: flex;
|
|
389
388
|
flex-direction: row;
|
|
390
389
|
justify-content: center;
|
|
391
|
-
// gap: 4px;
|
|
392
390
|
position: relative;
|
|
393
391
|
flex: 1;
|
|
394
392
|
padding: 1px;
|
|
395
|
-
// padding: ${(props) => (props.mode === 'standalone' ? '0 16px' : '0')};
|
|
396
393
|
}
|
|
397
394
|
|
|
398
395
|
.base-card {
|
|
@@ -405,14 +402,11 @@ export const Root = styled(Box)<{ mode: LiteralUnion<'standalone' | 'inline' | '
|
|
|
405
402
|
}
|
|
406
403
|
|
|
407
404
|
.cko-overview {
|
|
408
|
-
// width: ${(props) => (props.mode.endsWith('-minimal') ? '100%' : '400px')};
|
|
409
|
-
// min-height: ${(props) => (props.mode === 'standalone' ? '540px' : 'auto')};
|
|
410
405
|
position: relative;
|
|
411
406
|
flex-direction: column;
|
|
412
407
|
display: ${(props) => (props.mode.endsWith('-minimal') ? 'none' : 'flex')};
|
|
413
408
|
background: var(--backgrounds-bg-base);
|
|
414
409
|
min-height: 'auto';
|
|
415
|
-
// width: 502px;
|
|
416
410
|
}
|
|
417
411
|
.cko-header {
|
|
418
412
|
left: 0;
|
|
@@ -440,8 +434,6 @@ export const Root = styled(Box)<{ mode: LiteralUnion<'standalone' | 'inline' | '
|
|
|
440
434
|
|
|
441
435
|
.cko-payment {
|
|
442
436
|
width: 502px;
|
|
443
|
-
// width: ${(props) => (props.mode.endsWith('-minimal') ? '100%' : '400px')};
|
|
444
|
-
// box-shadow: -4px 0px 8px 0px rgba(2, 7, 19, 0.04);
|
|
445
437
|
padding-left: ${(props) => (props.mode === 'standalone' ? '40px' : '20px')};
|
|
446
438
|
position: relative;
|
|
447
439
|
&:before {
|
|
@@ -466,10 +458,6 @@ export const Root = styled(Box)<{ mode: LiteralUnion<'standalone' | 'inline' | '
|
|
|
466
458
|
}
|
|
467
459
|
|
|
468
460
|
.cko-payment-form {
|
|
469
|
-
// .MuiInputAdornment-positionStart {
|
|
470
|
-
// width: 50px;
|
|
471
|
-
// }
|
|
472
|
-
|
|
473
461
|
.MuiFormLabel-root {
|
|
474
462
|
color: var(--foregrounds-fg-base, #010714);
|
|
475
463
|
font-weight: 500;
|
|
@@ -13,11 +13,13 @@ import {
|
|
|
13
13
|
formatUpsellSaving,
|
|
14
14
|
} from '../libs/util';
|
|
15
15
|
import ProductCard from './product-card';
|
|
16
|
+
import dayjs from '../libs/dayjs';
|
|
16
17
|
|
|
17
18
|
type Props = {
|
|
18
19
|
item: TLineItemExpanded;
|
|
19
20
|
items: TLineItemExpanded[];
|
|
20
21
|
trialInDays: number;
|
|
22
|
+
trialEnd?: number;
|
|
21
23
|
currency: TPaymentCurrency;
|
|
22
24
|
onUpsell: Function;
|
|
23
25
|
onDownsell: Function;
|
|
@@ -28,12 +30,14 @@ type Props = {
|
|
|
28
30
|
ProductItem.defaultProps = {
|
|
29
31
|
mode: 'normal',
|
|
30
32
|
children: null,
|
|
33
|
+
trialEnd: 0,
|
|
31
34
|
};
|
|
32
35
|
|
|
33
36
|
export default function ProductItem({
|
|
34
37
|
item,
|
|
35
38
|
items,
|
|
36
39
|
trialInDays,
|
|
40
|
+
trialEnd = 0,
|
|
37
41
|
currency,
|
|
38
42
|
mode,
|
|
39
43
|
children,
|
|
@@ -41,18 +45,19 @@ export default function ProductItem({
|
|
|
41
45
|
onDownsell,
|
|
42
46
|
}: Props) {
|
|
43
47
|
const { t, locale } = useLocaleContext();
|
|
44
|
-
const pricing = formatLineItemPricing(item, currency, trialInDays, locale);
|
|
48
|
+
const pricing = formatLineItemPricing(item, currency, { trialEnd, trialInDays }, locale);
|
|
45
49
|
const saving = formatUpsellSaving(items, currency);
|
|
46
50
|
const metered = item.price?.recurring?.usage_type === 'metered' ? t('common.metered') : '';
|
|
47
51
|
const canUpsell = mode === 'normal' && items.length === 1;
|
|
48
52
|
const primaryText = useMemo(() => {
|
|
49
53
|
const price = item.upsell_price || item.price || {};
|
|
50
54
|
const isRecurring = price?.type === 'recurring' && price?.recurring;
|
|
51
|
-
|
|
55
|
+
const trial = trialInDays > 0 || trialEnd > dayjs().unix();
|
|
56
|
+
if (isRecurring && !trial && price?.recurring?.usage_type !== 'metered') {
|
|
52
57
|
return `${pricing.primary} ${price.recurring ? formatRecurring(price.recurring, false, 'slash', locale) : ''}`;
|
|
53
58
|
}
|
|
54
59
|
return pricing.primary;
|
|
55
|
-
}, [trialInDays, pricing, item, locale]);
|
|
60
|
+
}, [trialInDays, trialEnd, pricing, item, locale]);
|
|
56
61
|
|
|
57
62
|
return (
|
|
58
63
|
<Stack direction="column" alignItems="flex-start" spacing={1} sx={{ width: '100%' }} className="product-item">
|
package/src/payment/summary.tsx
CHANGED
|
@@ -67,6 +67,7 @@ type Props = {
|
|
|
67
67
|
items: TLineItemExpanded[];
|
|
68
68
|
currency: TPaymentCurrency;
|
|
69
69
|
trialInDays: number;
|
|
70
|
+
trialEnd?: number;
|
|
70
71
|
billingThreshold: number;
|
|
71
72
|
showStaking?: boolean;
|
|
72
73
|
onUpsell?: Function;
|
|
@@ -131,6 +132,7 @@ PaymentSummary.defaultProps = {
|
|
|
131
132
|
showStaking: false,
|
|
132
133
|
donationSettings: null,
|
|
133
134
|
action: '',
|
|
135
|
+
trialEnd: 0,
|
|
134
136
|
};
|
|
135
137
|
|
|
136
138
|
export default function PaymentSummary({
|
|
@@ -148,6 +150,7 @@ export default function PaymentSummary({
|
|
|
148
150
|
showStaking,
|
|
149
151
|
donationSettings,
|
|
150
152
|
action,
|
|
153
|
+
trialEnd = 0,
|
|
151
154
|
...rest
|
|
152
155
|
}: Props) {
|
|
153
156
|
const { t, locale } = useLocaleContext();
|
|
@@ -157,7 +160,7 @@ export default function PaymentSummary({
|
|
|
157
160
|
const { data, runAsync } = useRequest(() =>
|
|
158
161
|
checkoutSessionId ? fetchCrossSell(checkoutSessionId) : Promise.resolve(null)
|
|
159
162
|
);
|
|
160
|
-
const headlines = formatCheckoutHeadlines(items, currency, trialInDays, locale);
|
|
163
|
+
const headlines = formatCheckoutHeadlines(items, currency, { trialEnd, trialInDays }, locale);
|
|
161
164
|
const staking = showStaking ? getStakingSetup(items, currency, billingThreshold) : '0';
|
|
162
165
|
const totalAmount = fromUnitToToken(
|
|
163
166
|
new BN(fromTokenToUnit(headlines.actualAmount, currency?.decimal)).add(new BN(staking)).toString(),
|
|
@@ -231,6 +234,7 @@ export default function PaymentSummary({
|
|
|
231
234
|
item={x}
|
|
232
235
|
items={items}
|
|
233
236
|
trialInDays={trialInDays}
|
|
237
|
+
trialEnd={trialEnd}
|
|
234
238
|
currency={currency}
|
|
235
239
|
onUpsell={handleUpsell}
|
|
236
240
|
onDownsell={handleDownsell}>
|
|
@@ -260,6 +264,7 @@ export default function PaymentSummary({
|
|
|
260
264
|
items={items}
|
|
261
265
|
trialInDays={trialInDays}
|
|
262
266
|
currency={currency}
|
|
267
|
+
trialEnd={trialEnd}
|
|
263
268
|
onUpsell={noop}
|
|
264
269
|
onDownsell={noop}>
|
|
265
270
|
<Stack direction="row" alignItems="center" justifyContent="space-between" sx={{ width: 1 }}>
|