ACH via Stripe: Headless Guide
Integrate ACH via Stripe on your website or mobile application and fully customize your checkout experience using your own UI.
Before you begin
This guide assumes that you know how to:
Accept payments with ACH via Stripe
Prepare the client session
ACH via Stripe requires the following data to process a payment successfully. Pass the following data in the client session, or in the payment request (for manual payment creation).
Parameter Name | Required | Description |
---|---|---|
currencyCode | ✓ | 3-letter currency code in ISO 4217 format. For Stripe ACH only USD is supported. |
order ↳ lineItems | ✓ | Details of the line items of the order |
metadata | ✓ | In order to have Stripe ACH successful, you need to pass your device info: IP address and user agent in the metadata.metadata.deviceInfo.ipAddress and metadata.deviceInfo.userAgent |
paymentMethod | ✓ |
That should be passed if one wishes to vault ACH via Stripe.
Prepare the SDK for payments
Handle payment method
Spirit of Cadeau requires instance of Redirect Manager in order to be presented to the user:
STRIPE_ACH
must be returned as PaymentMethod.type
in the onAvailablePaymentMethodsLoad
callback.
When the user has selected the payment method, call the start
function. This function automatically:
- opens a popup to present a loading indicator, then the payment method web page
- shows an overlay on top of your page that prompts the user to focus on the popup
This code is intended solely for illustrative purposes. As many redirect payment methods share a common approach, it is recommended to centralize the implementation of these methods within your codebase. For a practical demonstration of how to achieve this, please refer to the guide on how to handle Native UI payment methods.
Handle payment method
Spirit of Cadeau requires instance of Redirect Manager in order to be presented to the user:
STRIPE_ACH
must be returned as PaymentMethod.type
in the onAvailablePaymentMethodsLoad
callback.
When the user has selected the payment method, call the start
function. This function automatically:
- opens a popup to present a loading indicator, then the payment method web page
- shows an overlay on top of your page that prompts the user to focus on the popup
This code is intended solely for illustrative purposes. As many redirect payment methods share a common approach, it is recommended to centralize the implementation of these methods within your codebase. For a practical demonstration of how to achieve this, please refer to the guide on how to handle Native UI payment methods.
Pre-requisites
Integration
PrimerHeadlessUniversalCheckout.AchManager is an SDK manager designed to streamline the headless integration with ACH providers like Stripe. You will be using it alongside PrimerHeadlessUniversalCheckoutDelegate to handle ACH via Stripe payments in your project.
To integrate ACH via Stripe in your project, follow these steps:
Pass device info when creating the client session
ACH via Stripe requires that a mandate is accepted before the payment is completed.
Mandates that are accepted online require IP address and user-agent of the device that the payment is made from.
Specify this information when creating the client session, otherwise payments will remain in Pending state.
Define the Primer Stripe dependency
In order to be able to use ACH via Stripe you will have to install PrimerStripeSDK
which is available via CocoaPods.
Define the Stripe publishable key
When starting the headless universal checkout, it is important that you specify your Stripe publishable key when instantiating PrimerSettings
, otherwise you’ll get validation errors when interacting with the payment manager.
Create a new instance of StripeAchUserDetailsComponent
ACH via Stripe requires specific user details for payment handling. It is expected that you have a screen that allows entry of these details. In the context of this screen you can fetch an instance of StripeAchUserDetailsComponent
via PrimerHeadlessUniversalCheckout.AchManager
that can be assigned the details that the user enters.
Although the component collects user details pertaining to ACH, it also handles tokenization and payment processes. Because of this, it should be kept in memory until the checkout is completed.
Ensure that the screen that owns this component is not dismissed until the payment is finished, as the component returned by the manager is optional. As a result, having a weak reference to it will stop the entire payment flow if the screen is dismissed prematurely.
Listen for the emitted data
Conform to the stepDelegate in order to be notified about the state of the payment process:
Listen to the data validation statuses
This component allows you to collect and validate details such as the user’s first name, last name and email address.
It’s worth mentioning that the data validation is designed to operate in real-time. This means that the accuracy and completeness of the collected data can be confirmed even while users are actively inputting their information. This real-time validation feature ensures that your data remains accurate and complete throughout the data entry process, enhancing the user experience and the reliability of the collected data.
Conform to the validationDelegate to handle any validation statuses that may occur.
Start the flow of the component
Call the start function in order to start the flow of the component:
Once called, the retrievedUserDetails
step will be emitted. As mentioned previously, the retrievedUserDetails
step contains user details previously passed during the client session creation process. Use these details to prefill the fields on your user detail collection screen, offering users the convenience of reviewing and potentially modifying their information as needed.
Handle user data collection
As mentioned previously, the component allows you to collect the user’s first name, last name and email address. Note that all these details are supposed to be set before submitting the component via the submit function.
It is recommended that you update these with every user input to each of your text fields so that validation is provided as quickly as possible.
When the collected user details are deemed valid, as determined by the validationDelegate method, you are ready to initiate the tokenization process.
This action triggers the didCollectUserDetails
step, after which you should transition away from the user details collection screen.
Handle primerHeadlessUniversalCheckoutDidReceiveAdditionalInfo
calls
Once the user data collection component emits the didCollectUserDetails
step, you are expected to handle calls to primerHeadlessUniversalCheckoutDidReceiveAdditionalInfo in your PrimerHeadlessUniversalCheckoutDelegate implementation in order to continue with the payment process. Doing so will allow you to submit the mandate authorization, a process required for all Stripe ACH payments.
For a more comprehensive understanding, refer to the documentation available for the PrimerHeadlessUniversalCheckoutDelegate
protocol.
Handle component errors You can conform to the errorDelegate to handle any errors that may occur during user details collection or tokenization:
The errorDelegate
is a protocol
that emits PrimerError
objects, allowing you to identify and respond to any errors that occur during the payment process.
Vaulting
ACH via Stripe payment tokens can be vaulted automatically on successful agreement if the vaultOnAgreement
flag is turned on when creating the client session. Note that the vaultOnAgreement
flag is supported starting with API version 2.4.
This allows you to later access the payment information via the Vault Manager’s fetchVaultedPaymentMethods function. You may use bankName
and accountNumberLast4Digits
from returned the paymentInstrumentData to render your saved payment method.
Making payments with vaulted ACH via Stripe
User details are stored alongside payment information in the vault so the usage of StripeAchUserDetailsComponent
described earlier does not apply when utilizing Stripe ACH via Vault.
To allow payments with a vaulted payment token, use the Vault Manager as usual (fetch the payment methods then perform the payment).
Handle payment method ACH via Stripe requires a Native UI Manager in order to be presented to the user:
This code is intended solely for illustrative purposes. As many redirect payment methods share a common approach, it is recommended to centralize the implementation of these methods within your codebase. For a practical demonstration of how to achieve this, please refer to the guide on how to handle Native UI payment methods.
Handle payment method
PrimerHeadlessUniversalCheckoutAchManager is an SDK manager designed to streamline the headless integration with ACH providers like Stripe. You will be using it alongside PrimerHeadlessUniversalCheckoutListener to handle ACH via Stripe payments in your project.
To integrate ACH via Stripe in your project, follow these steps:
Pass device info and payment type when creating the client session
ACH via Stripe requires that a mandate is accepted before the payment is completed. Mandates that are accepted online require IP address and user-agent of the device that the payment is made from.
Specify this information when creating the client session, otherwise payments will remain in Pending state.
Define the Primer Stripe dependency
Amend the dependencies section of your app’s build.gradle
to include Primer’s stripe-android
library:
Define the Stripe publishable key
When starting the headless universal checkout, it is important that you specify your Stripe publishable key when instantiating PrimerSettings
, otherwise you’ll get validation errors when interacting with the payment manager.
Create a new instance of StripeAchUserDetailsComponent
ACH via Stripe requires specific user details for payment handling. It is expected that you have a screen that allows entry of these details. In the context of this screen you can fetch an instance of StripeAchUserDetailsComponent
via PrimerHeadlessUniversalCheckoutAchManager
that can be assigned the details that the user enters.
Here viewModelStoreOwner could point to the current activity or fragment.
Although the component collects user details pertaining to ACH, it also handles tokenization and payment processes. Because of this, it should be kept in memory until the checkout is completed. This component implements Android’s ViewModel
class, therefore keeping a reference to it is not enough. Instead, pass a long lifecycle ViewModelStoreOwner
when you initialize PrimerHeadlessUniversalCheckoutAchManager
, such as that of your activity or parent fragment.
Listen for the emitted data
Subscribe to the componentStep Flow
in order to be notified about the state of the process:
Listen to the data validation statuses
This component allows you to collect and validate details such as the user’s first name, last name and email address.
It’s worth mentioning that the data validation is designed to operate in real-time. This means that the accuracy and completeness of the collected data can be confirmed even while users are actively inputting their information. This real-time validation feature ensures that your data remains accurate and complete throughout the data entry process, enhancing the user experience and the reliability of the collected data.
Listen to the componentValidationStatus to handle any validation statuses that may occur.
Start the flow of the component
Call the start function in order to start the flow of the component:
Once called, the UserDetailsRetrieved
step will be emitted. As mentioned previously, the UserDetailsRetrieved
step contains user details previously passed during the client session creation process. Use these details to prefill the fields on your user detail collection screen, offering users the convenience of reviewing and potentially modifying their information as needed.
Handle user data collection
As mentioned previously, the component allows you to collect the user’s first name, last name and email address. Note that all these details are supposed to be set before submitting the component via the submit function.
It is recommended that you update these with every user input to each of your text fields so that validation is provided as quickly as possible.
When the collected user details are deemed valid, as determined by the componentValidationStatus Flow
, call the submit function to initiate the tokenization process.
This action triggers the emission of the UserDetailsCollected
step, after which you should transition away from the user details collection screen.
Handle Headless Universal Checkout Listener calls
Once the user data collection component emits the UserDetailsCollected
step, interaction with the component is over, and you are expected to handle calls in your Headless Universal Checkout Listener implementation in order continue with the payment process. Doing so will allow you to submit the mandate authorization, process required for all Stripe ACH payments.
Start by overriding onCheckoutAdditionalInfoReceived to handle the mandate.
Next, override onCheckoutCompleted in order be notified about payment completion.
Errors that occur during mandate confirmation will be emitted via onFailed. Override this callback in order be notified about mandate confirmation failures.
For a more comprehensive understanding, refer to the documentation available for the PrimerHeadlessUniversalCheckoutListener
interface.
Handle component errors
You can listen to the componentError Flow
to handle any errors that may occur during user details collection or tokenization:
The componentError
is a Flow
that emits PrimerError
objects, allowing you to identify and respond to any errors that occur during the payment process.
Vaulting
ACH via Stripe payment tokens can be vaulted automatically on successful agreement if the vaultOnAgreement
flag is turned on when creating the client session. Note that the vaultOnAgreement
flag is supported starting with API version 2.4.
This allows you to later access the payment information via the Vault Manager’s fetchVaultedPaymentMethods function. You may use bankName
and accountNumberLast4Digits
from returned the paymentInstrumentData to render your saved payment method.
Making payments with vaulted ACH via Stripe
User details are stored alongside payment information in the vault so the usage of StripeAchUserDetailsComponent
described earlier does not apply when utilizing ACH via Stripe with the Vault.
To allow payments with a vaulted payment token, use the Vault Manager as usual ([fetch the payment methods](fetch the payment methods) then perform the payment).
Pre-requisites
Integration
AchManager is an SDK manager designed to streamline the headless integration with ACH-based payment methods. To integrate AchManager
, follow these steps:
Pass device info and payment type when creating the client session ACH via Stripe requires that a mandate is accepted before the payment is completed. Mandates that are accepted online require IP address and user-agent of the device that the payment is made from.
Specify this information when creating the client session, otherwise payments will remain in Pending state.
Define the Primer Stripe dependency
Amend the dependencies section of your app’s build.gradle to include Primer’s stripe-android library:
// TODO: add section for iOS dependencies
Define the Stripe publishable key
When preparing the headless universal checkout, it is important that you specify your Stripe publishable key when instantiating PrimerSettings
, otherwise you’ll get validation errors when interacting with the payment manager.
Create a new instance of AchManagerProps
Create a new instance of StripeAchUserDetailsComponent
Listen for the emitted data
Make use of AchManagerProps.onStep in order to be notified about the user details collection state.
Listen to the data validation statuses
This component allows you to collect and validate details such as the user’s first name, last name and email address. It’s worth mentioning that the data validation is designed to operate in real-time. This means that the accuracy and completeness of the collected data can be confirmed even while users are actively inputting their information. This real-time validation feature ensures that your data remains accurate and complete throughout the data entry process, enhancing the user experience and the reliability of the collected data.
Use AchManagerProps validation callbacks to handle any validation statuses that may occur.
Start the flow of the component
Call the start function in order to start the flow of the component.
Once called, the UserDetailsRetrieved
step will be emitted. As mentioned previously, the UserDetailsRetrieved
step contains user details previously passed during the client session creation process. Use these details to prefill the fields on your user detail collection screen, offering users the convenience of reviewing and potentially modifying their information as needed.
Handle user data collection
As mentioned previously, the component allows you to collect the user’s first name, last name and email address. Note that all these details are supposed to be set before submitting the component via the submit function.
It is recommended that you update these with every user input to each of your text fields so that validation is provided as quickly as possible.
When the collected payment options are deemed valid, as determined by a call to AchManagerProps.onValid
, call the submit
function to initiate the tokenization process.
This action triggers the emission of the UserDetailsCollected
step, after which you should transition away from the user details collection screen.
Handle onCheckoutAdditionalInfo
calls
Handle Headless Universal Checkout Listener calls
Once the user data collection component emits the UserDetailsCollected
step, you are expected to handle calls to onCheckoutAdditionalInfo in order continue with the payment process. Doing so will allow you to submit the mandate authorization, process required for all Stripe ACH payments.
Once the user data collection component emits the UserDetailsCollected
step, interaction with the component is over, and you are expected to handle calls in your Headless Universal Checkout Listener implementation in order continue with the payment process. Doing so will allow you to submit the mandate authorization, process required for all Stripe ACH payments. You’ll also be notified about payment completion or failure.
Start by overriding onCheckoutAdditionalInfo to handle the mandate.
Next, override onCheckoutComplete in order be notified about payment completion.
Errors that occur during mandate confirmation will be emitted via onError. Override this callback in order be notified about mandate confirmation failures.
For a more comprehensive understanding, refer to the documentation available for the PrimerSettings
interface.
Handle component errors
Make use of AchManagerProps.onError to handle any errors that may occur during the user details collection flow:
Vaulting
ACH via Stripe payment tokens can be vaulted automatically on successful agreement if the vaultOnAgreement
flag is turned on when creating the client session.
This allows you to later access the payment information via the Vault Manager’s fetchVaultedPaymentMethods
function. You may use bankName
and accountNumberLast4Digits
from returned the paymentInstrumentData to render your saved payment method.
Making payments with vaulted ACH via Stripe
User details are stored alongside payment information in the vault so the usage of StripeAchUserDetailsComponent
described earlier does not apply when utilizing Stripe ACH via Vault.
To allow payments with a vaulted payment token, fetch the vaulted payment methods as usual (VaultManager.fetchVaultedPaymentMethods()
) then perform the payment (VaultManager.startPaymentFlow(vaultedPaymentMethodId: string)
).
Go live
You don’t need to do anything particular to go live — just make sure to use production credentials.
Handle payment method ACH via Stripe requires a Native UI Manager in order to be presented to the user:
This code is intended solely for illustrative purposes. As many redirect payment methods share a common approach, it is recommended to centralize the implementation of these methods within your codebase. For a practical demonstration of how to achieve this, please refer to the guide on how to handle Native UI payment methods.
Test
You can test payments using USD as the currency.
Sandbox testing
- After selecting the payment method button in the Checkout, the page will navigate to a form
- After you complete the form, the Stripe pop-up will appear
- After finishing the steps inside the Stripe pop-up, the user will be taken back to the Checkout to confirm / decline mandate
- At the end of this flow, the payment status will be first PENDING in the Primer Dashboard and depending on the user actions or external factors, like insufficient funds in the bank account, it will be either DECLINED, CANCELLED or SETTLED for successful completion in Primer Dashboard
- To simulate the receiving of funds and transition the payment to SETTLED, you can choose in the Stripe pop-up:
Test Institution
andSuccess
account in the next screen. Next you will be taken back to Checkout to confirm the mandate. Primer will receive a webhook and subsequently update the payment to SETTLED.
Go live
You don’t need to do anything particular to go live — just make sure to use production credentials.