{
~iframeId,
(),
)
- ()
} else {
postFailedSubmitResponse(~errortype="validation_error", ~message="Please enter all fields")
}
diff --git a/src/Payments/CardPayment.res b/src/Payments/CardPayment.res
index 915df0735..6f3cfe39a 100644
--- a/src/Payments/CardPayment.res
+++ b/src/Payments/CardPayment.res
@@ -355,7 +355,7 @@ let make = (
CardUtils.getCardType} />
-
+
{switch (
paymentMethodListValue.mandate_payment,
options.terms.card,
diff --git a/src/Payments/PaypalSDK.res b/src/Payments/PaypalSDK.res
index 1b72dd12e..bb58dd951 100644
--- a/src/Payments/PaypalSDK.res
+++ b/src/Payments/PaypalSDK.res
@@ -1,5 +1,4 @@
open PaypalSDKTypes
-open Promise
@react.component
let make = (~sessionObj: SessionsType.token, ~paymentType: CardThemeType.mode) => {
@@ -13,6 +12,7 @@ let make = (~sessionObj: SessionsType.token, ~paymentType: CardThemeType.mode) =
let token = sessionObj.token
let orderDetails = sessionObj.orderDetails->getOrderDetails(paymentType)
let intent = PaymentHelpers.usePaymentIntent(Some(loggerState), Paypal)
+ let completeAuthorize = PaymentHelpers.useCompleteAuthorize(Some(loggerState), Paypal)
let checkoutScript =
Window.document(Window.window)->Window.getElementById("braintree-checkout")->Nullable.toOption
let clientScript =
@@ -51,123 +51,70 @@ let make = (~sessionObj: SessionsType.token, ~paymentType: CardThemeType.mode) =
PaymentUtils.useStatesJson(setStatesJson)
- let loadPaypalSdk = () => {
- loggerState.setLogInfo(
- ~value="Paypal SDK Button Clicked",
- ~eventName=PAYPAL_SDK_FLOW,
- ~paymentMethod="PAYPAL",
- (),
- )
- Utils.makeOneClickHandlerPromise(sdkHandleOneClickConfirmPayment)
- ->then(result => {
- let result = result->JSON.Decode.bool->Option.getOr(false)
- if result {
- braintree.client.create({authorization: token}, (clientErr, clientInstance) => {
- if clientErr {
- Console.error2("Error creating client", clientErr)
- }
- braintree.paypalCheckout.create(
- {client: clientInstance},
- (paypalCheckoutErr, paypalCheckoutInstance) => {
- switch paypalCheckoutErr->Nullable.toOption {
- | Some(val) => Console.warn(`INTEGRATION ERROR: ${val.message}`)
- | None => ()
- }
- paypalCheckoutInstance.loadPayPalSDK(
- {vault: true},
- () => {
- let paypalWrapper = GooglePayType.getElementById(Utils.document, "paypal-button")
- paypalWrapper.innerHTML = ""
- paypal["Buttons"]({
- style: buttonStyle,
- fundingSource: paypal["FUNDING"]["PAYPAL"],
- createBillingAgreement: () => {
- //Paypal Clicked
- Utils.handlePostMessage([
- ("fullscreen", true->JSON.Encode.bool),
- ("param", "paymentloader"->JSON.Encode.string),
- ("iframeId", iframeId->JSON.Encode.string),
- ])
- options.readOnly ? () : paypalCheckoutInstance.createPayment(orderDetails)
- },
- onApprove: (data, _actions) => {
- options.readOnly
- ? ()
- : paypalCheckoutInstance.tokenizePayment(
- data,
- (_err, payload) => {
- let (connectors, _) =
- paymentMethodListValue->PaymentUtils.getConnectors(
- Wallets(Paypal(SDK)),
- )
- let body = PaymentBody.paypalSdkBody(
- ~token=payload.nonce,
- ~connectors,
- )
-
- let requiredFieldsBody = DynamicFieldsUtils.getPaypalRequiredFields(
- ~details=payload.details,
- ~paymentMethodTypes,
- ~statesList=stateJson,
- )
-
- let paypalBody =
- body
- ->Utils.getJsonFromArrayOfJson
- ->Utils.flattenObject(true)
- ->Utils.mergeTwoFlattenedJsonDicts(requiredFieldsBody)
- ->Utils.getArrayOfTupleFromDict
-
- let modifiedPaymentBody = PaymentUtils.appendedCustomerAcceptance(
- ~isGuestCustomer,
- ~paymentType=paymentMethodListValue.payment_type,
- ~body=paypalBody,
- )
-
- intent(
- ~bodyArr=modifiedPaymentBody,
- ~confirmParam={
- return_url: options.wallets.walletReturnUrl,
- publishableKey,
- },
- ~handleUserError=true,
- (),
- )
- },
- )
- },
- onCancel: _data => {
- handleCloseLoader()
- },
- onError: _err => {
- handleCloseLoader()
- },
- }).render("#paypal-button")
- areOneClickWalletsRendered(
- prev => {
- ...prev,
- isPaypal: true,
- },
- )
- },
- )
- },
- )
- })->ignore
- }
- resolve()
+ let mountPaypalSDK = () => {
+ let clientId = sessionObj.token
+ let paypalScriptURL = `https://www.paypal.com/sdk/js?client-id=${clientId}&components=buttons,hosted-fields`
+ loggerState.setLogInfo(~value="PayPal SDK Script Loading", ~eventName=PAYPAL_SDK_FLOW, ())
+ let paypalScript = Window.createElement("script")
+ paypalScript->Window.elementSrc(paypalScriptURL)
+ paypalScript->Window.elementOnerror(exn => {
+ let err = exn->Identity.anyTypeToJson->JSON.stringify
+ loggerState.setLogError(
+ ~value=`Error During Loading PayPal SDK Script: ${err}`,
+ ~eventName=PAYPAL_SDK_FLOW,
+ (),
+ )
+ })
+ paypalScript->Window.elementOnload(_ => {
+ loggerState.setLogInfo(~value="PayPal SDK Script Loaded", ~eventName=PAYPAL_SDK_FLOW, ())
+ PaypalSDKHelpers.loadPaypalSDK(
+ ~loggerState,
+ ~sdkHandleOneClickConfirmPayment,
+ ~buttonStyle,
+ ~iframeId,
+ ~paymentMethodListValue,
+ ~isGuestCustomer,
+ ~intent,
+ ~options,
+ ~publishableKey,
+ ~paymentMethodTypes,
+ ~stateJson,
+ ~completeAuthorize,
+ ~handleCloseLoader,
+ ~areOneClickWalletsRendered,
+ )
})
- ->ignore
+ Window.body->Window.appendChild(paypalScript)
}
+
React.useEffect(() => {
try {
- switch (
- checkoutScript,
- clientScript,
- stateJson->Identity.jsonToNullableJson->Js.Nullable.isNullable,
- ) {
- | (Some(_), Some(_), false) => loadPaypalSdk()
- | (_, _, _) => Utils.logInfo(Console.log("Error loading Paypal"))
+ if stateJson->Identity.jsonToNullableJson->Js.Nullable.isNullable->not {
+ switch sessionObj.connector {
+ | "paypal" => mountPaypalSDK()
+ | _ =>
+ switch (checkoutScript, clientScript) {
+ | (Some(_), Some(_)) =>
+ PaypalSDKHelpers.loadBraintreePaypalSdk(
+ ~loggerState,
+ ~sdkHandleOneClickConfirmPayment,
+ ~token,
+ ~buttonStyle,
+ ~iframeId,
+ ~paymentMethodListValue,
+ ~isGuestCustomer,
+ ~intent,
+ ~options,
+ ~orderDetails,
+ ~publishableKey,
+ ~paymentMethodTypes,
+ ~stateJson,
+ ~handleCloseLoader,
+ ~areOneClickWalletsRendered,
+ )
+ | _ => ()
+ }
+ }
}
} catch {
| _err => Utils.logInfo(Console.log("Error loading Paypal"))
diff --git a/src/Payments/PaypalSDKHelpers.res b/src/Payments/PaypalSDKHelpers.res
new file mode 100644
index 000000000..aa7abe4e8
--- /dev/null
+++ b/src/Payments/PaypalSDKHelpers.res
@@ -0,0 +1,243 @@
+open PaypalSDKTypes
+open Promise
+
+let loadPaypalSDK = (
+ ~loggerState: OrcaLogger.loggerMake,
+ ~sdkHandleOneClickConfirmPayment,
+ ~buttonStyle,
+ ~iframeId,
+ ~paymentMethodListValue,
+ ~isGuestCustomer,
+ ~intent: PaymentHelpers.paymentIntent,
+ ~options: PaymentType.options,
+ ~publishableKey,
+ ~paymentMethodTypes,
+ ~stateJson,
+ ~completeAuthorize: PaymentHelpers.completeAuthorize,
+ ~handleCloseLoader,
+ ~areOneClickWalletsRendered: (
+ RecoilAtoms.areOneClickWalletsRendered => RecoilAtoms.areOneClickWalletsRendered
+ ) => unit,
+) => {
+ loggerState.setLogInfo(
+ ~value="Paypal SDK Button Clicked",
+ ~eventName=PAYPAL_SDK_FLOW,
+ ~paymentMethod="PAYPAL",
+ (),
+ )
+ Utils.makeOneClickHandlerPromise(sdkHandleOneClickConfirmPayment)
+ ->then(result => {
+ let result = result->JSON.Decode.bool->Option.getOr(false)
+ if result {
+ let paypalWrapper = GooglePayType.getElementById(Utils.document, "paypal-button")
+ paypalWrapper.innerHTML = ""
+ paypal["Buttons"]({
+ style: buttonStyle,
+ fundingSource: paypal["FUNDING"]["PAYPAL"],
+ createOrder: () => {
+ Utils.handlePostMessage([
+ ("fullscreen", true->JSON.Encode.bool),
+ ("param", "paymentloader"->JSON.Encode.string),
+ ("iframeId", iframeId->JSON.Encode.string),
+ ])
+ let (connectors, _) =
+ paymentMethodListValue->PaymentUtils.getConnectors(Wallets(Paypal(SDK)))
+ let body = PaymentBody.paypalSdkBody(~token="", ~connectors)
+ let modifiedPaymentBody = PaymentUtils.appendedCustomerAcceptance(
+ ~isGuestCustomer,
+ ~paymentType=paymentMethodListValue.payment_type,
+ ~body,
+ )
+ Promise.make((resolve, _) => {
+ intent(
+ ~bodyArr=modifiedPaymentBody,
+ ~confirmParam={
+ return_url: options.wallets.walletReturnUrl,
+ publishableKey,
+ },
+ ~handleUserError=true,
+ ~intentCallback=val =>
+ val->Utils.getDictFromJson->Utils.getString("orderId", "")->resolve,
+ (),
+ )
+ })
+ },
+ onApprove: (_data, actions) => {
+ if !options.readOnly {
+ actions.order.get()
+ ->then(val => {
+ let purchaseUnit =
+ val
+ ->Utils.getDictFromJson
+ ->Utils.getArray("purchase_units")
+ ->Array.get(0)
+ ->Option.flatMap(JSON.Decode.object)
+ ->Option.getOr(Dict.make())
+ let details = purchaseUnit->paypalShippingDetails
+ let requiredFieldsBody = DynamicFieldsUtils.getPaypalRequiredFields(
+ ~details,
+ ~paymentMethodTypes,
+ ~statesList=stateJson,
+ )
+
+ let bodyArr =
+ requiredFieldsBody
+ ->JSON.Encode.object
+ ->Utils.unflattenObject
+ ->Utils.getArrayOfTupleFromDict
+
+ completeAuthorize(
+ ~bodyArr,
+ ~confirmParam={
+ return_url: options.wallets.walletReturnUrl,
+ publishableKey,
+ },
+ ~handleUserError=true,
+ (),
+ )
+
+ resolve()
+ })
+ ->ignore
+ }
+ },
+ onCancel: _data => {
+ handleCloseLoader()
+ },
+ onError: _err => {
+ handleCloseLoader()
+ },
+ }).render("#paypal-button")
+ areOneClickWalletsRendered(prev => {
+ ...prev,
+ isPaypal: true,
+ })
+ }
+ resolve()
+ })
+ ->ignore
+}
+
+let loadBraintreePaypalSdk = (
+ ~loggerState: OrcaLogger.loggerMake,
+ ~sdkHandleOneClickConfirmPayment,
+ ~token,
+ ~buttonStyle,
+ ~iframeId,
+ ~paymentMethodListValue,
+ ~isGuestCustomer,
+ ~intent: PaymentHelpers.paymentIntent,
+ ~options: PaymentType.options,
+ ~orderDetails,
+ ~publishableKey,
+ ~paymentMethodTypes,
+ ~stateJson,
+ ~handleCloseLoader,
+ ~areOneClickWalletsRendered: (
+ RecoilAtoms.areOneClickWalletsRendered => RecoilAtoms.areOneClickWalletsRendered
+ ) => unit,
+) => {
+ loggerState.setLogInfo(
+ ~value="Paypal Braintree SDK Button Clicked",
+ ~eventName=PAYPAL_SDK_FLOW,
+ ~paymentMethod="PAYPAL",
+ (),
+ )
+ Utils.makeOneClickHandlerPromise(sdkHandleOneClickConfirmPayment)
+ ->then(result => {
+ let result = result->JSON.Decode.bool->Option.getOr(false)
+ if result {
+ braintree.client.create({authorization: token}, (clientErr, clientInstance) => {
+ if clientErr {
+ Console.error2("Error creating client", clientErr)
+ }
+ braintree.paypalCheckout.create(
+ {client: clientInstance},
+ (paypalCheckoutErr, paypalCheckoutInstance) => {
+ switch paypalCheckoutErr->Nullable.toOption {
+ | Some(val) => Console.warn(`INTEGRATION ERROR: ${val.message}`)
+ | None => ()
+ }
+ paypalCheckoutInstance.loadPayPalSDK(
+ {vault: true},
+ () => {
+ let paypalWrapper = GooglePayType.getElementById(Utils.document, "paypal-button")
+ paypalWrapper.innerHTML = ""
+ paypal["Buttons"]({
+ style: buttonStyle,
+ fundingSource: paypal["FUNDING"]["PAYPAL"],
+ createBillingAgreement: () => {
+ //Paypal Clicked
+ Utils.handlePostMessage([
+ ("fullscreen", true->JSON.Encode.bool),
+ ("param", "paymentloader"->JSON.Encode.string),
+ ("iframeId", iframeId->JSON.Encode.string),
+ ])
+ options.readOnly ? () : paypalCheckoutInstance.createPayment(orderDetails)
+ },
+ onApprove: (data, _actions) => {
+ options.readOnly
+ ? ()
+ : paypalCheckoutInstance.tokenizePayment(
+ data,
+ (_err, payload) => {
+ let (connectors, _) =
+ paymentMethodListValue->PaymentUtils.getConnectors(
+ Wallets(Paypal(SDK)),
+ )
+ let body = PaymentBody.paypalSdkBody(~token=payload.nonce, ~connectors)
+
+ let requiredFieldsBody = DynamicFieldsUtils.getPaypalRequiredFields(
+ ~details=payload.details,
+ ~paymentMethodTypes,
+ ~statesList=stateJson,
+ )
+
+ let paypalBody =
+ body
+ ->Utils.getJsonFromArrayOfJson
+ ->Utils.flattenObject(true)
+ ->Utils.mergeTwoFlattenedJsonDicts(requiredFieldsBody)
+ ->Utils.getArrayOfTupleFromDict
+
+ let modifiedPaymentBody = PaymentUtils.appendedCustomerAcceptance(
+ ~isGuestCustomer,
+ ~paymentType=paymentMethodListValue.payment_type,
+ ~body=paypalBody,
+ )
+
+ intent(
+ ~bodyArr=modifiedPaymentBody,
+ ~confirmParam={
+ return_url: options.wallets.walletReturnUrl,
+ publishableKey,
+ },
+ ~handleUserError=true,
+ (),
+ )
+ },
+ )
+ },
+ onCancel: _data => {
+ handleCloseLoader()
+ },
+ onError: _err => {
+ handleCloseLoader()
+ },
+ }).render("#paypal-button")
+ areOneClickWalletsRendered(
+ prev => {
+ ...prev,
+ isPaypal: true,
+ },
+ )
+ },
+ )
+ },
+ )
+ })->ignore
+ }
+ resolve()
+ })
+ ->ignore
+}
diff --git a/src/Types/PaymentConfirmTypes.res b/src/Types/PaymentConfirmTypes.res
index caa90596a..f16088dbb 100644
--- a/src/Types/PaymentConfirmTypes.res
+++ b/src/Types/PaymentConfirmTypes.res
@@ -42,6 +42,7 @@ type nextAction = {
three_ds_data: option,
voucher_details: option,
display_to_timestamp: option,
+ next_action_data: option,
}
type intent = {
nextAction: nextAction,
@@ -51,6 +52,7 @@ type intent = {
error_message: string,
payment_method_type: string,
manualRetryAllowed: bool,
+ connectorTransactionId: string,
}
open Utils
@@ -67,6 +69,7 @@ let defaultNextAction = {
three_ds_data: None,
voucher_details: None,
display_to_timestamp: None,
+ next_action_data: None,
}
let defaultIntent = {
nextAction: defaultNextAction,
@@ -76,6 +79,7 @@ let defaultIntent = {
error_message: "",
payment_method_type: "",
manualRetryAllowed: false,
+ connectorTransactionId: "",
}
let getAchCreditTransfer = (dict, str) => {
@@ -159,6 +163,7 @@ let getNextAction = (dict, str) => {
->Option.flatMap(JSON.Decode.object)
->Option.map(json => json->getVoucherDetails)
},
+ next_action_data: Some(json->getDictfromDict("next_action_data")->JSON.Encode.object),
}
})
->Option.getOr(defaultNextAction)
@@ -172,5 +177,6 @@ let itemToObjMapper = dict => {
error_message: getString(dict, "error_message", ""),
payment_method_type: getString(dict, "payment_method_type", ""),
manualRetryAllowed: getBool(dict, "manual_retry_allowed", false),
+ connectorTransactionId: getString(dict, "connector_transaction_id", ""),
}
}
diff --git a/src/Types/PaypalSDKTypes.res b/src/Types/PaypalSDKTypes.res
index dd44f1ec5..ce66bbc22 100644
--- a/src/Types/PaypalSDKTypes.res
+++ b/src/Types/PaypalSDKTypes.res
@@ -2,7 +2,8 @@ type clientErr = bool
type clientInstance
type paypalCheckoutErr = {message: string}
type data
-type actions
+type order = {get: unit => RescriptCore.Promise.t}
+type actions = {order: order}
type err
type vault = {vault: bool}
type shipping = {
@@ -73,10 +74,11 @@ type style = {
type buttons = {
style: style,
fundingSource: string,
- createBillingAgreement: unit => unit,
+ createBillingAgreement?: unit => unit,
+ createOrder?: unit => RescriptCore.Promise.t,
onApprove: (data, actions) => unit,
onCancel: data => unit,
- onError: err => unit,
+ onError?: err => unit,
}
let getLabel = (var: PaymentType.paypalStyleType) => {
switch var {
@@ -123,6 +125,41 @@ let getShippingDetails = shippingAddressOverrideObj => {
}
}
+let paypalShippingDetails = purchaseUnit => {
+ let shippingAddress = purchaseUnit->Utils.getDictfromDict("shipping")
+ let payee = purchaseUnit->Utils.getDictfromDict("payee")
+
+ let address = shippingAddress->Utils.getDictfromDict("address")
+ let name = shippingAddress->Utils.getDictfromDict("name")
+
+ let recipientName = name->Utils.getOptionString("full_name")
+ let line1 = address->Utils.getOptionString("address_line_1")
+ let line2 = address->Utils.getOptionString("address_line_2")
+ let city = address->Utils.getOptionString("admin_area_2")
+ let countryCode = address->Utils.getOptionString("country_code")
+ let postalCode = address->Utils.getOptionString("postal_code")
+ let state = address->Utils.getOptionString("admin_area_1")
+ let email = payee->Utils.getString("email_address", "")
+
+ let payeePhone = payee->Utils.getOptionString("phone")
+ let shippingAddressPhone = address->Utils.getOptionString("phone")
+
+ {
+ email,
+ shippingAddress: {
+ recipientName,
+ line1,
+ line2,
+ city,
+ countryCode,
+ postalCode,
+ state,
+ phone: shippingAddressPhone,
+ },
+ phone: payeePhone,
+ }
+}
+
let getOrderDetails = (orderDetails, paymentType) => {
let orderDetailsDict = orderDetails->Utils.getDictFromJson
diff --git a/src/Types/SessionsType.res b/src/Types/SessionsType.res
index 395a0b699..1557ddb8d 100644
--- a/src/Types/SessionsType.res
+++ b/src/Types/SessionsType.res
@@ -14,6 +14,7 @@ type token = {
emailRequired: bool,
shippingAddressParameters: JSON.t,
orderDetails: JSON.t,
+ connector: string,
}
type tokenType =
@@ -41,6 +42,7 @@ let defaultToken = {
emailRequired: false,
shippingAddressParameters: Dict.make()->JSON.Encode.object,
orderDetails: Dict.make()->JSON.Encode.object,
+ connector: "",
}
let getWallet = str => {
switch str {
@@ -71,6 +73,7 @@ let getSessionsToken = (dict, str) => {
emailRequired: getBool(dict, "email_required", false),
shippingAddressParameters: getJsonObjectFromDict(dict, "shipping_address_parameters"),
orderDetails: getJsonObjectFromDict(dict, "order_details"),
+ connector: getString(dict, "connector", ""),
}
})
})
diff --git a/src/Utilities/PaymentHelpers.res b/src/Utilities/PaymentHelpers.res
index 257edf0c2..4f993fafe 100644
--- a/src/Utilities/PaymentHelpers.res
+++ b/src/Utilities/PaymentHelpers.res
@@ -12,6 +12,24 @@ type payment = Card | BankTransfer | BankDebits | KlarnaRedirect | Gpay | Applep
let closePaymentLoaderIfAny = () => handlePostMessage([("fullscreen", false->JSON.Encode.bool)])
+type paymentIntent = (
+ ~handleUserError: bool=?,
+ ~bodyArr: array<(string, JSON.t)>,
+ ~confirmParam: ConfirmType.confirmParams,
+ ~iframeId: string=?,
+ ~isThirdPartyFlow: bool=?,
+ ~intentCallback: Core__JSON.t => unit=?,
+ unit,
+) => unit
+
+type completeAuthorize = (
+ ~handleUserError: bool=?,
+ ~bodyArr: array<(string, JSON.t)>,
+ ~confirmParam: ConfirmType.confirmParams,
+ ~iframeId: string=?,
+ unit,
+) => unit
+
let retrievePaymentIntent = (
clientSecret,
headers,
@@ -327,9 +345,15 @@ let rec intentCall = (
) => {
open Promise
let isConfirm = uri->String.includes("/confirm")
- let (eventName: OrcaLogger.eventName, initEventName: OrcaLogger.eventName) = isConfirm
- ? (CONFIRM_CALL, CONFIRM_CALL_INIT)
- : (RETRIEVE_CALL, RETRIEVE_CALL_INIT)
+ let isCompleteAuthorize = uri->String.includes("/complete_authorize")
+ let (eventName: OrcaLogger.eventName, initEventName: OrcaLogger.eventName) = switch (
+ isConfirm,
+ isCompleteAuthorize,
+ ) {
+ | (true, _) => (CONFIRM_CALL, CONFIRM_CALL_INIT)
+ | (_, true) => (COMPLETE_AUTHORIZE_CALL, COMPLETE_AUTHORIZE_CALL_INIT)
+ | _ => (RETRIEVE_CALL, RETRIEVE_CALL_INIT)
+ }
logApi(
~optLogger,
~url=uri,
@@ -708,6 +732,15 @@ let rec intentCall = (
handlePostMessage(message)
}
resolve(data)
+ } else if intent.nextAction.type_ === "invoke_sdk_client" {
+ let nextActionData =
+ intent.nextAction.next_action_data->Option.getOr(JSON.Encode.null)
+ let response =
+ [
+ ("orderId", intent.connectorTransactionId->JSON.Encode.string),
+ ("nextActionData", nextActionData),
+ ]->getJsonFromArrayOfJson
+ resolve(response)
} else {
if !isPaymentSession {
postFailedSubmitResponse(
@@ -949,6 +982,7 @@ let rec maskPayload = payloadJson => {
let usePaymentIntent = (optLogger, paymentType) => {
open RecoilAtoms
+ open Promise
let url = RescriptReactRouter.useUrl()
let paymentTypeFromUrl =
CardUtils.getQueryParamsDictforKey(url.search, "componentName")->CardThemeType.getPaymentMode
@@ -964,6 +998,7 @@ let usePaymentIntent = (optLogger, paymentType) => {
~confirmParam: ConfirmType.confirmParams,
~iframeId=keys.iframeId,
~isThirdPartyFlow=false,
+ ~intentCallback=_ => (),
(),
) => {
switch keys.clientSecret {
@@ -1054,7 +1089,12 @@ let usePaymentIntent = (optLogger, paymentType) => {
~sdkHandleOneClickConfirmPayment=keys.sdkHandleOneClickConfirmPayment,
~counter=0,
(),
- )->ignore
+ )
+ ->then(val => {
+ intentCallback(val)
+ resolve()
+ })
+ ->ignore
}
}
@@ -1126,6 +1166,73 @@ let usePaymentIntent = (optLogger, paymentType) => {
}
}
+let useCompleteAuthorize = (optLogger: option, paymentType: payment) => {
+ open RecoilAtoms
+ let paymentMethodList = Recoil.useRecoilValueFromAtom(paymentMethodList)
+ let keys = Recoil.useRecoilValueFromAtom(keys)
+ let switchToCustomPod = Recoil.useRecoilValueFromAtom(switchToCustomPod)
+ let setIsManualRetryEnabled = Recoil.useSetRecoilState(isManualRetryEnabled)
+ let url = RescriptReactRouter.useUrl()
+ let paymentTypeFromUrl =
+ CardUtils.getQueryParamsDictforKey(url.search, "componentName")->CardThemeType.getPaymentMode
+ (
+ ~handleUserError=false,
+ ~bodyArr: array<(string, JSON.t)>,
+ ~confirmParam: ConfirmType.confirmParams,
+ ~iframeId=keys.iframeId,
+ (),
+ ) => {
+ switch keys.clientSecret {
+ | Some(clientSecret) =>
+ let paymentIntentID = String.split(clientSecret, "_secret_")->Array.get(0)->Option.getOr("")
+ let headers = [
+ ("Content-Type", "application/json"),
+ ("api-key", confirmParam.publishableKey),
+ ("X-Client-Source", paymentTypeFromUrl->CardThemeType.getPaymentModeToStrMapper),
+ ]
+ let endpoint = ApiEndpoint.getApiEndPoint(~publishableKey=confirmParam.publishableKey, ())
+ let uri = `${endpoint}/payments/${paymentIntentID}/complete_authorize`
+
+ let browserInfo = BrowserSpec.broswerInfo
+ let bodyStr =
+ [("client_secret", clientSecret->JSON.Encode.string)]
+ ->Array.concatMany([bodyArr, browserInfo()])
+ ->Utils.getJsonFromArrayOfJson
+ ->JSON.stringify
+
+ let completeAuthorize = () => {
+ intentCall(
+ ~fetchApi,
+ ~uri,
+ ~headers,
+ ~bodyStr,
+ ~confirmParam: ConfirmType.confirmParams,
+ ~clientSecret,
+ ~optLogger,
+ ~handleUserError,
+ ~paymentType,
+ ~iframeId,
+ ~fetchMethod=#POST,
+ ~setIsManualRetryEnabled,
+ ~switchToCustomPod,
+ ~sdkHandleOneClickConfirmPayment=keys.sdkHandleOneClickConfirmPayment,
+ ~counter=0,
+ (),
+ )->ignore
+ }
+ switch paymentMethodList {
+ | Loaded(_) => completeAuthorize()
+ | _ => ()
+ }
+ | None =>
+ postFailedSubmitResponse(
+ ~errortype="complete_authorize_failed",
+ ~message="Complete Authorize Failed. Try Again!",
+ )
+ }
+ }
+}
+
let fetchSessions = (
~clientSecret,
~publishableKey,
diff --git a/src/orca-loader/Elements.res b/src/orca-loader/Elements.res
index f868ec559..217db77d9 100644
--- a/src/orca-loader/Elements.res
+++ b/src/orca-loader/Elements.res
@@ -752,7 +752,10 @@ let make = (
applePayPresent->Belt.Option.isSome
) {
//do operations here
- let processPayment = (payment: ApplePayTypes.paymentResult) => {
+ let processPayment = (
+ payment: ApplePayTypes.paymentResult,
+ applePayEvent: Types.event,
+ ) => {
//let body = PaymentBody.applePayBody(~token)
let msg =
[
@@ -760,11 +763,11 @@ let make = (
("applePayBillingContact", payment.billingContact),
("applePayShippingContact", payment.shippingContact),
]->Dict.fromArray
- event.source->Window.sendPostMessage(msg)
+ applePayEvent.source->Window.sendPostMessage(msg)
}
- let handleApplePayMessages = (event: Types.event) => {
- let json = event.data->Identity.anyTypeToJson
+ let handleApplePayMessages = (applePayEvent: Types.event) => {
+ let json = applePayEvent.data->Identity.anyTypeToJson
let dict = json->getDictFromJson
switch (
dict->Dict.get("applePayButtonClicked"),
@@ -817,7 +820,7 @@ let make = (
{"status": ssn.\"STATUS_SUCCESS"}->Identity.anyTypeToJson,
)
applePaySessionRef := Nullable.null
- processPayment(event.payment)
+ processPayment(event.payment, applePayEvent)
let value = "Payment Data Filled: New Payment Method"
logger.setLogInfo(
~value,
@@ -829,7 +832,7 @@ let make = (
ssn.oncancel = _ev => {
let msg =
[("showApplePayButton", true->JSON.Encode.bool)]->Dict.fromArray
- event.source->Window.sendPostMessage(msg)
+ applePayEvent.source->Window.sendPostMessage(msg)
applePaySessionRef := Nullable.null
logInfo(Console.log("Apple Pay Payment Cancelled"))
logger.setLogInfo(
diff --git a/src/orca-log-catcher/OrcaLogger.res b/src/orca-log-catcher/OrcaLogger.res
index 15d345cda..1c2852210 100644
--- a/src/orca-log-catcher/OrcaLogger.res
+++ b/src/orca-log-catcher/OrcaLogger.res
@@ -65,6 +65,8 @@ type eventName =
| PAYMENT_SESSION_INITIATED
| POLL_STATUS_INIT
| POLL_STATUS_CALL
+ | COMPLETE_AUTHORIZE_CALL_INIT
+ | COMPLETE_AUTHORIZE_CALL
let eventNameToStrMapper = eventName => {
switch eventName {
@@ -130,6 +132,8 @@ let eventNameToStrMapper = eventName => {
| PAYMENT_SESSION_INITIATED => "PAYMENT_SESSION_INITIATED"
| POLL_STATUS_INIT => "POLL_STATUS_INIT"
| POLL_STATUS_CALL => "POLL_STATUS_CALL"
+ | COMPLETE_AUTHORIZE_CALL_INIT => "COMPLETE_AUTHORIZE_CALL_INIT"
+ | COMPLETE_AUTHORIZE_CALL => "COMPLETE_AUTHORIZE_CALL"
}
}