@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,262 @@
|
|
|
1
|
+
import type { TLineItemExpanded, TPaymentMethodExpanded, TPaymentCurrency, TPrice, TCheckoutSessionExpanded, TPaymentIntent, TCustomer } from '@blocklet/payment-types';
|
|
2
|
+
export type SubmitStatus = 'idle' | 'submitting' | 'confirming_price' | 'confirming_fast_pay' | 'credit_insufficient' | 'waiting_did' | 'waiting_stripe' | 'completed' | 'failed';
|
|
3
|
+
export type SubmitContext = {
|
|
4
|
+
type: 'price_change';
|
|
5
|
+
changePercent: number;
|
|
6
|
+
} | {
|
|
7
|
+
type: 'fast_pay';
|
|
8
|
+
payType: 'balance' | 'delegation' | 'credit';
|
|
9
|
+
amount: string;
|
|
10
|
+
payer: string;
|
|
11
|
+
} | {
|
|
12
|
+
type: 'credit_insufficient';
|
|
13
|
+
available: string;
|
|
14
|
+
required: string;
|
|
15
|
+
} | {
|
|
16
|
+
type: 'stripe';
|
|
17
|
+
clientSecret: string;
|
|
18
|
+
intentType?: 'payment_intent' | 'setup_intent';
|
|
19
|
+
} | {
|
|
20
|
+
type: 'did_connect';
|
|
21
|
+
action: string;
|
|
22
|
+
checkpointId: string;
|
|
23
|
+
extraParams: Record<string, unknown>;
|
|
24
|
+
} | {
|
|
25
|
+
type: 'error';
|
|
26
|
+
message: string;
|
|
27
|
+
code?: string;
|
|
28
|
+
} | null;
|
|
29
|
+
export interface FieldConfig {
|
|
30
|
+
name: string;
|
|
31
|
+
type: 'text' | 'email' | 'phone' | 'select' | 'country';
|
|
32
|
+
required: boolean;
|
|
33
|
+
options?: Array<{
|
|
34
|
+
value: string;
|
|
35
|
+
label: string;
|
|
36
|
+
}>;
|
|
37
|
+
group?: string;
|
|
38
|
+
}
|
|
39
|
+
export type CheckoutFormData = {
|
|
40
|
+
customer_name: string;
|
|
41
|
+
customer_email?: string;
|
|
42
|
+
customer_phone?: string;
|
|
43
|
+
payment_method: string;
|
|
44
|
+
payment_currency: string;
|
|
45
|
+
billing_address?: {
|
|
46
|
+
country: string;
|
|
47
|
+
state?: string;
|
|
48
|
+
city?: string;
|
|
49
|
+
line1?: string;
|
|
50
|
+
line2?: string;
|
|
51
|
+
postal_code: string;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
export type CheckoutResult = {
|
|
55
|
+
checkoutSession: TCheckoutSessionExpanded;
|
|
56
|
+
paymentMethods: TPaymentMethodExpanded[];
|
|
57
|
+
paymentIntent?: TPaymentIntent;
|
|
58
|
+
customer?: TCustomer;
|
|
59
|
+
quotes?: Record<string, {
|
|
60
|
+
quote_id: string;
|
|
61
|
+
expires_at: number;
|
|
62
|
+
quoted_amount: string;
|
|
63
|
+
exchange_rate?: string;
|
|
64
|
+
rate_provider_name?: string;
|
|
65
|
+
rate_provider_id?: string;
|
|
66
|
+
}>;
|
|
67
|
+
rateUnavailable?: boolean;
|
|
68
|
+
};
|
|
69
|
+
export interface UseCheckoutReturn {
|
|
70
|
+
isLoading: boolean;
|
|
71
|
+
error: string | null;
|
|
72
|
+
/** Structured error code: 'SESSION_EXPIRED' | 'EMPTY_LINE_ITEMS' | null */
|
|
73
|
+
errorCode: 'SESSION_EXPIRED' | 'EMPTY_LINE_ITEMS' | null;
|
|
74
|
+
refresh: () => Promise<void>;
|
|
75
|
+
vendorCount: number;
|
|
76
|
+
product: {
|
|
77
|
+
name: string;
|
|
78
|
+
description: string;
|
|
79
|
+
images: string[];
|
|
80
|
+
features: Array<{
|
|
81
|
+
name: string;
|
|
82
|
+
icon?: string;
|
|
83
|
+
}>;
|
|
84
|
+
billing: {
|
|
85
|
+
mode: 'payment' | 'subscription';
|
|
86
|
+
interval: 'month' | 'year' | 'week' | 'day' | null;
|
|
87
|
+
intervalCount: number;
|
|
88
|
+
displayInterval: string;
|
|
89
|
+
};
|
|
90
|
+
metadata: Record<string, string>;
|
|
91
|
+
} | null;
|
|
92
|
+
lineItems: {
|
|
93
|
+
items: Array<TLineItemExpanded & {
|
|
94
|
+
adjustable_quantity?: {
|
|
95
|
+
enabled: boolean;
|
|
96
|
+
minimum?: number;
|
|
97
|
+
maximum?: number;
|
|
98
|
+
};
|
|
99
|
+
}>;
|
|
100
|
+
updateQuantity: (itemId: string, qty: number) => Promise<void>;
|
|
101
|
+
upsell: (fromId: string, toId: string) => Promise<void>;
|
|
102
|
+
downsell: (priceId: string) => Promise<void>;
|
|
103
|
+
billingInterval: {
|
|
104
|
+
current: 'month' | 'year' | 'week' | 'day' | null;
|
|
105
|
+
available: Array<{
|
|
106
|
+
interval: 'month' | 'year' | 'week' | 'day';
|
|
107
|
+
priceId: string;
|
|
108
|
+
amount: string;
|
|
109
|
+
savings: string | null;
|
|
110
|
+
}>;
|
|
111
|
+
switch: (interval: 'month' | 'year' | 'week' | 'day') => Promise<void>;
|
|
112
|
+
} | null;
|
|
113
|
+
crossSellItem: TPrice | null;
|
|
114
|
+
crossSellRequired: boolean;
|
|
115
|
+
addCrossSell: () => Promise<void>;
|
|
116
|
+
removeCrossSell: () => Promise<void>;
|
|
117
|
+
};
|
|
118
|
+
paymentMethod: {
|
|
119
|
+
current: TPaymentMethodExpanded;
|
|
120
|
+
currency: TPaymentCurrency;
|
|
121
|
+
available: TPaymentMethodExpanded[];
|
|
122
|
+
currencies: TPaymentCurrency[];
|
|
123
|
+
isStripe: boolean;
|
|
124
|
+
isCrypto: boolean;
|
|
125
|
+
isCredit: boolean;
|
|
126
|
+
setType: (type: 'stripe' | 'crypto') => Promise<void>;
|
|
127
|
+
types: Array<{
|
|
128
|
+
type: 'stripe' | 'crypto';
|
|
129
|
+
label: string;
|
|
130
|
+
currencies: TPaymentCurrency[];
|
|
131
|
+
active: boolean;
|
|
132
|
+
}>;
|
|
133
|
+
setCurrency: (currencyId: string) => Promise<void>;
|
|
134
|
+
};
|
|
135
|
+
stripe: {
|
|
136
|
+
publishableKey: string | null;
|
|
137
|
+
clientSecret: string | null;
|
|
138
|
+
status: 'idle' | 'ready' | 'processing' | 'succeeded' | 'failed';
|
|
139
|
+
} | null;
|
|
140
|
+
pricing: {
|
|
141
|
+
subtotal: string;
|
|
142
|
+
discount: string | null;
|
|
143
|
+
tax: {
|
|
144
|
+
amount: string;
|
|
145
|
+
rate: number;
|
|
146
|
+
inclusive: boolean;
|
|
147
|
+
} | null;
|
|
148
|
+
staking: string | null;
|
|
149
|
+
total: string;
|
|
150
|
+
usdEquivalent: string | null;
|
|
151
|
+
hasDynamicPricing: boolean;
|
|
152
|
+
rate: {
|
|
153
|
+
value: string | null;
|
|
154
|
+
display: string | null;
|
|
155
|
+
provider: string | null;
|
|
156
|
+
providerDisplay: string | null;
|
|
157
|
+
fetchedAt: number | null;
|
|
158
|
+
status: 'loading' | 'available' | 'unavailable';
|
|
159
|
+
refresh: () => Promise<void>;
|
|
160
|
+
};
|
|
161
|
+
quote: {
|
|
162
|
+
locked: boolean;
|
|
163
|
+
lockedAt: number | null;
|
|
164
|
+
expiresAt: number | null;
|
|
165
|
+
expired: boolean;
|
|
166
|
+
baseCurrency: string | null;
|
|
167
|
+
};
|
|
168
|
+
slippage: {
|
|
169
|
+
percent: number;
|
|
170
|
+
set: (config: {
|
|
171
|
+
mode: string;
|
|
172
|
+
percent: number;
|
|
173
|
+
}) => Promise<void>;
|
|
174
|
+
};
|
|
175
|
+
promotion: {
|
|
176
|
+
applied: boolean;
|
|
177
|
+
code: string | null;
|
|
178
|
+
active: boolean;
|
|
179
|
+
inactiveReason: string | null;
|
|
180
|
+
apply: (code: string) => Promise<{
|
|
181
|
+
success: boolean;
|
|
182
|
+
error?: string;
|
|
183
|
+
}>;
|
|
184
|
+
remove: () => Promise<void>;
|
|
185
|
+
};
|
|
186
|
+
trial: {
|
|
187
|
+
active: boolean;
|
|
188
|
+
days: number;
|
|
189
|
+
afterTrialPrice: string | null;
|
|
190
|
+
afterTrialInterval: string | null;
|
|
191
|
+
};
|
|
192
|
+
};
|
|
193
|
+
form: {
|
|
194
|
+
fields: FieldConfig[];
|
|
195
|
+
values: CheckoutFormData;
|
|
196
|
+
onChange: (field: string, value: string | boolean | Record<string, string>) => void;
|
|
197
|
+
errors: Partial<Record<string, string>>;
|
|
198
|
+
touched: Record<string, boolean>;
|
|
199
|
+
validate: () => Promise<boolean>;
|
|
200
|
+
validateField: (field: string) => Promise<void>;
|
|
201
|
+
};
|
|
202
|
+
submit: {
|
|
203
|
+
status: SubmitStatus;
|
|
204
|
+
context: SubmitContext;
|
|
205
|
+
execute: () => Promise<void>;
|
|
206
|
+
confirm: () => Promise<void>;
|
|
207
|
+
cancel: () => void;
|
|
208
|
+
result: CheckoutResult | null;
|
|
209
|
+
retry: () => Promise<void>;
|
|
210
|
+
reset: () => void;
|
|
211
|
+
stripeConfirm: () => Promise<void>;
|
|
212
|
+
stripeCancel: () => Promise<void>;
|
|
213
|
+
vendorStatus: {
|
|
214
|
+
payment_status: string;
|
|
215
|
+
session_status: string;
|
|
216
|
+
vendors: Array<{
|
|
217
|
+
success: boolean;
|
|
218
|
+
status: 'delivered' | 'pending' | 'failed';
|
|
219
|
+
progress: number;
|
|
220
|
+
message: string;
|
|
221
|
+
appUrl?: string;
|
|
222
|
+
title?: string;
|
|
223
|
+
name?: string;
|
|
224
|
+
vendorType: string;
|
|
225
|
+
}>;
|
|
226
|
+
error: string | null;
|
|
227
|
+
isAllCompleted: boolean;
|
|
228
|
+
hasFailed: boolean;
|
|
229
|
+
} | null;
|
|
230
|
+
};
|
|
231
|
+
subscription: {
|
|
232
|
+
mode: 'payment' | 'subscription' | 'setup';
|
|
233
|
+
showStake: boolean;
|
|
234
|
+
confirmMessage: string;
|
|
235
|
+
} | null;
|
|
236
|
+
pageInfo: {
|
|
237
|
+
formPurposeDescription?: {
|
|
238
|
+
en: string;
|
|
239
|
+
zh: string;
|
|
240
|
+
};
|
|
241
|
+
showProductFeatures: boolean;
|
|
242
|
+
} | null;
|
|
243
|
+
canSubmit: boolean;
|
|
244
|
+
isCompleted: boolean;
|
|
245
|
+
isDonation: boolean;
|
|
246
|
+
setDonationAmount: (priceId: string, amount: string) => Promise<void>;
|
|
247
|
+
customer: {
|
|
248
|
+
name: string;
|
|
249
|
+
email: string;
|
|
250
|
+
phone: string;
|
|
251
|
+
address: {
|
|
252
|
+
country: string;
|
|
253
|
+
state: string;
|
|
254
|
+
city: string;
|
|
255
|
+
line1: string;
|
|
256
|
+
line2: string;
|
|
257
|
+
postal_code: string;
|
|
258
|
+
};
|
|
259
|
+
} | null;
|
|
260
|
+
livemode: boolean;
|
|
261
|
+
session: TCheckoutSessionExpanded | null;
|
|
262
|
+
}
|
|
File without changes
|
package/es/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { type UseCheckoutReturn, type SubmitStatus, type SubmitContext, type FieldConfig, type CheckoutFormData, type CheckoutResult, type UseCheckoutSessionReturn, type SessionData, type UsePaymentMethodReturn, type UsePricingReturn, type UseCustomerFormReturn, type UseSubmitReturn, type UseProductReturn, type UseLineItemsReturn, type UseBillingIntervalReturn, type BillingIntervalData, type UseUpsellReturn, type UseCrossSellReturn, type UsePromotionReturn, type UseExchangeRateReturn, type UseSlippageReturn, type UseCheckoutStatusReturn, type UsePricingFeatureReturn, type CheckoutProviderProps, CheckoutProvider, useSessionContext, usePaymentMethodContext, useExchangeRateContext, useCustomerFormContext, useSubmitContext, useCheckout, useCheckoutSession, usePaymentMethod, usePricing, useCustomerForm, useSubmit, useProduct, useLineItems, useBillingInterval, useUpsell, useCrossSell, usePromotion, useExchangeRate, useSlippage, useCheckoutStatus, usePricingFeature, usePaymentMethodFeature, useCustomerFormFeature, useSubmitFeature, getPriceUnitAmountByCurrency, } from './checkout';
|
package/es/index.js
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export {
|
|
2
|
+
CheckoutProvider,
|
|
3
|
+
useSessionContext,
|
|
4
|
+
usePaymentMethodContext,
|
|
5
|
+
useExchangeRateContext,
|
|
6
|
+
useCustomerFormContext,
|
|
7
|
+
useSubmitContext,
|
|
8
|
+
useCheckout,
|
|
9
|
+
useCheckoutSession,
|
|
10
|
+
usePaymentMethod,
|
|
11
|
+
usePricing,
|
|
12
|
+
useCustomerForm,
|
|
13
|
+
useSubmit,
|
|
14
|
+
useProduct,
|
|
15
|
+
useLineItems,
|
|
16
|
+
useBillingInterval,
|
|
17
|
+
useUpsell,
|
|
18
|
+
useCrossSell,
|
|
19
|
+
usePromotion,
|
|
20
|
+
useExchangeRate,
|
|
21
|
+
useSlippage,
|
|
22
|
+
useCheckoutStatus,
|
|
23
|
+
usePricingFeature,
|
|
24
|
+
usePaymentMethodFeature,
|
|
25
|
+
useCustomerFormFeature,
|
|
26
|
+
useSubmitFeature,
|
|
27
|
+
getPriceUnitAmountByCurrency
|
|
28
|
+
} from "./checkout/index.js";
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
declare global {
|
|
2
|
+
interface Window {
|
|
3
|
+
blocklet?: {
|
|
4
|
+
prefix?: string;
|
|
5
|
+
componentId?: string;
|
|
6
|
+
componentMountPoints?: Array<{
|
|
7
|
+
did: string;
|
|
8
|
+
mountPoint: string;
|
|
9
|
+
}>;
|
|
10
|
+
appName?: string;
|
|
11
|
+
languages?: string[];
|
|
12
|
+
};
|
|
13
|
+
__PAYMENT_KIT_AUTH_TOKEN?: string;
|
|
14
|
+
__PAYMENT_KIT_BASE_URL?: string;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export declare function getPrefix(): string;
|
|
18
|
+
export declare function getLocale(languages?: string[]): string;
|
|
19
|
+
declare const api: import("axios").AxiosInstance;
|
|
20
|
+
export default api;
|
|
21
|
+
export declare const API: {
|
|
22
|
+
readonly START_PAYMENT_LINK: (id: string) => string;
|
|
23
|
+
readonly RETRIEVE_SESSION: (id: string) => string;
|
|
24
|
+
readonly SWITCH_CURRENCY: (id: string) => string;
|
|
25
|
+
readonly SUBMIT: (id: string) => string;
|
|
26
|
+
readonly DONATE_SUBMIT: (id: string) => string;
|
|
27
|
+
readonly FAST_CHECKOUT_CONFIRM: (id: string) => string;
|
|
28
|
+
readonly EXCHANGE_RATE: (id: string) => string;
|
|
29
|
+
readonly ADJUST_QUANTITY: (id: string) => string;
|
|
30
|
+
readonly UPSELL: (id: string) => string;
|
|
31
|
+
readonly DOWNSELL: (id: string) => string;
|
|
32
|
+
readonly CROSS_SELL: (id: string) => string;
|
|
33
|
+
readonly CHANGE_AMOUNT: (id: string) => string;
|
|
34
|
+
readonly SLIPPAGE: (id: string) => string;
|
|
35
|
+
readonly ABORT_STRIPE: (id: string) => string;
|
|
36
|
+
readonly RECALCULATE_PROMOTION_SESSION: (id: string) => string;
|
|
37
|
+
readonly APPLY_PROMOTION: (id: string) => string;
|
|
38
|
+
readonly REMOVE_PROMOTION: (id: string) => string;
|
|
39
|
+
readonly CUSTOMER_ME: "/api/customers/me";
|
|
40
|
+
readonly VENDOR_ORDER_STATUS: (id: string) => string;
|
|
41
|
+
};
|
package/es/shared/api.js
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { createAxios } from "@blocklet/js-sdk";
|
|
2
|
+
import isNull from "lodash/isNull";
|
|
3
|
+
const PAYMENT_KIT_DID = "z2qaCNvKMv5GjouKdcDWexv6WqtHbpNPQDnAk";
|
|
4
|
+
export function getPrefix() {
|
|
5
|
+
const prefix = window.blocklet?.prefix || "/";
|
|
6
|
+
const baseUrl = window.location?.origin;
|
|
7
|
+
if (window.__PAYMENT_KIT_BASE_URL) {
|
|
8
|
+
try {
|
|
9
|
+
const tmp = new URL(window.__PAYMENT_KIT_BASE_URL);
|
|
10
|
+
if (tmp.origin !== window.location.origin) {
|
|
11
|
+
return window.__PAYMENT_KIT_BASE_URL;
|
|
12
|
+
}
|
|
13
|
+
} catch {
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const componentId = (window.blocklet?.componentId || "").split("/").pop();
|
|
17
|
+
if (componentId === PAYMENT_KIT_DID) {
|
|
18
|
+
return `${baseUrl}${prefix}`;
|
|
19
|
+
}
|
|
20
|
+
const component = (window.blocklet?.componentMountPoints || []).find((x) => x?.did === PAYMENT_KIT_DID);
|
|
21
|
+
if (component) {
|
|
22
|
+
return `${baseUrl}${component.mountPoint}`;
|
|
23
|
+
}
|
|
24
|
+
return `${baseUrl}${prefix}`;
|
|
25
|
+
}
|
|
26
|
+
export function getLocale(languages) {
|
|
27
|
+
if (typeof window === "undefined") return "en";
|
|
28
|
+
try {
|
|
29
|
+
const stored = localStorage.getItem("locale");
|
|
30
|
+
if (stored) return stored;
|
|
31
|
+
} catch {
|
|
32
|
+
}
|
|
33
|
+
if (languages && languages.length > 0) return languages[0];
|
|
34
|
+
return navigator.language?.split("-")[0] || "en";
|
|
35
|
+
}
|
|
36
|
+
function createApi() {
|
|
37
|
+
const api2 = createAxios();
|
|
38
|
+
api2.interceptors.request.use(
|
|
39
|
+
(config) => {
|
|
40
|
+
const prefix = getPrefix();
|
|
41
|
+
config.baseURL = prefix || "";
|
|
42
|
+
const locale = getLocale(window.blocklet?.languages);
|
|
43
|
+
const query = new URLSearchParams(config.url?.split("?").pop());
|
|
44
|
+
config.params = { ...config.params || {}, locale };
|
|
45
|
+
const authToken = window.__PAYMENT_KIT_AUTH_TOKEN;
|
|
46
|
+
if (authToken && typeof config.params.authToken === "undefined" && !query.has("authToken")) {
|
|
47
|
+
config.params.authToken = authToken;
|
|
48
|
+
}
|
|
49
|
+
if (typeof config.params.livemode === "undefined" && query.has("livemode") === false) {
|
|
50
|
+
const livemode = localStorage.getItem("livemode");
|
|
51
|
+
config.params.livemode = isNull(livemode) ? true : JSON.parse(livemode);
|
|
52
|
+
}
|
|
53
|
+
return config;
|
|
54
|
+
},
|
|
55
|
+
(err) => Promise.reject(err)
|
|
56
|
+
);
|
|
57
|
+
return api2;
|
|
58
|
+
}
|
|
59
|
+
const api = createApi();
|
|
60
|
+
export default api;
|
|
61
|
+
export const API = {
|
|
62
|
+
START_PAYMENT_LINK: (id) => `/api/checkout-sessions/start/${id}`,
|
|
63
|
+
RETRIEVE_SESSION: (id) => `/api/checkout-sessions/retrieve/${id}`,
|
|
64
|
+
SWITCH_CURRENCY: (id) => `/api/checkout-sessions/${id}/switch-currency`,
|
|
65
|
+
SUBMIT: (id) => `/api/checkout-sessions/${id}/submit`,
|
|
66
|
+
DONATE_SUBMIT: (id) => `/api/checkout-sessions/${id}/donate-submit`,
|
|
67
|
+
FAST_CHECKOUT_CONFIRM: (id) => `/api/checkout-sessions/${id}/fast-checkout-confirm`,
|
|
68
|
+
EXCHANGE_RATE: (id) => `/api/checkout-sessions/${id}/exchange-rate`,
|
|
69
|
+
ADJUST_QUANTITY: (id) => `/api/checkout-sessions/${id}/adjust-quantity`,
|
|
70
|
+
UPSELL: (id) => `/api/checkout-sessions/${id}/upsell`,
|
|
71
|
+
DOWNSELL: (id) => `/api/checkout-sessions/${id}/downsell`,
|
|
72
|
+
CROSS_SELL: (id) => `/api/checkout-sessions/${id}/cross-sell`,
|
|
73
|
+
CHANGE_AMOUNT: (id) => `/api/checkout-sessions/${id}/amount`,
|
|
74
|
+
SLIPPAGE: (id) => `/api/checkout-sessions/${id}/slippage`,
|
|
75
|
+
ABORT_STRIPE: (id) => `/api/checkout-sessions/${id}/abort-stripe`,
|
|
76
|
+
RECALCULATE_PROMOTION_SESSION: (id) => `/api/checkout-sessions/${id}/recalculate-promotion`,
|
|
77
|
+
APPLY_PROMOTION: (id) => `/api/checkout-sessions/${id}/apply-promotion`,
|
|
78
|
+
REMOVE_PROMOTION: (id) => `/api/checkout-sessions/${id}/remove-promotion`,
|
|
79
|
+
CUSTOMER_ME: "/api/customers/me",
|
|
80
|
+
VENDOR_ORDER_STATUS: (id) => `/api/vendors/order/${id}/status`
|
|
81
|
+
};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { BN } from '@ocap/util';
|
|
2
|
+
import type { TPaymentCurrency, TPrice, TLineItemExpanded } from '@blocklet/payment-types';
|
|
3
|
+
export declare function formatNumber(n: number | string, precision?: number, trim?: boolean, thousandSeparated?: boolean): string;
|
|
4
|
+
export declare function formatBNStr(str?: string, decimals?: number, precision?: number, trim?: boolean, thousandSeparated?: boolean): string;
|
|
5
|
+
export declare function formatDynamicPrice(n: number | string, isDynamic: boolean, precision?: number, trim?: boolean, thousandSeparated?: boolean): string;
|
|
6
|
+
export declare function getUsdAmountFromTokenUnits(tokenAmount: BN | string, tokenDecimals: number, exchangeRate?: string | null): string | null;
|
|
7
|
+
export declare function formatUsdAmount(amount: string | null, locale?: string): string | null;
|
|
8
|
+
export declare function formatExchangeRate(amount: string | null): string | null;
|
|
9
|
+
export declare function formatExchangeRateDisplay(rate: string | number | null | undefined, currency?: string, decimals?: number): string | null;
|
|
10
|
+
export declare function formatAmount(amount: string, decimals: number, precision?: number): string;
|
|
11
|
+
export declare function getPriceCurrencyOptions(price: TPrice): Array<{
|
|
12
|
+
currency_id: string;
|
|
13
|
+
unit_amount: string;
|
|
14
|
+
custom_unit_amount: {
|
|
15
|
+
preset?: string;
|
|
16
|
+
presets: string[];
|
|
17
|
+
} | null;
|
|
18
|
+
tiers: unknown;
|
|
19
|
+
}>;
|
|
20
|
+
export declare function getPriceUnitAmountByCurrency(price: TPrice, currency: TPaymentCurrency): string;
|
|
21
|
+
export declare function getLineItemAmounts(item: TLineItemExpanded, currency: TPaymentCurrency, { useUpsell, exchangeRate }?: {
|
|
22
|
+
useUpsell?: boolean;
|
|
23
|
+
exchangeRate?: string | null;
|
|
24
|
+
}): {
|
|
25
|
+
unitAmount: BN;
|
|
26
|
+
totalAmount: BN;
|
|
27
|
+
isDynamicQuote: boolean;
|
|
28
|
+
};
|
|
29
|
+
export declare function getCheckoutAmount(items: TLineItemExpanded[], currency: TPaymentCurrency, trialing?: boolean, upsell?: boolean, { exchangeRate }?: {
|
|
30
|
+
exchangeRate?: string | null;
|
|
31
|
+
}): {
|
|
32
|
+
subtotal: string;
|
|
33
|
+
total: string;
|
|
34
|
+
renew: string;
|
|
35
|
+
discount: string;
|
|
36
|
+
shipping: string;
|
|
37
|
+
tax: string;
|
|
38
|
+
};
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { BN, fromUnitToToken, fromTokenToUnit } from "@ocap/util";
|
|
2
|
+
export function formatNumber(n, precision = 6, trim = true, thousandSeparated = true) {
|
|
3
|
+
if (!n || n === "0") {
|
|
4
|
+
return "0";
|
|
5
|
+
}
|
|
6
|
+
const num = Number(n);
|
|
7
|
+
if (!Number.isFinite(num)) {
|
|
8
|
+
return "0";
|
|
9
|
+
}
|
|
10
|
+
let result;
|
|
11
|
+
if (thousandSeparated) {
|
|
12
|
+
result = num.toLocaleString("en-US", {
|
|
13
|
+
minimumFractionDigits: precision,
|
|
14
|
+
maximumFractionDigits: precision
|
|
15
|
+
});
|
|
16
|
+
} else {
|
|
17
|
+
result = num.toFixed(precision);
|
|
18
|
+
}
|
|
19
|
+
if (!trim) {
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
const [left, right] = result.split(".");
|
|
23
|
+
if (!right) return left;
|
|
24
|
+
const trimmed = right.replace(/0+$/, "");
|
|
25
|
+
return trimmed ? `${left}.${trimmed}` : left;
|
|
26
|
+
}
|
|
27
|
+
export function formatBNStr(str = "", decimals = 18, precision = 6, trim = true, thousandSeparated = true) {
|
|
28
|
+
if (!str) {
|
|
29
|
+
return "0";
|
|
30
|
+
}
|
|
31
|
+
return formatNumber(fromUnitToToken(str, decimals), precision, trim, thousandSeparated);
|
|
32
|
+
}
|
|
33
|
+
export function formatDynamicPrice(n, isDynamic, precision = 6, trim = true, thousandSeparated = true) {
|
|
34
|
+
if (!isDynamic) {
|
|
35
|
+
return formatNumber(n, precision, trim, thousandSeparated);
|
|
36
|
+
}
|
|
37
|
+
const num = Number(n);
|
|
38
|
+
if (!Number.isFinite(num)) {
|
|
39
|
+
return formatNumber(n, precision, trim, thousandSeparated);
|
|
40
|
+
}
|
|
41
|
+
const abs = Math.abs(num);
|
|
42
|
+
const targetPrecision = abs > 0 && abs < 0.01 ? precision : 2;
|
|
43
|
+
return formatNumber(n, targetPrecision, trim, thousandSeparated);
|
|
44
|
+
}
|
|
45
|
+
const USD_DECIMALS = 8;
|
|
46
|
+
export function getUsdAmountFromTokenUnits(tokenAmount, tokenDecimals, exchangeRate) {
|
|
47
|
+
if (!exchangeRate && exchangeRate !== "0") {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
if (tokenDecimals === void 0 || tokenDecimals === null) {
|
|
51
|
+
return null;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
const amountBN = tokenAmount instanceof BN ? tokenAmount : new BN(tokenAmount || "0");
|
|
55
|
+
const tokenScale = new BN(10).pow(new BN(tokenDecimals));
|
|
56
|
+
if (tokenScale.isZero()) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
const rateBN = new BN(exchangeRate.replace(".", ""));
|
|
60
|
+
const rateDecimalPlaces = exchangeRate.includes(".") ? exchangeRate.split(".")[1]?.length || 0 : 0;
|
|
61
|
+
const rateScale = new BN(10).pow(new BN(rateDecimalPlaces));
|
|
62
|
+
const usdPrecisionScale = new BN(10).pow(new BN(USD_DECIMALS));
|
|
63
|
+
const usdUnit = amountBN.mul(rateBN).mul(usdPrecisionScale).div(tokenScale.mul(rateScale));
|
|
64
|
+
return fromUnitToToken(usdUnit.toString(), USD_DECIMALS);
|
|
65
|
+
} catch {
|
|
66
|
+
return null;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export function formatUsdAmount(amount, locale = "en") {
|
|
70
|
+
if (!amount && amount !== "0") {
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
const num = Number(amount);
|
|
74
|
+
if (!Number.isFinite(num)) {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
return new Intl.NumberFormat(locale, {
|
|
78
|
+
minimumFractionDigits: 2,
|
|
79
|
+
maximumFractionDigits: 2
|
|
80
|
+
}).format(num);
|
|
81
|
+
}
|
|
82
|
+
export function formatExchangeRate(amount) {
|
|
83
|
+
if (!amount && amount !== "0") {
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
const value = String(amount);
|
|
87
|
+
const num = Number(value);
|
|
88
|
+
if (!Number.isFinite(num)) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
return value;
|
|
92
|
+
}
|
|
93
|
+
export function formatExchangeRateDisplay(rate, currency = "USD", decimals = 2) {
|
|
94
|
+
if (rate === null || rate === void 0) {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
const num = Number(rate);
|
|
98
|
+
if (!Number.isFinite(num)) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
const formattedValue = num.toFixed(decimals);
|
|
102
|
+
if (currency === "USD") {
|
|
103
|
+
return `$${formattedValue}`;
|
|
104
|
+
}
|
|
105
|
+
return `${formattedValue} ${currency}`;
|
|
106
|
+
}
|
|
107
|
+
export function formatAmount(amount, decimals, precision = 2) {
|
|
108
|
+
const tokenAmount = fromUnitToToken(amount, decimals);
|
|
109
|
+
const numericValue = Number(tokenAmount);
|
|
110
|
+
if (!Number.isFinite(numericValue)) {
|
|
111
|
+
return formatBNStr(amount, decimals, precision, true, false);
|
|
112
|
+
}
|
|
113
|
+
const abs = Math.abs(numericValue);
|
|
114
|
+
const targetPrecision = abs > 0 && abs < 0.01 ? decimals : 2;
|
|
115
|
+
return formatNumber(tokenAmount, targetPrecision, true, false);
|
|
116
|
+
}
|
|
117
|
+
export function getPriceCurrencyOptions(price) {
|
|
118
|
+
if (Array.isArray(price.currency_options)) {
|
|
119
|
+
return price.currency_options;
|
|
120
|
+
}
|
|
121
|
+
return [
|
|
122
|
+
{
|
|
123
|
+
currency_id: price.currency_id,
|
|
124
|
+
unit_amount: price.unit_amount,
|
|
125
|
+
custom_unit_amount: price.custom_unit_amount || null,
|
|
126
|
+
tiers: null
|
|
127
|
+
}
|
|
128
|
+
];
|
|
129
|
+
}
|
|
130
|
+
export function getPriceUnitAmountByCurrency(price, currency) {
|
|
131
|
+
const options = getPriceCurrencyOptions(price);
|
|
132
|
+
const option = options.find((x) => x.currency_id === currency?.id);
|
|
133
|
+
if (option) {
|
|
134
|
+
if (option.custom_unit_amount) {
|
|
135
|
+
return option.custom_unit_amount.preset || option.custom_unit_amount.presets[0];
|
|
136
|
+
}
|
|
137
|
+
return option.unit_amount;
|
|
138
|
+
}
|
|
139
|
+
if (price.currency_id === currency?.id) {
|
|
140
|
+
if (price.custom_unit_amount) {
|
|
141
|
+
return price.custom_unit_amount.preset || price.custom_unit_amount.presets[0];
|
|
142
|
+
}
|
|
143
|
+
return price.unit_amount;
|
|
144
|
+
}
|
|
145
|
+
return "0";
|
|
146
|
+
}
|
|
147
|
+
export function getLineItemAmounts(item, currency, { useUpsell = true, exchangeRate = null } = {}) {
|
|
148
|
+
if (!currency) {
|
|
149
|
+
return { unitAmount: new BN(0), totalAmount: new BN(0), isDynamicQuote: false };
|
|
150
|
+
}
|
|
151
|
+
const price = useUpsell ? item.upsell_price || item.price : item.price;
|
|
152
|
+
const quantity = new BN(item.quantity || 0);
|
|
153
|
+
const quoteAmount = item.quoted_amount;
|
|
154
|
+
const quoteCurrencyId = item.quote_currency_id;
|
|
155
|
+
const isDynamicPrice = price?.pricing_type === "dynamic";
|
|
156
|
+
const isQuoteValidForCurrency = isDynamicPrice && quoteAmount && quoteCurrencyId === currency.id;
|
|
157
|
+
if (isQuoteValidForCurrency) {
|
|
158
|
+
const totalAmount = new BN(quoteAmount || "0");
|
|
159
|
+
const unitAmount2 = quantity.gt(new BN(0)) ? totalAmount.add(quantity).sub(new BN(1)).div(quantity) : new BN(0);
|
|
160
|
+
return { unitAmount: unitAmount2, totalAmount, isDynamicQuote: true };
|
|
161
|
+
}
|
|
162
|
+
if (isDynamicPrice && exchangeRate && price?.base_amount) {
|
|
163
|
+
const rate = Number(exchangeRate);
|
|
164
|
+
if (rate > 0 && Number.isFinite(rate)) {
|
|
165
|
+
const baseAmountUsd = Number(price.base_amount);
|
|
166
|
+
if (baseAmountUsd > 0 && Number.isFinite(baseAmountUsd)) {
|
|
167
|
+
const tokenAmount = baseAmountUsd / rate;
|
|
168
|
+
const unitAmount2 = fromTokenToUnit(tokenAmount.toFixed(currency.decimal || 8), currency.decimal || 8);
|
|
169
|
+
return {
|
|
170
|
+
unitAmount: unitAmount2,
|
|
171
|
+
totalAmount: unitAmount2.mul(quantity),
|
|
172
|
+
isDynamicQuote: false
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (!exchangeRate && price?.base_amount != null) {
|
|
178
|
+
const baseAmountUsd = Number(price.base_amount);
|
|
179
|
+
if (baseAmountUsd >= 0 && Number.isFinite(baseAmountUsd)) {
|
|
180
|
+
const dec = currency.decimal || 2;
|
|
181
|
+
const unitAmountBN = fromTokenToUnit(baseAmountUsd.toFixed(dec), dec);
|
|
182
|
+
return {
|
|
183
|
+
unitAmount: unitAmountBN,
|
|
184
|
+
totalAmount: unitAmountBN.mul(quantity),
|
|
185
|
+
isDynamicQuote: false
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
const unitAmount = new BN(getPriceUnitAmountByCurrency(price, currency));
|
|
190
|
+
return {
|
|
191
|
+
unitAmount,
|
|
192
|
+
totalAmount: unitAmount.mul(quantity),
|
|
193
|
+
isDynamicQuote: false
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
export function getCheckoutAmount(items, currency, trialing = false, upsell = true, { exchangeRate = null } = {}) {
|
|
197
|
+
let renew = new BN(0);
|
|
198
|
+
const total = items.filter((x) => {
|
|
199
|
+
const price = upsell ? x.upsell_price || x.price : x.price;
|
|
200
|
+
return price != null;
|
|
201
|
+
}).reduce((acc, x) => {
|
|
202
|
+
const quoteCurrencyId = x.quote_currency_id;
|
|
203
|
+
let totalAmount;
|
|
204
|
+
if (x.custom_amount && quoteCurrencyId && quoteCurrencyId === currency.id) {
|
|
205
|
+
totalAmount = new BN(x.custom_amount);
|
|
206
|
+
} else {
|
|
207
|
+
({ totalAmount } = getLineItemAmounts(x, currency, { useUpsell: upsell, exchangeRate }));
|
|
208
|
+
}
|
|
209
|
+
const price = upsell ? x.upsell_price || x.price : x.price;
|
|
210
|
+
if (price?.type === "recurring") {
|
|
211
|
+
renew = renew.add(totalAmount);
|
|
212
|
+
if (trialing) {
|
|
213
|
+
return acc;
|
|
214
|
+
}
|
|
215
|
+
if (price.recurring?.usage_type === "metered") {
|
|
216
|
+
return acc;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return acc.add(totalAmount);
|
|
220
|
+
}, new BN(0)).toString();
|
|
221
|
+
return {
|
|
222
|
+
subtotal: total,
|
|
223
|
+
total,
|
|
224
|
+
renew: formatDynamicPrice(renew.toString(), !!exchangeRate),
|
|
225
|
+
discount: "0",
|
|
226
|
+
shipping: "0",
|
|
227
|
+
tax: "0"
|
|
228
|
+
};
|
|
229
|
+
}
|