Skip to content

Commit

Permalink
feat(paymentmethods): boleto Payment Method Integration (#195)
Browse files Browse the repository at this point in the history
Co-authored-by: ArushKapoorJuspay <[email protected]>
  • Loading branch information
vsrivatsa-edinburgh and ArushKapoorJuspay authored Mar 5, 2024
1 parent c3911b9 commit f4fc04d
Show file tree
Hide file tree
Showing 18 changed files with 364 additions and 20 deletions.
3 changes: 3 additions & 0 deletions public/icons/orca.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 8 additions & 4 deletions src/App.res
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,20 @@ let make = () => {
log
})

React.useEffect1(()=>{
setLoggerState(._=>logger)
React.useEffect1(() => {
setLoggerState(._ => logger)
None
},[logger])
}, [logger])

let renderFullscreen = {
switch fullscreenMode {
| "paymentloader" => <PaymentLoader />
| "fullscreen" => <div id="fullscreen"> <FullScreenDivDriver /> </div>
| "fullscreen" =>
<div id="fullscreen">
<FullScreenDivDriver />
</div>
| "qrData" => <QRCodeDisplay />
| "voucherData" => <VoucherDisplay />
| "preMountLoader" => {
let clientSecret = CardUtils.getQueryParamsDictforKey(url.search, "clientSecret")
let sessionId = CardUtils.getQueryParamsDictforKey(url.search, "sessionId")
Expand Down
3 changes: 2 additions & 1 deletion src/Components/InfoElement.res
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ let make = () => {
{switch selectedOption {
| ACHTransfer
| BacsTransfer
| SepaTransfer =>
| SepaTransfer
| Boleto =>
localeString.bankDetailsText
| _ => localeString.redirectText
}->React.string}
Expand Down
11 changes: 10 additions & 1 deletion src/LocaleString.res
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ type localeStrings = {
nameEmptyText: string => string,
completeNameEmptyText: string => string,
billingDetailsText: string,
socialSecurityNumberLabel: string,
}

let defaultLocale = {
Expand Down Expand Up @@ -137,6 +138,7 @@ let defaultLocale = {
nameEmptyText: str => `Please provide your ${str}`,
completeNameEmptyText: str => `Please provide your complete ${str}`,
billingDetailsText: "Billing Details",
socialSecurityNumberLabel: "Social Security Number",
}

type locale = {localeStrings: array<localeStrings>}
Expand Down Expand Up @@ -215,6 +217,7 @@ let localeStrings = [
nameEmptyText: str => `Please provide your ${str}`,
completeNameEmptyText: str => `Please provide your complete ${str}`,
billingDetailsText: "Billing Details",
socialSecurityNumberLabel: "Social Security Number",
},
{
locale: "he",
Expand Down Expand Up @@ -290,6 +293,7 @@ let localeStrings = [
nameEmptyText: str => `אנא ספק את שלך ${str}`,
completeNameEmptyText: str => `אנא ספק את המלא שלך ${str}`,
billingDetailsText: `פרטי תשלום`,
socialSecurityNumberLabel: `מספר ביטוח לאומי`,
},
{
locale: `fr`,
Expand Down Expand Up @@ -364,7 +368,8 @@ let localeStrings = [
\"and": `et`,
nameEmptyText: str => `Veuillez fournir votre ${str}`,
completeNameEmptyText: str => `Veuillez fournir votre complet ${str}`,
billingDetailsText: "Détails de la facturation",
billingDetailsText: `Détails de la facturation`,
socialSecurityNumberLabel: `Numéro de sécurité sociale`,
},
{
locale: "en-GB",
Expand Down Expand Up @@ -440,6 +445,7 @@ let localeStrings = [
nameEmptyText: str => `Please provide your ${str}`,
completeNameEmptyText: str => `Please provide your complete ${str}`,
billingDetailsText: "Billing Details",
socialSecurityNumberLabel: "Social Security Number",
},
{
locale: "ar",
Expand Down Expand Up @@ -515,6 +521,7 @@ let localeStrings = [
nameEmptyText: str => `يرجى تقديم الخاص بك ${str}`,
completeNameEmptyText: str => `يرجى تقديم كامل الخاص بك ${str}`,
billingDetailsText: `تفاصيل الفاتورة`,
socialSecurityNumberLabel: `رقم الضمان الاجتماعي`,
},
{
locale: "ja",
Expand Down Expand Up @@ -590,6 +597,7 @@ let localeStrings = [
nameEmptyText: str => `あなたの情報を提供してください ${str}`,
completeNameEmptyText: str => `完全な情報を提供してください ${str}`,
billingDetailsText: `支払明細`,
socialSecurityNumberLabel: `社会保障番号`,
},
{
locale: "de",
Expand Down Expand Up @@ -665,5 +673,6 @@ let localeStrings = [
nameEmptyText: str => `Bitte geben Sie Ihre an ${str}`,
completeNameEmptyText: str => `Bitte geben Sie Ihr vollständiges Formular an ${str}`,
billingDetailsText: `Rechnungsdetails`,
socialSecurityNumberLabel: `Sozialversicherungsnummer`,
},
]
5 changes: 5 additions & 0 deletions src/PaymentDetails.res
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,9 @@ let details = [
icon: Some(icon("bank", ~size=21)),
displayName: "BECS Debit",
},
{
type_: "boleto",
icon: Some(icon("boleto", ~size=19)),
displayName: "Boleto",
},
]
4 changes: 4 additions & 0 deletions src/PaymentElement.res
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,10 @@ let make = (
<ApplePayLazy sessionObj=optToken list walletOptions paymentType />
| _ => React.null
}
| Boleto =>
<React.Suspense fallback={loader()}>
<BoletoLazy paymentType list />
</React.Suspense>
| _ =>
<React.Suspense fallback={loader()}>
<PaymentMethodsWrapperLazy paymentType list paymentMethodName=selectedOption />
Expand Down
115 changes: 115 additions & 0 deletions src/Payments/Boleto.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
open RecoilAtoms
open Utils

let cleanSocialSecurityNumber = socialSecurityNumber =>
socialSecurityNumber->Js.String2.replaceByRe(%re("/\D+/g"), "")

let formatSocialSecurityNumber = socialSecurityNumber => {
let formatted = socialSecurityNumber->cleanSocialSecurityNumber
let firstPart = formatted->CardUtils.slice(0, 3)
let secondPart = formatted->CardUtils.slice(3, 6)
let thirdPart = formatted->CardUtils.slice(6, 9)
let fourthPart = formatted->CardUtils.slice(9, 11)

if formatted->Js.String2.length <= 3 {
firstPart
} else if formatted->Js.String2.length > 3 && formatted->Js.String2.length <= 6 {
`${firstPart}.${secondPart}`
} else if formatted->Js.String2.length > 6 && formatted->Js.String2.length <= 9 {
`${firstPart}.${secondPart}.${thirdPart}`
} else {
`${firstPart}.${secondPart}.${thirdPart}-${fourthPart}`
}
}

@react.component
let make = (~paymentType: CardThemeType.mode, ~list: PaymentMethodsRecord.list) => {
let loggerState = Recoil.useRecoilValueFromAtom(loggerAtom)

let {config, themeObj, localeString} = Recoil.useRecoilValueFromAtom(configAtom)
let {iframeId} = Recoil.useRecoilValueFromAtom(keys)

let intent = PaymentHelpers.usePaymentIntent(Some(loggerState), Other)
let setComplete = Recoil.useSetRecoilState(fieldsComplete)
let (socialSecurityNumber, setSocialSecurityNumber) = React.useState(_ => "")

let (socialSecurityNumberError, setSocialSecurityNumberError) = React.useState(_ => "")

let socialSecurityNumberRef = React.useRef(Js.Nullable.null)

let (complete, empty) = React.useMemo1(() => {
(
socialSecurityNumber->cleanSocialSecurityNumber->Js.String2.length == 11,
socialSecurityNumber->Js.String2.length == 0,
)
}, [socialSecurityNumber])

React.useEffect2(() => {
handlePostMessageEvents(~complete, ~empty, ~paymentType="boleto", ~loggerState)
None
}, (complete, empty))

React.useEffect1(() => {
setComplete(._ => complete)
None
}, [complete])

let submitCallback = React.useCallback1((ev: Window.event) => {
let json = ev.data->Js.Json.parseExn
let confirm = json->Utils.getDictFromJson->ConfirmType.itemToObjMapper

if confirm.doSubmit {
if complete {
let body = PaymentBody.boletoBody(
~socialSecurityNumber=socialSecurityNumber->Js.String2.replaceByRe(%re("/\D+/g"), ""),
)
intent(
~bodyArr=body,
~confirmParam=confirm.confirmParams,
~handleUserError=false,
~iframeId,
(),
)
()
} else {
postFailedSubmitResponse(~errortype="validation_error", ~message="Please enter all fields")
}
}
}, [socialSecurityNumber])
submitPaymentData(submitCallback)

let changeSocialSecurityNumber = ev => {
let val = ReactEvent.Form.target(ev)["value"]
setSocialSecurityNumberError(_ => "")
setSocialSecurityNumber(_ => val->formatSocialSecurityNumber)
}
let socialSecurityNumberBlur = ev => {
let val = ReactEvent.Focus.target(ev)["value"]->cleanSocialSecurityNumber
if val->Js.String2.length != 11 && val->Js.String2.length > 0 {
setSocialSecurityNumberError(_ => "The social security number entered is invalid.")
}
}

<div
className="flex flex-col animate-slowShow"
style={ReactDOMStyle.make(~gridGap=themeObj.spacingGridColumn, ())}>
<PaymentInputField
fieldName=localeString.socialSecurityNumberLabel
value=socialSecurityNumber
onChange=changeSocialSecurityNumber
paymentType
errorString=socialSecurityNumberError
isValid={socialSecurityNumberError == "" ? None : Some(false)}
type_="tel"
appearance=config.appearance
maxLength=14
onBlur=socialSecurityNumberBlur
inputRef=socialSecurityNumberRef
placeholder="000.000.000-00"
/>
<Surcharge list paymentMethod="voucher" paymentMethodType="boleto" />
<InfoElement />
</div>
}

let default = make
5 changes: 5 additions & 0 deletions src/Payments/Boleto.resi
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
let cleanSocialSecurityNumber: Js.String2.t => Js.String2.t
let formatSocialSecurityNumber: Js.String2.t => Js.String2.t
@react.component
let make: (~paymentType: CardThemeType.mode, ~list: PaymentMethodsRecord.list) => React.element
let default: props<CardThemeType.mode, PaymentMethodsRecord.list> => React.element
8 changes: 8 additions & 0 deletions src/Payments/BoletoLazy.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
open LazyUtils

type props = {
paymentType: CardThemeType.mode,
list: PaymentMethodsRecord.list,
}

let make: props => React.element = reactLazy(.() => import_("./Boleto.bs.js"))
10 changes: 9 additions & 1 deletion src/Payments/PaymentMethodsRecord.res
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,13 @@ let paymentMethodsFields = [
displayName: "Pix",
miniIcon: None,
},
{
paymentMethodName: "boleto",
icon: Some(icon("boleto", ~size=19, ~width=25)),
displayName: "Boleto",
fields: [InfoElement],
miniIcon: None,
},
]

type required_fields = {
Expand Down Expand Up @@ -651,7 +658,7 @@ let getPaymentDetails = (arr: array<string>) => {
}

type paymentMethod =
Cards | Wallets | PayLater | BankRedirect | BankTransfer | BankDebit | Crypto | NONE
Cards | Wallets | PayLater | BankRedirect | BankTransfer | BankDebit | Crypto | Voucher | NONE

type cardType = Credit | Debit
type paymentMethodType =
Expand Down Expand Up @@ -737,6 +744,7 @@ let getMethod = str => {
| "bank_transfer" => BankTransfer
| "bank_debit" => BankDebit
| "crypto" => Crypto
| "voucher" => Voucher
| _ => NONE
}
}
Expand Down
Loading

0 comments on commit f4fc04d

Please sign in to comment.