Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into 773-feature-handle-if…
Browse files Browse the repository at this point in the history
…rame-redirections
  • Loading branch information
kashif-m committed Nov 7, 2024
2 parents 1965e20 + 2930ae0 commit d39aeaf
Show file tree
Hide file tree
Showing 10 changed files with 115 additions and 26 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
## [0.101.2](https://github.com/juspay/hyperswitch-web/compare/v0.101.1...v0.101.2) (2024-11-07)

## [0.101.1](https://github.com/juspay/hyperswitch-web/compare/v0.101.0...v0.101.1) (2024-11-07)

# [0.101.0](https://github.com/juspay/hyperswitch-web/compare/v0.100.1...v0.101.0) (2024-11-07)
Expand Down
81 changes: 81 additions & 0 deletions cypress-tests/cypress/e2e/external-3DS-netcetera-e2e-test.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import * as testIds from "../../../src/Utilities/TestUtils.bs";
import { getClientURL, netceteraChallengeTestCard, createPaymentBody, changeObjectKeyValue, connectorProfileIdMapping, connectorEnum } from "../support/utils";
describe("External 3DS using Netcetera Checks", () => {
let getIframeBody: () => Cypress.Chainable<JQuery<HTMLBodyElement>>;
const publishableKey = Cypress.env('HYPERSWITCH_PUBLISHABLE_KEY')
const secretKey = Cypress.env('HYPERSWITCH_SECRET_KEY')
changeObjectKeyValue(createPaymentBody, "profile_id", connectorProfileIdMapping.get(connectorEnum.NETCETERA))
changeObjectKeyValue(createPaymentBody, "request_external_three_ds_authentication", true)
changeObjectKeyValue(createPaymentBody, "authentication_type", "three_ds")
let iframeSelector =
"#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element";

beforeEach(() => {
getIframeBody = () => cy.iframe(iframeSelector);
cy.createPaymentIntent(secretKey, createPaymentBody).then(() => {
cy.getGlobalState("clientSecret").then((clientSecret) => {

cy.visit(getClientURL(clientSecret, publishableKey));
});

})
});


it("title rendered correctly", () => {
cy.contains("Hyperswitch Unified Checkout").should("be.visible");
});

it("orca-payment-element iframe loaded", () => {
cy.get(
"#orca-payment-element-iframeRef-orca-elements-payment-element-payment-element"
)
.should("be.visible")
.its("0.contentDocument")
.its("body");
});


it('If the user completes the challenge, the payment should be successful.', () => {
getIframeBody().find(`[data-testid=${testIds.addNewCardIcon}]`).click()
getIframeBody().find(`[data-testid=${testIds.cardNoInputTestId}]`).type(netceteraChallengeTestCard)
getIframeBody().find(`[data-testid=${testIds.expiryInputTestId}]`).type("0444")
cy.wait(1000)
getIframeBody().find(`[data-testid=${testIds.cardCVVInputTestId}]`).type("1234")
getIframeBody().get("#submit").click();
cy.wait(4000)

cy.nestedIFrame("#threeDsAuthFrame", ($body) => {
cy.wrap($body).find('#otp')
.type('1234')

cy.wrap($body).find('#sendOtp')
.click()
cy.contains("Thanks for your order!").should("be.visible");
})

})

it('If the user closes the challenge, the payment should fail.', () => {
getIframeBody().find(`[data-testid=${testIds.addNewCardIcon}]`).click()
getIframeBody().find(`[data-testid=${testIds.cardNoInputTestId}]`).type(netceteraChallengeTestCard)
getIframeBody().find(`[data-testid=${testIds.expiryInputTestId}]`).type("0444")
cy.wait(1000)
getIframeBody().find(`[data-testid=${testIds.cardCVVInputTestId}]`).type("1234")
getIframeBody().get("#submit").click();
cy.wait(4000)

cy.nestedIFrame("#threeDsAuthFrame", ($body) => {
cy.wrap($body)
.find('#cancel')
.click()
cy.contains("Payment Failed!").should("be.visible");
})
})


})




8 changes: 8 additions & 0 deletions cypress-tests/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,11 @@ Cypress.Commands.add("createPaymentIntent", (secretKey: string, createPaymentBod
Cypress.Commands.add("getGlobalState", (key: any) => {
return globalState[key];
});

Cypress.Commands.add("nestedIFrame", (selector, callback) => {
cy.iframe("#orca-fullscreen").find(selector).should("exist").should("be.visible").then(($ele) => {
const $body =
$ele.contents().find('body')
callback($body);
})
});
1 change: 1 addition & 0 deletions cypress-tests/cypress/support/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ declare global {
): Chainable<JQuery<HTMLElement>>
createPaymentIntent(secretKey: string, createPaymentBody: Record<string, any>): Chainable<Response<any>>
getGlobalState(key: string): Chainable<Response<any>>
nestedIFrame(selector: string, callback: (body: Chainable<JQuery<HTMLElement>>) => void): Chainable<void>;
}
}
}
9 changes: 6 additions & 3 deletions cypress-tests/cypress/support/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,17 @@ export const getClientURL = (clientSecret, publishableKey) => {
return `${CLIENT_BASE_URL}?isCypressTestMode=true&clientSecret=${clientSecret}&publishableKey=${publishableKey}`;
}

export const enum connectorEnum{
export const enum connectorEnum {
TRUSTPAY,
ADYEN,
STRIPE
STRIPE,
NETCETERA
}
export const connectorProfileIdMapping = new Map<connectorEnum, string>([
[connectorEnum.TRUSTPAY, "pro_eP323T9e4ApKpilWBfPA"],
[connectorEnum.ADYEN, "pro_Kvqzu8WqBZsT1OjHlCj4"],
[connectorEnum.STRIPE, "pro_5fVcCxU8MFTYozgtf0P8"],
[connectorEnum.NETCETERA, "pro_h9VHXnJx8s6W4KSZfSUL"]
]);

export const createPaymentBody = {
Expand Down Expand Up @@ -78,7 +80,7 @@ export const createPaymentBody = {

}

export const changeObjectKeyValue = (object: Record<string, any>, key: string, value: string) => {
export const changeObjectKeyValue = (object: Record<string, any>, key: string, value: boolean | string) => {
object[key] = value
}

Expand Down Expand Up @@ -128,3 +130,4 @@ export const adyenTestCard = "4917610000000000";
export const bluesnapTestCard = "4000000000001091";
export const amexTestCard = "378282246310005"
export const visaTestCard = "4242424242424242";
export const netceteraChallengeTestCard = "348638267931507";
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "orca-payment-page",
"version": "0.101.1",
"version": "0.101.2",
"main": "index.js",
"private": true,
"dependencies": {
Expand Down
16 changes: 12 additions & 4 deletions src/Payments/ACHBankTransfer.res
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ let make = (~paymentType: CardThemeType.mode) => {
let intent = PaymentHelpers.usePaymentIntent(Some(loggerState), BankTransfer)
let (email, _) = Recoil.useLoggedRecoilState(userEmailAddress, "email", loggerState)
let setComplete = Recoil.useSetRecoilState(fieldsComplete)
let paymentMethodListValue = Recoil.useRecoilValueFromAtom(PaymentUtils.paymentMethodListValue)

let (requiredFieldsBody, setRequiredFieldsBody) = React.useState(_ => Dict.make())

let complete = email.value != "" && email.isValid->Option.getOr(false)
let empty = email.value == ""
Expand All @@ -27,9 +28,14 @@ let make = (~paymentType: CardThemeType.mode) => {
let confirm = json->getDictFromJson->ConfirmType.itemToObjMapper
if confirm.doSubmit {
if complete {
let (connectors, _) = paymentMethodListValue->PaymentUtils.getConnectors(BankTransfer(ACH))
let bodyArr =
PaymentBody.dynamicPaymentBody("bank_transfer", "ach")
->getJsonFromArrayOfJson
->flattenObject(true)
->mergeTwoFlattenedJsonDicts(requiredFieldsBody)
->getArrayOfTupleFromDict
intent(
~bodyArr=PaymentBody.achBankTransferBody(~email=email.value, ~connectors),
~bodyArr,
~confirmParam=confirm.confirmParams,
~handleUserError=false,
~iframeId,
Expand All @@ -43,7 +49,9 @@ let make = (~paymentType: CardThemeType.mode) => {
useSubmitPaymentData(submitCallback)

<div className="flex flex-col animate-slowShow" style={gridGap: themeObj.spacingTab}>
<EmailPaymentInput paymentType />
<DynamicFields
paymentType paymentMethod="bank_transfer" paymentMethodType="ach" setRequiredFieldsBody
/>
<Surcharge paymentMethod="bank_transfer" paymentMethodType="ach" />
<InfoElement />
</div>
Expand Down
1 change: 1 addition & 0 deletions src/Payments/PaymentMethodsRecord.res
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,7 @@ let dynamicFieldsEnabledPaymentMethods = [
"upi_collect",
"sepa",
"affirm",
"ach",
]

let getIsBillingField = requiredFieldType => {
Expand Down
17 changes: 1 addition & 16 deletions src/Utilities/PaymentBody.res
Original file line number Diff line number Diff line change
Expand Up @@ -654,21 +654,6 @@ let epsBody = (~name, ~bankName) => [
),
]

let achBankTransferBody = (~email, ~connectors) => [
("payment_method", "bank_transfer"->JSON.Encode.string),
("connector", connectors->Utils.getArrofJsonString->JSON.Encode.array),
("payment_method_type", "ach"->JSON.Encode.string),
(
"payment_method_data",
[
("billing", [("email", email->JSON.Encode.string)]->Utils.getJsonFromArrayOfJson),
(
"bank_transfer",
[("ach_bank_transfer", Dict.make()->JSON.Encode.object)]->Utils.getJsonFromArrayOfJson,
),
]->Utils.getJsonFromArrayOfJson,
),
]
let bacsBankTransferBody = (~email, ~name, ~connectors) => {
let (firstName, lastName) = name->Utils.getFirstAndLastNameFromFullName

Expand Down Expand Up @@ -945,7 +930,7 @@ let appendRedirectPaymentMethods = [
]

let appendBankeDebitMethods = ["sepa"]
let appendBankTransferMethods = ["sepa"]
let appendBankTransferMethods = ["sepa", "ach"]

let getPaymentMethodSuffix = (~paymentMethodType, ~paymentMethod, ~isQrPaymentMethod) => {
if isQrPaymentMethod {
Expand Down

0 comments on commit d39aeaf

Please sign in to comment.