Skip to content

Commit

Permalink
fix: added Fixes for one click widgets
Browse files Browse the repository at this point in the history
  • Loading branch information
ArushKapoorJuspay committed May 27, 2024
1 parent f085bfb commit 7a19970
Show file tree
Hide file tree
Showing 12 changed files with 158 additions and 117 deletions.
2 changes: 1 addition & 1 deletion src/CardUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ let getCardBrandIcon = (cardType, paymentType) => {
| GooglePayElement
| PayPalElement
| ApplePayElement
| PaymentRequestButtonsElement
| ExpressCheckoutElement
| NONE =>
<Icon size=brandIconSize name="default-card" />
}
Expand Down
2 changes: 1 addition & 1 deletion src/LoaderController.res
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ let make = (~children, ~paymentMode, ~setIntegrateErrorError, ~logger, ~initTime
| GooglePayElement
| PayPalElement
| ApplePayElement
| PaymentRequestButtonsElement
| ExpressCheckoutElement
| Payment => {
let paymentOptions = PaymentType.itemToObjMapper(optionsDict, logger)
setOptionsPayment(_ => paymentOptions)
Expand Down
11 changes: 10 additions & 1 deletion src/Payments/ApplePay.res
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ open Utils
open Promise
@react.component
let make = (~sessionObj: option<JSON.t>) => {
let url = RescriptReactRouter.useUrl()
let componentName = CardUtils.getQueryParamsDictforKey(url.search, "componentName")
let loggerState = Recoil.useRecoilValueFromAtom(RecoilAtoms.loggerAtom)
let {publishableKey, sdkHandleOneClickConfirmPayment} = Recoil.useRecoilValueFromAtom(
RecoilAtoms.keys,
Expand Down Expand Up @@ -242,7 +244,14 @@ let make = (~sessionObj: option<JSON.t>) => {
let bodyDict = PaymentBody.applePayThirdPartySdkBody(~connectors)
processPayment(bodyDict, ~isThirdPartyFlow=true, ())
} else {
let message = [("applePayButtonClicked", true->JSON.Encode.bool)]
let paymentRequest = ApplePayTypes.getPaymentRequestFromSession(
~sessionObj,
~componentName,
)
let message = [
("applePayButtonClicked", true->JSON.Encode.bool),
("applePayPaymentRequest", paymentRequest),
]
handlePostMessage(message)
}
} else {
Expand Down
10 changes: 9 additions & 1 deletion src/Payments/GPay.res
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ open Promise

@react.component
let make = (~sessionObj: option<SessionsType.token>, ~thirdPartySessionObj: option<JSON.t>) => {
let url = RescriptReactRouter.useUrl()
let componentName = CardUtils.getQueryParamsDictforKey(url.search, "componentName")
let loggerState = Recoil.useRecoilValueFromAtom(loggerAtom)
let {iframeId} = Recoil.useRecoilValueFromAtom(keys)
let {publishableKey, sdkHandleOneClickConfirmPayment} = Recoil.useRecoilValueFromAtom(keys)
Expand Down Expand Up @@ -183,12 +185,18 @@ let make = (~sessionObj: option<SessionsType.token>, ~thirdPartySessionObj: opti
let bodyDict = PaymentBody.gPayThirdPartySdkBody(~connectors)
processPayment(bodyDict, ~isThirdPartyFlow=true, ())
} else {
let paymentDataRequest = getPaymentDataFromSession(~sessionObj, ~componentName)
handlePostMessage([
("fullscreen", true->JSON.Encode.bool),
("param", "paymentloader"->JSON.Encode.string),
("iframeId", iframeId->JSON.Encode.string),
])
options.readOnly ? () : handlePostMessage([("GpayClicked", true->JSON.Encode.bool)])
if !options.readOnly {
handlePostMessage([
("GpayClicked", true->JSON.Encode.bool),
("GpayPaymentDataRequest", paymentDataRequest->Identity.anyTypeToJson),
])
}
}
} else {
let bodyDict = PaymentBody.gpayRedirectBody(~connectors)
Expand Down
2 changes: 1 addition & 1 deletion src/RenderPaymentMethods.res
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ let make = (
| GooglePayElement
| PayPalElement
| ApplePayElement
| PaymentRequestButtonsElement
| ExpressCheckoutElement
| Payment =>
<React.Suspense
fallback={<RenderIf condition={showLoader}>
Expand Down
106 changes: 71 additions & 35 deletions src/Types/ApplePayTypes.res
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
open Utils

type token = {paymentData: JSON.t}
type billingContact = {
addressLines: array<string>,
Expand Down Expand Up @@ -65,68 +67,102 @@ type paymentRequestData = {

let jsonToPaymentRequestDataType: Dict.t<JSON.t> => paymentRequestData = jsonDict => {
let clientTimeZone = CardUtils.dateTimeFormat().resolvedOptions().timeZone
let clientCountry = Utils.getClientCountry(clientTimeZone)
let clientCountry = getClientCountry(clientTimeZone)
let defaultCountryCode = clientCountry.isoAlpha2

let getTotal = totalDict => {
Utils.getString(totalDict, "type", "") == ""
getString(totalDict, "type", "") == ""
? total(
~label=Utils.getString(totalDict, "label", ""),
~amount=Utils.getString(totalDict, "amount", ""),
~label=getString(totalDict, "label", ""),
~amount=getString(totalDict, "amount", ""),
(),
)
: total(
~label=Utils.getString(totalDict, "label", ""),
~amount=Utils.getString(totalDict, "amount", ""),
~\"type"=Utils.getString(totalDict, "type", ""),
~label=getString(totalDict, "label", ""),
~amount=getString(totalDict, "amount", ""),
~\"type"=getString(totalDict, "type", ""),
(),
)
}

if Utils.getString(jsonDict, "merchant_identifier", "") == "" {
if getString(jsonDict, "merchant_identifier", "") == "" {
paymentRequestData(
~countryCode=Utils.getString(jsonDict, "country_code", defaultCountryCode),
~currencyCode=Utils.getString(jsonDict, "currency_code", ""),
~merchantCapabilities=Utils.getStrArray(jsonDict, "merchant_capabilities"),
~supportedNetworks=Utils.getStrArray(jsonDict, "supported_networks"),
~total=getTotal(jsonDict->Utils.getDictFromObj("total")),
~countryCode=getString(jsonDict, "country_code", defaultCountryCode),
~currencyCode=getString(jsonDict, "currency_code", ""),
~merchantCapabilities=getStrArray(jsonDict, "merchant_capabilities"),
~supportedNetworks=getStrArray(jsonDict, "supported_networks"),
~total=getTotal(jsonDict->getDictFromObj("total")),
(),
)
} else {
paymentRequestData(
~countryCode=Utils.getString(jsonDict, "country_code", ""),
~currencyCode=Utils.getString(jsonDict, "currency_code", ""),
~merchantCapabilities=Utils.getStrArray(jsonDict, "merchant_capabilities"),
~supportedNetworks=Utils.getStrArray(jsonDict, "supported_networks"),
~total=getTotal(jsonDict->Utils.getDictFromObj("total")),
~merchantIdentifier=Utils.getString(jsonDict, "merchant_identifier", ""),
~countryCode=getString(jsonDict, "country_code", ""),
~currencyCode=getString(jsonDict, "currency_code", ""),
~merchantCapabilities=getStrArray(jsonDict, "merchant_capabilities"),
~supportedNetworks=getStrArray(jsonDict, "supported_networks"),
~total=getTotal(jsonDict->getDictFromObj("total")),
~merchantIdentifier=getString(jsonDict, "merchant_identifier", ""),
(),
)
}
}

let billingContactItemToObjMapper = dict => {
{
addressLines: dict->Utils.getStrArray("addressLines"),
administrativeArea: dict->Utils.getString("administrativeArea", ""),
countryCode: dict->Utils.getString("countryCode", ""),
familyName: dict->Utils.getString("familyName", ""),
givenName: dict->Utils.getString("givenName", ""),
locality: dict->Utils.getString("locality", ""),
postalCode: dict->Utils.getString("postalCode", ""),
addressLines: dict->getStrArray("addressLines"),
administrativeArea: dict->getString("administrativeArea", ""),
countryCode: dict->getString("countryCode", ""),
familyName: dict->getString("familyName", ""),
givenName: dict->getString("givenName", ""),
locality: dict->getString("locality", ""),
postalCode: dict->getString("postalCode", ""),
}
}

let shippingContactItemToObjMapper = dict => {
{
emailAddress: dict->Utils.getString("emailAddress", ""),
phoneNumber: dict->Utils.getString("phoneNumber", ""),
addressLines: dict->Utils.getStrArray("addressLines"),
administrativeArea: dict->Utils.getString("administrativeArea", ""),
countryCode: dict->Utils.getString("countryCode", ""),
familyName: dict->Utils.getString("familyName", ""),
givenName: dict->Utils.getString("givenName", ""),
locality: dict->Utils.getString("locality", ""),
postalCode: dict->Utils.getString("postalCode", ""),
emailAddress: dict->getString("emailAddress", ""),
phoneNumber: dict->getString("phoneNumber", ""),
addressLines: dict->getStrArray("addressLines"),
administrativeArea: dict->getString("administrativeArea", ""),
countryCode: dict->getString("countryCode", ""),
familyName: dict->getString("familyName", ""),
givenName: dict->getString("givenName", ""),
locality: dict->getString("locality", ""),
postalCode: dict->getString("postalCode", ""),
}
}

let getPaymentRequestFromSession = (~sessionObj, ~componentName) => {
let paymentRequest =
sessionObj
->Option.flatMap(JSON.Decode.object)
->Option.getOr(Dict.make())
->Dict.get("payment_request_data")
->Option.getOr(Dict.make()->JSON.Encode.object)
->transformKeys(CamelCase)

let requiredShippingContactFields =
paymentRequest
->getDictFromJson
->getStrArray("requiredShippingContactFields")

if (
componentName->getIsExpressCheckoutComponent->not &&
requiredShippingContactFields->Array.length !== 0
) {
let shippingFieldsWithoutPostalAddress =
requiredShippingContactFields->Array.filter(item => item !== "postalAddress")

paymentRequest
->getDictFromJson
->Dict.set(
"requiredShippingContactFields",
shippingFieldsWithoutPostalAddress
->getArrofJsonString
->JSON.Encode.array,
)
}

paymentRequest
}
6 changes: 3 additions & 3 deletions src/Types/CardThemeType.res
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type mode =
| GooglePayElement
| PayPalElement
| ApplePayElement
| PaymentRequestButtonsElement
| ExpressCheckoutElement
| NONE
type label = Above | Floating | Never
type themeClass = {
Expand Down Expand Up @@ -98,7 +98,7 @@ let getPaymentMode = val => {
| "googlePay" => GooglePayElement
| "payPal" => PayPalElement
| "applePay" => ApplePayElement
| "paymentRequestButtons" => PaymentRequestButtonsElement
| "expressCheckout" => ExpressCheckoutElement
| _ => NONE
}
}
Expand All @@ -113,7 +113,7 @@ let getPaymentModeToStrMapper = val => {
| GooglePayElement => "GooglePayElement"
| PayPalElement => "PayPalElement"
| ApplePayElement => "ApplePayElement"
| PaymentRequestButtonsElement => "PaymentRequestButtonsElement"
| ExpressCheckoutElement => "ExpressCheckoutElement"
| NONE => "None"
}
}
28 changes: 28 additions & 0 deletions src/Types/GooglePayType.res
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,31 @@ let billingContactItemToObjMapper = dict => {
sortingCode: dict->getString("sortingCode", ""),
}
}

let baseRequest = {
"apiVersion": 2,
"apiVersionMinor": 0,
}

let getPaymentDataFromSession = (~sessionObj, ~componentName) => {
let gpayobj = switch sessionObj {
| Some(val) => val
| _ => SessionsType.defaultToken
}
let paymentDataRequest = assign2(
Dict.make()->JSON.Encode.object,
baseRequest->Identity.anyTypeToJson,
)
paymentDataRequest.allowedPaymentMethods = gpayobj.allowed_payment_methods->arrayJsonToCamelCase
paymentDataRequest.transactionInfo = gpayobj.transaction_info->transformKeys(CamelCase)
paymentDataRequest.merchantInfo = gpayobj.merchant_info->transformKeys(CamelCase)
paymentDataRequest.emailRequired = gpayobj.emailRequired

if componentName->getIsExpressCheckoutComponent {
paymentDataRequest.shippingAddressRequired = gpayobj.shippingAddressRequired
paymentDataRequest.shippingAddressParameters =
gpayobj.shippingAddressParameters->transformKeys(CamelCase)
}

paymentDataRequest
}
4 changes: 2 additions & 2 deletions src/Utilities/Utils.res
Original file line number Diff line number Diff line change
Expand Up @@ -1230,7 +1230,7 @@ let getWalletPaymentMethod = (wallets, paymentType: CardThemeType.mode) => {
}
}

let expressCheckoutComponents = ["googlePay", "payPal", "applePay", "paymentRequestButtons"]
let expressCheckoutComponents = ["googlePay", "payPal", "applePay", "expressCheckout"]

let componentsForPaymentElementCreate = ["payment"]->Array.concat(expressCheckoutComponents)

Expand All @@ -1246,7 +1246,7 @@ let walletElementPaymentType: array<CardThemeType.mode> = [
GooglePayElement,
PayPalElement,
ApplePayElement,
PaymentRequestButtonsElement,
ExpressCheckoutElement,
]

let getIsWalletElementPaymentType = (paymentType: CardThemeType.mode) => {
Expand Down
6 changes: 5 additions & 1 deletion src/Window.res
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,17 @@ external style: Dom.element => style = "style"
@send external paymentRequest: (JSON.t, JSON.t, JSON.t) => JSON.t = "PaymentRequest"
@send external click: Dom.element => unit = "click"

let sendPostMessage = (element, message) => {
element->postMessage(message->JSON.Encode.object->JSON.stringify, GlobalVars.targetOrigin)
}

let iframePostMessage = (iframeRef: nullable<Dom.element>, message) => {
switch iframeRef->Nullable.toOption {
| Some(ref) =>
try {
ref
->contentWindow
->postMessage(message->JSON.Encode.object->JSON.stringify, GlobalVars.targetOrigin)
->sendPostMessage(message)
} catch {
| _ => ()
}
Expand Down
Loading

0 comments on commit 7a19970

Please sign in to comment.