diff --git a/src/lib/appSwitchResume.js b/src/lib/appSwitchResume.js index b7dbb0ae5..c5bb7f3d3 100644 --- a/src/lib/appSwitchResume.js +++ b/src/lib/appSwitchResume.js @@ -1,5 +1,6 @@ /* @flow */ import { FUNDING } from "@paypal/sdk-constants/src"; +import { parseQuery } from "@krakenjs/belter/src"; import { APP_SWITCH_RETURN_HASH } from "../constants"; @@ -16,46 +17,47 @@ export type AppSwitchResumeParams = {| |}; export function getAppSwitchResumeParams(): AppSwitchResumeParams | null { - const urlHash = String(window.location.hash).replace("#", ""); + const hashString = window.location.hash && window.location.hash.slice(1); + const [hash, queryString] = hashString.split("?"); + const isPostApprovalAction = [ APP_SWITCH_RETURN_HASH.ONAPPROVE, APP_SWITCH_RETURN_HASH.ONCANCEL, APP_SWITCH_RETURN_HASH.ONERROR, - ].includes(urlHash); + ].includes(hash); if (!isPostApprovalAction) { return null; } - // eslint-disable-next-line compat/compat - const search = new URLSearchParams(window.location.search); - const orderID = search.get("orderID"); - const payerID = search.get("payerID"); - const buttonSessionID = search.get("buttonSessionID"); - const billingToken = search.get("billingToken"); - const paymentID = search.get("paymentID"); - const subscriptionID = search.get("subscriptionID"); - const vaultSetupToken = search.get("vaultSetupToken"); - const fundingSource = search.get("fundingSource"); - if (buttonSessionID) { - const params: AppSwitchResumeParams = { - orderID, - buttonSessionID, - payerID, - billingToken, - paymentID, - subscriptionID, - // URLSearchParams get returns as string, - // but below code excepts a value from list of string. - // $FlowIgnore[incompatible-type] - fundingSource, - vaultSetupToken, - // the isPostApprovalAction already ensures - // that the function will exit if url hash is not one of supported values. - // $FlowIgnore[incompatible-type] - checkoutState: urlHash, - }; - return params; - } - return null; + + const { + token, + PayerID, + buttonSessionID, + billingToken, + paymentID, + subscriptionID, + vaultSetupToken, + fundingSource, + } = parseQuery(queryString); + + const params: AppSwitchResumeParams = { + orderID: token, + buttonSessionID, + payerID: PayerID, + billingToken, + paymentID, + subscriptionID, + // URLSearchParams get returns as string, + // but below code excepts a value from list of string. + // $FlowIgnore[incompatible-type] + fundingSource, + vaultSetupToken, + // the isPostApprovalAction already ensures + // that the function will exit if url hash is not one of supported values. + // $FlowIgnore[incompatible-type] + checkoutState: hash, + }; + return params; } export function isAppSwitchResumeFlow(): boolean { diff --git a/src/lib/appSwithResume.test.js b/src/lib/appSwithResume.test.js index 9ec37c8aa..ef23550ff 100644 --- a/src/lib/appSwithResume.test.js +++ b/src/lib/appSwithResume.test.js @@ -26,23 +26,17 @@ describe("app switch resume flow", () => { test("should test fetching resume params when parameters are correctly passed", () => { vi.spyOn(window, "location", "get").mockReturnValue({ - hash: "#onApprove", - search: `buttonSessionID=${buttonSessionID}&orderID=${orderID}&fundingSource=${fundingSource}`, + hash: `#onApprove?buttonSessionID=${buttonSessionID}&token=${orderID}&fundingSource=${fundingSource}`, }); const params = getAppSwitchResumeParams(); expect.assertions(2); expect(params).toEqual({ - billingToken: null, buttonSessionID, checkoutState: "onApprove", fundingSource, orderID, - payerID: null, - paymentID: null, - subscriptionID: null, - vaultSetupToken: null, }); expect(isAppSwitchResumeFlow()).toEqual(true); }); @@ -50,7 +44,7 @@ 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}&orderID=${orderID}&fundingSource=${fundingSource}`, + search: `buttonSessionID=${buttonSessionID}&token=${orderID}&fundingSource=${fundingSource}`, }); const params = getAppSwitchResumeParams(); @@ -62,8 +56,7 @@ describe("app switch resume flow", () => { test("should test null fetching resume params with invalid callback passed", () => { vi.spyOn(window, "location", "get").mockReturnValue({ - hash: "#Unknown", - search: `buttonSessionID=${buttonSessionID}&orderID=${orderID}&fundingSource=${fundingSource}`, + hash: `#Unknown?buttonSessionID=${buttonSessionID}&token=${orderID}&fundingSource=${fundingSource}`, }); const params = getAppSwitchResumeParams(); @@ -73,10 +66,9 @@ describe("app switch resume flow", () => { expect(isAppSwitchResumeFlow()).toEqual(false); }); - test("should test fetching resume params when parameters are correctly passed", () => { + test("should test fetching multiple resume params when parameters are correctly passed", () => { vi.spyOn(window, "location", "get").mockReturnValue({ - hash: "#onApprove", - search: `buttonSessionID=${buttonSessionID}&orderID=${orderID}&fundingSource=${fundingSource}&billingToken=BA-124&payerID=PP-122&paymentID=PAY-123&subscriptionID=I-1234&vaultSetupToken=VA-3`, + hash: `#onApprove?buttonSessionID=${buttonSessionID}&token=${orderID}&fundingSource=${fundingSource}&billingToken=BA-124&PayerID=PP-payer-122&paymentID=PAY-123&subscriptionID=I-1234&vaultSetupToken=VA-3`, }); const params = getAppSwitchResumeParams(); @@ -88,7 +80,7 @@ describe("app switch resume flow", () => { checkoutState: "onApprove", fundingSource, orderID, - payerID: "PP-122", + payerID: "PP-payer-122", paymentID: "PAY-123", subscriptionID: "I-1234", vaultSetupToken: "VA-3",