diff --git a/cypress-tests/cypress.config.js b/cypress-tests/cypress.config.js index 7def1f1b9f..e36f68e80e 100644 --- a/cypress-tests/cypress.config.js +++ b/cypress-tests/cypress.config.js @@ -1,25 +1,24 @@ - let globalState; module.exports = { e2e: { setupNodeEvents(on, config) { - on('task', { + on("task", { setGlobalState: (val) => { - return (globalState = (val || {})) + return (globalState = val || {}); }, getGlobalState: () => { - return (globalState || {}) + return globalState || {}; }, cli_log: (message) => { console.log("Logging console message from task"); console.log(message); return null; - } - }) + }, + }); }, - experimentalRunAllSpecs: true + experimentalRunAllSpecs: true, }, chromeWebSecurity: false, defaultCommandTimeout: 10000, - pageLoadTimeout: 20000 -}; \ No newline at end of file + pageLoadTimeout: 20000, +}; diff --git a/cypress-tests/cypress/e2e/ConnectorTest/00016-BankTransfers.cy.js b/cypress-tests/cypress/e2e/ConnectorTest/00016-BankTransfers.cy.js new file mode 100644 index 0000000000..ae5f098710 --- /dev/null +++ b/cypress-tests/cypress/e2e/ConnectorTest/00016-BankTransfers.cy.js @@ -0,0 +1,81 @@ +import confirmBody from "../../fixtures/confirm-body.json"; +import createPaymentBody from "../../fixtures/create-payment-body.json"; +import State from "../../utils/State"; +import getConnectorDetails, * as utils from "../ConnectorUtils/utils"; + +let globalState; + +describe("Bank Transfers", () => { + before("seed global state", () => { + cy.task("getGlobalState").then((state) => { + globalState = new State(state); + console.log("seeding globalState -> " + JSON.stringify(globalState)); + }); + }); + + after("flush global state", () => { + console.log("flushing globalState -> " + JSON.stringify(globalState)); + cy.task("setGlobalState", globalState.data); + }); + + context("Bank transfer - Pix forward flow", () => { + let should_continue = true; // variable that will be used to skip tests if a previous test fails + + beforeEach(function () { + if (!should_continue) { + this.skip(); + } + }); + + it("create-payment-call-test", () => { + let data = getConnectorDetails(globalState.get("connectorId"))[ + "bank_transfer_pm" + ]["PaymentIntent"]; + let req_data = data["Request"]; + let res_data = data["Response"]; + cy.createPaymentIntentTest( + createPaymentBody, + req_data, + res_data, + "three_ds", + "automatic", + globalState + ); + if (should_continue) + should_continue = utils.should_continue_further(res_data); + }); + + it("payment_methods-call-test", () => { + cy.task("cli_log", "PM CALL "); + cy.paymentMethodsCallTest(globalState); + }); + + it("Confirm bank transfer", () => { + let data = getConnectorDetails(globalState.get("connectorId"))[ + "bank_transfer_pm" + ]["Pix"]; + let req_data = data["Request"]; + let res_data = data["Response"]; + cy.task("cli_log", "GLOBAL STATE -> " + JSON.stringify(globalState.data)); + cy.confirmBankTransferCallTest( + confirmBody, + req_data, + res_data, + true, + globalState + ); + if (should_continue) + should_continue = utils.should_continue_further(res_data); + }); + + it("Handle bank transfer redirection", () => { + let expected_redirection = confirmBody["return_url"]; + let payment_method_type = globalState.get("paymentMethodType"); + cy.handleBankTransferRedirection( + globalState, + payment_method_type, + expected_redirection + ); + }); + }); +}); diff --git a/cypress-tests/cypress/e2e/ConnectorTest/00017-BankRedirect.cy.js b/cypress-tests/cypress/e2e/ConnectorTest/00017-BankRedirect.cy.js new file mode 100644 index 0000000000..c08468022a --- /dev/null +++ b/cypress-tests/cypress/e2e/ConnectorTest/00017-BankRedirect.cy.js @@ -0,0 +1,325 @@ +import confirmBody from "../../fixtures/confirm-body.json"; +import createPaymentBody from "../../fixtures/create-payment-body.json"; +import State from "../../utils/State"; +import getConnectorDetails, * as utils from "../ConnectorUtils/utils"; + +let globalState; + +describe("Bank Redirect tests", () => { + before("seed global state", () => { + cy.task("getGlobalState").then((state) => { + globalState = new State(state); + console.log("seeding globalState -> " + JSON.stringify(globalState)); + }); + }); + + after("flush global state", () => { + console.log("flushing globalState -> " + JSON.stringify(globalState)); + cy.task("setGlobalState", globalState.data); + }); + + afterEach("flush global state", () => { + console.log("flushing globalState -> " + JSON.stringify(globalState)); + cy.task("setGlobalState", globalState.data); + cy.task( + "cli_log", + " FLUSHING GLOBAL STATE -> " + JSON.stringify(globalState) + ); + }); + + context("Blik Create and Confirm flow test", () => { + let should_continue = true; // variable that will be used to skip tests if a previous test fails + + beforeEach(function () { + if (!should_continue) { + this.skip(); + } + }); + + it("create-payment-call-test", () => { + let data = getConnectorDetails(globalState.get("connectorId"))[ + "bank_redirect_pm" + ]["blikPaymentIntent"]; + let req_data = data["Request"]; + let res_data = data["Response"]; + cy.createPaymentIntentTest( + createPaymentBody, + req_data, + res_data, + "three_ds", + "automatic", + globalState + ); + if (should_continue) + should_continue = utils.should_continue_further(res_data); + }); + + it("payment_methods-call-test", () => { + cy.task("cli_log", "PM CALL "); + cy.paymentMethodsCallTest(globalState); + }); + + it("Confirm bank redirect", () => { + let data = getConnectorDetails(globalState.get("connectorId"))[ + "bank_redirect_pm" + ]["blik"]; + let req_data = data["Request"]; + let res_data = data["Response"]; + cy.task("cli_log", "GLOBAL STATE -> " + JSON.stringify(globalState.data)); + cy.confirmBankRedirectCallTest( + confirmBody, + req_data, + res_data, + true, + globalState + ); + if (should_continue) + should_continue = utils.should_continue_further(res_data); + }); + }); + + context("EPS Create and Confirm flow test", () => { + let should_continue = true; // variable that will be used to skip tests if a previous test fails + + beforeEach(function () { + if (!should_continue) { + this.skip(); + } + }); + it("create-payment-call-test", () => { + let data = getConnectorDetails(globalState.get("connectorId"))[ + "bank_redirect_pm" + ]["PaymentIntent"]; + let req_data = data["Request"]; + let res_data = data["Response"]; + cy.createPaymentIntentTest( + createPaymentBody, + req_data, + res_data, + "three_ds", + "automatic", + globalState + ); + if (should_continue) + should_continue = utils.should_continue_further(res_data); + }); + + it("payment_methods-call-test", () => { + cy.task("cli_log", "PM CALL "); + cy.paymentMethodsCallTest(globalState); + }); + + it("Confirm bank redirect", () => { + let data = getConnectorDetails(globalState.get("connectorId"))[ + "bank_redirect_pm" + ]["eps"]; + let req_data = data["Request"]; + let res_data = data["Response"]; + cy.task("cli_log", "GLOBAL STATE -> " + JSON.stringify(globalState.data)); + cy.confirmBankRedirectCallTest( + confirmBody, + req_data, + res_data, + true, + globalState + ); + if (should_continue) + should_continue = utils.should_continue_further(res_data); + }); + + it("Handle bank redirect redirection", () => { + // return_url is a static url (https://hyperswitch.io) taken from confirm-body fixture and is not updated + let expected_redirection = confirmBody["return_url"]; + let payment_method_type = globalState.get("paymentMethodType"); + cy.handleBankRedirectRedirection( + globalState, + payment_method_type, + expected_redirection + ); + }); + }); + + context("iDEAL Create and Confirm flow test", () => { + let should_continue = true; // variable that will be used to skip tests if a previous test fails + + beforeEach(function () { + if (!should_continue) { + this.skip(); + } + }); + + it("create-payment-call-test", () => { + let data = getConnectorDetails(globalState.get("connectorId"))[ + "bank_redirect_pm" + ]["PaymentIntent"]; + let req_data = data["Request"]; + let res_data = data["Response"]; + cy.createPaymentIntentTest( + createPaymentBody, + req_data, + res_data, + "three_ds", + "automatic", + globalState + ); + if (should_continue) + should_continue = utils.should_continue_further(res_data); + }); + + it("payment_methods-call-test", () => { + cy.task("cli_log", "PM CALL "); + cy.paymentMethodsCallTest(globalState); + }); + + it("Confirm bank redirect", () => { + let data = getConnectorDetails(globalState.get("connectorId"))[ + "bank_redirect_pm" + ]["ideal"]; + let req_data = data["Request"]; + let res_data = data["Response"]; + cy.task("cli_log", "GLOBAL STATE -> " + JSON.stringify(globalState.data)); + cy.confirmBankRedirectCallTest( + confirmBody, + req_data, + res_data, + true, + globalState + ); + if (should_continue) + should_continue = utils.should_continue_further(res_data); + }); + + it("Handle bank redirect redirection", () => { + // return_url is a static url (https://hyperswitch.io) taken from confirm-body fixture and is not updated + let expected_redirection = confirmBody["return_url"]; + let payment_method_type = globalState.get("paymentMethodType"); + cy.handleBankRedirectRedirection( + globalState, + payment_method_type, + expected_redirection + ); + }); + }); + + context("Giropay Create and Confirm flow test", () => { + let should_continue = true; // variable that will be used to skip tests if a previous test fails + + beforeEach(function () { + if (!should_continue) { + this.skip(); + } + }); + it("create-payment-call-test", () => { + let data = getConnectorDetails(globalState.get("connectorId"))[ + "bank_redirect_pm" + ]["PaymentIntent"]; + let req_data = data["Request"]; + let res_data = data["Response"]; + cy.createPaymentIntentTest( + createPaymentBody, + req_data, + res_data, + "three_ds", + "automatic", + globalState + ); + if (should_continue) + should_continue = utils.should_continue_further(res_data); + }); + + it("payment_methods-call-test", () => { + cy.task("cli_log", "PM CALL "); + cy.paymentMethodsCallTest(globalState); + }); + + it("Confirm bank redirect", () => { + let data = getConnectorDetails(globalState.get("connectorId"))[ + "bank_redirect_pm" + ]["giropay"]; + let req_data = data["Request"]; + let res_data = data["Response"]; + cy.task("cli_log", "GLOBAL STATE -> " + JSON.stringify(globalState.data)); + cy.confirmBankRedirectCallTest( + confirmBody, + req_data, + res_data, + true, + globalState + ); + if (should_continue) + should_continue = utils.should_continue_further(res_data); + }); + + it("Handle bank redirect redirection", () => { + // return_url is a static url (https://hyperswitch.io) taken from confirm-body fixture and is not updated + let expected_redirection = confirmBody["return_url"]; + let payment_method_type = globalState.get("paymentMethodType"); + cy.handleBankRedirectRedirection( + globalState, + payment_method_type, + expected_redirection + ); + }); + }); + + context("Sofort Create and Confirm flow test", () => { + let should_continue = true; // variable that will be used to skip tests if a previous test fails + + beforeEach(function () { + if (!should_continue) { + this.skip(); + } + }); + it("create-payment-call-test", () => { + let data = getConnectorDetails(globalState.get("connectorId"))[ + "bank_redirect_pm" + ]["PaymentIntent"]; + let req_data = data["Request"]; + let res_data = data["Response"]; + cy.createPaymentIntentTest( + createPaymentBody, + req_data, + res_data, + "three_ds", + "automatic", + globalState + ); + if (should_continue) + should_continue = utils.should_continue_further(res_data); + }); + + it("payment_methods-call-test", () => { + cy.task("cli_log", "PM CALL "); + cy.paymentMethodsCallTest(globalState); + }); + + it("Confirm bank redirect", () => { + let data = getConnectorDetails(globalState.get("connectorId"))[ + "bank_redirect_pm" + ]["sofort"]; + let req_data = data["Request"]; + let res_data = data["Response"]; + cy.task("cli_log", "GLOBAL STATE -> " + JSON.stringify(globalState.data)); + cy.confirmBankRedirectCallTest( + confirmBody, + req_data, + res_data, + true, + globalState + ); + if (should_continue) + should_continue = utils.should_continue_further(res_data); + }); + + it("Handle bank redirect redirection", () => { + // return_url is a static url (https://hyperswitch.io) taken from confirm-body fixture and is not updated + let expected_redirection = confirmBody["return_url"]; + let payment_method_type = globalState.get("paymentMethodType"); + cy.handleBankRedirectRedirection( + globalState, + payment_method_type, + expected_redirection + ); + }); + }); +}); diff --git a/cypress-tests/cypress/e2e/ConnectorUtils/Adyen.js b/cypress-tests/cypress/e2e/ConnectorUtils/Adyen.js index 1bbbbbd4b5..19b6f34224 100644 --- a/cypress-tests/cypress/e2e/ConnectorUtils/Adyen.js +++ b/cypress-tests/cypress/e2e/ConnectorUtils/Adyen.js @@ -1,382 +1,531 @@ +import { getCustomExchange } from "./Commons"; const successfulNo3DSCardDetails = { - "card_number": "371449635398431", - "card_exp_month": "03", - "card_exp_year": "30", - "card_holder_name": "John Doe", - "card_cvc": "7373" + card_number: "371449635398431", + card_exp_month: "03", + card_exp_year: "30", + card_holder_name: "John Doe", + card_cvc: "7373", }; const successfulThreeDSTestCardDetails = { - "card_number": "4917610000000000", - "card_exp_month": "03", - "card_exp_year": "30", - "card_holder_name": "Joseph Doe", - "card_cvc": "737" + card_number: "4917610000000000", + card_exp_month: "03", + card_exp_year: "30", + card_holder_name: "Joseph Doe", + card_cvc: "737", }; export const connectorDetails = { -card_pm:{ - "PaymentIntent": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "customer_acceptance": null, - "setup_future_usage": "on_session" + card_pm: { + PaymentIntent: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", }, - "Response": { - "status": 200, - "body": { - "status": "requires_payment_method" - } - } + }, }, "3DSManualCapture": { - "Request": { - "card": successfulThreeDSTestCardDetails, - "currency": "USD", - "customer_acceptance": null, - "setup_future_usage": "on_session" + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "processing", }, - "Response": { - "status": 200, - "body": { - "status": "processing" - } - } + }, }, "3DSAutoCapture": { - "Request": { - "card": successfulThreeDSTestCardDetails, - "currency": "USD", - "customer_acceptance": null, - "setup_future_usage": "on_session" + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "succeeded", }, - "Response": { - "status": 200, - "body": { - "status": "succeeded" - } - } + }, }, - "No3DSManualCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "customer_acceptance": null, - "setup_future_usage": "on_session" + No3DSManualCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "requires_capture", }, - "Response": { - "status": 200, - "body": { - "status": "requires_capture" - } - } + }, }, - "No3DSAutoCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "customer_acceptance": null, - "setup_future_usage": "on_session" + No3DSAutoCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "succeeded", }, - "Response": { - "status": 200, - "body": { - "status": "succeeded" - } - } + }, }, - "Capture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "customer_acceptance": null, + Capture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 200, + body: { + status: "processing", + amount: 6500, + amount_capturable: 6500, + amount_received: 0, }, - "Response": { - "status": 200, - "body":{ - "status": "processing", - "amount": 6500, - "amount_capturable": 6500, - "amount_received": 0, - - } - } + }, }, - "PartialCapture": { - "Request": { + PartialCapture: { + Request: {}, + Response: { + status: 200, + body: { + status: "processing", + amount: 6500, + amount_capturable: 6500, + amount_received: 0, }, - "Response": { - "status": 200, - "body": { - "status": "processing", - "amount": 6500, - "amount_capturable": 6500, - "amount_received": 0, - } - - } + }, }, - "Void":{ - "Request": { + Void: { + Request: {}, + Response: { + status: 200, + body: { + status: "processing", }, - "Response": { - "status": 200, - "body":{ - status: "processing" - - } - } + }, }, - "Refund": { - "Request": { - - "currency": "USD", - + Refund: { + Request: { + currency: "USD", + }, + Response: { + status: 200, + body: { + status: "pending", }, - "Response": { - "status": 400, - "body": { - "status": "pending", - } - - } - }, - "PartialRefund": { - "Request": { - - "currency": "USD", - + status: 200, + body: { + status: "pending", }, - "Response": { - "status": 200, - "body": { - "status": "pending", - } - - } + }, }, - "SyncRefund": { - "Request": { - - "currency": "USD", - + PartialRefund: { + Request: { + currency: "USD", + }, + Response: { + status: 200, + body: { + status: "pending", }, - "Response": { - "status": 200, - "body": { - "status": "pending", - } - - } + }, }, - "MandateSingleUse3DSAutoCapture": { - "Request": { - "card": successfulThreeDSTestCardDetails, - "currency": "USD", - "mandate_type": { - "single_use": { - "amount": 8000, - "currency": "USD" - } - } + SyncRefund: { + Request: { + currency: "USD", + }, + Response: { + status: 200, + body: { + status: "pending", }, - "Response": { - "status": 200, - "body": { - "status": "succeeded" - } - } - + }, }, - "MandateSingleUse3DSManualCapture": { - "Request": { - "card": successfulThreeDSTestCardDetails, - "currency": "USD", - "mandate_type": { - "single_use": { - "amount": 8000, - "currency": "USD" - } - } + MandateSingleUse3DSAutoCapture: { + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, }, - "Response": { - "status": 200, - "body": { - "status": "requires_customer_action" - } - } - - }, - "MandateSingleUseNo3DSAutoCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "mandate_type": { - "single_use": { - "amount": 8000, - "currency": "USD" - } - } + }, + Response: { + status: 200, + body: { + status: "succeeded", }, - "Response": { - "status": 200, - "body": { - "status": "succeeded" - } - } + }, }, - "MandateSingleUseNo3DSManualCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "mandate_type": { - "single_use": { - "amount": 8000, - "currency": "USD" - } - } + MandateSingleUse3DSManualCapture: { + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, }, - "Response": { - "status": 200, - "body": { - "status": "processing" - } - } - }, - "MandateMultiUseNo3DSAutoCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "mandate_type": { - "multi_use": { - "amount": 8000, - "currency": "USD" - } - } + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", }, - "Response": { - "status": 200, - "body": { - "status": "succeeded" - } - } + }, }, - "MandateMultiUseNo3DSManualCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "mandate_type": { - "multi_use": { - "amount": 8000, - "currency": "USD" - } - } + MandateSingleUseNo3DSAutoCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, }, - "Response": { - "status": 200, - "body": { - "status": "requires_capture" - } - } + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, }, - "MandateMultiUse3DSAutoCapture": { - "Request": { - "card": successfulThreeDSTestCardDetails, - "currency": "USD", - "mandate_type": { - "multi_use": { - "amount": 8000, - "currency": "USD" - } + MandateSingleUseNo3DSManualCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + Response: { + status: 200, + body: { + status: "processing", + }, + }, + }, + MandateMultiUseNo3DSAutoCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + multi_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + MandateMultiUseNo3DSManualCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + multi_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + Response: { + status: 200, + body: { + status: "requires_capture", + }, + }, + }, + MandateMultiUse3DSAutoCapture: { + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + mandate_type: { + multi_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + Response: { + status: 200, + body: { + status: "requires_capture", + }, + }, + }, + MandateMultiUse3DSManualCapture: { + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + mandate_type: { + multi_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + Response: { + status: 200, + body: { + status: "requires_capture", + }, + }, + }, + ZeroAuthMandate: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + SaveCardUseNo3DSAutoCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + setup_future_usage: "on_session", + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "127.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + SaveCardUseNo3DSManualCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + setup_future_usage: "on_session", + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "127.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + Response: { + status: 200, + body: { + status: "requires_capture", + }, + }, + }, + }, + bank_transfer_pm: { + PaymentIntent: { + Request: { + currency: "BRL", + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", + }, + }, + }, + Pix: { + Request: { + payment_method: "bank_transfer", + payment_method_type: "pix", + payment_method_data: { + bank_transfer: { + pix: {}, + }, + }, + currency: "BRL", + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, + }, + bank_redirect_pm: { + PaymentIntent: getCustomExchange({ + Request: { + currency: "EUR", + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", + }, + }, + }), + ideal: { + Request: { + payment_method: "bank_redirect", + payment_method_type: "ideal", + payment_method_data: { + bank_redirect: { + ideal: { + bank_name: "ing", + country: "NL", }, + }, }, - "Response": { - "status": 200, - "body": { - "status": "requires_capture" - } - } + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, }, - "MandateMultiUse3DSManualCapture": { - "Request": { - "card": successfulThreeDSTestCardDetails, - "currency": "USD", - "mandate_type": { - "multi_use": { - "amount": 8000, - "currency": "USD" - } + giropay: { + Request: { + payment_method: "bank_redirect", + payment_method_type: "giropay", + payment_method_data: { + bank_redirect: { + giropay: { + bank_name: "", + bank_account_bic: "", + bank_account_iban: "", + preferred_language: "en", + country: "DE", }, + }, }, - "Response": { - "status": 200, - "body": { - "status": "requires_capture" - } - } - }, - "ZeroAuthMandate": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "mandate_type": { - "single_use": { - "amount": 8000, - "currency": "USD" - } - } + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", }, - "Response": { - "status": 200, - "body": { - "status": "succeeded" - } - } + }, }, - "SaveCardUseNo3DSAutoCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "setup_future_usage": "on_session", - "customer_acceptance": { - "acceptance_type": "offline", - "accepted_at": "1963-05-03T04:07:52.723Z", - "online": { - "ip_address": "127.0.0.1", - "user_agent": "amet irure esse" - } + sofort: { + Request: { + payment_method: "bank_redirect", + payment_method_type: "sofort", + payment_method_data: { + bank_redirect: { + sofort: { + country: "DE", + preferred_language: "en", }, + }, }, - "Response": { - "status": 200, - "body": { - "status": "succeeded" - } - } + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, }, - "SaveCardUseNo3DSManualCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "setup_future_usage": "on_session", - "customer_acceptance": { - "acceptance_type": "offline", - "accepted_at": "1963-05-03T04:07:52.723Z", - "online": { - "ip_address": "127.0.0.1", - "user_agent": "amet irure esse" - } + eps: { + Request: { + payment_method: "bank_redirect", + payment_method_type: "eps", + payment_method_data: { + bank_redirect: { + eps: { + bank_name: "ing", }, + }, }, - "Response": { - "status": 200, - "body": { - "status": "requires_capture" - } - } + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, }, -} -}; \ No newline at end of file + blik: { + Request: { + payment_method: "bank_redirect", + payment_method_type: "blik", + payment_method_data: { + bank_redirect: { + blik: { + name: "John Doe", + email: "example@email.com", + blik_code: "777987", + }, + }, + }, + billing: { + address: { + line1: "1467", + line2: "Harrison Street", + line3: "Harrison Street", + city: "San Fransico", + state: "California", + zip: "94122", + country: "PL", + first_name: "john", + last_name: "doe", + }, + }, + }, + Response: { + status: 200, + body: { + status: "processing", + }, + }, + }, + }, +}; diff --git a/cypress-tests/cypress/e2e/ConnectorUtils/Commons.js b/cypress-tests/cypress/e2e/ConnectorUtils/Commons.js new file mode 100644 index 0000000000..9436f33406 --- /dev/null +++ b/cypress-tests/cypress/e2e/ConnectorUtils/Commons.js @@ -0,0 +1,507 @@ +// This file is the default. To override, add to connector.js +import State from "../../utils/State"; + +const globalState = new State({ + connectorId: Cypress.env("CONNECTOR"), + baseUrl: Cypress.env("BASEURL"), + adminApiKey: Cypress.env("ADMINAPIKEY"), + connectorAuthFilePath: Cypress.env("CONNECTOR_AUTH_FILE_PATH"), +}); + +const connectorId = globalState.get("connectorId"); + +const successfulNo3DSCardDetails = { + card_number: "4111111111111111", + card_exp_month: "08", + card_exp_year: "25", + card_holder_name: "joseph Doe", + card_cvc: "999", +}; + +const successfulThreeDSTestCardDetails = { + card_number: "4111111111111111", + card_exp_month: "10", + card_exp_year: "25", + card_holder_name: "morino", + card_cvc: "999", +}; + +/* +`getDefaultExchange` contains the default Request and Response to be considered if none provided. +`getCustomExchange` takes in 2 optional fields named as Request and Response. +with `getCustomExchange`, if 501 response is expected, there is no need to pass Response as it considers default values. +*/ + +// Const to get default PaymentExchange object +const getDefaultExchange = () => ({ + Request: { + currency: "EUR", + }, + Response: { + status: 501, + body: { + error: { + type: "invalid_request", + message: `Selected payment method through ${connectorId} is not implemented`, + code: "IR_00", + }, + }, + }, +}); + +// Const to get PaymentExchange with overridden properties +export const getCustomExchange = (overrides) => { + const defaultExchange = getDefaultExchange(); + + return { + ...defaultExchange, + Request: { + ...defaultExchange.Request, + ...(overrides.Request || {}), + }, + Response: { + ...defaultExchange.Response, + ...(overrides.Response || {}), + }, + }; +}; + +export const connectorDetails = { + card_pm: { + PaymentIntent: getCustomExchange({ + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", + }, + }, + }), + "3DSManualCapture": { + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "processing", + }, + }, + }, + "3DSAutoCapture": { + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "processing", + }, + }, + }, + No3DSManualCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "processing", + }, + }, + }, + No3DSAutoCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "processing", + }, + }, + }, + Capture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 200, + body: { + status: "processing", + amount: 6500, + amount_capturable: 6500, + }, + }, + }, + PartialCapture: { + Request: {}, + Response: { + status: 200, + body: { + status: "processing", + amount: 6500, + amount_capturable: 6500, + }, + }, + }, + Void: { + Request: {}, + Response: { + status: 400, + body: { + error: { + code: "IR_16", + message: + "You cannot cancel this payment because it has status processing", + type: "invalid_request", + }, + }, + }, + }, + Refund: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: + "This Payment could not be refund because it has a status of processing. The expected state is succeeded, partially_captured", + code: "IR_14", + }, + }, + }, + }, + PartialRefund: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: + "This Payment could not be refund because it has a status of processing. The expected state is succeeded, partially_captured", + code: "IR_14", + }, + }, + }, + }, + SyncRefund: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: + "This Payment could not be refund because it has a status of processing. The expected state is succeeded, partially_captured", + code: "IR_14", + }, + }, + }, + }, + MandateSingleUse3DSAutoCapture: getCustomExchange({ + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + }), + MandateSingleUse3DSManualCapture: getCustomExchange({ + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + }), + MandateSingleUseNo3DSAutoCapture: getCustomExchange({ + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + }), + MandateSingleUseNo3DSManualCapture: getCustomExchange({ + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + }), + MandateMultiUseNo3DSAutoCapture: getCustomExchange({ + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + }), + MandateMultiUseNo3DSManualCapture: getCustomExchange({ + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + multi_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + }), + MandateMultiUse3DSAutoCapture: getCustomExchange({ + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + mandate_type: { + multi_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + }), + MandateMultiUse3DSManualCapture: getCustomExchange({ + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + mandate_type: { + multi_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + }), + ZeroAuthMandate: getCustomExchange({ + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + }), + SaveCardUseNo3DSAutoCapture: getCustomExchange({ + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + setup_future_usage: "on_session", + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "127.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + }), + SaveCardUseNo3DSManualCapture: getCustomExchange({ + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + setup_future_usage: "on_session", + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "127.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + }), + }, + bank_transfer_pm: { + PaymentIntent: getCustomExchange({ + Request: { + currency: "BRL", + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", + }, + }, + }), + Pix: getCustomExchange({ + Request: { + payment_method: "bank_transfer", + payment_method_type: "pix", + payment_method_data: { + bank_transfer: { + pix: {}, + }, + }, + currency: "BRL", + }, + }), + }, + bank_redirect_pm: { + PaymentIntent: getCustomExchange({ + Request: { + currency: "EUR", + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", + }, + }, + }), + ideal: getCustomExchange({ + Request: { + payment_method: "bank_redirect", + payment_method_type: "ideal", + payment_method_data: { + bank_redirect: { + ideal: { + bank_name: "ing", + country: "NL", + }, + }, + }, + }, + }), + giropay: getCustomExchange({ + Request: { + payment_method: "bank_redirect", + payment_method_type: "giropay", + payment_method_data: { + bank_redirect: { + giropay: { + bank_name: "", + bank_account_bic: "", + bank_account_iban: "", + preferred_language: "en", + country: "DE", + }, + }, + }, + }, + }), + sofort: getCustomExchange({ + Request: { + payment_method: "bank_redirect", + payment_method_type: "sofort", + payment_method_data: { + bank_redirect: { + sofort: { + country: "DE", + preferred_language: "en", + }, + }, + }, + }, + }), + eps: getCustomExchange({ + Request: { + payment_method: "bank_redirect", + payment_method_type: "eps", + payment_method_data: { + bank_redirect: { + eps: { + bank_name: "ing", + }, + }, + }, + }, + }), + blikPaymentIntent: getCustomExchange({ + Request: { + currency: "PLN", + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", + }, + }, + }), + blik: getCustomExchange({ + Request: { + payment_method: "bank_redirect", + payment_method_type: "blik", + payment_method_data: { + bank_redirect: { + blik: { + blik_code: "777987", + }, + }, + }, + billing: { + address: { + line1: "1467", + line2: "Harrison Street", + line3: "Harrison Street", + city: "San Fransico", + state: "California", + zip: "94122", + country: "PL", + first_name: "john", + last_name: "doe", + }, + }, + }, + }), + }, +}; diff --git a/cypress-tests/cypress/e2e/ConnectorUtils/Trustpay.js b/cypress-tests/cypress/e2e/ConnectorUtils/Trustpay.js index 182d10857e..d2a8b956b9 100644 --- a/cypress-tests/cypress/e2e/ConnectorUtils/Trustpay.js +++ b/cypress-tests/cypress/e2e/ConnectorUtils/Trustpay.js @@ -1,434 +1,560 @@ +import { getCustomExchange } from "./Commons"; + const successfulNo3DSCardDetails = { - "card_number": "4200000000000000", - "card_exp_month": "10", - "card_exp_year": "25", - "card_holder_name": "joseph Doe", - "card_cvc": "123" + card_number: "4200000000000000", + card_exp_month: "10", + card_exp_year: "25", + card_holder_name: "joseph Doe", + card_cvc: "123", }; const successfulThreeDSTestCardDetails = { - "card_number": "4200000000000067", - "card_exp_month": "03", - "card_exp_year": "2030", - "card_holder_name": "John Doe", - "card_cvc": "737", + card_number: "4200000000000067", + card_exp_month: "03", + card_exp_year: "2030", + card_holder_name: "John Doe", + card_cvc: "737", }; export const connectorDetails = { -card_pm:{ - "PaymentIntent": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "customer_acceptance": null, - "setup_future_usage": "on_session" + card_pm: { + PaymentIntent: getCustomExchange({ + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", }, - "Response": { - "status": 200, - "body": { - "status": "requires_payment_method" - } - } - }, + }, + }), "3DSAutoCapture": { - "Request": { - "card": successfulThreeDSTestCardDetails, - "currency": "USD", - "customer_acceptance": null, - "setup_future_usage": "on_session" + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "succeeded", }, - "Response": { - "status": 200, - "body": { - "status": "succeeded" - } - } + }, }, "3DSManualCapture": { - "Request": { - "card": successfulThreeDSTestCardDetails, - "currency": "USD", - "customer_acceptance": null, - "setup_future_usage": "on_session" + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: "Payment method type not supported", + code: "HE_03", + reason: "manual is not supported by trustpay", + }, }, - "Response": { - "status": 400, - "body": { - "error": { - "type": "invalid_request", - "message": "Payment method type not supported", - "code": "HE_03", - "reason": "manual is not supported by trustpay" - } - } - } + }, }, - "No3DSAutoCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "customer_acceptance": null, - "setup_future_usage": "on_session" + No3DSAutoCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 200, + body: { + status: "succeeded", }, - "Response": { - "status": 200, - "body": { - "status": "succeeded" - } - } + }, }, - "No3DSManualCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "customer_acceptance": null, - "setup_future_usage": "on_session" + No3DSManualCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + setup_future_usage: "on_session", + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: "Payment method type not supported", + code: "HE_03", + reason: "manual is not supported by trustpay", + }, }, - "Response": { - "status": 400, - "body": { - "error": { - "type": "invalid_request", - "message": "Payment method type not supported", - "code": "HE_03", - "reason": "manual is not supported by trustpay" - } - } - } + }, }, - "Capture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "customer_acceptance": null, + Capture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: + "This Payment could not be captured because it has a payment.status of requires_payment_method. The expected state is requires_capture, partially_captured_and_capturable, processing", + code: "IR_14", + }, }, - "Response": { - "status": 400, - "body": { - "error": { - "type": "invalid_request", - "message": "This Payment could not be captured because it has a payment.status of requires_payment_method. The expected state is requires_capture, partially_captured_and_capturable, processing", - "code": "IR_14", - } - } - } + }, }, - "PartialCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "paymentSuccessfulStatus": "succeeded", - "paymentSyncStatus": "succeeded", - "refundStatus": "succeeded", - "refundSyncStatus": "succeeded", - "customer_acceptance": null, + PartialCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + paymentSuccessfulStatus: "succeeded", + paymentSyncStatus: "succeeded", + refundStatus: "succeeded", + refundSyncStatus: "succeeded", + customer_acceptance: null, + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: + "This Payment could not be captured because it has a payment.status of requires_payment_method. The expected state is requires_capture, partially_captured_and_capturable, processing", + code: "IR_14", + }, }, - "Response": { - "status": 400, - "body": { - "error": { - "type": "invalid_request", - "message": "This Payment could not be captured because it has a payment.status of requires_payment_method. The expected state is requires_capture, partially_captured_and_capturable, processing", - "code": "IR_14", - } - } - } + }, }, - "Void":{ - "Request": { + Void: { + Request: {}, + Response: { + status: 200, + body: { + status: "cancelled", }, - "Response": { - "status": 200, - "body":{ - status: "cancelled" - - } - } + }, }, - "Refund": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "customer_acceptance": null, + Refund: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 200, + body: { + status: "succeeded", }, - "Response": { - "status": 200, - "body": { - "status": "succeeded", - } - - } + }, }, - "PartialRefund": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "customer_acceptance": null, + PartialRefund: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 200, + body: { + error_code: "1", + error_message: "transaction declined (invalid amount)", }, - "Response": { - "status": 200, - "body": { - "error_code": "1", - "error_message": "transaction declined (invalid amount)", - } - - } + }, }, - "SyncRefund": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "customer_acceptance": null, + SyncRefund: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + customer_acceptance: null, + }, + Response: { + status: 200, + body: { + status: "succeeded", }, - "Response": { - "status": 200, - "body": { - "status": "succeeded", - } - - } + }, }, - "MandateSingleUse3DSAutoCapture": { - "Request": { - "card": successfulThreeDSTestCardDetails, - "currency": "USD", - "mandate_type": { - "single_use": { - "amount": 8000, - "currency": "USD" - } - } + MandateSingleUse3DSAutoCapture: { + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, }, - "Response": { - "status": 400, - "body": { - "error": { - "type": "invalid_request", - "message": "Payment method type not supported", - "code": "HE_03", - } - } - } - - }, - "MandateSingleUse3DSManualCapture": { - "Request": { - "card": successfulThreeDSTestCardDetails, - "currency": "USD", - "mandate_type": { - "single_use": { - "amount": 8000, - "currency": "USD" - } - } + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: "Payment method type not supported", + code: "HE_03", + }, }, - "Response": { - "status": 400, - "body": { - "error": { - "type": "invalid_request", - "message": "Payment method type not supported", - "code": "HE_03", - } - } - } - + }, }, - "MandateSingleUseNo3DSManualCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "mandate_type": { - "single_use": { - "amount": 8000, - "currency": "USD" - } - } + MandateSingleUse3DSManualCapture: { + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, }, - "Response": { - "status": 400, - "body": { - "error": { - "type": "invalid_request", - "message": "Payment method type not supported", - "code": "HE_03", - } - } - } - }, - "MandateSingleUseNo3DSAutoCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "mandate_type": { - "single_use": { - "amount": 8000, - "currency": "USD" - } - } + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: "Payment method type not supported", + code: "HE_03", + }, }, - "Response": { - "status": 400, - "body": { - "error": { - "type": "invalid_request", - "message": "Payment method type not supported", - "code": "HE_03", - } - } - } + }, }, - "MandateMultiUseNo3DSAutoCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "mandate_type": { - "multi_use": { - "amount": 8000, - "currency": "USD" - } - } + MandateSingleUseNo3DSManualCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, }, - "Response": { - "status": 400, - "body": { - "error": { - "type": "invalid_request", - "message": "Payment method type not supported", - "code": "HE_03", - } - } - } - }, - "MandateMultiUseNo3DSManualCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "mandate_type": { - "multi_use": { - "amount": 8000, - "currency": "USD" - } - } + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: "Payment method type not supported", + code: "HE_03", + }, }, - "Response": { - "status": 400, - "body": { - "error": { - "type": "invalid_request", - "message": "Payment method type not supported", - "code": "HE_03", - } - } - } + }, }, - "MandateMultiUse3DSAutoCapture": { - "Request": { - "card": successfulThreeDSTestCardDetails, - "currency": "USD", - "mandate_type": { - "multi_use": { - "amount": 8000, - "currency": "USD" - } - } + MandateSingleUseNo3DSAutoCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, }, - "Response": { - "status": 200, - "body": { - "status": "succeeded" - } - } - }, - "MandateMultiUse3DSManualCapture": { - "Request": { - "card": successfulThreeDSTestCardDetails, - "currency": "USD", - "mandate_type": { - "multi_use": { - "amount": 8000, - "currency": "USD" - } - } + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: "Payment method type not supported", + code: "HE_03", + }, }, - "Response": { - "status": 400, - "body": { - "error": { - "type": "invalid_request", - "message": "Payment method type not supported", - "code": "HE_03", - } - } - } + }, }, - "ZeroAuthMandate": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "mandate_type": { - "single_use": { - "amount": 8000, - "currency": "USD" - } - } + MandateMultiUseNo3DSAutoCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + multi_use: { + amount: 8000, + currency: "USD", + }, }, - "Response": { - "status": 501, - "body": { - "error": { - "type": "invalid_request", - "message": "Setup Mandate flow for Trustpay is not implemented", - "code": "IR_00", - } - } - } + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: "Payment method type not supported", + code: "HE_03", + }, + }, + }, }, - "SaveCardUseNo3DSAutoCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "setup_future_usage": "on_session", - "customer_acceptance": { - "acceptance_type": "offline", - "accepted_at": "1963-05-03T04:07:52.723Z", - "online": { - "ip_address": "127.0.0.1", - "user_agent": "amet irure esse" - } + MandateMultiUseNo3DSManualCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + multi_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: "Payment method type not supported", + code: "HE_03", + }, + }, + }, + }, + MandateMultiUse3DSAutoCapture: { + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + mandate_type: { + multi_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + MandateMultiUse3DSManualCapture: { + Request: { + card: successfulThreeDSTestCardDetails, + currency: "USD", + mandate_type: { + multi_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: "Payment method type not supported", + code: "HE_03", + }, + }, + }, + }, + ZeroAuthMandate: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + mandate_type: { + single_use: { + amount: 8000, + currency: "USD", + }, + }, + }, + Response: { + status: 501, + body: { + error: { + type: "invalid_request", + message: "Setup Mandate flow for Trustpay is not implemented", + code: "IR_00", + }, + }, + }, + }, + SaveCardUseNo3DSAutoCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + setup_future_usage: "on_session", + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "127.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + Response: { + status: 200, + body: { + status: "succeeded", + }, + }, + }, + SaveCardUseNo3DSManualCapture: { + Request: { + card: successfulNo3DSCardDetails, + currency: "USD", + setup_future_usage: "on_session", + customer_acceptance: { + acceptance_type: "offline", + accepted_at: "1963-05-03T04:07:52.723Z", + online: { + ip_address: "127.0.0.1", + user_agent: "amet irure esse", + }, + }, + }, + Response: { + status: 400, + body: { + error: { + type: "invalid_request", + message: "Payment method type not supported", + code: "HE_03", + }, + }, + }, + }, + }, + bank_redirect_pm: { + PaymentIntent: getCustomExchange({ + Request: { + currency: "EUR", + }, + Response: { + status: 200, + body: { + status: "requires_payment_method", + }, + }, + }), + ideal: { + Request: { + payment_method: "bank_redirect", + payment_method_type: "ideal", + payment_method_data: { + bank_redirect: { + ideal: { + bank_name: "ing", + country: "NL", }, + }, }, - "Response": { - "status": 200, - "body": { - "status": "succeeded" - } - } + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, }, - "SaveCardUseNo3DSManualCapture": { - "Request": { - "card": successfulNo3DSCardDetails, - "currency": "USD", - "setup_future_usage": "on_session", - "customer_acceptance": { - "acceptance_type": "offline", - "accepted_at": "1963-05-03T04:07:52.723Z", - "online": { - "ip_address": "127.0.0.1", - "user_agent": "amet irure esse" - } + giropay: { + Request: { + payment_method: "bank_redirect", + payment_method_type: "giropay", + payment_method_data: { + bank_redirect: { + giropay: { + bank_name: "", + bank_account_bic: "", + bank_account_iban: "", + preferred_language: "en", + country: "DE", }, + }, }, - "Response": { - "status": 400, - "body": { - "error": { - "type": "invalid_request", - "message": "Payment method type not supported", - "code": "HE_03", - } - } - } + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, }, -} -} \ No newline at end of file + sofort: { + Request: { + payment_method: "bank_redirect", + payment_method_type: "sofort", + payment_method_data: { + bank_redirect: { + sofort: { + country: "DE", + preferred_language: "en", + }, + }, + }, + }, + Response: { + status: 200, + body: { + status: "failed", + error_code: "1133001", + }, + }, + }, + eps: { + Request: { + payment_method: "bank_redirect", + payment_method_type: "eps", + payment_method_data: { + bank_redirect: { + eps: { + bank_name: "ing", + }, + }, + }, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, + blik: { + Request: { + payment_method: "bank_redirect", + payment_method_type: "blik", + payment_method_data: { + bank_redirect: { + blik: { + name: "John Doe", + email: "example@email.com", + }, + }, + }, + billing: { + address: { + line1: "1467", + line2: "Harrison Street", + line3: "Harrison Street", + city: "San Fransico", + state: "California", + zip: "94122", + country: "PL", + first_name: "john", + last_name: "doe", + }, + }, + }, + Response: { + status: 200, + body: { + status: "requires_customer_action", + }, + }, + }, + }, +}; diff --git a/cypress-tests/cypress/e2e/ConnectorUtils/utils.js b/cypress-tests/cypress/e2e/ConnectorUtils/utils.js index 960481a125..f14c68ce94 100644 --- a/cypress-tests/cypress/e2e/ConnectorUtils/utils.js +++ b/cypress-tests/cypress/e2e/ConnectorUtils/utils.js @@ -1,6 +1,7 @@ import { connectorDetails as adyenConnectorDetails } from "./Adyen.js"; import { connectorDetails as bankOfAmericaConnectorDetails } from "./BankOfAmerica.js"; import { connectorDetails as bluesnapConnectorDetails } from "./Bluesnap.js"; +import { connectorDetails as CommonConnectorDetails } from "./Commons.js"; import { connectorDetails as cybersourceConnectorDetails } from "./Cybersource.js"; import { connectorDetails as nmiConnectorDetails } from "./Nmi.js"; import { connectorDetails as paypalConnectorDetails } from "./Paypal.js"; @@ -8,28 +9,62 @@ import { connectorDetails as stripeConnectorDetails } from "./Stripe.js"; import { connectorDetails as trustpayConnectorDetails } from "./Trustpay.js"; const connectorDetails = { - "adyen": adyenConnectorDetails, - "bankofamerica": bankOfAmericaConnectorDetails, - "bluesnap": bluesnapConnectorDetails, - "cybersource": cybersourceConnectorDetails, - "nmi": nmiConnectorDetails, - "paypal": paypalConnectorDetails, - "stripe": stripeConnectorDetails, - "trustpay": trustpayConnectorDetails - - -} - + adyen: adyenConnectorDetails, + bankofamerica: bankOfAmericaConnectorDetails, + bluesnap: bluesnapConnectorDetails, + commons: CommonConnectorDetails, + cybersource: cybersourceConnectorDetails, + nmi: nmiConnectorDetails, + paypal: paypalConnectorDetails, + stripe: stripeConnectorDetails, + trustpay: trustpayConnectorDetails, +}; export default function getConnectorDetails(connectorId) { - let x = getValueByKey(connectorDetails, connectorId); + let x = mergeDetails(connectorId); return x; } -function getValueByKey(jsonObject, key) { - const data = typeof jsonObject === 'string' ? JSON.parse(jsonObject) : jsonObject; +function mergeDetails(connectorId) { + const connectorData = getValueByKey(connectorDetails, connectorId); + const fallbackData = getValueByKey(connectorDetails, "commons"); + // Merge data, prioritizing connectorData and filling missing data from fallbackData + const mergedDetails = mergeConnectorDetails(connectorData, fallbackData); + return mergedDetails; +} - if (data && typeof data === 'object' && key in data) { +function mergeConnectorDetails(source, fallback) { + const merged = {}; + + // Loop through each key in the source object + for (const key in source) { + merged[key] = { ...source[key] }; // Copy properties from source + + // Check if fallback has the same key and properties are missing in source + if (fallback[key]) { + for (const subKey in fallback[key]) { + if (!merged[key][subKey]) { + merged[key][subKey] = fallback[key][subKey]; + } + } + } + } + + // Add missing keys from fallback that are not present in source + for (const key in fallback) { + if (!merged[key]) { + merged[key] = fallback[key]; + } + } + + return merged; +} + +function getValueByKey(jsonObject, key) { + const data = + typeof jsonObject === "string" ? JSON.parse(jsonObject) : jsonObject; + + if (data && typeof data === "object" && key in data) { return data[key]; } else { return null; @@ -37,10 +72,13 @@ function getValueByKey(jsonObject, key) { } export const should_continue_further = (res_data) => { - if(res_data.body.error !== undefined || res_data.body.error_code !== undefined || res_data.body.error_message !== undefined){ - return false; + if ( + res_data.body.error !== undefined || + res_data.body.error_code !== undefined || + res_data.body.error_message !== undefined + ) { + return false; + } else { + return true; } - else { - return true; - } -} \ No newline at end of file +}; diff --git a/cypress-tests/cypress/fixtures/confirm-body.json b/cypress-tests/cypress/fixtures/confirm-body.json index 32b9a7108b..fbf23a2016 100644 --- a/cypress-tests/cypress/fixtures/confirm-body.json +++ b/cypress-tests/cypress/fixtures/confirm-body.json @@ -1,20 +1,9 @@ { "client_secret": "", "return_url": "https://hyperswitch.io", - "payment_method": "card", "confirm": true, - "payment_method_data": { - "card": { - "_comment": "these details are fetched from utils", - "card_number": "YourCardNumberHere", - "card_exp_month": "04", - "card_exp_year": "24", - "card_holder_name": "xyz", - "card_cvc": "424", - "card_issuer": "", - "card_network": "Visa" - } - }, + "payment_method": "card", + "payment_method_data": {}, "customer_acceptance": { "acceptance_type": "offline", "accepted_at": "1963-05-03T04:07:52.723Z", diff --git a/cypress-tests/cypress/fixtures/create-connector-body.json b/cypress-tests/cypress/fixtures/create-connector-body.json index d3575c0b2c..9ab253565e 100644 --- a/cypress-tests/cypress/fixtures/create-connector-body.json +++ b/cypress-tests/cypress/fixtures/create-connector-body.json @@ -52,6 +52,78 @@ "installment_payment_enabled": true } ] + }, + { + "payment_method": "bank_transfer", + "payment_method_types": [ + { + "payment_method_type": "pix", + "minimum_amount": 0, + "maximum_amount": 68607706, + "recurring_enabled": false, + "installment_payment_enabled": true + } + ] + }, + { + "payment_method": "bank_redirect", + "payment_method_types": [ + { + "payment_method_type": "ideal", + "payment_experience": null, + "card_networks": null, + "accepted_currencies": null, + "accepted_countries": null, + "minimum_amount": 1, + "maximum_amount": 68607706, + "recurring_enabled": true, + "installment_payment_enabled": true + }, + { + "payment_method_type": "giropay", + "payment_experience": null, + "card_networks": null, + "accepted_currencies": null, + "accepted_countries": null, + "minimum_amount": 1, + "maximum_amount": 68607706, + "recurring_enabled": true, + "installment_payment_enabled": true + }, + { + "payment_method_type": "sofort", + "payment_experience": null, + "card_networks": null, + "accepted_currencies": null, + "accepted_countries": null, + "minimum_amount": 1, + "maximum_amount": 68607706, + "recurring_enabled": true, + "installment_payment_enabled": true + }, + { + "payment_method_type": "eps", + "payment_experience": null, + "card_networks": null, + "accepted_currencies": null, + "accepted_countries": null, + "minimum_amount": 1, + "maximum_amount": 68607706, + "recurring_enabled": true, + "installment_payment_enabled": true + }, + { + "payment_method_type": "blik", + "payment_experience": null, + "card_networks": null, + "accepted_currencies": null, + "accepted_countries": null, + "minimum_amount": 1, + "maximum_amount": 68607706, + "recurring_enabled": true, + "installment_payment_enabled": true + } + ] } ], "metadata": { diff --git a/cypress-tests/cypress/support/commands.js b/cypress-tests/cypress/support/commands.js index e78802e366..4842ed0173 100644 --- a/cypress-tests/cypress/support/commands.js +++ b/cypress-tests/cypress/support/commands.js @@ -26,6 +26,7 @@ // commands.js or your custom support file import * as RequestBodyUtils from "../utils/RequestBodyUtils"; +import { handleRedirection } from "./redirectionHandler"; function logRequestId(xRequestId) { if (xRequestId) { @@ -35,6 +36,13 @@ function logRequestId(xRequestId) { } } +function defaultErrorHandler(response, response_data) { + expect(response.body).to.have.property("error"); + for (const key in response_data.body.error) { + expect(response_data.body.error[key]).to.equal(response.body.error[key]); + } +} + Cypress.Commands.add("merchantCreateCallTest", (merchantCreateBody, globalState) => { const randomMerchantId = RequestBodyUtils.generateRandomString(); RequestBodyUtils.setMerchantId(merchantCreateBody, randomMerchantId); @@ -171,10 +179,7 @@ Cypress.Commands.add("createPaymentIntentTest", (request, req_data, res_data, au expect(request.amount).to.equal(response.body.amount_capturable); } else { - expect(response.body).to.have.property("error"); - for(const key in res_data.body.error) { - expect(res_data.body.error[key]).to.equal(response.body.error[key]); - } + defaultErrorHandler(response, res_data); } }); }); @@ -219,7 +224,6 @@ Cypress.Commands.add("confirmCallTest", (confirmBody, req_data, res_data, confir body: confirmBody, }).then((response) => { logRequestId(response.headers['x-request-id']); - expect(res_data.status).to.equal(response.status); expect(response.headers["content-type"]).to.include("application/json"); if(response.status === 200){ @@ -227,15 +231,14 @@ Cypress.Commands.add("confirmCallTest", (confirmBody, req_data, res_data, confir if (response.body.capture_method === "automatic") { if (response.body.authentication_type === "three_ds") { expect(response.body).to.have.property("next_action") - .to.have.property("redirect_to_url"); + .to.have.property("redirect_to_url"); globalState.set("nextActionUrl", response.body.next_action.redirect_to_url); } else if (response.body.authentication_type === "no_three_ds") { for(const key in res_data.body) { expect(res_data.body[key]).to.equal(response.body[key]); } } else { - // Handle other authentication types as needed - throw new Error(`Unsupported authentication type: ${authentication_type}`); + defaultErrorHandler(response, res_data); } } else if (response.body.capture_method === "manual") { if (response.body.authentication_type === "three_ds") { @@ -244,24 +247,158 @@ Cypress.Commands.add("confirmCallTest", (confirmBody, req_data, res_data, confir globalState.set("nextActionUrl", response.body.next_action.redirect_to_url); } else if (response.body.authentication_type === "no_three_ds") { - for(const key in res_data.body) { + for (const key in res_data.body) { expect(res_data.body[key]).to.equal(response.body[key]); - } } else { - // Handle other authentication types as needed - throw new Error(`Unsupported authentication type: ${authentication_type}`); + } + } else { + defaultErrorHandler(response, res_data); } } } else { - expect(response.body).to.have.property("error"); - for(const key in res_data.body.error) { - expect(res_data.body.error[key]).to.equal(response.body.error[key]); - } + defaultErrorHandler(response, res_data); } - }); }); +Cypress.Commands.add( + "confirmBankRedirectCallTest", + (confirmBody, req_data, res_data, confirm, globalState) => { + const paymentIntentId = globalState.get("paymentID"); + const connectorId = globalState.get("connectorId"); + for (const key in req_data) { + confirmBody[key] = req_data[key]; + } + confirmBody.confirm = confirm; + confirmBody.client_secret = globalState.get("clientSecret"); + + cy.request({ + method: "POST", + url: `${globalState.get("baseUrl")}/payments/${paymentIntentId}/confirm`, + headers: { + "Content-Type": "application/json", + "api-key": globalState.get("publishableKey"), + }, + failOnStatusCode: false, + body: confirmBody, + }).then((response) => { + logRequestId(response.headers["x-request-id"]); + expect(res_data.status).to.equal(response.status); + expect(response.headers["content-type"]).to.include("application/json"); + globalState.set("paymentID", paymentIntentId); + globalState.set("paymentMethodType", confirmBody.payment_method_type); + + switch (response.body.authentication_type) { + case "three_ds": + if ( + response.body.capture_method === "automatic" || + response.body.capture_method === "manual" + ) { + if (response.body.status !== "failed") { // we get many statuses here, hence this verification + if (connectorId === "adyen" && response.body.payment_method_type === "blik") { + expect(response.body) + .to.have.property("next_action") + .to.have.property("type") + .to.equal("wait_screen_information"); + } else { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + globalState.set( + "nextActionUrl", + response.body.next_action.redirect_to_url + ); + } + } else if (response.body.status === "failed") { + expect(response.body.error_code).to.equal(res_data.body.error_code); + } + } else { + defaultErrorHandler(response, res_data); + } + break; + case "no_three_ds": + if ( + response.body.capture_method === "automatic" || + response.body.capture_method === "manual" + ) { + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + globalState.set( + "nextActionUrl", + response.body.next_action.redirect_to_url + ); + } else { + defaultErrorHandler(response, res_data); + } + break; + default: + defaultErrorHandler(response, res_data); + } + }); + } +); + +Cypress.Commands.add( + "confirmBankTransferCallTest", + (confirmBody, req_data, res_data, confirm, globalState) => { + const paymentIntentID = globalState.get("paymentID"); + for (const key in req_data) { + confirmBody[key] = req_data[key]; + } + confirmBody.confirm = confirm; + confirmBody.client_secret = globalState.get("clientSecret"); + globalState.set("paymentMethodType", confirmBody.payment_method_type); + + cy.request({ + method: "POST", + url: `${globalState.get("baseUrl")}/payments/${paymentIntentID}/confirm`, + headers: { + "Content-Type": "application/json", + "api-key": globalState.get("publishableKey"), + }, + failOnStatusCode: false, + body: confirmBody, + }).then((response) => { + logRequestId(response.headers["x-request-id"]); + expect(res_data.status).to.equal(response.status); + expect(response.headers["content-type"]).to.include("application/json"); + globalState.set("paymentID", paymentIntentID); + if (response.status === 200) { + if ( + response.body.capture_method === "automatic" || + response.body.capture_method === "manual" + ) { + switch (response.body.payment_method_type) { + case "pix": + expect(response.body) + .to.have.property("next_action") + .to.have.property("qr_code_url"); + globalState.set( + "nextActionUrl", // This is intentionally kept as nextActionUrl to avoid issues during handleRedirection call, + response.body.next_action.qr_code_url + ); + break; + default: + expect(response.body) + .to.have.property("next_action") + .to.have.property("redirect_to_url"); + globalState.set( + "nextActionUrl", + response.body.next_action.redirect_to_url + ); + break; + } + } else { + defaultErrorHandler(response, res_data); + } + } else { + defaultErrorHandler(response, res_data); + } + }); + } +); + Cypress.Commands.add("createConfirmPaymentTest", (createConfirmPaymentBody, req_data, res_data, authentication_type, capture_method, globalState) => { createConfirmPaymentBody.payment_method_data.card = req_data.card; createConfirmPaymentBody.authentication_type = authentication_type; @@ -301,8 +438,7 @@ Cypress.Commands.add("createConfirmPaymentTest", (createConfirmPaymentBody, req_ expect(res_data.body[key]).to.equal(response.body[key]); } } else { - // Handle other authentication types as needed - throw new Error(`Unsupported authentication type: ${authentication_type}`); + defaultErrorHandler(response, res_data); } } else if (response.body.capture_method === "manual") { @@ -317,28 +453,24 @@ Cypress.Commands.add("createConfirmPaymentTest", (createConfirmPaymentBody, req_ else if (response.body.authentication_type === "no_three_ds") { for(const key in res_data.body) { expect(res_data.body[key]).to.equal(response.body[key]); - } } else { - // Handle other authentication types as needed - throw new Error(`Unsupported authentication type: ${authentication_type}`); + } + } else { + defaultErrorHandler(response, res_data); } } } else{ - expect(response.body).to.have.property("error"); - for(const key in res_data.body.error) { - expect(res_data.body.error[key]).to.equal(response.body.error[key]); - } + defaultErrorHandler(response, res_data); } }); }); // This is consequent saved card payment confirm call test(Using payment token) -Cypress.Commands.add("saveCardConfirmCallTest", (SaveCardConfirmBody, req_data, res_data,globalState) => { +Cypress.Commands.add("saveCardConfirmCallTest", (saveCardConfirmBody, req_data, res_data,globalState) => { const paymentIntentID = globalState.get("paymentID"); - SaveCardConfirmBody.card_cvc = req_data.card.card_cvc; - SaveCardConfirmBody.payment_token = globalState.get("paymentToken"); - SaveCardConfirmBody.client_secret = globalState.get("clientSecret"); - console.log("conf conn ->" + globalState.get("connectorId")); + saveCardConfirmBody.card_cvc = req_data.card.card_cvc; + saveCardConfirmBody.payment_token = globalState.get("paymentToken"); + saveCardConfirmBody.client_secret = globalState.get("clientSecret"); cy.request({ method: "POST", url: `${globalState.get("baseUrl")}/payments/${paymentIntentID}/confirm`, @@ -347,7 +479,7 @@ Cypress.Commands.add("saveCardConfirmCallTest", (SaveCardConfirmBody, req_data, "api-key": globalState.get("publishableKey"), }, failOnStatusCode: false, - body: SaveCardConfirmBody, + body: saveCardConfirmBody, }) .then((response) => { logRequestId(response.headers['x-request-id']); @@ -368,7 +500,7 @@ Cypress.Commands.add("saveCardConfirmCallTest", (SaveCardConfirmBody, req_data, expect(response.body.customer_id).to.equal(globalState.get("customerId")); } else { // Handle other authentication types as needed - throw new Error(`Unsupported authentication type: ${authentication_type}`); + defaultErrorHandler(response, res_data); } } else if (response.body.capture_method === "manual") { if (response.body.authentication_type === "three_ds") { @@ -378,18 +510,16 @@ Cypress.Commands.add("saveCardConfirmCallTest", (SaveCardConfirmBody, req_data, else if (response.body.authentication_type === "no_three_ds") { for(const key in res_data.body) { expect(res_data.body[key]).to.equal(response.body[key]); - } expect(response.body.customer_id).to.equal(globalState.get("customerId")); + } + expect(response.body.customer_id).to.equal(globalState.get("customerId")); } else { // Handle other authentication types as needed - throw new Error(`Unsupported authentication type: ${authentication_type}`); + defaultErrorHandler(response, res_data); } } } else { - expect(response.body).to.have.property("error"); - for(const key in res_data.body.error) { - expect(res_data.body.error[key]).to.equal(response.body.error[key]); - } + defaultErrorHandler(response, res_data); } }); }); @@ -419,12 +549,8 @@ Cypress.Commands.add("captureCallTest", (requestBody, req_data, res_data, amount } } else{ - expect(response.body).to.have.property("error"); - for(const key in res_data.body.error) { - expect(res_data.body.error[key]).to.equal(response.body.error[key]); - } + defaultErrorHandler(response, res_data); } - }); }); @@ -450,16 +576,12 @@ Cypress.Commands.add("voidCallTest", (requestBody, req_data, res_data, globalSta } } else{ - expect(response.body).to.have.property("error"); - for(const key in res_data.body.error) { - expect(res_data.body.error[key]).to.equal(response.body.error[key]); - } + defaultErrorHandler(response, res_data); } }); }); Cypress.Commands.add("retrievePaymentCallTest", (globalState) => { - console.log("syncpaymentID ->" + globalState.get("paymentID")); const payment_id = globalState.get("paymentID"); cy.request({ method: "GET", @@ -476,7 +598,6 @@ Cypress.Commands.add("retrievePaymentCallTest", (globalState) => { expect(response.body.payment_id).to.equal(payment_id); expect(response.body.amount).to.equal(globalState.get("paymentAmount")); globalState.set("paymentID", response.body.payment_id); - }); }); @@ -506,10 +627,7 @@ Cypress.Commands.add("refundCallTest", (requestBody, req_data, res_data, refund_ expect(response.body.payment_id).to.equal(payment_id); } else{ - expect(response.body).to.have.property("error"); - for(const key in res_data.body.error) { - expect(res_data.body.error[key]).to.equal(response.body.error[key]); - } + defaultErrorHandler(response, res_data); } }); @@ -591,10 +709,7 @@ Cypress.Commands.add("citForMandatesCallTest", (requestBody, req_data, res_data, } } else{ - expect(response.body).to.have.property("error"); - for(const key in res_data.body.error) { - expect(res_data.body.error[key]).to.equal(response.body.error[key]); - } + defaultErrorHandler(response, res_data); } }); }); @@ -606,7 +721,6 @@ Cypress.Commands.add("mitForMandatesCallTest", (requestBody, amount, confirm, ca requestBody.mandate_id = globalState.get("mandateId"); requestBody.customer_id = globalState.get("customerId"); globalState.set("paymentAmount", requestBody.amount); - console.log("mit body " + JSON.stringify(requestBody)); cy.request({ method: "POST", url: `${globalState.get("baseUrl")}/payments`, @@ -620,7 +734,6 @@ Cypress.Commands.add("mitForMandatesCallTest", (requestBody, amount, confirm, ca logRequestId(response.headers['x-request-id']); expect(response.headers["content-type"]).to.include("application/json"); globalState.set("paymentID", response.body.payment_id); - console.log("mit statusss-> " + response.body.status); if (response.body.capture_method === "automatic") { if (response.body.authentication_type === "three_ds") { expect(response.body).to.have.property("next_action") @@ -631,8 +744,7 @@ Cypress.Commands.add("mitForMandatesCallTest", (requestBody, amount, confirm, ca } else if (response.body.authentication_type === "no_three_ds") { expect(response.body.status).to.equal("succeeded"); } else { - // Handle other authentication types as needed - throw new Error(`Unsupported authentication type: ${authentication_type}`); + defaultErrorHandler(response, res_data); } } else if (response.body.capture_method === "manual") { @@ -645,8 +757,7 @@ Cypress.Commands.add("mitForMandatesCallTest", (requestBody, amount, confirm, ca } else if (response.body.authentication_type === "no_three_ds") { expect(response.body.status).to.equal("requires_capture"); } else { - // Handle other authentication types as needed - throw new Error(`Unsupported authentication type: ${authentication_type}`); + defaultErrorHandler(response, res_data); } } }); @@ -698,82 +809,53 @@ Cypress.Commands.add("revokeMandateCallTest", (globalState) => { }); }); - Cypress.Commands.add("handleRedirection", (globalState, expected_redirection) => { let connectorId = globalState.get("connectorId"); let expected_url = new URL(expected_redirection); let redirection_url = new URL(globalState.get("nextActionUrl")); - cy.visit(redirection_url.href); - if (globalState.get("connectorId") == "adyen") { - cy.get('iframe') - .its('0.contentDocument.body') - .within((body) => { - cy.get('input[type="password"]').click(); - cy.get('input[type="password"]').type("password"); - cy.get('#buttonSubmit').click(); - }) - } - else if (globalState.get("connectorId") === "cybersource" || globalState.get("connectorId") === "bankofamerica") { - cy.get('iframe', { timeout: 15000 }) - .its('0.contentDocument.body') - .within((body) => { - cy.get('input[type="text"]').click().type("1234"); - cy.get('input[value="SUBMIT"]').click(); - }) - } - else if (globalState.get("connectorId") === "nmi" || globalState.get("connectorId") === "noon") { - cy.get('iframe', { timeout: 150000 }) - .its('0.contentDocument.body') - .within((body) => { - cy.get('iframe', { timeout: 20000 }) - .its('0.contentDocument.body') - .within((body) => { - cy.get('form[name="cardholderInput"]', { timeout: 20000 }).should('exist').then(form => { - cy.get('input[name="challengeDataEntry"]').click().type("1234"); - cy.get('input[value="SUBMIT"]').click(); - }) - }) - }) - } - - else if (globalState.get("connectorId") === "stripe") { - cy.get('iframe', { timeout: 30000 }) - .its('0.contentDocument.body') - .within((body) => { - cy.get('iframe') - .its('0.contentDocument.body') - .within((body) => { - cy.get('#test-source-authorize-3ds').click(); - }) - }) - } - else if (globalState.get("connectorId") === "trustpay") { - cy.get('form[name="challengeForm"]', { timeout: 10000 }).should('exist').then(form => { - cy.get('#outcomeSelect').select('Approve').should('have.value', 'Y') - cy.get('button[type="submit"]').click(); - }) - } - - - else { - // If connectorId is neither of adyen, trustpay, nmi, stripe, bankofamerica or cybersource, wait for 10 seconds - cy.wait(10000); - } - - // Handling redirection - if (redirection_url.host.endsWith(expected_url.host)) { - // No CORS workaround needed - cy.window().its('location.origin').should('eq', expected_url.origin); - } else { - // Workaround for CORS to allow cross-origin iframe - cy.origin(expected_url.origin, { args: { expected_url: expected_url.origin } }, ({ expected_url }) => { - cy.window().its('location.origin').should('eq', expected_url); - }) - } + handleRedirection( + "three_ds", + { redirection_url, expected_url }, + connectorId, + null + ); }); +Cypress.Commands.add( + "handleBankRedirectRedirection", + (globalState, payment_method_type, expected_redirection) => { + let connectorId = globalState.get("connectorId"); + let expected_url = new URL(expected_redirection); + let redirection_url = new URL(globalState.get("nextActionUrl")); + // explicitly restricting `sofort` payment method by adyen from running as it stops other tests from running + // trying to handle that specific case results in stripe 3ds tests to fail + if (!(connectorId == "adyen" && payment_method_type == "sofort")) { + handleRedirection( + "bank_redirect", + { redirection_url, expected_url }, + connectorId, + payment_method_type + ); + } + } +); + +Cypress.Commands.add( + "handleBankTransferRedirection", + (globalState, payment_method_type, expected_redirection) => { + let connectorId = globalState.get("connectorId"); + let redirection_url = new URL(globalState.get("nextActionUrl")); + cy.log(payment_method_type); + handleRedirection( + "bank_transfer", + { redirection_url, expected_redirection }, + connectorId, + payment_method_type + ); + } +); + Cypress.Commands.add("listCustomerPMCallTest", (globalState) => { - console.log("customerID ->" + globalState.get("customerId")); const customerId = globalState.get("customerId"); cy.request({ method: "GET", @@ -792,7 +874,7 @@ Cypress.Commands.add("listCustomerPMCallTest", (globalState) => { expect(paymentToken).to.equal(globalState.get("paymentToken")); // Verify paymentToken } else { - throw new Error(`Payment token not found`); + defaultErrorHandler(response, res_data); } }); }); @@ -808,11 +890,7 @@ Cypress.Commands.add("listRefundCallTest", (requestBody, globalState) => { body: requestBody, }).then((response) => { logRequestId(response.headers['x-request-id']); - expect(response.headers["content-type"]).to.include("application/json"); expect(response.body.data).to.be.an('array').and.not.empty; - }); }); - - diff --git a/cypress-tests/cypress/support/redirectionhandler.js b/cypress-tests/cypress/support/redirectionhandler.js new file mode 100644 index 0000000000..6e48185815 --- /dev/null +++ b/cypress-tests/cypress/support/redirectionhandler.js @@ -0,0 +1,319 @@ +import jsQR from "jsqr"; + +export function handleRedirection( + redirection_type, + urls, + connectorId, + payment_method_type +) { + switch (redirection_type) { + case "three_ds": + threeDsRedirection(urls.redirection_url, urls.expected_url, connectorId); + break; + case "bank_redirect": + bankRedirectRedirection( + urls.redirection_url, + urls.expected_url, + connectorId, + payment_method_type + ); + break; + case "bank_transfer": + bankTransferRedirection( + urls.redirection_url, + urls.expected_url, + connectorId, + payment_method_type + ); + break; + default: + throw new Error(`Redirection known: ${redirection_type}`); + } +} + +function bankTransferRedirection( + redirection_url, + expected_url, + connectorId, + payment_method_type +) { + cy.request(redirection_url.href).then((response) => { + switch (connectorId) { + case "adyen": + switch (payment_method_type) { + case "pix": + expect(response.status).to.eq(200); + fetchAndParseQRCode(redirection_url.href).then((qrCodeData) => { + expect(qrCodeData).to.eq("TestQRCodeEMVToken"); + }); + break; + default: + verifyReturnUrl(redirection_url, expected_url, true); + // expected_redirection can be used here to handle other payment methods + } + break; + default: + verifyReturnUrl(redirection_url, expected_url, true); + } + }); +} + +function threeDsRedirection(redirection_url, expected_url, connectorId) { + cy.visit(redirection_url.href); + if (connectorId == "adyen") { + cy.get("iframe") + .its("0.contentDocument.body") + .within((body) => { + cy.get('input[type="password"]').click(); + cy.get('input[type="password"]').type("password"); + cy.get("#buttonSubmit").click(); + }); + } else if (connectorId === "bankofamerica" || connectorId === "cybersource") { + cy.get("iframe", { timeout: 15000 }) + .its("0.contentDocument.body") + .within((body) => { + cy.get('input[type="text"]').click().type("1234"); + cy.get('input[value="SUBMIT"]').click(); + }); + } else if (connectorId === "nmi" || connectorId === "noon") { + cy.get("iframe", { timeout: 150000 }) + .its("0.contentDocument.body") + .within((body) => { + cy.get("iframe", { timeout: 20000 }) + .its("0.contentDocument.body") + .within((body) => { + cy.get('form[name="cardholderInput"]', { timeout: 20000 }) + .should("exist") + .then((form) => { + cy.get('input[name="challengeDataEntry"]').click().type("1234"); + cy.get('input[value="SUBMIT"]').click(); + }); + }); + }); + } else if (connectorId === "stripe") { + cy.get("iframe", { timeout: 15000 }) + .its("0.contentDocument.body") + .within((body) => { + cy.get("iframe") + .its("0.contentDocument.body") + .within((body) => { + cy.get("#test-source-authorize-3ds").click(); + }); + }); + } else if (connectorId === "trustpay") { + cy.get('form[name="challengeForm"]', { timeout: 10000 }) + .should("exist") + .then((form) => { + cy.get("#outcomeSelect").select("Approve").should("have.value", "Y"); + cy.get('button[type="submit"]').click(); + }); + } else { + // If connectorId is neither of adyen, trustpay, nmi, stripe, bankofamerica or cybersource, wait for 10 seconds + cy.wait(10000); + } + + verifyReturnUrl(redirection_url, expected_url, true); +} + +function bankRedirectRedirection( + redirection_url, + expected_url, + connectorId, + payment_method_type +) { + let verifyUrl = false; + cy.visit(redirection_url.href); + + switch (connectorId) { + case "adyen": + switch (payment_method_type) { + case "eps": + cy.get("h1").should("contain.text", "Acquirer Simulator"); + cy.get('[value="authorised"]').click(); + cy.url().should("include", "status=succeeded"); + cy.wait(5000); + break; + case "ideal": + cy.get(":nth-child(4) > td > p").should( + "contain.text", + "Your Payment was Authorised/Refused/Cancelled (It may take up to five minutes to show on the Payment List)" + ); + cy.get(".btnLink").click(); + cy.url().should("include", "status=succeeded"); + cy.wait(5000); + break; + case "giropay": + cy.get( + ".rds-cookies-overlay__allow-all-cookies-btn > .rds-button" + ).click(); + cy.wait(5000); + cy.get(".normal-3").should( + "contain.text", + "Bank suchen ‑ mit giropay zahlen." + ); + cy.get("#bankSearch").type("giropay TestBank{enter}"); + cy.get(".normal-2 > div").click(); + cy.get('[data-testid="customerIban"]').type("DE48499999601234567890"); + cy.get('[data-testid="customerIdentification"]').type("1234567890"); + cy.get(":nth-child(3) > .rds-button").click(); + cy.get('[data-testid="onlineBankingPin"]').type("1234"); + cy.get(".rds-button--primary").click(); + cy.get(":nth-child(5) > .rds-radio-input-group__label").click(); + cy.get(".rds-button--primary").click(); + cy.get('[data-testid="photoTan"]').type("123456"); + cy.get(".rds-button--primary").click(); + cy.wait(5000); + cy.url().should("include", "status=succeeded"); + cy.wait(5000); + break; + case "sofort": + cy.get(".modal-overlay.modal-shown.in", { timeout: 5000 }).then( + ($modal) => { + // If modal is found, handle it + if ($modal.length > 0) { + cy.get("button.cookie-modal-deny-all.button-tertiary") + .should("be.visible") + .should("contain", "Reject All") + .click({ force: true, multiple: true }); + cy.get("div#TopBanks.top-banks-multistep") + .should("contain", "Demo Bank") + .as("btn") + .click(); + cy.get("@btn").click(); + } else { + cy.get("input.phone").type("9123456789"); + cy.get("#button.onContinue") + .should("contain", "Continue") + .click(); + } + } + ); + break; + case "trustly": + break; + default: + throw new Error( + `Unsupported payment method type: ${payment_method_type}` + ); + } + verifyUrl = true; + break; + case "trustpay": + switch (payment_method_type) { + case "eps": + cy.get("._transactionId__header__iXVd_").should( + "contain.text", + "Bank suchen ‑ mit eps zahlen." + ); + cy.get(".BankSearch_searchInput__uX_9l").type( + "Allgemeine Sparkasse Oberösterreich Bank AG{enter}" + ); + cy.get(".BankSearch_searchResultItem__lbcKm").click(); + cy.get("._transactionId__primaryButton__nCa0r").click(); + cy.get("#loginTitle").should( + "contain.text", + "eps Online-Überweisung Login" + ); + cy.get("#user") + .should("be.visible") + .should("be.enabled") + .focus() + .type("Verfügernummer"); + cy.get("input#submitButton.btn.btn-primary").click(); + break; + case "ideal": + cy.get("p").should( + "contain.text", + "Choose your iDeal Issuer Bank please" + ); + cy.get("#issuerSearchInput").click(); + cy.get("#issuerSearchInput").type("ING{enter}"); + cy.get("#trustpay__selectIssuer_submit").click(); + break; + case "giropay": + cy.get("._transactionId__header__iXVd_").should( + "contain.text", + "Bank suchen ‑ mit giropay zahlen." + ); + cy.get(".BankSearch_searchInput__uX_9l").type( + "Volksbank Hildesheim{enter}" + ); + cy.get(".BankSearch_searchIcon__EcVO7").click(); + cy.get(".BankSearch_bankWrapper__R5fUK").click(); + cy.get("._transactionId__primaryButton__nCa0r").click(); + cy.get(".normal-3").should("contain.text", "Kontoauswahl"); + break; + case "sofort": + break; + case "trustly": + break; + default: + throw new Error( + `Unsupported payment method type: ${payment_method_type}` + ); + } + verifyUrl = false; + break; + default: + throw new Error(`Unsupported connector: ${connectorId}`); + } + verifyReturnUrl(redirection_url, expected_url, verifyUrl); +} + +function verifyReturnUrl(redirection_url, expected_url, forward_flow) { + if (forward_flow) { + // Handling redirection + if (redirection_url.host.endsWith(expected_url.host)) { + // No CORS workaround needed + cy.window().its("location.origin").should("eq", expected_url.origin); + } else { + // Workaround for CORS to allow cross-origin iframe + cy.origin( + expected_url.origin, + { args: { expected_url: expected_url.origin } }, + ({ expected_url }) => { + cy.window().its("location.origin").should("eq", expected_url); + } + ); + } + } +} + +async function fetchAndParseQRCode(url) { + const response = await fetch(url, { encoding: "binary" }); + if (!response.ok) { + throw new Error(`Failed to fetch QR code image: ${response.statusText}`); + } + const blob = await response.blob(); + const reader = new FileReader(); + return await new Promise((resolve, reject) => { + reader.onload = () => { + const base64Image = reader.result.split(",")[1]; // Remove data URI prefix + const image = new Image(); + image.src = base64Image; + + image.onload = () => { + const canvas = document.createElement("canvas"); + const ctx = canvas.getContext("2d"); + canvas.width = image.width; + canvas.height = image.height; + ctx.drawImage(image, 0, 0); + + const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); + const qrCodeData = jsQR( + imageData.data, + imageData.width, + imageData.height + ); + + if (qrCodeData) { + resolve(qrCodeData.data); + } else { + reject(new Error("Failed to decode QR code")); + } + }; + image.onerror = reject; // Handle image loading errors + }; + reader.readAsDataURL(blob); + }); +} diff --git a/cypress-tests/package.json b/cypress-tests/package.json index fff8cd8b3f..af4b0244fb 100644 --- a/cypress-tests/package.json +++ b/cypress-tests/package.json @@ -9,5 +9,8 @@ "cypress:ci": "npx cypress run --headless" }, "author": "", - "license": "ISC" + "license": "ISC", + "dependencies": { + "jsqr": "^1.4.0" + } }