Pay via ACH
Pay external bank accounts using the ACH network
Pay via ACH lets you send funds from a Passport Account to a bank account outside the Passport system through the ACH (Automated Clearing House) network.
This payout method supports multiple destination types, depending on who you are paying. Use a pre-linked External Account when sending money to your own bank account outside the system, use a Contact when sending money to another person or business outside the system, or use a one-time destination when you do not want to save the recipient in advance.
ACH is commonly used for vendor payments, payroll disbursements, and transfers from a Passport Account to an external bank account.
Use Pay via ACH when you need to send funds to a bank account in a cost-effective manner.
Common Use Cases:
- Transfer funds from a Passport Account to your own external bank account
- Pay vendors, suppliers, or service providers
- Disburse payroll to employees
- Pay saved Contacts
Prepare payout recipients
Before initiating an ACH payout, decide how you want to provide the destination bank account.
- Use External Accounts when sending funds to your own bank account outside the system and you want to save it for reuse.
- Use Add Payees as Contacts when sending funds to another person’s or business’s bank account outside the system and you want to reuse their saved payee details later.
- Use a one-time destination when you need to send funds to a bank account outside the system without saving it in advance.
This helps you choose the right destination type based on whether you are paying your own external account, a third-party recipient, or a one-time bank destination.
Create an ACH payout
Processing an ACH payout involves sending bank account details to the API and tracking the transaction lifecycle.
-
Make a
POSTrequest to/v1/customer/id/{id}/transaction(orexternalId) API endpoint with the required parameters:Parameter Required Description method✓ Set to ACHexternalIdOptional Your own reference ID for the transaction. Maximum 45 characters. typeOptional Type of transaction. Possible values: REGULAR. UseREFUNDonly when refunding a previously completed ACH payout. See Optional: Refund a completed ACH payout.source.account.id(orexternalId)✓ The Passport Account to be debited destination✓ Defines the bank account to be credited. Refer to the Destination Types accordion below for supported options. amount✓ Amount to send (in USD) purpose✓ Purpose of the transaction. Maximum 128 characters.
Destination Types
Pre-linked External Account
Use this option when you want to send money from a Passport Account to your own bank account outside the Passport system.
Pre-linked External Accounts are best for transfers to bank accounts that belong to you and are already saved within the system. If you have not added the destination bank account yet, first create it in External Accounts.
| Parameter | Required | Description |
|---|---|---|
destination.externalAccount.id or externalId | ✓ | Identifier of the linked external account |
Best for:
- Transferring funds to your own external bank account
- Reusing your previously linked bank account for repeat payouts
One-time destination
Use this option when sending money to a bank account outside the Passport system without saving it in advance.
This is useful when you need to make a one-off payout and do not want to first add the bank account as an External Account, or save the recipient as a Contact.
| Parameter | Required | Description |
|---|---|---|
destination.externalAccount.holderName | ✓ | Name of the bank account holder as it appears on bank records |
destination.externalAccount.accountNumber | ✓ | The bank account number to be credited |
destination.externalAccount.routingNumber | ✓ | 9-digit routing number of the account |
destination.externalAccount.type | Type of bank account. Possible values: SAVING, CHECKING | |
destination.externalAccount.holderType | Type of account holder. Possible values: CONSUMER, CORPORATE |
Best for:
- One-off payments to new or unregistered recipients
- Situations where you do not want to save the destination for future use
Payee added as Contact
Use this option when you want to send money from a Passport Account to another person’s or business’s bank account outside the Passport system.
Contacts are best for third-party recipients that you pay repeatedly, such as vendors, contractors, employees, or other external payees. If you have not created the recipient yet, first add them in Add Payees as Contacts.
| Parameter | Required | Description |
|---|---|---|
destination.contact.id or externalId | ✓ | Unique identifier of the Contact assigned by Passport |
destination.contact.externalAccount.id or externalId | ✓ | Unique identifier of the External Account linked to the Contact |
Best for:
- Paying another person or business outside the system
- Reusing saved third-party payee details for repeat ACH payouts
-
You can also pass the
processingDetailobject, which carries additional processing instructions for your transaction. While optional as a whole, certain fields within it may be required depending on your Program Manager configuration.Parameter Required Description processingDetail.processingModeRecommended Processing mode for the transaction. Possible values: FORWARD(default) – Settles next business day (end-of-day batch);SAME_DAY– Settles same day if submitted before cutoff, else next business day.processingDetail.companyNameRecommended The payee name populated in the NACHA file. Defaults to Program Manager configuration if not provided. Maximum 16 characters. processingDetail.companyDescriptionRecommended Short description shown on the recipient's bank statement. Common examples: PAYROLL,PURCHASE. Defaults to Program Manager configuration if not provided. Maximum 10 characters. Per NACHA rules (effective March 20, 2026), set toPAYROLLfor PPD credit transactions for wages or salaries, andPURCHASEfor WEB debit transactions authorized for online consumer purchases.processingDetail.authTypeConditional Authorization type for the transaction. Possible values: WRITTEN– Signed authorization;PHONE– Recorded call authorization;ONLINE– Digital or web authorization. Mandatory if no default is configured at the Program Manager level.processingDetail.addendaRecommended Additional reference data for reconciliation. Examples: Invoice number, customer reference ID, order ID. Maximum 80 characters. processingDetail.location.idUnique identifier of a location to be linked to the transaction, assigned by Passport. -
Once the request is submitted, our system performs a series of system-level validations before sending the transaction for processing. These validations check for:
- Missing or invalid required fields
- Incorrect parameter formats or values
- Program Manager configuration or permission issues
If any validation fails, the request is rejected immediately and an error response is returned. You must correct the issue and resubmit the request. For a complete list of validation errors and how to resolve them, refer to the Error Codes & Messages section.
-
If all validations pass, the transaction is submitted for processing. You can track the outcome by:
- Retrieving the transaction via GET
/v1/customer/id/{id}/transaction/id/{id}(orexternalId) API endpoint - Subscribing to Transaction webhooks
Check the
statusfield to understand the current state of the transaction. - Retrieving the transaction via GET
-
For every successfully created transaction, store:
id– Unique transaction identifier assigned by PassportexternalId– Your reference identifier (if provided)
These are required for tracking, reconciliation, and any follow-up actions such as cancellations.
Optional: Refund a completed ACH payout
Use this flow when you need to refund a previously completed ACH payout.
To refund a previously completed ACH payout, set type to REFUND and reference the original transaction using processingDetail.parent.id. Source and destination do not need to be passed for refund transactions because the system derives them from the parent transaction.
| Parameter | Required | Description |
|---|---|---|
type | ✓ | Set to REFUND |
method | ✓ | Set to ACH |
amount | ✓ | Amount to refund, in USD |
purpose | ✓ | Purpose of the refund |
processingDetail.parent.id | ✓ | The id of the original transaction being refunded |
processingDetail.achRefundCompanyName | Company name to be populated in the NACHA file for the refund | |
processingDetail.achRefundCompanyDescription | Company description to be populated in the NACHA file for the refund | |
reason | Reason for the refund. For example: ON_CUSTOMER_REQUEST |
Example Request
{
"method": "ACH",
"type": "REFUND",
"processingDetail": {
"achRefundCompanyName": "AMEX LTD",
"achRefundCompanyDescription": "756766876",
"parent": {
"id": "3317"
}
},
"amount": "05.00",
"purpose": "Card Refund",
"reason": "ON_CUSTOMER_REQUEST"
}Transaction Statuses
The table below describes the possible statuses of an ACH Send transaction and the reasons associated with each.
| Status | Description | Reason |
|---|---|---|
SCHEDULED | Default status upon transaction creation. | ON_USER_REQUEST |
PENDING | Transaction is on hold as one or more processing conditions are not met. This may include inactive accounts, insufficient funds, or pending compliance checks. | EXTERNAL_ACCOUNT_BLOCKEDEXTERNAL_ACCOUNT_INACTIVEACCOUNT_INACTIVEACCOUNT_BLOCKEDACCOUNT_CLOSURE_INITIATEDACCOUNT_CLOSEDCUSTOMER_SUSPENDEDOFAC_STATUS_NOT_VERIFIED |
PROCESSING | Transaction has been picked up for processing and is in transit. | PROCESSING_IN_TRANSIT |
COMPLETED | Funds have been successfully credited to the destination account after settlement. | PROCESSED_BY_SYSTEM |
FAILED | Transaction could not be completed due to processing failure or bank return. | EXTERNAL_ACCOUNT_BLOCKEDEXTERNAL_ACCOUNT_INACTIVEINSUFFICIENT_FUNDSOFAC_VERIFICATION_FAILED<return-description> (<return-code>) |
CANCELLED | Transaction was cancelled before processing was completed. | ON_USER_REQUESTINCORRECTLY_CREATEDOTHERS |
Best Practices
| Practice | Description |
|---|---|
| Verify destination details | For one-time payments, ensure the account and routing numbers are accurate to avoid failures or misrouted funds. |
| Use the correct authorization type | Pass processingDetail.authType (WRITTEN, PHONE, ONLINE) to reflect how authorization was obtained. |
| Set meaningful NACHA descriptors | Populate processingDetail.companyName and processingDetail.companyDescription for clear identification on the recipient’s bank statement. |
| Use addenda for reconciliation | Include invoice numbers or reference IDs using processingDetail.addenda to simplify reconciliation. |
| Use webhooks for tracking | Subscribe to transaction webhooks to receive real-time status updates without polling. |
| Test thoroughly in sandbox | Validate all scenarios, including failures and returns, before going live. |
Updated 25 minutes ago