From 7144fb6cd4ffab9685cbbda41333be83a31f0141 Mon Sep 17 00:00:00 2001 From: Guilherme Ribeiro Date: Wed, 7 Feb 2024 13:15:46 +0100 Subject: [PATCH] v6 - Passing AdyenCheckout as first parameter (#2535) * feat: fixed lint issues in the components * fixing old playground * fix: passing props as optional for components * feat: unit tests fixed * feat: storybook * fix: playwright pages * fix: testcafe playground * feat: validating checkout parameter * fix: googlepay getting countryCode from core * fix: fixing createComponent umd function --- .../e2e-playwright/app/src/pages/ANCV/ANCV.js | 2 +- .../app/src/pages/Cards/Cards.js | 3 +- .../app/src/pages/CustomCards/CustomCards.js | 6 +- .../app/src/pages/Dropin/Dropin.js | 4 +- .../app/src/pages/IssuerLists/IssuerLists.js | 2 +- packages/e2e/app/src/pages/Address/Address.js | 2 +- packages/e2e/app/src/pages/Cards/Cards.js | 3 +- .../app/src/pages/CustomCards/CustomCards.js | 26 ++++--- packages/e2e/app/src/pages/Dropin/Dropin.js | 2 +- .../pages/DropinSessions/DropinSessions.js | 4 +- .../e2e/app/src/pages/GiftCards/GiftCards.js | 3 +- .../GiftCardsSessions/GiftCardsSessions.js | 3 +- .../app/src/pages/IssuerLists/IssuerLists.js | 2 +- .../src/pages/OpenInvoices/OpenInvoices.js | 2 +- .../app/src/pages/StoredCards/StoredCards.js | 2 +- .../e2e/app/src/pages/Vouchers/Vouchers.js | 8 +-- .../lib/src/components/Affirm/Affirm.test.tsx | 4 +- .../src/components/AfterPay/AfterPay.test.ts | 4 +- .../components/AfterPay/AfterPayB2B.test.ts | 6 +- .../components/AmazonPay/AmazonPay.test.tsx | 5 +- .../src/components/ApplePay/ApplePay.test.ts | 38 +++-------- .../lib/src/components/ApplePay/ApplePay.tsx | 10 +-- .../components/ApplePay/payment-request.ts | 5 +- packages/lib/src/components/ApplePay/types.ts | 5 -- .../lib/src/components/Atome/Atome.test.ts | 6 +- .../components/BcmcMobile/BcmcMobile.test.ts | 6 +- .../lib/src/components/Card/Bancontact.ts | 5 +- .../lib/src/components/Card/Card.test.tsx | 28 ++++---- packages/lib/src/components/Card/Card.tsx | 9 +-- .../components/CashAppPay/CashAppPay.test.ts | 10 ++- .../src/components/CashAppPay/CashAppPay.tsx | 5 +- .../components/ClickToPay/ClickToPay.test.ts | 10 +-- .../src/components/ClickToPay/ClickToPay.tsx | 9 +-- .../components/CustomCard/CustomCard.test.ts | 2 +- .../lib/src/components/Donation/Donation.tsx | 5 +- .../lib/src/components/Dropin/Dropin.test.ts | 28 +++----- packages/lib/src/components/Dropin/Dropin.tsx | 6 +- .../PaymentMethod/PaymentMethodList.test.tsx | 3 +- .../Dropin/components/status/Status.test.tsx | 2 +- .../Dropin/elements/createElements.ts | 14 ++-- .../elements/createInstantPaymentElements.ts | 10 +-- .../Dropin/elements/createStoredElements.ts | 10 +-- .../src/components/Dropin/elements/filters.ts | 4 +- packages/lib/src/components/Dropin/types.ts | 2 + .../src/components/DuitNow/DuitNow.test.ts | 6 +- .../src/components/Giftcard/Giftcard.test.tsx | 4 +- .../components/GooglePay/GooglePay.test.ts | 44 +++++------- .../src/components/GooglePay/GooglePay.tsx | 13 ++-- .../components/GooglePay/GooglePayService.ts | 15 ++-- .../src/components/GooglePay/defaultProps.ts | 1 - .../src/components/GooglePay/requests.test.ts | 15 ++-- .../lib/src/components/GooglePay/requests.ts | 6 +- .../components/Klarna/KlarnaPayments.test.tsx | 10 +-- .../src/components/Klarna/KlarnaPayments.tsx | 5 +- .../MealVoucherFR/MealVoucherFR.tsx | 5 +- .../components/Multibanco/Multibanco.test.ts | 6 +- .../OnlinebankingPL/OnlineBankingPL.test.ts | 8 +-- .../OnlinebankingPL/OnlineBankingPL.tsx | 5 +- packages/lib/src/components/Oxxo/Oxxo.test.ts | 8 +-- .../components/PayByBank/PayByBank.test.ts | 11 ++- .../src/components/PayByBank/PayByBank.tsx | 5 +- .../lib/src/components/PayNow/PayNow.test.ts | 6 +- .../lib/src/components/PayPal/Paypal.test.ts | 12 ++-- packages/lib/src/components/PayPal/Paypal.tsx | 5 +- .../PersonalDetails/PersonalDetails.test.tsx | 3 +- packages/lib/src/components/Pix/Pix.test.ts | 12 ++-- .../components/PromptPay/PromptPay.test.ts | 6 +- .../src/components/RatePay/RatePay.test.tsx | 4 +- .../src/components/Redirect/Redirect.test.tsx | 4 +- .../lib/src/components/Sepa/Sepa.test.tsx | 15 ++-- packages/lib/src/components/Sepa/Sepa.tsx | 5 +- .../src/components/Trustly/Trustly.test.tsx | 9 +-- .../lib/src/components/Twint/Twint.test.tsx | 11 ++- .../lib/src/components/WeChat/WeChat.test.ts | 6 +- .../IssuerListContainer.tsx | 5 +- .../OpenInvoiceContainer.test.tsx | 2 +- .../helpers/OpenInvoiceContainer/types.ts | 2 - .../components/internal/Await/Await.test.tsx | 2 +- .../internal/BaseElement/BaseElement.test.ts | 17 +++-- .../internal/BaseElement/BaseElement.ts | 32 ++++++--- .../components/internal/BaseElement/types.ts | 2 - .../internal/Countdown/Countdown.test.tsx | 2 +- .../internal/QRLoader/QRLoader.test.tsx | 2 +- .../internal/UIElement/UIElement.test.ts | 68 ++++++++----------- .../internal/UIElement/UIElement.tsx | 24 +++---- packages/lib/src/core/AdyenCheckout.ts | 6 +- .../lib/src/core/CheckoutSession/types.ts | 2 +- packages/lib/src/core/Errors/SRPanel.test.tsx | 4 +- packages/lib/src/core/Errors/SRPanel.tsx | 5 +- packages/lib/src/core/Errors/types.ts | 7 +- .../PaymentAction/actionTypes.ts | 4 +- .../lib/src/core/RiskModule/RiskModule.tsx | 5 +- .../lib/src/core/core.component.props.test.ts | 46 ++++++++----- packages/lib/src/core/core.registry.ts | 4 +- packages/lib/src/core/core.test.ts | 12 ++-- packages/lib/src/core/core.ts | 9 +-- packages/lib/src/create-component.umd.test.ts | 20 ++---- packages/lib/src/create-component.umd.ts | 18 +++-- .../storybook/helpers/checkout-api-calls.ts | 4 +- .../storybook/helpers/checkout-handlers.ts | 2 + .../stories/cards/Bancontact.stories.tsx | 2 +- .../storybook/stories/cards/Card.stories.tsx | 2 +- .../stories/components/ANCV.stories.tsx | 2 +- .../stories/components/Klarna.stories.tsx | 2 +- .../stories/components/Pix.stories.tsx | 2 +- .../stories/components/UPI.stories.tsx | 2 +- .../stories/dropin/Dropin.stories.tsx | 2 +- .../stories/issuer-lists/Dotpay.stories.tsx | 2 +- .../stories/issuer-lists/Ideal.stories.tsx | 2 +- packages/lib/storybook/stories/types.ts | 3 +- .../stories/vouchers/Oxxo.stories.tsx | 2 +- .../stories/wallets/ApplePay.stories.tsx | 8 +-- .../wallets/ApplePayExpress.stories.tsx | 4 +- .../stories/wallets/GooglePay.stories.tsx | 2 +- .../wallets/GooglePayExpress.stories.tsx | 2 +- .../stories/wallets/PayPal.stories.tsx | 2 +- packages/lib/tsconfig.json | 2 +- packages/playground/src/pages/Cards/Cards.js | 28 +++----- .../src/pages/Components/Components.js | 28 ++++---- .../src/pages/CustomCards/CustomCards.js | 12 ++-- .../playground/src/pages/Dropin/manual.js | 20 ++---- .../playground/src/pages/Dropin/session.js | 3 +- .../playground/src/pages/DropinAuto/manual.js | 22 +++++- .../src/pages/DropinAuto/session.js | 3 +- .../playground/src/pages/DropinUMD/manual.js | 23 ++++++- .../playground/src/pages/DropinUMD/session.js | 3 +- .../src/pages/GiftCards/GiftCards.js | 11 ++- .../playground/src/pages/Helpers/Helpers.js | 9 +-- .../src/pages/IssuerLists/IssuerLists.js | 18 ++--- .../src/pages/OpenInvoices/OpenInvoices.js | 21 ++---- .../playground/src/pages/QRCodes/QRCodes.js | 18 ++--- .../playground/src/pages/Vouchers/Vouchers.js | 25 +++---- .../playground/src/pages/Wallets/Wallets.js | 26 +++---- 133 files changed, 568 insertions(+), 641 deletions(-) diff --git a/packages/e2e-playwright/app/src/pages/ANCV/ANCV.js b/packages/e2e-playwright/app/src/pages/ANCV/ANCV.js index 878b63663b..c36496ce9f 100644 --- a/packages/e2e-playwright/app/src/pages/ANCV/ANCV.js +++ b/packages/e2e-playwright/app/src/pages/ANCV/ANCV.js @@ -34,7 +34,7 @@ const initCheckout = async () => { onError: handleError }); - window.paymentMethod = new ANCV({ core: checkout }).mount('.ancv-field'); + window.paymentMethod = new ANCV(checkout).mount('.ancv-field'); }; initCheckout(); diff --git a/packages/e2e-playwright/app/src/pages/Cards/Cards.js b/packages/e2e-playwright/app/src/pages/Cards/Cards.js index 09feb6fd5e..f0e32d1cb2 100644 --- a/packages/e2e-playwright/app/src/pages/Cards/Cards.js +++ b/packages/e2e-playwright/app/src/pages/Cards/Cards.js @@ -21,8 +21,7 @@ const initCheckout = async () => { }); // Credit card with installments - window.card = new Card({ - core: checkout, + window.card = new Card(checkout, { brands: ['mc', 'visa', 'amex', 'maestro', 'bcmc'], onChange: state => { /** diff --git a/packages/e2e-playwright/app/src/pages/CustomCards/CustomCards.js b/packages/e2e-playwright/app/src/pages/CustomCards/CustomCards.js index 9248945ebe..4e76e3354d 100644 --- a/packages/e2e-playwright/app/src/pages/CustomCards/CustomCards.js +++ b/packages/e2e-playwright/app/src/pages/CustomCards/CustomCards.js @@ -20,8 +20,7 @@ const initCheckout = async () => { ...window.mainConfiguration }); - window.customCard = new CustomCard({ - core: checkout, + window.customCard = new CustomCard(checkout, { type: 'card', brands: ['mc', 'visa', 'synchrony_plcc'], onConfigSuccess, @@ -34,8 +33,7 @@ const initCheckout = async () => { createPayButton('.secured-fields', window.customCard, 'customCardRegular'); - window.customCardSeparate = new CustomCard({ - core: checkout, + window.customCardSeparate = new CustomCard(checkout, { type: 'card', brands: ['mc', 'visa', 'synchrony_plcc'], onConfigSuccess, diff --git a/packages/e2e-playwright/app/src/pages/Dropin/Dropin.js b/packages/e2e-playwright/app/src/pages/Dropin/Dropin.js index 20d3da7869..dbf230df22 100644 --- a/packages/e2e-playwright/app/src/pages/Dropin/Dropin.js +++ b/packages/e2e-playwright/app/src/pages/Dropin/Dropin.js @@ -8,8 +8,6 @@ import '../../style.scss'; const initCheckout = async () => { const paymentMethodsResponse = await getPaymentMethods({ amount, shopperLocale }); - console.log(window.mainConfiguration); - window.checkout = await AdyenCheckout({ amount, countryCode, @@ -24,7 +22,7 @@ const initCheckout = async () => { ...window.mainConfiguration }); - window.dropin = new Dropin({ core: window.checkout, ...window.dropinConfig }).mount('#dropin-container'); + window.dropin = new Dropin(window.checkout, { ...window.dropinConfig }).mount('#dropin-container'); }; initCheckout(); diff --git a/packages/e2e-playwright/app/src/pages/IssuerLists/IssuerLists.js b/packages/e2e-playwright/app/src/pages/IssuerLists/IssuerLists.js index c94c3ba257..e71f89e517 100644 --- a/packages/e2e-playwright/app/src/pages/IssuerLists/IssuerLists.js +++ b/packages/e2e-playwright/app/src/pages/IssuerLists/IssuerLists.js @@ -29,7 +29,7 @@ const initCheckout = async () => { // ...window.mainConfiguration }); - window.ideal = new Ideal({ core: checkout, highlightedIssuers: ['1121', '1154', '1153'] }).mount('.ideal-field'); + window.ideal = new Ideal(checkout, { highlightedIssuers: ['1121', '1154', '1153'] }).mount('.ideal-field'); }; initCheckout(); diff --git a/packages/e2e/app/src/pages/Address/Address.js b/packages/e2e/app/src/pages/Address/Address.js index 9e55fbc827..9aaa3846c6 100644 --- a/packages/e2e/app/src/pages/Address/Address.js +++ b/packages/e2e/app/src/pages/Address/Address.js @@ -4,7 +4,7 @@ import '../../style.scss'; const initCheckout = async () => { window.checkout = await AdyenCheckout(); - window.address = new Address({core: checkout}).mount('.address-field'); + window.address = new Address(checkout).mount('.address-field'); }; initCheckout(); diff --git a/packages/e2e/app/src/pages/Cards/Cards.js b/packages/e2e/app/src/pages/Cards/Cards.js index 09feb6fd5e..f0e32d1cb2 100644 --- a/packages/e2e/app/src/pages/Cards/Cards.js +++ b/packages/e2e/app/src/pages/Cards/Cards.js @@ -21,8 +21,7 @@ const initCheckout = async () => { }); // Credit card with installments - window.card = new Card({ - core: checkout, + window.card = new Card(checkout, { brands: ['mc', 'visa', 'amex', 'maestro', 'bcmc'], onChange: state => { /** diff --git a/packages/e2e/app/src/pages/CustomCards/CustomCards.js b/packages/e2e/app/src/pages/CustomCards/CustomCards.js index a3a26f274f..1111094c4d 100644 --- a/packages/e2e/app/src/pages/CustomCards/CustomCards.js +++ b/packages/e2e/app/src/pages/CustomCards/CustomCards.js @@ -6,7 +6,6 @@ import '../../style.scss'; import './customcards.style.scss'; import { setFocus, onBrand, onConfigSuccess, onBinLookup, onChange } from './customCards.config'; import { makePayment } from '@adyen/adyen-web-playwright/app/src/services'; -import { showAuthorised } from '@adyen/adyen-web-playwright/app/src/handlers'; const initCheckout = async () => { // window.TextEncoder = null; // Comment in to force use of "compat" version @@ -22,8 +21,7 @@ const initCheckout = async () => { ...window.mainConfiguration }); - window.securedFields = new CustomCard({ - core: checkout, + window.securedFields = new CustomCard(checkout, { type: 'card', brands: ['mc', 'visa', 'amex', 'bcmc', 'maestro', 'cartebancaire'], onConfigSuccess, @@ -36,17 +34,17 @@ const initCheckout = async () => { createPayButton('.secured-fields', window.securedFields, 'securedfields'); - window.securedFields2 = new CustomCard({ - core: checkout, - // type: 'card',// Deliberately exclude to ensure a default value is set - brands: ['mc', 'visa', 'amex', 'bcmc', 'maestro', 'cartebancaire'], - onConfigSuccess, - onBrand, - onFocus: setFocus, - onBinLookup, - onChange, - ...window.cardConfig - }).mount('.secured-fields-2'); + window.securedFields2 = new CustomCard(checkout, { + // type: 'card',// Deliberately exclude to ensure a default value is set + brands: ['mc', 'visa', 'amex', 'bcmc', 'maestro', 'cartebancaire'], + onConfigSuccess, + onBrand, + onFocus: setFocus, + onBinLookup, + onChange, + ...window.cardConfig + }) + .mount('.secured-fields-2'); createPayButton('.secured-fields-2', window.securedFields2, 'securedfields2'); diff --git a/packages/e2e/app/src/pages/Dropin/Dropin.js b/packages/e2e/app/src/pages/Dropin/Dropin.js index 64a201424e..25071ad418 100644 --- a/packages/e2e/app/src/pages/Dropin/Dropin.js +++ b/packages/e2e/app/src/pages/Dropin/Dropin.js @@ -22,7 +22,7 @@ const initCheckout = async () => { ...window.mainConfiguration }); - window.dropin = new Dropin({ core: checkout, ...window.dropinConfig }).mount('#dropin-container'); + window.dropin = new Dropin(checkout, { ...window.dropinConfig }).mount('#dropin-container'); }; initCheckout(); diff --git a/packages/e2e/app/src/pages/DropinSessions/DropinSessions.js b/packages/e2e/app/src/pages/DropinSessions/DropinSessions.js index 5036a60c32..70f83f4d44 100644 --- a/packages/e2e/app/src/pages/DropinSessions/DropinSessions.js +++ b/packages/e2e/app/src/pages/DropinSessions/DropinSessions.js @@ -28,9 +28,7 @@ const initCheckout = async () => { ...window.mainConfiguration }); - window.dropin = new Dropin({ core: checkout, paymentMethodComponents: [Card, Giftcard], ...window.dropinConfig }).mount( - '#dropin-sessions-container' - ); + window.dropin = new Dropin(checkout, { paymentMethodComponents: [Card, Giftcard], ...window.dropinConfig }).mount('#dropin-sessions-container'); }; initCheckout(); diff --git a/packages/e2e/app/src/pages/GiftCards/GiftCards.js b/packages/e2e/app/src/pages/GiftCards/GiftCards.js index bd261c5c66..04f4c54fe0 100644 --- a/packages/e2e/app/src/pages/GiftCards/GiftCards.js +++ b/packages/e2e/app/src/pages/GiftCards/GiftCards.js @@ -20,8 +20,7 @@ const initCheckout = async () => { ...window.mainConfiguration }); - window.giftcard = new Giftcard({ - core: window.checkout, + window.giftcard = new Giftcard(window.checkout, { type: 'giftcard', brand: 'valuelink', onBalanceCheck: async (resolve, reject, data) => { diff --git a/packages/e2e/app/src/pages/GiftCardsSessions/GiftCardsSessions.js b/packages/e2e/app/src/pages/GiftCardsSessions/GiftCardsSessions.js index 796980bfa1..ee2214c205 100644 --- a/packages/e2e/app/src/pages/GiftCardsSessions/GiftCardsSessions.js +++ b/packages/e2e/app/src/pages/GiftCardsSessions/GiftCardsSessions.js @@ -33,8 +33,7 @@ const initCheckout = async () => { } }); - window.giftcard = new Giftcard({ - core: window.sessionCheckout, + window.giftcard = new Giftcard(window.sessionCheckout, { type: 'giftcard', brand: 'valuelink', onOrderUpdated: data => { diff --git a/packages/e2e/app/src/pages/IssuerLists/IssuerLists.js b/packages/e2e/app/src/pages/IssuerLists/IssuerLists.js index c94c3ba257..e71f89e517 100644 --- a/packages/e2e/app/src/pages/IssuerLists/IssuerLists.js +++ b/packages/e2e/app/src/pages/IssuerLists/IssuerLists.js @@ -29,7 +29,7 @@ const initCheckout = async () => { // ...window.mainConfiguration }); - window.ideal = new Ideal({ core: checkout, highlightedIssuers: ['1121', '1154', '1153'] }).mount('.ideal-field'); + window.ideal = new Ideal(checkout, { highlightedIssuers: ['1121', '1154', '1153'] }).mount('.ideal-field'); }; initCheckout(); diff --git a/packages/e2e/app/src/pages/OpenInvoices/OpenInvoices.js b/packages/e2e/app/src/pages/OpenInvoices/OpenInvoices.js index a0a1fe25a4..fcc2646497 100644 --- a/packages/e2e/app/src/pages/OpenInvoices/OpenInvoices.js +++ b/packages/e2e/app/src/pages/OpenInvoices/OpenInvoices.js @@ -26,7 +26,7 @@ const initCheckout = async () => { // ...window.mainConfiguration }); - window.afterpay = new AfterPay({ core: checkout }).mount('.afterpay-field'); + window.afterpay = new AfterPay(checkout).mount('.afterpay-field'); }; initCheckout(); diff --git a/packages/e2e/app/src/pages/StoredCards/StoredCards.js b/packages/e2e/app/src/pages/StoredCards/StoredCards.js index bec33e2e4a..c798d32bfd 100644 --- a/packages/e2e/app/src/pages/StoredCards/StoredCards.js +++ b/packages/e2e/app/src/pages/StoredCards/StoredCards.js @@ -35,7 +35,7 @@ const initCheckout = async () => { }; // Credit card with installments - window.storedCard = new Card({ core: checkout, ...storedCardData }).mount('.stored-card-field'); + window.storedCard = new Card(checkout, { ...storedCardData }).mount('.stored-card-field'); }; initCheckout(); diff --git a/packages/e2e/app/src/pages/Vouchers/Vouchers.js b/packages/e2e/app/src/pages/Vouchers/Vouchers.js index 4419abf296..609ce582a7 100644 --- a/packages/e2e/app/src/pages/Vouchers/Vouchers.js +++ b/packages/e2e/app/src/pages/Vouchers/Vouchers.js @@ -11,12 +11,10 @@ const initCheckout = async () => { }); // Boleto Input - window.boletoInput = new Boleto({ - core: window.checkout, + window.boletoInput = new Boleto(window.checkout, { type: 'boletobancario', - ...window.boletoConfig - }) - .mount('#boleto-input-container'); + ...window.boletoConfig + }).mount('#boleto-input-container'); }; initCheckout(); diff --git a/packages/lib/src/components/Affirm/Affirm.test.tsx b/packages/lib/src/components/Affirm/Affirm.test.tsx index e8f64f7e3b..7d5e246f53 100644 --- a/packages/lib/src/components/Affirm/Affirm.test.tsx +++ b/packages/lib/src/components/Affirm/Affirm.test.tsx @@ -2,12 +2,12 @@ import Affirm from './Affirm'; describe('Affirm', () => { test('returns false if there is no state', () => { - const affirm = new Affirm({ core: global.core }); + const affirm = new Affirm(global.core); expect(affirm.isValid).toBe(false); }); test('returns a type', () => { - const affirm = new Affirm({ core: global.core }); + const affirm = new Affirm(global.core); expect(affirm.data.paymentMethod.type).toBe('affirm'); }); }); diff --git a/packages/lib/src/components/AfterPay/AfterPay.test.ts b/packages/lib/src/components/AfterPay/AfterPay.test.ts index 46de580faa..706eb01d93 100644 --- a/packages/lib/src/components/AfterPay/AfterPay.test.ts +++ b/packages/lib/src/components/AfterPay/AfterPay.test.ts @@ -2,12 +2,12 @@ import AfterPay from './AfterPay'; describe('AfterPay', () => { test('returns false if there is no state', () => { - const afterPay = new AfterPay({ core: global.core }); + const afterPay = new AfterPay(global.core); expect(afterPay.isValid).toBe(false); }); test('returns a type', () => { - const afterPay = new AfterPay({ core: global.core }); + const afterPay = new AfterPay(global.core); expect(afterPay.data.paymentMethod.type).toBe('afterpay_default'); }); }); diff --git a/packages/lib/src/components/AfterPay/AfterPayB2B.test.ts b/packages/lib/src/components/AfterPay/AfterPayB2B.test.ts index 8fb6025b74..871e8fb575 100644 --- a/packages/lib/src/components/AfterPay/AfterPayB2B.test.ts +++ b/packages/lib/src/components/AfterPay/AfterPayB2B.test.ts @@ -2,17 +2,17 @@ import AfterPayB2B from './AfterPayB2B'; describe('AfterPay B2B', () => { test('returns false if there is no state', () => { - const afterPay = new AfterPayB2B({ core: global.core }); + const afterPay = new AfterPayB2B(global.core); expect(afterPay.isValid).toBe(false); }); test('returns a type', () => { - const afterPay = new AfterPayB2B({ core: global.core }); + const afterPay = new AfterPayB2B(global.core); expect(afterPay.data.paymentMethod.type).toBe('afterpay_b2b'); }); test('should show the company details as editable by default', () => { - const afterPay = new AfterPayB2B({ core: global.core }); + const afterPay = new AfterPayB2B(global.core); expect(afterPay.props.visibility.companyDetails).toBe('editable'); }); }); diff --git a/packages/lib/src/components/AmazonPay/AmazonPay.test.tsx b/packages/lib/src/components/AmazonPay/AmazonPay.test.tsx index 2a9404cd71..4aa904fa65 100644 --- a/packages/lib/src/components/AmazonPay/AmazonPay.test.tsx +++ b/packages/lib/src/components/AmazonPay/AmazonPay.test.tsx @@ -15,11 +15,10 @@ const spyFetch = (httpPost as jest.Mock).mockImplementation(jest.fn(() => Promis describe('AmazonPay', () => { const amazonProps = mock(); const getElement = (props = {}) => - new AmazonPay({ + new AmazonPay(global.core, { ...defaultProps, ...props, - ...amazonProps, - core: global.core + ...amazonProps }); test('always returns isValid as true', () => { diff --git a/packages/lib/src/components/ApplePay/ApplePay.test.ts b/packages/lib/src/components/ApplePay/ApplePay.test.ts index 93815334ec..fab5dfcf2a 100644 --- a/packages/lib/src/components/ApplePay/ApplePay.test.ts +++ b/packages/lib/src/components/ApplePay/ApplePay.test.ts @@ -31,9 +31,7 @@ describe('ApplePay', () => { } }); - const applepay = new ApplePay({ - core: global.core, - countryCode: 'US', + const applepay = new ApplePay(global.core, { amount: { currency: 'EUR', value: 2000 }, onPaymentFailed: onPaymentFailedMock, onSubmit(state, component, actions) { @@ -88,9 +86,7 @@ describe('ApplePay', () => { resolve(orderDetails); }); - const applepay = new ApplePay({ - core: global.core, - countryCode: 'US', + const applepay = new ApplePay(global.core, { amount: { currency: 'EUR', value: 2000 }, onOrderTrackingRequest: onOrderTrackingRequestMock, onPaymentCompleted: onPaymentCompletedMock @@ -140,9 +136,7 @@ describe('ApplePay', () => { resolve(); }); - const applepay = new ApplePay({ - core: global.core, - countryCode: 'US', + const applepay = new ApplePay(global.core, { amount: { currency: 'EUR', value: 2000 }, onOrderTrackingRequest: onOrderTrackingRequestMock, onPaymentCompleted: onPaymentCompletedMock @@ -186,9 +180,7 @@ describe('ApplePay', () => { reject(); }); - const applepay = new ApplePay({ - core: global.core, - countryCode: 'US', + const applepay = new ApplePay(global.core, { amount: { currency: 'EUR', value: 2000 }, onOrderTrackingRequest: onOrderTrackingRequestMock, onPaymentCompleted: onPaymentCompletedMock @@ -264,9 +256,7 @@ describe('ApplePay', () => { actions.reject(); }); - const applepay = new ApplePay({ - core: global.core, - countryCode: 'US', + const applepay = new ApplePay(global.core, { amount: { currency: 'EUR', value: 2000 }, onAuthorized: onAuthorizedMock, onChange: onChangeMock, @@ -347,9 +337,7 @@ describe('ApplePay', () => { describe('formatProps', () => { test('accepts an amount in a regular format', () => { - const applepay = new ApplePay({ - core: global.core, - countryCode: 'US', + const applepay = new ApplePay(global.core, { amount: { currency: 'EUR', value: 2000 } }); expect(applepay.props.amount.value).toEqual(2000); @@ -357,24 +345,18 @@ describe('ApplePay', () => { }); test('accepts an amount with default values', () => { - const applepay = new ApplePay({ core: global.core, countryCode: 'US' }); + const applepay = new ApplePay(global.core); expect(applepay.props.amount.value).toEqual(0); expect(applepay.props.amount.currency).toEqual('USD'); }); test('uses merchantName if no totalPriceLabel was defined', () => { - const applepay = new ApplePay({ - core: global.core, - countryCode: 'US', - configuration: { merchantName: 'Test' } - }); + const applepay = new ApplePay(global.core, { configuration: { merchantName: 'Test' } }); expect(applepay.props.totalPriceLabel).toEqual('Test'); }); test('can set totalPriceLabel', () => { - const applepay = new ApplePay({ - core: global.core, - countryCode: 'US', + const applepay = new ApplePay(global.core, { configuration: { merchantName: 'Test' }, totalPriceLabel: 'Total' }); @@ -384,7 +366,7 @@ describe('ApplePay', () => { describe('get data', () => { test('always returns a type', () => { - const applepay = new ApplePay({ core: global.core, countryCode: 'US' }); + const applepay = new ApplePay(global.core); expect(applepay.data).toMatchObject({ paymentMethod: { type: 'applepay' } }); }); }); diff --git a/packages/lib/src/components/ApplePay/ApplePay.tsx b/packages/lib/src/components/ApplePay/ApplePay.tsx index b09b4dc701..9b71164af8 100644 --- a/packages/lib/src/components/ApplePay/ApplePay.tsx +++ b/packages/lib/src/components/ApplePay/ApplePay.tsx @@ -8,11 +8,12 @@ import { httpPost } from '../../core/Services/http'; import { APPLEPAY_SESSION_ENDPOINT } from './config'; import { preparePaymentRequest } from './payment-request'; import { resolveSupportedVersion, mapBrands, formatApplePayContactToAdyenAddressFormat } from './utils'; -import { ApplePayConfiguration, ApplePayElementData, ApplePayPaymentOrderDetails, ApplePaySessionRequest } from './types'; import AdyenCheckoutError from '../../core/Errors/AdyenCheckoutError'; import { TxVariants } from '../tx-variants'; -import { PaymentResponseData, RawPaymentResponse } from '../../types/global-types'; import { sanitizeResponse, verifyPaymentDidNotFail } from '../internal/UIElement/utils'; +import type { ApplePayConfiguration, ApplePayElementData, ApplePayPaymentOrderDetails, ApplePaySessionRequest } from './types'; +import type { ICore } from '../../core/types'; +import type { PaymentResponseData, RawPaymentResponse } from '../../types/global-types'; const latestSupportedVersion = 14; @@ -20,8 +21,8 @@ class ApplePayElement extends UIElement { public static type = TxVariants.applepay; protected static defaultProps = defaultProps; - constructor(props: ApplePayConfiguration) { - super(props); + constructor(checkout: ICore, props?: ApplePayConfiguration) { + super(checkout, props); this.startSession = this.startSession.bind(this); this.submit = this.submit.bind(this); this.validateMerchant = this.validateMerchant.bind(this); @@ -70,6 +71,7 @@ class ApplePayElement extends UIElement { const paymentRequest = preparePaymentRequest({ companyName: this.props.configuration.merchantName, + countryCode: this.core.options.countryCode, ...this.props }); diff --git a/packages/lib/src/components/ApplePay/payment-request.ts b/packages/lib/src/components/ApplePay/payment-request.ts index a151b477a4..47f9b40369 100644 --- a/packages/lib/src/components/ApplePay/payment-request.ts +++ b/packages/lib/src/components/ApplePay/payment-request.ts @@ -5,9 +5,12 @@ const formatAmount = (amount: PaymentAmount) => String(getDecimalAmount(amount.v export const preparePaymentRequest = (paymentRequest): ApplePayJS.ApplePayPaymentRequest => { const { countryCode, companyName, amount, ...props } = paymentRequest; - const formattedAmount = formatAmount(amount); + if (!countryCode) { + console.warn('ApplePay - Make sure to set the countryCode in the AdyenCheckout configuration or in the Checkout Session creation'); + } + return { countryCode, currencyCode: amount.currency, diff --git a/packages/lib/src/components/ApplePay/types.ts b/packages/lib/src/components/ApplePay/types.ts index 53a84bd645..5e865e5b56 100644 --- a/packages/lib/src/components/ApplePay/types.ts +++ b/packages/lib/src/components/ApplePay/types.ts @@ -45,11 +45,6 @@ export interface ApplePayConfiguration extends UIElementProps { */ version?: number; - /** - * The merchant’s two-letter ISO 3166 country code. - */ - countryCode: string; - /** * Part of the 'ApplePayLineItem' object, which sets the label of the payment request * @see {@link https://developer.apple.com/documentation/apple_pay_on_the_web/applepaylineitem ApplePayLineItem docs} diff --git a/packages/lib/src/components/Atome/Atome.test.ts b/packages/lib/src/components/Atome/Atome.test.ts index baa6a5feba..2dc8ea044a 100644 --- a/packages/lib/src/components/Atome/Atome.test.ts +++ b/packages/lib/src/components/Atome/Atome.test.ts @@ -2,7 +2,7 @@ import Atome from './Atome'; describe('Atome', () => { test('should be required for personal details only the firstName, lastName and telephoneNumber', () => { - const atome = new Atome({ core: global.core }); + const atome = new Atome(global.core); expect(atome.props.personalDetailsRequiredFields.length).toBe(3); expect(atome.props.personalDetailsRequiredFields.includes('firstName')).toBeTruthy(); @@ -11,7 +11,7 @@ describe('Atome', () => { }); test('should be required for billing address only the country, street and postal code', () => { - const atome = new Atome({ core: global.core }); + const atome = new Atome(global.core); expect(atome.props.billingAddressRequiredFields.length).toBe(3); expect(atome.props.billingAddressRequiredFields.includes('country')).toBeTruthy(); @@ -20,7 +20,7 @@ describe('Atome', () => { }); test('should hide companyDetails and deliveryAddress sections', () => { - const atome = new Atome({ core: global.core }); + const atome = new Atome(global.core); expect(atome.props.visibility.deliveryAddress).toBe('hidden'); expect(atome.props.visibility.companyDetails).toBe('hidden'); diff --git a/packages/lib/src/components/BcmcMobile/BcmcMobile.test.ts b/packages/lib/src/components/BcmcMobile/BcmcMobile.test.ts index a85526f652..22d006d3a3 100644 --- a/packages/lib/src/components/BcmcMobile/BcmcMobile.test.ts +++ b/packages/lib/src/components/BcmcMobile/BcmcMobile.test.ts @@ -5,21 +5,21 @@ describe('BcmcMobile', () => { describe('isValid', () => { test('should be always true', () => { - const bcmcMobile = new BcmcMobile({ core: global.core }); + const bcmcMobile = new BcmcMobile(global.core); expect(bcmcMobile.isValid).toBe(true); }); }); describe('get data', () => { test('always returns a type', () => { - const bcmcMobile = new BcmcMobile({ core: global.core }); + const bcmcMobile = new BcmcMobile(global.core); expect(bcmcMobile.data.paymentMethod.type).toBe('bcmc_mobile'); }); }); describe('render', () => { test('does render something by default', () => { - const bcmcMobile = new BcmcMobile({ core: global.core }); + const bcmcMobile = new BcmcMobile(global.core); expect(bcmcMobile.render()).not.toBe(null); }); }); diff --git a/packages/lib/src/components/Card/Bancontact.ts b/packages/lib/src/components/Card/Bancontact.ts index d5a1d6cada..47cd917cf5 100644 --- a/packages/lib/src/components/Card/Bancontact.ts +++ b/packages/lib/src/components/Card/Bancontact.ts @@ -2,12 +2,13 @@ import { CardElement } from './Card'; import { CardElementData, CardConfiguration } from './types'; import { CVC_POLICY_HIDDEN } from '../internal/SecuredFields/lib/configuration/constants'; import { TxVariants } from '../tx-variants'; +import type { ICore } from '../../core/types'; class BancontactElement extends CardElement { public static type = TxVariants.bcmc; - constructor(props: CardConfiguration) { - super(props); + constructor(checkout: ICore, props?: CardConfiguration) { + super(checkout, props); } protected static defaultProps = { diff --git a/packages/lib/src/components/Card/Card.test.tsx b/packages/lib/src/components/Card/Card.test.tsx index ff42dd7d2e..a84d9f4376 100644 --- a/packages/lib/src/components/Card/Card.test.tsx +++ b/packages/lib/src/components/Card/Card.test.tsx @@ -8,18 +8,18 @@ import { Resources } from '../../core/Context/Resources'; describe('Card', () => { describe('formatProps', function () { test('should not require a billingAddress if it is a stored card', () => { - const card = new CardElement({ core: global.core, billingAddressRequired: true, storedPaymentMethodId: 'test' }); + const card = new CardElement(global.core, { billingAddressRequired: true, storedPaymentMethodId: 'test' }); expect(card.props.billingAddressRequired).toBe(false); expect(card.props.type).toEqual('scheme'); }); test('should format countryCode to lowerCase', () => { - const card = new CardElement({ core: global.core, countryCode: 'KR' }); + const card = new CardElement(global.core, { countryCode: 'KR' }); expect(card.props.countryCode).toEqual('kr'); }); test('should return false for enableStoreDetails in case of zero-auto transaction', () => { - const card = new CardElement({ core: global.core, amount: { value: 0, currency: 'eur' }, enableStoreDetails: true }); + const card = new CardElement(global.core, { amount: { value: 0, currency: 'eur' }, enableStoreDetails: true }); expect(card.props.enableStoreDetails).toEqual(false); }); }); @@ -27,7 +27,7 @@ describe('Card', () => { describe('payButton', () => { describe('Zero auth transaction', () => { const i18n = new Language('en-US'); - const props = { core: global.core, amount: { value: 0, currency: 'eur' }, enableStoreDetails: true, i18n }; + const props = { amount: { value: 0, currency: 'eur' }, enableStoreDetails: true, i18n }; const customRender = (ui: h.JSX.Element) => { return render( // @ts-ignore ignore @@ -38,14 +38,14 @@ describe('Card', () => { }; test('should show the label "Save details" for the regular card', async () => { - const card = new CardElement(props); + const card = new CardElement(global.core, props); // @ts-ignore ignore customRender(card.payButton()); expect(await screen.findByRole('button', { name: 'Save details' })).toBeTruthy(); }); test('should show the label "Confirm preauthorization" for the stored card', async () => { - const card = new CardElement({ ...props, storedPaymentMethodId: 'test' }); + const card = new CardElement(global.core, { ...props, storedPaymentMethodId: 'test' }); // @ts-ignore ignore customRender(card.payButton()); expect(await screen.findByRole('button', { name: 'Confirm preauthorization' })).toBeTruthy(); @@ -55,25 +55,25 @@ describe('Card', () => { describe('get data', () => { test('always returns a type', () => { - const card = new CardElement({ core: global.core }); + const card = new CardElement(global.core); card.setState({ data: { card: '123' }, isValid: true }); expect(card.data.paymentMethod.type).toBe('scheme'); }); test('always returns a state', () => { - const card = new CardElement({ core: global.core }); + const card = new CardElement(global.core); card.setState({ data: { card: '123' }, isValid: true }); expect(card.data.paymentMethod.card).toBe('123'); }); test('should return storePaymentMethod if enableStoreDetails is enabled', () => { - const card = new CardElement({ core: global.core, enableStoreDetails: true }); + const card = new CardElement(global.core, { enableStoreDetails: true }); card.setState({ storePaymentMethod: true }); expect(card.data.storePaymentMethod).toBe(true); }); test('should not return storePaymentMethod if enableStoreDetails is disabled', () => { - const card = new CardElement({ core: global.core, enableStoreDetails: false }); + const card = new CardElement(global.core, { enableStoreDetails: false }); card.setState({ storePaymentMethod: true }); expect(card.data.storePaymentMethod).not.toBeDefined(); }); @@ -81,12 +81,12 @@ describe('Card', () => { describe('isValid', () => { test('returns false if there is no state', () => { - const card = new CardElement({ core: global.core }); + const card = new CardElement(global.core); expect(card.isValid).toBe(false); }); test('returns true if the state is valid', () => { - const card = new CardElement({ core: global.core }); + const card = new CardElement(global.core); card.setState({ data: { card: '123' }, isValid: true }); expect(card.isValid).toBe(true); }); @@ -94,12 +94,12 @@ describe('Card', () => { describe('Test setting of configuration prop: koreanAuthenticationRequired', () => { test('Returns default value', () => { - const card = new CardElement({ core: global.core, configuration: {} }); + const card = new CardElement(global.core, { configuration: {} }); expect(card.props.configuration.koreanAuthenticationRequired).toBe(undefined); }); test('Returns configuration defined value', () => { - const card = new CardElement({ core: global.core, configuration: { koreanAuthenticationRequired: true } }); + const card = new CardElement(global.core, { configuration: { koreanAuthenticationRequired: true } }); expect(card.props.configuration.koreanAuthenticationRequired).toBe(true); }); }); diff --git a/packages/lib/src/components/Card/Card.tsx b/packages/lib/src/components/Card/Card.tsx index 6538fd4497..ce0c789270 100644 --- a/packages/lib/src/components/Card/Card.tsx +++ b/packages/lib/src/components/Card/Card.tsx @@ -16,6 +16,7 @@ import { UIElementStatus } from '../internal/UIElement/types'; import UIElement from '../internal/UIElement'; import PayButton from '../internal/PayButton'; import { PayButtonProps } from '../internal/PayButton/PayButton'; +import type { ICore } from '../../core/types'; export class CardElement extends UIElement { public static type = TxVariants.scheme; @@ -27,8 +28,8 @@ export class CardElement extends UIElement { */ private clickToPayRef = null; - constructor(props: CardConfiguration) { - super(props); + constructor(checkout: ICore, props?: CardConfiguration) { + super(checkout, props); if (props && !props._disableClickToPay) { this.clickToPayService = createClickToPayService(this.props.configuration, this.props.clickToPayConfiguration, this.props.environment); @@ -90,8 +91,8 @@ export class CardElement extends UIElement { clickToPayConfiguration: { ...props.clickToPayConfiguration, disableOtpAutoFocus: props.clickToPayConfiguration?.disableOtpAutoFocus || false, - shopperEmail: props.clickToPayConfiguration?.shopperEmail || props?.core?.options?.session?.shopperEmail, - telephoneNumber: props.clickToPayConfiguration?.telephoneNumber || props?.core?.options?.session?.telephoneNumber, + shopperEmail: props.clickToPayConfiguration?.shopperEmail || this.core.options?.session?.shopperEmail, + telephoneNumber: props.clickToPayConfiguration?.telephoneNumber || this.core.options?.session?.telephoneNumber, locale: props.clickToPayConfiguration?.locale || props.i18n?.locale?.replace('-', '_') } }; diff --git a/packages/lib/src/components/CashAppPay/CashAppPay.test.ts b/packages/lib/src/components/CashAppPay/CashAppPay.test.ts index 76b82e12c0..2e72b6af66 100644 --- a/packages/lib/src/components/CashAppPay/CashAppPay.test.ts +++ b/packages/lib/src/components/CashAppPay/CashAppPay.test.ts @@ -20,7 +20,7 @@ test('should return on-file data if available', () => { const customerId = 'abcdef'; const cashTag = '$john-doe'; - const cashAppPayElement = new CashAppPay({ core: global.core, storePaymentMethod: true }); + const cashAppPayElement = new CashAppPay(global.core, { storePaymentMethod: true }); const data: CashAppPayEventData = { onFileGrantId, @@ -40,7 +40,7 @@ test('should return grantId, customerId and correct txVariant', () => { const grantId = 'xxxx-yyyy'; const customerId = 'abcdef'; - const cashAppPayElement = new CashAppPay({ core: global.core }); + const cashAppPayElement = new CashAppPay(global.core); const data: CashAppPayEventData = { grantId, @@ -53,8 +53,7 @@ test('should return grantId, customerId and correct txVariant', () => { }); test('should initially display the loading spinner while SDK is being loaded', async () => { - const cashAppPayElement = new CashAppPay({ - core: global.core, + const cashAppPayElement = new CashAppPay(global.core, { i18n: global.i18n, loadingContext: 'test', modules: { resources: global.resources } @@ -67,8 +66,7 @@ test('should initially display the loading spinner while SDK is being loaded', a test('should create customer request and then begin CashApp flow when submit is triggered', async () => { const onClick = jest.fn().mockImplementation(actions => actions.resolve()); - const cashAppPayElement = new CashAppPay({ - core: global.core, + const cashAppPayElement = new CashAppPay(global.core, { onClick, i18n: global.i18n, loadingContext: 'test', diff --git a/packages/lib/src/components/CashAppPay/CashAppPay.tsx b/packages/lib/src/components/CashAppPay/CashAppPay.tsx index 86e9c6887a..ec753d33cb 100644 --- a/packages/lib/src/components/CashAppPay/CashAppPay.tsx +++ b/packages/lib/src/components/CashAppPay/CashAppPay.tsx @@ -10,6 +10,7 @@ import defaultProps from './defaultProps'; import RedirectButton from '../internal/RedirectButton'; import { payAmountLabel } from '../internal/PayButton'; import { TxVariants } from '../tx-variants'; +import type { ICore } from '../../core/types'; export class CashAppPay extends UIElement { public static type = TxVariants.cashapp; @@ -18,8 +19,8 @@ export class CashAppPay extends UIElement { protected static defaultProps = defaultProps; - constructor(props: CashAppPayConfiguration) { - super(props); + constructor(checkout: ICore, props?: CashAppPayConfiguration) { + super(checkout, props); if (this.props.enableStoreDetails && this.props.storePaymentMethod) { console.warn( diff --git a/packages/lib/src/components/ClickToPay/ClickToPay.test.ts b/packages/lib/src/components/ClickToPay/ClickToPay.test.ts index 2c75fe2439..3c6a113de4 100644 --- a/packages/lib/src/components/ClickToPay/ClickToPay.test.ts +++ b/packages/lib/src/components/ClickToPay/ClickToPay.test.ts @@ -22,7 +22,7 @@ test('should initialize ClickToPayService when creating the element', () => { }; // eslint-disable-next-line @typescript-eslint/no-unused-vars - const element = new ClickToPayElement({ core: global.core, environment: 'test', configuration, ...ctpConfiguration }); + const element = new ClickToPayElement(global.core, { environment: 'test', configuration, ...ctpConfiguration }); expect(createClickToPayService).toHaveBeenCalledWith(configuration, ctpConfiguration, 'test'); expect(mockCtpService.initialize).toHaveBeenCalledTimes(1); @@ -35,7 +35,7 @@ test('should formatData() to click to pay /payment request format', () => { srcScheme: 'mc' }; - const element = new ClickToPayElement({ core: global.core }); + const element = new ClickToPayElement(global.core); element.setState({ data: paymentDataReceivedFromScheme }); const data = element.formatData(); @@ -61,7 +61,7 @@ test('should get shopperEmail from session if available', () => { } }; - const element = new ClickToPayElement({ core: global.core }); + const element = new ClickToPayElement(global.core); expect(element.props.shopperEmail).toBe('shopper@example.com'); }); @@ -76,7 +76,7 @@ test('should resolve isAvailable if shopper account is found', async () => { get: jest.fn(() => true) }); - const element = new ClickToPayElement({ core: global.core }); + const element = new ClickToPayElement(global.core); await expect(element.isAvailable()).resolves.not.toThrow(); }); @@ -95,7 +95,7 @@ test('should reject isAvailable if shopper account is not found', async () => { get: jest.fn(() => false) }); - const element = new ClickToPayElement({ core: global.core }); + const element = new ClickToPayElement(global.core); await expect(element.isAvailable()).rejects.toBeFalsy(); }); diff --git a/packages/lib/src/components/ClickToPay/ClickToPay.tsx b/packages/lib/src/components/ClickToPay/ClickToPay.tsx index 5d2e9eaf25..7f732d2a58 100644 --- a/packages/lib/src/components/ClickToPay/ClickToPay.tsx +++ b/packages/lib/src/components/ClickToPay/ClickToPay.tsx @@ -11,6 +11,7 @@ import ClickToPayProvider from '../internal/ClickToPay/context/ClickToPayProvide import ClickToPayComponent from '../internal/ClickToPay'; import AdyenCheckoutError from '../../core/Errors/AdyenCheckoutError'; import { TxVariants } from '../tx-variants'; +import type { ICore } from '../../core/types'; export class ClickToPayElement extends UIElement { public static type = TxVariants.clicktopay; @@ -18,8 +19,8 @@ export class ClickToPayElement extends UIElement { private readonly clickToPayService: IClickToPayService | null; private readonly ctpConfiguration: ClickToPayProps; - constructor(props: ClickToPayConfiguration) { - super(props); + constructor(checkout: ICore, props?: ClickToPayConfiguration) { + super(checkout, props); this.ctpConfiguration = { shopperEmail: this.props.shopperEmail, @@ -68,8 +69,8 @@ export class ClickToPayElement extends UIElement { return { ...props, disableOtpAutoFocus: props.disableOtpAutoFocus || false, - shopperEmail: props.shopperEmail || props?.core?.options?.session?.shopperEmail, - telephoneNumber: props.telephoneNumber || props?.core?.options?.session?.telephoneNumber, + shopperEmail: props.shopperEmail || this.core.options?.session?.shopperEmail, + telephoneNumber: props.telephoneNumber || this.core.options?.session?.telephoneNumber, locale: props.locale || props.i18n?.locale?.replace('-', '_') }; } diff --git a/packages/lib/src/components/CustomCard/CustomCard.test.ts b/packages/lib/src/components/CustomCard/CustomCard.test.ts index 77d22cb2a0..fb2cdf232b 100644 --- a/packages/lib/src/components/CustomCard/CustomCard.test.ts +++ b/packages/lib/src/components/CustomCard/CustomCard.test.ts @@ -4,7 +4,7 @@ describe('CustomCard', () => { let customCard; beforeEach(() => { - customCard = new CustomCard({ core: global.core }); + customCard = new CustomCard(global.core); }); describe('get data', () => { diff --git a/packages/lib/src/components/Donation/Donation.tsx b/packages/lib/src/components/Donation/Donation.tsx index 8dac85db76..3ef0135d6a 100644 --- a/packages/lib/src/components/Donation/Donation.tsx +++ b/packages/lib/src/components/Donation/Donation.tsx @@ -4,12 +4,13 @@ import CoreProvider from '../../core/Context/CoreProvider'; import DonationComponent from './components/DonationComponent'; import { TxVariants } from '../tx-variants'; import { DonationConfiguration } from './types'; +import type { ICore } from '../../core/types'; class DonationElement extends UIElement { public static type = TxVariants.donation; - constructor(props: DonationConfiguration) { - super(props); + constructor(checkout: ICore, props?: DonationConfiguration) { + super(checkout, props); this.donate = this.donate.bind(this); } diff --git a/packages/lib/src/components/Dropin/Dropin.test.ts b/packages/lib/src/components/Dropin/Dropin.test.ts index c5a3c37e4d..6652aca2f4 100644 --- a/packages/lib/src/components/Dropin/Dropin.test.ts +++ b/packages/lib/src/components/Dropin/Dropin.test.ts @@ -25,21 +25,21 @@ describe('Dropin', () => { describe('isValid', () => { test('should fail if no activePaymentMethod', () => { - const dropin = new Dropin({ core: checkout }); + const dropin = new Dropin(checkout); expect(dropin.isValid).toEqual(false); }); }); describe('submit', () => { test('should fail if no activePaymentMethod', () => { - const dropin = new Dropin({ core: checkout }); + const dropin = new Dropin(checkout); expect(() => dropin.submit()).toThrow(); }); }); describe('closeActivePaymentMethod', () => { test('should close active payment method', async () => { - const dropin = new Dropin({ core: checkout }); + const dropin = new Dropin(checkout); const component = await mount(dropin.render()); await component.update(); @@ -59,7 +59,7 @@ describe('Dropin', () => { type: 'threeDS2' }; - const dropin = new Dropin({ core: checkout }); + const dropin = new Dropin(checkout); dropin.handleAction(fingerprintAction); expect(dropin.componentFromAction instanceof ThreeDS2DeviceFingerprint).toEqual(true); @@ -77,7 +77,7 @@ describe('Dropin', () => { paymentMethodType: 'scheme' }; - const dropin = new Dropin({ core: checkout }); + const dropin = new Dropin(checkout); dropin.handleAction(challengeAction); expect(dropin.componentFromAction instanceof ThreeDS2Challenge).toEqual(true); @@ -101,10 +101,7 @@ describe('Dropin', () => { analytics: { enabled: false } }); - const dropin = new Dropin({ - core: checkout, - paymentMethodsConfiguration: { card: { challengeWindowSize: '02' } } - }); + const dropin = new Dropin(checkout, { paymentMethodsConfiguration: { card: { challengeWindowSize: '02' } } }); jest.spyOn(dropin, 'activePaymentMethod', 'get').mockReturnValue({ props: { challengeWindowSize: '02' } }); dropin.handleAction(challengeAction); @@ -121,7 +118,7 @@ describe('Dropin', () => { paymentMethodType: 'scheme' }; - const dropin = new Dropin({ core: checkout }); + const dropin = new Dropin(checkout); dropin.handleAction(challengeAction, { challengeWindowSize: '03' @@ -133,18 +130,15 @@ describe('Dropin', () => { describe('Instant Payments feature', () => { test('formatProps formats instantPaymentTypes removing duplicates and invalid values', async () => { - const dropin = new Dropin({ - core: checkout, - // @ts-ignore Valid test case - instantPaymentTypes: ['paywithgoogle', 'paywithgoogle', 'paypal', 'alipay'] - }); + // @ts-ignore Testing invalid interface + const dropin = new Dropin(checkout, { instantPaymentTypes: ['paywithgoogle', 'paywithgoogle', 'paypal', 'alipay'] }); expect(dropin.props.instantPaymentTypes).toStrictEqual(['paywithgoogle']); }); }); describe('Payment status', () => { test('should show success status', async () => { - const dropin = new Dropin({ core: checkout }); + const dropin = new Dropin(checkout); render(dropin.render()); expect(await screen.findByRole('radio')).toBeTruthy(); dropin.setStatus('success'); @@ -152,7 +146,7 @@ describe('Dropin', () => { }); test('should show Error status', async () => { - const dropin = new Dropin({ core: checkout }); + const dropin = new Dropin(checkout); render(dropin.render()); expect(await screen.findByRole('radio')).toBeTruthy(); dropin.setStatus('error'); diff --git a/packages/lib/src/components/Dropin/Dropin.tsx b/packages/lib/src/components/Dropin/Dropin.tsx index 77f5097d5a..9db64f8b77 100644 --- a/packages/lib/src/components/Dropin/Dropin.tsx +++ b/packages/lib/src/components/Dropin/Dropin.tsx @@ -11,6 +11,7 @@ import createInstantPaymentElements from './elements/createInstantPaymentElement import { hasOwnProperty } from '../../utils/hasOwnProperty'; import SRPanelProvider from '../../core/Errors/SRPanelProvider'; import splitPaymentMethods from './elements/splitPaymentMethods'; +import type { ICore } from '../../core/types'; const SUPPORTED_INSTANT_PAYMENTS = ['paywithgoogle', 'googlepay', 'applepay']; @@ -25,8 +26,8 @@ class DropinElement extends UIElement { */ public componentFromAction?: UIElement; - constructor(props: DropinConfiguration) { - super(props); + constructor(checkout: ICore, props?: DropinConfiguration) { + super(checkout, props); this.submit = this.submit.bind(this); this.handleAction = this.handleAction.bind(this); @@ -177,6 +178,7 @@ class DropinElement extends UIElement { { beforeEach(() => { const props = { - core: global.core, id: '3', type: 'giftcard', brand: 'givex', @@ -178,7 +177,7 @@ describe('Gift card', () => { givex: { icon: 'https://example.com' } } }; - giftCardPayment = new Giftcard(props); + giftCardPayment = new Giftcard(global.core, props); }); test('should display the gift card custom icon in the payment method list', async () => { diff --git a/packages/lib/src/components/Dropin/components/status/Status.test.tsx b/packages/lib/src/components/Dropin/components/status/Status.test.tsx index 12b6cb44b7..7990c00987 100644 --- a/packages/lib/src/components/Dropin/components/status/Status.test.tsx +++ b/packages/lib/src/components/Dropin/components/status/Status.test.tsx @@ -7,7 +7,7 @@ import Success from './Success'; import CoreProvider from '../../../../core/Context/CoreProvider'; describe('Status', () => { - const srPanel = new SRPanel({ core: global.core }); + const srPanel = new SRPanel(global.core); const customRender = ui => { return render( diff --git a/packages/lib/src/components/Dropin/elements/createElements.ts b/packages/lib/src/components/Dropin/elements/createElements.ts index 538fed7c8d..91995ca28d 100644 --- a/packages/lib/src/components/Dropin/elements/createElements.ts +++ b/packages/lib/src/components/Dropin/elements/createElements.ts @@ -1,10 +1,10 @@ import { filterUnsupported, filterPresent, filterAvailable } from './filters'; -import { PaymentMethod, StoredPaymentMethod } from '../../../types/global-types'; import { getComponentConfiguration } from './getComponentConfiguration'; -import { ICore } from '../../../core/types'; -import UIElement from '../../internal/UIElement/UIElement'; -import { PaymentMethodsConfiguration } from '../types'; import getComponentNameOfPaymentType from '../../components-name-map'; +import type { PaymentMethod, StoredPaymentMethod } from '../../../types/global-types'; +import type { PaymentMethodsConfiguration } from '../types'; +import type { ICore } from '../../../core/types'; +import type { IUIElement } from '../../internal/UIElement/types'; /** * Returns a filtered (available) list of component Elements @@ -19,7 +19,7 @@ const createElements = ( paymentMethodsConfiguration: PaymentMethodsConfiguration, commonProps, core: ICore -): Promise => { +): Promise => { const elements = paymentMethods .map(paymentMethod => { const paymentMethodConfigurationProps = getComponentConfiguration( @@ -40,9 +40,9 @@ const createElements = ( return null; } - const elementProps = { core, ...paymentMethod, ...commonProps, ...paymentMethodConfigurationProps }; + const elementProps = { ...paymentMethod, ...commonProps, ...paymentMethodConfigurationProps }; - return new PaymentMethodElement(elementProps); + return new PaymentMethodElement(core, elementProps); }) .filter(filterPresent) .filter(filterUnsupported); diff --git a/packages/lib/src/components/Dropin/elements/createInstantPaymentElements.ts b/packages/lib/src/components/Dropin/elements/createInstantPaymentElements.ts index bf8494fcd7..c58256719e 100644 --- a/packages/lib/src/components/Dropin/elements/createInstantPaymentElements.ts +++ b/packages/lib/src/components/Dropin/elements/createInstantPaymentElements.ts @@ -1,8 +1,8 @@ import createElements from './createElements'; -import { PaymentMethod } from '../../../types/global-types'; -import UIElement from '../../internal/UIElement/UIElement'; -import { ICore } from '../../../core/types'; -import { PaymentMethodsConfiguration } from '../types'; +import type { PaymentMethod } from '../../../types/global-types'; +import type { ICore } from '../../../core/types'; +import type { PaymentMethodsConfiguration } from '../types'; +import type { IUIElement } from '../../internal/UIElement/types'; /** * Returns a filtered (available) list of InstantPaymentMethods Elements @@ -17,7 +17,7 @@ const createInstantPaymentElements = ( paymentMethodsConfiguration: PaymentMethodsConfiguration, commonProps, core: ICore -): Promise => { +): Promise => { if (instantPaymentMethods.length) { return createElements( instantPaymentMethods, diff --git a/packages/lib/src/components/Dropin/elements/createStoredElements.ts b/packages/lib/src/components/Dropin/elements/createStoredElements.ts index ea7035915c..eb64ba5775 100644 --- a/packages/lib/src/components/Dropin/elements/createStoredElements.ts +++ b/packages/lib/src/components/Dropin/elements/createStoredElements.ts @@ -1,8 +1,8 @@ import createElements from './createElements'; -import { StoredPaymentMethod } from '../../../types/global-types'; -import { ICore } from '../../../core/types'; -import UIElement from '../../internal/UIElement/UIElement'; -import { PaymentMethodsConfiguration } from '../types'; +import type { StoredPaymentMethod } from '../../../types/global-types'; +import type { ICore } from '../../../core/types'; +import type { PaymentMethodsConfiguration } from '../types'; +import type { IUIElement } from '../../internal/UIElement/types'; /** * Returns a filtered (available) list of oneClick paymentMethod Elements @@ -17,6 +17,6 @@ const createStoredElements = ( paymentMethodsConfiguration: PaymentMethodsConfiguration, commonProps, core: ICore -): Promise => createElements(paymentMethods, paymentMethodsConfiguration, { ...commonProps, oneClick: true }, core); +): Promise => createElements(paymentMethods, paymentMethodsConfiguration, { ...commonProps, oneClick: true }, core); export default createStoredElements; diff --git a/packages/lib/src/components/Dropin/elements/filters.ts b/packages/lib/src/components/Dropin/elements/filters.ts index 6dce64f3f1..c9b160aeee 100644 --- a/packages/lib/src/components/Dropin/elements/filters.ts +++ b/packages/lib/src/components/Dropin/elements/filters.ts @@ -1,5 +1,5 @@ import promiseTimeout from '../../../utils/promiseTimeout'; -import UIElement from '../../internal/UIElement/UIElement'; +import type { IUIElement } from '../../internal/UIElement/types'; export const UNSUPPORTED_PAYMENT_METHODS = ['androidpay', 'samsungpay', 'clicktopay']; @@ -10,7 +10,7 @@ export const filterUnsupported = paymentMethod => !UNSUPPORTED_PAYMENT_METHODS.i export const filterPresent = paymentMethod => !!paymentMethod; // filter payment methods that are available to the user -export const filterAvailable = (elements: UIElement[]) => { +export const filterAvailable = (elements: IUIElement[]) => { const elementIsAvailablePromises = elements.map(element => { const { promise } = promiseTimeout(5000, element.isAvailable(), {}); return promise; diff --git a/packages/lib/src/components/Dropin/types.ts b/packages/lib/src/components/Dropin/types.ts index 2ee309bab9..aa4700459f 100644 --- a/packages/lib/src/components/Dropin/types.ts +++ b/packages/lib/src/components/Dropin/types.ts @@ -1,6 +1,7 @@ import type { Order, OrderStatus, PaymentActionsType } from '../../types/global-types'; import type { UIElementProps, UIElementStatus } from '../internal/UIElement/types'; import type { NewableComponent } from '../../core/core.registry'; +import type { ICore } from '../../core/types'; import UIElement from '../internal/UIElement/UIElement'; import { ComponentsMap } from '../components-map'; @@ -98,6 +99,7 @@ export interface onOrderCancelData { } export interface DropinComponentProps extends DropinConfiguration { + core: ICore; onCreateElements: any; onChange: (newState?: object) => void; onOrderCancel?: (data: onOrderCancelData) => void; diff --git a/packages/lib/src/components/DuitNow/DuitNow.test.ts b/packages/lib/src/components/DuitNow/DuitNow.test.ts index b162c1e2d7..50a4601207 100644 --- a/packages/lib/src/components/DuitNow/DuitNow.test.ts +++ b/packages/lib/src/components/DuitNow/DuitNow.test.ts @@ -3,21 +3,21 @@ import DuitNow from './DuitNow'; describe('DuitNow', () => { describe('isValid', () => { test('should always be true', () => { - const duitNow = new DuitNow({ core: global.core }); + const duitNow = new DuitNow(global.core); expect(duitNow.isValid).toBe(true); }); }); describe('get data', () => { test('always returns a type', () => { - const duitNow = new DuitNow({ core: global.core }); + const duitNow = new DuitNow(global.core); expect(duitNow.data.paymentMethod.type).toBe('duitnow'); }); }); describe('render', () => { test('does render something by default', () => { - const duitNow = new DuitNow({ core: global.core }); + const duitNow = new DuitNow(global.core); expect(duitNow.render()).not.toBe(null); }); }); diff --git a/packages/lib/src/components/Giftcard/Giftcard.test.tsx b/packages/lib/src/components/Giftcard/Giftcard.test.tsx index 75c96ba24d..7ac73b2a4c 100644 --- a/packages/lib/src/components/Giftcard/Giftcard.test.tsx +++ b/packages/lib/src/components/Giftcard/Giftcard.test.tsx @@ -7,7 +7,7 @@ describe('Giftcard', () => { describe('onBalanceCheck', () => { test('If onBalanceCheck is not provided, step is skipped and calls onSubmit', async () => { const onSubmitMock = jest.fn(); - const giftcard = new Giftcard({ core: global.core, ...baseProps, onSubmit: onSubmitMock }); + const giftcard = new Giftcard(global.core, { ...baseProps, onSubmit: onSubmitMock }); giftcard.setState({ isValid: true }); giftcard.onBalanceCheck(); await flushPromises(); @@ -17,7 +17,7 @@ describe('Giftcard', () => { test('onBalanceCheck will be skipped if the component is not valid', () => { const onBalanceCheck = jest.fn(); - const giftcard = new Giftcard({ core: global.core, ...baseProps, onBalanceCheck }); + const giftcard = new Giftcard(global.core, { ...baseProps, onBalanceCheck }); giftcard.setState({ isValid: false }); giftcard.onBalanceCheck(); diff --git a/packages/lib/src/components/GooglePay/GooglePay.test.ts b/packages/lib/src/components/GooglePay/GooglePay.test.ts index 4e42386dc0..a61716563a 100644 --- a/packages/lib/src/components/GooglePay/GooglePay.test.ts +++ b/packages/lib/src/components/GooglePay/GooglePay.test.ts @@ -59,8 +59,7 @@ describe('GooglePay', () => { }); const onPaymentCompletedMock = jest.fn(); - const gpay = new GooglePay({ - core: global.core, + const gpay = new GooglePay(global.core, { onSubmit: onSubmitMock, onPaymentCompleted: onPaymentCompletedMock }); @@ -124,8 +123,7 @@ describe('GooglePay', () => { }); }); - new GooglePay({ - core: global.core, + new GooglePay(global.core, { onSubmit: onSubmitMock }); @@ -163,8 +161,8 @@ describe('GooglePay', () => { }); const onPaymentFailedMock = jest.fn(); - const gpay = new GooglePay({ - core: global.core, + const gpay = new GooglePay(global.core, { + i18n: global.i18n, onSubmit: onSubmitMock, onPaymentFailed: onPaymentFailedMock }); @@ -243,7 +241,7 @@ describe('GooglePay', () => { test('should provide GooglePay auth event and formatted data', () => { const onAuthorizedMock = jest.fn(); - new GooglePay({ core: global.core, onAuthorized: onAuthorizedMock }); + new GooglePay(global.core, { onAuthorized: onAuthorizedMock }); // @ts-ignore GooglePayService is mocked const onPaymentAuthorized = GooglePayService.mock.calls[0][0].paymentDataCallbacks.onPaymentAuthorized; @@ -254,13 +252,12 @@ describe('GooglePay', () => { test('should pass error to GooglePay if the action.reject happens on onAuthorized', async () => { const onAuthorizedMock = jest.fn().mockImplementation((_data, actions) => { - console.log('reject'); actions.reject('Not supported network scheme'); }); const onPaymentFailedMock = jest.fn(); - new GooglePay({ - core: global.core, + new GooglePay(global.core, { + i18n: global.i18n, onAuthorized: onAuthorizedMock, onPaymentFailed: onPaymentFailedMock }); @@ -288,8 +285,8 @@ describe('GooglePay', () => { }); const onPaymentCompletedMock = jest.fn(); - const gpay = new GooglePay({ - core: global.core, + const gpay = new GooglePay(global.core, { + i18n: global.i18n, onAuthorized: onAuthorizedMock, onPaymentCompleted: onPaymentCompletedMock }); @@ -305,9 +302,7 @@ describe('GooglePay', () => { }); test('should make the payments call if onAuthorized is not provided', async () => { - const gpay = new GooglePay({ - core: global.core - }); + const gpay = new GooglePay(global.core, { i18n: global.i18n }); const paymentCall = jest.spyOn(gpay as any, 'makePaymentsCall'); @@ -322,7 +317,7 @@ describe('GooglePay', () => { describe('isAvailable()', () => { test('should resolve if GooglePay is available', async () => { - const gpay = new GooglePay({ core: global.core }); + const gpay = new GooglePay(global.core); gpay.isReadyToPay = jest.fn(() => { return Promise.resolve({ result: true }); }); @@ -331,7 +326,7 @@ describe('GooglePay', () => { }); test('should reject if is not available', async () => { - const gpay = new GooglePay({ core: global.core }); + const gpay = new GooglePay(global.core); gpay.isReadyToPay = jest.fn(() => { return Promise.resolve({ result: false }); }); @@ -340,7 +335,7 @@ describe('GooglePay', () => { }); test('should reject if "paymentMethodPresent" is false', async () => { - const gpay = new GooglePay({ core: global.core }); + const gpay = new GooglePay(global.core); gpay.isReadyToPay = jest.fn(() => { return Promise.resolve({ result: true, paymentMethodPresent: false }); }); @@ -351,21 +346,17 @@ describe('GooglePay', () => { describe('Process CA based configuration data', () => { test('Retrieves default merchantId', () => { - const gpay = new GooglePay({ core: global.core }); + const gpay = new GooglePay(global.core); expect(gpay.props.configuration.merchantId).toEqual(''); }); test('Retrieves merchantId from configuration', () => { - const gpay = new GooglePay({ - core: global.core, - configuration: { merchantId: 'abcdef', gatewayMerchantId: 'TestMerchant' } - }); + const gpay = new GooglePay(global.core, { configuration: { merchantId: 'abcdef', gatewayMerchantId: 'TestMerchant' } }); expect(gpay.props.configuration.merchantId).toEqual('abcdef'); }); test('Retrieves merchantId from configuration', () => { - const gpay = new GooglePay({ - core: global.core, + const gpay = new GooglePay(global.core, { configuration: { gatewayMerchantId: 'TestMerchant', merchantOrigin: 'example.com' @@ -375,8 +366,7 @@ describe('GooglePay', () => { }); test('Retrieves authJwt from configuration', () => { - const gpay = new GooglePay({ - core: global.core, + const gpay = new GooglePay(global.core, { configuration: { merchantId: 'abcdef', gatewayMerchantId: 'TestMerchant', authJwt: 'jwt.code' } }); expect(gpay.props.configuration.authJwt).toEqual('jwt.code'); diff --git a/packages/lib/src/components/GooglePay/GooglePay.tsx b/packages/lib/src/components/GooglePay/GooglePay.tsx index 9de377e834..af42ebccf7 100644 --- a/packages/lib/src/components/GooglePay/GooglePay.tsx +++ b/packages/lib/src/components/GooglePay/GooglePay.tsx @@ -3,13 +3,14 @@ import UIElement from '../internal/UIElement/UIElement'; import GooglePayService from './GooglePayService'; import GooglePayButton from './components/GooglePayButton'; import defaultProps from './defaultProps'; -import { GooglePayConfiguration } from './types'; import { formatGooglePayContactToAdyenAddressFormat, getGooglePayLocale } from './utils'; import collectBrowserInfo from '../../utils/browserInfo'; import AdyenCheckoutError from '../../core/Errors/AdyenCheckoutError'; import { TxVariants } from '../tx-variants'; -import { AddressData, PaymentResponseData, RawPaymentResponse } from '../../types/global-types'; import { sanitizeResponse, verifyPaymentDidNotFail } from '../internal/UIElement/utils'; +import type { AddressData, PaymentResponseData, RawPaymentResponse } from '../../types/global-types'; +import type { GooglePayConfiguration } from './types'; +import { ICore } from '../../core/types'; class GooglePay extends UIElement { public static type = TxVariants.googlepay; @@ -18,8 +19,8 @@ class GooglePay extends UIElement { protected readonly googlePay; - constructor(props) { - super(props); + constructor(checkout: ICore, props?: GooglePayConfiguration) { + super(checkout, props); this.handleAuthorization = this.handleAuthorization.bind(this); this.googlePay = new GooglePayService({ @@ -67,7 +68,7 @@ class GooglePay extends UIElement { public override submit = () => { new Promise((resolve, reject) => this.props.onClick(resolve, reject)) - .then(() => this.googlePay.initiatePayment(this.props)) + .then(() => this.googlePay.initiatePayment(this.props, this.core.options.countryCode)) .catch((error: google.payments.api.PaymentsError) => { if (error.statusCode === 'CANCELED') { this.handleError(new AdyenCheckoutError('CANCEL', error.toString(), { cause: error })); @@ -201,7 +202,7 @@ class GooglePay extends UIElement { * Use this method to prefetch a PaymentDataRequest configuration to improve loadPaymentData execution time on later user interaction. No value is returned. */ public prefetch = (): void => { - return this.googlePay.prefetchPaymentData(this.props); + return this.googlePay.prefetchPaymentData(this.props, this.core.options.countryCode); }; get browserInfo() { diff --git a/packages/lib/src/components/GooglePay/GooglePayService.ts b/packages/lib/src/components/GooglePay/GooglePayService.ts index c6b8c6db77..bd2d1626bb 100644 --- a/packages/lib/src/components/GooglePay/GooglePayService.ts +++ b/packages/lib/src/components/GooglePay/GooglePayService.ts @@ -2,15 +2,12 @@ import { isReadyToPayRequest, initiatePaymentRequest } from './requests'; import { resolveEnvironment } from './utils'; import Script from '../../utils/Script'; import config from './config'; - -interface GooglePayServiceProps { - [key: string]: any; -} +import type { GooglePayConfiguration } from './types'; class GooglePayService { public readonly paymentsClient: Promise; - constructor(props: GooglePayServiceProps) { + constructor(props: GooglePayConfiguration) { const environment = resolveEnvironment(props.environment); if (environment === 'TEST' && process.env.NODE_ENV === 'development') { console.warn('Google Pay initiated in TEST mode. Request non-chargeable payment methods suitable for testing.'); @@ -47,10 +44,10 @@ class GooglePayService { return this.paymentsClient.then(client => client.isReadyToPay(isReadyToPayRequest(props))); } - prefetchPaymentData(props): void { + prefetchPaymentData(props: GooglePayConfiguration, countryCode: string): void { if (!this.paymentsClient) throw new Error('Google Pay is not available'); - const paymentDataRequest = initiatePaymentRequest(props); + const paymentDataRequest = initiatePaymentRequest(props, countryCode); this.paymentsClient.then(client => client.prefetchPaymentData(paymentDataRequest)); } @@ -59,10 +56,10 @@ class GooglePayService { * @returns paymentData response from Google Pay API after user approves payment * @see {@link https://developers.google.com/pay/api/web/reference/object#PaymentData|PaymentData object reference} */ - initiatePayment(props): Promise { + initiatePayment(props: GooglePayConfiguration, countryCode: string): Promise { if (!this.paymentsClient) throw new Error('Google Pay is not available'); - const paymentDataRequest = initiatePaymentRequest(props); + const paymentDataRequest = initiatePaymentRequest(props, countryCode); return this.paymentsClient.then(client => client.loadPaymentData(paymentDataRequest)); } } diff --git a/packages/lib/src/components/GooglePay/defaultProps.ts b/packages/lib/src/components/GooglePay/defaultProps.ts index 0c62139100..c125a1dc75 100644 --- a/packages/lib/src/components/GooglePay/defaultProps.ts +++ b/packages/lib/src/components/GooglePay/defaultProps.ts @@ -26,7 +26,6 @@ export default { currency: 'USD' }, - countryCode: 'US', totalPriceStatus: 'FINAL' as google.payments.api.TotalPriceStatus, // Callbacks diff --git a/packages/lib/src/components/GooglePay/requests.test.ts b/packages/lib/src/components/GooglePay/requests.test.ts index cc1d282bec..c54503ceec 100644 --- a/packages/lib/src/components/GooglePay/requests.test.ts +++ b/packages/lib/src/components/GooglePay/requests.test.ts @@ -49,7 +49,7 @@ describe('Google Pay Requests', () => { describe('initiatePaymentRequest', () => { test('should get an initiatePaymentRequest', () => { - const paymentRequest = initiatePaymentRequest(defaultProps); + const paymentRequest = initiatePaymentRequest(defaultProps, 'US'); expect(paymentRequest.allowedPaymentMethods.length).toBeGreaterThan(0); expect(paymentRequest.allowedPaymentMethods[0].parameters.allowedAuthMethods).toBe(defaultProps.allowedAuthMethods); @@ -58,16 +58,19 @@ describe('Google Pay Requests', () => { }); test('should pass merchantOrigin correctly', () => { - const paymentRequest = initiatePaymentRequest({ - ...defaultProps, - configuration: { ...defaultProps.configuration, merchantOrigin: 'example.com' } - }); + const paymentRequest = initiatePaymentRequest( + { + ...defaultProps, + configuration: { ...defaultProps.configuration, merchantOrigin: 'example.com' } + }, + 'US' + ); expect(paymentRequest.merchantInfo.merchantOrigin).toBe('example.com'); }); test('should not have merchantOrigin when not in use', () => { - const paymentRequest = initiatePaymentRequest({ ...defaultProps }); + const paymentRequest = initiatePaymentRequest({ ...defaultProps }, 'US'); // eslint-disable-next-line no-prototype-builtins expect(paymentRequest.merchantInfo.hasOwnProperty('merchantOrigin')).toBe(false); diff --git a/packages/lib/src/components/GooglePay/requests.ts b/packages/lib/src/components/GooglePay/requests.ts index 6fcdd851e0..4673127933 100644 --- a/packages/lib/src/components/GooglePay/requests.ts +++ b/packages/lib/src/components/GooglePay/requests.ts @@ -44,7 +44,7 @@ export function getTransactionInfo({ countryCode = 'US', totalPriceStatus = 'FINAL', ...props -}: Omit): google.payments.api.TransactionInfo { +}: GooglePayConfiguration): google.payments.api.TransactionInfo { const formattedPrice = String(getDecimalAmount(amount.value, amount.currency)); return { @@ -56,11 +56,11 @@ export function getTransactionInfo({ }; } -export function initiatePaymentRequest({ configuration, ...props }: Omit): GooglePaymentDataRequest { +export function initiatePaymentRequest({ configuration, ...props }: GooglePayConfiguration, countryCode: string): GooglePaymentDataRequest { return { apiVersion: config.API_VERSION, apiVersionMinor: config.API_VERSION_MINOR, - transactionInfo: getTransactionInfo(props), + transactionInfo: getTransactionInfo({ countryCode, ...props }), merchantInfo: { merchantId: configuration.merchantId, merchantName: configuration.merchantName, diff --git a/packages/lib/src/components/Klarna/KlarnaPayments.test.tsx b/packages/lib/src/components/Klarna/KlarnaPayments.test.tsx index d0deeca34c..c783836c38 100644 --- a/packages/lib/src/components/Klarna/KlarnaPayments.test.tsx +++ b/packages/lib/src/components/Klarna/KlarnaPayments.test.tsx @@ -3,9 +3,9 @@ import KlarnaPayments from './KlarnaPayments'; import Dropin from '../Dropin'; describe('KlarnaPayments', () => { - const coreProps = { core: global.core, name: 'Klarna', i18n: global.i18n, loadingContext: 'test', modules: { resources: global.resources } }; + const coreProps = { name: 'Klarna', i18n: global.i18n, loadingContext: 'test', modules: { resources: global.resources } }; const renderKlarna = props => { - const KlarnaPaymentsEle = new KlarnaPayments({ + const KlarnaPaymentsEle = new KlarnaPayments(global.core, { ...coreProps, ...props }); @@ -23,11 +23,11 @@ describe('KlarnaPayments', () => { }); test('should call setStatus if elementRef is a drop-in', async () => { - const KlarnaPaymentsEle = new KlarnaPayments({ + const KlarnaPaymentsEle = new KlarnaPayments(global.core, { ...coreProps, ...{ paymentData: '', paymentMethodType: '', sdkData: undefined, useKlarnaWidget: false, showPayButton: false } }); - KlarnaPaymentsEle.elementRef = new Dropin({ core: global.core }); + KlarnaPaymentsEle.elementRef = new Dropin(global.core); render(KlarnaPaymentsEle.render()); const spy = jest.spyOn(KlarnaPaymentsEle.elementRef, 'setStatus'); // @ts-ignore to test @@ -40,7 +40,7 @@ describe('KlarnaPayments', () => { test('should call handleAdditionalDetails onComplete', async () => { const onAdditionalDetailsMock = jest.fn(() => {}); - const KlarnaPaymentsEle = new KlarnaPayments({ + const KlarnaPaymentsEle = new KlarnaPayments(global.core, { ...coreProps, ...{ paymentData: '', diff --git a/packages/lib/src/components/Klarna/KlarnaPayments.tsx b/packages/lib/src/components/Klarna/KlarnaPayments.tsx index 98dfadd346..e24af53067 100644 --- a/packages/lib/src/components/Klarna/KlarnaPayments.tsx +++ b/packages/lib/src/components/Klarna/KlarnaPayments.tsx @@ -6,6 +6,7 @@ import PayButton from '../internal/PayButton'; import { KlarnaContainer } from './components/KlarnaContainer/KlarnaContainer'; import { PaymentAction } from '../../types/global-types'; import { TxVariants } from '../tx-variants'; +import type { ICore } from '../../core/types'; class KlarnaPayments extends UIElement { public static type = TxVariants.klarna; @@ -15,8 +16,8 @@ class KlarnaPayments extends UIElement { useKlarnaWidget: false }; - constructor(props: KlarnConfiguration) { - super(props); + constructor(checkout: ICore, props?: KlarnConfiguration) { + super(checkout, props); this.onComplete = this.onComplete.bind(this); this.updateWithAction = this.updateWithAction.bind(this); diff --git a/packages/lib/src/components/MealVoucherFR/MealVoucherFR.tsx b/packages/lib/src/components/MealVoucherFR/MealVoucherFR.tsx index 41da59f674..7c1909a676 100644 --- a/packages/lib/src/components/MealVoucherFR/MealVoucherFR.tsx +++ b/packages/lib/src/components/MealVoucherFR/MealVoucherFR.tsx @@ -2,6 +2,7 @@ import GiftcardElement from '../Giftcard/Giftcard'; import { MealVoucherFields } from './components/MealVoucherFields'; import { TxVariants } from '../tx-variants'; import { GiftCardConfiguration } from '../Giftcard/types'; +import type { ICore } from '../../core/types'; export class MealVoucherFRElement extends GiftcardElement { public static type = TxVariants.mealVoucher_FR; @@ -12,8 +13,8 @@ export class MealVoucherFRElement extends GiftcardElement { TxVariants.mealVoucher_FR_groupeup ]; - constructor(props: GiftCardConfiguration) { - super({ + constructor(checkout: ICore, props?: GiftCardConfiguration) { + super(checkout, { ...props, pinRequired: true, expiryDateRequired: true, diff --git a/packages/lib/src/components/Multibanco/Multibanco.test.ts b/packages/lib/src/components/Multibanco/Multibanco.test.ts index 8b30f61f1a..1f6e5c1964 100644 --- a/packages/lib/src/components/Multibanco/Multibanco.test.ts +++ b/packages/lib/src/components/Multibanco/Multibanco.test.ts @@ -3,19 +3,19 @@ import { MultibancoElement } from './Multibanco'; describe('Multibanco', () => { describe('formatProps', () => { test('has a default name', () => { - const multibanco = new MultibancoElement({ core: global.core }); + const multibanco = new MultibancoElement(global.core); expect(multibanco.props.name).toEqual('Multibanco'); }); test('can override the name', () => { - const multibanco = new MultibancoElement({ core: global.core, name: 'Test' }); + const multibanco = new MultibancoElement(global.core, { name: 'Test' }); expect(multibanco.props.name).toEqual('Test'); }); }); describe('get data', () => { test('always returns a type', () => { - const multibanco = new MultibancoElement({ core: global.core }); + const multibanco = new MultibancoElement(global.core); expect(multibanco.data).toMatchObject({ paymentMethod: { type: 'multibanco' } }); }); }); diff --git a/packages/lib/src/components/OnlinebankingPL/OnlineBankingPL.test.ts b/packages/lib/src/components/OnlinebankingPL/OnlineBankingPL.test.ts index a3ac5f5208..ad9d7e0afa 100644 --- a/packages/lib/src/components/OnlinebankingPL/OnlineBankingPL.test.ts +++ b/packages/lib/src/components/OnlinebankingPL/OnlineBankingPL.test.ts @@ -4,7 +4,7 @@ import OnlineBankingPL from './OnlineBankingPL'; import { SRPanel } from '../../core/Errors/SRPanel'; test('should return expected data to perform the payment', () => { - const onlineBankingPL = new OnlineBankingPL({ core: global.core }); + const onlineBankingPL = new OnlineBankingPL(global.core); expect(onlineBankingPL.formatData()).toEqual({ paymentMethod: { type: 'onlineBanking_PL' } }); }); @@ -13,8 +13,7 @@ test('should show regulations and information obligation links', async () => { srPanel.props.moveFocus = false; const resources = global.resources; - const onlineBankingPL = new OnlineBankingPL({ - core: global.core, + const onlineBankingPL = new OnlineBankingPL(global.core, { issuers: [{ name: 'Issuer 1', id: '1' }], i18n: global.i18n, modules: { srPanel, resources } @@ -36,8 +35,7 @@ test('should show regulations and information obligation links', async () => { srPanel.props.moveFocus = false; const resources = global.resources; - const onlineBankingPL = new OnlineBankingPL({ - core: global.core, + const onlineBankingPL = new OnlineBankingPL(global.core, { issuers: [{ name: 'Issuer 1', id: '1' }], i18n: global.i18n, modules: { srPanel, resources } diff --git a/packages/lib/src/components/OnlinebankingPL/OnlineBankingPL.tsx b/packages/lib/src/components/OnlinebankingPL/OnlineBankingPL.tsx index e9e01c1305..b8ee945a1a 100644 --- a/packages/lib/src/components/OnlinebankingPL/OnlineBankingPL.tsx +++ b/packages/lib/src/components/OnlinebankingPL/OnlineBankingPL.tsx @@ -1,6 +1,7 @@ import IssuerListContainer from '../helpers/IssuerListContainer/IssuerListContainer'; import { TxVariants } from '../tx-variants'; import { IssuerListConfiguration } from '../helpers/IssuerListContainer/types'; +import type { ICore } from '../../core/types'; class OnlineBankingPL extends IssuerListContainer { public static type = TxVariants.onlineBanking_PL; @@ -15,8 +16,8 @@ class OnlineBankingPL extends IssuerListContainer { urls: [OnlineBankingPL.disclaimerUrlsMap.regulation, OnlineBankingPL.disclaimerUrlsMap.obligation] }; - constructor(props: IssuerListConfiguration) { - super({ ...props, termsAndConditions: OnlineBankingPL.termsAndConditions }); + constructor(checkout: ICore, props?: IssuerListConfiguration) { + super(checkout, { ...props, termsAndConditions: OnlineBankingPL.termsAndConditions }); } } diff --git a/packages/lib/src/components/Oxxo/Oxxo.test.ts b/packages/lib/src/components/Oxxo/Oxxo.test.ts index 8a1c8e6a62..c98780090f 100644 --- a/packages/lib/src/components/Oxxo/Oxxo.test.ts +++ b/packages/lib/src/components/Oxxo/Oxxo.test.ts @@ -3,13 +3,12 @@ import userEvent from '@testing-library/user-event'; import Oxxo from './Oxxo'; test('should return expected data to perform the payment', () => { - const oxxoElement = new Oxxo({ core: global.core }); + const oxxoElement = new Oxxo(global.core); expect(oxxoElement.formatData()).toEqual({ paymentMethod: { type: 'oxxo' } }); }); test('should show pay button if property is set to true', async () => { - const oxxoElement = new Oxxo({ - core: global.core, + const oxxoElement = new Oxxo(global.core, { loadingContext: 'test', showPayButton: true, i18n: global.i18n, @@ -23,8 +22,7 @@ test('should show pay button if property is set to true', async () => { test('should trigger submit when Pay button is pressed', async () => { const user = userEvent.setup(); - const oxxoElement = new Oxxo({ - core: global.core, + const oxxoElement = new Oxxo(global.core, { loadingContext: 'test', showPayButton: true, i18n: global.i18n, diff --git a/packages/lib/src/components/PayByBank/PayByBank.test.ts b/packages/lib/src/components/PayByBank/PayByBank.test.ts index b61b3954bc..ed3c4eabe5 100644 --- a/packages/lib/src/components/PayByBank/PayByBank.test.ts +++ b/packages/lib/src/components/PayByBank/PayByBank.test.ts @@ -3,13 +3,12 @@ import userEvent from '@testing-library/user-event'; import PayByBank from './PayByBank'; test('should return expected data to perform the payment', () => { - const payByBankEle = new PayByBank({ core: global.core, loadingContext: 'test', modules: { resources: global.resources } }); + const payByBankEle = new PayByBank(global.core, { loadingContext: 'test', modules: { resources: global.resources } }); expect(payByBankEle.formatData()).toEqual({ paymentMethod: { type: 'paybybank' } }); }); test('should show the pay button by default', async () => { - const payByBankEle = new PayByBank({ - core: global.core, + const payByBankEle = new PayByBank(global.core, { name: 'Pay By Bank', i18n: global.i18n, loadingContext: 'test', @@ -21,8 +20,7 @@ test('should show the pay button by default', async () => { }); test('should hide pay button if property is set to false', () => { - const payByBankEle = new PayByBank({ - core: global.core, + const payByBankEle = new PayByBank(global.core, { showPayButton: false, i18n: global.i18n, loadingContext: 'test', @@ -35,8 +33,7 @@ test('should hide pay button if property is set to false', () => { test('should trigger submit when Pay button is pressed', async () => { const user = userEvent.setup(); - const payByBankEle = new PayByBank({ - core: global.core, + const payByBankEle = new PayByBank(global.core, { showPayButton: true, name: 'Pay By Bank', i18n: global.i18n, diff --git a/packages/lib/src/components/PayByBank/PayByBank.tsx b/packages/lib/src/components/PayByBank/PayByBank.tsx index 01a9fbae2c..dd790478cc 100644 --- a/packages/lib/src/components/PayByBank/PayByBank.tsx +++ b/packages/lib/src/components/PayByBank/PayByBank.tsx @@ -1,12 +1,13 @@ import IssuerListContainer from '../helpers/IssuerListContainer/IssuerListContainer'; import { TxVariants } from '../tx-variants'; import { IssuerListConfiguration } from '../helpers/IssuerListContainer/types'; +import type { ICore } from '../../core/types'; class PayByBank extends IssuerListContainer { public static type = TxVariants.paybybank; - constructor(props: IssuerListConfiguration) { - super({ ...props, showPaymentMethodItemImages: true }); + constructor(checkout: ICore, props?: IssuerListConfiguration) { + super(checkout, { ...props, showPaymentMethodItemImages: true }); } } diff --git a/packages/lib/src/components/PayNow/PayNow.test.ts b/packages/lib/src/components/PayNow/PayNow.test.ts index 0e9fd056c8..8027f53e9f 100644 --- a/packages/lib/src/components/PayNow/PayNow.test.ts +++ b/packages/lib/src/components/PayNow/PayNow.test.ts @@ -3,21 +3,21 @@ import PayNow from './PayNow'; describe('PayNow', () => { describe('isValid', () => { test('should be always true', () => { - const paynow = new PayNow({ core: global.core }); + const paynow = new PayNow(global.core); expect(paynow.isValid).toBe(true); }); }); describe('get data', () => { test('always returns a type', () => { - const paynow = new PayNow({ core: global.core }); + const paynow = new PayNow(global.core); expect(paynow.data.paymentMethod.type).toBe('paynow'); }); }); describe('render', () => { test('does render something by default', () => { - const paynow = new PayNow({ core: global.core }); + const paynow = new PayNow(global.core); expect(paynow.render()).not.toBe(null); }); }); diff --git a/packages/lib/src/components/PayPal/Paypal.test.ts b/packages/lib/src/components/PayPal/Paypal.test.ts index 89435a6abe..336da6967e 100644 --- a/packages/lib/src/components/PayPal/Paypal.test.ts +++ b/packages/lib/src/components/PayPal/Paypal.test.ts @@ -2,7 +2,7 @@ import Paypal from './Paypal'; describe('Paypal', () => { test('Returns a data object', () => { - const paypal = new Paypal({ core: global.core }); + const paypal = new Paypal(global.core); expect(paypal.data).toEqual({ clientStateDataIndicator: true, paymentMethod: { subtype: 'sdk', type: 'paypal', checkoutAttemptId: 'do-not-track' } @@ -10,7 +10,7 @@ describe('Paypal', () => { }); test('should return subtype express if isExpress flag is set', () => { - const paypal = new Paypal({ core: global.core, isExpress: true }); + const paypal = new Paypal(global.core, { isExpress: true }); expect(paypal.data).toEqual({ clientStateDataIndicator: true, paymentMethod: { subtype: 'express', type: 'paypal', checkoutAttemptId: 'do-not-track' } @@ -18,13 +18,13 @@ describe('Paypal', () => { }); test('Is always valid', () => { - const paypal = new Paypal({ core: global.core }); + const paypal = new Paypal(global.core); expect(paypal.isValid).toBe(true); }); test('Prevents calling the submit method manually', async () => { const onErrorMock = jest.fn(); - const paypal = new Paypal({ core: global.core, onError: onErrorMock }); + const paypal = new Paypal(global.core, { onError: onErrorMock }); await paypal.submit(); expect(onErrorMock).toHaveBeenCalled(); }); @@ -32,13 +32,13 @@ describe('Paypal', () => { describe('Paypal configuration prop configures correctly', () => { test('Paypal element has configuration object with default values', () => { - const paypal = new Paypal({ core: global.core }); + const paypal = new Paypal(global.core); expect(paypal.props.configuration.merchantId).toEqual(''); expect(paypal.props.configuration.intent).toEqual(null); }); test('Paypal element has configuration object with values pulled from props.configuration', () => { - const paypal = new Paypal({ core: global.core, configuration: { merchantId: 'abcdef', intent: 'order' } }); + const paypal = new Paypal(global.core, { configuration: { merchantId: 'abcdef', intent: 'order' } }); expect(paypal.props.configuration.merchantId).toEqual('abcdef'); expect(paypal.props.configuration.intent).toEqual('order'); }); diff --git a/packages/lib/src/components/PayPal/Paypal.tsx b/packages/lib/src/components/PayPal/Paypal.tsx index f899d4b916..96b6f2568f 100644 --- a/packages/lib/src/components/PayPal/Paypal.tsx +++ b/packages/lib/src/components/PayPal/Paypal.tsx @@ -9,6 +9,7 @@ import CoreProvider from '../../core/Context/CoreProvider'; import AdyenCheckoutError from '../../core/Errors/AdyenCheckoutError'; import { ERRORS } from './constants'; import { TxVariants } from '../tx-variants'; +import type { ICore } from '../../core/types'; import { formatPaypalOrderContatcToAdyenFormat } from './utils/format-paypal-order-contact-to-adyen-format'; class PaypalElement extends UIElement { @@ -20,8 +21,8 @@ class PaypalElement extends UIElement { protected static defaultProps = defaultProps; - constructor(props: PayPalConfiguration) { - super(props); + constructor(checkout: ICore, props?: PayPalConfiguration) { + super(checkout, props); this.handleSubmit = this.handleSubmit.bind(this); } diff --git a/packages/lib/src/components/PersonalDetails/PersonalDetails.test.tsx b/packages/lib/src/components/PersonalDetails/PersonalDetails.test.tsx index a151d771f6..b8fd70291d 100644 --- a/packages/lib/src/components/PersonalDetails/PersonalDetails.test.tsx +++ b/packages/lib/src/components/PersonalDetails/PersonalDetails.test.tsx @@ -3,8 +3,7 @@ import PersonalDetails from './PersonalDetails'; describe('PersonalDetails', () => { test('should render FormInstruction by default', async () => { - const personalDetails = new PersonalDetails({ - core: global.core, + const personalDetails = new PersonalDetails(global.core, { i18n: global.i18n, loadingContext: 'test', modules: { resources: global.resources } diff --git a/packages/lib/src/components/Pix/Pix.test.ts b/packages/lib/src/components/Pix/Pix.test.ts index 9f83728b21..d6419fb798 100644 --- a/packages/lib/src/components/Pix/Pix.test.ts +++ b/packages/lib/src/components/Pix/Pix.test.ts @@ -3,14 +3,13 @@ import { render, screen, waitFor } from '@testing-library/preact'; import userEvent from '@testing-library/user-event'; test('should return only payment type if personalDetails is not required', async () => { - const pixElement = new Pix({ core: global.core }); + const pixElement = new Pix(global.core); expect(pixElement.data).toEqual({ clientStateDataIndicator: true, paymentMethod: { type: 'pix', checkoutAttemptId: 'do-not-track' } }); }); test('should show personal details form if enabled', async () => { const i18n = global.i18n; - const pixElement = new Pix({ - core: global.core, + const pixElement = new Pix(global.core, { personalDetailsRequired: true, i18n, loadingContext: 'ggg', @@ -25,7 +24,7 @@ test('should show personal details form if enabled', async () => { test('should show pay button if property is set to true', async () => { const i18n = global.i18n; - const pixElement = new Pix({ core: global.core, showPayButton: true, i18n, loadingContext: 'ggg', modules: { resources: global.resources } }); + const pixElement = new Pix(global.core, { showPayButton: true, i18n, loadingContext: 'ggg', modules: { resources: global.resources } }); render(pixElement.render()); expect(await screen.findByRole('button', { name: 'Continue to pix' })).toBeTruthy(); @@ -34,8 +33,7 @@ test('should show pay button if property is set to true', async () => { test('should validate Brazil SSN', async () => { const user = userEvent.setup(); const i18n = global.i18n; - const pixElement = new Pix({ - core: global.core, + const pixElement = new Pix(global.core, { personalDetailsRequired: true, i18n, loadingContext: 'ggg', @@ -64,7 +62,7 @@ test('should validate Brazil SSN', async () => { test('should trigger submit when Pay button is pressed', async () => { const user = userEvent.setup(); const i18n = global.i18n; - const pixElement = new Pix({ core: global.core, showPayButton: true, i18n, loadingContext: 'ggg', modules: { resources: global.resources } }); + const pixElement = new Pix(global.core, { showPayButton: true, i18n, loadingContext: 'ggg', modules: { resources: global.resources } }); pixElement.submit = jest.fn(); render(pixElement.render()); diff --git a/packages/lib/src/components/PromptPay/PromptPay.test.ts b/packages/lib/src/components/PromptPay/PromptPay.test.ts index 10aac6a52e..da31beba03 100644 --- a/packages/lib/src/components/PromptPay/PromptPay.test.ts +++ b/packages/lib/src/components/PromptPay/PromptPay.test.ts @@ -3,21 +3,21 @@ import PromptPay from './PromptPay'; describe('PromptPay', () => { describe('isValid', () => { test('should always be true', () => { - const promptPay = new PromptPay({ core: global.core }); + const promptPay = new PromptPay(global.core); expect(promptPay.isValid).toBe(true); }); }); describe('get data', () => { test('always returns a type', () => { - const promptPay = new PromptPay({ core: global.core }); + const promptPay = new PromptPay(global.core); expect(promptPay.data.paymentMethod.type).toBe('promptpay'); }); }); describe('render', () => { test('does render something by default', () => { - const promptPay = new PromptPay({ core: global.core }); + const promptPay = new PromptPay(global.core); expect(promptPay.render()).not.toBe(null); }); }); diff --git a/packages/lib/src/components/RatePay/RatePay.test.tsx b/packages/lib/src/components/RatePay/RatePay.test.tsx index e8ce578108..3f736fe368 100644 --- a/packages/lib/src/components/RatePay/RatePay.test.tsx +++ b/packages/lib/src/components/RatePay/RatePay.test.tsx @@ -3,14 +3,14 @@ import RatePay from './RatePay'; describe('RatePay', () => { describe('isValid', () => { test('returns false if there is no state', () => { - const ratePay = new RatePay({ core: global.core }); + const ratePay = new RatePay(global.core); expect(ratePay.isValid).toBe(false); }); }); describe('get data', () => { test('returns a type', () => { - const ratePay = new RatePay({ core: global.core }); + const ratePay = new RatePay(global.core); expect(ratePay.data.paymentMethod.type).toBe('ratepay'); }); }); diff --git a/packages/lib/src/components/Redirect/Redirect.test.tsx b/packages/lib/src/components/Redirect/Redirect.test.tsx index 0e3160b6a0..8ee697c304 100644 --- a/packages/lib/src/components/Redirect/Redirect.test.tsx +++ b/packages/lib/src/components/Redirect/Redirect.test.tsx @@ -13,7 +13,7 @@ jest.mock('../../utils/detectInIframeInSameOrigin', () => { describe('Redirect', () => { describe('isValid', () => { test('Is always valid', () => { - const redirect = new Redirect({ type: 'redirect', core: global.core }); + const redirect = new Redirect(global.core, { type: 'redirect' }); expect(redirect.isValid).toBe(true); }); }); @@ -45,7 +45,7 @@ describe('Redirect', () => { describe('Redirect formatData', () => { test('should send browserInfo in the data', () => { - const redirectElement = new RedirectElement({ core: global.core }); + const redirectElement = new RedirectElement(global.core); expect(redirectElement.formatData().browserInfo).not.toBeNull(); }); }); diff --git a/packages/lib/src/components/Sepa/Sepa.test.tsx b/packages/lib/src/components/Sepa/Sepa.test.tsx index 34ae04b9ec..66037890af 100644 --- a/packages/lib/src/components/Sepa/Sepa.test.tsx +++ b/packages/lib/src/components/Sepa/Sepa.test.tsx @@ -26,24 +26,24 @@ describe('Sepa', () => { describe('isValid', () => { test('Returns true if the state isValid', () => { - const sepa = mockStateChange(new Sepa({ core: global.core, loadingContext: 'test', modules: { resources: global.resources } })); + const sepa = mockStateChange(new Sepa(global.core, { loadingContext: 'test', modules: { resources: global.resources } })); expect(sepa.isValid).toBe(true); }); test('Returns false if the state is not valid ', () => { - const sepa = mockInvalidStateChange(new Sepa({ core: global.core, loadingContext: 'test', modules: { resources: global.resources } })); + const sepa = mockInvalidStateChange(new Sepa(global.core, { loadingContext: 'test', modules: { resources: global.resources } })); expect(sepa.isValid).toBe(false); }); }); describe('get data', () => { test('always returns a type', () => { - const sepa = mockStateChange(new Sepa({ core: global.core, loadingContext: 'test', modules: { resources: global.resources } })); + const sepa = mockStateChange(new Sepa(global.core, { loadingContext: 'test', modules: { resources: global.resources } })); expect(sepa.data.paymentMethod.type).toBe('sepadirectdebit'); }); test('returns necessary data from state', () => { - const sepa = mockStateChange(new Sepa({ core: global.core, loadingContext: 'test', modules: { resources: global.resources } })); + const sepa = mockStateChange(new Sepa(global.core, { loadingContext: 'test', modules: { resources: global.resources } })); expect(sepa.data.paymentMethod.iban).toBe('NL13TEST0123456789'); expect(sepa.data.paymentMethod.ownerName).toBe('A. Klaassen'); }); @@ -52,21 +52,20 @@ describe('Sepa', () => { describe('SepaElement render', () => { test('should render IbanInput by default', async () => { - const sepa = new Sepa({ core: global.core, i18n: global.i18n, loadingContext: 'test', modules: { resources: global.resources } }); + const sepa = new Sepa(global.core, { i18n: global.i18n, loadingContext: 'test', modules: { resources: global.resources } }); render(sepa.render()); expect(await screen.findByText('Holder Name')).toBeTruthy(); expect(await screen.findByText('Account Number (IBAN)')).toBeTruthy(); }); test('should render FormInstruction by default', async () => { - const sepa = new Sepa({ core: global.core, i18n: global.i18n, loadingContext: 'test', modules: { resources: global.resources } }); + const sepa = new Sepa(global.core, { i18n: global.i18n, loadingContext: 'test', modules: { resources: global.resources } }); render(sepa.render()); expect(await screen.findByText(/All fields are required unless marked otherwise./i)).toBeTruthy(); }); test('should not render FormInstruction if showFormInstruction sets to false', () => { - const sepa = new Sepa({ - core: global.core, + const sepa = new Sepa(global.core, { i18n: global.i18n, showFormInstruction: false, loadingContext: 'test', diff --git a/packages/lib/src/components/Sepa/Sepa.tsx b/packages/lib/src/components/Sepa/Sepa.tsx index 37baf567a9..30a535e844 100644 --- a/packages/lib/src/components/Sepa/Sepa.tsx +++ b/packages/lib/src/components/Sepa/Sepa.tsx @@ -5,6 +5,7 @@ import CoreProvider from '../../core/Context/CoreProvider'; import { SepaElementData, SepaConfiguration } from './types'; import { TxVariants } from '../tx-variants'; import FormInstruction from '../internal/FormInstruction'; +import type { ICore } from '../../core/types'; class SepaElement extends UIElement { public static type = TxVariants.sepadirectdebit; @@ -13,8 +14,8 @@ class SepaElement extends UIElement { showFormInstruction: true }; - constructor(props) { - super(props); + constructor(checkout: ICore, props?: SepaConfiguration) { + super(checkout, props); this.state = { ...this.state, ...{ data: { ibanNumber: '', ownerName: '' } } }; } diff --git a/packages/lib/src/components/Trustly/Trustly.test.tsx b/packages/lib/src/components/Trustly/Trustly.test.tsx index 0aaee1e480..58fa31be41 100644 --- a/packages/lib/src/components/Trustly/Trustly.test.tsx +++ b/packages/lib/src/components/Trustly/Trustly.test.tsx @@ -3,8 +3,7 @@ import Trustly from './Trustly'; describe('TrustlyElement', () => { test('should render payment description by default', async () => { - const trustly = new Trustly({ - core: global.core, + const trustly = new Trustly(global.core, { i18n: global.i18n, loadingContext: 'test', modules: { resources: global.resources } @@ -17,8 +16,7 @@ describe('TrustlyElement', () => { }); test('should render redirect button by default', async () => { - const trustly = new Trustly({ - core: global.core, + const trustly = new Trustly(global.core, { i18n: global.i18n, loadingContext: 'test', modules: { resources: global.resources } @@ -29,8 +27,7 @@ describe('TrustlyElement', () => { }); test('should not render pay button if showPayButton is false', () => { - const trustly = new Trustly({ - core: global.core, + const trustly = new Trustly(global.core, { i18n: global.i18n, loadingContext: 'test', modules: { resources: global.resources }, diff --git a/packages/lib/src/components/Twint/Twint.test.tsx b/packages/lib/src/components/Twint/Twint.test.tsx index dbe4d45378..180217abdf 100644 --- a/packages/lib/src/components/Twint/Twint.test.tsx +++ b/packages/lib/src/components/Twint/Twint.test.tsx @@ -3,27 +3,26 @@ import Twint from './Twint'; describe('Twint', () => { describe('isValid', () => { test('Is always valid', () => { - const twintElement = new Twint({ core: global.core }); + const twintElement = new Twint(global.core); expect(twintElement.isValid).toBe(true); }); }); describe('displayName', () => { test('Says saved in title if stored payment method', () => { - const twintElement = new Twint({ core: global.core, i18n: global.i18n, isStoredPaymentMethod: true }); + const twintElement = new Twint(global.core, { i18n: global.i18n, isStoredPaymentMethod: true }); expect(twintElement.displayName).toBe('Twint saved'); }); test('Just say TWINT in title if not stored payment method', () => { - const twintElement = new Twint({ core: global.core, i18n: global.i18n, name: 'TWINT' }); + const twintElement = new Twint(global.core, { i18n: global.i18n, name: 'TWINT' }); expect(twintElement.displayName).toBe('TWINT'); }); }); describe('payButtonLabel', () => { test('Says Pay + currency + amount', () => { - const twintElement = new Twint({ - core: global.core, + const twintElement = new Twint(global.core, { i18n: global.i18n, isStoredPaymentMethod: true, amount: { @@ -36,7 +35,7 @@ describe('Twint', () => { }); test('Says Continue to TWINT', () => { - const twintElement = new Twint({ core: global.core, i18n: global.i18n, name: 'TWINT' }); + const twintElement = new Twint(global.core, { i18n: global.i18n, name: 'TWINT' }); expect(twintElement.payButtonLabel()).toBe('Continue to TWINT'); }); }); diff --git a/packages/lib/src/components/WeChat/WeChat.test.ts b/packages/lib/src/components/WeChat/WeChat.test.ts index bd5e9524cb..683eb3716e 100644 --- a/packages/lib/src/components/WeChat/WeChat.test.ts +++ b/packages/lib/src/components/WeChat/WeChat.test.ts @@ -5,21 +5,21 @@ describe('WeChat', () => { describe('isValid', () => { test('should be always true', () => { - const wechat = new WeChat({ core: global.core }); + const wechat = new WeChat(global.core); expect(wechat.isValid).toBe(true); }); }); describe('get data', () => { test('always returns a type', () => { - const wechat = new WeChat({ core: global.core }); + const wechat = new WeChat(global.core); expect(wechat.data.paymentMethod.type).toBe('wechatpayQR'); }); }); describe('render', () => { test('does render something by default', () => { - const wechat = new WeChat({ core: global.core }); + const wechat = new WeChat(global.core); expect(wechat.render()).not.toBe(null); }); }); diff --git a/packages/lib/src/components/helpers/IssuerListContainer/IssuerListContainer.tsx b/packages/lib/src/components/helpers/IssuerListContainer/IssuerListContainer.tsx index 2d180e5a63..f138d6df46 100644 --- a/packages/lib/src/components/helpers/IssuerListContainer/IssuerListContainer.tsx +++ b/packages/lib/src/components/helpers/IssuerListContainer/IssuerListContainer.tsx @@ -7,6 +7,7 @@ import CoreProvider from '../../../core/Context/CoreProvider'; import RedirectButton from '../../internal/RedirectButton'; import SRPanelProvider from '../../../core/Errors/SRPanelProvider'; import { IssuerListConfiguration, IssuerListData } from './types'; +import type { ICore } from '../../../core/types'; class IssuerListContainer extends UIElement { protected static defaultProps = { @@ -18,8 +19,8 @@ class IssuerListContainer extends UIElement { showPaymentMethodItemImages: false }; - constructor(props: IssuerListConfiguration) { - super(props); + constructor(checkout: ICore, props?: IssuerListConfiguration) { + super(checkout, props); const getImage = props => this.resources.getImage(props); diff --git a/packages/lib/src/components/helpers/OpenInvoiceContainer/OpenInvoiceContainer.test.tsx b/packages/lib/src/components/helpers/OpenInvoiceContainer/OpenInvoiceContainer.test.tsx index c5fbc4a50f..5361f0ab65 100644 --- a/packages/lib/src/components/helpers/OpenInvoiceContainer/OpenInvoiceContainer.test.tsx +++ b/packages/lib/src/components/helpers/OpenInvoiceContainer/OpenInvoiceContainer.test.tsx @@ -1,7 +1,7 @@ import OpenInvoiceContainer from './OpenInvoiceContainer'; describe('OpenInvoiceContainer', () => { - const getWrapper = (props = {}) => new OpenInvoiceContainer({ core: global.core, ...props }); + const getWrapper = (props = {}) => new OpenInvoiceContainer(global.core, { ...props }); test('should use the passed countryCode in the address fieldsets', () => { const countryCode = 'US'; diff --git a/packages/lib/src/components/helpers/OpenInvoiceContainer/types.ts b/packages/lib/src/components/helpers/OpenInvoiceContainer/types.ts index 620a36406c..76d11a3305 100644 --- a/packages/lib/src/components/helpers/OpenInvoiceContainer/types.ts +++ b/packages/lib/src/components/helpers/OpenInvoiceContainer/types.ts @@ -1,10 +1,8 @@ import { OpenInvoiceProps } from '../../internal/OpenInvoice/types'; -import { ICore } from '../../../core/types'; import { h } from 'preact'; import { AddressSpecifications } from '../../internal/Address/types'; export interface OpenInvoiceConfiguration extends Partial { - core: ICore; consentCheckboxLabel?: h.JSX.Element; billingAddressRequiredFields?: string[]; billingAddressSpecification?: AddressSpecifications; diff --git a/packages/lib/src/components/internal/Await/Await.test.tsx b/packages/lib/src/components/internal/Await/Await.test.tsx index e40ebafedd..d1f1578dca 100644 --- a/packages/lib/src/components/internal/Await/Await.test.tsx +++ b/packages/lib/src/components/internal/Await/Await.test.tsx @@ -29,7 +29,7 @@ describe('Await', () => { type: 'mbway', awaitText: 'test' }; - const srPanel = new SRPanel({ core: global.core }); + const srPanel = new SRPanel(global.core); const renderAwait = (props: AwaitComponentProps) => { return render( // @ts-ignore ignore diff --git a/packages/lib/src/components/internal/BaseElement/BaseElement.test.ts b/packages/lib/src/components/internal/BaseElement/BaseElement.test.ts index cb6b9b17e7..778155bdf7 100644 --- a/packages/lib/src/components/internal/BaseElement/BaseElement.test.ts +++ b/packages/lib/src/components/internal/BaseElement/BaseElement.test.ts @@ -3,38 +3,41 @@ import { BaseElementProps } from './types'; import { mock } from 'jest-mock-extended'; import { ICore } from '../../../core/types'; +class MyElement extends BaseElement {} + describe('BaseElement', () => { - let MyElement; let core; beforeAll(() => { core = mock(); - MyElement = class extends BaseElement {}; }); describe('formatProps', () => { test('should return props by default', () => { - const baseElement = new MyElement({ core }); + const baseElement = new MyElement(core); const props = { prop1: 'prop1' }; + // @ts-ignore Testing internal method expect(baseElement.formatProps(props)).toBe(props); }); }); describe('formatData', () => { test('should return an empty object by default', () => { - const baseElement = new MyElement({ core }); + const baseElement = new MyElement(core); + // @ts-ignore Testing internal method expect(baseElement.formatData()).toEqual({}); }); }); describe('get data', () => { test('returns an empty object by default', () => { - const baseElement = new MyElement({ core }); + const baseElement = new MyElement(core); expect(baseElement.data).toEqual({ clientStateDataIndicator: true }); }); test('calls formatData to get the specific component output', () => { - const baseElement = new MyElement({ core }); + const baseElement = new MyElement(core); + // @ts-ignore Testing internal method const spy = jest.spyOn(baseElement, 'formatData'); expect(baseElement.data).toEqual({ clientStateDataIndicator: true }); expect(spy).toHaveBeenCalled(); @@ -43,7 +46,7 @@ describe('BaseElement', () => { describe('render', () => { test('does not render anything by default', () => { - const baseElement = new MyElement({ core }); + const baseElement = new MyElement(core); expect(() => baseElement.render()).toThrow(); }); }); diff --git a/packages/lib/src/components/internal/BaseElement/BaseElement.ts b/packages/lib/src/components/internal/BaseElement/BaseElement.ts index 1de2d926b1..df9e05a33e 100644 --- a/packages/lib/src/components/internal/BaseElement/BaseElement.ts +++ b/packages/lib/src/components/internal/BaseElement/BaseElement.ts @@ -2,9 +2,21 @@ import { ComponentChild, render } from 'preact'; import getProp from '../../../utils/getProp'; import uuid from '../../../utils/uuid'; import AdyenCheckoutError from '../../../core/Errors/AdyenCheckoutError'; -import { ICore } from '../../../core/types'; -import { BaseElementProps, IBaseElement } from './types'; -import { PaymentData } from '../../../types/global-types'; + +import type { ICore } from '../../../core/types'; +import type { BaseElementProps, IBaseElement } from './types'; +import type { PaymentData } from '../../../types/global-types'; + +/** + * Verify if the first parameter is instance of Core. + * We do not use 'instanceof' to avoid importing the Core class directly into this class. + * @param checkout + */ +function assertIsCoreInstance(checkout: ICore): checkout is ICore { + if (!checkout) return false; + const isCoreObject = typeof checkout.initialize === 'function' && typeof checkout.createFromAction === 'function'; + return isCoreObject; +} class BaseElement

implements IBaseElement { public readonly _id = `${this.constructor['type']}-${uuid()}`; @@ -18,22 +30,22 @@ class BaseElement

implements IBaseElement { protected static defaultProps = {}; - constructor(props: P) { - this.core = props.core; + constructor(checkout: ICore, props?: P) { + const isCoreInstance = assertIsCoreInstance(checkout); - if (!this.core) { + if (!isCoreInstance) { throw new AdyenCheckoutError( 'IMPLEMENTATION_ERROR', - `Trying to initialise the component '${this.constructor['type']}' without a reference to an instance of Checkout ('core' prop)` + `Trying to initialise the component '${this.constructor['type']}' without a reference to an instance of AdyenCheckout` ); } + this.core = checkout; this.buildElementProps(props); } - protected buildElementProps(componentProps: P) { - const { core, ...rest } = componentProps; - this.props = this.formatProps({ ...this.constructor['defaultProps'], ...rest }); + protected buildElementProps(componentProps?: P) { + this.props = this.formatProps({ ...this.constructor['defaultProps'], ...componentProps }); } /** diff --git a/packages/lib/src/components/internal/BaseElement/types.ts b/packages/lib/src/components/internal/BaseElement/types.ts index 15d226e983..5130a26224 100644 --- a/packages/lib/src/components/internal/BaseElement/types.ts +++ b/packages/lib/src/components/internal/BaseElement/types.ts @@ -1,4 +1,3 @@ -import { ICore } from '../../../core/types'; import { Order } from '../../../types/global-types'; import { SRPanel } from '../../../core/Errors/SRPanel'; import Analytics from '../../../core/Analytics'; @@ -7,7 +6,6 @@ import RiskElement from '../../../core/RiskModule'; import { ComponentChild } from 'preact'; export interface BaseElementProps { - core: ICore; order?: Order; modules?: { srPanel?: SRPanel; diff --git a/packages/lib/src/components/internal/Countdown/Countdown.test.tsx b/packages/lib/src/components/internal/Countdown/Countdown.test.tsx index d850d6029d..21eb4d4750 100644 --- a/packages/lib/src/components/internal/Countdown/Countdown.test.tsx +++ b/packages/lib/src/components/internal/Countdown/Countdown.test.tsx @@ -6,7 +6,7 @@ import SRPanelProvider from '../../../core/Errors/SRPanelProvider'; import CoreProvider from '../../../core/Context/CoreProvider'; describe('Countdown', () => { - const srPanel = new SRPanel({ core: global.core }); + const srPanel = new SRPanel(global.core); const customRender = ui => { // @ts-ignore render ui as children return render( diff --git a/packages/lib/src/components/internal/QRLoader/QRLoader.test.tsx b/packages/lib/src/components/internal/QRLoader/QRLoader.test.tsx index ff3caa814a..b96a583485 100644 --- a/packages/lib/src/components/internal/QRLoader/QRLoader.test.tsx +++ b/packages/lib/src/components/internal/QRLoader/QRLoader.test.tsx @@ -10,7 +10,7 @@ jest.mock('../../../core/Services/payment-status'); jest.useFakeTimers(); const getWrapper = ui => { - const srPanel = new SRPanel({ core: global.core }); + const srPanel = new SRPanel(global.core); return mount( {ui} diff --git a/packages/lib/src/components/internal/UIElement/UIElement.test.ts b/packages/lib/src/components/internal/UIElement/UIElement.test.ts index 277d391631..edfa49b8a9 100644 --- a/packages/lib/src/components/internal/UIElement/UIElement.test.ts +++ b/packages/lib/src/components/internal/UIElement/UIElement.test.ts @@ -42,7 +42,7 @@ describe('UIElement', () => { const txVariant = 'klarna_b2b'; - const element = new MyElement({ core: core, type: txVariant, modules: { resources } }); + const element = new MyElement(core, { type: txVariant, modules: { resources } }); const typeSpy = jest.spyOn(element, 'type', 'get'); const iconUrl = element.icon; @@ -55,7 +55,7 @@ describe('UIElement', () => { describe('onComplete()', () => { test('should call "onComplete" prop if available', () => { const onCompleteCb = jest.fn(); - const element = new MyElement({ core: core, onComplete: onCompleteCb }); + const element = new MyElement(core, { onComplete: onCompleteCb }); element.callOnComplete(); @@ -66,7 +66,7 @@ describe('UIElement', () => { describe('onChange()', () => { test('should call "onChange" prop if available', () => { const onChange = jest.fn(); - const element = new MyElement({ core: core, onChange }); + const element = new MyElement(core, { onChange }); element.callOnChange(); @@ -75,7 +75,7 @@ describe('UIElement', () => { test('should not trigger onValid method if the component is not valid', () => { const onValid = jest.fn(); - const element = new MyElement({ core: core, onValid }); + const element = new MyElement(core, { onValid }); element.callOnChange(); @@ -93,7 +93,7 @@ describe('UIElement', () => { } const onValid = jest.fn(); - const element = new MyValidElement({ core: core, onValid }); + const element = new MyValidElement(core, { onValid }); element.onChange(); expect(onValid.mock.calls.length).toBe(1); @@ -103,7 +103,7 @@ describe('UIElement', () => { describe('isValid()', () => { test('should be false by default', () => { class PristineUiElement extends UIElement {} - const element = new PristineUiElement({ core: core }); + const element = new PristineUiElement(core); expect(element.isValid).toBe(false); }); }); @@ -111,7 +111,7 @@ describe('UIElement', () => { describe('showValidation()', () => { test("should trigger the component's showValidation method", () => { const showValidation = jest.fn(); - const element = new MyElement({ core: core }); + const element = new MyElement(core); const componentRef = { showValidation @@ -126,12 +126,12 @@ describe('UIElement', () => { describe('get displayName()', () => { test('should use the name property if available', () => { - const element = new MyElement({ core: core, name: 'SuperPay' }); + const element = new MyElement(core, { name: 'SuperPay' }); expect(element.displayName).toEqual('SuperPay'); }); test('should use the constructor type if no name property is passed', () => { - const element = new MyElement({ core: core }); + const element = new MyElement(core); expect(element.displayName).toEqual('super_pay'); }); @@ -143,7 +143,7 @@ describe('UIElement', () => { } ]; - const element = new MyElement({ core: core }); + const element = new MyElement(core); expect(element.displayName).toEqual('SuperPayeee'); }); @@ -155,7 +155,7 @@ describe('UIElement', () => { } ]; - const element = new MyElement({ core: core, name: 'SuperbPay' }); + const element = new MyElement(core, { name: 'SuperbPay' }); expect(element.displayName).toEqual('SuperbPay'); }); }); @@ -177,7 +177,7 @@ describe('UIElement', () => { analytics: { enabled: false } }); - const element = new MyElement({ core: checkout }).mount('body'); + const element = new MyElement(checkout).mount('body'); const actionComponent = element.handleAction(fingerprintAction); expect(actionComponent instanceof ThreeDS2DeviceFingerprint).toEqual(true); @@ -204,7 +204,7 @@ describe('UIElement', () => { analytics: { enabled: false } }); - const element = new MyElement({ core: checkout, challengeWindowSize: '02' }).mount('body'); + const element = new MyElement(checkout, { challengeWindowSize: '02' }).mount('body'); const actionComponent = element.handleAction(challengeAction); expect(actionComponent instanceof ThreeDS2Challenge).toEqual(true); @@ -227,7 +227,7 @@ describe('UIElement', () => { resultCode: 'IdentifyShopper' }; - const element = new MyElement({ core }).mount('body'); + const element = new MyElement(core).mount('body'); expect(() => { // @ts-ignore tslint is not applicable here as merchant can potentially pass wrong object @@ -240,7 +240,7 @@ describe('UIElement', () => { paymentMethodType: 'scheme' }; - const element = new MyElement({ core }).mount('body'); + const element = new MyElement(core).mount('body'); expect(() => { // @ts-ignore tslint is not applicable here as merchant can potentially pass wrong object @@ -253,7 +253,7 @@ describe('UIElement', () => { test('should trigger showValidation() and not call makePaymentsCall() if component is not valid', () => { const showValidation = jest.fn(); - const element = new MyElement({ core: core }); + const element = new MyElement(core); // @ts-ignore Checking that internal method is not reached const makePaymentsCallSpy = jest.spyOn(element, 'makePaymentsCall'); @@ -284,8 +284,7 @@ describe('UIElement', () => { } }); - const element = new MyElement({ - core: core, + const element = new MyElement(core, { onSubmit: onSubmitMock, onPaymentCompleted: onPaymentCompletedMock }); @@ -315,8 +314,7 @@ describe('UIElement', () => { } }); - const element = new MyElement({ - core: core, + const element = new MyElement(core, { onPaymentCompleted: onPaymentCompletedMock }); @@ -350,8 +348,7 @@ describe('UIElement', () => { } }); - const element = new MyElement({ - core: core, + const element = new MyElement(core, { onSubmit: onSubmitMock, onPaymentFailed: onPaymentFailedMock }); @@ -371,8 +368,7 @@ describe('UIElement', () => { }); jest.spyOn(MyElement.prototype, 'isValid', 'get').mockReturnValue(true); - const element = new MyElement({ - core: core, + const element = new MyElement(core, { onSubmit: onSubmitMock, onPaymentFailed: onPaymentFailedMock }); @@ -399,8 +395,7 @@ describe('UIElement', () => { jest.spyOn(MyElement.prototype, 'isValid', 'get').mockReturnValue(true); - const element = new MyElement({ - core: core, + const element = new MyElement(core, { onSubmit: onSubmitMock }); @@ -446,8 +441,7 @@ describe('UIElement', () => { sessionResult: 'session-result' }); - const element = new MyElement({ - core: core, + const element = new MyElement(core, { onOrderUpdated: onOrderUpdatedMock }); @@ -496,8 +490,7 @@ describe('UIElement', () => { core.options.locale = 'en-US'; core.session = null; - const element = new MyElement({ - core: core, + const element = new MyElement(core, { onSubmit: onSubmitMock, onPaymentMethodsRequest: onPaymentMethodsRequestMock, onOrderUpdated: onOrderUpdatedMock @@ -559,8 +552,7 @@ describe('UIElement', () => { core.options.locale = 'en-US'; core.session = null; - const element = new MyElement({ - core: core, + const element = new MyElement(core, { onSubmit: onSubmitMock, onOrderUpdated: onOrderUpdatedMock, onError: onErrorMock @@ -593,8 +585,7 @@ describe('UIElement', () => { }); }); - const element = new MyElement({ - core: core, + const element = new MyElement(core, { onAdditionalDetails: onAdditionalDetailsMock, onPaymentCompleted: onPaymentCompletedMock }); @@ -623,8 +614,7 @@ describe('UIElement', () => { test('should make successfully payment/details using sessions flow', async () => { const onPaymentCompletedMock = jest.fn(); - const element = new MyElement({ - core: core, + const element = new MyElement(core, { onPaymentCompleted: onPaymentCompletedMock }); @@ -666,8 +656,7 @@ describe('UIElement', () => { }); }); - const element = new MyElement({ - core: core, + const element = new MyElement(core, { onAdditionalDetails: onAdditionalDetailsMock, onPaymentFailed: onPaymentFailedMock }); @@ -696,8 +685,7 @@ describe('UIElement', () => { actions.reject(); }); - const element = new MyElement({ - core: core, + const element = new MyElement(core, { onAdditionalDetails: onAdditionalDetailsMock, onPaymentFailed: onPaymentFailedMock }); diff --git a/packages/lib/src/components/internal/UIElement/UIElement.tsx b/packages/lib/src/components/internal/UIElement/UIElement.tsx index 880d7d9e77..41b3415ce6 100644 --- a/packages/lib/src/components/internal/UIElement/UIElement.tsx +++ b/packages/lib/src/components/internal/UIElement/UIElement.tsx @@ -4,11 +4,13 @@ import PayButton from '../PayButton'; import { cleanupFinalResult, sanitizeResponse, verifyPaymentDidNotFail } from './utils'; import AdyenCheckoutError from '../../../core/Errors/AdyenCheckoutError'; import { hasOwnProperty } from '../../../utils/hasOwnProperty'; -import { CoreConfiguration, ICore } from '../../../core/types'; import { Resources } from '../../../core/Context/Resources'; -import { NewableComponent } from '../../../core/core.registry'; -import { ComponentMethodsRef, IUIElement, PayButtonFunctionProps, UIElementProps, UIElementStatus } from './types'; -import { + +import type { CoreConfiguration, ICore } from '../../../core/types'; +import type { NewableComponent } from '../../../core/core.registry'; +import type { ComponentMethodsRef, IUIElement, PayButtonFunctionProps, UIElementProps, UIElementStatus } from './types'; +import type { CheckoutSessionDetailsResponse, CheckoutSessionPaymentResponse } from '../../../core/CheckoutSession/types'; +import type { AdditionalDetailsStateData, CheckoutAdvancedFlowResponse, Order, @@ -18,8 +20,8 @@ import { PaymentResponseData, RawPaymentResponse } from '../../../types/global-types'; + import './UIElement.scss'; -import { CheckoutSessionDetailsResponse, CheckoutSessionPaymentResponse } from '../../../core/CheckoutSession/types'; export abstract class UIElement

extends BaseElement

implements IUIElement { protected componentRef: any; @@ -35,8 +37,8 @@ export abstract class UIElement

exten */ public static txVariants: string[] = []; - constructor(props: P) { - super(props); + constructor(checkout: ICore, props?: P) { + super(checkout, props); // Only register UIElements that have the 'type' set. Drop-in for example does not have. if (this.constructor['type']) { @@ -64,12 +66,12 @@ export abstract class UIElement

exten this.storeElementRefOnCore(this.props); } - protected override buildElementProps(componentProps: P) { + protected override buildElementProps(componentProps?: P) { const globalCoreProps = this.core.getCorePropsForComponent(); - const isStoredPaymentMethod = !!componentProps.isStoredPaymentMethod; + const isStoredPaymentMethod = !!componentProps?.isStoredPaymentMethod; const paymentMethodsResponseProps = isStoredPaymentMethod ? {} - : this.core.paymentMethodsResponse.find(componentProps.type || this.constructor['type']); + : this.core.paymentMethodsResponse.find(componentProps?.type || this.constructor['type']); const finalProps = { showPayButton: true, @@ -306,7 +308,6 @@ export abstract class UIElement

exten } cleanupFinalResult(result); - this.props.onPaymentFailed?.(result, this.elementRef); }; @@ -316,7 +317,6 @@ export abstract class UIElement

exten } cleanupFinalResult(result); - this.props.onPaymentCompleted?.(result, this.elementRef); }; diff --git a/packages/lib/src/core/AdyenCheckout.ts b/packages/lib/src/core/AdyenCheckout.ts index 8617b0c311..def574c17a 100644 --- a/packages/lib/src/core/AdyenCheckout.ts +++ b/packages/lib/src/core/AdyenCheckout.ts @@ -1,13 +1,13 @@ -import { CoreConfiguration } from './types'; import Checkout from './index'; -import UIElement from '../components/internal/UIElement'; +import type { CoreConfiguration, ICore } from './types'; +import type { IUIElement } from '../components/internal/UIElement/types'; async function AdyenCheckout(props: CoreConfiguration): Promise { const checkout = new Checkout(props); return await checkout.initialize(); } -AdyenCheckout.register = (...items: (new (props) => UIElement)[]) => { +AdyenCheckout.register = (...items: (new (checkout: ICore, props) => IUIElement)[]) => { Checkout.register(...items); }; diff --git a/packages/lib/src/core/CheckoutSession/types.ts b/packages/lib/src/core/CheckoutSession/types.ts index 5bfa0f40a4..0008b8c46c 100644 --- a/packages/lib/src/core/CheckoutSession/types.ts +++ b/packages/lib/src/core/CheckoutSession/types.ts @@ -17,7 +17,7 @@ export type SessionConfiguration = { export type CheckoutSessionSetupResponse = { id: string; sessionData: string; - + countryCode?: string; amount: PaymentAmount; expiresAt: string; paymentMethods: any; diff --git a/packages/lib/src/core/Errors/SRPanel.test.tsx b/packages/lib/src/core/Errors/SRPanel.test.tsx index a1285952db..5ea2606c04 100644 --- a/packages/lib/src/core/Errors/SRPanel.test.tsx +++ b/packages/lib/src/core/Errors/SRPanel.test.tsx @@ -6,7 +6,7 @@ import { ICore } from '../types'; const core = mock(); describe('SRPanel disabled', () => { - new SRPanel({ core, enabled: false }); + new SRPanel(core, { enabled: false }); test('Does not render the SRPanel in the DOM', async () => { // Expect panel to not be present @@ -17,7 +17,7 @@ describe('SRPanel disabled', () => { describe('SRPanel in use', () => { test('Renders the SRPanel in the DOM, adds & clears messages in the panel', async () => { - const srPanel = new SRPanel({ core }); + const srPanel = new SRPanel(core); // Expect panel present - but empty expect(screen.getByTestId('ariaLiveSRPanel')).toBeTruthy(); diff --git a/packages/lib/src/core/Errors/SRPanel.tsx b/packages/lib/src/core/Errors/SRPanel.tsx index 6ad2dc3594..e8503b6518 100644 --- a/packages/lib/src/core/Errors/SRPanel.tsx +++ b/packages/lib/src/core/Errors/SRPanel.tsx @@ -3,6 +3,7 @@ import './SRPanel.scss'; import { AriaAttributes, SRPanelProps } from './types'; import BaseElement from '../../components/internal/BaseElement/BaseElement'; import { SRMessages, SRMessagesRef } from './SRMessages'; +import type { ICore } from '../types'; /** * A panel meant to hold messages that will be read out by ScreenReaders on an aria-live="polite" basis @@ -33,8 +34,8 @@ export class SRPanel extends BaseElement { private componentRef: SRMessagesRef; - constructor(props: SRPanelProps) { - super(props); + constructor(checkout: ICore, props?: SRPanelProps) { + super(checkout, props); this.id = this.props.id; this.showPanel = process.env.NODE_ENV !== 'production' ? this.props.showPanel : false; this._enabled = false; diff --git a/packages/lib/src/core/Errors/types.ts b/packages/lib/src/core/Errors/types.ts index 68c94e4e50..b93133f390 100644 --- a/packages/lib/src/core/Errors/types.ts +++ b/packages/lib/src/core/Errors/types.ts @@ -2,7 +2,7 @@ import { ValidationRuleResult } from '../../utils/Validator/ValidationRuleResult import { SFError } from '../../components/Card/components/CardInput/types'; import Language from '../../language'; import { StringObject } from '../../components/internal/Address/types'; -import { ICore } from '../types'; +import { BaseElementProps } from '../../components/internal/BaseElement/types'; export interface ErrorObj { // Describes an object with unknown keys whose value is always a ValidationRuleResult or FieldError @@ -36,8 +36,7 @@ export interface AriaAttributes { 'aria-atomic'?: 'true' | 'false'; } -export interface SRPanelProps { - core: ICore; +export interface SRPanelProps extends BaseElementProps { enabled?: boolean; node?: string; showPanel?: boolean; @@ -46,7 +45,7 @@ export interface SRPanelProps { ariaAttributes?: AriaAttributes; } -export type SRPanelConfig = Omit; +export type SRPanelConfig = Pick; export interface SRMessagesProps { setComponentRef: (ref: any) => void; diff --git a/packages/lib/src/core/ProcessResponse/PaymentAction/actionTypes.ts b/packages/lib/src/core/ProcessResponse/PaymentAction/actionTypes.ts index 2b24dc8ec1..5ac3d4f8e9 100644 --- a/packages/lib/src/core/ProcessResponse/PaymentAction/actionTypes.ts +++ b/packages/lib/src/core/ProcessResponse/PaymentAction/actionTypes.ts @@ -2,7 +2,7 @@ import { PaymentAction } from '../../../types/global-types'; import { get3DS2FlowProps } from '../../../components/ThreeDS2/components/utils'; import uuid from '../../../utils/uuid'; import type { IRegistry } from '../../core.registry'; -import { ICore } from '../../types'; +import type { ICore } from '../../types'; const createComponent = (core: ICore, registry: IRegistry, componentType, props) => { const Element = registry.getComponent(componentType); @@ -12,7 +12,7 @@ const createComponent = (core: ICore, registry: IRegistry, componentType, props) return; } - return new Element({ core, ...props, id: `${componentType}-${uuid()}` }); + return new Element(core, { ...props, id: `${componentType}-${uuid()}` }); }; const getActionHandler = statusType => { diff --git a/packages/lib/src/core/RiskModule/RiskModule.tsx b/packages/lib/src/core/RiskModule/RiskModule.tsx index f9e753f6a0..833cc910e0 100644 --- a/packages/lib/src/core/RiskModule/RiskModule.tsx +++ b/packages/lib/src/core/RiskModule/RiskModule.tsx @@ -4,6 +4,7 @@ import DeviceFingerprint from './components/DeviceFingerprint'; import base64 from '../../utils/base64'; import { RISK_DATA_VERSION, DEVICE_FINGERPRINT } from './constants'; import { BaseElementProps } from '../../components/internal/BaseElement/types'; +import type { ICore } from '../types'; export interface RiskModuleOptions { enabled: boolean; @@ -32,8 +33,8 @@ export default class RiskElement extends BaseElement { private nodeRiskContainer = null; - constructor(props) { - super(props); + constructor(checkout: ICore, props?) { + super(checkout, props); // Populate state with null values const riskElements = { diff --git a/packages/lib/src/core/core.component.props.test.ts b/packages/lib/src/core/core.component.props.test.ts index 0fdd20e04a..fdeb08f764 100644 --- a/packages/lib/src/core/core.component.props.test.ts +++ b/packages/lib/src/core/core.component.props.test.ts @@ -60,14 +60,15 @@ describe('Core - tests ensuring props reach components', () => { const checkout = new AdyenCheckout(coreOptions); await checkout.initialize(); - const component = new Card({ - core: checkout, + const component = new Card(checkout, { ...paymentMethodsResponse.storedPaymentMethods[0], hideCVC: true }); + // @ts-ignore Testing that property is available on component + expect(component.core).toEqual(checkout); + // Props from core.getCorePropsForComponent() - expect(component.props.core).toEqual(checkout); expect(component.props.loadingContext).toEqual('https://checkoutshopper-test.adyen.com/checkoutshopper/'); expect(component.props.clientKey).toEqual('test_F7_FEKJHF'); expect(component.props.amount.value).toEqual(19000); @@ -81,10 +82,12 @@ describe('Core - tests ensuring props reach components', () => { test('Test that expected props are propagated to a standalone Card ', async () => { const checkout = new AdyenCheckout(coreOptions); await checkout.initialize(); - const component = new Card({ core: checkout, showInstallmentAmounts: true }); + const component = new Card(checkout, { showInstallmentAmounts: true }); + + // @ts-ignore Testing that property is available on component + expect(component.core).toEqual(checkout); // Props from core.getCorePropsForComponent() - expect(component.props.core).toEqual(checkout); expect(component.props.loadingContext).toEqual('https://checkoutshopper-test.adyen.com/checkoutshopper/'); expect(component.props.clientKey).toEqual('test_F7_FEKJHF'); expect(component.props.amount.value).toEqual(19000); @@ -101,10 +104,12 @@ describe('Core - tests ensuring props reach components', () => { const checkout = new AdyenCheckout(coreOptions); await checkout.initialize(); - const component = new Redirect({ core: checkout, type: 'unionpay', ...pmObj }); + const component = new Redirect(checkout, { type: 'unionpay', ...pmObj }); + + // @ts-ignore Testing that property is available on component + expect(component.core).toEqual(checkout); // Props from core.getCorePropsForComponent() - expect(component.props.core).toEqual(checkout); expect(component.props.clientKey).toEqual('test_F7_FEKJHF'); expect(component.props.amount.value).toEqual(19000); @@ -115,10 +120,12 @@ describe('Core - tests ensuring props reach components', () => { test('Test that expected props are propagated to a standalone PayPal', async () => { const checkout = new AdyenCheckout(coreOptions); await checkout.initialize(); - const component = new PayPal({ core: checkout, enableMessages: true }); + const component = new PayPal(checkout, { enableMessages: true }); + + // @ts-ignore Testing that property is available on component + expect(component.core).toEqual(checkout); // Props from core.getCorePropsForComponent() - expect(component.props.core).toEqual(checkout); expect(component.props.clientKey).toEqual('test_F7_FEKJHF'); expect(component.props.amount.value).toEqual(19000); @@ -135,14 +142,14 @@ describe('Core - tests ensuring props reach components', () => { test('Dropin component receives correct props ', async () => { const checkout = new AdyenCheckout(coreOptions); await checkout.initialize(); - const dropin = new Dropin({ - core: checkout, + const dropin = new Dropin(checkout, { showStoredPaymentMethods: false, openFirstPaymentMethod: false }); // Props from core.getCorePropsForComponent() - expect(dropin.props.core).toEqual(checkout); + // @ts-ignore Testing that property is available on component + expect(dropin.core).toEqual(checkout); expect(dropin.props.clientKey).toEqual('test_F7_FEKJHF'); expect(dropin.props.amount.value).toEqual(19000); @@ -162,8 +169,7 @@ describe('Core - tests ensuring props reach components', () => { beforeEach(async () => { checkout = new AdyenCheckout(coreOptions); await checkout.initialize(); - dropin = new Dropin({ - core: checkout, + dropin = new Dropin(checkout, { paymentMethodsConfiguration: { card: { hasHolderName: true, @@ -190,8 +196,9 @@ describe('Core - tests ensuring props reach components', () => { const storedCard = dropin.dropinRef.state.storedPaymentElements[0]; + expect(storedCard.core).toEqual(checkout); + // Props from core.getCorePropsForComponent() - expect(storedCard.props.core).toEqual(checkout); expect(storedCard.props.i18n).not.toEqual(null); expect(storedCard.props.clientKey).toEqual('test_F7_FEKJHF'); expect(storedCard.props.amount.value).toEqual(19000); @@ -218,8 +225,9 @@ describe('Core - tests ensuring props reach components', () => { const card = dropin.dropinRef.state.elements[0]; + expect(card.core).toEqual(checkout); + // Props from core.getCorePropsForComponent() - expect(card.props.core).toEqual(checkout); expect(card.props.clientKey).toEqual('test_F7_FEKJHF'); expect(card.props.amount.value).toEqual(19000); @@ -246,8 +254,9 @@ describe('Core - tests ensuring props reach components', () => { const paypal = dropin.dropinRef.state.elements[1]; + expect(paypal.core).toEqual(checkout); + // Props from core.getCorePropsForComponent() - expect(paypal.props.core).toEqual(checkout); expect(paypal.props.clientKey).toEqual('test_F7_FEKJHF'); expect(paypal.props.amount.value).toEqual(19000); @@ -271,8 +280,9 @@ describe('Core - tests ensuring props reach components', () => { const redirect = dropin.dropinRef.state.elements[2]; + expect(redirect.core).toEqual(checkout); + // Props from core.getCorePropsForComponent() - expect(redirect.props.core).toEqual(checkout); expect(redirect.props.clientKey).toEqual('test_F7_FEKJHF'); expect(redirect.props.amount.value).toEqual(19000); diff --git a/packages/lib/src/core/core.registry.ts b/packages/lib/src/core/core.registry.ts index 49481aa11d..b30e2b0727 100644 --- a/packages/lib/src/core/core.registry.ts +++ b/packages/lib/src/core/core.registry.ts @@ -3,13 +3,15 @@ import ThreeDS2Challenge from '../components/ThreeDS2/ThreeDS2Challenge'; import ThreeDS2DeviceFingerprint from '../components/ThreeDS2/ThreeDS2DeviceFingerprint'; import Redirect from '../components/Redirect'; import { TxVariants } from '../components/tx-variants'; +import type { ICore } from './types'; +import type { IUIElement } from '../components/internal/UIElement/types'; function assertClassHasType(Class: any): Class is typeof UIElement { const hasValidType = typeof Class.type === 'string' && !!Class.type; return hasValidType; } -export type NewableComponent = new (props) => UIElement; +export type NewableComponent = new (checkout: ICore, props?) => IUIElement; export interface IRegistry { add(...items: NewableComponent[]): void; diff --git a/packages/lib/src/core/core.test.ts b/packages/lib/src/core/core.test.ts index 9cfe719287..2a655c1532 100644 --- a/packages/lib/src/core/core.test.ts +++ b/packages/lib/src/core/core.test.ts @@ -149,8 +149,7 @@ describe('Core', () => { }); await checkout.initialize(); - const dropin = new Ideal({ - core: checkout, + const dropin = new Ideal(checkout, { onAdditionalDetails: onAdditionalDetailsComponent }); @@ -165,9 +164,7 @@ describe('Core', () => { }); await checkout.initialize(); - const dropin = new Ideal({ - core: checkout - }); + const dropin = new Ideal(checkout); expect(dropin.props.onAdditionalDetails).toBe(onAdditionalDetailsGlobal); }); @@ -190,8 +187,7 @@ describe('Core', () => { await checkout.initialize(); - const dropin = new Dropin({ - core: checkout, + const dropin = new Dropin(checkout, { onAdditionalDetails: onAdditionalDetailsComponent, paymentMethodComponents: [Ideal], paymentMethodsConfiguration: { @@ -244,7 +240,7 @@ describe('Core', () => { }); await checkout.initialize(); - const component = new Dropin({ core: checkout }).mount('body'); + const component = new Dropin(checkout).mount('body'); const spy = jest.spyOn(component, 'update'); await checkout.update(); diff --git a/packages/lib/src/core/core.ts b/packages/lib/src/core/core.ts index bcf61453f8..b3f7b22cb0 100644 --- a/packages/lib/src/core/core.ts +++ b/packages/lib/src/core/core.ts @@ -76,12 +76,13 @@ class Core implements ICore { return this.session .setupSession(this.options) .then(sessionResponse => { - const { amount, shopperLocale, paymentMethods, ...rest } = sessionResponse; + const { amount, shopperLocale, countryCode, paymentMethods, ...rest } = sessionResponse; this.setOptions({ ...rest, amount: this.options.order ? this.options.order.remainingAmount : amount, - locale: this.options.locale || shopperLocale + locale: this.options.locale || shopperLocale, + countryCode: this.options.countryCode || countryCode }); this.createPaymentMethodsList(paymentMethods); @@ -275,7 +276,7 @@ class Core implements ICore { } this.modules = Object.freeze({ - risk: new RiskModule({ ...this.options, loadingContext: this.loadingContext, core: this }), + risk: new RiskModule(this, { ...this.options, loadingContext: this.loadingContext }), analytics: new Analytics({ loadingContext: this.loadingContext, clientKey: this.options.clientKey, @@ -285,7 +286,7 @@ class Core implements ICore { }), resources: new Resources(this.cdnContext), i18n: new Language(this.options.locale, this.options.translations, this.options.translationFile), - srPanel: new SRPanel({ core: this, ...this.options.srConfig }) + srPanel: new SRPanel(this, { ...this.options.srConfig }) }); } } diff --git a/packages/lib/src/create-component.umd.test.ts b/packages/lib/src/create-component.umd.test.ts index c3298b9738..4a876d13be 100644 --- a/packages/lib/src/create-component.umd.test.ts +++ b/packages/lib/src/create-component.umd.test.ts @@ -5,40 +5,32 @@ import createComponent from './create-component.umd'; describe('createComponent', () => { test('should create Card', () => { - const component = createComponent('card', { - core: global.core - }); + const component = createComponent('card', global.core); expect(component.type).toBe('card'); expect(component).toBeInstanceOf(CardElement); }); test('should create Econtext with right paymentType', () => { - const econtextSevenEleven = createComponent('econtext_seven_eleven', { - core: global.core - }); + const econtextSevenEleven = createComponent('econtext_seven_eleven', global.core); expect(econtextSevenEleven.type).toBe('econtext_seven_eleven'); expect(econtextSevenEleven).toBeInstanceOf(EcontextElement); - const econtextAtm = createComponent('econtext_atm', { - core: global.core - }); + const econtextAtm = createComponent('econtext_atm', global.core); expect(econtextAtm.type).toBe('econtext_atm'); expect(econtextAtm).toBeInstanceOf(EcontextElement); }); test('should create Redirect', () => { - const component = createComponent('paybright', { - core: global.core - }); + const component = createComponent('paybright', global.core); expect(component.type).toBe('paybright'); expect(component).toBeInstanceOf(RedirectElement); }); test('should throw Error if paymentType is not passed', () => { - expect(() => createComponent('', { core: global.core })).toThrow(); + expect(() => createComponent('', global.core)).toThrow(); }); test('should throw Error if paymentType is dropin', () => { - expect(() => createComponent('dropin', { core: global.core })).toThrow(); + expect(() => createComponent('dropin', global.core)).toThrow(); }); }); diff --git a/packages/lib/src/create-component.umd.ts b/packages/lib/src/create-component.umd.ts index e1369b4e24..7cb87a8ade 100644 --- a/packages/lib/src/create-component.umd.ts +++ b/packages/lib/src/create-component.umd.ts @@ -2,6 +2,7 @@ import { TxVariants } from './components/tx-variants'; import Redirect from './components/Redirect/Redirect'; import { ComponentsMap } from './components/components-map'; import type { PaymentMethodOptions, PaymentMethods } from './components/Dropin/types'; +import type { ICore } from './core/types'; /** * Helper function designed to be used internally by Adyen Plugins to create components @@ -9,11 +10,20 @@ import type { PaymentMethodOptions, PaymentMethods } from './components/Dropin/t * WARNING: This function breaks tree-shaking as it import all Components to create the mapping. It must be used only with UMD bundle * * @param paymentType - Component payment type + * @param checkout - Instance of AdyenCheckout * @param options - Component configuration */ -function createComponent(paymentType: T, options: PaymentMethodOptions): InstanceType; -function createComponent(paymentType: string, options: PaymentMethodOptions): InstanceType; -function createComponent(paymentType: any, options: any): any { +function createComponent( + paymentType: T, + checkout: ICore, + options?: PaymentMethodOptions +): InstanceType; +function createComponent( + paymentType: string, + checkout: ICore, + options?: PaymentMethodOptions +): InstanceType; +function createComponent(paymentType: any, checkout: ICore, options?: any): any { if (typeof paymentType !== 'string' || !paymentType) { throw Error('createComponent: Invalid payment type. Make sure to pass a string value'); } @@ -24,7 +34,7 @@ function createComponent(paymentType: any, options: any): any { const Class = ComponentsMap[paymentType] || Redirect; - return new Class({ + return new Class(checkout, { type: paymentType, ...options }); diff --git a/packages/lib/storybook/helpers/checkout-api-calls.ts b/packages/lib/storybook/helpers/checkout-api-calls.ts index 5bbaa9ebb5..bf06ef9e64 100644 --- a/packages/lib/storybook/helpers/checkout-api-calls.ts +++ b/packages/lib/storybook/helpers/checkout-api-calls.ts @@ -1,7 +1,7 @@ import paymentMethodsConfig from '../config/paymentMethodsConfig'; import paymentsConfig from '../config/paymentsConfig'; import { httpPost } from '../utils/http-post'; -import { +import type { Order, OrderStatus, PaymentAction, @@ -11,7 +11,7 @@ import { AdditionalDetailsStateData, ResultCode } from '../../src/types'; -import { CheckoutSessionSetupResponse } from '../../src/core/CheckoutSession/types'; +import type { CheckoutSessionSetupResponse } from '../../src/core/CheckoutSession/types'; export const getPaymentMethods = async (configuration?: any): Promise => await httpPost('paymentMethods', { ...paymentMethodsConfig, ...configuration }); diff --git a/packages/lib/storybook/helpers/checkout-handlers.ts b/packages/lib/storybook/helpers/checkout-handlers.ts index 00d4fcfc25..f59bc47127 100644 --- a/packages/lib/storybook/helpers/checkout-handlers.ts +++ b/packages/lib/storybook/helpers/checkout-handlers.ts @@ -77,6 +77,8 @@ export function handleChange(state: any, _component: UIElement) { console.groupCollapsed(`onChange - ${state.data.paymentMethod.type}`); console.log('isValid', state.isValid); console.log('data', state.data); + // @ts-ignore Logging internal data for testing purposes + console.log('node', component._node); console.log('state', state); console.groupEnd(); } diff --git a/packages/lib/storybook/stories/cards/Bancontact.stories.tsx b/packages/lib/storybook/stories/cards/Bancontact.stories.tsx index 51475f7494..efb223b252 100644 --- a/packages/lib/storybook/stories/cards/Bancontact.stories.tsx +++ b/packages/lib/storybook/stories/cards/Bancontact.stories.tsx @@ -13,7 +13,7 @@ const meta: MetaConfiguration = { const createComponent = (args: PaymentMethodStoryProps, context) => { const { componentConfiguration } = args; const checkout = getStoryContextCheckout(context); - const bancontact = new Bancontact({ core: checkout, ...componentConfiguration }); + const bancontact = new Bancontact(checkout, componentConfiguration); return ; }; diff --git a/packages/lib/storybook/stories/cards/Card.stories.tsx b/packages/lib/storybook/stories/cards/Card.stories.tsx index 72164d8302..a06aac1bb3 100644 --- a/packages/lib/storybook/stories/cards/Card.stories.tsx +++ b/packages/lib/storybook/stories/cards/Card.stories.tsx @@ -13,7 +13,7 @@ const meta: MetaConfiguration = { const createComponent = (args: PaymentMethodStoryProps, context) => { const { componentConfiguration } = args; const checkout = getStoryContextCheckout(context); - const card = new Card({ core: checkout, ...componentConfiguration }); + const card = new Card(checkout, componentConfiguration); return ; }; diff --git a/packages/lib/storybook/stories/components/ANCV.stories.tsx b/packages/lib/storybook/stories/components/ANCV.stories.tsx index db0f800934..7ba633c2b0 100644 --- a/packages/lib/storybook/stories/components/ANCV.stories.tsx +++ b/packages/lib/storybook/stories/components/ANCV.stories.tsx @@ -15,7 +15,7 @@ export const Default: ANCVStory = { render: (args, context) => { const { componentConfiguration } = args; const checkout = getStoryContextCheckout(context); - const ancv = new ANCV({ core: checkout, ...componentConfiguration }); + const ancv = new ANCV(checkout, componentConfiguration); return ; }, args: { diff --git a/packages/lib/storybook/stories/components/Klarna.stories.tsx b/packages/lib/storybook/stories/components/Klarna.stories.tsx index a190adc007..180089af98 100644 --- a/packages/lib/storybook/stories/components/Klarna.stories.tsx +++ b/packages/lib/storybook/stories/components/Klarna.stories.tsx @@ -13,7 +13,7 @@ const meta: MetaConfiguration = { const createComponent = (args: PaymentMethodStoryProps, context) => { const { componentConfiguration } = args; const checkout = getStoryContextCheckout(context); - const klarna = new Klarna({ core: checkout, ...componentConfiguration }); + const klarna = new Klarna(checkout, componentConfiguration); return ; }; diff --git a/packages/lib/storybook/stories/components/Pix.stories.tsx b/packages/lib/storybook/stories/components/Pix.stories.tsx index 0e0d48377e..496f302afd 100644 --- a/packages/lib/storybook/stories/components/Pix.stories.tsx +++ b/packages/lib/storybook/stories/components/Pix.stories.tsx @@ -13,7 +13,7 @@ const meta: MetaConfiguration = { const createComponent = (args: PaymentMethodStoryProps, context) => { const { componentConfiguration } = args; const checkout = getStoryContextCheckout(context); - const pix = new Pix({ core: checkout, ...componentConfiguration }); + const pix = new Pix(checkout, componentConfiguration); return ; }; diff --git a/packages/lib/storybook/stories/components/UPI.stories.tsx b/packages/lib/storybook/stories/components/UPI.stories.tsx index bb02f69c8c..7b7496eefc 100644 --- a/packages/lib/storybook/stories/components/UPI.stories.tsx +++ b/packages/lib/storybook/stories/components/UPI.stories.tsx @@ -14,7 +14,7 @@ export const Default: UpiStory = { render: (args: PaymentMethodStoryProps, context) => { const { componentConfiguration } = args; const checkout = getStoryContextCheckout(context); - const upi = new UPI({ core: checkout, ...componentConfiguration }); + const upi = new UPI(checkout, componentConfiguration); return ; }, args: { diff --git a/packages/lib/storybook/stories/dropin/Dropin.stories.tsx b/packages/lib/storybook/stories/dropin/Dropin.stories.tsx index ed3ea8d640..5752260a3b 100644 --- a/packages/lib/storybook/stories/dropin/Dropin.stories.tsx +++ b/packages/lib/storybook/stories/dropin/Dropin.stories.tsx @@ -36,7 +36,7 @@ export const Auto: DropinStory = { AdyenCheckout.register(...Classes); const checkout = getStoryContextCheckout(context); - const dropin = new DropinComponent({ core: checkout, ...componentConfiguration }); + const dropin = new DropinComponent(checkout, componentConfiguration); return ; } }; diff --git a/packages/lib/storybook/stories/issuer-lists/Dotpay.stories.tsx b/packages/lib/storybook/stories/issuer-lists/Dotpay.stories.tsx index c3b69b81c5..4fb6cb7ee9 100644 --- a/packages/lib/storybook/stories/issuer-lists/Dotpay.stories.tsx +++ b/packages/lib/storybook/stories/issuer-lists/Dotpay.stories.tsx @@ -14,7 +14,7 @@ export const Default: DotpayStory = { render: (args: PaymentMethodStoryProps, context) => { const { componentConfiguration } = args; const checkout = getStoryContextCheckout(context); - const dotpay = new Dotpay({ core: checkout, ...componentConfiguration }); + const dotpay = new Dotpay(checkout, componentConfiguration); return ; }, args: { diff --git a/packages/lib/storybook/stories/issuer-lists/Ideal.stories.tsx b/packages/lib/storybook/stories/issuer-lists/Ideal.stories.tsx index 5f757ddfef..80601d7b8e 100644 --- a/packages/lib/storybook/stories/issuer-lists/Ideal.stories.tsx +++ b/packages/lib/storybook/stories/issuer-lists/Ideal.stories.tsx @@ -13,7 +13,7 @@ const meta: MetaConfiguration = { const createComponent = (args, context) => { const { componentConfiguration } = args; const checkout = getStoryContextCheckout(context); - const ideal = new Ideal({ core: checkout, ...componentConfiguration }); + const ideal = new Ideal(checkout, componentConfiguration); return ; }; diff --git a/packages/lib/storybook/stories/types.ts b/packages/lib/storybook/stories/types.ts index 31185f0eec..9e49135a84 100644 --- a/packages/lib/storybook/stories/types.ts +++ b/packages/lib/storybook/stories/types.ts @@ -9,8 +9,7 @@ type GlobalStoryProps = { }; export interface PaymentMethodStoryProps extends GlobalStoryProps { - // Core is passed in the 'render' step, so no need to enforce it here - componentConfiguration: Omit; + componentConfiguration: T; } export type StoryConfiguration = StoryObj>; diff --git a/packages/lib/storybook/stories/vouchers/Oxxo.stories.tsx b/packages/lib/storybook/stories/vouchers/Oxxo.stories.tsx index 241e1360bb..f7137222da 100644 --- a/packages/lib/storybook/stories/vouchers/Oxxo.stories.tsx +++ b/packages/lib/storybook/stories/vouchers/Oxxo.stories.tsx @@ -14,7 +14,7 @@ export const Default: OxxoStory = { render: (args: PaymentMethodStoryProps, context) => { const { componentConfiguration } = args; const checkout = getStoryContextCheckout(context); - const oxxo = new Oxxo({ core: checkout, ...componentConfiguration }); + const oxxo = new Oxxo(checkout, componentConfiguration); return ; }, args: { diff --git a/packages/lib/storybook/stories/wallets/ApplePay.stories.tsx b/packages/lib/storybook/stories/wallets/ApplePay.stories.tsx index 4e0f419654..c23db30442 100644 --- a/packages/lib/storybook/stories/wallets/ApplePay.stories.tsx +++ b/packages/lib/storybook/stories/wallets/ApplePay.stories.tsx @@ -13,17 +13,13 @@ const meta: MetaConfiguration = { const createComponent = (args: PaymentMethodStoryProps, context) => { const { componentConfiguration } = args; const checkout = getStoryContextCheckout(context); - const applepay = new ApplePay({ core: checkout, ...componentConfiguration }); + const applepay = new ApplePay(checkout, componentConfiguration); return ; }; export const Default: ApplePayStory = { render: createComponent, - args: { - componentConfiguration: { - countryCode: 'US' - } - } + args: {} }; export default meta; diff --git a/packages/lib/storybook/stories/wallets/ApplePayExpress.stories.tsx b/packages/lib/storybook/stories/wallets/ApplePayExpress.stories.tsx index 5715049d46..ba63bffcfe 100644 --- a/packages/lib/storybook/stories/wallets/ApplePayExpress.stories.tsx +++ b/packages/lib/storybook/stories/wallets/ApplePayExpress.stories.tsx @@ -123,7 +123,7 @@ const ApplePayAmountHelper = createApplePayAmountHelper(); const createComponent = (args: PaymentMethodStoryProps, context) => { const { componentConfiguration } = args; const checkout = getStoryContextCheckout(context); - const applepay = new ApplePay({ core: checkout, ...componentConfiguration }); + const applepay = new ApplePay(checkout, componentConfiguration); return ; }; @@ -152,8 +152,6 @@ export const Express: ApplePayStory = { amount: INITIAL_AMOUNT, shopperLocale: SHOPPER_LOCALE, componentConfiguration: { - countryCode: COUNTRY_CODE, - onSubmit: async (state, component, actions) => { try { const paymentData = { diff --git a/packages/lib/storybook/stories/wallets/GooglePay.stories.tsx b/packages/lib/storybook/stories/wallets/GooglePay.stories.tsx index 7f2f24e648..c50392e95e 100644 --- a/packages/lib/storybook/stories/wallets/GooglePay.stories.tsx +++ b/packages/lib/storybook/stories/wallets/GooglePay.stories.tsx @@ -13,7 +13,7 @@ const meta: MetaConfiguration = { const createComponent = (args: PaymentMethodStoryProps, context) => { const { componentConfiguration } = args; const checkout = getStoryContextCheckout(context); - const googlepay = new GooglePay({ core: checkout, ...componentConfiguration }); + const googlepay = new GooglePay(checkout, componentConfiguration); return ; }; diff --git a/packages/lib/storybook/stories/wallets/GooglePayExpress.stories.tsx b/packages/lib/storybook/stories/wallets/GooglePayExpress.stories.tsx index 03226ecdc2..d1b0d6a6db 100644 --- a/packages/lib/storybook/stories/wallets/GooglePayExpress.stories.tsx +++ b/packages/lib/storybook/stories/wallets/GooglePayExpress.stories.tsx @@ -142,7 +142,7 @@ function calculateNewTransactionInfo(countryCode: string, selectedShippingOption const createComponent = (args: PaymentMethodStoryProps, context) => { const { componentConfiguration } = args; const checkout = getStoryContextCheckout(context); - const googlepay = new GooglePay({ core: checkout, ...componentConfiguration }); + const googlepay = new GooglePay(checkout, componentConfiguration); return ; }; diff --git a/packages/lib/storybook/stories/wallets/PayPal.stories.tsx b/packages/lib/storybook/stories/wallets/PayPal.stories.tsx index 7f19a256d2..757c37aff4 100644 --- a/packages/lib/storybook/stories/wallets/PayPal.stories.tsx +++ b/packages/lib/storybook/stories/wallets/PayPal.stories.tsx @@ -14,7 +14,7 @@ export const Default: PayPalStory = { render: (args: PaymentMethodStoryProps, context) => { const { componentConfiguration } = args; const checkout = getStoryContextCheckout(context); - const paypal = new PayPal({ core: checkout, ...componentConfiguration }); + const paypal = new PayPal(checkout, componentConfiguration); return ; } }; diff --git a/packages/lib/tsconfig.json b/packages/lib/tsconfig.json index 1a545ee6c6..8da9a3ef9a 100644 --- a/packages/lib/tsconfig.json +++ b/packages/lib/tsconfig.json @@ -40,5 +40,5 @@ "./src/**/*", "./src/types/custom.d.ts", ], - "exclude": ["node_modules", "./dist/**", "**/*.scss"] + "exclude": ["node_modules", "./dist/**", "**/*.scss"], } diff --git a/packages/playground/src/pages/Cards/Cards.js b/packages/playground/src/pages/Cards/Cards.js index ab7614bc67..bc89a19fec 100644 --- a/packages/playground/src/pages/Cards/Cards.js +++ b/packages/playground/src/pages/Cards/Cards.js @@ -61,8 +61,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = if (checkout.paymentMethodsResponse.storedPaymentMethods && checkout.paymentMethodsResponse.storedPaymentMethods.length > 0) { const storedCardData = checkout.paymentMethodsResponse.storedPaymentMethods[2]; - window.storedCard = new Card({ - core: checkout, + window.storedCard = new Card(checkout, { ...storedCardData, disclaimerMessage // maskSecurityCode: true @@ -77,8 +76,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = } if (onlyShowCard || showComps.card) { - window.card = new Card({ - core: checkout, + window.card = new Card(checkout, { challengeWindowSize: '01', _disableClickToPay: true, // hasHolderName: true, @@ -93,8 +91,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = // Credit card with installments if (!onlyShowCard && showComps.cardWithInstallments) { - window.cardWithInstallments = new Card({ - core: checkout, + window.cardWithInstallments = new Card(checkout, { _disableClickToPay: true, brands: ['mc', 'visa', 'amex', 'bcmc', 'maestro'], installmentOptions: { @@ -123,19 +120,18 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = // // Card mounted in a React app if (!onlyShowCard && showComps.cardInReact) { - window.cardReact = new Card({ core: checkout }); + window.cardReact = new Card(checkout); MockReactApp(window, 'cardReact', document.querySelector('.react-card-field'), false); } // Bancontact card if (!onlyShowCard && showComps.bcmcCard) { - window.bancontact = new Bancontact({ core: checkout }).mount('.bancontact-field'); + window.bancontact = new Bancontact(checkout).mount('.bancontact-field'); } // Credit card with AVS if (!onlyShowCard && showComps.avsCard) { - window.cardAvs = new Card({ - core: checkout, + window.cardAvs = new Card(checkout, { // type: 'scheme', brands: ['mc', 'visa', 'amex', 'bcmc', 'maestro'], enableStoreDetails: true, @@ -170,8 +166,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = } if (!onlyShowCard && showComps.addressLookup) { - window.addressLookupCard = new Card({ - core: checkout, + window.addressLookupCard = new Card(checkout, { brands: ['mc', 'visa', 'amex', 'bcmc', 'maestro'], billingAddressRequired: true, onAddressLookup: searchFunctionExample @@ -179,8 +174,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = } if (!onlyShowCard && showComps.avsPartialCard) { - window.avsPartialCard = new Card({ - core: checkout, + window.avsPartialCard = new Card(checkout, { // type: 'scheme', brands: ['mc', 'visa', 'amex', 'bcmc', 'maestro'], // billingAddress config: @@ -194,8 +188,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = // Credit card with KCP Authentication if (!onlyShowCard && showComps.kcpCard) { - window.kcpCard = new Card({ - core: checkout, + window.kcpCard = new Card(checkout, { // type: 'scheme', brands: ['mc', 'visa', 'amex', 'bcmc', 'maestro', 'korean_local_card'], // Set koreanAuthenticationRequired AND countryCode so KCP fields show at start @@ -212,8 +205,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = * Make sure that the initialization values are being set in the /paymentMethods response, * as part of the 'scheme' configuration object */ - window.ctpCard = new Card({ - core: checkout, + window.ctpCard = new Card(checkout, { type: 'scheme', brands: ['mc', 'visa'], configuration: { diff --git a/packages/playground/src/pages/Components/Components.js b/packages/playground/src/pages/Components/Components.js index 3d3d9662c2..e61885d507 100644 --- a/packages/playground/src/pages/Components/Components.js +++ b/packages/playground/src/pages/Components/Components.js @@ -50,7 +50,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = // // SEPA Bank Transfer // window.bankTransfer = new BankTransfer(checkout, { type: 'bankTransfer_IBAN' }).mount('.bankTransfer-field');// BankTransfer doesn't need constructor - window.bankTransfer = new BankTransfer({ core: checkout }).mount('.bankTransfer-field'); // BankTransfer needs constructor + window.bankTransfer = new BankTransfer(checkout).mount('.bankTransfer-field'); // BankTransfer needs constructor window.bankTransferResult = checkout .createFromAction({ paymentMethodType: 'bankTransfer_IBAN', @@ -68,14 +68,13 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = .mount('.bankTransfer-result-field'); // // MBWay - window.mbway = new MBWay({ core: checkout }).mount('.mbway-field'); + window.mbway = new MBWay(checkout).mount('.mbway-field'); // Klarna Widget - window.klarnaButton = new Klarna({ core: checkout, useKlarnaWidget: true }).mount('.klarna-field'); + window.klarnaButton = new Klarna(checkout, { useKlarnaWidget: true }).mount('.klarna-field'); // ACH - window.ach = new Ach({ - core: checkout, + window.ach = new Ach(checkout, { // holderNameRequired: false, // hasHolderName: false, // onConfigSuccess: obj => { @@ -97,33 +96,32 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = }).mount('.ach-field'); // SEPA Direct Debit - window.sepa = new SepaDirectDebit({ - core: checkout, + window.sepa = new SepaDirectDebit(checkout, { countryCode: 'NL', holderName: true }).mount('.sepa-field'); // // SEPA Direct Debit - window.vipps = new Vipps({ core: checkout }).mount('.vipps-field'); + window.vipps = new Vipps(checkout).mount('.vipps-field'); // // // BLIK - window.blik = new Blik({ core: checkout }).mount('.blik-field'); + window.blik = new Blik(checkout).mount('.blik-field'); // // // Giropay - window.giropay = new Giropay({ core: checkout }).mount('.giropay-field'); + window.giropay = new Giropay(checkout).mount('.giropay-field'); // // // UPI - window.upi = new UPI({ core: checkout }).mount('.upi-field'); + window.upi = new UPI(checkout).mount('.upi-field'); // PIX - window.pix = new Pix({ core: checkout, countdownTime: 5 }).mount('.pix-field'); + window.pix = new Pix(checkout, { countdownTime: 5 }).mount('.pix-field'); // Oxxo - window.oxxo = new Oxxo({ core: checkout }).mount('.oxxo-field'); + window.oxxo = new Oxxo(checkout).mount('.oxxo-field'); // Twint - window.twint = new Twint({ core: checkout }).mount('.twint-field'); + window.twint = new Twint(checkout).mount('.twint-field'); // Redirect - window.alipay = new Redirect({ core: checkout, type: 'alipay' }).mount('.redirect-field'); + window.alipay = new Redirect(checkout, { type: 'alipay' }).mount('.redirect-field'); }); diff --git a/packages/playground/src/pages/CustomCards/CustomCards.js b/packages/playground/src/pages/CustomCards/CustomCards.js index b0a633db2f..5f9f180c9f 100644 --- a/packages/playground/src/pages/CustomCards/CustomCards.js +++ b/packages/playground/src/pages/CustomCards/CustomCards.js @@ -76,8 +76,7 @@ const initCheckout = async () => { window.checkout = await AdyenCheckout(configObj); // SECURED FIELDS - window.customCard = new CustomCard({ - core: window.checkout, + window.customCard = new CustomCard(window.checkout, { type: 'card', brands: ['mc', 'visa', 'amex', 'bcmc', 'maestro', 'cartebancaire', 'synchrony_plcc'], styles, @@ -113,8 +112,7 @@ const initCheckout = async () => { window.customCardSi = showOtherExamples && - new CustomCard({ - core: window.checkout, + new CustomCard(window.checkout, { type: 'card', brands: ['mc', 'visa', 'amex', 'bcmc', 'maestro'], styles: styles_si, @@ -128,8 +126,7 @@ const initCheckout = async () => { window.fancyCustomCard = showOtherExamples && - new CustomCard({ - core: window.checkout, + new CustomCard(window.checkout, { type: 'card', brands: ['mc', 'visa', 'amex', 'bcmc', 'maestro'], styles: fancyStyles, @@ -158,8 +155,7 @@ const initCheckout2 = async () => { window.materialDesignCustomCard = showOtherExamples && - new CustomCard({ - core: window.checkout, + new CustomCard(window.checkout, { type: 'card', brands: ['mc', 'visa', 'amex', 'bcmc', 'maestro'], styles: materialStyles, diff --git a/packages/playground/src/pages/Dropin/manual.js b/packages/playground/src/pages/Dropin/manual.js index 82bf645d86..df2173379b 100644 --- a/packages/playground/src/pages/Dropin/manual.js +++ b/packages/playground/src/pages/Dropin/manual.js @@ -107,8 +107,7 @@ export async function initManual() { // Handle Amazon Pay redirect result if (amazonCheckoutSessionId) { - window.amazonpay = new AmazonPay({ - core: checkout, + window.amazonpay = new AmazonPay(checkout, { amazonCheckoutSessionId, showOrderButton: false, onSubmit: state => { @@ -128,19 +127,8 @@ export async function initManual() { return Promise.resolve(true); } - // const gpay = new GooglePay({ - // core: checkout, - // shippingAddressRequired: true, - // shippingAddressParameters: { - // phoneNumberRequired: true - // }, - - // billingAddressRequired: true - // }).mount('#dropin-container'); - - const dropin = new Dropin({ - core: checkout, - paymentMethodComponents: [Card, Ideal, GooglePay, PayPal, Ach, Affirm, WeChat, Giftcard, AmazonPay], + const dropin = new Dropin(checkout, { + paymentMethodComponents: [Card, GooglePay, PayPal, Ach, Affirm, WeChat, Giftcard, AmazonPay], instantPaymentTypes: ['googlepay'], paymentMethodsConfiguration: { card: { @@ -160,5 +148,5 @@ export async function initManual() { handleRedirectResult(); - return [checkout]; + return [checkout, dropin]; } diff --git a/packages/playground/src/pages/Dropin/session.js b/packages/playground/src/pages/Dropin/session.js index b71f10cb16..abf8cfa374 100644 --- a/packages/playground/src/pages/Dropin/session.js +++ b/packages/playground/src/pages/Dropin/session.js @@ -41,8 +41,7 @@ export async function initSession() { } }); - const dropin = new Dropin({ - core: checkout, + const dropin = new Dropin(checkout, { instantPaymentTypes: ['googlepay'], paymentMethodComponents: [Card, WeChat, Giftcard, PayPal, Ach, GooglePay, Ideal], paymentMethodsConfiguration: { diff --git a/packages/playground/src/pages/DropinAuto/manual.js b/packages/playground/src/pages/DropinAuto/manual.js index 379abbe798..d1af527621 100644 --- a/packages/playground/src/pages/DropinAuto/manual.js +++ b/packages/playground/src/pages/DropinAuto/manual.js @@ -114,11 +114,29 @@ export async function initManual() { }); } + // Handle Amazon Pay redirect result + if (amazonCheckoutSessionId) { + window.amazonpay = new AmazonPay(checkout, { + amazonCheckoutSessionId, + showOrderButton: false, + onSubmit: state => { + makePayment(state.data).then(result => { + if (result.action) { + dropin.handleAction(result.action); + } else { + handleFinalState(result.resultCode, dropin); + } + }); + } + }).mount('body'); + + window.amazonpay.submit(); + } + return Promise.resolve(true); } - const dropin = new Dropin({ - core: checkout, + const dropin = new Dropin(checkout, { instantPaymentTypes: ['googlepay'], paymentMethodsConfiguration: { card: { diff --git a/packages/playground/src/pages/DropinAuto/session.js b/packages/playground/src/pages/DropinAuto/session.js index c752a3837e..e40c97663b 100644 --- a/packages/playground/src/pages/DropinAuto/session.js +++ b/packages/playground/src/pages/DropinAuto/session.js @@ -44,8 +44,7 @@ export async function initSession() { } }); - const dropin = new Dropin({ - core: checkout, + const dropin = new Dropin(checkout, { instantPaymentTypes: ['googlepay'], paymentMethodsConfiguration: { paywithgoogle: { diff --git a/packages/playground/src/pages/DropinUMD/manual.js b/packages/playground/src/pages/DropinUMD/manual.js index afffcef5dc..589d6ffc0d 100644 --- a/packages/playground/src/pages/DropinUMD/manual.js +++ b/packages/playground/src/pages/DropinUMD/manual.js @@ -107,11 +107,30 @@ export async function initManual() { return true; }); } + + // Handle Amazon Pay redirect result + if (amazonCheckoutSessionId) { + window.amazonpay = new AmazonPay(checkout, { + amazonCheckoutSessionId, + showOrderButton: false, + onSubmit: state => { + makePayment(state.data).then(result => { + if (result.action) { + dropin.handleAction(result.action); + } else { + handleFinalState(result.resultCode, dropin); + } + }); + } + }).mount('body'); + + window.amazonpay.submit(); + } + return Promise.resolve(true); } - const dropin = new Dropin({ - core: checkout, + const dropin = new Dropin(checkout, { instantPaymentTypes: ['googlepay'], paymentMethodsConfiguration: { card: { diff --git a/packages/playground/src/pages/DropinUMD/session.js b/packages/playground/src/pages/DropinUMD/session.js index 9c1307272c..deb6d05085 100644 --- a/packages/playground/src/pages/DropinUMD/session.js +++ b/packages/playground/src/pages/DropinUMD/session.js @@ -41,8 +41,7 @@ export async function initSession() { } }); - const dropin = new Dropin({ - core: checkout, + const dropin = new Dropin(checkout, { instantPaymentTypes: ['googlepay'], paymentMethodsConfiguration: { paywithgoogle: { diff --git a/packages/playground/src/pages/GiftCards/GiftCards.js b/packages/playground/src/pages/GiftCards/GiftCards.js index 61e2931542..40c7d01f16 100644 --- a/packages/playground/src/pages/GiftCards/GiftCards.js +++ b/packages/playground/src/pages/GiftCards/GiftCards.js @@ -27,8 +27,7 @@ import getTranslationFile from '../../config/getTranslation'; amount }); - window.giftcard = new Giftcard({ - core: window.checkout, + window.giftcard = new Giftcard(window.checkout, { type: 'giftcard', brand: 'valuelink', onBalanceCheck: async (resolve, reject, data) => { @@ -44,8 +43,7 @@ import getTranslationFile from '../../config/getTranslation'; }).mount('#genericgiftcard-container'); // TODO: Double-check if it is supposed to be like that - window.giftcard = new MealVoucherFR({ - core: window.checkout, + window.giftcard = new MealVoucherFR(window.checkout, { type: 'mealVoucher_FR_natixis', brand: 'mealVoucher_FR_natixis', onBalanceCheck: async (resolve, reject, data) => { @@ -101,8 +99,7 @@ import getTranslationFile from '../../config/getTranslation'; checkoutConfirmButton.addEventListener('click', giftcardSubmit); checkoutCardButton.addEventListener('click', cardSubmit); - window.giftcard = new Giftcard({ - core: sessionCheckout, + window.giftcard = new Giftcard(sessionCheckout, { type: 'giftcard', brand: 'svs', onOrderUpdated: () => { @@ -115,5 +112,5 @@ import getTranslationFile from '../../config/getTranslation'; } }).mount('#giftcard-session-container'); - window.card = new Card({ core: sessionCheckout }).mount('#payment-method-container'); + window.card = new Card(sessionCheckout).mount('#payment-method-container'); })(); diff --git a/packages/playground/src/pages/Helpers/Helpers.js b/packages/playground/src/pages/Helpers/Helpers.js index daf6b39743..4025e8ab92 100644 --- a/packages/playground/src/pages/Helpers/Helpers.js +++ b/packages/playground/src/pages/Helpers/Helpers.js @@ -26,8 +26,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = }); // Adyen Giving - window.donation = new Donation({ - core: window.checkout, + window.donation = new Donation(window.checkout, { onDonate: (state, component) => { console.log({ state, component }); setTimeout(() => component.setStatus('ready'), 1000); @@ -53,14 +52,12 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = }).mount('.donation-field'); // Personal details - window.personalDetails = new PersonalDetails({ - core: window.checkout, + window.personalDetails = new PersonalDetails(window.checkout, { onChange: console.log }).mount('.personalDetails-field'); // Address - window.address = new Address({ - core: window.checkout, + window.address = new Address(window.checkout, { onAddressLookup: searchFunctionExample, onChange: console.log, validationRules: { diff --git a/packages/playground/src/pages/IssuerLists/IssuerLists.js b/packages/playground/src/pages/IssuerLists/IssuerLists.js index 1c32153a81..2dd70dfa85 100644 --- a/packages/playground/src/pages/IssuerLists/IssuerLists.js +++ b/packages/playground/src/pages/IssuerLists/IssuerLists.js @@ -44,30 +44,30 @@ import getTranslationFile from '../../config/getTranslation'; }); // iDEAL - window.ideal = new Ideal({ core: window.core }).mount('.ideal-field'); + window.ideal = new Ideal(window.core).mount('.ideal-field'); // BillDesk Online - window.billdesk_online = new BillDeskOnline({ core: window.core }).mount('.billdesk_online-field'); + window.billdesk_online = new BillDeskOnline(window.core).mount('.billdesk_online-field'); // return; // BillDesk Wallet - window.billdesk_wallet = new BillDeskWallet({ core: window.core }).mount('.billdesk_wallet-field'); + window.billdesk_wallet = new BillDeskWallet(window.core).mount('.billdesk_wallet-field'); // PayU CashCard - window.payu_cashcard = new PayuCashcard({ core: window.core }).mount('.payu_cc-field'); + window.payu_cashcard = new PayuCashcard(window.core).mount('.payu_cc-field'); // PayU NetBanking - window.payu_nb = new PayuNetBanking({ core: window.core }).mount('.payu_nb-field'); + window.payu_nb = new PayuNetBanking(window.core).mount('.payu_nb-field'); // Dotpay - window.dotpay = new Dotpay({ core: window.core }).mount('.dotpay-field'); + window.dotpay = new Dotpay(window.core).mount('.dotpay-field'); // Online banking PL - window.onlineBanking_PL = new OnlineBankingPL({ core: window.core }).mount('.onlinebanking_PL-field'); + window.onlineBanking_PL = new OnlineBankingPL(window.core).mount('.onlinebanking_PL-field'); // Molpay MY - window.molpay = new MolPayEBankingMY({ core: window.core }).mount('.molpay-field'); + window.molpay = new MolPayEBankingMY(window.core).mount('.molpay-field'); // Pay By Bank - window.paybybank_NL = new PayByBank({ core: window.core }).mount('.paybybank_NL-field'); + window.paybybank_NL = new PayByBank(window.core).mount('.paybybank_NL-field'); })(); diff --git a/packages/playground/src/pages/OpenInvoices/OpenInvoices.js b/packages/playground/src/pages/OpenInvoices/OpenInvoices.js index a6534a1743..9ba57211ed 100644 --- a/packages/playground/src/pages/OpenInvoices/OpenInvoices.js +++ b/packages/playground/src/pages/OpenInvoices/OpenInvoices.js @@ -41,8 +41,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsData => { // RATEPAY if (showComps.ratepay) { - window.ratepay = new RatePay({ - core: window.core, + window.ratepay = new RatePay(window.core, { countryCode: 'DE', // 'DE' / 'AT' / 'CH' visibility: { personalDetails: 'editable', // editable [default] / readOnly / hidden @@ -54,8 +53,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsData => { // RATEPAY if (showComps.ratepaydd) { - window.ratepaydd = new RatePayDirectDebit({ - core: window.core, + window.ratepaydd = new RatePayDirectDebit(window.core, { //countryCode: 'DE', // 'DE' / 'AT' / 'CH' visibility: { personalDetails: 'editable', // editable [default] / readOnly / hidden @@ -67,8 +65,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsData => { // AFTERPAY if (showComps.afterpay) { - window.afterpay = new AfterPay({ - core: window.core, + window.afterpay = new AfterPay(window.core, { countryCode: 'NL', // 'NL' / 'BE' visibility: { personalDetails: 'editable', // editable [default] / readOnly / hidden @@ -89,8 +86,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsData => { // AFTERPAY B2B if (showComps.afterpayb2b) { - window.afterpayb2b = new AfterPayB2B({ - core: window.core, + window.afterpayb2b = new AfterPayB2B(window.core, { countryCode: 'NL', // 'NL' / 'BE' visibility: { companyDetails: 'editable' // editable [default] / readOnly / hidden @@ -100,8 +96,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsData => { // FACILYPAY_3x if (showComps.facilypay_3x) { - window.facilypay_3x = new FacilPay3x({ - core: window.core, + window.facilypay_3x = new FacilPay3x(window.core, { countryCode: 'ES', // 'ES' / 'FR' visibility: { personalDetails: 'editable', // editable [default] / readOnly / hidden @@ -113,8 +108,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsData => { // AFFIRM if (showComps.affirm) { - window.affirm = new Affirm({ - core: window.core, + window.affirm = new Affirm(window.core, { countryCode: 'US', // 'US' / 'CA' visibility: { personalDetails: 'hidden', // editable [default] / readOnly / hidden @@ -142,8 +136,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsData => { // ATOME if (showComps.atome) { - window.atome = new Atome({ - core: window.core, + window.atome = new Atome(window.core, { countryCode: 'SG', data: { personalDetails: { diff --git a/packages/playground/src/pages/QRCodes/QRCodes.js b/packages/playground/src/pages/QRCodes/QRCodes.js index 27ff0e20ea..f142feb52e 100644 --- a/packages/playground/src/pages/QRCodes/QRCodes.js +++ b/packages/playground/src/pages/QRCodes/QRCodes.js @@ -48,8 +48,7 @@ const handleQRCodePayment = async (state, component, actions, countryCode) => { }); // WechatPay QR - new WeChat({ - core: checkout, + new WeChat(checkout, { type: 'wechatpayQR', onSubmit: (state, component, actions) => { handleQRCodePayment(state, component, actions, 'CN'); @@ -57,36 +56,31 @@ const handleQRCodePayment = async (state, component, actions, countryCode) => { }).mount('#wechatpayqr-container'); // BCMC Mobile - new BcmcMobile({ - core: checkout, + new BcmcMobile(checkout, { onSubmit: (state, component, actions) => { handleQRCodePayment(state, component, actions, 'BE'); } }).mount('#bcmcqr-container'); - new Swish({ - core: checkout, + new Swish(checkout, { onSubmit: (state, component, actions) => { handleQRCodePayment(state, component, actions, 'SE'); } }).mount('#swish-container'); - new PromptPay({ - core: checkout, + new PromptPay(checkout, { onSubmit: (state, component, actions) => { handleQRCodePayment(state, component, actions, 'TH'); } }).mount('#promptpay-container'); - new PayNow({ - core: checkout, + new PayNow(checkout, { onSubmit: (state, component, actions) => { handleQRCodePayment(state, component, actions, 'SG'); } }).mount('#paynow-container'); - new DuitNow({ - core: checkout, + new DuitNow(checkout, { onSubmit: (state, component, actions) => { handleQRCodePayment(state, component, actions, 'MY'); } diff --git a/packages/playground/src/pages/Vouchers/Vouchers.js b/packages/playground/src/pages/Vouchers/Vouchers.js index e01c794057..647d261d88 100644 --- a/packages/playground/src/pages/Vouchers/Vouchers.js +++ b/packages/playground/src/pages/Vouchers/Vouchers.js @@ -16,8 +16,7 @@ import getTranslationFile from '../../config/getTranslation'; onChange: handleChange }); - window.bacsdd = new BacsDirectDebit({ - core: window.checkout, + window.bacsdd = new BacsDirectDebit(window.checkout, { countryCode: 'GB', data: { holderName: 'Philip Dog', @@ -58,8 +57,7 @@ import getTranslationFile from '../../config/getTranslation'; .mount('#multibanco-result-container'); // Boleto Input - window.boletoInput = new Boleto({ - core: window.checkout, + window.boletoInput = new Boleto(window.checkout, { type: 'boletobancario', // --> HAS MULTIPLE TX VARIANTS.. HOW TO ENFORCE IT? // personalDetailsRequired: false, // billingAddressRequired: false, @@ -101,7 +99,6 @@ import getTranslationFile from '../../config/getTranslation'; // Oxxo Result AdyenCheckout.register(Oxxo); - window.oxxoResult = checkout .createFromAction({ expiresAt: '2019-08-17T23:59:59', @@ -124,8 +121,7 @@ import getTranslationFile from '../../config/getTranslation'; .mount('#oxxo-result-container'); // Dragonpay Input - window.dragonpayInput = new Dragonpay({ - core: window.checkout, + window.dragonpayInput = new Dragonpay(window.checkout, { type: 'dragonpay_otc_philippines' // --> // HAS MULTIPLE TX VARIANTS.. HOW TO ENFORCE IT? }).mount('#dragonpay-input-container'); @@ -157,8 +153,7 @@ import getTranslationFile from '../../config/getTranslation'; .mount('#dragonpay-result-container'); // Doku Input - window.dokuInput = new Doku({ - core: window.checkout, + window.dokuInput = new Doku(window.checkout, { type: 'doku_alfamart' }).mount('#doku-input-container'); @@ -185,16 +180,14 @@ import getTranslationFile from '../../config/getTranslation'; .mount('#doku-result-container'); // Econtext Stores Input without personal details form - window.econtextStoresInput = new Econtext({ - core: window.checkout, + window.econtextStoresInput = new Econtext(window.checkout, { type: 'econtext_stores', // --> HAS MULTIPLE TX VARIANTS.. HOW TO ENFORCE IT? personalDetailsRequired: false, onSubmit: e => console.log('SUBMIT:', e) }).mount('#econtext-stores-without-form-input-container'); // Econtext Stores Input - window.econtextStoresInput = new Econtext({ - core: window.checkout, + window.econtextStoresInput = new Econtext(window.checkout, { type: 'econtext_stores', data: { firstName: 'Joe', @@ -227,8 +220,7 @@ import getTranslationFile from '../../config/getTranslation'; .mount('#econtext-stores-result-container'); // Econtext ATM Input - window.econtextAtmInput = new Econtext({ - core: window.checkout, + window.econtextAtmInput = new Econtext(window.checkout, { type: 'econtext_atm', data: { firstName: 'Joe', @@ -261,8 +253,7 @@ import getTranslationFile from '../../config/getTranslation'; .mount('#econtext-atm-result-container'); // Econtext 7 11 input - window.econtext711Input = new Econtext({ - core: window.checkout, + window.econtext711Input = new Econtext(window.checkout, { type: 'econtext_seven_eleven' }).mount('#econtext-seven-eleven-input-container'); diff --git a/packages/playground/src/pages/Wallets/Wallets.js b/packages/playground/src/pages/Wallets/Wallets.js index b526e10d8b..334c4f929d 100644 --- a/packages/playground/src/pages/Wallets/Wallets.js +++ b/packages/playground/src/pages/Wallets/Wallets.js @@ -32,8 +32,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = }); // Cash App Pay - window.cashApp = new CashAppPay({ - core: window.checkout, + window.cashApp = new CashAppPay(window.checkout, { onClick(actions) { console.log('CashAppApp: onClick'); actions.resolve(); @@ -41,8 +40,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = }).mount('.cashapp-field'); // CLICK TO PAY - window.clickToPay = new ClickToPay({ - core: window.checkout, + window.clickToPay = new ClickToPay(window.checkout, { shopperEmail: 'gui.ctp@adyen.com', onReady() { console.log('ClickToPay is ready'); @@ -79,8 +77,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = // Initial state if (!step) { - window.amazonpay = new AmazonPay({ - core: window.checkout, + window.amazonpay = new AmazonPay(window.checkout, { productType: 'PayOnly', ...chargeOptions, // Regular checkout: @@ -94,8 +91,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = // Review and confirm order if (step === 'review') { - window.amazonpay = new AmazonPay({ - core: window.checkout, + window.amazonpay = new AmazonPay(window.checkout, { ...chargeOptions, /** * The merchant will receive the amazonCheckoutSessionId attached in the return URL. @@ -108,9 +104,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = // Make payment if (step === 'result') { - window.amazonpay = new AmazonPay({ - core: window.checkout, - + window.amazonpay = new AmazonPay(window.checkout, { /** * The merchant will receive the amazonCheckoutSessionId attached in the return URL. */ @@ -146,8 +140,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = } // PAYPAL - window.paypalButtons = new PayPal({ - core: window.checkout, + window.paypalButtons = new PayPal(window.checkout, { onAuthorized(data, actions) { console.log('onAuthorized', data, actions); actions.resolve(); @@ -158,8 +151,8 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = }).mount('.paypal-field'); // GOOGLE PAY - const googlepay = new GooglePay({ - core: window.checkout, + const googlepay = new GooglePay(window.checkout, { + // environment: 'PRODUCTION', environment: 'TEST', // Callbacks @@ -192,8 +185,7 @@ getPaymentMethods({ amount, shopperLocale }).then(async paymentMethodsResponse = window.googlepay = googlepay; // APPLE PAY - const applepay = new ApplePay({ - core: window.checkout, + const applepay = new ApplePay(window.checkout, { onClick: (resolve, reject) => { console.log('Apple Pay - Button clicked'); resolve();