From bfc747010c6a5c891d0d93e7ce9dbbcdd8980e07 Mon Sep 17 00:00:00 2001 From: ArushKapoorJuspay <121166031+ArushKapoorJuspay@users.noreply.github.com> Date: Thu, 30 May 2024 16:23:11 +0530 Subject: [PATCH 1/5] fix: fixed ApplePay Event Handler (#406) --- src/orca-loader/Elements.res | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) 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( From 084932d644cc4f7da9aebe124e069e97ee14476b Mon Sep 17 00:00:00 2001 From: ArushKapoorJuspay <121166031+ArushKapoorJuspay@users.noreply.github.com> Date: Thu, 30 May 2024 16:24:01 +0530 Subject: [PATCH 2/5] feat: added PayPal SDK Via PayPal (#404) Co-authored-by: Shiva Nandan --- src/Payments/Boleto.res | 1 - src/Payments/PaypalSDK.res | 175 +++++++------------- src/Payments/PaypalSDKHelpers.res | 243 ++++++++++++++++++++++++++++ src/Types/PaymentConfirmTypes.res | 6 + src/Types/PaypalSDKTypes.res | 43 ++++- src/Types/SessionsType.res | 3 + src/Utilities/PaymentHelpers.res | 115 ++++++++++++- src/orca-log-catcher/OrcaLogger.res | 4 + 8 files changed, 468 insertions(+), 122 deletions(-) create mode 100644 src/Payments/PaypalSDKHelpers.res diff --git a/src/Payments/Boleto.res b/src/Payments/Boleto.res index 4378285a6..33ac77d1b 100644 --- a/src/Payments/Boleto.res +++ b/src/Payments/Boleto.res @@ -66,7 +66,6 @@ let make = (~paymentType: CardThemeType.mode) => { ~iframeId, (), ) - () } else { postFailedSubmitResponse(~errortype="validation_error", ~message="Please enter all fields") } 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-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" } } From 2e3552c238b5124cd9f49516a7ae75e9b4a98c9b Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 30 May 2024 10:57:38 +0000 Subject: [PATCH 3/5] chore(release): 0.57.0 [skip ci] # [0.57.0](https://github.com/juspay/hyperswitch-web/compare/v0.56.1...v0.57.0) (2024-05-30) ### Bug Fixes * fixed ApplePay Event Handler ([#406](https://github.com/juspay/hyperswitch-web/issues/406)) ([bfc7470](https://github.com/juspay/hyperswitch-web/commit/bfc747010c6a5c891d0d93e7ce9dbbcdd8980e07)) ### Features * added PayPal SDK Via PayPal ([#404](https://github.com/juspay/hyperswitch-web/issues/404)) ([084932d](https://github.com/juspay/hyperswitch-web/commit/084932d644cc4f7da9aebe124e069e97ee14476b)) --- CHANGELOG.md | 12 ++++++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fd9e83ea..0e78ebe91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,15 @@ +# [0.57.0](https://github.com/juspay/hyperswitch-web/compare/v0.56.1...v0.57.0) (2024-05-30) + + +### Bug Fixes + +* fixed ApplePay Event Handler ([#406](https://github.com/juspay/hyperswitch-web/issues/406)) ([bfc7470](https://github.com/juspay/hyperswitch-web/commit/bfc747010c6a5c891d0d93e7ce9dbbcdd8980e07)) + + +### Features + +* added PayPal SDK Via PayPal ([#404](https://github.com/juspay/hyperswitch-web/issues/404)) ([084932d](https://github.com/juspay/hyperswitch-web/commit/084932d644cc4f7da9aebe124e069e97ee14476b)) + ## [0.56.1](https://github.com/juspay/hyperswitch-web/compare/v0.56.0...v0.56.1) (2024-05-27) diff --git a/package-lock.json b/package-lock.json index 983d2fdf2..f28375e49 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.56.1", + "version": "0.57.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.56.1", + "version": "0.57.0", "hasInstallScript": true, "dependencies": { "@aws-sdk/client-cloudfront": "^3.414.0", diff --git a/package.json b/package.json index e49143145..6a455901a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.56.1", + "version": "0.57.0", "main": "index.js", "private": true, "dependencies": { From 8a5d5548d70750725a61381abf4fa68879fa4746 Mon Sep 17 00:00:00 2001 From: Pritish Budhiraja Date: Thu, 30 May 2024 16:38:12 +0530 Subject: [PATCH 4/5] fix: hide terms based upon prop (#408) --- src/Components/SavedMethods.res | 4 +++- src/Payments/CardPayment.res | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Components/SavedMethods.res b/src/Components/SavedMethods.res index 7d8544605..eae7aad23 100644 --- a/src/Components/SavedMethods.res +++ b/src/Components/SavedMethods.res @@ -214,7 +214,9 @@ let make = ( - +
CardUtils.getCardType} /> - + {switch ( paymentMethodListValue.mandate_payment, options.terms.card, From cc00bb0499083e2670a6e730cbe5c9f5b750a727 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Thu, 30 May 2024 11:09:52 +0000 Subject: [PATCH 5/5] chore(release): 0.57.1 [skip ci] ## [0.57.1](https://github.com/juspay/hyperswitch-web/compare/v0.57.0...v0.57.1) (2024-05-30) ### Bug Fixes * hide terms based upon prop ([#408](https://github.com/juspay/hyperswitch-web/issues/408)) ([8a5d554](https://github.com/juspay/hyperswitch-web/commit/8a5d5548d70750725a61381abf4fa68879fa4746)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0e78ebe91..37d2c537a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [0.57.1](https://github.com/juspay/hyperswitch-web/compare/v0.57.0...v0.57.1) (2024-05-30) + + +### Bug Fixes + +* hide terms based upon prop ([#408](https://github.com/juspay/hyperswitch-web/issues/408)) ([8a5d554](https://github.com/juspay/hyperswitch-web/commit/8a5d5548d70750725a61381abf4fa68879fa4746)) + # [0.57.0](https://github.com/juspay/hyperswitch-web/compare/v0.56.1...v0.57.0) (2024-05-30) diff --git a/package-lock.json b/package-lock.json index f28375e49..e6e0d019a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "orca-payment-page", - "version": "0.57.0", + "version": "0.57.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "orca-payment-page", - "version": "0.57.0", + "version": "0.57.1", "hasInstallScript": true, "dependencies": { "@aws-sdk/client-cloudfront": "^3.414.0", diff --git a/package.json b/package.json index 6a455901a..12fb0b60d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "orca-payment-page", - "version": "0.57.0", + "version": "0.57.1", "main": "index.js", "private": true, "dependencies": {