-
Notifications
You must be signed in to change notification settings - Fork 7
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 debit #162
base: main
Are you sure you want to change the base?
Conversation
status: "failed", | ||
}, | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add this in else
user_agent: ?nativeProp.hyperParams.userAgent, | ||
}, | ||
}, | ||
// mandate_type: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove unwanted code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Everything fine, remove those suggestions
@@ -88,6 +97,17 @@ type customer_acceptance = { | |||
accepted_at: string, | |||
online: online, | |||
} | |||
// type metadata = {frequency: string} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove unwanted comment
src/hooks/AllPaymentHooks.res
Outdated
if paymentMethod->Option.getOr("") == "ach" { | ||
responseCallback( | ||
~paymentStatus=ProcessingPayments(None), | ||
~status={ | ||
message: "Bank Debit Payment Method: Transactions through this method typically take 1-4 business days to process. Please ensure a valid descriptor code, starting with 'SM,' is provided to initiate the payment successfully.", | ||
code: "", | ||
type_: "", | ||
status: "failed", | ||
}, | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why you are closing the SDK with failed status. Isn't this the happy flow?
Returning the status as "failed" to merchant will be not be correct in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@manideepk90 and i thought to add new status as pending.
discussed with akash
~errorCallback, | ||
~processor, | ||
~paymentMethod=?, | ||
) => { | ||
BrowserHook.openUrl(openUrl, nativeProp.hyperParams.appId, intervalId) | ||
->Promise.then(res => { | ||
if res.error === Success { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sh-iv-am can we do some refactoring in BrowserHook? . This promise should resolve with a proper object.
This promise is currently resolved with the following object in case of success in BrowserHook.res
let browserRes = {
paymentID: (resP[1]->Option.getOr("")->String.split("="))[1]->Option.getOr(""),
amount: am,
error: Success,
}
@manideepk90 @Pradeep-kumar1202 please look into this and make a proper type for this object. The key name can be something else here. error:Success
doesn't make any sense here.
type customValidationFunc = | ||
| Error(string) | ||
| OtherValidation | ||
| NoError |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems if customValidationFunc is passed you need to call it. Can it be done by making customValidationFunc an optional prop? Instead of making it's type a complex variant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function is optional, but we need to validate only some data, other data should follow the default data, if we pass a function it will validate all data and this will fail. so we decided to use a variant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variant is needed as per @manideepk90 suggestion or else we need to validate externally if we pass the function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make it more readable. The function i.e. customValidationFunc should be an optional prop in this component which return a variant based on validation. We can connect regarding this if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure let's connect tomorrow
let tempValid = switch switch customValidationFunc { | ||
| Some(validation) => | ||
validation( | ||
~text, | ||
~field_type=required_fields_type.field_type, | ||
~display_name=Some(required_fields_type.display_name), | ||
) | ||
| None => OtherValidation | ||
} { | ||
| Error(errorMessage) => Some(errorMessage) | ||
| OtherValidation => | ||
RequiredFieldsTypes.checkIsValid( | ||
~text, | ||
~field_type=required_fields_type.field_type, | ||
~localeObject, | ||
) | ||
| NoError => None | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactor this if it can be done without a variant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
bro, we need this for default validation. or else we need to call the default validation from here only
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i am working on bacs, sepa and becs. which have same fields like account number but different validations. such that passing a optional function will not be a good idea.
0f56aa7
to
50f389f
Compare
Description
Integrated ACH Debit with
dynamicFields
support.Passing of mandate data should be done from redirect.res as the customer_acceptance object should be inside the
mandate_data object.
Mandate_data object has been taken from the Hyperswitch API reference.
NOTE: The mandate_type should be passed from create-payment-intent
Validations:
These are validated by a
customValidationFunc
for validation and for user input restriction by usingcustomOnChangeFunc
Added Local Strings for validations
Please enter valid X digits Bank Routing Number.
Please enter valid details.
NOTE: The
localeStrings
are taken reference from ChatGPT and copilotAdded icons for ach debit, which can be moved to maven central.
Users need to manually close the web/redirect page in order to see the status i.e.,
Payment Pending - the status will be updated after 1-4 days
usually this flow takes 1-4 days for confirmation.Note
If the user cancels/closes the page without entering the data will also show the status as
Payment Pending - the status will be updated after 1-4 days
.ACH Debit payment flow video :
ACH_Debit_Payment_flow.mp4
Final Message after completing the payment :
About ACH micro deposits
The ACH debit payment flow uses microdeposits for user authentication instead of a synchronous redirection URL like Card 3DS. Stripe deposits small amounts into the user’s bank account, including a 4-character alphanumeric descriptor code (prefixed with
"SM."
) that the user must enter for verification. Upon successful entry, the event"elements.payment_intent_verify_microdeposits.success"
is triggered, confirming ownership and updating the payment status. This flow ensures secure and asynchronous account verification, adhering to Stripe's API requirements for ACH payments. Reference: Stripe ACH Direct Debit.