diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 6a037a237..6da05b26c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -74,4 +74,3 @@ jobs: with: directory: ./coverage/vitest flags: vitest - diff --git a/src/lib/appSwitchResume.js b/src/lib/appSwitchResume.js index c5bb7f3d3..178ccc8bb 100644 --- a/src/lib/appSwitchResume.js +++ b/src/lib/appSwitchResume.js @@ -16,8 +16,52 @@ export type AppSwitchResumeParams = {| checkoutState: "onApprove" | "onCancel" | "onError", |}; +// The Web fallback flow uses different set of query params then appswitch flow. +function getAppSwitchParamsWebFallback(): AppSwitchResumeParams | null { + try { + const params = Object.fromEntries( + // eslint-disable-next-line compat/compat + new URLSearchParams(window.location.search) + ); + const { + buttonSessionID, + fundingSource, + token: orderID, + PayerID: payerID, + vaultSetupToken: vaultToken, + approval_token_id: approvalTokenID, + approval_session_id: approvalSessionID, + } = params; + + const vaultSetupToken = vaultToken || approvalTokenID || approvalSessionID; + + if (vaultSetupToken || orderID) { + const resumeParams: AppSwitchResumeParams = { + checkoutState: payerID ? "onApprove" : "onCancel", + payerID, + orderID, + vaultSetupToken, + buttonSessionID, + // URLSearchParams get returns as string, + // but below code excepts a value from list of string. + // $FlowIgnore[incompatible-type] + fundingSource, + }; + return resumeParams; + } + return null; + } catch (err) { + // no-op + return null; + } +} + export function getAppSwitchResumeParams(): AppSwitchResumeParams | null { - const hashString = window.location.hash && window.location.hash.slice(1); + const hashString = + window.location.hash && String(window.location.hash).slice(1); + if (!hashString) { + return getAppSwitchParamsWebFallback(); + } const [hash, queryString] = hashString.split("?"); const isPostApprovalAction = [ @@ -26,7 +70,7 @@ export function getAppSwitchResumeParams(): AppSwitchResumeParams | null { APP_SWITCH_RETURN_HASH.ONERROR, ].includes(hash); if (!isPostApprovalAction) { - return null; + return getAppSwitchParamsWebFallback(); } const { diff --git a/src/lib/appSwithResume.test.js b/src/lib/appSwithResume.test.js index ef23550ff..dbf604e06 100644 --- a/src/lib/appSwithResume.test.js +++ b/src/lib/appSwithResume.test.js @@ -44,7 +44,6 @@ describe("app switch resume flow", () => { test("should test fetching resume params with invalid callback passed", () => { vi.spyOn(window, "location", "get").mockReturnValue({ hash: "#Unknown", - search: `buttonSessionID=${buttonSessionID}&token=${orderID}&fundingSource=${fundingSource}`, }); const params = getAppSwitchResumeParams(); @@ -87,4 +86,41 @@ describe("app switch resume flow", () => { }); expect(isAppSwitchResumeFlow()).toEqual(true); }); + + test("should test onApprove resume params when parameters are passed from web fallback", () => { + vi.spyOn(window, "location", "get").mockReturnValue({ + search: `?buttonSessionID=${buttonSessionID}&token=${orderID}&fundingSource=${fundingSource}&vaultSetupToken=VA-3&PayerID=PP123456`, + }); + + const params = getAppSwitchResumeParams(); + + expect.assertions(2); + expect(params).toEqual({ + buttonSessionID, + checkoutState: "onApprove", + fundingSource, + orderID, + payerID: "PP123456", + vaultSetupToken: "VA-3", + }); + expect(isAppSwitchResumeFlow()).toEqual(true); + }); + + test("should test onCancel resume params when parameters are passed from web fallback", () => { + vi.spyOn(window, "location", "get").mockReturnValue({ + search: `?buttonSessionID=${buttonSessionID}&token=${orderID}&fundingSource=${fundingSource}&vaultSetupToken=VA-3`, + }); + + const params = getAppSwitchResumeParams(); + + expect.assertions(2); + expect(params).toEqual({ + buttonSessionID, + checkoutState: "onCancel", + fundingSource, + orderID, + vaultSetupToken: "VA-3", + }); + expect(isAppSwitchResumeFlow()).toEqual(true); + }); }); diff --git a/src/zoid/buttons/component.jsx b/src/zoid/buttons/component.jsx index e731c5c35..3ef21ae05 100644 --- a/src/zoid/buttons/component.jsx +++ b/src/zoid/buttons/component.jsx @@ -371,7 +371,7 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => { () => { window.addEventListener( "visibilitychange", - props.hashChangeHandler + props.visibilityChangeHandler ); }, }, @@ -384,7 +384,7 @@ export const getButtonsComponent: () => ButtonsComponent = memoize(() => { () => { window.removeEventListener( "visibilitychange", - props.hashChangeHandler + props.visibilityChangeHandler ); }, },