@blocklet/payment-react 1.26.2 → 1.26.3
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/checkout-v2/components/dialogs/checkout-dialogs.js +2 -0
- package/es/checkout-v2/components/left/promotion-input.d.ts +2 -1
- package/es/checkout-v2/components/left/promotion-input.js +4 -11
- package/es/checkout-v2/components/right/customer-info-card.d.ts +2 -0
- package/es/checkout-v2/components/right/customer-info-card.js +22 -14
- package/es/checkout-v2/components/right/status-feedback.js +1 -1
- package/es/checkout-v2/layouts/checkout-layout.js +13 -3
- package/es/checkout-v2/panels/right/payment-panel.js +3 -1
- package/es/checkout-v2/views/error-view.d.ts +1 -1
- package/es/checkout-v2/views/error-view.js +7 -0
- package/es/components/service-suspended-dialog.d.ts +4 -0
- package/es/components/service-suspended-dialog.js +61 -0
- package/es/locales/en.js +4 -0
- package/es/locales/zh.js +4 -0
- package/es/payment/form/index.js +17 -0
- package/es/payment/index.js +15 -4
- package/lib/checkout-v2/components/dialogs/checkout-dialogs.js +4 -0
- package/lib/checkout-v2/components/left/promotion-input.d.ts +2 -1
- package/lib/checkout-v2/components/left/promotion-input.js +5 -17
- package/lib/checkout-v2/components/right/customer-info-card.d.ts +2 -0
- package/lib/checkout-v2/components/right/customer-info-card.js +19 -13
- package/lib/checkout-v2/components/right/status-feedback.js +1 -1
- package/lib/checkout-v2/layouts/checkout-layout.js +28 -5
- package/lib/checkout-v2/panels/right/payment-panel.js +3 -1
- package/lib/checkout-v2/views/error-view.d.ts +1 -1
- package/lib/checkout-v2/views/error-view.js +7 -0
- package/lib/components/service-suspended-dialog.d.ts +4 -0
- package/lib/components/service-suspended-dialog.js +97 -0
- package/lib/locales/en.js +4 -0
- package/lib/locales/zh.js +4 -0
- package/lib/payment/form/index.js +23 -0
- package/lib/payment/index.js +15 -4
- package/package.json +4 -4
- package/src/checkout-v2/components/dialogs/checkout-dialogs.tsx +4 -0
- package/src/checkout-v2/components/left/promotion-input.tsx +6 -14
- package/src/checkout-v2/components/right/customer-info-card.tsx +29 -16
- package/src/checkout-v2/components/right/status-feedback.tsx +2 -2
- package/src/checkout-v2/layouts/checkout-layout.tsx +25 -10
- package/src/checkout-v2/panels/right/payment-panel.tsx +2 -0
- package/src/checkout-v2/views/error-view.tsx +9 -1
- package/src/components/service-suspended-dialog.tsx +64 -0
- package/src/locales/en.tsx +4 -0
- package/src/locales/zh.tsx +4 -0
- package/src/payment/form/index.tsx +20 -0
- package/src/payment/index.tsx +26 -4
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Box, Button, Dialog, DialogContent, Stack, Typography } from '@mui/material';
|
|
2
|
+
import { alpha } from '@mui/material/styles';
|
|
3
|
+
import PauseCircleOutlineIcon from '@mui/icons-material/PauseCircleOutline';
|
|
4
|
+
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
5
|
+
|
|
6
|
+
export default function ServiceSuspendedDialog({ open, onClose }: { open: boolean; onClose: () => void }) {
|
|
7
|
+
const { t } = useLocaleContext();
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<Dialog
|
|
11
|
+
open={open}
|
|
12
|
+
onClose={onClose}
|
|
13
|
+
PaperProps={{
|
|
14
|
+
sx: {
|
|
15
|
+
borderRadius: 3,
|
|
16
|
+
maxWidth: 400,
|
|
17
|
+
mx: 'auto',
|
|
18
|
+
overflow: 'hidden',
|
|
19
|
+
},
|
|
20
|
+
}}>
|
|
21
|
+
<DialogContent sx={{ p: 0 }}>
|
|
22
|
+
<Stack alignItems="center" sx={{ pt: 4, pb: 3, px: 4, textAlign: 'center' }}>
|
|
23
|
+
<Box
|
|
24
|
+
sx={{
|
|
25
|
+
width: 64,
|
|
26
|
+
height: 64,
|
|
27
|
+
borderRadius: '50%',
|
|
28
|
+
display: 'flex',
|
|
29
|
+
alignItems: 'center',
|
|
30
|
+
justifyContent: 'center',
|
|
31
|
+
bgcolor: (theme) => alpha(theme.palette.warning.main, 0.1),
|
|
32
|
+
mb: 2.5,
|
|
33
|
+
}}>
|
|
34
|
+
<PauseCircleOutlineIcon sx={{ fontSize: 36, color: 'warning.main' }} />
|
|
35
|
+
</Box>
|
|
36
|
+
|
|
37
|
+
<Typography sx={{ fontWeight: 700, fontSize: 18, mb: 1, color: 'text.primary' }}>
|
|
38
|
+
{t('payment.checkout.stopAcceptingOrders.title')}
|
|
39
|
+
</Typography>
|
|
40
|
+
|
|
41
|
+
<Typography sx={{ color: 'text.secondary', fontSize: 14, lineHeight: 1.6 }}>
|
|
42
|
+
{t('payment.checkout.stopAcceptingOrders.description')}
|
|
43
|
+
</Typography>
|
|
44
|
+
</Stack>
|
|
45
|
+
|
|
46
|
+
<Box sx={{ px: 4, pb: 3 }}>
|
|
47
|
+
<Button
|
|
48
|
+
fullWidth
|
|
49
|
+
variant="contained"
|
|
50
|
+
disableElevation
|
|
51
|
+
onClick={onClose}
|
|
52
|
+
sx={{
|
|
53
|
+
borderRadius: 2,
|
|
54
|
+
textTransform: 'none',
|
|
55
|
+
fontWeight: 600,
|
|
56
|
+
py: 1,
|
|
57
|
+
}}>
|
|
58
|
+
{t('common.know')}
|
|
59
|
+
</Button>
|
|
60
|
+
</Box>
|
|
61
|
+
</DialogContent>
|
|
62
|
+
</Dialog>
|
|
63
|
+
);
|
|
64
|
+
}
|
package/src/locales/en.tsx
CHANGED
|
@@ -396,6 +396,10 @@ export default flat({
|
|
|
396
396
|
title: 'Nothing to show here',
|
|
397
397
|
description: 'It seems this checkout session is not configured properly',
|
|
398
398
|
},
|
|
399
|
+
stopAcceptingOrders: {
|
|
400
|
+
title: 'Service Suspended',
|
|
401
|
+
description: 'New order placement is temporarily unavailable due to a system-level service suspension.',
|
|
402
|
+
},
|
|
399
403
|
error: {
|
|
400
404
|
title: 'Something went wrong',
|
|
401
405
|
},
|
package/src/locales/zh.tsx
CHANGED
|
@@ -61,6 +61,7 @@ import LoadingButton from '../../components/loading-button';
|
|
|
61
61
|
import OverdueInvoicePayment from '../../components/over-due-invoice-payment';
|
|
62
62
|
import { saveCurrencyPreference } from '../../libs/currency';
|
|
63
63
|
import ConfirmDialog from '../../components/confirm';
|
|
64
|
+
import ServiceSuspendedDialog from '../../components/service-suspended-dialog';
|
|
64
65
|
import PriceChangeConfirm from '../../components/price-change-confirm';
|
|
65
66
|
import { getFieldValidation, validatePostalCode } from '../../libs/validator';
|
|
66
67
|
|
|
@@ -267,6 +268,7 @@ export default function PaymentForm({
|
|
|
267
268
|
};
|
|
268
269
|
customer?: TCustomer;
|
|
269
270
|
customerLimited?: boolean;
|
|
271
|
+
serviceSuspended?: boolean;
|
|
270
272
|
stripePaying: boolean;
|
|
271
273
|
fastCheckoutInfo: FastCheckoutInfo | null;
|
|
272
274
|
creditInsufficientInfo: {
|
|
@@ -289,6 +291,7 @@ export default function PaymentForm({
|
|
|
289
291
|
stripeContext: undefined,
|
|
290
292
|
customer,
|
|
291
293
|
customerLimited: false,
|
|
294
|
+
serviceSuspended: false,
|
|
292
295
|
stripePaying: false,
|
|
293
296
|
fastCheckoutInfo: null,
|
|
294
297
|
creditInsufficientInfo: null,
|
|
@@ -1198,6 +1201,11 @@ export default function PaymentForm({
|
|
|
1198
1201
|
shouldToast = false;
|
|
1199
1202
|
setState({ customerLimited: true });
|
|
1200
1203
|
}
|
|
1204
|
+
|
|
1205
|
+
if (errorCode === 'STOP_ACCEPTING_ORDERS') {
|
|
1206
|
+
shouldToast = false;
|
|
1207
|
+
setState({ serviceSuspended: true });
|
|
1208
|
+
}
|
|
1201
1209
|
}
|
|
1202
1210
|
if (shouldToast) {
|
|
1203
1211
|
Toast.error(formatError(err));
|
|
@@ -1474,6 +1482,9 @@ export default function PaymentForm({
|
|
|
1474
1482
|
}}
|
|
1475
1483
|
/>
|
|
1476
1484
|
)}
|
|
1485
|
+
{state.serviceSuspended && (
|
|
1486
|
+
<ServiceSuspendedDialog open onClose={() => setState({ serviceSuspended: false })} />
|
|
1487
|
+
)}
|
|
1477
1488
|
{FastCheckoutConfirmDialog}
|
|
1478
1489
|
{CreditInsufficientDialog}
|
|
1479
1490
|
{PriceUpdatedDialog}
|
|
@@ -1748,6 +1759,15 @@ export default function PaymentForm({
|
|
|
1748
1759
|
}}
|
|
1749
1760
|
/>
|
|
1750
1761
|
)}
|
|
1762
|
+
{state.serviceSuspended && (
|
|
1763
|
+
<ConfirmDialog
|
|
1764
|
+
onConfirm={() => setState({ serviceSuspended: false })}
|
|
1765
|
+
onCancel={() => setState({ serviceSuspended: false })}
|
|
1766
|
+
title={t('payment.checkout.stopAcceptingOrders.title')}
|
|
1767
|
+
message={t('payment.checkout.stopAcceptingOrders.description')}
|
|
1768
|
+
confirm={t('common.confirm')}
|
|
1769
|
+
/>
|
|
1770
|
+
)}
|
|
1751
1771
|
{FastCheckoutConfirmDialog}
|
|
1752
1772
|
{CreditInsufficientDialog}
|
|
1753
1773
|
{PriceUpdatedDialog}
|
package/src/payment/index.tsx
CHANGED
|
@@ -125,6 +125,19 @@ function PaymentInner({
|
|
|
125
125
|
}, [paymentMethods]);
|
|
126
126
|
|
|
127
127
|
const defaultCurrencyId = useMemo(() => {
|
|
128
|
+
// Keep session currency stable when a promotion is already applied.
|
|
129
|
+
// Otherwise auto-picking from URL/local preference/no-wallet may switch currency
|
|
130
|
+
// on refresh and trigger a second recalculate-promotion that removes discount
|
|
131
|
+
// with `currency_incompatible`.
|
|
132
|
+
const hasAppliedDiscount = Boolean((state.checkoutSession as any)?.discounts?.length);
|
|
133
|
+
if (
|
|
134
|
+
hasAppliedDiscount &&
|
|
135
|
+
state.checkoutSession.currency_id &&
|
|
136
|
+
availableCurrencyIds.includes(state.checkoutSession.currency_id)
|
|
137
|
+
) {
|
|
138
|
+
return state.checkoutSession.currency_id;
|
|
139
|
+
}
|
|
140
|
+
|
|
128
141
|
// 1. first check url currencyId
|
|
129
142
|
if (query.currencyId && availableCurrencyIds.includes(query.currencyId)) {
|
|
130
143
|
return query.currencyId;
|
|
@@ -151,7 +164,7 @@ function PaymentInner({
|
|
|
151
164
|
return state.checkoutSession.currency_id;
|
|
152
165
|
}
|
|
153
166
|
return availableCurrencyIds?.[0];
|
|
154
|
-
}, [query.currencyId, availableCurrencyIds, session?.user, state.checkoutSession
|
|
167
|
+
}, [query.currencyId, availableCurrencyIds, session?.user, state.checkoutSession, paymentMethods]);
|
|
155
168
|
|
|
156
169
|
const defaultMethodId = paymentMethods.find((m) => m.payment_currencies.some((c) => c.id === defaultCurrencyId))?.id;
|
|
157
170
|
const hideSummaryCard = mode.endsWith('-minimal') || !showCheckoutSummary;
|
|
@@ -183,14 +196,23 @@ function PaymentInner({
|
|
|
183
196
|
});
|
|
184
197
|
|
|
185
198
|
useEffect(() => {
|
|
199
|
+
const hasAppliedDiscount = Boolean((state.checkoutSession as any)?.discounts?.length);
|
|
200
|
+
const currentCurrency = methods.getValues('payment_currency');
|
|
201
|
+
const currentMethod = methods.getValues('payment_method');
|
|
202
|
+
|
|
186
203
|
if (defaultCurrencyId) {
|
|
187
|
-
|
|
204
|
+
// Avoid overriding current currency on refresh when a promotion is already applied.
|
|
205
|
+
if (!hasAppliedDiscount || !currentCurrency) {
|
|
206
|
+
methods.setValue('payment_currency', defaultCurrencyId);
|
|
207
|
+
}
|
|
188
208
|
}
|
|
189
209
|
if (defaultMethodId) {
|
|
190
|
-
|
|
210
|
+
if (!hasAppliedDiscount || !currentMethod) {
|
|
211
|
+
methods.setValue('payment_method', defaultMethodId);
|
|
212
|
+
}
|
|
191
213
|
}
|
|
192
214
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
193
|
-
}, [defaultCurrencyId, defaultMethodId]);
|
|
215
|
+
}, [defaultCurrencyId, defaultMethodId, state.checkoutSession.discounts]);
|
|
194
216
|
|
|
195
217
|
useEffect(() => {
|
|
196
218
|
if (!isMobileSafari()) {
|