@wearejh/m2-pwa-adyen 0.13.2 → 0.16.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,33 @@
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.16.0](https://github.com/WeareJH/mage-mono/compare/v0.15.0...v0.16.0) (2022-10-24)
7
+
8
+ **Note:** Version bump only for package @wearejh/m2-pwa-adyen
9
+
10
+
11
+
12
+
13
+
14
+ # [0.15.0](https://github.com/WeareJH/mage-mono/compare/v0.14.0...v0.15.0) (2022-10-13)
15
+
16
+ **Note:** Version bump only for package @wearejh/m2-pwa-adyen
17
+
18
+
19
+
20
+
21
+
22
+ # [0.14.0](https://github.com/WeareJH/mage-mono/compare/v0.13.2...v0.14.0) (2022-10-13)
23
+
24
+
25
+ ### Features
26
+
27
+ * add Giftcards via Adyen support ([#77](https://github.com/WeareJH/mage-mono/issues/77)) ([632bdbf](https://github.com/WeareJH/mage-mono/commit/632bdbf859202554296c4b47a7da067f3905e499))
28
+
29
+
30
+
31
+
32
+
6
33
  ## [0.13.2](https://github.com/WeareJH/mage-mono/compare/v0.13.0...v0.13.2) (2022-04-04)
7
34
 
8
35
  **Note:** Version bump only for package @wearejh/m2-pwa-adyen
@@ -210,6 +210,10 @@ export function AdyenProvider(props: AdyenProviderProps) {
210
210
  const attemptPayment = useCallback(
211
211
  (props: AttemptPaymentProps) => {
212
212
  const newState = {
213
+ data: {
214
+ brandCode: undefined,
215
+ type: undefined,
216
+ },
213
217
  ...props.state,
214
218
  };
215
219
 
@@ -9,7 +9,7 @@ import { useAdyen } from './AdyenProvider';
9
9
  * React component for for processing the the payment provider
10
10
  * redirection response.
11
11
  */
12
- export function AdyenRedirect(props: Pick<AdyenRedirectParams, 'redirectResult'>) {
12
+ export function AdyenRedirect(props: Omit<AdyenRedirectParams, 'orderId'>) {
13
13
  const { redirectResult } = props;
14
14
 
15
15
  const { step } = useAdyen();
@@ -39,12 +39,12 @@ export function AdyenRedirect(props: Pick<AdyenRedirectParams, 'redirectResult'>
39
39
  dispatch(
40
40
  AdyenMessage(ActionTypes.ProcessPaymentDetails, {
41
41
  details: {
42
- redirectResult,
42
+ ...props,
43
43
  },
44
44
  }),
45
45
  );
46
46
  }
47
- }, [dispatch, redirectResult, step]);
47
+ }, [dispatch, props, redirectResult, step]);
48
48
 
49
49
  return <div></div>;
50
50
  }
@@ -1,6 +1,6 @@
1
1
  import React, { useMemo } from 'react';
2
2
 
3
- import { PaymentMethodTypes } from './adyen.types';
3
+ import { GiftCardTypes, PaymentMethodTypes } from './adyen.types';
4
4
  import { ApplePay } from './paymentMethods/ApplePay/ApplePay';
5
5
  import { Card } from './paymentMethods/Card/Card';
6
6
  import { GooglePayMethod } from './paymentMethods/GooglePay/GooglePay';
@@ -8,8 +8,14 @@ import { Klarna } from './paymentMethods/Klarna/Klarna';
8
8
  import { KlarnaOverTime } from './paymentMethods/Klarna/KlarnaOverTime';
9
9
  import { KlarnaPayNow } from './paymentMethods/Klarna/KlarnaPayNow';
10
10
  import { PayPal } from './paymentMethods/PayPal/PayPal';
11
+ import { Giftcard } from './paymentMethods/Giftcard';
11
12
 
12
13
  interface PaymentMethodHandlerProps {
14
+ /**
15
+ * The type of Giftcard
16
+ */
17
+ brand?: GiftCardTypes;
18
+
13
19
  /**
14
20
  * The type of Adyen payment method.
15
21
  */
@@ -21,7 +27,7 @@ interface PaymentMethodHandlerProps {
21
27
  * payment method component should be rendered.
22
28
  */
23
29
  export function PaymentMethodHandler(props: PaymentMethodHandlerProps) {
24
- const { type } = props;
30
+ const { brand, type } = props;
25
31
 
26
32
  const render = useMemo(() => {
27
33
  switch (type) {
@@ -46,11 +52,18 @@ export function PaymentMethodHandler(props: PaymentMethodHandlerProps) {
46
52
  case PaymentMethodTypes.PayPal:
47
53
  return <PayPal />;
48
54
 
55
+ case PaymentMethodTypes.Giftcard:
56
+ if (brand) {
57
+ return <Giftcard brand={brand} />;
58
+ }
59
+
60
+ return null;
61
+
49
62
  case PaymentMethodTypes.None:
50
63
  default:
51
64
  return null;
52
65
  }
53
- }, [type]);
66
+ }, [brand, type]);
54
67
 
55
68
  return render;
56
69
  }
package/lib/README.md CHANGED
@@ -20,6 +20,7 @@
20
20
  This package supports the following payment methods:
21
21
 
22
22
  - [Apple Pay](paymentMethods/ApplePay)
23
+ - [GiftCard](paymentMethods/Giftcard)
23
24
  - [Card](paymentMethods/Card)
24
25
  - [3DSecure 1](paymentMethods/Card/ThreeDS1Redirect.tsx)
25
26
  - [3DSecure 2](paymentMethods/Card/ThreeDS2Challenge.tsx)
@@ -22,6 +22,7 @@ export enum AdyenActionTypes {
22
22
 
23
23
  export enum AdyenBrandCodes {
24
24
  Klarna = 'klarna',
25
+ Giftcard = 'giftcard',
25
26
  }
26
27
 
27
28
  export type AdyenCheckout = Core;
@@ -82,8 +83,12 @@ export interface AdyenPaymentAction extends PaymentAction {
82
83
  }
83
84
 
84
85
  export interface AdyenRedirectParams {
86
+ merchantReference?: string;
85
87
  orderId?: string;
88
+ payload?: string;
86
89
  redirectResult?: string;
90
+ resultCode?: string;
91
+ type?: string;
87
92
  }
88
93
 
89
94
  /**
@@ -197,6 +202,59 @@ export enum PaymentMethodTypes {
197
202
  KlarnaPayNow = 'klarna_paynow',
198
203
  None = 'none',
199
204
  PayPal = 'paypal',
205
+ Giftcard = 'giftcard',
206
+ }
207
+
208
+ /**
209
+ * Type of Adyen Giftcards
210
+ *
211
+ * @link https://docs.adyen.com/payment-methods/gift-cards
212
+ */
213
+ export enum GiftCardTypes {
214
+ Auriga = 'auriga',
215
+ BabyGiftCard = 'babygiftcard',
216
+ BloemenGiftcard = 'bloemengiftcard',
217
+ Cashcom = 'cashcomgiftcard',
218
+ EagleEye = 'eagleeye_voucher',
219
+ EnterCard = 'entercard',
220
+ ExpertCadeaukaart = 'expertgiftcard',
221
+ Fashiocheque = 'fashioncheque',
222
+ FijnCadeau = 'fijncadeau',
223
+ Fiserv = 'valuelink',
224
+ FleuropBloemenbon = 'fleuropbloemenbon',
225
+ FonqGiftcard = 'fonqgiftcard',
226
+ GallAndGall = 'gallgall',
227
+ GiveX = 'givex',
228
+ Hallmark = 'hallmarkcard',
229
+ iGive = 'igive',
230
+ Ikano = 'ikano',
231
+ Illicado = 'prosodie_illicado',
232
+ KadoWerekeld = 'kadowereld',
233
+ KidsCadeau = 'kidscadeau',
234
+ Kindpas = 'kindpas',
235
+ LeisureVoucher = 'leisurecard',
236
+ NationaleBioscoopbon = 'nationalebioscoopbon',
237
+ Netscard = 'netscard',
238
+ Oberthur = 'oberthur',
239
+ PatheGiftcard = 'pathegiftcard',
240
+ PayEx = 'payex',
241
+ PodiumCard = 'podiumcard',
242
+ ResursGiftCard = 'resursgiftcard',
243
+ Rotterdampas = 'rotterdampas',
244
+ Savvy = 'genericgiftcard',
245
+ Schoolspullenpas = 'schoolspullenpas',
246
+ SpareBank = 'sparebank',
247
+ SparNord = 'sparnord',
248
+ SVS = 'svs',
249
+ UniversalGiftCard = 'universalgiftcard',
250
+ ValueLink = 'valuelink',
251
+ VVVCadeaubon = 'vvvcadeaubon',
252
+ VVVGiftcard = 'vvvgiftcard',
253
+ WebshopGiftcard = 'webshopgiftcard',
254
+ WinkelCheque = 'winkelcheque',
255
+ Winterkledingpas = 'winterkledingpas',
256
+ XPonCard = 'xponcard',
257
+ YourGift = 'yourgift',
200
258
  }
201
259
 
202
260
  /**
@@ -250,3 +308,7 @@ export interface MagentoAdyenPaymentMethodsQueryResponse {
250
308
  paymentMethodsExtraDetails: MagentoAdyenPaymentMethodsExtraDetails;
251
309
  paymentMethodsResponse: MagentoAdyenPaymentMethodsResponseObject;
252
310
  }
311
+
312
+ export type AdyenPaymentMethod = PaymentMethod & {
313
+ brand?: GiftCardTypes;
314
+ };
@@ -35,21 +35,21 @@ export function adyenPayment(action$: Observable<any>, state$: Observable<any>,
35
35
 
36
36
  const payloadComposed: AdyenPayload = {
37
37
  additional_data: {
38
- brand_code: payload.brandCode,
39
- cc_type: payload.paymentMethod.brand,
40
- cvc: payload.paymentMethod.encryptedSecurityCode,
41
- expiryMonth: payload.paymentMethod.encryptedExpiryMonth,
42
- expiryYear: payload.paymentMethod.encryptedExpiryYear,
43
- java_enabled: payload.browserInfo?.javaEnabled || false,
44
- language: payload.browserInfo?.language || '',
45
- number: payload.paymentMethod.encryptedCardNumber,
46
- screen_color_depth: payload.browserInfo?.colorDepth || 0,
47
- screen_height: payload.browserInfo?.screenHeight || 0,
48
- screen_width: payload.browserInfo?.screenWidth || 0,
38
+ brand_code: payload?.brandCode,
39
+ cc_type: payload?.paymentMethod?.brand,
40
+ cvc: payload?.paymentMethod?.encryptedSecurityCode,
41
+ expiryMonth: payload?.paymentMethod?.encryptedExpiryMonth,
42
+ expiryYear: payload?.paymentMethod?.encryptedExpiryYear,
43
+ java_enabled: payload?.browserInfo?.javaEnabled || false,
44
+ language: payload?.browserInfo?.language || '',
45
+ number: payload?.paymentMethod?.encryptedCardNumber,
46
+ screen_color_depth: payload?.browserInfo?.colorDepth || 0,
47
+ screen_height: payload?.browserInfo?.screenHeight || 0,
48
+ screen_width: payload?.browserInfo?.screenWidth || 0,
49
49
  stateData: JSON.stringify(payload),
50
- timezone_offset: payload.browserInfo?.timeZoneOffset || 0,
50
+ timezone_offset: payload?.browserInfo?.timeZoneOffset || 0,
51
51
  },
52
- method: payload.type,
52
+ method: payload?.type,
53
53
  };
54
54
 
55
55
  return concat(
@@ -22,8 +22,8 @@ export function attemptPayment(action$: Observable<any>, _state$: Observable<any
22
22
  const output: AdyenSubmitParams = {
23
23
  brandCode: payload?.brandCode,
24
24
  browserInfo: payload?.browserInfo,
25
- paymentMethod: payload.paymentMethod,
26
- type: payload.type,
25
+ paymentMethod: payload?.paymentMethod,
26
+ type: payload?.type,
27
27
  };
28
28
 
29
29
  return of(AdyenMessage(ActionTypes.PaymentSubmit, output));
@@ -58,9 +58,23 @@ export function processAdyenResponse(response?: AdyenResponseParams, orderId?: s
58
58
  const paymentMethodType = action?.paymentMethodType;
59
59
 
60
60
  switch (paymentMethodType) {
61
- case PaymentMethodTypes.Card:
62
- return of(AdyenMessage(ActionTypes.ActionThreeDS1Redirect, action));
61
+ case PaymentMethodTypes.Giftcard:
62
+ return of(
63
+ /**
64
+ * Giftcards uses a redirect to process payment, so
65
+ * we need to store the users order id in
66
+ * localstorage, so that it can be restored when
67
+ * the user is returned to the site.
68
+ */
69
+ StorageMsg(StorageActions.Set, {
70
+ expiry: new Date().getTime() + ONE_DAY,
71
+ key: AdyenStorageKey.OrderId,
72
+ value: orderId,
73
+ }),
74
+ AdyenMessage(ActionTypes.ActionThreeDS1Redirect, action),
75
+ );
63
76
 
77
+ case PaymentMethodTypes.Card:
64
78
  case PaymentMethodTypes.GooglePay:
65
79
  return of(AdyenMessage(ActionTypes.ActionThreeDS1Redirect, action));
66
80
 
@@ -13,7 +13,7 @@
13
13
  ## :credit_card: Payment Process
14
14
 
15
15
  1. Mount Card component
16
- 2. User enters card details, then presseds submit button.
16
+ 2. User enters card details, then presses submit button.
17
17
  3. Payment details are sent to Magento for processing.
18
18
  4. If the payment card supports 3DS1/3DS2 (security check), the user is shown a verification popup.
19
19
  1. The verification result is passed back to Magento for processing.
@@ -26,4 +26,4 @@
26
26
  - [Adyen Card Web Component Source Code](https://github.com/Adyen/adyen-web/tree/master/packages/lib/src/components/Card) - GitHub source code for Adyen's Card component.
27
27
  - [Adyen Test Cards](https://docs.adyen.com/development-resources/test-cards/test-card-numbers#mastercard) - Card details for testing the component.
28
28
 
29
- <br/>
29
+ <br/>
@@ -0,0 +1,102 @@
1
+ import React, { useEffect, useRef } from 'react';
2
+
3
+ import { useAdyen } from '../../AdyenProvider';
4
+ import { AdyenBrandCodes, AdyenSteps, GiftCardTypes, MagentoPaymentTypes } from '../../adyen.types';
5
+
6
+ export type GiftCardProps = {
7
+ brand: GiftCardTypes;
8
+ };
9
+
10
+ /**
11
+ * Generic Giftcard component that supports the majority of Adyen giftcards.
12
+ *
13
+ * Adyen via Magento only supports Giftcards with HPP fallback.
14
+ * The 'GiftCard' web component is not currently supported. Instead we
15
+ * display a basic 'pay now' button, which sends a 'setPaymentMethod' event
16
+ * to Magento.
17
+ *
18
+ * Example flow:
19
+ * 1. Giftcard enabled in Dashboard
20
+ * 2. Displayed in UI using a basic button (not the Giftcard Web Component)
21
+ * 3. User clicks on button
22
+ * 4. API request made to Magento to set the payment method as the giftcard.
23
+ * 5. Magento returns a redirect URL
24
+ * 6. User is redirected to Adyen Hosted Payment Page (HPP) to complete
25
+ * the order.
26
+ * 7. Upon completion the User is redirected back to the site.
27
+ * 8. Request sent to Magento to check Adyen order status
28
+ * - onSuccess - Checkout complete
29
+ * - onFail - Checkout failed
30
+ *
31
+ * Note:
32
+ * Partial payments with Giftcards is handled within the HPP.
33
+ * If the Giftcard balance doesn't cover the entire order, Adyen will present
34
+ * the User with other payment methods which can be used to pay the
35
+ * remaining balance.
36
+ */
37
+ export function Giftcard(props: GiftCardProps) {
38
+ /**
39
+ * Get Adyen components/functions
40
+ */
41
+ const { adyenCheckout, action, attemptPayment, paymentFormSubmitted, step } = useAdyen();
42
+
43
+ /**
44
+ * Setup a container that the Adyen component will be mounted on
45
+ */
46
+ const giftcardContainer = useRef<HTMLDivElement>(null);
47
+
48
+ /**
49
+ * Setup a container that the Adyen redirect component will be mounted on.
50
+ */
51
+ const redirectContainer = useRef<HTMLDivElement>(null);
52
+
53
+ /**
54
+ * When the payment form has been submitted, set the Giftcard as the
55
+ * chosen payment method for the order.
56
+ */
57
+ useEffect(() => {
58
+ if (paymentFormSubmitted) {
59
+ attemptPayment({
60
+ brandCode: AdyenBrandCodes.Giftcard,
61
+ magentoPaymentType: MagentoPaymentTypes.HPP,
62
+ state: {
63
+ data: {
64
+ paymentMethod: {
65
+ brand: props.brand,
66
+ type: AdyenBrandCodes.Giftcard,
67
+ },
68
+ },
69
+ },
70
+ });
71
+ }
72
+ }, [attemptPayment, paymentFormSubmitted, props.brand]);
73
+
74
+ /**
75
+ * Pass Magento's submit reponse to an Adyen Redirect component.
76
+ *
77
+ * Adyen will redirect the user to a Adyen Hosted Payment Page (HPP),
78
+ * to capture payment, before redirecting the user back to the PWA.
79
+ * Partial payments with Giftcards is handled within the HPP.
80
+ */
81
+ useEffect(() => {
82
+ if (action?.url && adyenCheckout && step === AdyenSteps.ThreeDS1Redirect && redirectContainer.current) {
83
+ const redirect = adyenCheckout?.create('redirect');
84
+
85
+ if (redirect) {
86
+ redirect.mount(redirectContainer.current);
87
+ redirect?.handleAction(action);
88
+ }
89
+ }
90
+ }, [action, adyenCheckout, step]);
91
+
92
+ /**
93
+ * Return our component
94
+ */
95
+ return (
96
+ <div ref={giftcardContainer}>
97
+ <div ref={redirectContainer} />
98
+ </div>
99
+ );
100
+ }
101
+
102
+ export default Giftcard;
@@ -0,0 +1,23 @@
1
+ <!-- Title -->
2
+ <h1 align="center">
3
+ Gift Cards
4
+ </h1>
5
+
6
+ <!-- Description -->
7
+ <p align="center">Adyen Gift Card Component</p>
8
+
9
+ <br/>
10
+
11
+ ## 🎁 Payment Process
12
+
13
+ 1. Mount the GiftCard component
14
+ 2. User presses the 'pay' button.
15
+ 3. The Giftcard is set as the order payment method and the order locked, to await payment.
16
+ 4. The order details are saved in localstorage, before the user redirected to Adyen Hosted Payment Page (HPP) for payment.
17
+ 5. The user is returned to the website and the order is restored.
18
+ 6. The Giftcard payment details are sent to Magento for processing.
19
+
20
+ ## 🖖 Useful Resources
21
+
22
+ - [Adyen Supported GiftCards](https://docs.adyen.com/payment-methods/gift-cards#supported-gift-cards) - The types of Giftcards supported by Adyen.
23
+ - [Adyen GiftCard Test Numbers](https://docs.adyen.com/development-resources/testing/test-card-numbers#gift-cards) - Card details for testing the component.
@@ -0,0 +1 @@
1
+ export * from './Giftcard';
@@ -22,8 +22,9 @@
22
22
  3. It may be useful to use an existing payment method component as a template:
23
23
  1. Standard workflow - [Card component](Card/Card.tsx)
24
24
  2. Redirect workflow - [Klarna component](Klarna/Klarna.tsx)
25
- 3. SDK workflow - [PayPal component](PayPal/PayPal.tsx)
26
- 4. Native/Async workflow - [ApplePay component](ApplePay/ApplePay.tsx)
25
+ 3. Adyen Hosted Payment Page (HPP) Redirection workflow = [GiftCard component](Giftcard/Giftcard.tsx)
26
+ 4. SDK workflow - [PayPal component](PayPal/PayPal.tsx)
27
+ 5. Native/Async workflow - [ApplePay component](ApplePay/ApplePay.tsx)
27
28
  4. Add your component to the `PaymentMethodTypes` enum in [`adyen.types.ts`](../adyen.types.ts).
28
29
  1. The enum value must match the type name used by Magento and Adyen.
29
30
  5. Add your component to the [`PaymentMethodHandler`](../PaymentMethodHandler.tsx).
@@ -43,6 +44,7 @@ This package supports the following payment methods:
43
44
 
44
45
  - [Apple Pay](paymentMethods/ApplePay)
45
46
  - [Google Pay](paymentMethods/GooglePay)
47
+ - [GiftCard](paymentMethods/Giftcard)
46
48
  - [Card](paymentMethods/Card)
47
49
  - [3DSecure 1](paymentMethods/Card/ThreeDS1Redirect.tsx)
48
50
  - [3DSecure 2](paymentMethods/Card/ThreeDS2Challenge.tsx)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wearejh/m2-pwa-adyen",
3
- "version": "0.13.2",
3
+ "version": "0.16.0",
4
4
  "description": "> TODO: description",
5
5
  "author": "Shane Osbourne <shane.osbourne8@gmail.com>",
6
6
  "homepage": "",
@@ -22,13 +22,13 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "@adyen/adyen-web": "4.5.0",
25
- "@wearejh/m2-pwa-cart": "^0.13.2",
26
- "@wearejh/m2-pwa-checkout": "^0.13.2",
27
- "@wearejh/m2-pwa-engine": "^0.13.2",
28
- "@wearejh/react-hooks": "^0.13.2",
29
- "@wearejh/rx-form": "^0.13.2",
30
- "@wearejh/swagger-rxjs": "^0.13.2",
25
+ "@wearejh/m2-pwa-cart": "^0.16.0",
26
+ "@wearejh/m2-pwa-checkout": "^0.16.0",
27
+ "@wearejh/m2-pwa-engine": "^0.16.0",
28
+ "@wearejh/react-hooks": "^0.16.0",
29
+ "@wearejh/rx-form": "^0.16.0",
30
+ "@wearejh/swagger-rxjs": "^0.16.0",
31
31
  "load-js": "^3.0.3"
32
32
  },
33
- "gitHead": "a17286833b7fd91270b8fa60d65427b9b931dd81"
33
+ "gitHead": "4575ad20a27273e832a2f202ae941e3cae828ac8"
34
34
  }