@akinon/next 1.107.0-rc.86 → 1.108.0-rc.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 +39 -1299
- package/__tests__/next-config.test.ts +10 -1
- package/bin/pz-prebuild.js +0 -1
- package/components/input.tsx +0 -2
- package/components/link.tsx +12 -16
- package/components/plugin-module.tsx +2 -0
- package/components/selected-payment-option-view.tsx +9 -0
- package/data/client/checkout.ts +2 -4
- package/data/server/category.ts +24 -44
- package/data/server/flatpage.ts +12 -16
- package/data/server/landingpage.ts +12 -16
- package/data/server/list.ts +13 -23
- package/data/server/special-page.ts +12 -16
- package/data/urls.ts +1 -5
- package/hocs/server/with-segment-defaults.tsx +2 -5
- package/hooks/use-localization.ts +3 -2
- package/middlewares/complete-gpay.ts +1 -2
- package/middlewares/complete-masterpass.ts +1 -2
- package/middlewares/complete-wallet.ts +179 -0
- package/middlewares/default.ts +3 -0
- package/middlewares/index.ts +2 -0
- package/middlewares/locale.ts +1 -10
- package/middlewares/redirection-payment.ts +1 -2
- package/middlewares/saved-card-redirection.ts +1 -2
- package/middlewares/three-d-redirection.ts +1 -2
- package/package.json +2 -2
- package/plugins.d.ts +11 -7
- package/plugins.js +1 -0
- package/redux/middlewares/checkout.ts +1 -5
- package/redux/middlewares/index.ts +6 -7
- package/redux/reducers/index.ts +3 -1
- package/types/commerce/order.ts +0 -1
- package/types/index.ts +0 -6
- package/utils/app-fetch.ts +2 -7
- package/utils/redirect.ts +3 -22
- package/__tests__/redirect.test.ts +0 -319
- package/api/image-proxy.ts +0 -75
- package/api/similar-product-list.ts +0 -84
- package/api/similar-products.ts +0 -120
- package/data/server/basket.ts +0 -72
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { resolve } from 'path';
|
|
2
2
|
import type { NextConfig } from 'next';
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
function findBaseDir() {
|
|
5
|
+
const insideNodeModules = __dirname.includes('node_modules');
|
|
6
|
+
|
|
7
|
+
if (insideNodeModules) {
|
|
8
|
+
return resolve(__dirname, '../../../../');
|
|
9
|
+
} else {
|
|
10
|
+
return resolve(__dirname, '../../../apps/projectzeronext');
|
|
11
|
+
}
|
|
12
|
+
}
|
|
4
13
|
|
|
5
14
|
const baseDir = findBaseDir();
|
|
6
15
|
|
package/bin/pz-prebuild.js
CHANGED
package/components/input.tsx
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
2
|
import { forwardRef, FocusEvent, useState, Ref } from 'react';
|
|
3
3
|
import { Controller } from 'react-hook-form';
|
|
4
|
-
|
|
5
|
-
// @ts-ignore
|
|
6
4
|
import { PatternFormat, PatternFormatProps } from 'react-number-format';
|
|
7
5
|
import { InputProps } from '../types';
|
|
8
6
|
import { twMerge } from 'tailwind-merge';
|
package/components/link.tsx
CHANGED
|
@@ -10,9 +10,7 @@ type LinkProps = Omit<
|
|
|
10
10
|
React.AnchorHTMLAttributes<HTMLAnchorElement>,
|
|
11
11
|
keyof NextLinkProps
|
|
12
12
|
> &
|
|
13
|
-
NextLinkProps
|
|
14
|
-
href: string;
|
|
15
|
-
};
|
|
13
|
+
NextLinkProps;
|
|
16
14
|
|
|
17
15
|
export const Link = ({ children, href, ...rest }: LinkProps) => {
|
|
18
16
|
const { locale, defaultLocaleValue, localeUrlStrategy } = useLocalization();
|
|
@@ -28,21 +26,19 @@ export const Link = ({ children, href, ...rest }: LinkProps) => {
|
|
|
28
26
|
return href;
|
|
29
27
|
}
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
return hrefWithLocale;
|
|
42
|
-
}
|
|
29
|
+
const pathnameWithoutLocale = href.replace(urlLocaleMatcherRegex, '');
|
|
30
|
+
const hrefWithLocale = `/${locale}${pathnameWithoutLocale}`;
|
|
31
|
+
|
|
32
|
+
if (localeUrlStrategy === LocaleUrlStrategy.ShowAllLocales) {
|
|
33
|
+
return hrefWithLocale;
|
|
34
|
+
} else if (
|
|
35
|
+
localeUrlStrategy === LocaleUrlStrategy.HideDefaultLocale &&
|
|
36
|
+
locale !== defaultLocaleValue
|
|
37
|
+
) {
|
|
38
|
+
return hrefWithLocale;
|
|
43
39
|
}
|
|
44
40
|
|
|
45
|
-
return href;
|
|
41
|
+
return href || '#';
|
|
46
42
|
}, [href, defaultLocaleValue, locale, localeUrlStrategy]);
|
|
47
43
|
|
|
48
44
|
return (
|
|
@@ -48,6 +48,7 @@ export enum Component {
|
|
|
48
48
|
AkifastCheckoutButton = 'CheckoutButton',
|
|
49
49
|
MultiBasket = 'MultiBasket',
|
|
50
50
|
SavedCard = 'SavedCardOption',
|
|
51
|
+
IyzicoSavedCard = 'IyzicoSavedCardOption',
|
|
51
52
|
Hepsipay = 'Hepsipay',
|
|
52
53
|
FlowPayment = 'FlowPayment'
|
|
53
54
|
}
|
|
@@ -82,6 +83,7 @@ const PluginComponents = new Map([
|
|
|
82
83
|
[Component.AkifastQuickLoginButton, Component.AkifastCheckoutButton]
|
|
83
84
|
],
|
|
84
85
|
[Plugin.MultiBasket, [Component.MultiBasket]],
|
|
86
|
+
[Plugin.SavedCard, [Component.SavedCard, Component.IyzicoSavedCard]],
|
|
85
87
|
[Plugin.SavedCard, [Component.SavedCard]],
|
|
86
88
|
[Plugin.Hepsipay, [Component.Hepsipay]],
|
|
87
89
|
[Plugin.FlowPayment, [Component.FlowPayment]]
|
|
@@ -60,6 +60,15 @@ export default function SelectedPaymentOptionView({
|
|
|
60
60
|
return typeof mod?.default === 'function'
|
|
61
61
|
? mod.default
|
|
62
62
|
: fallbackView;
|
|
63
|
+
} else if (
|
|
64
|
+
payment_option?.payment_type === 'wallet' &&
|
|
65
|
+
wallet_method === 'cybersource_uc'
|
|
66
|
+
) {
|
|
67
|
+
const mod = await import('@akinon/pz-cybersource-uc');
|
|
68
|
+
|
|
69
|
+
return typeof mod?.CyberSourceUcPaymentOption === 'function'
|
|
70
|
+
? mod.CyberSourceUcPaymentOption
|
|
71
|
+
: fallbackView;
|
|
63
72
|
}
|
|
64
73
|
|
|
65
74
|
if (
|
package/data/client/checkout.ts
CHANGED
|
@@ -35,10 +35,8 @@ import {
|
|
|
35
35
|
|
|
36
36
|
interface CheckoutResponse {
|
|
37
37
|
pre_order?: PreOrder;
|
|
38
|
-
errors
|
|
39
|
-
non_field_errors
|
|
40
|
-
sample_products?: string[];
|
|
41
|
-
[key: string]: string | string[] | undefined;
|
|
38
|
+
errors: {
|
|
39
|
+
non_field_errors: string;
|
|
42
40
|
};
|
|
43
41
|
context_list?: CheckoutContext[];
|
|
44
42
|
template_name?: string;
|
package/data/server/category.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { category, product } from '../urls';
|
|
|
5
5
|
import { Cache, CacheKey } from '../../lib/cache';
|
|
6
6
|
import { parse } from 'lossless-json';
|
|
7
7
|
import logger from '../../utils/log';
|
|
8
|
+
import { headers as nHeaders } from 'next/headers';
|
|
8
9
|
import { ServerVariables } from '../../utils/server-variables';
|
|
9
10
|
|
|
10
11
|
function getCategoryDataHandler(
|
|
@@ -17,30 +18,19 @@ function getCategoryDataHandler(
|
|
|
17
18
|
return async function () {
|
|
18
19
|
const params = generateCommerceSearchParams(searchParams);
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
headers
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
},
|
|
34
|
-
responseType: FetchResponseType.TEXT
|
|
35
|
-
});
|
|
36
|
-
} catch (error) {
|
|
37
|
-
logger.error('Failed to fetch category data', {
|
|
38
|
-
handler: 'getCategoryDataHandler',
|
|
39
|
-
pk,
|
|
40
|
-
error: error.message
|
|
41
|
-
});
|
|
42
|
-
return null;
|
|
43
|
-
}
|
|
21
|
+
const rawData = await appFetch<string>({
|
|
22
|
+
url: `${category.getCategoryByPk(pk)}${params ? params : ''}`,
|
|
23
|
+
locale,
|
|
24
|
+
currency,
|
|
25
|
+
init: {
|
|
26
|
+
headers: {
|
|
27
|
+
Accept: 'application/json',
|
|
28
|
+
'Content-Type': 'application/json',
|
|
29
|
+
...(headers ?? {})
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
responseType: FetchResponseType.TEXT
|
|
33
|
+
});
|
|
44
34
|
|
|
45
35
|
let data: GetCategoryResponse;
|
|
46
36
|
|
|
@@ -74,27 +64,17 @@ function getCategoryDataHandler(
|
|
|
74
64
|
return { data, breadcrumbData: undefined };
|
|
75
65
|
}
|
|
76
66
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
headers: {
|
|
86
|
-
Accept: 'application/json',
|
|
87
|
-
'Content-Type': 'application/json'
|
|
88
|
-
}
|
|
67
|
+
const breadcrumbData = await appFetch<any>({
|
|
68
|
+
url: product.breadcrumbUrl(menuItemModel),
|
|
69
|
+
locale,
|
|
70
|
+
currency,
|
|
71
|
+
init: {
|
|
72
|
+
headers: {
|
|
73
|
+
Accept: 'application/json',
|
|
74
|
+
'Content-Type': 'application/json'
|
|
89
75
|
}
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
logger.warn('Failed to fetch breadcrumb data', {
|
|
93
|
-
handler: 'getCategoryDataHandler',
|
|
94
|
-
pk,
|
|
95
|
-
error: error.message
|
|
96
|
-
});
|
|
97
|
-
}
|
|
76
|
+
}
|
|
77
|
+
});
|
|
98
78
|
|
|
99
79
|
return { data, breadcrumbData: breadcrumbData?.menu };
|
|
100
80
|
};
|
package/data/server/flatpage.ts
CHANGED
|
@@ -11,24 +11,20 @@ const getFlatPageDataHandler = (
|
|
|
11
11
|
headers?: Record<string, string>
|
|
12
12
|
) => {
|
|
13
13
|
return async function () {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
...(headers ?? {})
|
|
24
|
-
}
|
|
14
|
+
const data = await appFetch<FlatPage>({
|
|
15
|
+
url: flatpage.getFlatPageByPk(pk),
|
|
16
|
+
locale,
|
|
17
|
+
currency,
|
|
18
|
+
init: {
|
|
19
|
+
headers: {
|
|
20
|
+
Accept: 'application/json',
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
...(headers ?? {})
|
|
25
23
|
}
|
|
26
|
-
}
|
|
24
|
+
}
|
|
25
|
+
});
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
} catch (error) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
27
|
+
return data;
|
|
32
28
|
};
|
|
33
29
|
};
|
|
34
30
|
|
|
@@ -11,24 +11,20 @@ const getLandingPageHandler = (
|
|
|
11
11
|
headers?: Record<string, string>
|
|
12
12
|
) => {
|
|
13
13
|
return async function () {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
...(headers ?? {})
|
|
24
|
-
}
|
|
14
|
+
const data = await appFetch<LandingPage>({
|
|
15
|
+
url: landingpage.getLandingPageByPk(pk),
|
|
16
|
+
locale,
|
|
17
|
+
currency,
|
|
18
|
+
init: {
|
|
19
|
+
headers: {
|
|
20
|
+
Accept: 'application/json',
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
...(headers ?? {})
|
|
25
23
|
}
|
|
26
|
-
}
|
|
24
|
+
}
|
|
25
|
+
});
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
} catch (error) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
27
|
+
return data;
|
|
32
28
|
};
|
|
33
29
|
};
|
|
34
30
|
|
package/data/server/list.ts
CHANGED
|
@@ -16,29 +16,19 @@ const getListDataHandler = (
|
|
|
16
16
|
return async function () {
|
|
17
17
|
const params = generateCommerceSearchParams(searchParams);
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
headers
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
},
|
|
33
|
-
responseType: FetchResponseType.TEXT
|
|
34
|
-
});
|
|
35
|
-
} catch (error) {
|
|
36
|
-
logger.error('Failed to fetch list data', {
|
|
37
|
-
handler: 'getListDataHandler',
|
|
38
|
-
error: error.message
|
|
39
|
-
});
|
|
40
|
-
return null;
|
|
41
|
-
}
|
|
19
|
+
const rawData = await appFetch<string>({
|
|
20
|
+
url: `${category.list}${params}`,
|
|
21
|
+
locale,
|
|
22
|
+
currency,
|
|
23
|
+
init: {
|
|
24
|
+
headers: {
|
|
25
|
+
Accept: 'application/json',
|
|
26
|
+
'Content-Type': 'application/json',
|
|
27
|
+
...(headers ?? {})
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
responseType: FetchResponseType.TEXT
|
|
31
|
+
});
|
|
42
32
|
|
|
43
33
|
let data: GetCategoryResponse;
|
|
44
34
|
|
|
@@ -15,24 +15,20 @@ const getSpecialPageDataHandler = (
|
|
|
15
15
|
return async function () {
|
|
16
16
|
const params = generateCommerceSearchParams(searchParams);
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
...(headers ?? {})
|
|
28
|
-
}
|
|
18
|
+
const data: GetCategoryResponse = await appFetch({
|
|
19
|
+
url: `${category.getSpecialPageByPk(pk)}${params}`,
|
|
20
|
+
locale,
|
|
21
|
+
currency,
|
|
22
|
+
init: {
|
|
23
|
+
headers: {
|
|
24
|
+
Accept: 'application/json',
|
|
25
|
+
'Content-Type': 'application/json',
|
|
26
|
+
...(headers ?? {})
|
|
29
27
|
}
|
|
30
|
-
}
|
|
28
|
+
}
|
|
29
|
+
});
|
|
31
30
|
|
|
32
|
-
|
|
33
|
-
} catch (error) {
|
|
34
|
-
return null;
|
|
35
|
-
}
|
|
31
|
+
return data;
|
|
36
32
|
};
|
|
37
33
|
};
|
|
38
34
|
|
package/data/urls.ts
CHANGED
|
@@ -183,11 +183,7 @@ export const product = {
|
|
|
183
183
|
breadcrumbUrl: (menuitemmodel: string) =>
|
|
184
184
|
`/menus/generate_breadcrumb/?item=${menuitemmodel}&generator_name=menu_item`,
|
|
185
185
|
bundleProduct: (productPk: string, queryString: string) =>
|
|
186
|
-
`/bundle-product/${productPk}/?${queryString}
|
|
187
|
-
similarProducts: (params?: string) =>
|
|
188
|
-
`/similar-products${params ? `?${params}` : ''}`,
|
|
189
|
-
similarProductsList: (params?: string) =>
|
|
190
|
-
`/similar-product-list${params ? `?${params}` : ''}`
|
|
186
|
+
`/bundle-product/${productPk}/?${queryString}`
|
|
191
187
|
};
|
|
192
188
|
|
|
193
189
|
export const wishlist = {
|
|
@@ -72,13 +72,10 @@ const addRootLayoutProps = async (componentProps: RootLayoutProps) => {
|
|
|
72
72
|
const checkRedisVariables = () => {
|
|
73
73
|
const requiredVariableValues = [
|
|
74
74
|
process.env.CACHE_HOST,
|
|
75
|
-
process.env.CACHE_PORT
|
|
75
|
+
process.env.CACHE_PORT,
|
|
76
|
+
process.env.CACHE_SECRET
|
|
76
77
|
];
|
|
77
78
|
|
|
78
|
-
if (!settings.usePrettyUrlRoute) {
|
|
79
|
-
requiredVariableValues.push(process.env.CACHE_SECRET);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
79
|
if (
|
|
83
80
|
!requiredVariableValues.every((v) => v) &&
|
|
84
81
|
process.env.NODE_ENV === 'production'
|
|
@@ -4,6 +4,7 @@ import { LocalizationContext } from '../localization/provider';
|
|
|
4
4
|
import { useContext } from 'react';
|
|
5
5
|
import { setCookie, urlLocaleMatcherRegex } from '../utils';
|
|
6
6
|
import { LocaleUrlStrategy } from '../localization';
|
|
7
|
+
import { useRouter } from 'next/navigation';
|
|
7
8
|
|
|
8
9
|
export const useLocalization = () => {
|
|
9
10
|
const {
|
|
@@ -17,6 +18,8 @@ export const useLocalization = () => {
|
|
|
17
18
|
localeUrlStrategy
|
|
18
19
|
} = useContext(LocalizationContext);
|
|
19
20
|
|
|
21
|
+
const router = useRouter();
|
|
22
|
+
|
|
20
23
|
/**
|
|
21
24
|
* Sets the locale in the URL.
|
|
22
25
|
* @param locale Locale value defined in the settings.
|
|
@@ -27,8 +30,6 @@ export const useLocalization = () => {
|
|
|
27
30
|
|
|
28
31
|
let targetUrl;
|
|
29
32
|
|
|
30
|
-
setCookie('pz-locale', locale);
|
|
31
|
-
|
|
32
33
|
if (localeUrlStrategy === LocaleUrlStrategy.Subdomain) {
|
|
33
34
|
const hostParts = hostname.split('.');
|
|
34
35
|
const subDomain = hostParts[0];
|
|
@@ -148,8 +148,7 @@ const withCompleteGpay =
|
|
|
148
148
|
logger.info('Redirecting to order success page', {
|
|
149
149
|
middleware: 'complete-gpay',
|
|
150
150
|
redirectUrlWithLocale,
|
|
151
|
-
ip
|
|
152
|
-
setCookie: request.headers.get('set-cookie')
|
|
151
|
+
ip
|
|
153
152
|
});
|
|
154
153
|
|
|
155
154
|
// Using POST method while redirecting causes an error,
|
|
@@ -149,8 +149,7 @@ const withCompleteMasterpass =
|
|
|
149
149
|
logger.info('Redirecting to order success page', {
|
|
150
150
|
middleware: 'complete-masterpass',
|
|
151
151
|
redirectUrlWithLocale,
|
|
152
|
-
ip
|
|
153
|
-
setCookie: request.headers.get('set-cookie')
|
|
152
|
+
ip
|
|
154
153
|
});
|
|
155
154
|
|
|
156
155
|
// Using POST method while redirecting causes an error,
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { NextFetchEvent, NextMiddleware, NextResponse } from 'next/server';
|
|
2
|
+
import Settings from 'settings';
|
|
3
|
+
import { Buffer } from 'buffer';
|
|
4
|
+
import logger from '../utils/log';
|
|
5
|
+
import { getUrlPathWithLocale } from '../utils/localization';
|
|
6
|
+
import { PzNextRequest } from '.';
|
|
7
|
+
|
|
8
|
+
const streamToString = async (stream: ReadableStream<Uint8Array> | null) => {
|
|
9
|
+
if (stream) {
|
|
10
|
+
const chunks = [];
|
|
11
|
+
let result = '';
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
for await (const chunk of stream as any) {
|
|
15
|
+
chunks.push(Buffer.from(chunk));
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
result = Buffer.concat(chunks).toString('utf-8');
|
|
19
|
+
} catch (error) {
|
|
20
|
+
logger.error('Error while reading body stream', {
|
|
21
|
+
middleware: 'complete-wallet',
|
|
22
|
+
error
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
return null;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const withCompleteWallet =
|
|
32
|
+
(middleware: NextMiddleware) =>
|
|
33
|
+
async (req: PzNextRequest, event: NextFetchEvent) => {
|
|
34
|
+
const url = req.nextUrl.clone();
|
|
35
|
+
const ip = req.headers.get('x-forwarded-for') ?? '';
|
|
36
|
+
const sessionId = req.cookies.get('osessionid');
|
|
37
|
+
|
|
38
|
+
if (url.search.indexOf('WalletRedirectCompletePage') === -1) {
|
|
39
|
+
return middleware(req, event);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const requestUrl = `${Settings.commerceUrl}/orders/checkout/${url.search}`;
|
|
43
|
+
const requestHeaders = {
|
|
44
|
+
'X-Requested-With': 'XMLHttpRequest',
|
|
45
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
46
|
+
Cookie: req.headers.get('cookie') ?? '',
|
|
47
|
+
'x-currency': req.cookies.get('pz-currency')?.value ?? '',
|
|
48
|
+
'x-forwarded-for': ip
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
const body = await streamToString(req.body);
|
|
53
|
+
|
|
54
|
+
if (!sessionId) {
|
|
55
|
+
logger.warn(
|
|
56
|
+
'Make sure that the SESSION_COOKIE_SAMESITE environment variable is set to None in Commerce.',
|
|
57
|
+
{
|
|
58
|
+
middleware: 'complete-wallet',
|
|
59
|
+
ip
|
|
60
|
+
}
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
return NextResponse.redirect(
|
|
64
|
+
`${url.origin}${getUrlPathWithLocale(
|
|
65
|
+
'/orders/checkout/',
|
|
66
|
+
req.cookies.get('pz-locale')?.value
|
|
67
|
+
)}`,
|
|
68
|
+
303
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const request = await fetch(requestUrl, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
headers: requestHeaders,
|
|
75
|
+
body
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
logger.info('Complete Wallet payment request', {
|
|
79
|
+
requestUrl,
|
|
80
|
+
status: request.status,
|
|
81
|
+
requestHeaders,
|
|
82
|
+
ip
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const response = await request.json();
|
|
86
|
+
|
|
87
|
+
const { context_list: contextList, errors } = response;
|
|
88
|
+
const redirectionContext = contextList?.find(
|
|
89
|
+
(context) => context.page_context?.redirect_url
|
|
90
|
+
);
|
|
91
|
+
const redirectUrl = redirectionContext?.page_context?.redirect_url;
|
|
92
|
+
|
|
93
|
+
if (errors && Object.keys(errors).length) {
|
|
94
|
+
logger.error('Error while completing Wallet payment', {
|
|
95
|
+
middleware: 'complete-wallet',
|
|
96
|
+
errors,
|
|
97
|
+
requestHeaders,
|
|
98
|
+
ip
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return NextResponse.redirect(
|
|
102
|
+
`${url.origin}${getUrlPathWithLocale(
|
|
103
|
+
'/orders/checkout/',
|
|
104
|
+
req.cookies.get('pz-locale')?.value
|
|
105
|
+
)}`,
|
|
106
|
+
{
|
|
107
|
+
status: 303,
|
|
108
|
+
headers: {
|
|
109
|
+
'Set-Cookie': `pz-pos-error=${JSON.stringify(errors)}; path=/;`
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
logger.info('Order success page context list', {
|
|
116
|
+
middleware: 'complete-wallet',
|
|
117
|
+
contextList,
|
|
118
|
+
ip
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
if (!redirectUrl) {
|
|
122
|
+
logger.warn(
|
|
123
|
+
'No redirection url for order success page found in page_context. Redirecting to checkout page.',
|
|
124
|
+
{
|
|
125
|
+
middleware: 'complete-wallet',
|
|
126
|
+
requestHeaders,
|
|
127
|
+
response: JSON.stringify(response),
|
|
128
|
+
ip
|
|
129
|
+
}
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
const redirectUrlWithLocale = `${url.origin}${getUrlPathWithLocale(
|
|
133
|
+
'/orders/checkout/',
|
|
134
|
+
req.cookies.get('pz-locale')?.value
|
|
135
|
+
)}`;
|
|
136
|
+
|
|
137
|
+
return NextResponse.redirect(redirectUrlWithLocale, 303);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const redirectUrlWithLocale = `${url.origin}${getUrlPathWithLocale(
|
|
141
|
+
redirectUrl,
|
|
142
|
+
req.cookies.get('pz-locale')?.value
|
|
143
|
+
)}`;
|
|
144
|
+
|
|
145
|
+
logger.info('Redirecting to order success page', {
|
|
146
|
+
middleware: 'complete-wallet',
|
|
147
|
+
redirectUrlWithLocale,
|
|
148
|
+
ip
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Using POST method while redirecting causes an error,
|
|
152
|
+
// So we use 303 status code to change the method to GET
|
|
153
|
+
const nextResponse = NextResponse.redirect(redirectUrlWithLocale, 303);
|
|
154
|
+
|
|
155
|
+
nextResponse.headers.set(
|
|
156
|
+
'Set-Cookie',
|
|
157
|
+
request.headers.get('set-cookie') ?? ''
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
return nextResponse;
|
|
161
|
+
} catch (error) {
|
|
162
|
+
logger.error('Error while completing Wallet payment', {
|
|
163
|
+
middleware: 'complete-wallet',
|
|
164
|
+
error,
|
|
165
|
+
requestHeaders,
|
|
166
|
+
ip
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
return NextResponse.redirect(
|
|
170
|
+
`${url.origin}${getUrlPathWithLocale(
|
|
171
|
+
'/orders/checkout/',
|
|
172
|
+
req.cookies.get('pz-locale')?.value
|
|
173
|
+
)}`,
|
|
174
|
+
303
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export default withCompleteWallet;
|
package/middlewares/default.ts
CHANGED
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
withSavedCardRedirection,
|
|
13
13
|
withThreeDRedirection,
|
|
14
14
|
withUrlRedirection,
|
|
15
|
+
withCompleteWallet,
|
|
15
16
|
withWalletCompleteRedirection
|
|
16
17
|
} from '.';
|
|
17
18
|
import { urlLocaleMatcherRegex } from '../utils';
|
|
@@ -228,6 +229,7 @@ const withPzDefault =
|
|
|
228
229
|
withCompleteGpay(
|
|
229
230
|
withCompleteMasterpass(
|
|
230
231
|
withSavedCardRedirection(
|
|
232
|
+
withCompleteWallet(
|
|
231
233
|
withWalletCompleteRedirection(
|
|
232
234
|
async (
|
|
233
235
|
req: PzNextRequest,
|
|
@@ -459,6 +461,7 @@ const withPzDefault =
|
|
|
459
461
|
)
|
|
460
462
|
)
|
|
461
463
|
)
|
|
464
|
+
)
|
|
462
465
|
)(req, event);
|
|
463
466
|
};
|
|
464
467
|
|
package/middlewares/index.ts
CHANGED
|
@@ -9,6 +9,7 @@ import withCompleteGpay from './complete-gpay';
|
|
|
9
9
|
import withCompleteMasterpass from './complete-masterpass';
|
|
10
10
|
import withCheckoutProvider from './checkout-provider';
|
|
11
11
|
import withSavedCardRedirection from './saved-card-redirection';
|
|
12
|
+
import withCompleteWallet from './complete-wallet';
|
|
12
13
|
import withWalletCompleteRedirection from './wallet-complete-redirection';
|
|
13
14
|
import { NextRequest } from 'next/server';
|
|
14
15
|
|
|
@@ -24,6 +25,7 @@ export {
|
|
|
24
25
|
withCompleteMasterpass,
|
|
25
26
|
withCheckoutProvider,
|
|
26
27
|
withSavedCardRedirection,
|
|
28
|
+
withCompleteWallet,
|
|
27
29
|
withWalletCompleteRedirection
|
|
28
30
|
};
|
|
29
31
|
|