@akinon/next 1.107.0-rc.86 → 1.108.0-rc.87

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 CHANGED
@@ -1,13 +1,11 @@
1
1
  # @akinon/next
2
2
 
3
- ## 1.107.0-rc.86
3
+ ## 1.108.0-rc.87
4
4
 
5
5
  ### Minor Changes
6
6
 
7
- - 4ca44c78: ZERO-3634: add register_consumer_card
8
- - 5dfeea04: ZERO-2801: Revert ZERO-2801
7
+ - 5dfeea04a: ZERO-2801: Revert ZERO-2801
9
8
  - 823d82f9: ZERO-3393: Enhance error handling in checkout middleware to ensure errors are checked for existence before processing
10
- - 28c7ea79: ZERO-3427: Refactor redirect utility to handle undefined URL and improve locale handling
11
9
  - e1aa030d: ZERO-3473: Refactor locale handling to prioritize cookie value for matched locale
12
10
  - 2d9b2b2c9: ZERO-2816: Add segment to headers
13
11
  - 5e1feca6: Revert "ZERO-3286: Add notFound handling for chunk URLs starting with \_next"
@@ -37,7 +35,6 @@
37
35
  - 65d3b862: ZERO-3054: Update headers in appFetch
38
36
  - bbe18b9ff: ZERO-2575: Fix build error
39
37
  - 4920742c2: Disable getCachedTranslations
40
- - b6e5b624: ZERO-3257: Enhance locale middleware to redirect using existing or default locale and support 303 status for POST requests
41
38
  - 7e56d6b6b: ZERO-2841: Update api tagTypes
42
39
  - d99a6a7d: ZERO-3457: Fixed the settings prop and made sure everything is customizable.
43
40
  - 33377cfd: ZERO-3267: Refactor import statement for ROUTES in error-page component
@@ -45,7 +42,6 @@
45
42
  - c480272c: ZERO-3531: Refactor checkoutApi: Remove unnecessary invalidatesTags property from POST request from sample products
46
43
  - facf1ada: ZERO-3445: Add SameSite and Secure attributes
47
44
  - eeb20bea: Revert "ZERO-3054: Refactor cache handler to use custom Redis handler and implement key hashing"
48
- - 5b500797: ZERO-3634: iyzico saved card
49
45
  - 3bf63c8a: ZERO-3286: Add notFound handling for chunk URLs starting with \_next
50
46
  - 9be2c081: ZERO-3243: Improve basket update query handling with optimistic updates
51
47
  - f7fd459b: ZERO-3445: Refactor setCookie function to include domain handling and improve cookie string construction
@@ -55,11 +51,20 @@
55
51
  - 7bd3d9928: ZERO-2801: Refactor locale middleware to handle single locale configuration
56
52
  - acd2afdf: ZERO-3431: Fix import statement for findBaseDir in next-config test
57
53
  - fdd255ee: ZERO-3054: Refactor cache handler to use custom Redis handler and implement key hashing
58
- - 49eeebfa: ZERO-2909: Add deleteCollectionItem query to wishlistApi
54
+ - 49eeebfaa: ZERO-2909: Add deleteCollectionItem query to wishlistApi
59
55
  - 3f9b8d7e7: ZERO-2761: Update plugins.js for akinon-next
60
- - 33d4d0c: ZERO-3615: remove custom not found
56
+ - 33d4d0c9: ZERO-3615: remove custom not found
61
57
  - 0e823010: ZERO-3531: Add saveSampleProducts endpoint
62
58
 
59
+ ## 1.107.0
60
+
61
+ ### Minor Changes
62
+
63
+ - 4ca44c78: ZERO-3634: add register_consumer_card
64
+ - 28c7ea79: ZERO-3427: Refactor redirect utility to handle undefined URL and improve locale handling
65
+ - b6e5b624: ZERO-3257: Enhance locale middleware to redirect using existing or default locale and support 303 status for POST requests
66
+ - 5b500797: ZERO-3634: iyzico saved card
67
+
63
68
  ## 1.106.0
64
69
 
65
70
  ### Minor Changes
@@ -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 (
@@ -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;
@@ -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
 
@@ -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
 
@@ -77,7 +77,6 @@ const withLocale =
77
77
  req.method === 'GET'
78
78
  ) {
79
79
  // Redirect to existing or default locale
80
-
81
80
  url.pathname = getUrlPathWithLocale(
82
81
  url.pathname,
83
82
  req.cookies.get('pz-locale')?.value
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@akinon/next",
3
3
  "description": "Core package for Project Zero Next",
4
- "version": "1.107.0-rc.86",
4
+ "version": "1.108.0-rc.87",
5
5
  "private": false,
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -35,7 +35,7 @@
35
35
  "set-cookie-parser": "2.6.0"
36
36
  },
37
37
  "devDependencies": {
38
- "@akinon/eslint-plugin-projectzero": "1.107.0-rc.86",
38
+ "@akinon/eslint-plugin-projectzero": "1.108.0-rc.87",
39
39
  "@babel/core": "7.26.10",
40
40
  "@babel/preset-env": "7.26.9",
41
41
  "@babel/preset-typescript": "7.27.0",
package/plugins.d.ts CHANGED
@@ -33,6 +33,18 @@ declare module '@akinon/pz-saved-card' {
33
33
 
34
34
  declare module '@akinon/pz-apple-pay' {}
35
35
 
36
+ declare module '@akinon/pz-cybersource-uc/src/redux/middleware' {
37
+ export default middleware as any;
38
+ }
39
+
40
+ declare module '@akinon/pz-cybersource-uc/src/redux/reducer' {
41
+ export default reducer as any;
42
+ }
43
+
44
+ declare module '@akinon/pz-cybersource-uc' {
45
+ export const CyberSourceUcPaymentOption: any;
46
+ }
47
+
36
48
  declare module '@akinon/pz-flow-payment' {}
37
49
 
38
50
  declare module '@akinon/pz-similar-products' {
package/plugins.js CHANGED
@@ -16,6 +16,7 @@ module.exports = [
16
16
  'pz-tabby-extension',
17
17
  'pz-apple-pay',
18
18
  'pz-tamara-extension',
19
+ 'pz-cybersource-uc',
19
20
  'pz-hepsipay',
20
21
  'pz-flow-payment'
21
22
  ];
@@ -18,13 +18,11 @@ import logger from '@akinon/next/utils/log';
18
18
 
19
19
  // Plugin middlewares
20
20
  import { savedCardMiddleware } from '@akinon/pz-saved-card';
21
+ import cyberSourceUcMiddleware from '@akinon/pz-cybersource-uc/src/redux/middleware';
21
22
 
22
- export const rtkQueryResponseHandler: Middleware =
23
- ({ dispatch }) =>
24
- (next) =>
25
- (action) => {
26
- return next(action);
27
- };
23
+ export const rtkQueryResponseHandler: Middleware = () => (next) => (action) => {
24
+ return next(action);
25
+ };
28
26
 
29
27
  export const rtkQueryErrorHandler: Middleware =
30
28
  () => (next) => async (action) => {
@@ -56,7 +54,8 @@ const middlewares = [
56
54
  contextListMiddleware,
57
55
  hepsiPayMiddleware,
58
56
  walletPaymentMiddleware,
59
- savedCardMiddleware
57
+ savedCardMiddleware,
58
+ cyberSourceUcMiddleware
60
59
  ];
61
60
 
62
61
  // Filter out any non-function middleware to ensure all middlewares are valid and executable
@@ -8,6 +8,7 @@ import { api } from '../../data/client/api';
8
8
  import { masterpassReducer } from '@akinon/pz-masterpass';
9
9
  import { otpReducer } from '@akinon/pz-otp';
10
10
  import { savedCardReducer } from '@akinon/pz-saved-card';
11
+ import cyberSourceUcReducer from '@akinon/pz-cybersource-uc/src/redux/reducer';
11
12
 
12
13
  const fallbackReducer = (state = {}) => state;
13
14
 
@@ -19,7 +20,8 @@ const reducers = {
19
20
  header: headerReducer,
20
21
  masterpass: masterpassReducer || fallbackReducer,
21
22
  otp: otpReducer || fallbackReducer,
22
- savedCard: savedCardReducer || fallbackReducer
23
+ savedCard: savedCardReducer || fallbackReducer,
24
+ cybersource_uc: cyberSourceUcReducer || fallbackReducer
23
25
  };
24
26
 
25
27
  export default reducers;
package/utils/redirect.ts CHANGED
@@ -30,10 +30,6 @@ export const redirect = (path: string, type?: RedirectType) => {
30
30
  (locale) => locale.value === currentLocaleValue
31
31
  );
32
32
 
33
- if (!currentLocale) {
34
- currentLocaleValue = Settings.localization.defaultLocaleValue;
35
- }
36
-
37
33
  const searchParams = new URLSearchParams(pageUrl.search);
38
34
 
39
35
  const callbackUrl =