Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: added ACH Bank Transfer #217

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions hyperswitch-sdk-ios
Submodule hyperswitch-sdk-ios added at e7ade8
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
"prepare": "husky"
},
"dependencies": {
"@react-native-clipboard/clipboard": "^1.16.1",
"@sentry/react-native": "^5.9.1",
"pako": "^2.1.0",
"react-native-code-push": "^8.3.1",
Expand Down
11 changes: 8 additions & 3 deletions src/components/elements/ModalHeader.res
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ let make = (~onModalClose) => {
| PaymentScreenContext.PAYMENTSHEET => nativeProp.configuration.paymentSheetHeaderText
| PaymentScreenContext.SAVEDCARDSCREEN =>
nativeProp.configuration.savedPaymentScreenHeaderText
| BANK_TRANSFER(_) => None
} {
| Some(var) =>
<View style={viewStyle(~maxWidth=60.->pct, ())}>
Expand Down Expand Up @@ -64,9 +65,13 @@ let make = (~onModalClose) => {
overrideStyle=Some(textStyle(~color="black", ()))
/>
</View>}
<CustomTouchableOpacity onPress={_ => onModalClose()}>
<Icon name="close" width=16. height=16. fill=iconColor />
</CustomTouchableOpacity>
{switch paymentScreenType {
| BANK_TRANSFER(_) => React.null
| _ =>
<CustomTouchableOpacity onPress={_ => onModalClose()}>
<Icon name="close" width=16. height=16. fill=iconColor />
</CustomTouchableOpacity>
}}
</>}
</View>
</View>
Expand Down
1 change: 1 addition & 0 deletions src/contexts/LoadingContext.res
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ type sdkPaymentState =
| ProcessingPayments(option<processingPayments>)
| PaymentSuccess
| PaymentCancelled
| BankTransfer
let defaultSetter = (_: sdkPaymentState) => ()
let loadingContext = React.createContext((FillingDetails, defaultSetter))

Expand Down
3 changes: 2 additions & 1 deletion src/contexts/PaymentScreenContext.res
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
type paymentScreenType = PAYMENTSHEET | SAVEDCARDSCREEN
type paymentScreenType =
PAYMENTSHEET | SAVEDCARDSCREEN | BANK_TRANSFER(option<PaymentConfirmTypes.ach_credit_transfer>)
let dafaultVal = SAVEDCARDSCREEN

let paymentScreenTypeContext = React.createContext((dafaultVal, (_: paymentScreenType) => ()))
Expand Down
17 changes: 17 additions & 0 deletions src/hooks/AllPaymentHooks.res
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,8 @@ let useBrowserHook = () => {
let useRedirectHook = () => {
let (nativeProp, _) = React.useContext(NativePropContext.nativePropContext)
let (allApiData, setAllApiData) = React.useContext(AllApiDataContext.allApiDataContext)
let (_, setPaymentScreenType) = React.useContext(PaymentScreenContext.paymentScreenTypeContext)
let (_, setLoading) = React.useContext(LoadingContext.loadingContext)
let redirectioBrowserHook = useBrowserHook()
let retrievePayment = useRetrieveHook()
let apiLogWrapper = LoggerHook.useApiLogWrapper()
Expand Down Expand Up @@ -428,6 +430,21 @@ let useRedirectHook = () => {
| None => ()
}
}
| "display_bank_transfer_information" => {
switch nextAction {
| None => ()
| Some(data) =>
setLoading(BankTransfer)
setPaymentScreenType(
BANK_TRANSFER(
Some(
data.bank_transfer_steps_and_charges_detail->getACH_bank_transfer->getACH_details,
),
),
)
}
()
}
| _ =>
switch status {
| "succeeded" =>
Expand Down
20 changes: 20 additions & 0 deletions src/hooks/PMListModifier.res
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,26 @@ let useListModifier = () => {
setConfirmButtonDataRef
/>,
})
| BANK_TRANSFER(bankTransferVal) =>
let fields =
redirectionList
->Array.find(l => {
l.name === bankTransferVal.payment_method_type ++ "_bank_transfer"
})
->Option.getOr(Types.defaultRedirectType)

Some({
name: fields.text,
componentHoc: (~isScreenFocus, ~setConfirmButtonDataRef) =>
<Redirect
isScreenFocus
isDynamicFields={true}
dynamicFields={bankTransferVal.required_field}
redirectProp=BANK_TRANSFER(bankTransferVal)
fields
setConfirmButtonDataRef
/>,
})
} {
| Some(tab) =>
let isInvalidScreen =
Expand Down
25 changes: 25 additions & 0 deletions src/hooks/S3ApiHook.res
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,31 @@ let getLocaleStrings: Js.Json.t => localeStrings = data => {
defaultLocale.enterValidDigitsText,
),
digitsText: Utils.getString(res, "digitsText", defaultLocale.digitsText),
disclaimerTextAchTransfer: Utils.getString(
res,
"disclaimerTextAchTransfer",
defaultLocale.disclaimerTextAchTransfer,
),
instructionalTextOfAchTransfer: Utils.getString(
res,
"instructionalTextOfAchTransfer",
defaultLocale.instructionalTextOfAchTransfer,
),
accountDetailsText: Utils.getString(
res,
"accountDetailsText",
defaultLocale.accountDetailsText,
),
achBankTransferText: Utils.getString(
res,
"achBankTransferText",
defaultLocale.achBankTransferText,
),
bankName: Utils.getString(res, "bankName", defaultLocale.bankName),
routingNumber: Utils.getString(res, "routingNumber", defaultLocale.routingNumber),
swiftCode: Utils.getString(res, "swiftCode", defaultLocale.swiftCode),
doneText: Utils.getString(res, "doneText", defaultLocale.doneText),
copyToClipboard: Utils.getString(res, "copyToClipboard", defaultLocale.copyToClipboard),
}
| None => defaultLocale
}
Expand Down
42 changes: 42 additions & 0 deletions src/hooks/ThemebasedStyle.res
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,13 @@ type themeBasedStyleObj = {
shadowColor: string,
shadowIntensity: float,
primaryButtonHeight: float,
disclaimerBackgroundColor: string,
disclaimerTextColor: string,
instructionalTextColor: string,
poweredByTextColor: string,
detailsViewTextKeyColor: string,
detailsViewTextValueColor: string,
silverBorderColor:string,
}

let darkRecord = {
Expand Down Expand Up @@ -251,6 +258,13 @@ let darkRecord = {
normalTextInputBoderColor: "rgba(204, 210, 226, 0.75)",
shadowColor: "black",
shadowIntensity: 2.,
disclaimerBackgroundColor: "#FDF3E0",
disclaimerTextColor: "#D57F0C",
instructionalTextColor: "#999999",
poweredByTextColor: "#111111",
detailsViewTextKeyColor: "#999999",
detailsViewTextValueColor: "#333333",
silverBorderColor:"#CCCCCC",
}
let lightRecord = {
primaryButtonHeight: 45.,
Expand Down Expand Up @@ -328,6 +342,13 @@ let lightRecord = {
normalTextInputBoderColor: "rgba(204, 210, 226, 0.75)",
shadowColor: "black",
shadowIntensity: 2.,
disclaimerBackgroundColor: "#FDF3E0",
disclaimerTextColor: "#D57F0C",
instructionalTextColor: "#999999",
poweredByTextColor: "#111111",
detailsViewTextKeyColor: "#999999",
detailsViewTextValueColor: "#333333",
silverBorderColor:"#CCCCCC",
}

let minimal = {
Expand Down Expand Up @@ -406,6 +427,13 @@ let minimal = {
normalTextInputBoderColor: "rgba(204, 210, 226, 0.75)",
shadowColor: "black",
shadowIntensity: 3.,
disclaimerBackgroundColor: "#FDF3E0",
disclaimerTextColor: "#D57F0C",
instructionalTextColor: "#999999",
poweredByTextColor: "#111111",
detailsViewTextKeyColor: "#999999",
detailsViewTextValueColor: "#333333",
silverBorderColor:"#CCCCCC",
}

let flatMinimal = {
Expand Down Expand Up @@ -484,6 +512,13 @@ let flatMinimal = {
normalTextInputBoderColor: "rgba(204, 210, 226, 0.75)",
shadowColor: "black",
shadowIntensity: 3.,
disclaimerBackgroundColor: "#FDF3E0",
disclaimerTextColor: "#D57F0C",
instructionalTextColor: "#999999",
poweredByTextColor: "#111111",
detailsViewTextKeyColor: "#999999",
detailsViewTextValueColor: "#333333",
silverBorderColor:"#CCCCCC",
}

let some = (~override, ~fn, ~default) => {
Expand Down Expand Up @@ -870,6 +905,13 @@ let itemToObj = (
~defaultProp=themeObj.shadowIntensity,
),
paymentSheetOverlay: themeObj.paymentSheetOverlay,
disclaimerBackgroundColor: themeObj.disclaimerBackgroundColor,
disclaimerTextColor: themeObj.disclaimerTextColor,
instructionalTextColor: themeObj.instructionalTextColor,
poweredByTextColor: themeObj.poweredByTextColor,
detailsViewTextKeyColor: themeObj.detailsViewTextKeyColor,
detailsViewTextValueColor: themeObj.detailsViewTextValueColor,
silverBorderColor:themeObj.silverBorderColor,
}
}

Expand Down
6 changes: 6 additions & 0 deletions src/icons/Icon.res

Large diffs are not rendered by default.

144 changes: 144 additions & 0 deletions src/pages/payment/ACHBankDetails.res
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
open ReactNative
open Style
open ThemebasedStyle

module DetailsView = {
@react.component
let make = (~title, ~value) => {
<View style={viewStyle(~flexDirection=#row, ~gap=5., ~alignItems=#center, ())}>
<Text style={textStyle(~fontSize=10., ~fontWeight=#400, ~color=useThemeBasedStyle().detailsViewTextKeyColor, ())}>
{React.string(title ++ ":")}
</Text>
<Text style={textStyle(~fontSize=12., ~fontWeight=#400, ~color=useThemeBasedStyle().detailsViewTextValueColor, ())}>
{React.string(value)}
</Text>
</View>
}
}

@react.component
let make = (~data: PaymentConfirmTypes.ach_credit_transfer) => {
let (clicked, setClicked) = React.useState(_ => false)
let handleSuccessFailure = AllPaymentHooks.useHandleSuccessFailure()
let localeObject = GetLocale.useGetLocalObj()
<View>
<View style={array([viewStyle(~flexDirection=#row, ~gap=8., ~alignItems=#center, ())])}>
<Icon name={"ach bank transfer"} height=20. width=20. />
<TextWrapper
textType={HeadingBold}
text=localeObject.achBankTransferText
overrideStyle=Some(Style.textStyle(~fontSize=16.0, ~fontWeight=#600, ()))
/>
</View>
<Space height=20.0 />
<View style={array([viewStyle(~flexDirection=#row, ~gap=4., ~alignItems=#center, ())])}>
<Icon name={"bank"} height=20. width=20. />
<TextWrapper
textType={HeadingBold}
text=localeObject.accountDetailsText
overrideStyle=Some(Style.textStyle(~fontSize=14.0, ~fontWeight=#600, ()))
/>
</View>
<Space height=6.0 />
<TextWrapper
textType={CardText}
text=localeObject.instructionalTextOfAchTransfer
overrideStyle=Some(Style.textStyle(~fontSize=12.0, ~fontWeight=#400, ~color=useThemeBasedStyle().instructionalTextColor, ()))
/>
<Space height=12.0 />
<View
style={viewStyle(
~paddingVertical=16.->dp,
~paddingHorizontal=14.->dp,
~borderRadius=8.,
~borderWidth=0.5,
~borderColor=useThemeBasedStyle().silverBorderColor,
~gap=12.,
(),
)}>
<DetailsView title=localeObject.accountNumberText value={data.account_number} />
<DetailsView title=localeObject.bankName value={data.bank_name} />
<DetailsView title=localeObject.routingNumber value={data.routing_number} />
<DetailsView title=localeObject.swiftCode value={data.swift_code} />
</View>
<Space height=18.0 />
<View
style={viewStyle(
~flexDirection=#row,
~gap=4.,
~paddingVertical=10.->dp,
~paddingHorizontal=12.->dp,
~borderRadius=8.,
~backgroundColor=useThemeBasedStyle().disclaimerBackgroundColor,
(),
)}>
<Icon name={"disclaimer"} height=20. width=20. />
<Text
style={textStyle(~fontSize=12., ~fontWeight=#400, ~lineHeight=18., ~color=useThemeBasedStyle().disclaimerTextColor, ())}>
{React.string(localeObject.disclaimerTextAchTransfer)}
</Text>
</View>
<Space height=28.0 />
<CustomButton
text={clicked ? localeObject.doneText : localeObject.copyToClipboard}
borderRadius=4.
onPress={_ => {
if clicked {
handleSuccessFailure(
~apiResStatus=PaymentConfirmTypes.defaultSuccess,
~closeSDK=true,
~reset=false,
(),
)
} else {
setClicked(_ => true)
let textToCopy =
localeObject.accountNumberText ++
" : " ++
data.account_number ++
"\n" ++
localeObject.bankName ++
" : " ++
data.bank_name ++
"\n" ++
localeObject.bankName ++
" : " ++
data.routing_number ++
"\n" ++
localeObject.swiftCode ++
" : " ++
data.swift_code
// let copyToClipboard = () => {
// Clipboard.setString(textToCopy)
RNClipboard.setString(textToCopy)
// }
}
}}
/>
<Space height=14.0 />
<View
style={viewStyle(
~flexDirection=#row,
~alignItems=#center,
~justifyContent=#center,
~gap=4.,
(),
)}>
<TextWrapper
textType={Heading}
overrideStyle={Some(
textStyle(~fontSize=10., ~fontWeight=#400, ~lineHeight=12., ~color=useThemeBasedStyle().poweredByTextColor, ()),
)}>
// {"powered by"->React.string}
{localeObject.poweredBy->React.string}
</TextWrapper>
// <TextWrapper
// textType={Heading}
// overrideStyle={Some(textStyle(~fontSize=12., ~fontWeight=#600, ~lineHeight=12., ()))}>
// {"hyperswitch"->React.string}
// </TextWrapper>
</View>
<CustomTouchableOpacity onPress={_ => ()} />
<Space height=8.0 />
</View>
}
1 change: 1 addition & 0 deletions src/pages/payment/ClickableTextElement.res
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ let make = (
let newSheetType = switch isSavedCardScreen {
| PAYMENTSHEET => PaymentScreenContext.SAVEDCARDSCREEN
| SAVEDCARDSCREEN => PaymentScreenContext.PAYMENTSHEET
| _ => PaymentScreenContext.PAYMENTSHEET
}
setSaveCardScreen(newSheetType)
}
Expand Down
Loading
Loading