Skip to content

Commit

Permalink
feat: klarna Checkout SDK added (#851)
Browse files Browse the repository at this point in the history
Co-authored-by: Pritish Budhiraja <pritish.budhiraja@gmail.com>
  • Loading branch information
Sweta-Kumari-Sharma and PritishBudhiraja authored Jan 3, 2025
1 parent 19acc32 commit 3011a1c
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 9 deletions.
84 changes: 84 additions & 0 deletions src/Payments/KlarnaCheckout.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
open RecoilAtoms
open Promise

let klarnaIcon = <Icon size=35 width=90 name="klarna" />

@react.component
let make = () => {
let loggerState = Recoil.useRecoilValueFromAtom(loggerAtom)
let sdkHandleIsThere = Recoil.useRecoilValueFromAtom(isPaymentButtonHandlerProvidedAtom)
let {publishableKey} = Recoil.useRecoilValueFromAtom(keys)
let options = Recoil.useRecoilValueFromAtom(optionAtom)
let isManualRetryEnabled = Recoil.useRecoilValueFromAtom(isManualRetryEnabled)
let intent = PaymentHelpers.usePaymentIntent(Some(loggerState), Other)
let paymentMethodListValue = Recoil.useRecoilValueFromAtom(PaymentUtils.paymentMethodListValue)
let (klarnaClicked, setKlarnaClicked) = React.useState(_ => false)

let (_, _, _, heightType, _) = options.wallets.style.height
let height = switch heightType {
| Klarna(val) => val
| _ => 48
}
let (buttonColor, textColor) =
options.wallets.style.theme == Light ? ("#0070ba", "#ffffff") : ("#0b051d", "#000000")

let onKlarnaClick = async _ev => {
try {
loggerState.setLogInfo(
~value="Klarna Checkout Button Clicked",
~eventName=KLARNA_CHECKOUT_FLOW,
~paymentMethod="KLARNA",
)

setKlarnaClicked(_ => true)

let result = await Utils.makeOneClickHandlerPromise(sdkHandleIsThere)
let decodedResult = result->JSON.Decode.bool->Option.getOr(false)

if decodedResult {
let (connectors, _) =
paymentMethodListValue->PaymentUtils.getConnectors(PayLater(Klarna(Redirect)))
let body = PaymentBody.klarnaCheckoutBody(~connectors)

intent(
~bodyArr=body,
~confirmParam={
return_url: options.wallets.walletReturnUrl,
publishableKey,
},
~handleUserError=true,
~manualRetry=isManualRetryEnabled,
)
} else {
setKlarnaClicked(_ => false)
}
resolve()
} catch {
| _ => resolve()
}
}

<button
style={
display: "inline-block",
color: textColor,
height: `${height->Int.toString}px`,
borderRadius: `${options.wallets.style.buttonRadius->Int.toString}px`,
width: "100%",
backgroundColor: buttonColor,
}
onClick={_ =>
if !options.readOnly {
onKlarnaClick()->ignore
}}>
<div className="justify-center" style={display: "flex", flexDirection: "row", color: textColor}>
{if klarnaClicked {
<Loader />
} else {
klarnaIcon
}}
</div>
</button>
}

let default = make
1 change: 1 addition & 0 deletions src/Payments/KlarnaCheckoutLazy.res
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let make = React.lazy_(() => Js.import(KlarnaCheckout.default))
32 changes: 32 additions & 0 deletions src/Payments/KlarnaHelpers.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
open PaymentMethodsRecord
open SessionsType

type klarnaExperienceData = {
klarnaTokenObj: optionalTokenType,
isKlarnaSDKFlow: bool,
isKlarnaCheckoutFlow: bool,
}

let usePaymentMethodExperience = (~paymentMethodListValue, ~sessionObj: sessions) => {
let klarnaPaymentMethodExperience = React.useMemo(() => {
getPaymentExperienceTypeFromPML(
~paymentMethodList=paymentMethodListValue,
~paymentMethodName="pay_later",
~paymentMethodType="klarna",
)
}, [paymentMethodListValue])

let klarnaTokenObj = React.useMemo(
() => getPaymentSessionObj(sessionObj.sessionsToken, Klarna),
[sessionObj],
)

let isKlarnaSDKFlow = klarnaPaymentMethodExperience->Array.includes(InvokeSDK)
let isKlarnaCheckoutFlow = klarnaPaymentMethodExperience->Array.includes(RedirectToURL)

{
klarnaTokenObj,
isKlarnaSDKFlow,
isKlarnaCheckoutFlow,
}
}
20 changes: 13 additions & 7 deletions src/Payments/PaymentRequestButtonElement.res
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ let make = (~sessions, ~walletOptions, ~paymentType) => {
Gpay,
)

let {isKlarnaSDKFlow, isKlarnaCheckoutFlow} = KlarnaHelpers.usePaymentMethodExperience(~paymentMethodListValue, ~sessionObj)

let klarnaTokenObj = getPaymentSessionObj(sessionObj.sessionsToken, Klarna)
let pazeTokenObj = getPaymentSessionObj(sessionObj.sessionsToken, Paze)

Expand Down Expand Up @@ -136,14 +138,18 @@ let make = (~sessions, ~walletOptions, ~paymentType) => {
| _ => React.null
}
| KlarnaWallet =>
<SessionPaymentWrapper type_=Others>
<SessionPaymentWrapper type_={Others}>
{switch klarnaTokenObj {
| OtherTokenOptional(optToken) =>
switch optToken {
| Some(token) => <KlarnaSDKLazy sessionObj=token />
| None => React.null
}
| _ => React.null
| OtherTokenOptional(optToken) =>
switch (optToken, isKlarnaSDKFlow, isKlarnaCheckoutFlow) {
| (Some(token), true, _) => <KlarnaSDKLazy sessionObj=token />
| (_, _, true) => <KlarnaCheckoutLazy/>
| _ => React.null
}
| _ =>
<RenderIf condition={isKlarnaCheckoutFlow}>
<KlarnaCheckoutLazy/>
</RenderIf>
}}
</SessionPaymentWrapper>

Expand Down
14 changes: 14 additions & 0 deletions src/Utilities/PaymentBody.res
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,20 @@ let klarnaSDKbody = (~token, ~connectors) => [
),
]

let klarnaCheckoutBody = (~connectors) => {
open Utils
let checkoutBody=[]->Utils.getJsonFromArrayOfJson
let payLaterBody = [("klarna_checkout", checkoutBody)]->getJsonFromArrayOfJson
let paymentMethodData = [("pay_later", payLaterBody)]->getJsonFromArrayOfJson
[
("payment_method", "pay_later"->JSON.Encode.string),
("payment_method_type", "klarna"->JSON.Encode.string),
("payment_experience", "redirect_to_url"->JSON.Encode.string),
("connector", connectors->getArrofJsonString->JSON.Encode.array),
("payment_method_data", paymentMethodData),
]
}

let paypalRedirectionBody = (~connectors) => [
("payment_method", "wallet"->JSON.Encode.string),
("payment_method_type", "paypal"->JSON.Encode.string),
Expand Down
5 changes: 3 additions & 2 deletions src/Utilities/PaymentUtils.res
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,10 @@ let paymentListLookupNew = (
let isInvokeSDKExperience = klarnaPaymentMethodExperience->Array.includes(InvokeSDK)
let isRedirectExperience = klarnaPaymentMethodExperience->Array.includes(RedirectToURL)

if isKlarnaSDKFlow && isShowKlarnaOneClick && isInvokeSDKExperience {
if (isKlarnaSDKFlow && isShowKlarnaOneClick && isInvokeSDKExperience) || isRedirectExperience {
walletsList->Array.push(item.paymentMethodName)->ignore
} else if isRedirectExperience {
}
else {
otherPaymentList->Array.push(item.paymentMethodName)->ignore
}
} else {
Expand Down
1 change: 1 addition & 0 deletions src/hyper-log-catcher/HyperLogger.res
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type eventName =
| GOOGLE_PAY_FLOW
| PAYPAL_FLOW
| PAYPAL_SDK_FLOW
| KLARNA_CHECKOUT_FLOW
| APP_INITIATED
| APP_REINITIATED
| LOG_INITIATED
Expand Down

0 comments on commit 3011a1c

Please sign in to comment.