@akinon/next 2.0.0-beta.8 → 2.0.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/CHANGELOG.md +438 -21
- package/__tests__/next-config.test.ts +83 -0
- package/__tests__/tsconfig.json +23 -0
- package/api/auth.ts +367 -63
- package/api/barcode-search.ts +59 -0
- package/api/cache.ts +41 -5
- package/api/client.ts +21 -4
- package/api/form.ts +85 -0
- package/api/image-proxy.ts +75 -0
- package/api/product-categories.ts +53 -0
- package/api/similar-product-list.ts +63 -0
- package/api/similar-products.ts +111 -0
- package/api/virtual-try-on.ts +382 -0
- package/assets/styles/index.scss +84 -0
- package/babel.config.js +6 -0
- package/bin/pz-generate-routes.js +115 -0
- package/bin/pz-install-plugins.js +1 -1
- package/bin/pz-prebuild.js +1 -0
- package/bin/pz-predev.js +1 -0
- package/bin/pz-run-tests.js +99 -0
- package/components/accordion.tsx +21 -6
- package/components/client-root.tsx +119 -3
- package/components/file-input.tsx +65 -3
- package/components/index.ts +1 -0
- package/components/input.tsx +2 -2
- package/components/link.tsx +46 -16
- package/components/logger-popup.tsx +213 -0
- package/components/modal.tsx +32 -16
- package/components/plugin-module.tsx +62 -3
- package/components/price.tsx +2 -2
- package/components/select.tsx +3 -3
- package/components/selected-payment-option-view.tsx +21 -0
- package/data/client/account.ts +17 -2
- package/data/client/basket.ts +39 -0
- package/data/client/checkout.ts +336 -99
- package/data/client/misc.ts +13 -1
- package/data/server/category.ts +11 -9
- package/data/server/flatpage.ts +4 -1
- package/data/server/form.ts +4 -1
- package/data/server/landingpage.ts +4 -1
- package/data/server/list.ts +5 -4
- package/data/server/menu.ts +4 -1
- package/data/server/product.ts +97 -52
- package/data/server/seo.ts +4 -1
- package/data/server/special-page.ts +5 -4
- package/data/server/widget.ts +71 -1
- package/data/urls.ts +6 -3
- package/hocs/client/with-segment-defaults.tsx +2 -2
- package/hocs/server/with-segment-defaults.tsx +81 -20
- package/hooks/index.ts +3 -0
- package/hooks/use-localization.ts +24 -10
- package/hooks/use-logger-context.tsx +114 -0
- package/hooks/use-logger.ts +92 -0
- package/hooks/use-loyalty-availability.ts +21 -0
- package/hooks/use-payment-options.ts +2 -1
- package/hooks/use-pz-params.ts +37 -0
- package/hooks/use-router.ts +53 -19
- package/instrumentation/index.ts +0 -1
- package/instrumentation/node.ts +2 -20
- package/jest.config.js +25 -0
- package/lib/cache-handler.mjs +534 -16
- package/lib/cache.ts +269 -34
- package/localization/provider.tsx +2 -5
- package/middlewares/bfcache-headers.ts +18 -0
- package/middlewares/checkout-provider.ts +1 -1
- package/middlewares/complete-gpay.ts +32 -26
- package/middlewares/complete-masterpass.ts +33 -26
- package/middlewares/complete-wallet.ts +182 -0
- package/middlewares/default.ts +357 -203
- package/middlewares/index.ts +10 -2
- package/middlewares/locale.ts +5 -3
- package/middlewares/masterpass-rest-callback.ts +230 -0
- package/middlewares/oauth-login.ts +200 -57
- package/middlewares/pretty-url.ts +21 -8
- package/middlewares/redirection-payment.ts +32 -26
- package/middlewares/saved-card-redirection.ts +33 -26
- package/middlewares/three-d-redirection.ts +32 -26
- package/middlewares/url-redirection.ts +9 -15
- package/middlewares/wallet-complete-redirection.ts +206 -0
- package/package.json +24 -10
- package/plugins.d.ts +19 -4
- package/plugins.js +9 -1
- package/redux/actions.ts +47 -0
- package/redux/middlewares/checkout.ts +61 -8
- package/redux/middlewares/index.ts +14 -10
- package/redux/middlewares/pre-order/address.ts +1 -1
- package/redux/middlewares/pre-order/attribute-based-shipping-option.ts +1 -1
- package/redux/middlewares/pre-order/data-source-shipping-option.ts +1 -1
- package/redux/middlewares/pre-order/delivery-option.ts +1 -1
- package/redux/middlewares/pre-order/index.ts +3 -1
- package/redux/middlewares/pre-order/installment-option.ts +2 -1
- package/redux/middlewares/pre-order/payment-option-reset.ts +37 -0
- package/redux/middlewares/pre-order/payment-option.ts +1 -1
- package/redux/middlewares/pre-order/pre-order-validation.ts +4 -3
- package/redux/middlewares/pre-order/redirection.ts +2 -2
- package/redux/middlewares/pre-order/set-pre-order.ts +2 -2
- package/redux/middlewares/pre-order/shipping-option.ts +1 -1
- package/redux/middlewares/pre-order/shipping-step.ts +1 -1
- package/redux/reducers/checkout.ts +15 -1
- package/redux/reducers/index.ts +7 -1
- package/redux/reducers/widget.ts +80 -0
- package/sentry/index.ts +54 -17
- package/tailwind/content.js +16 -0
- package/types/commerce/checkout.ts +26 -1
- package/types/commerce/widget.ts +33 -0
- package/types/index.ts +114 -5
- package/types/next-auth.d.ts +2 -2
- package/types/widget.ts +80 -0
- package/utils/app-fetch.ts +7 -2
- package/utils/generate-commerce-search-params.ts +3 -2
- package/utils/get-checkout-path.ts +3 -0
- package/utils/get-root-hostname.ts +28 -0
- package/utils/index.ts +69 -18
- package/utils/mobile-3d-iframe.ts +8 -2
- package/utils/override-middleware.ts +1 -0
- package/utils/pz-segments.ts +92 -0
- package/utils/redirect-ignore.ts +35 -0
- package/utils/redirect.ts +9 -3
- package/utils/redirection-iframe.ts +8 -2
- package/utils/widget-styles.ts +107 -0
- package/with-pz-config.js +20 -7
package/data/client/checkout.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
} from '../../redux/reducers/checkout';
|
|
11
11
|
import {
|
|
12
12
|
CheckoutContext,
|
|
13
|
+
AccountUsage,
|
|
13
14
|
ExtraField,
|
|
14
15
|
GuestLoginFormParams,
|
|
15
16
|
Order,
|
|
@@ -17,10 +18,10 @@ import {
|
|
|
17
18
|
SendSmsType,
|
|
18
19
|
VerifySmsType
|
|
19
20
|
} from '../../types';
|
|
20
|
-
import { buildClientRequestUrl } from '../../utils';
|
|
21
|
+
import { buildClientRequestUrl, getCookie } from '../../utils';
|
|
21
22
|
import { api } from './api';
|
|
22
23
|
import { checkout } from '../urls';
|
|
23
|
-
import { AppDispatch, AppStore
|
|
24
|
+
import type { AppDispatch, AppStore } from 'redux/store';
|
|
24
25
|
import settings from 'settings';
|
|
25
26
|
import { showMobile3dIframe } from '../../utils/mobile-3d-iframe';
|
|
26
27
|
import {
|
|
@@ -32,6 +33,21 @@ import {
|
|
|
32
33
|
buildDirectPurchaseForm,
|
|
33
34
|
buildPurchaseForm
|
|
34
35
|
} from '@akinon/pz-masterpass/src/utils';
|
|
36
|
+
import { devLogger } from '@akinon/next/hooks/use-logger-context';
|
|
37
|
+
import { LogLevel } from '@akinon/next/hooks/use-logger';
|
|
38
|
+
|
|
39
|
+
const getLatestState = async (getState: () => any): Promise<any> => {
|
|
40
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
41
|
+
|
|
42
|
+
return getState();
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const recentLogMessages = new Map<string, number>();
|
|
46
|
+
|
|
47
|
+
const getStore = async (): Promise<AppStore> => {
|
|
48
|
+
const { store } = await import('redux/store');
|
|
49
|
+
return store;
|
|
50
|
+
};
|
|
35
51
|
|
|
36
52
|
interface CheckoutResponse {
|
|
37
53
|
pre_order?: PreOrder;
|
|
@@ -43,6 +59,53 @@ interface CheckoutResponse {
|
|
|
43
59
|
redirect_url?: string;
|
|
44
60
|
}
|
|
45
61
|
|
|
62
|
+
const validateCheckoutState = (
|
|
63
|
+
state: any,
|
|
64
|
+
validations: Array<{
|
|
65
|
+
condition: (state: any) => boolean;
|
|
66
|
+
errorMessage: string;
|
|
67
|
+
severity?: LogLevel;
|
|
68
|
+
data?: any;
|
|
69
|
+
action?: () => void;
|
|
70
|
+
}>
|
|
71
|
+
) => {
|
|
72
|
+
validations.forEach(
|
|
73
|
+
({
|
|
74
|
+
condition,
|
|
75
|
+
errorMessage,
|
|
76
|
+
severity = 'error',
|
|
77
|
+
data: logData,
|
|
78
|
+
action
|
|
79
|
+
}) => {
|
|
80
|
+
if (condition(state)) {
|
|
81
|
+
const now = Date.now();
|
|
82
|
+
const lastLogged = recentLogMessages.get(errorMessage) || 0;
|
|
83
|
+
|
|
84
|
+
if (now - lastLogged > 2000) {
|
|
85
|
+
recentLogMessages.set(errorMessage, now);
|
|
86
|
+
|
|
87
|
+
switch (severity) {
|
|
88
|
+
case 'error':
|
|
89
|
+
devLogger.error(
|
|
90
|
+
errorMessage,
|
|
91
|
+
logData || state.checkout?.preOrder
|
|
92
|
+
);
|
|
93
|
+
action?.();
|
|
94
|
+
break;
|
|
95
|
+
case 'warn':
|
|
96
|
+
devLogger.warn(errorMessage, logData || state.checkout?.preOrder);
|
|
97
|
+
action?.();
|
|
98
|
+
break;
|
|
99
|
+
default:
|
|
100
|
+
devLogger.info(errorMessage, logData || state.checkout?.preOrder);
|
|
101
|
+
action?.();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
);
|
|
107
|
+
};
|
|
108
|
+
|
|
46
109
|
interface SetAddressesParams {
|
|
47
110
|
shippingAddressPk: number;
|
|
48
111
|
billingAddressPk: number;
|
|
@@ -82,6 +145,18 @@ export interface PayOnDeliveryParams {
|
|
|
82
145
|
paymentType: string;
|
|
83
146
|
}
|
|
84
147
|
|
|
148
|
+
const buildCheckoutRequestUrl = (
|
|
149
|
+
path: string,
|
|
150
|
+
options?: Parameters<typeof buildClientRequestUrl>[1]
|
|
151
|
+
) => {
|
|
152
|
+
const effectivePath =
|
|
153
|
+
getCookie('pz-post-checkout-flow') === 'true' &&
|
|
154
|
+
/^\/orders\/checkout(\/|\?|$)/.test(path)
|
|
155
|
+
? path.replace('/orders/checkout', '/orders/post-checkout')
|
|
156
|
+
: path;
|
|
157
|
+
return buildClientRequestUrl(effectivePath, options);
|
|
158
|
+
};
|
|
159
|
+
|
|
85
160
|
const completeMasterpassPayment = async (
|
|
86
161
|
params: CompleteCreditCardParams,
|
|
87
162
|
dispatch: AppDispatch,
|
|
@@ -177,45 +252,59 @@ const completeMasterpassPayment = async (
|
|
|
177
252
|
});
|
|
178
253
|
};
|
|
179
254
|
|
|
255
|
+
let checkoutAbortController = new AbortController();
|
|
256
|
+
|
|
257
|
+
export const getCheckoutAbortSignal = () => {
|
|
258
|
+
if (checkoutAbortController.signal.aborted) {
|
|
259
|
+
checkoutAbortController = new AbortController();
|
|
260
|
+
}
|
|
261
|
+
return checkoutAbortController.signal;
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
const abortCheckout = () => {
|
|
265
|
+
checkoutAbortController.abort();
|
|
266
|
+
checkoutAbortController = new AbortController();
|
|
267
|
+
};
|
|
268
|
+
|
|
180
269
|
export const checkoutApi = api.injectEndpoints({
|
|
181
270
|
endpoints: (build) => ({
|
|
182
271
|
fetchCheckout: build.query<CheckoutResponse, void>({
|
|
183
272
|
query: () => ({
|
|
184
|
-
url:
|
|
273
|
+
url: buildCheckoutRequestUrl(checkout.fetchCheckout, {})
|
|
185
274
|
}),
|
|
186
275
|
providesTags: ['Checkout']
|
|
187
276
|
}),
|
|
188
277
|
resetCheckoutState: build.query<CheckoutResponse, void>({
|
|
189
278
|
query: () => ({
|
|
190
|
-
url:
|
|
279
|
+
url: buildCheckoutRequestUrl(checkout.guestLogin, {})
|
|
191
280
|
})
|
|
192
281
|
}),
|
|
193
282
|
fetchCheckoutResult: build.query<{ order: Order }, string>({
|
|
194
283
|
query: (token: string) =>
|
|
195
|
-
|
|
284
|
+
buildCheckoutRequestUrl(checkout.fetchCheckoutResult(token))
|
|
196
285
|
}),
|
|
197
286
|
get3dRedirectForm: build.query<{ result: string }, void>({
|
|
198
287
|
query: () =>
|
|
199
|
-
|
|
288
|
+
buildCheckoutRequestUrl(checkout.get3dRedirectForm, {
|
|
200
289
|
responseType: 'text'
|
|
201
290
|
})
|
|
202
291
|
}),
|
|
203
292
|
getContract: build.query<GetContractResponse, string>({
|
|
204
293
|
query: (slug: string) =>
|
|
205
|
-
|
|
294
|
+
buildCheckoutRequestUrl(checkout.getContract(slug), {
|
|
206
295
|
responseType: 'text'
|
|
207
296
|
})
|
|
208
297
|
}),
|
|
209
298
|
getCoupons: build.query<CheckoutResponse, void>({
|
|
210
299
|
query: () => ({
|
|
211
|
-
url:
|
|
300
|
+
url: buildCheckoutRequestUrl(checkout.couponSelectionPage)
|
|
212
301
|
})
|
|
213
302
|
}),
|
|
214
303
|
|
|
215
304
|
setCoupon: build.mutation<CheckoutResponse, { pk: number; action: string }>(
|
|
216
305
|
{
|
|
217
306
|
query: ({ pk, action }) => ({
|
|
218
|
-
url:
|
|
307
|
+
url: buildCheckoutRequestUrl(checkout.couponSelectionPage, {
|
|
219
308
|
useFormData: true
|
|
220
309
|
}),
|
|
221
310
|
method: 'POST',
|
|
@@ -231,25 +320,32 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
231
320
|
CheckoutResponse,
|
|
232
321
|
CompleteCreditCardParams
|
|
233
322
|
>({
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
323
|
+
async queryFn(
|
|
324
|
+
{
|
|
325
|
+
card_holder,
|
|
326
|
+
card_cvv,
|
|
327
|
+
card_number,
|
|
328
|
+
card_month,
|
|
329
|
+
card_year,
|
|
330
|
+
use_three_d = true,
|
|
331
|
+
save = undefined
|
|
332
|
+
},
|
|
333
|
+
_queryApi,
|
|
334
|
+
_extraOptions,
|
|
335
|
+
baseQuery
|
|
336
|
+
) {
|
|
337
|
+
const reduxStore = await getStore();
|
|
243
338
|
const paymentOption =
|
|
244
|
-
|
|
339
|
+
reduxStore.getState().checkout?.preOrder?.payment_option;
|
|
245
340
|
|
|
246
341
|
if (paymentOption?.payment_type === 'masterpass') {
|
|
247
|
-
|
|
248
|
-
url:
|
|
342
|
+
const result = await baseQuery({
|
|
343
|
+
url: buildCheckoutRequestUrl(checkout.getMasterpassOrderNo, {
|
|
249
344
|
useFormData: true
|
|
250
345
|
}),
|
|
251
346
|
method: 'POST'
|
|
252
|
-
};
|
|
347
|
+
});
|
|
348
|
+
return result as { data: CheckoutResponse } | { error: any };
|
|
253
349
|
}
|
|
254
350
|
|
|
255
351
|
const body: Record<string, string> = {
|
|
@@ -266,18 +362,19 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
266
362
|
body.save = save ? '1' : '0';
|
|
267
363
|
}
|
|
268
364
|
|
|
269
|
-
|
|
270
|
-
url:
|
|
365
|
+
const result = await baseQuery({
|
|
366
|
+
url: buildCheckoutRequestUrl(checkout.completeCreditCardPayment, {
|
|
271
367
|
useFormData: true
|
|
272
368
|
}),
|
|
273
369
|
method: 'POST',
|
|
274
370
|
body
|
|
275
|
-
};
|
|
371
|
+
});
|
|
372
|
+
return result as { data: CheckoutResponse } | { error: any };
|
|
276
373
|
},
|
|
277
374
|
async onQueryStarted(args, { dispatch, queryFulfilled }) {
|
|
278
375
|
dispatch(setPaymentStepBusy(true));
|
|
279
376
|
const { data } = await queryFulfilled;
|
|
280
|
-
const reduxStore =
|
|
377
|
+
const reduxStore = await getStore();
|
|
281
378
|
const completePaymentContext = data?.context_list?.find(
|
|
282
379
|
(context) => context?.page_name === 'MasterpassCompletePage'
|
|
283
380
|
);
|
|
@@ -302,7 +399,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
302
399
|
}
|
|
303
400
|
>({
|
|
304
401
|
query: ({ token }) => ({
|
|
305
|
-
url:
|
|
402
|
+
url: buildCheckoutRequestUrl(checkout.completeMasterpassPayment, {
|
|
306
403
|
useFormData: true
|
|
307
404
|
}),
|
|
308
405
|
method: 'POST',
|
|
@@ -319,7 +416,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
319
416
|
}),
|
|
320
417
|
completeFundsTransfer: build.mutation<CheckoutResponse, void>({
|
|
321
418
|
query: () => ({
|
|
322
|
-
url:
|
|
419
|
+
url: buildCheckoutRequestUrl(checkout.completeFundsTransfer, {
|
|
323
420
|
useFormData: true
|
|
324
421
|
}),
|
|
325
422
|
method: 'POST',
|
|
@@ -336,7 +433,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
336
433
|
}),
|
|
337
434
|
guestLogin: build.mutation<CheckoutResponse, GuestLoginFormParams>({
|
|
338
435
|
query: ({ user_email, phone_number }) => ({
|
|
339
|
-
url:
|
|
436
|
+
url: buildCheckoutRequestUrl(checkout.guestLogin, {
|
|
340
437
|
useFormData: true
|
|
341
438
|
}),
|
|
342
439
|
method: 'POST',
|
|
@@ -349,56 +446,132 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
349
446
|
}),
|
|
350
447
|
setDeliveryOption: build.mutation<CheckoutResponse, number>({
|
|
351
448
|
query: (pk: number) => ({
|
|
352
|
-
url:
|
|
449
|
+
url: buildCheckoutRequestUrl(checkout.setDeliveryOption, {
|
|
353
450
|
useFormData: true
|
|
354
451
|
}),
|
|
355
452
|
method: 'POST',
|
|
356
453
|
body: {
|
|
357
454
|
delivery_option: String(pk)
|
|
358
|
-
}
|
|
455
|
+
},
|
|
456
|
+
signal: getCheckoutAbortSignal()
|
|
359
457
|
}),
|
|
360
|
-
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
458
|
+
async onQueryStarted(arg, { dispatch, queryFulfilled, getState }) {
|
|
361
459
|
dispatch(setShippingStepBusy(true));
|
|
362
|
-
|
|
363
|
-
|
|
460
|
+
|
|
461
|
+
const state = await getLatestState(getState);
|
|
462
|
+
|
|
463
|
+
validateCheckoutState(state, [
|
|
464
|
+
{
|
|
465
|
+
condition: (state) => {
|
|
466
|
+
const preOrder = state.checkout?.preOrder;
|
|
467
|
+
|
|
468
|
+
return preOrder?.basket?.basketitem_set?.length === 0;
|
|
469
|
+
},
|
|
470
|
+
errorMessage:
|
|
471
|
+
'Your shopping basket is empty. Please add items to your basket before selecting a delivery option.',
|
|
472
|
+
action: () => abortCheckout()
|
|
473
|
+
}
|
|
474
|
+
]);
|
|
475
|
+
|
|
476
|
+
try {
|
|
477
|
+
await queryFulfilled;
|
|
478
|
+
dispatch(setShippingStepBusy(false));
|
|
479
|
+
} catch (error) {
|
|
480
|
+
dispatch(setShippingStepBusy(false));
|
|
481
|
+
}
|
|
364
482
|
}
|
|
365
483
|
}),
|
|
366
484
|
setAddresses: build.mutation<CheckoutResponse, SetAddressesParams>({
|
|
367
485
|
query: ({ shippingAddressPk, billingAddressPk }) => ({
|
|
368
|
-
url:
|
|
486
|
+
url: buildCheckoutRequestUrl(checkout.setAddresses, {
|
|
369
487
|
useFormData: true
|
|
370
488
|
}),
|
|
371
489
|
method: 'POST',
|
|
372
490
|
body: {
|
|
373
491
|
shipping_address: String(shippingAddressPk),
|
|
374
492
|
billing_address: String(billingAddressPk)
|
|
375
|
-
}
|
|
493
|
+
},
|
|
494
|
+
signal: getCheckoutAbortSignal()
|
|
376
495
|
}),
|
|
377
|
-
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
496
|
+
async onQueryStarted(arg, { dispatch, queryFulfilled, getState }) {
|
|
378
497
|
dispatch(setShippingStepBusy(true));
|
|
379
|
-
|
|
380
|
-
|
|
498
|
+
|
|
499
|
+
const state = await getLatestState(getState);
|
|
500
|
+
|
|
501
|
+
validateCheckoutState(state, [
|
|
502
|
+
{
|
|
503
|
+
condition: (state) => {
|
|
504
|
+
const deliveryOptions = state.checkout?.deliveryOptions;
|
|
505
|
+
const preOrder = state.checkout?.preOrder;
|
|
506
|
+
|
|
507
|
+
return deliveryOptions?.length > 0
|
|
508
|
+
? preOrder && !preOrder.delivery_option?.pk
|
|
509
|
+
: false;
|
|
510
|
+
},
|
|
511
|
+
errorMessage:
|
|
512
|
+
'You need to select a delivery option before setting your addresses. Dispatch setAddresses action after delivery option selection.',
|
|
513
|
+
action: () => abortCheckout()
|
|
514
|
+
}
|
|
515
|
+
]);
|
|
516
|
+
|
|
517
|
+
try {
|
|
518
|
+
await queryFulfilled;
|
|
519
|
+
dispatch(setShippingStepBusy(false));
|
|
520
|
+
} catch (error) {
|
|
521
|
+
dispatch(setShippingStepBusy(false));
|
|
522
|
+
}
|
|
381
523
|
}
|
|
382
524
|
}),
|
|
383
525
|
setShippingOption: build.mutation<CheckoutResponse, number>({
|
|
384
526
|
query: (pk: number) => ({
|
|
385
|
-
url:
|
|
527
|
+
url: buildCheckoutRequestUrl(checkout.setShippingOption, {
|
|
386
528
|
useFormData: true
|
|
387
529
|
}),
|
|
388
530
|
method: 'POST',
|
|
389
531
|
body: {
|
|
390
532
|
shipping_option: String(pk)
|
|
391
|
-
}
|
|
533
|
+
},
|
|
534
|
+
signal: getCheckoutAbortSignal()
|
|
392
535
|
}),
|
|
393
|
-
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
536
|
+
async onQueryStarted(arg, { dispatch, queryFulfilled, getState }) {
|
|
394
537
|
dispatch(setShippingStepBusy(true));
|
|
395
|
-
|
|
396
|
-
|
|
538
|
+
|
|
539
|
+
const state = await getLatestState(getState);
|
|
540
|
+
|
|
541
|
+
validateCheckoutState(state, [
|
|
542
|
+
{
|
|
543
|
+
condition: (state) => {
|
|
544
|
+
const preOrder = state.checkout?.preOrder;
|
|
545
|
+
|
|
546
|
+
return !preOrder?.billing_address;
|
|
547
|
+
},
|
|
548
|
+
errorMessage:
|
|
549
|
+
'You need to provide a billing address before selecting a shipping option. Dispatch setShippingOption action after billing address selection.',
|
|
550
|
+
action: () => abortCheckout()
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
condition: (state) => {
|
|
554
|
+
const preOrder = state.checkout?.preOrder;
|
|
555
|
+
|
|
556
|
+
return !preOrder?.shipping_address;
|
|
557
|
+
},
|
|
558
|
+
errorMessage:
|
|
559
|
+
'You need to provide a shipping address before selecting a shipping option. Dispatch setShippingOption action after shipping address selection.',
|
|
560
|
+
action: () => abortCheckout()
|
|
561
|
+
}
|
|
562
|
+
]);
|
|
563
|
+
|
|
564
|
+
try {
|
|
565
|
+
await queryFulfilled;
|
|
566
|
+
dispatch(setShippingStepBusy(false));
|
|
567
|
+
} catch (error) {
|
|
568
|
+
dispatch(setShippingStepBusy(false));
|
|
569
|
+
}
|
|
397
570
|
}
|
|
398
571
|
}),
|
|
399
572
|
setDataSourceShippingOptions: build.mutation<CheckoutResponse, number[]>({
|
|
400
573
|
query: (pks) => ({
|
|
401
|
-
url:
|
|
574
|
+
url: buildCheckoutRequestUrl(checkout.setDataSourceShippingOption, {
|
|
402
575
|
useFormData: true
|
|
403
576
|
}),
|
|
404
577
|
method: 'POST',
|
|
@@ -414,7 +587,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
414
587
|
}),
|
|
415
588
|
setRetailStore: build.mutation<CheckoutResponse, SetRetailStoreParams>({
|
|
416
589
|
query: ({ retailStorePk, billingAddressPk }) => ({
|
|
417
|
-
url:
|
|
590
|
+
url: buildCheckoutRequestUrl(
|
|
418
591
|
'/orders/checkout?page=RetailStoreSelectionPage',
|
|
419
592
|
{
|
|
420
593
|
useFormData: true
|
|
@@ -429,28 +602,49 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
429
602
|
}),
|
|
430
603
|
fetchPaymentOptions: build.query<CheckoutResponse, void>({
|
|
431
604
|
query: () => ({
|
|
432
|
-
url:
|
|
605
|
+
url: buildCheckoutRequestUrl(checkout.setPaymentOption)
|
|
433
606
|
}),
|
|
434
607
|
providesTags: ['PaymentOptions']
|
|
435
608
|
}),
|
|
436
609
|
setPaymentOption: build.mutation<CheckoutResponse, number>({
|
|
437
610
|
query: (pk: number) => ({
|
|
438
|
-
url:
|
|
611
|
+
url: buildCheckoutRequestUrl(checkout.setPaymentOption, {
|
|
439
612
|
useFormData: true
|
|
440
613
|
}),
|
|
441
614
|
method: 'POST',
|
|
442
615
|
body: {
|
|
443
616
|
payment_option: String(pk)
|
|
444
|
-
}
|
|
617
|
+
},
|
|
618
|
+
signal: getCheckoutAbortSignal()
|
|
445
619
|
}),
|
|
446
|
-
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
620
|
+
async onQueryStarted(arg, { dispatch, queryFulfilled, getState }) {
|
|
447
621
|
dispatch(setPaymentStepBusy(true));
|
|
448
622
|
dispatch(setInstallmentOptions([]));
|
|
449
623
|
dispatch(setBankAccounts([]));
|
|
450
624
|
dispatch(setSelectedBankAccountPk(null));
|
|
451
625
|
dispatch(setCardType(null));
|
|
452
|
-
|
|
453
|
-
|
|
626
|
+
|
|
627
|
+
const state = await getLatestState(getState);
|
|
628
|
+
|
|
629
|
+
validateCheckoutState(state, [
|
|
630
|
+
{
|
|
631
|
+
condition: (state) => {
|
|
632
|
+
const preOrder = state.checkout?.preOrder;
|
|
633
|
+
|
|
634
|
+
return !preOrder?.shipping_option?.pk;
|
|
635
|
+
},
|
|
636
|
+
errorMessage:
|
|
637
|
+
'You need to select a shipping option before choosing a payment method. Dispatch setPaymentOption action after shipping option selection.',
|
|
638
|
+
action: () => abortCheckout()
|
|
639
|
+
}
|
|
640
|
+
]);
|
|
641
|
+
|
|
642
|
+
try {
|
|
643
|
+
await queryFulfilled;
|
|
644
|
+
dispatch(setPaymentStepBusy(false));
|
|
645
|
+
} catch (error) {
|
|
646
|
+
dispatch(setPaymentStepBusy(false));
|
|
647
|
+
}
|
|
454
648
|
}
|
|
455
649
|
}),
|
|
456
650
|
setWalletSelectionPage: build.mutation<
|
|
@@ -461,7 +655,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
461
655
|
}
|
|
462
656
|
>({
|
|
463
657
|
query: ({ payment_option: pk, validationURL }) => ({
|
|
464
|
-
url:
|
|
658
|
+
url: buildCheckoutRequestUrl(checkout.setWalletSelectionPage, {
|
|
465
659
|
useFormData: true
|
|
466
660
|
}),
|
|
467
661
|
method: 'POST',
|
|
@@ -485,7 +679,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
485
679
|
}
|
|
486
680
|
>({
|
|
487
681
|
query: (requestBody) => ({
|
|
488
|
-
url:
|
|
682
|
+
url: buildCheckoutRequestUrl(checkout.setWalletPaymentPage, {
|
|
489
683
|
useFormData: true
|
|
490
684
|
}),
|
|
491
685
|
method: 'POST',
|
|
@@ -497,12 +691,22 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
497
691
|
dispatch(setPaymentStepBusy(false));
|
|
498
692
|
}
|
|
499
693
|
}),
|
|
500
|
-
setWalletCompletePage: build.mutation<
|
|
501
|
-
|
|
502
|
-
|
|
694
|
+
setWalletCompletePage: build.mutation<
|
|
695
|
+
CheckoutResponse,
|
|
696
|
+
{
|
|
697
|
+
success: boolean;
|
|
698
|
+
cko_payment_id?: string;
|
|
699
|
+
[key: string]: any;
|
|
700
|
+
}
|
|
701
|
+
>({
|
|
702
|
+
query: ({ success, ...additionalParams }) => ({
|
|
703
|
+
url: buildCheckoutRequestUrl(checkout.setWalletCompletePage, {
|
|
704
|
+
useFormData: true
|
|
705
|
+
}),
|
|
503
706
|
method: 'POST',
|
|
504
707
|
body: {
|
|
505
|
-
success
|
|
708
|
+
success,
|
|
709
|
+
...additionalParams
|
|
506
710
|
}
|
|
507
711
|
}),
|
|
508
712
|
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
@@ -512,23 +716,25 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
512
716
|
}
|
|
513
717
|
}),
|
|
514
718
|
setBinNumber: build.mutation<CheckoutResponse, string>({
|
|
515
|
-
|
|
719
|
+
async queryFn(binNumber, _queryApi, _extraOptions, baseQuery) {
|
|
720
|
+
const reduxStore = await getStore();
|
|
516
721
|
const paymentOption =
|
|
517
|
-
|
|
722
|
+
reduxStore.getState().checkout?.preOrder?.payment_option;
|
|
518
723
|
const binNumberUrl =
|
|
519
724
|
paymentOption?.payment_type === 'masterpass'
|
|
520
725
|
? checkout.setMasterpassBinNumber
|
|
521
726
|
: checkout.setBinNumber;
|
|
522
727
|
|
|
523
|
-
|
|
524
|
-
url:
|
|
728
|
+
const result = await baseQuery({
|
|
729
|
+
url: buildCheckoutRequestUrl(binNumberUrl, {
|
|
525
730
|
useFormData: true
|
|
526
731
|
}),
|
|
527
732
|
method: 'POST',
|
|
528
733
|
body: {
|
|
529
734
|
bin_number: binNumber
|
|
530
735
|
}
|
|
531
|
-
};
|
|
736
|
+
});
|
|
737
|
+
return result as { data: CheckoutResponse } | { error: any };
|
|
532
738
|
},
|
|
533
739
|
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
534
740
|
dispatch(setPaymentStepBusy(true));
|
|
@@ -538,22 +744,25 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
538
744
|
}
|
|
539
745
|
}),
|
|
540
746
|
setInstallmentOption: build.mutation<CheckoutResponse, number>({
|
|
541
|
-
|
|
747
|
+
async queryFn(pk, _queryApi, _extraOptions, baseQuery) {
|
|
748
|
+
const reduxStore = await getStore();
|
|
542
749
|
const paymentOption =
|
|
543
|
-
|
|
750
|
+
reduxStore.getState().checkout?.preOrder?.payment_option;
|
|
544
751
|
const installmentOption =
|
|
545
752
|
paymentOption?.payment_type === 'masterpass'
|
|
546
753
|
? checkout.setMasterPassInstallmentOption
|
|
547
754
|
: checkout.setInstallmentOption;
|
|
548
|
-
|
|
549
|
-
|
|
755
|
+
|
|
756
|
+
const result = await baseQuery({
|
|
757
|
+
url: buildCheckoutRequestUrl(installmentOption, {
|
|
550
758
|
useFormData: true
|
|
551
759
|
}),
|
|
552
760
|
method: 'POST',
|
|
553
761
|
body: {
|
|
554
762
|
installment: String(pk)
|
|
555
763
|
}
|
|
556
|
-
};
|
|
764
|
+
});
|
|
765
|
+
return result as { data: CheckoutResponse } | { error: any };
|
|
557
766
|
},
|
|
558
767
|
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
559
768
|
dispatch(setPaymentStepBusy(true));
|
|
@@ -563,7 +772,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
563
772
|
}),
|
|
564
773
|
setFundsTransferOption: build.mutation<CheckoutResponse, number>({
|
|
565
774
|
query: (pk: number) => ({
|
|
566
|
-
url:
|
|
775
|
+
url: buildCheckoutRequestUrl(checkout.setFundsTransferOption, {
|
|
567
776
|
useFormData: true
|
|
568
777
|
}),
|
|
569
778
|
method: 'POST',
|
|
@@ -580,7 +789,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
580
789
|
}),
|
|
581
790
|
setCreditPaymentOption: build.mutation<CheckoutResponse, number>({
|
|
582
791
|
query: (pk: number) => ({
|
|
583
|
-
url:
|
|
792
|
+
url: buildCheckoutRequestUrl(checkout.setCreditPaymentOption, {
|
|
584
793
|
useFormData: true
|
|
585
794
|
}),
|
|
586
795
|
method: 'POST',
|
|
@@ -597,7 +806,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
597
806
|
}),
|
|
598
807
|
confirmationCreditPayment: build.mutation<CheckoutResponse, void>({
|
|
599
808
|
query: () => ({
|
|
600
|
-
url:
|
|
809
|
+
url: buildCheckoutRequestUrl(checkout.confirmationCreditPayment, {
|
|
601
810
|
useFormData: true
|
|
602
811
|
}),
|
|
603
812
|
method: 'POST',
|
|
@@ -613,7 +822,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
613
822
|
}),
|
|
614
823
|
completeRedirectionPayment: build.mutation<CheckoutResponse, void>({
|
|
615
824
|
query: () => ({
|
|
616
|
-
url:
|
|
825
|
+
url: buildCheckoutRequestUrl(checkout.completeRedirectionPayment, {
|
|
617
826
|
useFormData: true
|
|
618
827
|
}),
|
|
619
828
|
method: 'POST',
|
|
@@ -629,7 +838,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
629
838
|
}),
|
|
630
839
|
applePaymentSelect: build.mutation<CheckoutResponse, ApplePaySelectParams>({
|
|
631
840
|
query: ({ agreement, validationURL }) => ({
|
|
632
|
-
url:
|
|
841
|
+
url: buildCheckoutRequestUrl(checkout.confirmationPaymentSelect, {
|
|
633
842
|
useFormData: true
|
|
634
843
|
}),
|
|
635
844
|
method: 'POST',
|
|
@@ -646,7 +855,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
646
855
|
}),
|
|
647
856
|
appleQuery: build.mutation<CheckoutResponse, ApplePayQueryParams>({
|
|
648
857
|
query: ({ agreement, paymentToken }) => ({
|
|
649
|
-
url:
|
|
858
|
+
url: buildCheckoutRequestUrl(checkout.confirmationQuery, {
|
|
650
859
|
useFormData: true
|
|
651
860
|
}),
|
|
652
861
|
method: 'POST',
|
|
@@ -663,7 +872,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
663
872
|
}),
|
|
664
873
|
completeConfirmation: build.mutation<CheckoutResponse, void>({
|
|
665
874
|
query: () => ({
|
|
666
|
-
url:
|
|
875
|
+
url: buildCheckoutRequestUrl(checkout.confirmationComplete, {
|
|
667
876
|
useFormData: true
|
|
668
877
|
}),
|
|
669
878
|
method: 'POST',
|
|
@@ -682,7 +891,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
682
891
|
PayOnDeliveryParams
|
|
683
892
|
>({
|
|
684
893
|
query: ({ paymentType }) => ({
|
|
685
|
-
url:
|
|
894
|
+
url: buildCheckoutRequestUrl(
|
|
686
895
|
`${checkout.fetchCheckout}?page=PayOnDeliveryPage`,
|
|
687
896
|
{ useFormData: true }
|
|
688
897
|
),
|
|
@@ -700,7 +909,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
700
909
|
}),
|
|
701
910
|
setPayOnDeliveryChoice: build.mutation<CheckoutResponse, string>({
|
|
702
911
|
query: (body) => ({
|
|
703
|
-
url:
|
|
912
|
+
url: buildCheckoutRequestUrl(
|
|
704
913
|
`${checkout.fetchCheckout}?page=PayOnDeliveryPaymentChoicePage`,
|
|
705
914
|
{ useFormData: true }
|
|
706
915
|
),
|
|
@@ -717,7 +926,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
717
926
|
}),
|
|
718
927
|
completeLoyaltyPayment: build.mutation<CheckoutResponse, void>({
|
|
719
928
|
query: () => ({
|
|
720
|
-
url:
|
|
929
|
+
url: buildCheckoutRequestUrl(checkout.completeLoyaltyPayment, {
|
|
721
930
|
useFormData: true
|
|
722
931
|
}),
|
|
723
932
|
method: 'POST',
|
|
@@ -733,19 +942,31 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
733
942
|
}),
|
|
734
943
|
getCheckoutLoyaltyBalance: build.query<CheckoutResponse, void>({
|
|
735
944
|
query: () => ({
|
|
736
|
-
url:
|
|
945
|
+
url: buildCheckoutRequestUrl(checkout.loyaltyMoneyUsage)
|
|
737
946
|
})
|
|
738
947
|
}),
|
|
739
|
-
payWithLoyaltyBalance: build.mutation<
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
948
|
+
payWithLoyaltyBalance: build.mutation<
|
|
949
|
+
any,
|
|
950
|
+
string | { account_usages: AccountUsage[] }
|
|
951
|
+
>({
|
|
952
|
+
query: (params) => {
|
|
953
|
+
const isAccountUsages =
|
|
954
|
+
typeof params === 'object' && 'account_usages' in params;
|
|
955
|
+
|
|
956
|
+
return {
|
|
957
|
+
url: buildCheckoutRequestUrl(checkout.loyaltyMoneyUsage, {
|
|
958
|
+
useFormData: true
|
|
959
|
+
}),
|
|
960
|
+
method: 'POST',
|
|
961
|
+
body: isAccountUsages
|
|
962
|
+
? {
|
|
963
|
+
account_usages: JSON.stringify(params.account_usages)
|
|
964
|
+
}
|
|
965
|
+
: {
|
|
966
|
+
loyalty_amount_to_use: params
|
|
967
|
+
}
|
|
968
|
+
};
|
|
969
|
+
},
|
|
749
970
|
async onQueryStarted(arg, { dispatch, queryFulfilled }) {
|
|
750
971
|
dispatch(setPaymentStepBusy(true));
|
|
751
972
|
dispatch(setPaymentOptions([]));
|
|
@@ -769,7 +990,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
769
990
|
}),
|
|
770
991
|
setOrderNote: build.mutation<CheckoutResponse, string>({
|
|
771
992
|
query: (notes) => ({
|
|
772
|
-
url:
|
|
993
|
+
url: buildCheckoutRequestUrl(checkout.setOrderNote, {
|
|
773
994
|
useFormData: true
|
|
774
995
|
}),
|
|
775
996
|
method: 'POST',
|
|
@@ -789,7 +1010,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
789
1010
|
};
|
|
790
1011
|
|
|
791
1012
|
return {
|
|
792
|
-
url:
|
|
1013
|
+
url: buildCheckoutRequestUrl(checkout.deliveryBagsPage, {
|
|
793
1014
|
useFormData: true
|
|
794
1015
|
}),
|
|
795
1016
|
method: 'POST',
|
|
@@ -802,7 +1023,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
802
1023
|
Record<string, number>
|
|
803
1024
|
>({
|
|
804
1025
|
query: (options) => ({
|
|
805
|
-
url:
|
|
1026
|
+
url: buildCheckoutRequestUrl(checkout.setAttributeBasedShippingOption, {
|
|
806
1027
|
useFormData: true
|
|
807
1028
|
}),
|
|
808
1029
|
method: 'POST',
|
|
@@ -821,7 +1042,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
821
1042
|
{ extra_field: ExtraField }
|
|
822
1043
|
>({
|
|
823
1044
|
query: ({ extra_field }) => ({
|
|
824
|
-
url:
|
|
1045
|
+
url: buildCheckoutRequestUrl(checkout.setOrderSelectionPage, {
|
|
825
1046
|
useFormData: true
|
|
826
1047
|
}),
|
|
827
1048
|
method: 'POST',
|
|
@@ -832,16 +1053,16 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
832
1053
|
}),
|
|
833
1054
|
fetchLoyaltyData: build.query<CheckoutResponse, void>({
|
|
834
1055
|
query: () => ({
|
|
835
|
-
url:
|
|
1056
|
+
url: buildCheckoutRequestUrl(checkout.loyaltyCardPage, {
|
|
836
1057
|
accept: 'application/json',
|
|
837
1058
|
contentType: 'application/json'
|
|
838
1059
|
}),
|
|
839
1060
|
method: 'GET'
|
|
840
1061
|
})
|
|
841
1062
|
}),
|
|
842
|
-
setLoyaltyData: build.mutation<CheckoutResponse, number>({
|
|
1063
|
+
setLoyaltyData: build.mutation<CheckoutResponse, number | string>({
|
|
843
1064
|
query: (amount) => ({
|
|
844
|
-
url:
|
|
1065
|
+
url: buildCheckoutRequestUrl(checkout.loyaltyCardPage, {
|
|
845
1066
|
useFormData: true
|
|
846
1067
|
}),
|
|
847
1068
|
method: 'POST',
|
|
@@ -852,7 +1073,7 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
852
1073
|
}),
|
|
853
1074
|
sendSms: build.mutation<CheckoutResponse, SendSmsType>({
|
|
854
1075
|
query: (body) => ({
|
|
855
|
-
url:
|
|
1076
|
+
url: buildCheckoutRequestUrl(checkout.sendSmsPage, {
|
|
856
1077
|
useFormData: true
|
|
857
1078
|
}),
|
|
858
1079
|
method: 'POST',
|
|
@@ -861,12 +1082,27 @@ export const checkoutApi = api.injectEndpoints({
|
|
|
861
1082
|
}),
|
|
862
1083
|
verifySms: build.mutation<CheckoutResponse, VerifySmsType>({
|
|
863
1084
|
query: (body) => ({
|
|
864
|
-
url:
|
|
1085
|
+
url: buildCheckoutRequestUrl(checkout.verifySmsPage, {
|
|
865
1086
|
useFormData: true
|
|
866
1087
|
}),
|
|
867
1088
|
method: 'POST',
|
|
868
1089
|
body
|
|
869
1090
|
})
|
|
1091
|
+
}),
|
|
1092
|
+
saveSampleProducts: build.mutation<CheckoutResponse, number[] | undefined>({
|
|
1093
|
+
query: (products = []) => {
|
|
1094
|
+
const formData = new FormData();
|
|
1095
|
+
|
|
1096
|
+
products.forEach((product) => {
|
|
1097
|
+
formData.append('sample_products', String(product));
|
|
1098
|
+
});
|
|
1099
|
+
|
|
1100
|
+
return {
|
|
1101
|
+
url: buildCheckoutRequestUrl(checkout.saveSampleProducts),
|
|
1102
|
+
method: 'POST',
|
|
1103
|
+
body: formData
|
|
1104
|
+
};
|
|
1105
|
+
}
|
|
870
1106
|
})
|
|
871
1107
|
}),
|
|
872
1108
|
overrideExisting: false
|
|
@@ -914,5 +1150,6 @@ export const {
|
|
|
914
1150
|
useSetWalletCompletePageMutation,
|
|
915
1151
|
useSendSmsMutation,
|
|
916
1152
|
useVerifySmsMutation,
|
|
917
|
-
useResetCheckoutStateQuery
|
|
1153
|
+
useResetCheckoutStateQuery,
|
|
1154
|
+
useSaveSampleProductsMutation
|
|
918
1155
|
} = checkoutApi;
|