Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: express checkout for paze #779

Merged
merged 9 commits into from
Nov 12, 2024
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
Loading