Skip to content

Commit

Permalink
feat: express checkout for paze (#779)
Browse files Browse the repository at this point in the history
  • Loading branch information
PritishBudhiraja authored Nov 12, 2024
1 parent f12ce20 commit f5dd999
Show file tree
Hide file tree
Showing 11 changed files with 84 additions and 43 deletions.
1 change: 1 addition & 0 deletions src/CardUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ let getCardBrandIcon = (cardType, paymentType) => {
| KlarnaElement
| ExpressCheckoutElement
| PaymentMethodsManagement
| PazeElement
| NONE =>
<Icon size=brandIconSize name="default-card" />
}
Expand Down
1 change: 1 addition & 0 deletions src/LoaderController.res
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime
| PayPalElement
| ApplePayElement
| KlarnaElement
| PazeElement
| ExpressCheckoutElement
| Payment => {
let paymentOptions = PaymentType.itemToObjMapper(optionsDict, logger)
Expand Down
23 changes: 13 additions & 10 deletions src/Payments/PaymentRequestButtonElement.res
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ let make = (~sessions, ~walletOptions, ~paymentType) => {
let pazeTokenObj = getPaymentSessionObj(sessionObj.sessionsToken, Paze)

let {clientSecret} = Recoil.useRecoilValueFromAtom(RecoilAtoms.keys)
let options = Recoil.useRecoilValueFromAtom(RecoilAtoms.optionAtom)
let isPaypalSDKFlow = paypalPaymentMethodExperience->Array.includes(InvokeSDK)
let isPaypalRedirectFlow = paypalPaymentMethodExperience->Array.includes(RedirectToURL)

Expand Down Expand Up @@ -140,16 +141,18 @@ let make = (~sessions, ~walletOptions, ~paymentType) => {
</SessionPaymentWrapper>

| PazeWallet =>
<SessionPaymentWrapper type_={Wallet}>
{switch pazeTokenObj {
| OtherTokenOptional(optToken) =>
switch optToken {
| Some(token) => <PazeButton token />
| None => React.null
}
| _ => React.null
}}
</SessionPaymentWrapper>
<RenderIf condition={options.wallets.paze === Auto}>
<SessionPaymentWrapper type_={Wallet}>
{switch pazeTokenObj {
| OtherTokenOptional(optToken) =>
switch optToken {
| Some(token) => <PazeButton token />
| None => React.null
}
| _ => React.null
}}
</SessionPaymentWrapper>
</RenderIf>
| NONE => React.null
}
| None => React.null
Expand Down
5 changes: 5 additions & 0 deletions src/Payments/PazeButton.res
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
let make = (~token: SessionsType.token) => {
open Utils
open RecoilAtoms

let url = RescriptReactRouter.useUrl()
let componentName = CardUtils.getQueryParamsDictforKey(url.search, "componentName")

let {iframeId, publishableKey, clientSecret} = Recoil.useRecoilValueFromAtom(keys)
let {themeObj} = Recoil.useRecoilValueFromAtom(configAtom)
let options = Recoil.useRecoilValueFromAtom(optionAtom)
Expand All @@ -15,6 +19,7 @@ let make = (~token: SessionsType.token) => {
setShowLoader(_ => true)
let metadata =
[
("componentName", componentName->JSON.Encode.string),
("wallet", (token.walletName :> string)->JSON.Encode.string),
("clientId", token.clientId->JSON.Encode.string),
("clientName", token.clientName->JSON.Encode.string),
Expand Down
3 changes: 3 additions & 0 deletions src/Payments/PazeWallet.res
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ let make = () => {
let emailAddress = metaData->getString("emailAddress", "")
let transactionAmount = metaData->getString("transactionAmount", "")
let transactionCurrencyCode = metaData->getString("transactionCurrencyCode", "")
let componentName = metaData->getString("componentName", "")

let mountPazeSDK = () => {
let pazeScriptURL =
Expand Down Expand Up @@ -84,6 +85,7 @@ let make = () => {
messageParentWindow([
("fullscreen", false->JSON.Encode.bool),
("isPaze", true->JSON.Encode.bool),
("componentName", componentName->JSON.Encode.string),
(
"completeResponse",
completeResponse
Expand All @@ -100,6 +102,7 @@ let make = () => {
("fullscreen", false->JSON.Encode.bool),
("isPaze", true->JSON.Encode.bool),
("flowExited", "stop"->JSON.Encode.string),
("componentName", componentName->JSON.Encode.string),
])
resolve()
}
Expand Down
1 change: 1 addition & 0 deletions src/RenderPaymentMethods.res
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ let make = (
| PayPalElement
| ApplePayElement
| KlarnaElement
| PazeElement
| ExpressCheckoutElement
| Payment =>
<ReusableReactSuspense
Expand Down
18 changes: 0 additions & 18 deletions src/Types/ApplePayTypes.res
Original file line number Diff line number Diff line change
Expand Up @@ -185,21 +185,3 @@ let getPaymentRequestFromSession = (~sessionObj, ~componentName) => {

paymentRequest
}

let handleApplePayIframePostMessage = (msg, componentName, mountedIframeRef) => {
let isApplePayMessageSent = ref(false)

let iframes = Window.querySelectorAll("iframe")

iframes->Array.forEach(iframe => {
let iframeSrc = iframe->Window.getAttribute("src")->Option.getOr("")
if iframeSrc->String.includes(`componentName=${componentName}`) {
iframe->Js.Nullable.return->Window.iframePostMessage(msg)
isApplePayMessageSent := true
}
})

if !isApplePayMessageSent.contents {
mountedIframeRef->Window.iframePostMessage(msg)
}
}
4 changes: 3 additions & 1 deletion src/Types/CardThemeType.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
type theme = Default | Brutal | Midnight | Soft | Charcoal| Bubblegum | NONE
type theme = Default | Brutal | Midnight | Soft | Charcoal | Bubblegum | NONE

type innerLayout = Spaced | Compressed

Expand All @@ -15,6 +15,7 @@ type mode =
| PayPalElement
| ApplePayElement
| KlarnaElement
| PazeElement
| ExpressCheckoutElement
| PaymentMethodsManagement
| NONE
Expand Down Expand Up @@ -105,6 +106,7 @@ let getPaymentMode = val => {
| "paymentMethodCollect" => PaymentMethodCollectElement
| "klarna" => KlarnaElement
| "expressCheckout" => ExpressCheckoutElement
| "paze" => PazeElement
| "paymentMethodsManagement" => PaymentMethodsManagement
| _ => NONE
}
Expand Down
6 changes: 6 additions & 0 deletions src/Types/PaymentType.res
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ type wallets = {
googlePay: showType,
payPal: showType,
klarna: showType,
paze: showType,
style: style,
}
type business = {name: string}
Expand Down Expand Up @@ -283,6 +284,7 @@ let defaultWallets = {
googlePay: Auto,
payPal: Auto,
klarna: Auto,
paze: Auto,
style: defaultStyle,
}
let defaultBillingAddress = {
Expand Down Expand Up @@ -830,6 +832,10 @@ let getWallets = (dict, str, logger) => {
"options.wallets.klarna",
logger,
),
paze: getWarningString(json, "paze", "auto", ~logger)->getShowType(
"options.wallets.paze",
logger,
),
style: getStyle(json, "style", logger),
}
})
Expand Down
40 changes: 39 additions & 1 deletion src/Utilities/Utils.res
Original file line number Diff line number Diff line change
Expand Up @@ -1284,11 +1284,19 @@ let getWalletPaymentMethod = (wallets, paymentType: CardThemeType.mode) => {
| PayPalElement => wallets->Array.filter(item => item === "paypal")
| ApplePayElement => wallets->Array.filter(item => item === "apple_pay")
| KlarnaElement => wallets->Array.filter(item => item === "klarna")
| PazeElement => wallets->Array.filter(item => item === "paze")
| _ => wallets
}
}

let expressCheckoutComponents = ["googlePay", "payPal", "applePay", "klarna", "expressCheckout"]
let expressCheckoutComponents = [
"googlePay",
"payPal",
"applePay",
"klarna",
"paze",
"expressCheckout",
]

let spmComponents = ["paymentMethodCollect"]->Array.concat(expressCheckoutComponents)

Expand All @@ -1310,6 +1318,7 @@ let walletElementPaymentType: array<CardThemeType.mode> = [
PayPalElement,
ApplePayElement,
KlarnaElement,
PazeElement,
ExpressCheckoutElement,
]

Expand Down Expand Up @@ -1425,3 +1434,32 @@ let mergeAndFlattenToTuples = (body, requiredFieldsBody) =>
->flattenObject(true)
->mergeTwoFlattenedJsonDicts(requiredFieldsBody)
->getArrayOfTupleFromDict

let sendMessageToIframe = (~msg, ~componentName, ~eventSource=None, ~mountedIframeRef=None) => {
let isMessageSent = ref(false)
let iframes = Window.querySelectorAll("iframe")

iframes->Array.forEach(iframe => {
let iframeSrc = iframe->Window.getAttribute("src")->Option.getOr("")
if iframeSrc->String.includes(`componentName=${componentName}`) {
iframe->Js.Nullable.return->Window.iframePostMessage(msg)
isMessageSent := true
}
})

if !isMessageSent.contents {
switch (eventSource, mountedIframeRef) {
| (Some(source), _) => source->Window.sendPostMessage(msg)
| (None, Some(ref)) => ref->Window.iframePostMessage(msg)
| (None, None) => ()
}
}
}

let handleApplePayIframePostMessage = (msg, componentName, mountedIframeRef) => {
sendMessageToIframe(~msg, ~componentName, ~mountedIframeRef=Some(mountedIframeRef))
}

let handlePazeIframePostMessage = (msg, componentName, eventSource) => {
sendMessageToIframe(~msg, ~componentName, ~eventSource=Some(eventSource))
}
25 changes: 12 additions & 13 deletions src/hyper-loader/Elements.res
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ open ErrorUtils
open Identity
open Utils
open EventListenerManager
open ApplePayTypes

type trustPayFunctions = {
finishApplePaymentV2: (string, paymentRequestData) => promise<JSON.t>,
finishApplePaymentV2: (string, ApplePayTypes.paymentRequestData) => promise<JSON.t>,
executeGooglePayment: (string, GooglePayType.paymentDataRequest) => promise<JSON.t>,
}
@new external trustPayApi: JSON.t => trustPayFunctions = "TrustPayApi"
Expand Down Expand Up @@ -130,14 +129,13 @@ let make = (
}
}

let onPazeCallback = mountedIframeRef => {
(ev: Types.event) => {
let json = ev.data->Identity.anyTypeToJson
let dict = json->getDictFromJson
let isPazeExist = dict->getBool("isPaze", false)
if isPazeExist {
mountedIframeRef->Window.iframePostMessage([("data", json)]->Dict.fromArray)
}
let onPazeCallback = (event: Types.event) => {
let json = event.data->Identity.anyTypeToJson
let dict = json->getDictFromJson
if dict->getBool("isPaze", false) {
let componentName = dict->getString("componentName", "payment")
let msg = [("data", json)]->Dict.fromArray
handlePazeIframePostMessage(msg, componentName, event.source)
}
}

Expand All @@ -150,7 +148,7 @@ let make = (
isTaxCalculationEnabled.contents =
dict->getDictFromDict("response")->getBool("is_tax_calculation_enabled", false)
addSmartEventListener("message", onPlaidCallback(mountedIframeRef), "onPlaidCallback")
addSmartEventListener("message", onPazeCallback(mountedIframeRef), "onPazeCallback")
addSmartEventListener("message", onPazeCallback, "onPazeCallback")

let json = dict->getJsonFromDict("response", JSON.Encode.null)
let isApplePayPresent = PaymentMethodsRecord.getPaymentMethodTypeFromList(
Expand Down Expand Up @@ -292,6 +290,7 @@ let make = (
| "applePay"
| "klarna"
| "expressCheckout"
| "paze"
| "paymentMethodsManagement"
| "payment" => ()
| str => manageErrorWarning(UNKNOWN_KEY, ~dynamicStr=`${str} type in create`, ~logger)
Expand Down Expand Up @@ -355,7 +354,7 @@ let make = (

if dict->Dict.get("applePayMounted")->Option.isSome {
if wallets.applePay === Auto {
switch sessionForApplePay->Nullable.toOption {
switch ApplePayTypes.sessionForApplePay->Nullable.toOption {
| Some(session) =>
try {
if session.canMakePayments() {
Expand Down Expand Up @@ -943,7 +942,7 @@ let make = (
intermediatePaymentData
->getDictFromJson
->getDictFromDict("shippingAddress")
->billingContactItemToObjMapper
->ApplePayTypes.billingContactItemToObjMapper
let newShippingAddress =
[
("state", shippingAddress.administrativeArea->JSON.Encode.string),
Expand Down

0 comments on commit f5dd999

Please sign in to comment.