@blocklet/payment-react 1.24.3 → 1.25.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/es/components/auto-topup/modal.d.ts +2 -0
- package/es/components/auto-topup/modal.js +48 -6
- package/es/components/auto-topup/product-card.d.ts +16 -1
- package/es/components/auto-topup/product-card.js +97 -15
- package/es/components/dynamic-pricing-unavailable.d.ts +9 -0
- package/es/components/dynamic-pricing-unavailable.js +58 -0
- package/es/components/loading-amount.d.ts +17 -0
- package/es/components/loading-amount.js +46 -0
- package/es/components/price-change-confirm.d.ts +18 -0
- package/es/components/price-change-confirm.js +107 -0
- package/es/components/quote-details-panel.d.ts +21 -0
- package/es/components/quote-details-panel.js +170 -0
- package/es/components/quote-lock-banner.d.ts +7 -0
- package/es/components/quote-lock-banner.js +79 -0
- package/es/components/slippage-config.d.ts +20 -0
- package/es/components/slippage-config.js +261 -0
- package/es/history/credit/transactions-list.js +11 -1
- package/es/history/invoice/list.js +125 -15
- package/es/hooks/dynamic-pricing.d.ts +102 -0
- package/es/hooks/dynamic-pricing.js +393 -0
- package/es/index.d.ts +6 -1
- package/es/index.js +9 -1
- package/es/libs/util.d.ts +42 -5
- package/es/libs/util.js +345 -57
- package/es/locales/en.js +114 -3
- package/es/locales/zh.js +114 -3
- package/es/payment/form/index.d.ts +4 -1
- package/es/payment/form/index.js +454 -22
- package/es/payment/index.d.ts +1 -1
- package/es/payment/index.js +279 -16
- package/es/payment/product-item.d.ts +26 -1
- package/es/payment/product-item.js +330 -51
- package/es/payment/summary-section/promotion-section.d.ts +32 -0
- package/es/payment/summary-section/promotion-section.js +143 -0
- package/es/payment/summary-section/total-section.d.ts +39 -0
- package/es/payment/summary-section/total-section.js +83 -0
- package/es/payment/summary.d.ts +17 -2
- package/es/payment/summary.js +300 -253
- package/es/types/index.d.ts +11 -0
- package/lib/components/auto-topup/modal.d.ts +2 -0
- package/lib/components/auto-topup/modal.js +54 -6
- package/lib/components/auto-topup/product-card.d.ts +16 -1
- package/lib/components/auto-topup/product-card.js +75 -7
- package/lib/components/dynamic-pricing-unavailable.d.ts +9 -0
- package/lib/components/dynamic-pricing-unavailable.js +81 -0
- package/lib/components/loading-amount.d.ts +17 -0
- package/lib/components/loading-amount.js +53 -0
- package/lib/components/price-change-confirm.d.ts +18 -0
- package/lib/components/price-change-confirm.js +157 -0
- package/lib/components/quote-details-panel.d.ts +21 -0
- package/lib/components/quote-details-panel.js +226 -0
- package/lib/components/quote-lock-banner.d.ts +7 -0
- package/lib/components/quote-lock-banner.js +93 -0
- package/lib/components/slippage-config.d.ts +20 -0
- package/lib/components/slippage-config.js +316 -0
- package/lib/history/credit/transactions-list.js +11 -1
- package/lib/history/invoice/list.js +167 -27
- package/lib/hooks/dynamic-pricing.d.ts +102 -0
- package/lib/hooks/dynamic-pricing.js +390 -0
- package/lib/index.d.ts +6 -1
- package/lib/index.js +32 -0
- package/lib/libs/util.d.ts +42 -5
- package/lib/libs/util.js +367 -49
- package/lib/locales/en.js +114 -3
- package/lib/locales/zh.js +114 -3
- package/lib/payment/form/index.d.ts +4 -1
- package/lib/payment/form/index.js +476 -20
- package/lib/payment/index.d.ts +1 -1
- package/lib/payment/index.js +308 -14
- package/lib/payment/product-item.d.ts +26 -1
- package/lib/payment/product-item.js +270 -35
- package/lib/payment/summary-section/promotion-section.d.ts +32 -0
- package/lib/payment/summary-section/promotion-section.js +133 -0
- package/lib/payment/summary-section/total-section.d.ts +39 -0
- package/lib/payment/summary-section/total-section.js +117 -0
- package/lib/payment/summary.d.ts +17 -2
- package/lib/payment/summary.js +205 -127
- package/lib/types/index.d.ts +11 -0
- package/package.json +3 -3
- package/src/components/auto-topup/modal.tsx +59 -6
- package/src/components/auto-topup/product-card.tsx +118 -11
- package/src/components/dynamic-pricing-unavailable.tsx +69 -0
- package/src/components/loading-amount.tsx +66 -0
- package/src/components/price-change-confirm.tsx +136 -0
- package/src/components/quote-details-panel.tsx +218 -0
- package/src/components/quote-lock-banner.tsx +99 -0
- package/src/components/slippage-config.tsx +336 -0
- package/src/history/credit/transactions-list.tsx +14 -1
- package/src/history/invoice/list.tsx +143 -9
- package/src/hooks/dynamic-pricing.ts +617 -0
- package/src/index.ts +9 -0
- package/src/libs/util.ts +473 -58
- package/src/locales/en.tsx +117 -0
- package/src/locales/zh.tsx +111 -0
- package/src/payment/form/index.tsx +561 -19
- package/src/payment/index.tsx +349 -10
- package/src/payment/product-item.tsx +451 -37
- package/src/payment/summary-section/promotion-section.tsx +172 -0
- package/src/payment/summary-section/total-section.tsx +141 -0
- package/src/payment/summary.tsx +334 -192
- package/src/types/index.ts +15 -0
package/es/payment/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { Box, Fade, Stack } from "@mui/material";
|
|
|
7
7
|
import { styled } from "@mui/system";
|
|
8
8
|
import { fromTokenToUnit } from "@ocap/util";
|
|
9
9
|
import { useSetState } from "ahooks";
|
|
10
|
-
import { useEffect,
|
|
10
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
11
11
|
import { FormProvider, useForm, useWatch } from "react-hook-form";
|
|
12
12
|
import trim from "lodash/trim";
|
|
13
13
|
import { usePaymentContext } from "../contexts/payment.js";
|
|
@@ -43,12 +43,28 @@ function PaymentInner({
|
|
|
43
43
|
onError,
|
|
44
44
|
onChange,
|
|
45
45
|
action,
|
|
46
|
-
showCheckoutSummary = true
|
|
46
|
+
showCheckoutSummary = true,
|
|
47
|
+
quotes,
|
|
48
|
+
rateUnavailable,
|
|
49
|
+
rateError
|
|
47
50
|
}) {
|
|
48
51
|
const { t } = useLocaleContext();
|
|
49
52
|
const { settings, session } = usePaymentContext();
|
|
50
53
|
const { isMobile } = useMobile();
|
|
51
|
-
const [state, setState] = useSetState({
|
|
54
|
+
const [state, setState] = useSetState({
|
|
55
|
+
checkoutSession,
|
|
56
|
+
quotes,
|
|
57
|
+
rateUnavailable,
|
|
58
|
+
rateError,
|
|
59
|
+
paymentIntent,
|
|
60
|
+
liveRateInfo: void 0,
|
|
61
|
+
liveQuoteSnapshot: void 0,
|
|
62
|
+
liveRateUnavailable: false,
|
|
63
|
+
liveRateError: void 0,
|
|
64
|
+
isRateLoading: false
|
|
65
|
+
});
|
|
66
|
+
const isCurrencySwitchRef = useRef(false);
|
|
67
|
+
const prevCurrencyIdRef = useRef(null);
|
|
52
68
|
const query = getQueryParams(window.location.href);
|
|
53
69
|
const availableCurrencyIds = useMemo(() => {
|
|
54
70
|
const currencyIds = /* @__PURE__ */ new Set();
|
|
@@ -135,13 +151,185 @@ function PaymentInner({
|
|
|
135
151
|
const currencyId = useWatch({ control: methods.control, name: "payment_currency", defaultValue: defaultCurrencyId });
|
|
136
152
|
const currency = findCurrency(paymentMethods, currencyId) || settings.baseCurrency;
|
|
137
153
|
const method = paymentMethods.find((x) => x.id === currency.payment_method_id);
|
|
138
|
-
const
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
154
|
+
const hasDynamicPricing = useMemo(
|
|
155
|
+
() => state.checkoutSession.line_items.some(
|
|
156
|
+
(item) => (item.upsell_price || item.price)?.pricing_type === "dynamic"
|
|
157
|
+
),
|
|
158
|
+
[state.checkoutSession.line_items]
|
|
159
|
+
);
|
|
160
|
+
const isStripePayment = method?.type === "stripe";
|
|
161
|
+
const needsExchangeRate = hasDynamicPricing && !isStripePayment;
|
|
162
|
+
const effectiveRateUnavailable = needsExchangeRate && (state.rateUnavailable || state.liveRateUnavailable);
|
|
163
|
+
if (state.liveRateError || state.rateError) {
|
|
164
|
+
console.error("[Rate Error]", { liveRateError: state.liveRateError, rateError: state.rateError });
|
|
165
|
+
}
|
|
166
|
+
const refreshRateRef = useRef(null);
|
|
167
|
+
useEffect(() => {
|
|
168
|
+
if (!currencyId) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
const isCurrencySwitch = prevCurrencyIdRef.current !== null && prevCurrencyIdRef.current !== currencyId;
|
|
172
|
+
prevCurrencyIdRef.current = currencyId;
|
|
173
|
+
if (isCurrencySwitch) {
|
|
174
|
+
isCurrencySwitchRef.current = true;
|
|
175
|
+
setState({ isRateLoading: true });
|
|
176
|
+
}
|
|
177
|
+
if (needsExchangeRate) {
|
|
178
|
+
setState({
|
|
179
|
+
liveRateInfo: void 0,
|
|
180
|
+
liveQuoteSnapshot: void 0,
|
|
181
|
+
liveRateUnavailable: false,
|
|
182
|
+
liveRateError: void 0
|
|
144
183
|
});
|
|
184
|
+
liveRateRefreshRef.current = false;
|
|
185
|
+
refreshRateRef.current?.();
|
|
186
|
+
} else {
|
|
187
|
+
setState({
|
|
188
|
+
liveRateInfo: void 0,
|
|
189
|
+
liveQuoteSnapshot: void 0,
|
|
190
|
+
liveRateUnavailable: false,
|
|
191
|
+
liveRateError: void 0
|
|
192
|
+
});
|
|
193
|
+
liveRateRefreshRef.current = false;
|
|
194
|
+
if (isCurrencySwitch && !state.checkoutSession?.discounts?.length) {
|
|
195
|
+
setState({ isRateLoading: false });
|
|
196
|
+
isCurrencySwitchRef.current = false;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}, [currencyId, needsExchangeRate]);
|
|
200
|
+
useEffect(() => {
|
|
201
|
+
if (!state.checkoutSession?.id || completed || !needsExchangeRate) {
|
|
202
|
+
return void 0;
|
|
203
|
+
}
|
|
204
|
+
let cancelled = false;
|
|
205
|
+
let consecutiveFailures = 0;
|
|
206
|
+
const baseInterval = 3e4;
|
|
207
|
+
const MAX_INTERVAL = 5 * 60 * 1e3;
|
|
208
|
+
const QUICK_RETRY_DELAY = 1e3;
|
|
209
|
+
const MAX_QUICK_RETRIES = 2;
|
|
210
|
+
let currentInterval = baseInterval;
|
|
211
|
+
let timer = null;
|
|
212
|
+
const scheduleNext = () => {
|
|
213
|
+
if (timer) {
|
|
214
|
+
clearInterval(timer);
|
|
215
|
+
}
|
|
216
|
+
timer = window.setInterval(() => {
|
|
217
|
+
fetchRate(false);
|
|
218
|
+
}, currentInterval);
|
|
219
|
+
};
|
|
220
|
+
const fetchRate = async (isManualRetry = false) => {
|
|
221
|
+
if (document.hidden && !isManualRetry) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (typeof navigator !== "undefined" && !navigator.onLine) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
if (liveRateRefreshRef.current) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
liveRateRefreshRef.current = true;
|
|
231
|
+
let quickRetryCount = 0;
|
|
232
|
+
let lastError = null;
|
|
233
|
+
try {
|
|
234
|
+
while (quickRetryCount <= MAX_QUICK_RETRIES) {
|
|
235
|
+
try {
|
|
236
|
+
const { data } = await api.get(`/api/checkout-sessions/${state.checkoutSession.id}/exchange-rate`, {
|
|
237
|
+
params: currencyId ? { currency_id: currencyId } : void 0
|
|
238
|
+
});
|
|
239
|
+
if (cancelled) {
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
consecutiveFailures = 0;
|
|
243
|
+
currentInterval = baseInterval;
|
|
244
|
+
setState({
|
|
245
|
+
liveRateInfo: data,
|
|
246
|
+
liveQuoteSnapshot: void 0,
|
|
247
|
+
// Quote is created at submit time only
|
|
248
|
+
liveRateUnavailable: false,
|
|
249
|
+
liveRateError: void 0
|
|
250
|
+
});
|
|
251
|
+
if (isCurrencySwitchRef.current && !state.checkoutSession?.discounts?.length) {
|
|
252
|
+
setState({ isRateLoading: false });
|
|
253
|
+
isCurrencySwitchRef.current = false;
|
|
254
|
+
}
|
|
255
|
+
scheduleNext();
|
|
256
|
+
return;
|
|
257
|
+
} catch (err) {
|
|
258
|
+
lastError = err;
|
|
259
|
+
quickRetryCount++;
|
|
260
|
+
if (quickRetryCount <= MAX_QUICK_RETRIES && !cancelled) {
|
|
261
|
+
console.log(
|
|
262
|
+
`[Exchange Rate] Quick retry ${quickRetryCount}/${MAX_QUICK_RETRIES} after ${QUICK_RETRY_DELAY}ms`
|
|
263
|
+
);
|
|
264
|
+
await new Promise((resolve) => {
|
|
265
|
+
setTimeout(resolve, QUICK_RETRY_DELAY);
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
if (cancelled) {
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
consecutiveFailures++;
|
|
274
|
+
const technicalError = lastError?.response?.data?.error || formatError(lastError);
|
|
275
|
+
console.error("[Exchange Rate Fetch Error]", {
|
|
276
|
+
error: technicalError,
|
|
277
|
+
consecutiveFailures,
|
|
278
|
+
sessionId: state.checkoutSession?.id,
|
|
279
|
+
currencyId
|
|
280
|
+
});
|
|
281
|
+
setState({
|
|
282
|
+
liveRateUnavailable: true,
|
|
283
|
+
liveRateError: void 0
|
|
284
|
+
});
|
|
285
|
+
if (consecutiveFailures >= 3) {
|
|
286
|
+
console.warn("Exchange rate fetch failed multiple times", { consecutiveFailures, technicalError });
|
|
287
|
+
}
|
|
288
|
+
const nextInterval = Math.min(baseInterval * 2 ** (consecutiveFailures - 1), MAX_INTERVAL);
|
|
289
|
+
currentInterval = nextInterval;
|
|
290
|
+
scheduleNext();
|
|
291
|
+
} finally {
|
|
292
|
+
liveRateRefreshRef.current = false;
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
refreshRateRef.current = async () => {
|
|
296
|
+
liveRateRefreshRef.current = false;
|
|
297
|
+
await fetchRate(true);
|
|
298
|
+
};
|
|
299
|
+
fetchRate(false);
|
|
300
|
+
const handleVisibilityChange = () => {
|
|
301
|
+
if (!document.hidden) {
|
|
302
|
+
fetchRate(false);
|
|
303
|
+
}
|
|
304
|
+
};
|
|
305
|
+
document.addEventListener("visibilitychange", handleVisibilityChange);
|
|
306
|
+
return () => {
|
|
307
|
+
cancelled = true;
|
|
308
|
+
refreshRateRef.current = null;
|
|
309
|
+
if (timer) {
|
|
310
|
+
clearInterval(timer);
|
|
311
|
+
}
|
|
312
|
+
document.removeEventListener("visibilitychange", handleVisibilityChange);
|
|
313
|
+
};
|
|
314
|
+
}, [state.checkoutSession?.id, currencyId, completed, needsExchangeRate]);
|
|
315
|
+
const recalculatePromotion = async () => {
|
|
316
|
+
if (state.checkoutSession?.discounts?.length) {
|
|
317
|
+
try {
|
|
318
|
+
await api.post(`/api/checkout-sessions/${state.checkoutSession.id}/recalculate-promotion`, {
|
|
319
|
+
currency_id: currencyId
|
|
320
|
+
});
|
|
321
|
+
await onPromotionUpdate();
|
|
322
|
+
} catch (err) {
|
|
323
|
+
console.error("[recalculatePromotion] Error:", err);
|
|
324
|
+
} finally {
|
|
325
|
+
if (isCurrencySwitchRef.current) {
|
|
326
|
+
setState({ isRateLoading: false });
|
|
327
|
+
isCurrencySwitchRef.current = false;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
} else if (isCurrencySwitchRef.current) {
|
|
331
|
+
setState({ isRateLoading: false });
|
|
332
|
+
isCurrencySwitchRef.current = false;
|
|
145
333
|
}
|
|
146
334
|
};
|
|
147
335
|
useEffect(() => {
|
|
@@ -193,13 +381,19 @@ function PaymentInner({
|
|
|
193
381
|
try {
|
|
194
382
|
const { data } = await api.put(`/api/checkout-sessions/${state.checkoutSession.id}/adjust-quantity`, {
|
|
195
383
|
itemId,
|
|
196
|
-
quantity
|
|
384
|
+
quantity,
|
|
385
|
+
currency_id: currencyId
|
|
197
386
|
});
|
|
198
387
|
if (data.discounts?.length) {
|
|
199
388
|
recalculatePromotion();
|
|
200
389
|
return;
|
|
201
390
|
}
|
|
202
|
-
setState({
|
|
391
|
+
setState({
|
|
392
|
+
checkoutSession: data,
|
|
393
|
+
...data.rateUnavailable !== void 0 && { rateUnavailable: data.rateUnavailable },
|
|
394
|
+
...data.rateError !== void 0 && { rateError: data.rateError },
|
|
395
|
+
...data.quotes !== void 0 && { quotes: data.quotes }
|
|
396
|
+
});
|
|
203
397
|
} catch (err) {
|
|
204
398
|
console.error(err);
|
|
205
399
|
Toast.error(formatError(err));
|
|
@@ -247,6 +441,43 @@ function PaymentInner({
|
|
|
247
441
|
setState({ checkoutSession: result.checkoutSession });
|
|
248
442
|
onPaid(result);
|
|
249
443
|
};
|
|
444
|
+
const handleQuoteUpdated = (payload) => {
|
|
445
|
+
setState({
|
|
446
|
+
checkoutSession: payload.checkoutSession,
|
|
447
|
+
...payload.quotes !== void 0 && { quotes: payload.quotes },
|
|
448
|
+
...payload.rateUnavailable !== void 0 && { rateUnavailable: payload.rateUnavailable },
|
|
449
|
+
...payload.rateError !== void 0 && { rateError: payload.rateError },
|
|
450
|
+
...payload.paymentIntent !== void 0 && { paymentIntent: payload.paymentIntent }
|
|
451
|
+
});
|
|
452
|
+
};
|
|
453
|
+
const handlePaymentIntentUpdate = (intent) => {
|
|
454
|
+
setState({ paymentIntent: intent });
|
|
455
|
+
};
|
|
456
|
+
const quoteRefreshRef = useRef(false);
|
|
457
|
+
const liveRateRefreshRef = useRef(false);
|
|
458
|
+
const handleQuoteExpired = async (forceRefresh = false) => {
|
|
459
|
+
if (quoteRefreshRef.current) {
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
quoteRefreshRef.current = true;
|
|
463
|
+
try {
|
|
464
|
+
const { data } = await api.get(`/api/checkout-sessions/retrieve/${state.checkoutSession.id}`, {
|
|
465
|
+
params: forceRefresh ? { forceRefresh: "1" } : void 0
|
|
466
|
+
});
|
|
467
|
+
handleQuoteUpdated({
|
|
468
|
+
checkoutSession: data.checkoutSession,
|
|
469
|
+
quotes: data.quotes,
|
|
470
|
+
rateUnavailable: data.rateUnavailable,
|
|
471
|
+
rateError: data.rateError,
|
|
472
|
+
paymentIntent: data.paymentIntent
|
|
473
|
+
});
|
|
474
|
+
} catch (err) {
|
|
475
|
+
console.error(err);
|
|
476
|
+
Toast.error(formatError(err));
|
|
477
|
+
} finally {
|
|
478
|
+
quoteRefreshRef.current = false;
|
|
479
|
+
}
|
|
480
|
+
};
|
|
250
481
|
let trialInDays = Number(state.checkoutSession?.subscription_data?.trial_period_days || 0);
|
|
251
482
|
let trialEnd = Number(state.checkoutSession?.subscription_data?.trial_end || 0);
|
|
252
483
|
const trialCurrencyIds = (state.checkoutSession?.subscription_data?.trial_currency || "").split(",").map(trim).filter(Boolean);
|
|
@@ -270,6 +501,7 @@ function PaymentInner({
|
|
|
270
501
|
),
|
|
271
502
|
showStaking: showStaking(method, currency, !!state.checkoutSession.subscription_data?.no_stake),
|
|
272
503
|
currency,
|
|
504
|
+
paymentIntent: state.paymentIntent || paymentIntent,
|
|
273
505
|
onUpsell,
|
|
274
506
|
onDownsell,
|
|
275
507
|
onQuantityChange,
|
|
@@ -284,7 +516,29 @@ function PaymentInner({
|
|
|
284
516
|
checkoutSession: state.checkoutSession,
|
|
285
517
|
onPromotionUpdate,
|
|
286
518
|
paymentMethods,
|
|
287
|
-
showFeatures
|
|
519
|
+
showFeatures,
|
|
520
|
+
rateUnavailable: effectiveRateUnavailable,
|
|
521
|
+
isRateLoading: state.isRateLoading,
|
|
522
|
+
liveRate: state.liveRateInfo,
|
|
523
|
+
liveQuoteSnapshot: state.liveQuoteSnapshot,
|
|
524
|
+
onQuoteExpired: handleQuoteExpired,
|
|
525
|
+
onRefreshRate: refreshRateRef.current || void 0,
|
|
526
|
+
isStripePayment,
|
|
527
|
+
onSlippageChange: async (slippageConfig) => {
|
|
528
|
+
try {
|
|
529
|
+
const { data } = await api.put(`/api/checkout-sessions/${state.checkoutSession.id}/slippage`, {
|
|
530
|
+
slippage_config: slippageConfig
|
|
531
|
+
});
|
|
532
|
+
handleQuoteUpdated({
|
|
533
|
+
checkoutSession: data.checkoutSession || state.checkoutSession,
|
|
534
|
+
quotes: data.quotes,
|
|
535
|
+
rateUnavailable: data.rateUnavailable,
|
|
536
|
+
rateError: data.rateError
|
|
537
|
+
});
|
|
538
|
+
} catch (err) {
|
|
539
|
+
console.error("Failed to update slippage", err);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
288
542
|
}
|
|
289
543
|
),
|
|
290
544
|
mode === "standalone" && !isMobile && /* @__PURE__ */ jsx(CheckoutFooter, { className: "cko-footer", sx: { color: "text.lighter" } })
|
|
@@ -324,13 +578,16 @@ function PaymentInner({
|
|
|
324
578
|
currencyId,
|
|
325
579
|
checkoutSession: state.checkoutSession,
|
|
326
580
|
paymentMethods,
|
|
327
|
-
paymentIntent,
|
|
581
|
+
paymentIntent: state.paymentIntent || paymentIntent,
|
|
328
582
|
paymentLink,
|
|
329
583
|
customer,
|
|
330
584
|
onPaid: handlePaid,
|
|
331
585
|
onError,
|
|
586
|
+
onQuoteUpdated: handleQuoteUpdated,
|
|
587
|
+
onPaymentIntentUpdate: handlePaymentIntentUpdate,
|
|
332
588
|
mode,
|
|
333
|
-
action
|
|
589
|
+
action,
|
|
590
|
+
rateUnavailable: effectiveRateUnavailable
|
|
334
591
|
}
|
|
335
592
|
)
|
|
336
593
|
]
|
|
@@ -353,7 +610,10 @@ export default function Payment({
|
|
|
353
610
|
onChange,
|
|
354
611
|
goBack,
|
|
355
612
|
action,
|
|
356
|
-
showCheckoutSummary = true
|
|
613
|
+
showCheckoutSummary = true,
|
|
614
|
+
quotes,
|
|
615
|
+
rateUnavailable,
|
|
616
|
+
rateError
|
|
357
617
|
}) {
|
|
358
618
|
const { t } = useLocaleContext();
|
|
359
619
|
const { refresh, livemode, setLivemode } = usePaymentContext();
|
|
@@ -418,7 +678,10 @@ export default function Payment({
|
|
|
418
678
|
goBack,
|
|
419
679
|
mode,
|
|
420
680
|
action,
|
|
421
|
-
showCheckoutSummary
|
|
681
|
+
showCheckoutSummary,
|
|
682
|
+
quotes,
|
|
683
|
+
rateUnavailable,
|
|
684
|
+
rateError
|
|
422
685
|
}
|
|
423
686
|
);
|
|
424
687
|
};
|
|
@@ -1,5 +1,24 @@
|
|
|
1
1
|
import type { TLineItemExpanded, TPaymentCurrency } from '@blocklet/payment-types';
|
|
2
2
|
import React from 'react';
|
|
3
|
+
interface DiscountInfo {
|
|
4
|
+
promotion_code?: string;
|
|
5
|
+
coupon?: string;
|
|
6
|
+
discount_amount?: string;
|
|
7
|
+
promotion_code_details?: {
|
|
8
|
+
code?: string;
|
|
9
|
+
};
|
|
10
|
+
coupon_details?: {
|
|
11
|
+
percent_off?: number;
|
|
12
|
+
amount_off?: string;
|
|
13
|
+
currency_id?: string;
|
|
14
|
+
currency_options?: Record<string, {
|
|
15
|
+
amount_off?: string;
|
|
16
|
+
}>;
|
|
17
|
+
};
|
|
18
|
+
verification_data?: {
|
|
19
|
+
code?: string;
|
|
20
|
+
};
|
|
21
|
+
}
|
|
3
22
|
type Props = {
|
|
4
23
|
item: TLineItemExpanded;
|
|
5
24
|
items: TLineItemExpanded[];
|
|
@@ -18,6 +37,12 @@ type Props = {
|
|
|
18
37
|
onQuantityChange?: (itemId: string, quantity: number) => void;
|
|
19
38
|
completed?: boolean;
|
|
20
39
|
showFeatures?: boolean;
|
|
40
|
+
exchangeRate?: string | null;
|
|
41
|
+
isStripePayment?: boolean;
|
|
42
|
+
isPriceLocked?: boolean;
|
|
43
|
+
isRateLoading?: boolean;
|
|
44
|
+
discounts?: DiscountInfo[];
|
|
45
|
+
calculatedDiscountAmount?: string | null;
|
|
21
46
|
};
|
|
22
|
-
export default function ProductItem({ item, items, trialInDays, trialEnd, currency, mode, children, onUpsell, onDownsell, completed, adjustableQuantity, onQuantityChange, showFeatures, }: Props): JSX.Element;
|
|
47
|
+
export default function ProductItem({ item, items, trialInDays, trialEnd, currency, mode, children, onUpsell, onDownsell, completed, adjustableQuantity, onQuantityChange, showFeatures, exchangeRate, isStripePayment, isPriceLocked, isRateLoading, discounts, calculatedDiscountAmount, }: Props): JSX.Element;
|
|
23
48
|
export {};
|