@blocklet/payment-react-headless 1.26.0
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/.eslintrc.js +18 -0
- package/build.config.ts +30 -0
- package/es/checkout/context/CheckoutProvider.d.ts +6 -0
- package/es/checkout/context/CheckoutProvider.js +209 -0
- package/es/checkout/context/CustomerFormContext.d.ts +4 -0
- package/es/checkout/context/CustomerFormContext.js +9 -0
- package/es/checkout/context/ExchangeRateContext.d.ts +11 -0
- package/es/checkout/context/ExchangeRateContext.js +9 -0
- package/es/checkout/context/PaymentMethodContext.d.ts +26 -0
- package/es/checkout/context/PaymentMethodContext.js +9 -0
- package/es/checkout/context/SessionContext.d.ts +45 -0
- package/es/checkout/context/SessionContext.js +9 -0
- package/es/checkout/context/SubmitContext.d.ts +4 -0
- package/es/checkout/context/SubmitContext.js +9 -0
- package/es/checkout/context/index.d.ts +6 -0
- package/es/checkout/context/index.js +6 -0
- package/es/checkout/core/billingInterval.d.ts +15 -0
- package/es/checkout/core/billingInterval.js +36 -0
- package/es/checkout/core/crossSell.d.ts +4 -0
- package/es/checkout/core/crossSell.js +30 -0
- package/es/checkout/core/customerForm.d.ts +5 -0
- package/es/checkout/core/customerForm.js +105 -0
- package/es/checkout/core/exchangeRate.d.ts +11 -0
- package/es/checkout/core/exchangeRate.js +25 -0
- package/es/checkout/core/index.d.ts +10 -0
- package/es/checkout/core/index.js +55 -0
- package/es/checkout/core/lineItems.d.ts +7 -0
- package/es/checkout/core/lineItems.js +59 -0
- package/es/checkout/core/paymentMethod.d.ts +23 -0
- package/es/checkout/core/paymentMethod.js +85 -0
- package/es/checkout/core/pricing.d.ts +32 -0
- package/es/checkout/core/pricing.js +221 -0
- package/es/checkout/core/promotion.d.ts +10 -0
- package/es/checkout/core/promotion.js +39 -0
- package/es/checkout/core/session.d.ts +26 -0
- package/es/checkout/core/session.js +50 -0
- package/es/checkout/core/submit.d.ts +40 -0
- package/es/checkout/core/submit.js +66 -0
- package/es/checkout/hooks/index.d.ts +34 -0
- package/es/checkout/hooks/index.js +19 -0
- package/es/checkout/hooks/useBillingInterval.d.ts +14 -0
- package/es/checkout/hooks/useBillingInterval.js +50 -0
- package/es/checkout/hooks/useCheckout.d.ts +2 -0
- package/es/checkout/hooks/useCheckout.js +212 -0
- package/es/checkout/hooks/useCheckoutSession.d.ts +58 -0
- package/es/checkout/hooks/useCheckoutSession.js +107 -0
- package/es/checkout/hooks/useCheckoutStatus.d.ts +10 -0
- package/es/checkout/hooks/useCheckoutStatus.js +16 -0
- package/es/checkout/hooks/useCrossSell.d.ts +8 -0
- package/es/checkout/hooks/useCrossSell.js +57 -0
- package/es/checkout/hooks/useCustomerForm.d.ts +14 -0
- package/es/checkout/hooks/useCustomerForm.js +116 -0
- package/es/checkout/hooks/useCustomerFormFeature.d.ts +2 -0
- package/es/checkout/hooks/useCustomerFormFeature.js +4 -0
- package/es/checkout/hooks/useExchangeRate.d.ts +11 -0
- package/es/checkout/hooks/useExchangeRate.js +15 -0
- package/es/checkout/hooks/useLineItems.d.ts +22 -0
- package/es/checkout/hooks/useLineItems.js +139 -0
- package/es/checkout/hooks/usePaymentMethod.d.ts +26 -0
- package/es/checkout/hooks/usePaymentMethod.js +101 -0
- package/es/checkout/hooks/usePaymentMethodFeature.d.ts +2 -0
- package/es/checkout/hooks/usePaymentMethodFeature.js +4 -0
- package/es/checkout/hooks/usePricing.d.ts +57 -0
- package/es/checkout/hooks/usePricing.js +174 -0
- package/es/checkout/hooks/usePricingFeature.d.ts +28 -0
- package/es/checkout/hooks/usePricingFeature.js +36 -0
- package/es/checkout/hooks/useProduct.d.ts +32 -0
- package/es/checkout/hooks/useProduct.js +5 -0
- package/es/checkout/hooks/usePromotion.d.ts +12 -0
- package/es/checkout/hooks/usePromotion.js +48 -0
- package/es/checkout/hooks/useSlippage.d.ts +8 -0
- package/es/checkout/hooks/useSlippage.js +29 -0
- package/es/checkout/hooks/useSubmit.d.ts +38 -0
- package/es/checkout/hooks/useSubmit.js +493 -0
- package/es/checkout/hooks/useSubmitFeature.d.ts +2 -0
- package/es/checkout/hooks/useSubmitFeature.js +4 -0
- package/es/checkout/hooks/useUpsell.d.ts +5 -0
- package/es/checkout/hooks/useUpsell.js +25 -0
- package/es/checkout/index.d.ts +37 -0
- package/es/checkout/index.js +28 -0
- package/es/checkout/types.d.ts +262 -0
- package/es/checkout/types.js +0 -0
- package/es/index.d.ts +1 -0
- package/es/index.js +28 -0
- package/es/shared/api.d.ts +41 -0
- package/es/shared/api.js +81 -0
- package/es/shared/format.d.ts +38 -0
- package/es/shared/format.js +229 -0
- package/es/shared/polling.d.ts +15 -0
- package/es/shared/polling.js +20 -0
- package/es/shared/types.d.ts +10 -0
- package/es/shared/types.js +0 -0
- package/es/shared/validation.d.ts +38 -0
- package/es/shared/validation.js +190 -0
- package/es/types/checkout-augmented.d.ts +42 -0
- package/es/types/checkout-augmented.js +17 -0
- package/es/types/external.d.ts +18 -0
- package/examples/01-basic-checkout.tsx +159 -0
- package/examples/01-credit-recharge.tsx +19 -0
- package/examples/02-subscription.tsx +40 -0
- package/examples/03-upsell.tsx +60 -0
- package/examples/04-cross-sell.tsx +54 -0
- package/examples/05-full-checkout.tsx +126 -0
- package/jest.config.js +15 -0
- package/lib/checkout/context/CheckoutProvider.d.ts +6 -0
- package/lib/checkout/context/CheckoutProvider.js +181 -0
- package/lib/checkout/context/CustomerFormContext.d.ts +4 -0
- package/lib/checkout/context/CustomerFormContext.js +16 -0
- package/lib/checkout/context/ExchangeRateContext.d.ts +11 -0
- package/lib/checkout/context/ExchangeRateContext.js +16 -0
- package/lib/checkout/context/PaymentMethodContext.d.ts +26 -0
- package/lib/checkout/context/PaymentMethodContext.js +16 -0
- package/lib/checkout/context/SessionContext.d.ts +45 -0
- package/lib/checkout/context/SessionContext.js +16 -0
- package/lib/checkout/context/SubmitContext.d.ts +4 -0
- package/lib/checkout/context/SubmitContext.js +16 -0
- package/lib/checkout/context/index.d.ts +6 -0
- package/lib/checkout/context/index.js +77 -0
- package/lib/checkout/core/billingInterval.d.ts +15 -0
- package/lib/checkout/core/billingInterval.js +42 -0
- package/lib/checkout/core/crossSell.d.ts +4 -0
- package/lib/checkout/core/crossSell.js +43 -0
- package/lib/checkout/core/customerForm.d.ts +5 -0
- package/lib/checkout/core/customerForm.js +106 -0
- package/lib/checkout/core/exchangeRate.d.ts +11 -0
- package/lib/checkout/core/exchangeRate.js +45 -0
- package/lib/checkout/core/index.d.ts +10 -0
- package/lib/checkout/core/index.js +297 -0
- package/lib/checkout/core/lineItems.d.ts +7 -0
- package/lib/checkout/core/lineItems.js +76 -0
- package/lib/checkout/core/paymentMethod.d.ts +23 -0
- package/lib/checkout/core/paymentMethod.js +114 -0
- package/lib/checkout/core/pricing.d.ts +32 -0
- package/lib/checkout/core/pricing.js +216 -0
- package/lib/checkout/core/promotion.d.ts +10 -0
- package/lib/checkout/core/promotion.js +62 -0
- package/lib/checkout/core/session.d.ts +26 -0
- package/lib/checkout/core/session.js +58 -0
- package/lib/checkout/core/submit.d.ts +40 -0
- package/lib/checkout/core/submit.js +84 -0
- package/lib/checkout/hooks/index.d.ts +34 -0
- package/lib/checkout/hooks/index.js +138 -0
- package/lib/checkout/hooks/useBillingInterval.d.ts +14 -0
- package/lib/checkout/hooks/useBillingInterval.js +63 -0
- package/lib/checkout/hooks/useCheckout.d.ts +2 -0
- package/lib/checkout/hooks/useCheckout.js +190 -0
- package/lib/checkout/hooks/useCheckoutSession.d.ts +58 -0
- package/lib/checkout/hooks/useCheckoutSession.js +119 -0
- package/lib/checkout/hooks/useCheckoutStatus.d.ts +10 -0
- package/lib/checkout/hooks/useCheckoutStatus.js +28 -0
- package/lib/checkout/hooks/useCrossSell.d.ts +8 -0
- package/lib/checkout/hooks/useCrossSell.js +75 -0
- package/lib/checkout/hooks/useCustomerForm.d.ts +14 -0
- package/lib/checkout/hooks/useCustomerForm.js +135 -0
- package/lib/checkout/hooks/useCustomerFormFeature.d.ts +2 -0
- package/lib/checkout/hooks/useCustomerFormFeature.js +10 -0
- package/lib/checkout/hooks/useExchangeRate.d.ts +11 -0
- package/lib/checkout/hooks/useExchangeRate.js +29 -0
- package/lib/checkout/hooks/useLineItems.d.ts +22 -0
- package/lib/checkout/hooks/useLineItems.js +142 -0
- package/lib/checkout/hooks/usePaymentMethod.d.ts +26 -0
- package/lib/checkout/hooks/usePaymentMethod.js +101 -0
- package/lib/checkout/hooks/usePaymentMethodFeature.d.ts +2 -0
- package/lib/checkout/hooks/usePaymentMethodFeature.js +10 -0
- package/lib/checkout/hooks/usePricing.d.ts +57 -0
- package/lib/checkout/hooks/usePricing.js +168 -0
- package/lib/checkout/hooks/usePricingFeature.d.ts +28 -0
- package/lib/checkout/hooks/usePricingFeature.js +48 -0
- package/lib/checkout/hooks/useProduct.d.ts +32 -0
- package/lib/checkout/hooks/useProduct.js +21 -0
- package/lib/checkout/hooks/usePromotion.d.ts +12 -0
- package/lib/checkout/hooks/usePromotion.js +57 -0
- package/lib/checkout/hooks/useSlippage.d.ts +8 -0
- package/lib/checkout/hooks/useSlippage.js +39 -0
- package/lib/checkout/hooks/useSubmit.d.ts +38 -0
- package/lib/checkout/hooks/useSubmit.js +504 -0
- package/lib/checkout/hooks/useSubmitFeature.d.ts +2 -0
- package/lib/checkout/hooks/useSubmitFeature.js +10 -0
- package/lib/checkout/hooks/useUpsell.d.ts +5 -0
- package/lib/checkout/hooks/useUpsell.js +40 -0
- package/lib/checkout/index.d.ts +37 -0
- package/lib/checkout/index.js +182 -0
- package/lib/checkout/types.d.ts +262 -0
- package/lib/checkout/types.js +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +162 -0
- package/lib/shared/api.d.ts +41 -0
- package/lib/shared/api.js +88 -0
- package/lib/shared/format.d.ts +38 -0
- package/lib/shared/format.js +262 -0
- package/lib/shared/polling.d.ts +15 -0
- package/lib/shared/polling.js +32 -0
- package/lib/shared/types.d.ts +10 -0
- package/lib/shared/types.js +1 -0
- package/lib/shared/validation.d.ts +38 -0
- package/lib/shared/validation.js +212 -0
- package/lib/types/checkout-augmented.d.ts +42 -0
- package/lib/types/checkout-augmented.js +24 -0
- package/lib/types/external.d.ts +18 -0
- package/package.json +64 -0
- package/src/checkout/context/CheckoutProvider.tsx +269 -0
- package/src/checkout/context/CustomerFormContext.ts +14 -0
- package/src/checkout/context/ExchangeRateContext.ts +21 -0
- package/src/checkout/context/PaymentMethodContext.ts +36 -0
- package/src/checkout/context/SessionContext.ts +49 -0
- package/src/checkout/context/SubmitContext.ts +14 -0
- package/src/checkout/context/index.ts +6 -0
- package/src/checkout/core/billingInterval.ts +62 -0
- package/src/checkout/core/crossSell.ts +52 -0
- package/src/checkout/core/customerForm.ts +122 -0
- package/src/checkout/core/exchangeRate.ts +38 -0
- package/src/checkout/core/index.ts +60 -0
- package/src/checkout/core/lineItems.ts +106 -0
- package/src/checkout/core/paymentMethod.ts +113 -0
- package/src/checkout/core/pricing.ts +347 -0
- package/src/checkout/core/promotion.ts +59 -0
- package/src/checkout/core/session.ts +62 -0
- package/src/checkout/core/submit.ts +109 -0
- package/src/checkout/hooks/index.ts +41 -0
- package/src/checkout/hooks/useBillingInterval.ts +71 -0
- package/src/checkout/hooks/useCheckout.ts +267 -0
- package/src/checkout/hooks/useCheckoutSession.ts +217 -0
- package/src/checkout/hooks/useCheckoutStatus.ts +31 -0
- package/src/checkout/hooks/useCrossSell.ts +80 -0
- package/src/checkout/hooks/useCustomerForm.ts +156 -0
- package/src/checkout/hooks/useCustomerFormFeature.ts +7 -0
- package/src/checkout/hooks/useExchangeRate.ts +28 -0
- package/src/checkout/hooks/useLineItems.ts +191 -0
- package/src/checkout/hooks/usePaymentMethod.ts +165 -0
- package/src/checkout/hooks/usePaymentMethodFeature.ts +8 -0
- package/src/checkout/hooks/usePricing.ts +274 -0
- package/src/checkout/hooks/usePricingFeature.ts +73 -0
- package/src/checkout/hooks/useProduct.ts +32 -0
- package/src/checkout/hooks/usePromotion.ts +67 -0
- package/src/checkout/hooks/useSlippage.ts +39 -0
- package/src/checkout/hooks/useSubmit.ts +684 -0
- package/src/checkout/hooks/useSubmitFeature.ts +7 -0
- package/src/checkout/hooks/useUpsell.ts +35 -0
- package/src/checkout/index.ts +65 -0
- package/src/checkout/types.ts +292 -0
- package/src/index.ts +64 -0
- package/src/shared/api.ts +118 -0
- package/src/shared/format.ts +318 -0
- package/src/shared/polling.ts +49 -0
- package/src/shared/types.ts +13 -0
- package/src/shared/validation.ts +254 -0
- package/src/types/checkout-augmented.ts +77 -0
- package/src/types/external.d.ts +18 -0
- package/tools/jest.js +1 -0
- package/tsconfig.json +18 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { TPaymentMethodExpanded, TPaymentCurrency, TCheckoutSessionExpanded } from '@blocklet/payment-types';
|
|
2
|
+
import type { CheckoutSessionUser } from '../../types/checkout-augmented';
|
|
3
|
+
export type CurrencyWithMethod = TPaymentCurrency & {
|
|
4
|
+
method?: {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
type: string;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
export declare function flattenCurrencies(methods: TPaymentMethodExpanded[]): CurrencyWithMethod[];
|
|
11
|
+
export declare function hasDidWallet(user: CheckoutSessionUser | undefined): boolean;
|
|
12
|
+
export declare function getCurrencyStorageKey(did?: string): string;
|
|
13
|
+
export declare function getInitialCurrencyId(session: TCheckoutSessionExpanded | undefined | null, methods: TPaymentMethodExpanded[]): string | null;
|
|
14
|
+
export declare function findMethodAndCurrency(methods: TPaymentMethodExpanded[], currencyId: string | null): {
|
|
15
|
+
method: TPaymentMethodExpanded | null;
|
|
16
|
+
currency: TPaymentCurrency | null;
|
|
17
|
+
};
|
|
18
|
+
export declare function buildPaymentTypes(methods: TPaymentMethodExpanded[], currentMethod: TPaymentMethodExpanded | null): {
|
|
19
|
+
type: "stripe" | "crypto";
|
|
20
|
+
label: string;
|
|
21
|
+
currencies: CurrencyWithMethod[];
|
|
22
|
+
active: boolean;
|
|
23
|
+
}[];
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.buildPaymentTypes = buildPaymentTypes;
|
|
7
|
+
exports.findMethodAndCurrency = findMethodAndCurrency;
|
|
8
|
+
exports.flattenCurrencies = flattenCurrencies;
|
|
9
|
+
exports.getCurrencyStorageKey = getCurrencyStorageKey;
|
|
10
|
+
exports.getInitialCurrencyId = getInitialCurrencyId;
|
|
11
|
+
exports.hasDidWallet = hasDidWallet;
|
|
12
|
+
function flattenCurrencies(methods) {
|
|
13
|
+
const out = [];
|
|
14
|
+
methods.forEach(method => {
|
|
15
|
+
const currencies = method.payment_currencies || [];
|
|
16
|
+
currencies.forEach(currency => {
|
|
17
|
+
const enriched = {
|
|
18
|
+
...currency,
|
|
19
|
+
method: {
|
|
20
|
+
id: method.id,
|
|
21
|
+
name: method.name,
|
|
22
|
+
type: method.type
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
out.push(enriched);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
function hasDidWallet(user) {
|
|
31
|
+
const connected = user?.connectedAccounts || user?.extraConfigs?.connectedAccounts || [];
|
|
32
|
+
return connected.some(x => x.provider === "wallet");
|
|
33
|
+
}
|
|
34
|
+
const CURRENCY_PREFERENCE_KEY = "payment-currency-preference";
|
|
35
|
+
function getCurrencyStorageKey(did) {
|
|
36
|
+
return did ? `${CURRENCY_PREFERENCE_KEY}:${did}` : CURRENCY_PREFERENCE_KEY;
|
|
37
|
+
}
|
|
38
|
+
function getInitialCurrencyId(session, methods) {
|
|
39
|
+
if (typeof window !== "undefined") {
|
|
40
|
+
try {
|
|
41
|
+
const params = new URLSearchParams(window.location.search);
|
|
42
|
+
const urlCurrency = params.get("currencyId") || params.get("currency_id");
|
|
43
|
+
if (urlCurrency) return urlCurrency;
|
|
44
|
+
} catch {}
|
|
45
|
+
const user = session?.user;
|
|
46
|
+
if (user && !hasDidWallet(user)) {
|
|
47
|
+
const stripeMethod = methods.find(m => m.type === "stripe");
|
|
48
|
+
const stripeCurrency = stripeMethod?.payment_currencies?.[0];
|
|
49
|
+
if (stripeCurrency) return stripeCurrency.id;
|
|
50
|
+
}
|
|
51
|
+
try {
|
|
52
|
+
const did = session?.user?.did;
|
|
53
|
+
const stored = localStorage.getItem(getCurrencyStorageKey(did));
|
|
54
|
+
if (stored) return stored;
|
|
55
|
+
} catch {}
|
|
56
|
+
}
|
|
57
|
+
return session?.currency_id || null;
|
|
58
|
+
}
|
|
59
|
+
function findMethodAndCurrency(methods, currencyId) {
|
|
60
|
+
if (!currencyId) {
|
|
61
|
+
const first2 = methods[0];
|
|
62
|
+
const firstCurrency = first2?.payment_currencies?.[0] || null;
|
|
63
|
+
return {
|
|
64
|
+
method: first2 || null,
|
|
65
|
+
currency: firstCurrency
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
for (const method of methods) {
|
|
69
|
+
for (const currency of method.payment_currencies || []) {
|
|
70
|
+
if (currency.id === currencyId) {
|
|
71
|
+
return {
|
|
72
|
+
method,
|
|
73
|
+
currency
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
const first = methods[0];
|
|
79
|
+
return {
|
|
80
|
+
method: first || null,
|
|
81
|
+
currency: first?.payment_currencies?.[0] || null
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function buildPaymentTypes(methods, currentMethod) {
|
|
85
|
+
const typeMap = /* @__PURE__ */new Map();
|
|
86
|
+
methods.forEach(method => {
|
|
87
|
+
const type = method.type === "stripe" ? "stripe" : "crypto";
|
|
88
|
+
if (!typeMap.has(type)) {
|
|
89
|
+
typeMap.set(type, {
|
|
90
|
+
currencies: [],
|
|
91
|
+
active: false
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const entry = typeMap.get(type);
|
|
95
|
+
const enriched = (method.payment_currencies || []).map(cur => ({
|
|
96
|
+
...cur,
|
|
97
|
+
method: {
|
|
98
|
+
id: method.id,
|
|
99
|
+
name: method.name,
|
|
100
|
+
type: method.type
|
|
101
|
+
}
|
|
102
|
+
}));
|
|
103
|
+
entry.currencies.push(...enriched);
|
|
104
|
+
if (method === currentMethod) {
|
|
105
|
+
entry.active = true;
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
return Array.from(typeMap.entries()).map(([type, data]) => ({
|
|
109
|
+
type,
|
|
110
|
+
label: type === "stripe" ? "Card" : "Crypto",
|
|
111
|
+
currencies: data.currencies,
|
|
112
|
+
active: data.active
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { TCheckoutSessionExpanded, TPaymentCurrency, TLineItemExpanded } from '@blocklet/payment-types';
|
|
2
|
+
import type { SessionData } from '../hooks/useCheckoutSession';
|
|
3
|
+
export interface CalculatedAmounts {
|
|
4
|
+
subtotal: string;
|
|
5
|
+
paymentAmount: string;
|
|
6
|
+
total: string;
|
|
7
|
+
discount: string | null;
|
|
8
|
+
tax: {
|
|
9
|
+
amount: string;
|
|
10
|
+
rate: number;
|
|
11
|
+
inclusive: boolean;
|
|
12
|
+
} | null;
|
|
13
|
+
staking: string | null;
|
|
14
|
+
usdEquivalent: string | null;
|
|
15
|
+
subtotalUsdEquivalent?: string | null;
|
|
16
|
+
}
|
|
17
|
+
export declare function calculateAmounts(items: TLineItemExpanded[], currency: TPaymentCurrency | null, session: TCheckoutSessionExpanded | undefined | null, exchangeRate: string | null, hasDynamicPricing: boolean, paymentMethodType?: string | null): CalculatedAmounts;
|
|
18
|
+
export interface QuoteMeta {
|
|
19
|
+
locked: boolean;
|
|
20
|
+
lockedAt: number | null;
|
|
21
|
+
expiresAt: number | null;
|
|
22
|
+
expired: boolean;
|
|
23
|
+
baseCurrency: string | null;
|
|
24
|
+
slippagePercent: number | null;
|
|
25
|
+
}
|
|
26
|
+
export declare function calculateQuoteMeta(items: TLineItemExpanded[], hasDynamicPricing: boolean, sessionData: SessionData | null): QuoteMeta;
|
|
27
|
+
export declare function calculateTrial(session: TCheckoutSessionExpanded | undefined | null, currencyId: string | null | undefined, items: TLineItemExpanded[], currency: TPaymentCurrency | null, hasDynamicPricing: boolean, exchangeRate: string | null): {
|
|
28
|
+
active: boolean;
|
|
29
|
+
days: number;
|
|
30
|
+
afterTrialPrice: string | null;
|
|
31
|
+
afterTrialInterval: string | null;
|
|
32
|
+
};
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.calculateAmounts = calculateAmounts;
|
|
7
|
+
exports.calculateQuoteMeta = calculateQuoteMeta;
|
|
8
|
+
exports.calculateTrial = calculateTrial;
|
|
9
|
+
var _util = require("@ocap/util");
|
|
10
|
+
var _format = require("../../shared/format");
|
|
11
|
+
function getStakingSetup(items, currency, billingThreshold = 0) {
|
|
12
|
+
const staking = {
|
|
13
|
+
licensed: new _util.BN(0),
|
|
14
|
+
metered: new _util.BN(0)
|
|
15
|
+
};
|
|
16
|
+
const recurringItems = items.map(x => x.upsell_price || x.price).filter(x => x?.type === "recurring" && x?.recurring);
|
|
17
|
+
if (recurringItems.length > 0) {
|
|
18
|
+
if (+billingThreshold) {
|
|
19
|
+
return (0, _util.fromTokenToUnit)(billingThreshold, currency.decimal).toString();
|
|
20
|
+
}
|
|
21
|
+
items.forEach(x => {
|
|
22
|
+
const price = x.upsell_price || x.price;
|
|
23
|
+
const unit = (0, _format.getPriceUnitAmountByCurrency)(price, currency);
|
|
24
|
+
const amount = new _util.BN(unit).mul(new _util.BN(x.quantity));
|
|
25
|
+
if (price?.type === "recurring" && price?.recurring) {
|
|
26
|
+
if (price.recurring.usage_type === "licensed") {
|
|
27
|
+
staking.licensed = staking.licensed.add(amount);
|
|
28
|
+
}
|
|
29
|
+
if (price.recurring.usage_type === "metered") {
|
|
30
|
+
staking.metered = staking.metered.add(amount);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
return staking.licensed.add(staking.metered).toString();
|
|
35
|
+
}
|
|
36
|
+
return "0";
|
|
37
|
+
}
|
|
38
|
+
function calculateCouponDiscount(items, currency, session, hasDynamicPricing, exchangeRate, trialing, recurringOnly) {
|
|
39
|
+
const discounts = session?.discounts || [];
|
|
40
|
+
if (discounts.length === 0) return new _util.BN(0);
|
|
41
|
+
const coupon = discounts[0].coupon_details || {};
|
|
42
|
+
if (recurringOnly && coupon.duration === "once") return new _util.BN(0);
|
|
43
|
+
const discountableItems = items.filter(item => {
|
|
44
|
+
if (item.discountable === false) return false;
|
|
45
|
+
const price = item.upsell_price || item.price;
|
|
46
|
+
if (price?.recurring?.usage_type === "metered") return false;
|
|
47
|
+
return true;
|
|
48
|
+
});
|
|
49
|
+
const discountableResult = (0, _format.getCheckoutAmount)(discountableItems, currency, trialing, true, {
|
|
50
|
+
exchangeRate: hasDynamicPricing ? exchangeRate : null
|
|
51
|
+
});
|
|
52
|
+
const discountableSubtotalBN = new _util.BN(discountableResult.total);
|
|
53
|
+
if (discountableSubtotalBN.lte(new _util.BN(0))) return new _util.BN(0);
|
|
54
|
+
if (coupon.percent_off && coupon.percent_off > 0) {
|
|
55
|
+
return discountableSubtotalBN.mul(new _util.BN(coupon.percent_off)).div(new _util.BN(100));
|
|
56
|
+
}
|
|
57
|
+
if (coupon.amount_off && coupon.amount_off !== "0") {
|
|
58
|
+
const amountOff = coupon.currency_options?.[currency.id]?.amount_off || coupon.amount_off;
|
|
59
|
+
if (amountOff && amountOff !== "0") {
|
|
60
|
+
const amountOffBN = new _util.BN(amountOff);
|
|
61
|
+
return amountOffBN.lt(discountableSubtotalBN) ? amountOffBN : discountableSubtotalBN;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return new _util.BN(0);
|
|
65
|
+
}
|
|
66
|
+
function calculateAmounts(items, currency, session, exchangeRate, hasDynamicPricing, paymentMethodType) {
|
|
67
|
+
if (!currency || items.length === 0) {
|
|
68
|
+
return {
|
|
69
|
+
subtotal: "0",
|
|
70
|
+
paymentAmount: "0",
|
|
71
|
+
total: "0",
|
|
72
|
+
discount: null,
|
|
73
|
+
tax: null,
|
|
74
|
+
staking: null,
|
|
75
|
+
usdEquivalent: null
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const subData = session?.subscription_data;
|
|
79
|
+
const trialDays = Number(subData?.trial_period_days || 0);
|
|
80
|
+
const trialing = trialDays > 0;
|
|
81
|
+
const result = (0, _format.getCheckoutAmount)(items, currency, trialing, true, {
|
|
82
|
+
exchangeRate: hasDynamicPricing ? exchangeRate : null
|
|
83
|
+
});
|
|
84
|
+
const subtotalBN = new _util.BN(result.total);
|
|
85
|
+
const subtotalFormatted = (0, _format.formatDynamicPrice)((0, _util.fromUnitToToken)(subtotalBN, currency.decimal), hasDynamicPricing);
|
|
86
|
+
const discountBN = calculateCouponDiscount(items, currency, session, hasDynamicPricing, exchangeRate, trialing, false);
|
|
87
|
+
const discount = discountBN.gt(new _util.BN(0)) ? (0, _format.formatDynamicPrice)((0, _util.fromUnitToToken)(discountBN.toString(), currency.decimal), hasDynamicPricing) : null;
|
|
88
|
+
const taxAmount = session?.total_details?.amount_tax;
|
|
89
|
+
const taxBN = new _util.BN(taxAmount || "0");
|
|
90
|
+
const totalDetails = session?.total_details;
|
|
91
|
+
const tax = taxAmount && taxAmount !== "0" ? {
|
|
92
|
+
amount: (0, _util.fromUnitToToken)(taxAmount, currency.decimal),
|
|
93
|
+
rate: totalDetails?.tax_rate || 0,
|
|
94
|
+
inclusive: totalDetails?.tax_inclusive || false
|
|
95
|
+
} : null;
|
|
96
|
+
const noStake = subData?.no_stake || false;
|
|
97
|
+
const billingThreshold = Math.max(Number(subData?.billing_threshold_amount || 0), Number(subData?.min_stake_amount || 0));
|
|
98
|
+
const shouldShowStaking = paymentMethodType === "arcblock" && currency.type !== "credit" && !noStake;
|
|
99
|
+
const stakingUnitStr = shouldShowStaking ? getStakingSetup(items, currency, billingThreshold) : "0";
|
|
100
|
+
const stakingBN = new _util.BN(stakingUnitStr);
|
|
101
|
+
const subtotalWithStakingBN = subtotalBN.add(stakingBN);
|
|
102
|
+
let totalBN = subtotalWithStakingBN.sub(discountBN);
|
|
103
|
+
if (taxBN.gt(new _util.BN(0)) && !tax?.inclusive) {
|
|
104
|
+
totalBN = totalBN.add(taxBN);
|
|
105
|
+
}
|
|
106
|
+
if (totalBN.isNeg()) {
|
|
107
|
+
totalBN = new _util.BN(0);
|
|
108
|
+
}
|
|
109
|
+
const totalFormatted = (0, _format.formatDynamicPrice)((0, _util.fromUnitToToken)(totalBN, currency.decimal), hasDynamicPricing);
|
|
110
|
+
const displaySubtotalBN = subtotalWithStakingBN;
|
|
111
|
+
const displaySubtotalFormatted = (0, _format.formatDynamicPrice)((0, _util.fromUnitToToken)(displaySubtotalBN, currency.decimal), hasDynamicPricing);
|
|
112
|
+
let usdEquivalent = null;
|
|
113
|
+
let subtotalUsdEquivalent = null;
|
|
114
|
+
if (hasDynamicPricing && exchangeRate && currency) {
|
|
115
|
+
const totalUsd = (0, _format.getUsdAmountFromTokenUnits)(totalBN.toString(), currency.decimal, exchangeRate);
|
|
116
|
+
if (totalUsd) {
|
|
117
|
+
usdEquivalent = (0, _format.formatUsdAmount)(totalUsd) || null;
|
|
118
|
+
}
|
|
119
|
+
const subtotalUsd = (0, _format.getUsdAmountFromTokenUnits)(displaySubtotalBN.toString(), currency.decimal, exchangeRate);
|
|
120
|
+
if (subtotalUsd) {
|
|
121
|
+
subtotalUsdEquivalent = (0, _format.formatUsdAmount)(subtotalUsd) || null;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const stakingFormatted = stakingBN.gt(new _util.BN(0)) ? `${(0, _format.formatDynamicPrice)((0, _util.fromUnitToToken)(stakingBN.toString(), currency.decimal), hasDynamicPricing)} ${currency.symbol}` : null;
|
|
125
|
+
return {
|
|
126
|
+
subtotal: `${displaySubtotalFormatted} ${currency.symbol}`,
|
|
127
|
+
paymentAmount: `${subtotalFormatted} ${currency.symbol}`,
|
|
128
|
+
total: `${totalFormatted} ${currency.symbol}`,
|
|
129
|
+
discount: discount ? `${discount} ${currency.symbol}` : null,
|
|
130
|
+
tax,
|
|
131
|
+
staking: stakingFormatted,
|
|
132
|
+
usdEquivalent: usdEquivalent ? `$${usdEquivalent}` : null,
|
|
133
|
+
subtotalUsdEquivalent: subtotalUsdEquivalent ? `$${subtotalUsdEquivalent}` : null
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function calculateQuoteMeta(items, hasDynamicPricing, sessionData) {
|
|
137
|
+
if (!items.length || !hasDynamicPricing) {
|
|
138
|
+
return {
|
|
139
|
+
locked: false,
|
|
140
|
+
lockedAt: null,
|
|
141
|
+
expiresAt: null,
|
|
142
|
+
expired: false,
|
|
143
|
+
baseCurrency: null,
|
|
144
|
+
slippagePercent: null
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
const session = sessionData?.checkoutSession;
|
|
148
|
+
let baseCurrency = null;
|
|
149
|
+
let expiresAt = null;
|
|
150
|
+
let slippagePercent = null;
|
|
151
|
+
items.forEach(item => {
|
|
152
|
+
const price = item.upsell_price || item.price;
|
|
153
|
+
if (!baseCurrency && price?.base_currency) baseCurrency = price.base_currency;
|
|
154
|
+
const expires = item.expires_at;
|
|
155
|
+
if (expires) {
|
|
156
|
+
expiresAt = expiresAt === null ? expires : Math.min(expiresAt, expires);
|
|
157
|
+
}
|
|
158
|
+
const itemSlippage = item.slippage_percent;
|
|
159
|
+
if (slippagePercent === null && Number.isFinite(Number(itemSlippage))) {
|
|
160
|
+
slippagePercent = Number(itemSlippage);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
const piCreated = sessionData?.paymentIntent?.created_at ? new Date(sessionData.paymentIntent.created_at).getTime() : null;
|
|
164
|
+
const sessionLock = session?.quote_locked_at;
|
|
165
|
+
const lockedAt = piCreated || sessionLock || null;
|
|
166
|
+
const locked = !!lockedAt;
|
|
167
|
+
const now = Date.now();
|
|
168
|
+
const expired = expiresAt ? now > expiresAt : false;
|
|
169
|
+
return {
|
|
170
|
+
locked,
|
|
171
|
+
lockedAt,
|
|
172
|
+
expiresAt,
|
|
173
|
+
expired,
|
|
174
|
+
baseCurrency,
|
|
175
|
+
slippagePercent
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
function calculateTrial(session, currencyId, items, currency, hasDynamicPricing, exchangeRate) {
|
|
179
|
+
const subData = session?.subscription_data;
|
|
180
|
+
let trialDays = Number(subData?.trial_period_days || 0);
|
|
181
|
+
if (trialDays > 0 && currencyId) {
|
|
182
|
+
const trialCurrencyIds = (subData?.trial_currency || "").split(",").map(s => s.trim()).filter(Boolean);
|
|
183
|
+
if (trialCurrencyIds.length > 0 && !trialCurrencyIds.includes(currencyId)) {
|
|
184
|
+
trialDays = 0;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
const trialActive = trialDays > 0;
|
|
188
|
+
let afterTrialPrice = null;
|
|
189
|
+
let afterTrialInterval = null;
|
|
190
|
+
if (trialActive && currency && items.length > 0) {
|
|
191
|
+
const noTrialResult = (0, _format.getCheckoutAmount)(items, currency, false, true, {
|
|
192
|
+
exchangeRate: hasDynamicPricing ? exchangeRate : null
|
|
193
|
+
});
|
|
194
|
+
let afterTrialBN = new _util.BN(noTrialResult.total);
|
|
195
|
+
const recurringDiscount = calculateCouponDiscount(items, currency, session, hasDynamicPricing, exchangeRate, false, true);
|
|
196
|
+
if (recurringDiscount.gt(new _util.BN(0))) {
|
|
197
|
+
afterTrialBN = afterTrialBN.sub(recurringDiscount);
|
|
198
|
+
if (afterTrialBN.isNeg()) afterTrialBN = new _util.BN(0);
|
|
199
|
+
}
|
|
200
|
+
afterTrialPrice = `${(0, _format.formatDynamicPrice)((0, _util.fromUnitToToken)(afterTrialBN, currency.decimal), hasDynamicPricing)} ${currency.symbol}`;
|
|
201
|
+
const recurringItem = items.find(item => {
|
|
202
|
+
const price = item.upsell_price || item.price;
|
|
203
|
+
return price?.type === "recurring" && price?.recurring;
|
|
204
|
+
});
|
|
205
|
+
if (recurringItem) {
|
|
206
|
+
const price = recurringItem.upsell_price || recurringItem.price;
|
|
207
|
+
afterTrialInterval = price?.recurring?.interval || null;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
active: trialActive,
|
|
212
|
+
days: trialDays,
|
|
213
|
+
afterTrialPrice,
|
|
214
|
+
afterTrialInterval
|
|
215
|
+
};
|
|
216
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { TCheckoutSessionExpanded } from '@blocklet/payment-types';
|
|
2
|
+
export declare function extractPromotionCodeFromSession(session: TCheckoutSessionExpanded | undefined | null): string | null;
|
|
3
|
+
export declare function applyPromotionCode(sessionId: string, code: string, currencyId: string | null | undefined): Promise<{
|
|
4
|
+
success: boolean;
|
|
5
|
+
error?: string;
|
|
6
|
+
}>;
|
|
7
|
+
export declare function removePromotionCode(sessionId: string): Promise<void>;
|
|
8
|
+
export declare function recalculatePromotion(sessionId: string, currencyId: string | null | undefined): Promise<void>;
|
|
9
|
+
export declare function isPromotionActive(session: TCheckoutSessionExpanded | undefined | null): boolean;
|
|
10
|
+
export declare function hasAppliedDiscounts(session: TCheckoutSessionExpanded | undefined | null): boolean;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.applyPromotionCode = applyPromotionCode;
|
|
7
|
+
exports.extractPromotionCodeFromSession = extractPromotionCodeFromSession;
|
|
8
|
+
exports.hasAppliedDiscounts = hasAppliedDiscounts;
|
|
9
|
+
exports.isPromotionActive = isPromotionActive;
|
|
10
|
+
exports.recalculatePromotion = recalculatePromotion;
|
|
11
|
+
exports.removePromotionCode = removePromotionCode;
|
|
12
|
+
var _api = _interopRequireWildcard(require("../../shared/api"));
|
|
13
|
+
var _checkoutAugmented = require("../../types/checkout-augmented");
|
|
14
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
15
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
16
|
+
function extractPromotionCodeFromSession(session) {
|
|
17
|
+
const discounts = session?.discounts || [];
|
|
18
|
+
if (discounts.length === 0) return null;
|
|
19
|
+
const firstDiscount = discounts[0];
|
|
20
|
+
const details = firstDiscount.promotion_code_details;
|
|
21
|
+
const verification = firstDiscount.verification_data;
|
|
22
|
+
return details?.code || verification?.code || firstDiscount.promotion_code || firstDiscount.coupon || null;
|
|
23
|
+
}
|
|
24
|
+
async function applyPromotionCode(sessionId, code, currencyId) {
|
|
25
|
+
try {
|
|
26
|
+
const {
|
|
27
|
+
data
|
|
28
|
+
} = await _api.default.post(_api.API.APPLY_PROMOTION(sessionId), {
|
|
29
|
+
promotion_code: code,
|
|
30
|
+
currency_id: currencyId
|
|
31
|
+
});
|
|
32
|
+
if (data.error) {
|
|
33
|
+
return {
|
|
34
|
+
success: false,
|
|
35
|
+
error: data.error
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
success: true
|
|
40
|
+
};
|
|
41
|
+
} catch (err) {
|
|
42
|
+
return {
|
|
43
|
+
success: false,
|
|
44
|
+
error: (0, _checkoutAugmented.getErrorMessage)(err) || "Invalid promotion code"
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
async function removePromotionCode(sessionId) {
|
|
49
|
+
await _api.default.delete(_api.API.REMOVE_PROMOTION(sessionId));
|
|
50
|
+
}
|
|
51
|
+
async function recalculatePromotion(sessionId, currencyId) {
|
|
52
|
+
await _api.default.post(_api.API.RECALCULATE_PROMOTION_SESSION(sessionId), {
|
|
53
|
+
currency_id: currencyId
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
function isPromotionActive(session) {
|
|
57
|
+
return session?.allow_promotion_codes !== false;
|
|
58
|
+
}
|
|
59
|
+
function hasAppliedDiscounts(session) {
|
|
60
|
+
const discounts = session?.discounts || [];
|
|
61
|
+
return discounts.length > 0;
|
|
62
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { TCheckoutSessionExpanded } from '@blocklet/payment-types';
|
|
2
|
+
export declare function parseProduct(session: TCheckoutSessionExpanded): {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
images: any[];
|
|
6
|
+
features: {
|
|
7
|
+
name: string;
|
|
8
|
+
icon: string | undefined;
|
|
9
|
+
}[];
|
|
10
|
+
billing: {
|
|
11
|
+
mode: "payment" | "subscription";
|
|
12
|
+
interval: "month" | "year" | "week" | "day" | null;
|
|
13
|
+
intervalCount: number;
|
|
14
|
+
displayInterval: string;
|
|
15
|
+
};
|
|
16
|
+
metadata: Record<string, any>;
|
|
17
|
+
} | null;
|
|
18
|
+
export declare function parseSubscription(session: TCheckoutSessionExpanded): {
|
|
19
|
+
mode: "payment" | "subscription" | "setup";
|
|
20
|
+
showStake: boolean;
|
|
21
|
+
confirmMessage: string;
|
|
22
|
+
} | null;
|
|
23
|
+
export declare function parsePageInfo(session: TCheckoutSessionExpanded): {
|
|
24
|
+
formPurposeDescription: any;
|
|
25
|
+
showProductFeatures: boolean;
|
|
26
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.parsePageInfo = parsePageInfo;
|
|
7
|
+
exports.parseProduct = parseProduct;
|
|
8
|
+
exports.parseSubscription = parseSubscription;
|
|
9
|
+
function parseProduct(session) {
|
|
10
|
+
const items = session.line_items || [];
|
|
11
|
+
if (items.length === 0) return null;
|
|
12
|
+
const firstItem = items[0];
|
|
13
|
+
const price = firstItem.upsell_price || firstItem.price;
|
|
14
|
+
const product = price?.product;
|
|
15
|
+
if (!product) return null;
|
|
16
|
+
const recurring = price?.recurring;
|
|
17
|
+
const mode = session.mode === "subscription" ? "subscription" : "payment";
|
|
18
|
+
const intervalMap = {
|
|
19
|
+
day: "daily",
|
|
20
|
+
week: "weekly",
|
|
21
|
+
month: "monthly",
|
|
22
|
+
year: "yearly"
|
|
23
|
+
};
|
|
24
|
+
return {
|
|
25
|
+
name: product.name || "",
|
|
26
|
+
description: product.description || "",
|
|
27
|
+
images: product.images || [],
|
|
28
|
+
features: (product.features || []).map(f => ({
|
|
29
|
+
name: f.name || "",
|
|
30
|
+
icon: f.icon
|
|
31
|
+
})),
|
|
32
|
+
billing: {
|
|
33
|
+
mode,
|
|
34
|
+
interval: recurring?.interval || null,
|
|
35
|
+
intervalCount: recurring?.interval_count || 1,
|
|
36
|
+
displayInterval: recurring ? intervalMap[recurring.interval] || recurring.interval : ""
|
|
37
|
+
},
|
|
38
|
+
metadata: product.metadata || {}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function parseSubscription(session) {
|
|
42
|
+
const subData = session.subscription_data;
|
|
43
|
+
if (!subData && session.mode === "payment") return null;
|
|
44
|
+
return {
|
|
45
|
+
mode: session.mode || "payment",
|
|
46
|
+
showStake: !subData?.no_stake,
|
|
47
|
+
confirmMessage: ""
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
function parsePageInfo(session) {
|
|
51
|
+
const metadata = session.metadata;
|
|
52
|
+
const pageInfo = metadata?.page_info;
|
|
53
|
+
const showRaw = metadata?.show_product_features ?? pageInfo?.show_product_features;
|
|
54
|
+
return {
|
|
55
|
+
formPurposeDescription: pageInfo?.form_purpose_description,
|
|
56
|
+
showProductFeatures: `${showRaw}` === "true"
|
|
57
|
+
};
|
|
58
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { TCheckoutSessionExpanded } from '@blocklet/payment-types';
|
|
2
|
+
import type { CheckoutFormData } from '../types';
|
|
3
|
+
export declare const QUOTE_ERROR_CODES: readonly ["QUOTE_LOCK_EXPIRED", "QUOTE_AMOUNT_MISMATCH", "QUOTE_EXPIRED_OR_USED", "QUOTE_NOT_FOUND", "QUOTE_REQUIRED", "QUOTE_MAX_PAYABLE_EXCEEDED", "quote_validation_failed"];
|
|
4
|
+
export declare const RELAY_SOCKET_PREFIX = "/.well-known/service/relay";
|
|
5
|
+
export declare function getAppId(): string;
|
|
6
|
+
export declare function getRelayChannel(token: string): string;
|
|
7
|
+
export declare function getRelayProtocol(): string;
|
|
8
|
+
export declare function getSocketHost(): string;
|
|
9
|
+
/**
|
|
10
|
+
* Compute a fingerprint of the payment context for idempotency key stability.
|
|
11
|
+
* Key changes only when session state actually changes (quantity, upsell, currency).
|
|
12
|
+
* Same fingerprint → reuse Quote (intent: "retry with same Quote").
|
|
13
|
+
*/
|
|
14
|
+
export declare function getSessionFingerprint(session: TCheckoutSessionExpanded | undefined | null, currencyId: string | null): string;
|
|
15
|
+
export declare function buildSubmitPayload(sessionId: string, currencyId: string | null, formValues: CheckoutFormData, session: TCheckoutSessionExpanded | undefined | null, priceConfirmed?: boolean, idempotencyKey?: string): {
|
|
16
|
+
price_confirmed?: boolean | undefined;
|
|
17
|
+
idempotency_key: string;
|
|
18
|
+
preview_rate: string | undefined;
|
|
19
|
+
customer_name: string;
|
|
20
|
+
customer_email?: string;
|
|
21
|
+
customer_phone?: string;
|
|
22
|
+
payment_method: string;
|
|
23
|
+
payment_currency: string;
|
|
24
|
+
billing_address?: {
|
|
25
|
+
country: string;
|
|
26
|
+
state?: string;
|
|
27
|
+
city?: string;
|
|
28
|
+
line1?: string;
|
|
29
|
+
line2?: string;
|
|
30
|
+
postal_code: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
export declare function isQuoteError(errorCode: string): boolean;
|
|
34
|
+
export declare function abortStripePayment(sessionId: string): Promise<void>;
|
|
35
|
+
export declare function submitCheckout(sessionId: string, isDonation: boolean, payload: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
36
|
+
export declare function confirmFastCheckout(sessionId: string): Promise<Record<string, unknown>>;
|
|
37
|
+
export declare function updateSlippage(sessionId: string, config: {
|
|
38
|
+
mode: string;
|
|
39
|
+
percent: number;
|
|
40
|
+
}): Promise<Record<string, unknown>>;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.RELAY_SOCKET_PREFIX = exports.QUOTE_ERROR_CODES = void 0;
|
|
7
|
+
exports.abortStripePayment = abortStripePayment;
|
|
8
|
+
exports.buildSubmitPayload = buildSubmitPayload;
|
|
9
|
+
exports.confirmFastCheckout = confirmFastCheckout;
|
|
10
|
+
exports.getAppId = getAppId;
|
|
11
|
+
exports.getRelayChannel = getRelayChannel;
|
|
12
|
+
exports.getRelayProtocol = getRelayProtocol;
|
|
13
|
+
exports.getSessionFingerprint = getSessionFingerprint;
|
|
14
|
+
exports.getSocketHost = getSocketHost;
|
|
15
|
+
exports.isQuoteError = isQuoteError;
|
|
16
|
+
exports.submitCheckout = submitCheckout;
|
|
17
|
+
exports.updateSlippage = updateSlippage;
|
|
18
|
+
var _api = _interopRequireWildcard(require("../../shared/api"));
|
|
19
|
+
var _polling = require("../../shared/polling");
|
|
20
|
+
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
21
|
+
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
22
|
+
const QUOTE_ERROR_CODES = exports.QUOTE_ERROR_CODES = ["QUOTE_LOCK_EXPIRED", "QUOTE_AMOUNT_MISMATCH", "QUOTE_EXPIRED_OR_USED", "QUOTE_NOT_FOUND", "QUOTE_REQUIRED", "QUOTE_MAX_PAYABLE_EXCEEDED", "quote_validation_failed"];
|
|
23
|
+
const RELAY_SOCKET_PREFIX = exports.RELAY_SOCKET_PREFIX = "/.well-known/service/relay";
|
|
24
|
+
function getAppId() {
|
|
25
|
+
const blocklet = window.blocklet;
|
|
26
|
+
return blocklet?.appPid || blocklet?.appId || "";
|
|
27
|
+
}
|
|
28
|
+
function getRelayChannel(token) {
|
|
29
|
+
return `relay:${getAppId()}:${token}`;
|
|
30
|
+
}
|
|
31
|
+
function getRelayProtocol() {
|
|
32
|
+
return window.location.protocol === "https:" ? "wss:" : "ws:";
|
|
33
|
+
}
|
|
34
|
+
function getSocketHost() {
|
|
35
|
+
return new URL(window.location.href).host;
|
|
36
|
+
}
|
|
37
|
+
function getSessionFingerprint(session, currencyId) {
|
|
38
|
+
if (!session) return "";
|
|
39
|
+
const items = session.line_items || [];
|
|
40
|
+
const sig = items.map(i => `${i.upsell_price_id || i.price_id}:${i.quantity}`).join("|");
|
|
41
|
+
return `${session.id}-${currencyId}-${sig}`;
|
|
42
|
+
}
|
|
43
|
+
function buildSubmitPayload(sessionId, currencyId, formValues, session, priceConfirmed = false, idempotencyKey) {
|
|
44
|
+
const lineItems = session?.line_items || [];
|
|
45
|
+
const matchedItem = lineItems.find(item => item.exchange_rate);
|
|
46
|
+
const previewRate = matchedItem?.exchange_rate;
|
|
47
|
+
return {
|
|
48
|
+
...formValues,
|
|
49
|
+
idempotency_key: idempotencyKey || (0, _polling.generateIdempotencyKey)(sessionId, currencyId || ""),
|
|
50
|
+
preview_rate: previewRate || void 0,
|
|
51
|
+
...(priceConfirmed && {
|
|
52
|
+
price_confirmed: true
|
|
53
|
+
})
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function isQuoteError(errorCode) {
|
|
57
|
+
return QUOTE_ERROR_CODES.includes(errorCode) || errorCode === "QUOTE_UPDATED";
|
|
58
|
+
}
|
|
59
|
+
async function abortStripePayment(sessionId) {
|
|
60
|
+
try {
|
|
61
|
+
await _api.default.post(_api.API.ABORT_STRIPE(sessionId));
|
|
62
|
+
} catch {}
|
|
63
|
+
}
|
|
64
|
+
async function submitCheckout(sessionId, isDonation, payload) {
|
|
65
|
+
const url = isDonation ? _api.API.DONATE_SUBMIT(sessionId) : _api.API.SUBMIT(sessionId);
|
|
66
|
+
const {
|
|
67
|
+
data
|
|
68
|
+
} = await _api.default.put(url, payload);
|
|
69
|
+
return data;
|
|
70
|
+
}
|
|
71
|
+
async function confirmFastCheckout(sessionId) {
|
|
72
|
+
const {
|
|
73
|
+
data
|
|
74
|
+
} = await _api.default.post(_api.API.FAST_CHECKOUT_CONFIRM(sessionId), {});
|
|
75
|
+
return data;
|
|
76
|
+
}
|
|
77
|
+
async function updateSlippage(sessionId, config) {
|
|
78
|
+
const {
|
|
79
|
+
data
|
|
80
|
+
} = await _api.default.put(_api.API.SLIPPAGE(sessionId), {
|
|
81
|
+
slippage_config: config
|
|
82
|
+
});
|
|
83
|
+
return data;
|
|
84
|
+
}
|