@wearejh/m2-pwa-adyen 0.39.1 → 0.45.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 CHANGED
@@ -3,6 +3,94 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [0.45.0](https://github.com/WeareJH/mage-mono/compare/v0.44.0...v0.45.0) (2026-01-08)
7
+
8
+ **Note:** Version bump only for package @wearejh/m2-pwa-adyen
9
+
10
+
11
+
12
+
13
+
14
+ # [0.44.0](https://github.com/WeareJH/mage-mono/compare/v0.39.1...v0.44.0) (2026-01-08)
15
+
16
+
17
+ ### Bug Fixes
18
+
19
+ * only use node 12 and regenerate lockfiles ([61356b5](https://github.com/WeareJH/mage-mono/commit/61356b514f6dfc99814f7c108115c4c24bcc0a57))
20
+
21
+
22
+ ### Features
23
+
24
+ * **WOOD-3014:** Adyen upgrade ([e22eca3](https://github.com/WeareJH/mage-mono/commit/e22eca391e293d0241e031e3769e5a27078af99e))
25
+
26
+
27
+
28
+
29
+
30
+ # [0.43.0](https://github.com/WeareJH/mage-mono/compare/v0.39.1...v0.43.0) (2026-01-08)
31
+
32
+
33
+ ### Bug Fixes
34
+
35
+ * only use node 12 and regenerate lockfiles ([61356b5](https://github.com/WeareJH/mage-mono/commit/61356b514f6dfc99814f7c108115c4c24bcc0a57))
36
+
37
+
38
+ ### Features
39
+
40
+ * **WOOD-3014:** Adyen upgrade ([e22eca3](https://github.com/WeareJH/mage-mono/commit/e22eca391e293d0241e031e3769e5a27078af99e))
41
+
42
+
43
+
44
+
45
+
46
+ # [0.42.0](https://github.com/WeareJH/mage-mono/compare/v0.39.1...v0.42.0) (2026-01-08)
47
+
48
+
49
+ ### Bug Fixes
50
+
51
+ * only use node 12 and regenerate lockfiles ([61356b5](https://github.com/WeareJH/mage-mono/commit/61356b514f6dfc99814f7c108115c4c24bcc0a57))
52
+
53
+
54
+ ### Features
55
+
56
+ * **WOOD-3014:** Adyen upgrade ([e22eca3](https://github.com/WeareJH/mage-mono/commit/e22eca391e293d0241e031e3769e5a27078af99e))
57
+
58
+
59
+
60
+
61
+
62
+ # [0.41.0](https://github.com/WeareJH/mage-mono/compare/v0.39.1...v0.41.0) (2026-01-08)
63
+
64
+
65
+ ### Bug Fixes
66
+
67
+ * only use node 12 and regenerate lockfiles ([61356b5](https://github.com/WeareJH/mage-mono/commit/61356b514f6dfc99814f7c108115c4c24bcc0a57))
68
+
69
+
70
+ ### Features
71
+
72
+ * **WOOD-3014:** Adyen upgrade ([e22eca3](https://github.com/WeareJH/mage-mono/commit/e22eca391e293d0241e031e3769e5a27078af99e))
73
+
74
+
75
+
76
+
77
+
78
+ # [0.40.0](https://github.com/WeareJH/mage-mono/compare/v0.39.1...v0.40.0) (2026-01-08)
79
+
80
+
81
+ ### Bug Fixes
82
+
83
+ * only use node 12 and regenerate lockfiles ([61356b5](https://github.com/WeareJH/mage-mono/commit/61356b514f6dfc99814f7c108115c4c24bcc0a57))
84
+
85
+
86
+ ### Features
87
+
88
+ * **WOOD-3014:** Adyen upgrade ([e22eca3](https://github.com/WeareJH/mage-mono/commit/e22eca391e293d0241e031e3769e5a27078af99e))
89
+
90
+
91
+
92
+
93
+
6
94
  ## [0.39.1](https://github.com/WeareJH/mage-mono/compare/v0.39.0...v0.39.1) (2025-11-12)
7
95
 
8
96
  **Note:** Version bump only for package @wearejh/m2-pwa-adyen
@@ -1,6 +1,7 @@
1
1
  import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react';
2
2
  import { shallowEqual, useDispatch, useSelector } from 'react-redux';
3
3
  import { AppendState as CheckoutState } from '@wearejh/m2-pwa-checkout/lib/checkout.actions';
4
+ import { Core, CoreConfiguration } from '@adyen/adyen-web';
4
5
 
5
6
  import { ActionTypes, AdyenMessage } from './adyen.actions';
6
7
  import { initialState as initialStoreState } from './adyen.reducer';
@@ -134,7 +135,7 @@ export function AdyenProvider(props: AdyenProviderProps) {
134
135
  const currency = checkoutTotalsState?.base_currency_code ?? 'GBP';
135
136
  const price = checkoutTotalsState?.grand_total ?? 0;
136
137
 
137
- const adyenCheckoutConfig = useMemo(
138
+ const adyenCheckoutConfig = useMemo<CoreConfiguration>(
138
139
  () => ({
139
140
  ...checkoutConfig,
140
141
  amount: {
@@ -174,39 +175,38 @@ export function AdyenProvider(props: AdyenProviderProps) {
174
175
  [checkoutConfig, currency, price],
175
176
  );
176
177
 
177
- /**
178
- * The Adyen NPM package needs to fetched
179
- * client-side only, as it doesn't work
180
- * with server-side rendering.
181
- *
182
- * @link https://github.com/Adyen/adyen-web/issues/902
183
- */
184
- // const AdyenCheckout = useMemo(() => {
185
- // const AdyenCheckout = new (window as any).AdyenCheckout;
186
- // return AdyenCheckout;
187
- // }, []);
188
-
189
178
  /**
190
179
  * `AdyenCheckout` singleton instance.
180
+ * In v6, AdyenCheckout() is async and accessed via window.AdyenWeb
191
181
  *
192
- * @link https://docs.adyen.com/online-payments/components-web/#step-2-add-components
182
+ * @link https://docs.adyen.com/online-payments/upgrade-your-integration/upgrade-to-web-v6/from-v4?tab=component-step1_2
193
183
  */
194
- const adyenCheckout: AdyenCheckout | undefined = useMemo(() => {
195
- // const hasSettings = Object.keys(checkoutConfig).length > 0;
184
+ const [adyenCheckout, setAdyenCheckout] = useState<AdyenCheckout | undefined>(undefined);
196
185
 
197
- const AdyenCheckout = (window as any).AdyenCheckout;
186
+ useEffect(() => {
187
+ const initAdyenCheckout = async () => {
188
+ const AdyenCheckout = (window as any).AdyenWeb?.AdyenCheckout as
189
+ | ((props: CoreConfiguration) => Promise<Core>)
190
+ | undefined;
198
191
 
199
- if (!AdyenCheckout) {
200
- return null;
201
- }
192
+ if (!AdyenCheckout) {
193
+ return;
194
+ }
195
+
196
+ dispatch(AdyenMessage(ActionTypes.SetStep, AdyenSteps.CreatingAdyenCheckoutInstance));
202
197
 
203
- dispatch(AdyenMessage(ActionTypes.SetStep, AdyenSteps.CreatingAdyenCheckoutInstance));
198
+ try {
199
+ const checkout = await AdyenCheckout(adyenCheckoutConfig);
204
200
 
205
- const adyenCheckout = new AdyenCheckout(adyenCheckoutConfig);
201
+ dispatch(AdyenMessage(ActionTypes.SetStep, AdyenSteps.Ready));
206
202
 
207
- dispatch(AdyenMessage(ActionTypes.SetStep, AdyenSteps.Ready));
203
+ setAdyenCheckout(checkout);
204
+ } catch (error) {
205
+ console.error('Failed to initialize Adyen Checkout:', error);
206
+ }
207
+ };
208
208
 
209
- return adyenCheckout;
209
+ initAdyenCheckout();
210
210
  }, [adyenCheckoutConfig, dispatch]);
211
211
 
212
212
  const paymentFormSubmit = useCallback(() => {
@@ -233,36 +233,42 @@ export function AdyenProvider(props: AdyenProviderProps) {
233
233
 
234
234
  const [availiablePaymentMethods, setAvailiablePaymentMethods] = useState<any[]>([]);
235
235
 
236
- const getAvailiablePaymentMethods = useCallback(
237
- async () =>
238
- Promise.all(
239
- supportedPaymentMethods.map(async (paymentMethod) => {
240
- switch (paymentMethod.type) {
241
- case PaymentMethodTypes.ApplePay:
242
- try {
243
- await adyenCheckout?.create('applepay').isAvailable();
244
-
245
- return paymentMethod;
246
- } catch {}
247
- break;
236
+ const getAvailiablePaymentMethods = useCallback(async () => {
237
+ if (!adyenCheckout) {
238
+ return [];
239
+ }
248
240
 
249
- case PaymentMethodTypes.GooglePay:
250
- try {
251
- await adyenCheckout?.create('paywithgoogle').isAvailable();
241
+ const { ApplePay, GooglePay } = (window as any).AdyenWeb;
252
242
 
243
+ return Promise.all(
244
+ supportedPaymentMethods.map(async (paymentMethod) => {
245
+ switch (paymentMethod.type) {
246
+ case PaymentMethodTypes.ApplePay:
247
+ try {
248
+ if (ApplePay) {
249
+ await new ApplePay(adyenCheckout).isAvailable();
250
+ return paymentMethod;
251
+ }
252
+ } catch {}
253
+ break;
254
+
255
+ case PaymentMethodTypes.GooglePay:
256
+ try {
257
+ if (GooglePay) {
258
+ await new GooglePay(adyenCheckout).isAvailable();
253
259
  return paymentMethod;
254
- } catch {}
255
- break;
260
+ }
261
+ } catch {}
262
+ break;
256
263
 
257
- default:
258
- return paymentMethod;
259
- }
264
+ default:
265
+ return paymentMethod;
266
+ }
260
267
 
261
- return undefined;
262
- }),
263
- ),
264
- [adyenCheckout, supportedPaymentMethods],
265
- );
268
+ return undefined;
269
+ }),
270
+ );
271
+ }, [adyenCheckout, supportedPaymentMethods]);
266
272
 
267
273
  useEffect(() => {
268
274
  getAvailiablePaymentMethods()
@@ -355,11 +361,3 @@ export function useAdyen() {
355
361
  // ======
356
362
  // Hook End
357
363
  // ======
358
-
359
- // ======
360
- // Utils Start
361
- // ======
362
-
363
- // ======
364
- // Utils End
365
- // ======
@@ -3,7 +3,7 @@ import React, { useMemo } from 'react';
3
3
  import { GiftCardTypes, PaymentMethodTypes } from './adyen.types';
4
4
  import { ApplePay } from './paymentMethods/ApplePay/ApplePay';
5
5
  import { Card } from './paymentMethods/Card/Card';
6
- import { GooglePayMethod } from './paymentMethods/GooglePay/GooglePay';
6
+ import { GooglePay } from './paymentMethods/GooglePay/GooglePay';
7
7
  import { Klarna } from './paymentMethods/Klarna/Klarna';
8
8
  import { KlarnaOverTime } from './paymentMethods/Klarna/KlarnaOverTime';
9
9
  import { KlarnaPayNow } from './paymentMethods/Klarna/KlarnaPayNow';
@@ -38,7 +38,7 @@ export function PaymentMethodHandler(props: PaymentMethodHandlerProps) {
38
38
  return <Card />;
39
39
 
40
40
  case PaymentMethodTypes.GooglePay:
41
- return <GooglePayMethod />;
41
+ return <GooglePay />;
42
42
 
43
43
  case PaymentMethodTypes.Klarna:
44
44
  return <Klarna />;
@@ -1,7 +1,5 @@
1
- import Core from '@adyen/adyen-web/dist/types/core';
2
- import type { PaymentMethodsResponse } from '@adyen/adyen-web/dist/types/core/ProcessResponse/PaymentMethodsResponse/types';
3
- import type { CoreOptions } from '@adyen/adyen-web/dist/types/core/types';
4
- import type { PaymentAction, PaymentMethod } from '@adyen/adyen-web/dist/types/types';
1
+ import { Core, CoreConfiguration } from '@adyen/adyen-web';
2
+ import type { PaymentAction, PaymentMethodsResponse, RawPaymentMethod } from '@adyen/adyen-web';
5
3
  import { DataStatus, Message } from '@wearejh/m2-pwa-engine/lib/types';
6
4
 
7
5
  /**
@@ -30,7 +28,7 @@ export type AdyenCheckout = Core;
30
28
  /**
31
29
  * Options used to configure the `AdyenCheckout`
32
30
  */
33
- export type AdyenCheckoutConfig = CoreOptions;
31
+ export type AdyenCheckoutConfig = CoreConfiguration;
34
32
 
35
33
  /**
36
34
  * The internal Adyen error action.
@@ -327,7 +325,7 @@ export interface Store {
327
325
  */
328
326
  selectedPaymentMethod: PaymentMethodTypes;
329
327
 
330
- supportedPaymentMethods: PaymentMethod[];
328
+ supportedPaymentMethods: RawPaymentMethod[];
331
329
 
332
330
  status: DataStatus;
333
331
 
@@ -353,6 +351,6 @@ export interface MagentoAdyenPaymentMethodsQueryResponse {
353
351
  paymentMethodsResponse: MagentoAdyenPaymentMethodsResponseObject;
354
352
  }
355
353
 
356
- export type AdyenPaymentMethod = PaymentMethod & {
354
+ export type AdyenPaymentMethod = RawPaymentMethod & {
357
355
  brand?: GiftCardTypes | string;
358
356
  };
@@ -0,0 +1,107 @@
1
+ # Adyen Docs
2
+
3
+ ## AdyenProvider
4
+
5
+ A React context provider that initializes and manages the Adyen checkout instance, payment methods, and payment flow state.
6
+
7
+ ### Key Features
8
+ * Adyen Checkout Initialization: Creates singleton AdyenCheckout instance with configuration from Redux store
9
+ * Dynamic Pricing: Automatically converts checkout totals to minor units (e.g., £42.99 → 4299)
10
+ * Payment Method Availability: Filters supported payment methods based on browser/device compatibility (Apple Pay, Google Pay)
11
+ * Auto-reset on Error: Resets form submission state when payment is cancelled or encounters an error
12
+ * Client-side Only: Adyen Web SDK loaded client-side to avoid SSR issues
13
+
14
+ ### Context Values
15
+ Provides access to:
16
+
17
+ * adyenCheckout - Adyen checkout instance
18
+ * attemptPayment() - Submit payment with method-specific data
19
+ * checkoutConfig - Adyen configuration with currency and amount
20
+ * orderId - Current order ID
21
+ * step - Current payment flow step (Ready, Error, Cancelled, etc.)
22
+ * supportedPaymentMethods - Filtered list of available payment methods
23
+ * paymentFormSubmit() / paymentFormSubmitted - Form submission state
24
+ * waitForPaymentFormSubmit() - Async form submission handler
25
+
26
+ ### State Management
27
+ * Connects to Redux for Adyen state (action, checkoutConfig, orderId, etc.)
28
+ * Connects to Redux for checkout totals (base_currency_code, grand_total)
29
+ * Dispatches step changes during initialization
30
+
31
+ ### useAdyen
32
+ Custom hook to access the Adyen context.
33
+
34
+ ---
35
+
36
+ ## PaymentMethodHandler
37
+
38
+ A wrapper component that determines which Adyen payment method component should be rendered.
39
+
40
+ ### Behavior
41
+ * Uses a switch statement to map payment method types to their corresponding components:
42
+ * ApplePay → <ApplePay />
43
+ * Card → <Card />
44
+ * GooglePay → <GooglePay />
45
+ * Klarna variants → <Klarna />, <KlarnaOverTime />, <KlarnaPayNow />
46
+ * PayPal → <PayPal />
47
+ * Giftcard → <Giftcard brand={brand} /> (requires brand prop)
48
+
49
+ Returns null for unsupported or missing payment methods.
50
+
51
+ ---
52
+
53
+ ## Reducer, Actions, and Register
54
+ These three files form the Redux architecture for managing Adyen payment state in the application.
55
+
56
+ ### adyen.reducer.ts
57
+ Defines how the Adyen Redux store state changes in response to actions.
58
+
59
+ ### adyen.actions.ts
60
+ Defines all possible actions that can be dispatched to modify Adyen state.
61
+
62
+ ### adyen.register.ts
63
+ Registers the Adyen module with the Redux store.
64
+
65
+ ---
66
+
67
+ ## Epics
68
+
69
+ The `epics` directory contains Redux-Observable middleware that handles asynchronous side effects for the Adyen payment flow.
70
+
71
+ ### Purpose
72
+ Epics listen for specific Redux actions and perform async operations (API calls, redirects, etc.) before dispatching new actions to update the state.
73
+
74
+ ### Key Responsibilities
75
+ - **API Communication**: Handles all interactions with Magento and Adyen APIs
76
+ - **Payment Processing**: Manages the complete payment lifecycle from initialization to completion
77
+ - **Error Handling**: Catches and dispatches errors during async operations
78
+ - **State Transitions**: Orchestrates step changes during payment flows (3DS2, redirects, etc.)
79
+
80
+ ### Registered Epics
81
+ - `adyenPayment` - Processes final payment results
82
+ - `attemptPayment` - Initiates payment attempts with Magento
83
+ - `getAdyenConfig` - Fetches Adyen configuration and supported methods
84
+ - `getRedirectData` - Handles redirect return flows
85
+ - `paymentDetails` - Submits additional payment details (3DS2, redirect results)
86
+ - `onCancel` / `onError` - Manages payment cancellation and error states
87
+
88
+ These epics work together to handle the complex async flows required for different Adyen payment methods while keeping components focused on rendering UI.
89
+
90
+ ---
91
+
92
+ ## AdyenRedirect
93
+ A React component that handles the redirect flow when users return to the application after completing payment with redirect-based methods (e.g., iDEAL, Klarna, PayPal).
94
+
95
+ ### Payment Flow
96
+ * Initialize (AdyenSteps.Init): Component mounts and dispatches GetRedirectData action with the redirect result
97
+ * Process (AdyenSteps.ProcessRedirect): Once order ID is restored from session, dispatches ProcessPaymentDetails action with redirect parameters
98
+ * The getRedirectData and paymentDetails epics handle the actual API communication with Adyen
99
+
100
+ ### Key Features
101
+ * Two-stage processing: Waits for order restoration before processing payment details
102
+ * State-driven: Uses step from useAdyen to control flow progression
103
+ * Automatic: Executes on mount without user interaction
104
+ * Empty render: Displays nothing (parent handles loading states)
105
+
106
+ ### Use Case
107
+ This component is rendered on the redirect return URL (e.g., /checkout/adyen/return) after users complete payment in a third-party interface and are redirected back to your application.
@@ -0,0 +1,138 @@
1
+ ```mermaid
2
+ ---
3
+ config:
4
+ theme: redux
5
+ ---
6
+ sequenceDiagram
7
+ participant User
8
+ participant PaymentMethodHandler
9
+ participant PaymentComponent as Payment Component<br/>(e.g., ApplePay, Card, PayPal)
10
+ participant AdyenProvider
11
+ participant AdyenCheckout as Adyen Web SDK
12
+ participant Redux
13
+ participant Epic as Redux Epic
14
+ participant MagentoAPI as Magento API
15
+ participant AdyenAPI as Adyen API
16
+
17
+ Note over User,AdyenAPI: 1. INITIALIZATION PHASE
18
+
19
+ User->>PaymentMethodHandler: Navigate to checkout
20
+ PaymentMethodHandler->>Redux: Dispatch GetAdyenConfig
21
+ Redux->>Epic: getAdyenConfig epic triggered
22
+ Epic->>MagentoAPI: Fetch Adyen configuration
23
+ MagentoAPI-->>Epic: Return config + supported methods
24
+ Epic->>Redux: Store config & methods
25
+
26
+ Redux->>AdyenProvider: Subscribe to state changes
27
+ AdyenProvider->>AdyenProvider: Create AdyenCheckout instance
28
+ AdyenProvider->>Redux: Dispatch SetStep(CreatingAdyenCheckoutInstance)
29
+ AdyenProvider->>AdyenCheckout: new AdyenCheckout(config)
30
+ AdyenCheckout-->>AdyenProvider: Return checkout instance
31
+ AdyenProvider->>Redux: Dispatch SetStep(Ready)
32
+
33
+ AdyenProvider->>AdyenProvider: Filter payment methods<br/>(check Apple Pay/Google Pay availability)
34
+ AdyenProvider->>PaymentMethodHandler: Provide supportedPaymentMethods
35
+
36
+ PaymentMethodHandler->>PaymentComponent: Render available methods
37
+ PaymentComponent->>AdyenCheckout: create('applepay'|'card'|etc.)
38
+ AdyenCheckout-->>PaymentComponent: Return component instance
39
+ PaymentComponent->>PaymentComponent: Mount payment UI
40
+ PaymentComponent-->>User: Display payment button/form
41
+
42
+ Note over User,AdyenAPI: 2. PAYMENT ATTEMPT PHASE
43
+
44
+ User->>PaymentComponent: Click Pay button
45
+ PaymentComponent->>PaymentComponent: Validate input
46
+
47
+ alt Apple Pay / Google Pay (Redirect Flow)
48
+ PaymentComponent->>AdyenCheckout: Show Apple Pay sheet
49
+ User->>AdyenCheckout: Authorize payment
50
+ AdyenCheckout-->>PaymentComponent: onAuthorized(data)
51
+ PaymentComponent->>AdyenProvider: paymentFormSubmit()
52
+ AdyenProvider->>Redux: Trigger parent form submit
53
+ PaymentComponent->>AdyenProvider: waitForPaymentFormSubmit()
54
+ AdyenProvider-->>PaymentComponent: Promise resolves
55
+ PaymentComponent->>AdyenProvider: attemptPayment({state, magentoPaymentType})
56
+ else Card / Standard Flow
57
+ PaymentComponent->>PaymentComponent: onSubmit handler
58
+ PaymentComponent->>AdyenProvider: attemptPayment({state, magentoPaymentType})
59
+ end
60
+
61
+ Note over User,AdyenAPI: 3. ORDER CREATION PHASE
62
+
63
+ AdyenProvider->>Redux: Dispatch AttemptPayment action
64
+ Redux->>Epic: attemptPayment epic triggered
65
+ Epic->>MagentoAPI: POST /checkout/payment<br/>(create order with payment data)
66
+ MagentoAPI->>MagentoAPI: Create order
67
+ MagentoAPI->>AdyenAPI: Submit payment to Adyen
68
+ AdyenAPI-->>MagentoAPI: Return payment response
69
+ MagentoAPI-->>Epic: Return { action, orderId, resultCode }
70
+ Epic->>Redux: Store orderId & action
71
+
72
+ Note over User,AdyenAPI: 4. PAYMENT PROCESSING PHASE
73
+
74
+ alt 3DS2 Authentication Required
75
+ Epic->>Redux: Dispatch SetStep(ThreeDS2)
76
+ Redux->>AdyenProvider: step = ThreeDS2
77
+ AdyenProvider->>PaymentComponent: Re-render with action
78
+ PaymentComponent->>AdyenCheckout: createFromAction(action)
79
+ AdyenCheckout-->>User: Display 3DS2 challenge
80
+ User->>AdyenCheckout: Complete authentication
81
+ AdyenCheckout->>PaymentComponent: onAdditionalDetails(data)
82
+ PaymentComponent->>Redux: Dispatch ProcessPaymentDetails
83
+ Redux->>Epic: paymentDetails epic triggered
84
+ Epic->>MagentoAPI: POST /payment-details<br/>(submit 3DS2 result)
85
+ MagentoAPI->>AdyenAPI: Submit details to Adyen
86
+ AdyenAPI-->>MagentoAPI: Return final result
87
+ MagentoAPI-->>Epic: Return resultCode
88
+ Epic->>Redux: Dispatch AdyenPayment(response)
89
+
90
+ else Redirect Payment (Klarna, iDEAL, PayPal)
91
+ Epic->>Redux: Dispatch SetStep(Redirect)
92
+ Redux->>User: Redirect to Adyen/Partner URL
93
+ User->>AdyenAPI: Complete payment externally
94
+ AdyenAPI-->>User: Redirect back with redirectResult
95
+ User->>PaymentMethodHandler: Return to /checkout/adyen/return
96
+ PaymentMethodHandler->>PaymentComponent: Render AdyenRedirect
97
+ PaymentComponent->>Redux: Dispatch GetRedirectData(redirectResult)
98
+ Redux->>Epic: getRedirectData epic triggered
99
+ Epic->>MagentoAPI: Restore order session
100
+ MagentoAPI-->>Epic: Return orderId
101
+ Epic->>Redux: Store orderId
102
+ Redux->>AdyenProvider: step = ProcessRedirect
103
+ AdyenProvider->>PaymentComponent: Re-render
104
+ PaymentComponent->>Redux: Dispatch ProcessPaymentDetails
105
+ Epic->>MagentoAPI: POST /payment-details<br/>(submit redirect result)
106
+ MagentoAPI->>AdyenAPI: Verify payment
107
+ AdyenAPI-->>MagentoAPI: Return final result
108
+ MagentoAPI-->>Epic: Return resultCode
109
+ Epic->>Redux: Dispatch AdyenPayment(response)
110
+
111
+ else Instant Payment (No additional steps)
112
+ Epic->>Redux: Dispatch AdyenPayment(response)
113
+ end
114
+
115
+ Note over User,AdyenAPI: 5. FINALIZATION PHASE
116
+
117
+ Redux->>Epic: adyenPayment epic triggered
118
+ Epic->>Epic: Process resultCode
119
+
120
+ alt Payment Authorized
121
+ Epic->>Redux: Dispatch SetStep(Success)
122
+ Redux->>User: Redirect to success page
123
+ else Payment Refused/Error
124
+ Epic->>Redux: Dispatch SetStep(Error)
125
+ Epic->>Redux: Store error message
126
+ Redux->>AdyenProvider: step = Error
127
+ AdyenProvider->>AdyenProvider: setHasFormSubmitted(false)
128
+ AdyenProvider->>PaymentComponent: Re-render
129
+ PaymentComponent-->>User: Display error message
130
+ PaymentComponent-->>User: Allow retry
131
+ else Payment Cancelled
132
+ Epic->>Redux: Dispatch SetStep(Cancelled)
133
+ Redux->>AdyenProvider: step = Cancelled
134
+ AdyenProvider->>AdyenProvider: setHasFormSubmitted(false)
135
+ AdyenProvider->>PaymentComponent: Re-render
136
+ PaymentComponent-->>User: Allow retry
137
+ end
138
+ ```
@@ -32,7 +32,7 @@ const adyenWebComponentsApiUrl = 'https://checkoutshopper-live.adyen.com/checkou
32
32
  *
33
33
  * @url https://github.com/Adyen/adyen-web
34
34
  */
35
- const adyenWebComponentsVersion = '4.5.0';
35
+ const adyenWebComponentsVersion = '6.27.1';
36
36
 
37
37
  const CSS_FILE = `${adyenWebComponentsApiUrl}/${adyenWebComponentsVersion}/adyen.css`;
38
38
  const JS_FILE = `${adyenWebComponentsApiUrl}/${adyenWebComponentsVersion}/adyen.js`;
@@ -199,6 +199,7 @@ export function getAdyenConfig(action$: Observable<any>, state$: Observable<any>
199
199
  }
200
200
 
201
201
  const configuration: AdyenCheckoutConfig = {
202
+ countryCode: shippingAddress?.country_code || 'IE',
202
203
  clientKey,
203
204
  environment,
204
205
  paymentMethodsResponse,
@@ -1,6 +1,7 @@
1
1
  import { SimpleModal } from '@wearejh/m2-pwa-checkout/lib/components/Modal/SimpleModal';
2
2
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
3
3
  import { useDispatch } from 'react-redux';
4
+ import type { ThreeDS2Challenge as ThreeDS2ChallengeElement, ThreeDS2ChallengeConfiguration } from '@adyen/adyen-web';
4
5
 
5
6
  import { useAdyen } from '../../AdyenProvider';
6
7
  import { ActionTypes, AdyenMessage } from '../../adyen.actions';
@@ -63,7 +64,7 @@ export function ThreeDS2Challenge() {
63
64
  * from the `adyenCheckout` instance, so are
64
65
  * not necessary to redefine here.
65
66
  */
66
- const adyenChallengeConfig = useMemo(() => {
67
+ const adyenChallengeConfig = useMemo<ThreeDS2ChallengeConfiguration | undefined>(() => {
67
68
  if (paymentData && token) {
68
69
  return {
69
70
  onComplete,
@@ -92,12 +93,10 @@ export function ThreeDS2Challenge() {
92
93
  * The submit function which is called automatically
93
94
  * when the user has completed the challenge.
94
95
  */
95
- const adyenChallenge = useMemo(() => {
96
- if (adyenCheckout && adyenChallengeConfig) {
97
- return adyenCheckout.create('threeDS2Challenge', adyenChallengeConfig);
98
- }
96
+ const adyenChallenge = useMemo<ThreeDS2ChallengeElement>(() => {
97
+ const { ThreeDS2Challenge } = (window as any).AdyenWeb;
99
98
 
100
- return null;
99
+ return new ThreeDS2Challenge(adyenCheckout, adyenChallengeConfig) as ThreeDS2ChallengeElement;
101
100
  }, [adyenChallengeConfig, adyenCheckout]);
102
101
 
103
102
  /**
@@ -1,6 +1,6 @@
1
1
  import React, { useCallback, useEffect, useMemo, useRef } from 'react';
2
2
  import { useDispatch } from 'react-redux';
3
- import type ThreeDS2DeviceFingerprint from '@adyen/adyen-web/dist/types/components/ThreeDS2/ThreeDS2DeviceFingerprint';
3
+ import type { ThreeDS2DeviceFingerprint, ThreeDS2DeviceFingerprintConfiguration } from '@adyen/adyen-web';
4
4
 
5
5
  import { useAdyen } from '../../AdyenProvider';
6
6
  import { AdyenSteps } from '../../adyen.types';
@@ -51,7 +51,7 @@ export function ThreeDS2Fingerprint() {
51
51
  * from the `adyenCheckout` instance, so are
52
52
  * not necessary to redefine here.
53
53
  */
54
- const deviceFingerprintConfig = useMemo(() => {
54
+ const deviceFingerprintConfig = useMemo<ThreeDS2DeviceFingerprintConfiguration | undefined>(() => {
55
55
  if (paymentData && token) {
56
56
  return {
57
57
  onComplete,
@@ -69,6 +69,7 @@ export function ThreeDS2Fingerprint() {
69
69
  * newer flow.
70
70
  */
71
71
  useOriginalFlow: true,
72
+ showSpinner: true,
72
73
  };
73
74
  }
74
75
  }, [onError, onComplete, paymentData, token]);
@@ -76,28 +77,10 @@ export function ThreeDS2Fingerprint() {
76
77
  /**
77
78
  * Adyen device fingerprint component instance.
78
79
  */
79
- const deviceFingerprint = useMemo(() => {
80
- if (adyenCheckout && deviceFingerprintConfig) {
81
- /**
82
- * The `adyenCheckout` instance needs to be cast
83
- * as `any`, because the Adyen NPM package types
84
- * don't accept `onComplete` as a prop, which is
85
- * in consistent with the API.
86
- */
87
- const adyenCheckoutInstance = adyenCheckout as any;
80
+ const deviceFingerprint = useMemo<ThreeDS2DeviceFingerprint>(() => {
81
+ const { ThreeDS2DeviceFingerprint } = (window as any).AdyenWeb;
88
82
 
89
- const adyen3DSFingerprint = adyenCheckoutInstance.create(
90
- 'threeDS2DeviceFingerprint',
91
- deviceFingerprintConfig,
92
- );
93
-
94
- /**
95
- * Recast the device fingerprint component as
96
- * `ThreeDS2DeviceFingerprint`, so that
97
- * its typed.
98
- */
99
- return adyen3DSFingerprint as ThreeDS2DeviceFingerprint;
100
- }
83
+ return new ThreeDS2DeviceFingerprint(adyenCheckout, deviceFingerprintConfig) as ThreeDS2DeviceFingerprint;
101
84
  }, [adyenCheckout, deviceFingerprintConfig]);
102
85
 
103
86
  /**
@@ -1,5 +1,4 @@
1
- import type ApplePayElement from '@adyen/adyen-web/dist/types/components/ApplePay/ApplePay';
2
- import type { ApplePayElementProps } from '@adyen/adyen-web/dist/types/components/ApplePay/types';
1
+ import type { ApplePay as ApplePayElement, ApplePayConfiguration } from '@adyen/adyen-web';
3
2
  import React, { useCallback, useEffect, useMemo, useRef } from 'react';
4
3
  import { useDispatch } from 'react-redux';
5
4
 
@@ -90,7 +89,7 @@ export function ApplePay() {
90
89
  *
91
90
  * The Partial type sets all properties to optional.
92
91
  */
93
- const config: Partial<ApplePayElementProps> = useMemo(
92
+ const adyenApplePayConfig = useMemo<ApplePayConfiguration>(
94
93
  () => ({
95
94
  buttonColor: 'black',
96
95
  buttonType: 'buy',
@@ -105,22 +104,11 @@ export function ApplePay() {
105
104
  *
106
105
  * @link Adyen ApplePay Component Documentation: https://docs.adyen.com/payment-methods/apple-pay/web-component
107
106
  */
108
- const adyenApplePay = useMemo(() => {
109
- /**
110
- * The `adyenCheckout` instance needs to be cast
111
- * as `any`, because the Apple Pay props require
112
- * properties which will be automatically inherited
113
- * from the Adyen checkout instance.
114
- */
115
- const adyenCheckoutInstance = adyenCheckout as any;
107
+ const adyenApplePay = useMemo<ApplePayElement>(() => {
108
+ const { ApplePay } = (window as any).AdyenWeb;
116
109
 
117
- const adyenApplePay = adyenCheckoutInstance?.create('applepay', config);
118
-
119
- /**
120
- * Recast the component so that it's typed.
121
- */
122
- return adyenApplePay as ApplePayElement;
123
- }, [adyenCheckout, config]);
110
+ return new ApplePay(adyenCheckout, adyenApplePayConfig) as ApplePayElement;
111
+ }, [adyenCheckout, adyenApplePayConfig]);
124
112
 
125
113
  /**
126
114
  * Mount the Adyen ApplePay instance, when ready and availiable.
@@ -1,4 +1,4 @@
1
- import type { CardElementProps } from '@adyen/adyen-web/dist/types/components/Card/types';
1
+ import type { CardConfiguration, Card as CardElement } from '@adyen/adyen-web';
2
2
  import React, { useCallback, useEffect, useMemo, useRef } from 'react';
3
3
  import { useDispatch } from 'react-redux';
4
4
 
@@ -72,7 +72,7 @@ export function Card() {
72
72
  *
73
73
  * @link Adyen Card Component Documentation - https://docs.adyen.com/payment-methods/cards/web-component#page-introduction
74
74
  */
75
- const adyenCardConfig: CardElementProps = useMemo(
75
+ const adyenCardConfig: CardConfiguration = useMemo(
76
76
  () => ({
77
77
  onError,
78
78
  onSubmit,
@@ -85,7 +85,11 @@ export function Card() {
85
85
  *
86
86
  * @link Adyen Card Component Documentation - https://docs.adyen.com/payment-methods/cards/web-component#page-introduction
87
87
  */
88
- const adyenCard = useMemo(() => adyenCheckout?.create('card', adyenCardConfig), [adyenCheckout, adyenCardConfig]);
88
+ const adyenCard = useMemo<CardElement>(() => {
89
+ const { Card } = (window as any).AdyenWeb;
90
+
91
+ return new Card(adyenCheckout, adyenCardConfig).mount('#card') as CardElement;
92
+ }, [adyenCheckout, adyenCardConfig]);
89
93
 
90
94
  /**
91
95
  * Mount the Adyen card instance, when ready.
@@ -1,4 +1,5 @@
1
- import React, { useEffect, useRef } from 'react';
1
+ import React, { useEffect, useMemo, useRef } from 'react';
2
+ import type { Redirect as RedirectElement, RedirectConfiguration } from '@adyen/adyen-web';
2
3
 
3
4
  import { useAdyen } from '../../AdyenProvider';
4
5
  import { AdyenBrandCodes, AdyenSteps, GiftCardTypes, MagentoPaymentTypes } from '../../adyen.types';
@@ -71,6 +72,15 @@ export function Giftcard(props: GiftCardProps) {
71
72
  }
72
73
  }, [attemptPayment, paymentFormSubmitted, props.brand]);
73
74
 
75
+ const redirectConfig = useMemo<RedirectConfiguration | undefined>(() => {
76
+ if (action?.url) {
77
+ return {
78
+ type: 'redirect',
79
+ url: action.url,
80
+ };
81
+ }
82
+ }, [action?.url]);
83
+
74
84
  /**
75
85
  * Pass Magento's submit reponse to an Adyen Redirect component.
76
86
  *
@@ -80,14 +90,16 @@ export function Giftcard(props: GiftCardProps) {
80
90
  */
81
91
  useEffect(() => {
82
92
  if (action?.url && adyenCheckout && step === AdyenSteps.GiftCardRedirect && redirectContainer.current) {
83
- const redirect = adyenCheckout?.create('redirect');
93
+ const { Redirect } = (window as any).AdyenWeb;
94
+
95
+ const redirect: RedirectElement = new Redirect(adyenCheckout, redirectConfig);
84
96
 
85
97
  if (redirect) {
86
98
  redirect.mount(redirectContainer.current);
87
99
  redirect?.handleAction(action);
88
100
  }
89
101
  }
90
- }, [action, adyenCheckout, step]);
102
+ }, [action, adyenCheckout, redirectConfig, step]);
91
103
 
92
104
  /**
93
105
  * Return our component
@@ -1,5 +1,4 @@
1
- import type GooglePay from '@adyen/adyen-web/dist/types/components/GooglePay/GooglePay';
2
- import type { GooglePayProps } from '@adyen/adyen-web/dist/types/components/GooglePay/types';
1
+ import type { GooglePay as GooglePayElement, GooglePayConfiguration } from '@adyen/adyen-web';
3
2
  import React, { useCallback, useEffect, useMemo, useRef } from 'react';
4
3
  import { useDispatch } from 'react-redux';
5
4
 
@@ -28,7 +27,7 @@ import { ThreeDS2Fingerprint } from '../3DS/ThreeDS2Fingerprint';
28
27
  * @link https://docs.adyen.com/payment-methods/google-pay/web-component
29
28
  */
30
29
 
31
- export function GooglePayMethod() {
30
+ export function GooglePay() {
32
31
  const { adyenCheckout, attemptPayment, waitForPaymentFormSubmit, step } = useAdyen();
33
32
 
34
33
  /**
@@ -93,7 +92,7 @@ export function GooglePayMethod() {
93
92
  *
94
93
  * The Partial type sets all properties to optional.
95
94
  */
96
- const config: Partial<GooglePayProps> = useMemo(
95
+ const adyenGooglePayConfig: Partial<GooglePayConfiguration> = useMemo(
97
96
  () => ({
98
97
  onSubmit,
99
98
  buttonSizeMode: 'fill',
@@ -106,22 +105,11 @@ export function GooglePayMethod() {
106
105
  *
107
106
  * @link Adyen GooglePay Component Documentation: https://docs.adyen.com/payment-methods/google-pay/web-component
108
107
  */
109
- const adyenGooglePay = useMemo(() => {
110
- /**
111
- * The `adyenCheckout` instance needs to be cast
112
- * as `any`, because the Apple Pay props require
113
- * properties which will be automatically inherited
114
- * from the Adyen checkout instance.
115
- */
116
- const adyenCheckoutInstance = adyenCheckout as any;
108
+ const adyenGooglePay = useMemo<GooglePayElement>(() => {
109
+ const { GooglePay } = (window as any).AdyenWeb;
117
110
 
118
- const adyenGooglePay = adyenCheckoutInstance?.create('paywithgoogle', config);
119
-
120
- /**
121
- * Recast the component so that it's typed.
122
- */
123
- return adyenGooglePay as GooglePay;
124
- }, [adyenCheckout, config]);
111
+ return new GooglePay(adyenCheckout, adyenGooglePayConfig) as GooglePayElement;
112
+ }, [adyenCheckout, adyenGooglePayConfig]);
125
113
 
126
114
  /**
127
115
  * Mount the Adyen GooglePay instance, when ready and availiable.
@@ -1,5 +1,6 @@
1
1
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
  import { useDispatch } from 'react-redux';
3
+ import type { Klarna as KlarnaElement, KlarnaConfiguration } from '@adyen/adyen-web';
3
4
 
4
5
  import { useAdyen } from '../../AdyenProvider';
5
6
  import { AdyenBrandCodes, AdyenSteps, MagentoPaymentTypes } from '../../adyen.types';
@@ -64,8 +65,9 @@ export function Klarna() {
64
65
  * from the `adyenCheckout` instance, so are
65
66
  * not necessary to redefine here.
66
67
  */
67
- const adyenKlarnaConfig = useMemo(
68
+ const adyenKlarnaConfig = useMemo<KlarnaConfiguration>(
68
69
  () => ({
70
+ type: 'klarna',
69
71
  onError,
70
72
  onSubmit,
71
73
  }),
@@ -77,10 +79,11 @@ export function Klarna() {
77
79
  *
78
80
  * @link Adyen Klarna Component Documentation: https://docs.adyen.com/payment-methods/klarna/web-component
79
81
  */
80
- const adyenKlarna = useMemo(() => adyenCheckout?.create('klarna', adyenKlarnaConfig), [
81
- adyenCheckout,
82
- adyenKlarnaConfig,
83
- ]);
82
+ const adyenKlarna = useMemo<KlarnaElement>(() => {
83
+ const { Klarna } = (window as any).AdyenWeb;
84
+
85
+ return new Klarna(adyenCheckout, adyenKlarnaConfig) as KlarnaElement;
86
+ }, [adyenCheckout, adyenKlarnaConfig]);
84
87
 
85
88
  /**
86
89
  * Mount the Adyen Klarna instance, when ready.
@@ -118,9 +121,20 @@ export function Klarna() {
118
121
  */
119
122
  useEffect(() => {
120
123
  if (action && adyenKlarna && step === AdyenSteps.KlarnaRedirect) {
121
- adyenKlarna?.handleAction(action);
124
+ // adyenKlarnaOverTime?.handleAction(action);
125
+ if (
126
+ action.sdkData &&
127
+ typeof action.sdkData === 'object' &&
128
+ 'client_token' in action.sdkData &&
129
+ 'payment_method_category' in action.sdkData
130
+ ) {
131
+ adyenKlarna.handleAction(action as any);
132
+ } else {
133
+ console.error('Invalid Klarna action structure:', action);
134
+ onError({ message: 'Invalid Klarna payment action received' });
135
+ }
122
136
  }
123
- }, [action, adyenKlarna, step]);
137
+ }, [action, adyenKlarna, onError, step]);
124
138
 
125
139
  return (
126
140
  <div ref={klarnaContainer}>
@@ -1,5 +1,6 @@
1
1
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
  import { useDispatch } from 'react-redux';
3
+ import type { Klarna as KlarnaElement, KlarnaConfiguration } from '@adyen/adyen-web';
3
4
 
4
5
  import { useAdyen } from '../../AdyenProvider';
5
6
  import { AdyenBrandCodes, AdyenSteps, MagentoPaymentTypes } from '../../adyen.types';
@@ -74,8 +75,9 @@ export function KlarnaOverTime() {
74
75
  * from the `adyenCheckout` instance, so are
75
76
  * not necessary to redefine here.
76
77
  */
77
- const adyenKlarnaConfig = useMemo(
78
+ const adyenKlarnaConfig = useMemo<KlarnaConfiguration>(
78
79
  () => ({
80
+ type: 'klarna_account',
79
81
  onError,
80
82
  onSubmit,
81
83
  }),
@@ -87,19 +89,20 @@ export function KlarnaOverTime() {
87
89
  *
88
90
  * @link Adyen Klarna Component Documentation: https://docs.adyen.com/payment-methods/klarna/web-component
89
91
  */
90
- const adyenKlarna = useMemo(() => adyenCheckout?.create('klarna_account', adyenKlarnaConfig), [
91
- adyenCheckout,
92
- adyenKlarnaConfig,
93
- ]);
92
+ const adyenKlarnaOverTime = useMemo<KlarnaElement>(() => {
93
+ const { Klarna } = (window as any).AdyenWeb;
94
+
95
+ return new Klarna(adyenCheckout, adyenKlarnaConfig) as KlarnaElement;
96
+ }, [adyenCheckout, adyenKlarnaConfig]);
94
97
 
95
98
  /**
96
99
  * Mount the Adyen Klarna instance, when ready.
97
100
  */
98
101
  useEffect(() => {
99
- if (adyenCheckout && adyenKlarna && klarnaContainer.current) {
100
- adyenKlarna.mount(klarnaContainer.current);
102
+ if (adyenCheckout && adyenKlarnaOverTime && klarnaContainer.current) {
103
+ adyenKlarnaOverTime.mount(klarnaContainer.current);
101
104
  }
102
- }, [adyenCheckout, adyenKlarna, klarnaContainer]);
105
+ }, [adyenCheckout, adyenKlarnaOverTime, klarnaContainer]);
103
106
 
104
107
  /**
105
108
  * When the payment form has been submitted,
@@ -127,10 +130,21 @@ export function KlarnaOverTime() {
127
130
  * payment, before redirecting the user back to PWA.
128
131
  */
129
132
  useEffect(() => {
130
- if (action && adyenKlarna && step === AdyenSteps.KlarnaRedirect) {
131
- adyenKlarna?.handleAction(action);
133
+ if (action && adyenKlarnaOverTime && step === AdyenSteps.KlarnaRedirect) {
134
+ // adyenKlarnaOverTime?.handleAction(action);
135
+ if (
136
+ action.sdkData &&
137
+ typeof action.sdkData === 'object' &&
138
+ 'client_token' in action.sdkData &&
139
+ 'payment_method_category' in action.sdkData
140
+ ) {
141
+ adyenKlarnaOverTime.handleAction(action as any);
142
+ } else {
143
+ console.error('Invalid Klarna action structure:', action);
144
+ onError({ message: 'Invalid Klarna payment action received' });
145
+ }
132
146
  }
133
- }, [action, adyenKlarna, step]);
147
+ }, [action, adyenKlarnaOverTime, onError, step]);
134
148
 
135
149
  return (
136
150
  <div ref={klarnaContainer}>
@@ -1,5 +1,6 @@
1
1
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
  import { useDispatch } from 'react-redux';
3
+ import type { Klarna as KlarnaElement, KlarnaConfiguration } from '@adyen/adyen-web';
3
4
 
4
5
  import { useAdyen } from '../../AdyenProvider';
5
6
  import { AdyenBrandCodes, AdyenSteps, MagentoPaymentTypes } from '../../adyen.types';
@@ -64,8 +65,9 @@ export function KlarnaPayNow() {
64
65
  * from the `adyenCheckout` instance, so are
65
66
  * not necessary to redefine here.
66
67
  */
67
- const adyenKlarnaConfig = useMemo(
68
+ const adyenKlarnaConfig = useMemo<KlarnaConfiguration>(
68
69
  () => ({
70
+ type: 'klarna_paynow',
69
71
  onError,
70
72
  onSubmit,
71
73
  }),
@@ -77,19 +79,20 @@ export function KlarnaPayNow() {
77
79
  *
78
80
  * @link Adyen Klarna Component Documentation: https://docs.adyen.com/payment-methods/klarna/web-component
79
81
  */
80
- const adyenKlarna = useMemo(() => adyenCheckout?.create('klarna_paynow', adyenKlarnaConfig), [
81
- adyenCheckout,
82
- adyenKlarnaConfig,
83
- ]);
82
+ const adyenKlarnaPayNow = useMemo<KlarnaElement>(() => {
83
+ const { Klarna } = (window as any).AdyenWeb;
84
+
85
+ return new Klarna(adyenCheckout, adyenKlarnaConfig) as KlarnaElement;
86
+ }, [adyenCheckout, adyenKlarnaConfig]);
84
87
 
85
88
  /**
86
89
  * Mount the Adyen Klarna instance, when ready.
87
90
  */
88
91
  useEffect(() => {
89
- if (adyenCheckout && adyenKlarna && klarnaContainer.current) {
90
- adyenKlarna.mount(klarnaContainer.current);
92
+ if (adyenCheckout && adyenKlarnaPayNow && klarnaContainer.current) {
93
+ adyenKlarnaPayNow.mount(klarnaContainer.current);
91
94
  }
92
- }, [adyenCheckout, adyenKlarna, klarnaContainer]);
95
+ }, [adyenCheckout, adyenKlarnaPayNow, klarnaContainer]);
93
96
 
94
97
  /**
95
98
  * When the payment form has been submitted,
@@ -117,10 +120,21 @@ export function KlarnaPayNow() {
117
120
  * payment, before redirecting the user back to PWA.
118
121
  */
119
122
  useEffect(() => {
120
- if (action && adyenKlarna && step === AdyenSteps.KlarnaRedirect) {
121
- adyenKlarna?.handleAction(action);
123
+ if (action && adyenKlarnaPayNow && step === AdyenSteps.KlarnaRedirect) {
124
+ // adyenKlarnaOverTime?.handleAction(action);
125
+ if (
126
+ action.sdkData &&
127
+ typeof action.sdkData === 'object' &&
128
+ 'client_token' in action.sdkData &&
129
+ 'payment_method_category' in action.sdkData
130
+ ) {
131
+ adyenKlarnaPayNow.handleAction(action as any);
132
+ } else {
133
+ console.error('Invalid Klarna action structure:', action);
134
+ onError({ message: 'Invalid Klarna payment action received' });
135
+ }
122
136
  }
123
- }, [action, adyenKlarna, step]);
137
+ }, [action, adyenKlarnaPayNow, onError, step]);
124
138
 
125
139
  return (
126
140
  <div ref={klarnaContainer}>
@@ -1,5 +1,6 @@
1
1
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
2
  import { useDispatch } from 'react-redux';
3
+ import type { PayPal as PayPalElement, PayPalConfiguration } from '@adyen/adyen-web';
3
4
 
4
5
  import { useAdyen } from '../../AdyenProvider';
5
6
  import { AdyenSteps, MagentoPaymentTypes } from '../../adyen.types';
@@ -98,7 +99,7 @@ export function PayPal() {
98
99
  * from the `adyenCheckout` instance, so are
99
100
  * not necessary to redefine here.
100
101
  */
101
- const adyenPayPalConfig = useMemo(
102
+ const adyenPayPalConfig = useMemo<PayPalConfiguration>(
102
103
  () => ({
103
104
  onAdditionalDetails,
104
105
  onCancel,
@@ -124,10 +125,11 @@ export function PayPal() {
124
125
  *
125
126
  * @link Adyen PayPal Component Documentation: https://docs.adyen.com/payment-methods/paypal/web-component
126
127
  */
127
- const adyenPayPal = useMemo(() => adyenCheckout?.create('paypal', adyenPayPalConfig), [
128
- adyenCheckout,
129
- adyenPayPalConfig,
130
- ]);
128
+ const adyenPayPal = useMemo<PayPalElement>(() => {
129
+ const { PayPal } = (window as any).AdyenWeb;
130
+
131
+ return new PayPal(adyenCheckout, adyenPayPalConfig) as PayPalElement;
132
+ }, [adyenCheckout, adyenPayPalConfig]);
131
133
 
132
134
  /**
133
135
  * Mount the Adyen PayPal instance, when ready.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wearejh/m2-pwa-adyen",
3
- "version": "0.39.1",
3
+ "version": "0.45.0",
4
4
  "description": "> TODO: description",
5
5
  "author": "Shane Osbourne <shane.osbourne8@gmail.com>",
6
6
  "homepage": "",
@@ -21,14 +21,14 @@
21
21
  "@reach/dialog": "0.8.2"
22
22
  },
23
23
  "dependencies": {
24
- "@adyen/adyen-web": "5.59.0",
25
- "@wearejh/m2-pwa-cart": "^0.39.1",
26
- "@wearejh/m2-pwa-checkout": "^0.39.1",
27
- "@wearejh/m2-pwa-engine": "^0.39.1",
28
- "@wearejh/react-hooks": "^0.39.1",
29
- "@wearejh/rx-form": "^0.39.1",
30
- "@wearejh/swagger-rxjs": "^0.39.1",
24
+ "@adyen/adyen-web": "6.27.1",
25
+ "@wearejh/m2-pwa-cart": "^0.45.0",
26
+ "@wearejh/m2-pwa-checkout": "^0.45.0",
27
+ "@wearejh/m2-pwa-engine": "^0.45.0",
28
+ "@wearejh/react-hooks": "^0.45.0",
29
+ "@wearejh/rx-form": "^0.45.0",
30
+ "@wearejh/swagger-rxjs": "^0.45.0",
31
31
  "load-js": "^3.0.3"
32
32
  },
33
- "gitHead": "2c6b03d5992ff6f492c0cab6bb513d6973faa948"
33
+ "gitHead": "f22c9f8583c85902860ec49590cae76752f8d227"
34
34
  }