ACH Payments
How a bank debit clears, where to take one, and how to read its status from submission through settlement or return.
An ACH payment is a debit instruction against a bank account, cleared through the banking network in batches. That single sentence explains most of what makes ACH feel different from a card: the outcome confirms over the following days rather than in the moment, and the clearing happens on the ACH processor's side. WinkPG tracks the whole journey for you and records every status change on the transaction as it arrives.
This guide covers where you can take an ACH payment, how to store a bank account for later use, and how to read an ACH transaction's status from submission through settlement or return.
How an ACH payment differs from a card payment
The most useful thing to internalise is that an ACH sale is one operation. There is no authorization step that reserves funds, so there is no hold to place, nothing to capture afterwards, and no separate settlement decision to make. You submit the debit, and the banking network clears it.
| Card | ACH | |
|---|---|---|
| Approval | An authorization places a hold at the issuer, answered in seconds | No authorization construct; the debit is submitted for clearing |
| Steps | Authorize, capture, settle | One sale, then clearing |
| Outcome timing | Approved in seconds, funds move at the next batch close | Confirmed over the following days |
| Where the status comes from | The WinkPG settlement batch | The ACH processor's clearing feed |
| After it succeeds | A refund creates a new linked transaction | The receiving bank can still return the debit |
Because clearing runs on the processor's side, an ACH transaction sits at a Pending settlement status while it is in flight, and a long-running Pending on an ACH payment is normal in a way it would not be on a card. ACH payments are also kept out of the card settlement pipeline entirely, so their absence from the open batch is expected and correct.
Before you take ACH payments
An active ACH-capable processor profile on the merchant is the one prerequisite. WinkPG builds each merchant's payment-method capability from its active processor profiles, so once an ACH-capable profile is in place the bank-account tender becomes available on the surfaces below, and the transaction API accepts ACH submissions for that merchant.
Hosted Payment Pages offer ACH when it is selected in the page's payment methods. Every page carries its own list of methods, and the public page renders only the tenders the merchant can actually process, so both halves have to line up: the merchant needs the capability and the page needs ACH selected. If you enable ACH capability on a merchant after a page was already saved, open that page and re-save it with ACH selected so the page offers it. The page editors show a notice when a saved method selection was reconciled against the merchant's current capabilities, which is your prompt to re-select.
Taking an ACH payment
From the Virtual Terminal
The Virtual Terminal's check entry collects the account details directly: Name On Check, Routing Number, Account Number, Check Number, and an Account Type of Checking or Savings.
Below the account fields, the Virtual Terminal captures how the debit was authorized. You pick one of two answers to "How was this debit authorized?":
- Telephone (TEL), for an authorization the account holder gave verbally during a call.
- Signed form (PPD), for an authorization the account holder gave on a signed written form.
Each choice renders the exact attestation statement you are confirming, and a checkbox records that you obtained the authorization described. This evidence is required: the server rejects a Virtual Terminal ACH submission that arrives without it, and the statement text is stored verbatim on the transaction alongside a hash of its wording, so the language that authorized a given debit stays reproducible. The obligations the statement describes stay with the merchant: audio-recording or confirming a telephone authorization in writing before settlement, and retaining a signed form for the required period.
One detail worth separating: the Standard Entry Class code sent to the processor comes from the merchant's ACH processor profile configuration. The choice above records how the account holder authorized the debit and is kept as evidence.
From a Hosted Payment Page
A page that offers ACH renders a bank-account tab with the same account fields, plus the NACHA WEB authorization statement the payer accepts before submitting. Internet-initiated debits are authorized under the WEB Standard Entry Class, and the statement is what carries that authorization.
WinkPG ships default authorization language and captures the rendered text verbatim with the transaction, together with a content hash so you can tell which version of the wording authorized a given debit. You can override the language per page. There are three separate defaults, and the page renders whichever fits the session: one for a single debit, one for a recurring arrangement, and one for saving an account with no charge.
From the API
The transaction create request accepts bank-account details in place of card details, and the result is the same ACH sale the two screens above produce. The merchant capability gate and the field rules below apply identically, so an integration and an operator get the same answers.
What gets validated
One rule set backs every surface, so the Virtual Terminal, the Hosted Payment Page, and the API cannot disagree about what a valid account looks like:
- The routing number is 9 digits and must pass the ABA checksum.
- The account number is 1 to 17 digits.
- An account type (checking or savings) must be selected.
Saving a bank account without charging it
You can store a bank account for future use without taking any money. Since ACH has no authorization construct, the save-only flow is best understood as verification plus vaulting rather than any kind of approval: WinkPG validates the account details internally against the rules above, and on success stores the account in the vault so it can be charged later with the payer's authorization. Nothing is submitted to the ACH network, and the account is stored only if the verification passes.
Two places do this:
- A save-only Hosted Payment Page session. The payer sees the storage authorization language, which states explicitly that saving the account does not debit it today and that any future debit is separately authorized. An approved save publishes the
HostedPaymentPage.AchSavedevent, so your systems can pick up the stored account as soon as it exists. - The back office, when you add a bank account to a customer record by hand. The verification runs before the account is vaulted, so an account that fails validation is reported to you and not stored.
Reading the ACH status lifecycle
An ACH transaction's settlement status is the field to watch. It starts at Pending and moves when the processor reports an outcome for that entry. Usually that is a single transition, from Pending to one of the terminal statuses below. The exception is a late return, where a transaction that already reads Settled moves again to SettlementRolledBack, which the next section covers.
| Stage | Settlement status | What it means |
|---|---|---|
| Submitted | Pending | The transaction was created and handed to the ACH processor, which now has it. |
| In flight | Pending | The processor is working the entry through its own states (accepted, verifying, originated, partially settled). These are recognised and expected, and the settlement status stays Pending until the outcome is final. |
| Cleared | Settled | The debit cleared. The money has moved. |
| Returned | SettlementRolledBack | The receiving bank returned the debit. The NACHA return code and reason are recorded on the transaction. |
| Voided | Not Eligible | The entry was voided on the processor's side before it was originated to the ACH network, so it was never presented. |
| Errored | Failed | The processor reported an error on the entry. |
Status updates arrive on a scheduled synchronization that runs several times a day, and a separate daily reconciliation sweep runs behind it as a safety net. Each change WinkPG picks up is applied to the transaction and published as a notification, so both the screen and your own systems see the same transition.
Returns
When a receiving bank refuses a debit, it returns it with a standard NACHA return code and a reason, and WinkPG records both on the transaction. The codes are the familiar ones: R01 for insufficient funds, R02 for an account closed, and so on. Reading the code tells you whether a retry is worth attempting or whether you need new account details from the customer.
A return can arrive after a debit has already reported as settled. That is a late return, and it is a normal part of how ACH works rather than a fault. WinkPG moves the transaction to SettlementRolledBack when it happens and flags the notification so you can tell a late return apart from one that arrived before settlement. The practical consequence for fulfilment is worth stating plainly: treat an ACH settlement as durable rather than as the last word, and weigh how long you wait against the value of the order.
Watching ACH from your own systems
Two subscribable events cover ACH, and both are available at merchant scope:
Transaction.AchStatusChangedfires on every ACH settlement-status change. The payload carries the transaction and merchant identifiers, the previous status, the new status, and, when the change is a return, the NACHA return code and reason.Transaction.Returnedfires specifically on a bank return. The payload carries the resulting settlement status, the return code and reason, the effective entry date when the processor supplies one, and a flag saying whether the return arrived after settlement.
Both event types can be filtered on Return Code, so a subscription can target the returns you actually want to act on (dunning on an insufficient-funds return, for example, while routing an account-closed return somewhere else).
The card settlement events do not apply to ACH. ACH clears on the processor's side rather than through the card batch pipeline, so Transaction.Settled is a card signal and these two events are the ACH equivalent. An integration that wants to know when an ACH debit is good should subscribe to Transaction.AchStatusChanged rather than waiting on a settlement event that will not arrive.
One thing to expect on a newly connected merchant: notifications begin with activity that happens after onboarding. The first synchronization brings the merchant's existing ACH history up to date so the transaction records are correct from day one, and it does that without generating notifications for those historical rows, so your endpoint is not flooded with events about payments that resolved long ago.
See also
- Transaction Lifecycle and Settlement for the card lifecycle this guide contrasts against, including what the settlement statuses mean across both tenders.
- Webhook Integration for receiving the ACH events above at your own endpoint, including the signature scheme and deduplication.
- Customers and Saved Payment Methods for the customer record a stored bank account is saved against, and the consent that lets you charge it again.
- Setting Up a Hosted Payment Page for creating the page and choosing the payment methods it offers.