@blocklet/payment-react 1.14.21 → 1.14.23
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/README.md +77 -0
- package/es/checkout/donate.d.ts +4 -2
- package/es/checkout/donate.js +13 -10
- package/es/checkout/form.d.ts +1 -1
- package/es/checkout/form.js +50 -4
- package/es/checkout/table.d.ts +1 -1
- package/es/checkout/table.js +11 -1
- package/es/components/blockchain/tx.js +2 -1
- package/es/components/country-select.d.ts +16 -0
- package/es/components/country-select.js +82 -0
- package/es/components/input.d.ts +21 -21
- package/es/components/input.js +43 -42
- package/es/components/livemode.js +1 -0
- package/es/components/pricing-table.js +0 -2
- package/es/components/status.js +2 -3
- package/es/components/table.d.ts +2 -0
- package/es/components/table.js +186 -0
- package/es/contexts/payment.d.ts +2 -0
- package/es/contexts/payment.js +5 -2
- package/es/history/invoice/list.d.ts +3 -1
- package/es/history/invoice/list.js +215 -48
- package/es/hooks/mobile.d.ts +4 -0
- package/es/hooks/mobile.js +10 -0
- package/es/index.d.ts +5 -1
- package/es/index.js +7 -1
- package/es/libs/util.d.ts +21 -8
- package/es/libs/util.js +92 -28
- package/es/locales/en.js +22 -7
- package/es/locales/index.d.ts +0 -1
- package/es/locales/index.js +10 -1
- package/es/locales/zh.js +21 -6
- package/es/payment/error.js +2 -2
- package/es/payment/footer.js +1 -1
- package/es/payment/form/address.d.ts +9 -2
- package/es/payment/form/address.js +69 -69
- package/es/payment/form/currency.js +39 -25
- package/es/payment/form/index.d.ts +1 -1
- package/es/payment/form/index.js +83 -81
- package/es/payment/form/phone.js +15 -51
- package/es/payment/index.d.ts +3 -10
- package/es/payment/index.js +295 -224
- package/es/payment/product-card.js +4 -4
- package/es/payment/product-donation.js +9 -3
- package/es/payment/product-item.d.ts +2 -2
- package/es/payment/product-item.js +120 -81
- package/es/payment/summary.js +188 -118
- package/es/theme/index.css +240 -0
- package/es/theme/index.d.ts +14 -0
- package/es/theme/index.js +256 -0
- package/es/theme/typography.d.ts +2 -0
- package/es/theme/typography.js +53 -0
- package/es/types/index.d.ts +16 -0
- package/lib/checkout/donate.d.ts +4 -2
- package/lib/checkout/donate.js +23 -2
- package/lib/checkout/form.d.ts +1 -1
- package/lib/checkout/form.js +60 -15
- package/lib/checkout/table.d.ts +1 -1
- package/lib/checkout/table.js +22 -1
- package/lib/components/blockchain/tx.js +4 -1
- package/lib/components/country-select.d.ts +16 -0
- package/lib/components/country-select.js +115 -0
- package/lib/components/input.d.ts +21 -21
- package/lib/components/input.js +21 -12
- package/lib/components/livemode.js +1 -0
- package/lib/components/pricing-table.js +0 -2
- package/lib/components/status.js +2 -3
- package/lib/components/table.d.ts +2 -0
- package/lib/components/table.js +220 -0
- package/lib/contexts/payment.d.ts +2 -0
- package/lib/contexts/payment.js +4 -1
- package/lib/history/invoice/list.d.ts +3 -1
- package/lib/history/invoice/list.js +290 -62
- package/lib/hooks/mobile.d.ts +4 -0
- package/lib/hooks/mobile.js +17 -0
- package/lib/index.d.ts +5 -1
- package/lib/index.js +36 -0
- package/lib/libs/util.d.ts +21 -8
- package/lib/libs/util.js +115 -37
- package/lib/locales/en.js +22 -7
- package/lib/locales/index.d.ts +0 -1
- package/lib/locales/index.js +14 -3
- package/lib/locales/zh.js +21 -6
- package/lib/payment/error.js +5 -1
- package/lib/payment/footer.js +1 -1
- package/lib/payment/form/address.d.ts +9 -2
- package/lib/payment/form/address.js +67 -59
- package/lib/payment/form/currency.js +31 -24
- package/lib/payment/form/index.d.ts +1 -1
- package/lib/payment/form/index.js +92 -93
- package/lib/payment/form/phone.js +11 -59
- package/lib/payment/index.d.ts +3 -10
- package/lib/payment/index.js +302 -225
- package/lib/payment/product-card.js +5 -4
- package/lib/payment/product-donation.js +11 -7
- package/lib/payment/product-item.d.ts +2 -2
- package/lib/payment/product-item.js +38 -19
- package/lib/payment/summary.js +219 -127
- package/lib/theme/index.css +240 -0
- package/lib/theme/index.d.ts +14 -0
- package/lib/theme/index.js +273 -0
- package/lib/theme/typography.d.ts +2 -0
- package/lib/theme/typography.js +59 -0
- package/lib/types/index.d.ts +16 -0
- package/package.json +14 -11
- package/src/checkout/donate.tsx +25 -11
- package/src/checkout/form.tsx +63 -15
- package/src/checkout/table.tsx +20 -1
- package/src/components/blockchain/tx.tsx +2 -1
- package/src/components/country-select.tsx +93 -0
- package/src/components/input.tsx +49 -46
- package/src/components/livemode.tsx +1 -0
- package/src/components/pricing-table.tsx +0 -2
- package/src/components/status.tsx +1 -2
- package/src/components/table.tsx +200 -0
- package/src/contexts/payment.tsx +6 -1
- package/src/history/invoice/list.tsx +254 -49
- package/src/hooks/mobile.ts +13 -0
- package/src/index.ts +7 -0
- package/src/libs/util.ts +120 -31
- package/src/locales/en.tsx +18 -4
- package/src/locales/index.tsx +10 -3
- package/src/locales/zh.tsx +17 -3
- package/src/payment/error.tsx +2 -2
- package/src/payment/footer.tsx +1 -1
- package/src/payment/form/address.tsx +56 -47
- package/src/payment/form/currency.tsx +29 -23
- package/src/payment/form/index.tsx +89 -76
- package/src/payment/form/phone.tsx +14 -51
- package/src/payment/index.tsx +298 -231
- package/src/payment/product-card.tsx +4 -4
- package/src/payment/product-donation.tsx +9 -4
- package/src/payment/product-item.tsx +49 -20
- package/src/payment/summary.tsx +191 -108
- package/src/theme/index.css +240 -0
- package/src/theme/index.tsx +271 -0
- package/src/theme/typography.ts +56 -0
- package/src/types/index.ts +17 -0
package/src/libs/util.ts
CHANGED
|
@@ -24,7 +24,7 @@ import { joinURL } from 'ufo';
|
|
|
24
24
|
|
|
25
25
|
import { t } from '../locales';
|
|
26
26
|
import dayjs from './dayjs';
|
|
27
|
-
import { PricingRenderProps } from '../types';
|
|
27
|
+
import { ActionProps, PricingRenderProps } from '../types';
|
|
28
28
|
|
|
29
29
|
export const PAYMENT_KIT_DID = 'z2qaCNvKMv5GjouKdcDWexv6WqtHbpNPQDnAk';
|
|
30
30
|
|
|
@@ -533,6 +533,32 @@ export function formatUpsellSaving(items: TLineItemExpanded[], currency: TPaymen
|
|
|
533
533
|
return Number(before.sub(after).mul(new BN(100)).div(before).toString()).toFixed(0);
|
|
534
534
|
}
|
|
535
535
|
|
|
536
|
+
export function formatMeteredThen(
|
|
537
|
+
subscription: string,
|
|
538
|
+
recurring: string,
|
|
539
|
+
hasMetered: boolean,
|
|
540
|
+
locale: string = 'en'
|
|
541
|
+
): string {
|
|
542
|
+
if (hasMetered) {
|
|
543
|
+
return t('payment.checkout.meteredThen', locale, { subscription, recurring });
|
|
544
|
+
}
|
|
545
|
+
return t('payment.checkout.then', locale, { subscription, recurring });
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
export function formatPriceDisplay(
|
|
549
|
+
{ amount, then, actualAmount, showThen }: { amount: string; then?: string; actualAmount: string; showThen?: boolean },
|
|
550
|
+
recurring: string,
|
|
551
|
+
hasMetered: boolean,
|
|
552
|
+
locale: string = 'en'
|
|
553
|
+
) {
|
|
554
|
+
if (Number(actualAmount) === 0 && hasMetered) {
|
|
555
|
+
return t('payment.checkout.metered', locale, { recurring });
|
|
556
|
+
}
|
|
557
|
+
if (showThen) {
|
|
558
|
+
return [amount, then].filter(Boolean).join(', ');
|
|
559
|
+
}
|
|
560
|
+
return [amount, then].filter(Boolean).join(' ');
|
|
561
|
+
}
|
|
536
562
|
export function formatCheckoutHeadlines(
|
|
537
563
|
items: TLineItemExpanded[],
|
|
538
564
|
currency: TPaymentCurrency,
|
|
@@ -543,9 +569,13 @@ export function formatCheckoutHeadlines(
|
|
|
543
569
|
amount: string;
|
|
544
570
|
then?: string;
|
|
545
571
|
secondary?: string;
|
|
572
|
+
showThen?: boolean;
|
|
573
|
+
actualAmount: string;
|
|
574
|
+
priceDisplay: string;
|
|
546
575
|
} {
|
|
547
576
|
const brand = getStatementDescriptor(items);
|
|
548
577
|
const { total } = getCheckoutAmount(items, currency, trialInDays > 0);
|
|
578
|
+
const actualAmount = fromUnitToToken(total, currency.decimal);
|
|
549
579
|
const amount = `${fromUnitToToken(total, currency.decimal)} ${currency.symbol}`;
|
|
550
580
|
|
|
551
581
|
// empty
|
|
@@ -554,6 +584,8 @@ export function formatCheckoutHeadlines(
|
|
|
554
584
|
action: t('payment.checkout.empty', locale),
|
|
555
585
|
amount: '0',
|
|
556
586
|
then: '',
|
|
587
|
+
actualAmount: '0',
|
|
588
|
+
priceDisplay: '0',
|
|
557
589
|
};
|
|
558
590
|
}
|
|
559
591
|
|
|
@@ -563,10 +595,10 @@ export function formatCheckoutHeadlines(
|
|
|
563
595
|
if (items.every((x) => x.price.type === 'one_time')) {
|
|
564
596
|
const action = t('payment.checkout.pay', locale, { payee: brand });
|
|
565
597
|
if (items.length > 1) {
|
|
566
|
-
return { action, amount };
|
|
598
|
+
return { action, amount, actualAmount, priceDisplay: amount };
|
|
567
599
|
}
|
|
568
600
|
|
|
569
|
-
return { action, amount, then: '' };
|
|
601
|
+
return { action, amount, then: '', actualAmount, priceDisplay: amount };
|
|
570
602
|
}
|
|
571
603
|
|
|
572
604
|
const item = items.find((x) => x.price.type === 'recurring');
|
|
@@ -576,10 +608,9 @@ export function formatCheckoutHeadlines(
|
|
|
576
608
|
'per',
|
|
577
609
|
locale
|
|
578
610
|
);
|
|
579
|
-
|
|
611
|
+
const hasMetered = items.some((x) => x.price.type === 'recurring' && x.price.recurring?.usage_type === 'metered');
|
|
580
612
|
// all recurring
|
|
581
613
|
if (items.every((x) => x.price.type === 'recurring')) {
|
|
582
|
-
const hasMetered = items.some((x) => x.price.type === 'recurring' && x.price.recurring?.usage_type === 'metered');
|
|
583
614
|
const subscription = [
|
|
584
615
|
hasMetered ? t('payment.checkout.least', locale) : '',
|
|
585
616
|
fromUnitToToken(
|
|
@@ -597,32 +628,54 @@ export function formatCheckoutHeadlines(
|
|
|
597
628
|
.join(' ');
|
|
598
629
|
if (items.length > 1) {
|
|
599
630
|
if (trialInDays > 0) {
|
|
600
|
-
|
|
631
|
+
const result = {
|
|
601
632
|
action: t('payment.checkout.try2', locale, { name, count: items.length - 1 }),
|
|
602
633
|
amount: t('payment.checkout.free', locale, { count: trialInDays }),
|
|
603
|
-
then:
|
|
634
|
+
then: formatMeteredThen(subscription, recurring, hasMetered && Number(subscription) === 0, locale),
|
|
635
|
+
showThen: true,
|
|
636
|
+
actualAmount: '0',
|
|
637
|
+
};
|
|
638
|
+
return {
|
|
639
|
+
...result,
|
|
640
|
+
priceDisplay: formatPriceDisplay(result, recurring, hasMetered, locale),
|
|
604
641
|
};
|
|
605
642
|
}
|
|
606
|
-
|
|
607
|
-
return {
|
|
643
|
+
const result = {
|
|
608
644
|
action: t('payment.checkout.sub2', locale, { name, count: items.length - 1 }),
|
|
609
645
|
amount,
|
|
610
|
-
then: recurring,
|
|
646
|
+
then: hasMetered ? t('payment.checkout.meteredThen', locale, { recurring }) : recurring,
|
|
647
|
+
showThen: hasMetered,
|
|
648
|
+
actualAmount,
|
|
649
|
+
};
|
|
650
|
+
return {
|
|
651
|
+
...result,
|
|
652
|
+
priceDisplay: formatPriceDisplay(result, recurring, hasMetered, locale),
|
|
611
653
|
};
|
|
612
654
|
}
|
|
613
655
|
|
|
614
656
|
if (trialInDays > 0) {
|
|
615
|
-
|
|
657
|
+
const result = {
|
|
616
658
|
action: t('payment.checkout.try1', locale, { name }),
|
|
617
659
|
amount: t('payment.checkout.free', locale, { count: trialInDays }),
|
|
618
|
-
then:
|
|
660
|
+
then: formatMeteredThen(subscription, recurring, hasMetered && Number(subscription) === 0, locale),
|
|
661
|
+
showThen: true,
|
|
662
|
+
actualAmount: '0',
|
|
663
|
+
};
|
|
664
|
+
return {
|
|
665
|
+
...result,
|
|
666
|
+
priceDisplay: formatPriceDisplay(result, recurring, hasMetered, locale),
|
|
619
667
|
};
|
|
620
668
|
}
|
|
621
|
-
|
|
622
|
-
return {
|
|
669
|
+
const result = {
|
|
623
670
|
action: t('payment.checkout.sub1', locale, { name }),
|
|
624
671
|
amount,
|
|
625
|
-
then: recurring,
|
|
672
|
+
then: hasMetered ? t('payment.checkout.meteredThen', locale, { recurring }) : recurring,
|
|
673
|
+
showThen: hasMetered,
|
|
674
|
+
actualAmount,
|
|
675
|
+
};
|
|
676
|
+
return {
|
|
677
|
+
...result,
|
|
678
|
+
priceDisplay: formatPriceDisplay(result, recurring, hasMetered, locale),
|
|
626
679
|
};
|
|
627
680
|
}
|
|
628
681
|
|
|
@@ -639,10 +692,22 @@ export function formatCheckoutHeadlines(
|
|
|
639
692
|
currency.decimal
|
|
640
693
|
);
|
|
641
694
|
|
|
642
|
-
|
|
695
|
+
const result = {
|
|
643
696
|
action: t('payment.checkout.pay', locale, { payee: brand }),
|
|
644
697
|
amount,
|
|
645
|
-
then:
|
|
698
|
+
then: formatMeteredThen(
|
|
699
|
+
`${subscription} ${currency.symbol}`,
|
|
700
|
+
recurring,
|
|
701
|
+
hasMetered && Number(subscription) === 0,
|
|
702
|
+
locale
|
|
703
|
+
),
|
|
704
|
+
showThen: true,
|
|
705
|
+
actualAmount,
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
return {
|
|
709
|
+
...result,
|
|
710
|
+
priceDisplay: formatPriceDisplay(result, recurring, hasMetered, locale),
|
|
646
711
|
};
|
|
647
712
|
}
|
|
648
713
|
|
|
@@ -690,48 +755,65 @@ export function formatSubscriptionProduct(items: TSubscriptionItemExpanded[], ma
|
|
|
690
755
|
}
|
|
691
756
|
|
|
692
757
|
export const getSubscriptionTimeSummary = (subscription: TSubscriptionExpanded) => {
|
|
693
|
-
const lines = [`
|
|
758
|
+
const lines = [`Start on ${formatToDate(subscription.start_date * 1000, 'en', 'YYYY-MM-DD')}`];
|
|
759
|
+
|
|
760
|
+
const getLineTimeMessage = (time: number) => {
|
|
761
|
+
const curDay = dayjs().isSame(dayjs(time), 'day');
|
|
762
|
+
const timeFormat = curDay ? 'HH:mm:ss' : 'YYYY-MM-DD';
|
|
763
|
+
return `${curDay ? 'in' : 'on'} ${formatToDate(time, 'en', timeFormat)}`;
|
|
764
|
+
};
|
|
765
|
+
|
|
694
766
|
if (subscription.status === 'active' || subscription.status === 'trialing') {
|
|
695
767
|
if (subscription.cancel_at) {
|
|
696
|
-
lines.push(`
|
|
768
|
+
lines.push(`Ended ${getLineTimeMessage(subscription.cancel_at * 1000)}`);
|
|
697
769
|
} else if (subscription.cancel_at_period_end) {
|
|
698
|
-
lines.push(`
|
|
770
|
+
lines.push(`Ended ${getLineTimeMessage(subscription.current_period_end * 1000)}`);
|
|
699
771
|
} else {
|
|
700
|
-
lines.push(`
|
|
772
|
+
lines.push(`Renew ${getLineTimeMessage(subscription.current_period_end * 1000)}`);
|
|
701
773
|
}
|
|
702
774
|
} else if (subscription.status === 'past_due') {
|
|
703
|
-
lines.push(`
|
|
775
|
+
lines.push(`Ended ${getLineTimeMessage((subscription.cancel_at || subscription.current_period_end) * 1000)}`);
|
|
704
776
|
} else if (subscription.status === 'canceled') {
|
|
705
|
-
lines.push(`
|
|
777
|
+
lines.push(`Ended ${getLineTimeMessage(subscription.canceled_at * 1000)}`);
|
|
706
778
|
}
|
|
707
779
|
|
|
708
|
-
return lines.join(',
|
|
780
|
+
return lines.join(',');
|
|
709
781
|
};
|
|
710
782
|
|
|
711
|
-
export const getSubscriptionAction = (
|
|
783
|
+
export const getSubscriptionAction = (
|
|
784
|
+
subscription: TSubscriptionExpanded,
|
|
785
|
+
actionProps: ActionProps
|
|
786
|
+
): {
|
|
787
|
+
action: string;
|
|
788
|
+
variant: string;
|
|
789
|
+
color: string;
|
|
790
|
+
canRenew: boolean;
|
|
791
|
+
text?: string;
|
|
792
|
+
sx?: any;
|
|
793
|
+
} | null => {
|
|
712
794
|
if (subscription.status === 'active' || subscription.status === 'trialing') {
|
|
713
795
|
if (subscription.cancel_at_period_end) {
|
|
714
796
|
if (subscription.cancelation_details?.reason === 'payment_failed') {
|
|
715
797
|
return null;
|
|
716
798
|
}
|
|
717
799
|
|
|
718
|
-
return { action: 'recover', variant: 'contained', color: 'primary', canRenew: false };
|
|
800
|
+
return { action: 'recover', variant: 'contained', color: 'primary', canRenew: false, ...actionProps?.recover };
|
|
719
801
|
}
|
|
720
802
|
|
|
721
803
|
if (subscription.cancel_at && subscription.cancel_at !== subscription.current_period_end) {
|
|
722
804
|
return null;
|
|
723
805
|
}
|
|
724
806
|
|
|
725
|
-
return { action: 'cancel', variant: 'outlined', color: 'inherit', canRenew: false };
|
|
807
|
+
return { action: 'cancel', variant: 'outlined', color: 'inherit', canRenew: false, ...actionProps?.cancel };
|
|
726
808
|
}
|
|
727
809
|
|
|
728
810
|
if (subscription.status === 'past_due') {
|
|
729
811
|
const canRenew = subscription.cancel_at && subscription.cancel_at !== subscription.current_period_end;
|
|
730
|
-
return { action: 'pastDue', variant: 'contained', color: 'primary', canRenew };
|
|
812
|
+
return { action: 'pastDue', variant: 'contained', color: 'primary', canRenew, ...actionProps?.pastDue };
|
|
731
813
|
}
|
|
732
814
|
|
|
733
815
|
if (subscription.status !== 'canceled' && subscription.cancel_at_period_end) {
|
|
734
|
-
return { action: 'recover', variant: 'contained', color: 'primary', canRenew: false };
|
|
816
|
+
return { action: 'recover', variant: 'contained', color: 'primary', canRenew: false, ...actionProps?.recover };
|
|
735
817
|
}
|
|
736
818
|
|
|
737
819
|
return null;
|
|
@@ -855,9 +937,9 @@ export function formatTotalPrice({
|
|
|
855
937
|
const unitValue = new BN(price.custom_unit_amount || price.unit_amount);
|
|
856
938
|
const currency: TPaymentCurrency = price?.currency ?? {};
|
|
857
939
|
|
|
858
|
-
const total = `${fromUnitToToken(unitValue.mul(new BN(quantity)), currency.decimal)} ${currency.symbol}`;
|
|
940
|
+
const total = `${fromUnitToToken(unitValue.mul(new BN(quantity)), currency.decimal)} ${currency.symbol} `;
|
|
859
941
|
|
|
860
|
-
const unit = `${fromUnitToToken(unitValue, currency.decimal)} ${currency.symbol}`;
|
|
942
|
+
const unit = `${fromUnitToToken(unitValue, currency.decimal)} ${currency.symbol} `;
|
|
861
943
|
|
|
862
944
|
const appendUnit = (v: string, alt: string) => {
|
|
863
945
|
if (product.unit_label) {
|
|
@@ -893,6 +975,13 @@ export function formatQuantityInventory(price: TPrice, quantity: string | number
|
|
|
893
975
|
return '';
|
|
894
976
|
}
|
|
895
977
|
|
|
978
|
+
export function formatSubscriptionStatus(status: string) {
|
|
979
|
+
if (status === 'canceled') {
|
|
980
|
+
return 'Ended';
|
|
981
|
+
}
|
|
982
|
+
return status;
|
|
983
|
+
}
|
|
984
|
+
|
|
896
985
|
export function formatAmountPrecisionLimit(amount: string, locale = 'en', precision: number = 6) {
|
|
897
986
|
if (!amount) {
|
|
898
987
|
return '';
|
package/src/locales/en.tsx
CHANGED
|
@@ -62,7 +62,7 @@ export default flat({
|
|
|
62
62
|
continue: 'Continue',
|
|
63
63
|
qty: 'Qty {count}',
|
|
64
64
|
each: '{unit} each',
|
|
65
|
-
trial:
|
|
65
|
+
trial: "Free for {count} day{count > 1 ? 's' : ''}",
|
|
66
66
|
billed: 'billed {rule}',
|
|
67
67
|
metered: 'based on usage',
|
|
68
68
|
hour: 'hour',
|
|
@@ -111,11 +111,13 @@ export default flat({
|
|
|
111
111
|
subscription: 'View subscription',
|
|
112
112
|
invoice: 'View invoice',
|
|
113
113
|
},
|
|
114
|
+
paymentRequired: 'Payment Required',
|
|
114
115
|
staking: {
|
|
115
116
|
title: 'Staking Required',
|
|
116
117
|
tooltip:
|
|
117
118
|
'Staking is used to ensure that future invoices can be paid normally. Revoking the staking from DID Wallet means canceling the subscription.',
|
|
118
119
|
},
|
|
120
|
+
stakingConfirm: 'In this payment, the staked amount is separate from the product cost.',
|
|
119
121
|
donation: {
|
|
120
122
|
between: 'Please enter an amount between {min} and {max}.',
|
|
121
123
|
custom: 'Custom Amount',
|
|
@@ -132,7 +134,9 @@ export default flat({
|
|
|
132
134
|
sub1: 'Subscribe to {name}',
|
|
133
135
|
sub2: 'Subscribe to {name} and {count} more',
|
|
134
136
|
then: 'Then {subscription} {recurring}',
|
|
135
|
-
|
|
137
|
+
meteredThen: 'Then {recurring} based on usage',
|
|
138
|
+
metered: '{recurring} based on usage',
|
|
139
|
+
free: "{count} day{count > 1 ? 's' : ''} free",
|
|
136
140
|
least: 'continue with at least',
|
|
137
141
|
completed: {
|
|
138
142
|
payment: 'Thanks for your purchase',
|
|
@@ -141,8 +145,7 @@ export default flat({
|
|
|
141
145
|
donate: 'Thanks for your support',
|
|
142
146
|
tip: 'A payment to {payee} has been completed. You can view the details of this payment in your account.',
|
|
143
147
|
},
|
|
144
|
-
confirm:
|
|
145
|
-
'By confirming your subscription, you allow {payee} to charge your account or slashing your staking for this and future payments in accordance with their terms. You can always cancel your subscription, or revoking your staking from DID Wallet.',
|
|
148
|
+
confirm: 'Confirming allows {payee} to charge or reduce your staking. You can cancel or revoke staking anytime.',
|
|
146
149
|
required: 'Required',
|
|
147
150
|
invalid: 'Invalid',
|
|
148
151
|
billing: {
|
|
@@ -185,12 +188,16 @@ export default flat({
|
|
|
185
188
|
title: 'Nothing to show here',
|
|
186
189
|
description: 'Seems this checkoutSession is not configured properly',
|
|
187
190
|
},
|
|
191
|
+
orderSummary: 'Order Summary',
|
|
192
|
+
paymentDetails: 'Payment Details',
|
|
193
|
+
productListTotal: 'Includes {total} items',
|
|
188
194
|
},
|
|
189
195
|
customer: {
|
|
190
196
|
payments: 'Payment History',
|
|
191
197
|
invoices: 'Invoice History',
|
|
192
198
|
details: 'Details',
|
|
193
199
|
summary: 'Summary',
|
|
200
|
+
specifics: 'Specifics',
|
|
194
201
|
update: 'Update Information',
|
|
195
202
|
empty: 'Seems you do not have any subscriptions or payments here',
|
|
196
203
|
cancel: {
|
|
@@ -272,12 +279,16 @@ export default flat({
|
|
|
272
279
|
renewError: 'Failed to renew the subscription',
|
|
273
280
|
empty: 'There are no invoices',
|
|
274
281
|
next: 'No invoices yet, next invoice will be generated on {date}',
|
|
282
|
+
invoiceNumber: 'Invoice Number',
|
|
283
|
+
emptyList: 'No Invoice',
|
|
275
284
|
},
|
|
276
285
|
payment: {
|
|
277
286
|
empty: 'There are no payments',
|
|
287
|
+
emptyList: 'No Payment',
|
|
278
288
|
},
|
|
279
289
|
refund: {
|
|
280
290
|
empty: 'There are no refunds',
|
|
291
|
+
emptyList: 'No Refund',
|
|
281
292
|
},
|
|
282
293
|
subscriptions: {
|
|
283
294
|
plan: 'Plan',
|
|
@@ -311,4 +322,7 @@ export default flat({
|
|
|
311
322
|
[RefundType.stakeReturn]: 'Stake Return',
|
|
312
323
|
},
|
|
313
324
|
},
|
|
325
|
+
empty: {
|
|
326
|
+
records: 'No matching records found',
|
|
327
|
+
},
|
|
314
328
|
});
|
package/src/locales/index.tsx
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* eslint-disable no-prototype-builtins */
|
|
2
|
+
import { template } from 'lodash';
|
|
2
3
|
import en from './en';
|
|
3
4
|
import zh from './zh';
|
|
4
5
|
|
|
@@ -8,9 +9,15 @@ export const translations = {
|
|
|
8
9
|
en,
|
|
9
10
|
};
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
const replace = (t: string, data: Record<string, any> = {}): string => {
|
|
13
|
+
try {
|
|
14
|
+
const compiled = template(t, { interpolate: /{([\s\S]+?)}/g, escape: /{([\s\S]+?)}/g });
|
|
15
|
+
return compiled(data);
|
|
16
|
+
} catch (e) {
|
|
17
|
+
console.error(`Error evaluating template: ${t}`, e);
|
|
18
|
+
return '';
|
|
19
|
+
}
|
|
20
|
+
};
|
|
14
21
|
export const createTranslator = ({ fallbackLocale = 'en' }: { fallbackLocale?: string }, langs: any = translations) => {
|
|
15
22
|
return (key: string, locale = fallbackLocale, data: Record<string, any> = {}) => {
|
|
16
23
|
if (!langs[locale] || !langs[locale][key]) {
|
package/src/locales/zh.tsx
CHANGED
|
@@ -111,10 +111,12 @@ export default flat({
|
|
|
111
111
|
subscription: '查看订阅',
|
|
112
112
|
invoice: '查看账单',
|
|
113
113
|
},
|
|
114
|
+
paymentRequired: '支付数量',
|
|
114
115
|
staking: {
|
|
115
116
|
title: '质押数量',
|
|
116
117
|
tooltip: '质押相当于保证金,用于确保未来的账单能够正常扣款,如果你从 DID Wallet 撤销质押,订阅也会被取消。',
|
|
117
118
|
},
|
|
119
|
+
stakingConfirm: '在此支付中,质押金额与产品费用分开',
|
|
118
120
|
donation: {
|
|
119
121
|
between: '金额必须大于 {min} 且小于 {max}',
|
|
120
122
|
custom: '输入金额',
|
|
@@ -131,7 +133,9 @@ export default flat({
|
|
|
131
133
|
sub1: '订阅 {name}',
|
|
132
134
|
sub2: '订阅 {name} 等{count}个产品',
|
|
133
135
|
then: '然后 {subscription} {recurring}',
|
|
134
|
-
|
|
136
|
+
meteredThen: '然后{recurring}按用量计费',
|
|
137
|
+
metered: '{recurring}按用量计费',
|
|
138
|
+
free: '免费试用 {count} 天',
|
|
135
139
|
least: '至少',
|
|
136
140
|
completed: {
|
|
137
141
|
payment: '感谢您的购买',
|
|
@@ -140,8 +144,7 @@ export default flat({
|
|
|
140
144
|
donate: '感谢您的支持',
|
|
141
145
|
tip: '向{payee}的付款已完成。您可以在您的账户中查看此付款的详细信息。',
|
|
142
146
|
},
|
|
143
|
-
confirm:
|
|
144
|
-
'通过确认您的订阅,您允许{payee}按照其条款对您的账户进行付款或者罚没您的质押。您随时可以取消您的订阅,或者撤销质押。',
|
|
147
|
+
confirm: '确认允许{payee}对您的账户进行付款或者罚没您的质押。您随时可以取消您的订阅,或者撤销质押。',
|
|
145
148
|
required: '必填项',
|
|
146
149
|
invalid: '无效',
|
|
147
150
|
billing: {
|
|
@@ -182,12 +185,16 @@ export default flat({
|
|
|
182
185
|
title: '没有任何购买项目',
|
|
183
186
|
description: '可能这个付款链接没有正确配置',
|
|
184
187
|
},
|
|
188
|
+
orderSummary: '订单概览',
|
|
189
|
+
paymentDetails: '支付信息',
|
|
190
|
+
productListTotal: '包括 {total} 项',
|
|
185
191
|
},
|
|
186
192
|
customer: {
|
|
187
193
|
payments: '支付历史',
|
|
188
194
|
invoices: '账单历史',
|
|
189
195
|
details: '账户详情',
|
|
190
196
|
summary: '计费摘要',
|
|
197
|
+
specifics: '具体信息',
|
|
191
198
|
update: '更新客户信息',
|
|
192
199
|
empty: '看起来您在这里没有任何订阅或支付',
|
|
193
200
|
cancel: {
|
|
@@ -264,12 +271,16 @@ export default flat({
|
|
|
264
271
|
renewError: '订阅恢复失败',
|
|
265
272
|
empty: '没有任何账单',
|
|
266
273
|
next: '还没有账单,下次账单将在 {date} 生成',
|
|
274
|
+
invoiceNumber: '账单编号',
|
|
275
|
+
emptyList: '没有账单',
|
|
267
276
|
},
|
|
268
277
|
payment: {
|
|
269
278
|
empty: '没有支付记录',
|
|
279
|
+
emptyList: '没有支付记录',
|
|
270
280
|
},
|
|
271
281
|
refund: {
|
|
272
282
|
empty: '没有退款记录',
|
|
283
|
+
emptyList: '没有退款记录',
|
|
273
284
|
},
|
|
274
285
|
subscriptions: {
|
|
275
286
|
plan: '订阅',
|
|
@@ -303,4 +314,7 @@ export default flat({
|
|
|
303
314
|
[RefundType.stakeReturn]: '退押金',
|
|
304
315
|
},
|
|
305
316
|
},
|
|
317
|
+
empty: {
|
|
318
|
+
records: '没有找到匹配的记录',
|
|
319
|
+
},
|
|
306
320
|
});
|
package/src/payment/error.tsx
CHANGED
|
@@ -13,7 +13,7 @@ type Props = {
|
|
|
13
13
|
function getHeightStyle(mode: ModeType | undefined): any {
|
|
14
14
|
switch (mode) {
|
|
15
15
|
case 'standalone':
|
|
16
|
-
return { height: '100vh' }; // 独立模式下,高度为100vh
|
|
16
|
+
return { height: '100vh', maxHeight: '100%' }; // 独立模式下,高度为100vh
|
|
17
17
|
default:
|
|
18
18
|
return { height: 'auto', minHeight: 200 }; // 默认情况下,高度根据内容自动调整
|
|
19
19
|
}
|
|
@@ -29,7 +29,7 @@ export default function PaymentError({ title, description, button, mode }: Props
|
|
|
29
29
|
<Typography variant="body1" sx={{ mb: 2, textAlign: 'center' }}>
|
|
30
30
|
{description}
|
|
31
31
|
</Typography>
|
|
32
|
-
<Button variant="text" size="small" component={Link} href={window.blocklet?.appUrl}>
|
|
32
|
+
<Button variant="text" size="small" sx={{ color: 'text.link' }} component={Link} href={window.blocklet?.appUrl}>
|
|
33
33
|
{button}
|
|
34
34
|
</Button>
|
|
35
35
|
</Stack>
|
package/src/payment/footer.tsx
CHANGED
|
@@ -2,7 +2,7 @@ import { Typography } from '@mui/material';
|
|
|
2
2
|
|
|
3
3
|
export default function CheckoutFooter({ ...props }) {
|
|
4
4
|
return (
|
|
5
|
-
<Typography color="text.
|
|
5
|
+
<Typography color="text.lighter" fontSize={12} {...props}>
|
|
6
6
|
Powered by{' '}
|
|
7
7
|
<Typography component="span" sx={{ fontWeight: 'bold', fontSize: 12 }}>
|
|
8
8
|
ArcBlock
|
|
@@ -1,53 +1,59 @@
|
|
|
1
1
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
2
|
-
import { Fade, Stack,
|
|
2
|
+
import { Fade, FormLabel, InputAdornment, Stack, SxProps } from '@mui/material';
|
|
3
3
|
import { Controller, useFormContext } from 'react-hook-form';
|
|
4
|
-
import { CountrySelector } from 'react-international-phone';
|
|
5
|
-
|
|
6
4
|
import FormInput from '../../components/input';
|
|
5
|
+
import CountrySelect from '../../components/country-select';
|
|
7
6
|
|
|
8
7
|
type Props = {
|
|
9
8
|
mode: string;
|
|
10
9
|
stripe: boolean;
|
|
10
|
+
sx?: SxProps;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
AddressForm.defaultProps = {
|
|
14
|
+
sx: {},
|
|
11
15
|
};
|
|
12
16
|
|
|
13
|
-
export default function AddressForm({ mode, stripe }: Props) {
|
|
17
|
+
export default function AddressForm({ mode, stripe, sx = {} }: Props) {
|
|
14
18
|
const { t } = useLocaleContext();
|
|
15
|
-
const { control
|
|
19
|
+
const { control } = useFormContext();
|
|
16
20
|
|
|
17
21
|
if (mode === 'required') {
|
|
18
22
|
return (
|
|
19
23
|
<Fade in>
|
|
20
|
-
<Stack className="cko-payment-address cko-payment-form">
|
|
21
|
-
<
|
|
22
|
-
{t(`payment.checkout.billing.${mode}`)}
|
|
23
|
-
</Typography>
|
|
24
|
+
<Stack className="cko-payment-address cko-payment-form" sx={sx}>
|
|
25
|
+
<FormLabel className="base-label">{t(`payment.checkout.billing.${mode}`)}</FormLabel>
|
|
24
26
|
<Stack direction="column" className="cko-payment-form" spacing={0}>
|
|
25
27
|
<Stack direction="row" spacing={0}>
|
|
26
|
-
<Controller
|
|
27
|
-
name="billing_address.country"
|
|
28
|
-
control={control}
|
|
29
|
-
render={({ field }) => (
|
|
30
|
-
<CountrySelector
|
|
31
|
-
selectedCountry={field.value}
|
|
32
|
-
onSelect={({ iso2 }) => setValue(field.name, iso2)}
|
|
33
|
-
buttonStyle={{
|
|
34
|
-
width: '64px',
|
|
35
|
-
height: '40px',
|
|
36
|
-
border: '1px solid #ccc',
|
|
37
|
-
marginLeft: -1,
|
|
38
|
-
marginTop: -1,
|
|
39
|
-
}}
|
|
40
|
-
/>
|
|
41
|
-
)}
|
|
42
|
-
/>
|
|
43
28
|
<FormInput
|
|
44
29
|
name="billing_address.postal_code"
|
|
45
30
|
rules={{ required: t('payment.checkout.required') }}
|
|
46
31
|
errorPosition="right"
|
|
47
32
|
variant="outlined"
|
|
48
33
|
placeholder={t('payment.checkout.billing.postal_code')}
|
|
34
|
+
InputProps={{
|
|
35
|
+
startAdornment: (
|
|
36
|
+
<InputAdornment position="start">
|
|
37
|
+
<Controller
|
|
38
|
+
name="billing_address.country"
|
|
39
|
+
control={control}
|
|
40
|
+
render={({ field }) => (
|
|
41
|
+
<CountrySelect
|
|
42
|
+
{...field}
|
|
43
|
+
sx={{
|
|
44
|
+
'&.Mui-focused .MuiOutlinedInput-notchedOutline': {
|
|
45
|
+
borderColor: 'transparent',
|
|
46
|
+
},
|
|
47
|
+
}}
|
|
48
|
+
/>
|
|
49
|
+
)}
|
|
50
|
+
/>
|
|
51
|
+
</InputAdornment>
|
|
52
|
+
),
|
|
53
|
+
}}
|
|
49
54
|
/>
|
|
50
55
|
</Stack>
|
|
56
|
+
<FormLabel className="base-label">{t('payment.checkout.billing.state')}</FormLabel>
|
|
51
57
|
<FormInput
|
|
52
58
|
name="billing_address.state"
|
|
53
59
|
rules={{ required: t('payment.checkout.required') }}
|
|
@@ -55,6 +61,7 @@ export default function AddressForm({ mode, stripe }: Props) {
|
|
|
55
61
|
variant="outlined"
|
|
56
62
|
placeholder={t('payment.checkout.billing.state')}
|
|
57
63
|
/>
|
|
64
|
+
<FormLabel className="base-label">{t('payment.checkout.billing.line1')}</FormLabel>
|
|
58
65
|
<FormInput
|
|
59
66
|
name="billing_address.line1"
|
|
60
67
|
rules={{ required: t('payment.checkout.required') }}
|
|
@@ -62,6 +69,7 @@ export default function AddressForm({ mode, stripe }: Props) {
|
|
|
62
69
|
variant="outlined"
|
|
63
70
|
placeholder={t('payment.checkout.billing.line1')}
|
|
64
71
|
/>
|
|
72
|
+
<FormLabel className="base-label">{t('payment.checkout.billing.city')}</FormLabel>
|
|
65
73
|
<FormInput
|
|
66
74
|
name="billing_address.city"
|
|
67
75
|
rules={{ required: t('payment.checkout.required') }}
|
|
@@ -78,29 +86,10 @@ export default function AddressForm({ mode, stripe }: Props) {
|
|
|
78
86
|
if (stripe) {
|
|
79
87
|
return (
|
|
80
88
|
<Fade in>
|
|
81
|
-
<Stack className="cko-payment-address cko-payment-form">
|
|
82
|
-
<
|
|
83
|
-
{t(`payment.checkout.billing.${mode}`)}
|
|
84
|
-
</Typography>
|
|
89
|
+
<Stack className="cko-payment-address cko-payment-form" sx={sx}>
|
|
90
|
+
<FormLabel className="base-label">{t(`payment.checkout.billing.${mode}`)}</FormLabel>
|
|
85
91
|
<Stack direction="column" className="cko-payment-form" spacing={0}>
|
|
86
92
|
<Stack direction="row" spacing={0}>
|
|
87
|
-
<Controller
|
|
88
|
-
name="billing_address.country"
|
|
89
|
-
control={control}
|
|
90
|
-
render={({ field }) => (
|
|
91
|
-
<CountrySelector
|
|
92
|
-
selectedCountry={field.value}
|
|
93
|
-
onSelect={({ iso2 }) => setValue(field.name, iso2)}
|
|
94
|
-
buttonStyle={{
|
|
95
|
-
width: '64px',
|
|
96
|
-
height: '40px',
|
|
97
|
-
border: '1px solid #ccc',
|
|
98
|
-
marginLeft: -1,
|
|
99
|
-
marginTop: -1,
|
|
100
|
-
}}
|
|
101
|
-
/>
|
|
102
|
-
)}
|
|
103
|
-
/>
|
|
104
93
|
<FormInput
|
|
105
94
|
name="billing_address.postal_code"
|
|
106
95
|
rules={{ required: t('payment.checkout.required') }}
|
|
@@ -108,6 +97,26 @@ export default function AddressForm({ mode, stripe }: Props) {
|
|
|
108
97
|
variant="outlined"
|
|
109
98
|
placeholder={t('payment.checkout.billing.postal_code')}
|
|
110
99
|
wrapperStyle={{ height: '40px' }}
|
|
100
|
+
InputProps={{
|
|
101
|
+
startAdornment: (
|
|
102
|
+
<InputAdornment position="start">
|
|
103
|
+
<Controller
|
|
104
|
+
name="billing_address.country"
|
|
105
|
+
control={control}
|
|
106
|
+
render={({ field }) => (
|
|
107
|
+
<CountrySelect
|
|
108
|
+
{...field}
|
|
109
|
+
sx={{
|
|
110
|
+
'&.Mui-focused .MuiOutlinedInput-notchedOutline': {
|
|
111
|
+
borderColor: 'transparent',
|
|
112
|
+
},
|
|
113
|
+
}}
|
|
114
|
+
/>
|
|
115
|
+
)}
|
|
116
|
+
/>
|
|
117
|
+
</InputAdornment>
|
|
118
|
+
),
|
|
119
|
+
}}
|
|
111
120
|
/>
|
|
112
121
|
</Stack>
|
|
113
122
|
</Stack>
|