# ACH payments and returns

> ACH is a US bank-to-bank debit. Unlike a card authorisation, which is confirmed in real time, an ACH debit is only accepted for processing when it is submitted

## How ACH works on USAePay

ACH is a US bank-to-bank debit. Unlike a card authorisation, which is confirmed in
real time, an ACH debit is only *accepted for processing* when it is submitted —
the customer's bank can return it days later for insufficient funds, a closed
account, or a dispute.

USAePay accepts the payment immediately and reports the return separately, so
the integration holds the transaction as **Pending** until it knows the outcome.

### What the customer enters

- Routing number
- Account number
- Account type — Checking or Savings

### Limitations

ACH on USAePay is **sale-only**:

- **USD only.** A non-USD ACH payment is rejected.
- **No saved bank accounts.** USAePay cannot tokenise a bank account, so an ACH
  payment method cannot be stored.
- **No recurring ACH.** With no stored payment method, ACH cannot be used for
  contracts or scheduled charges. Use cards for recurring payments on this gateway.
- **No authorise / capture / void.** ACH is a straight sale; refunds are supported.

## The transaction lifecycle

- **Payment submitted** — USAePay accepts the debit. The transaction is recorded as
  **Pending**, not Approved.
- **Settled** — the funds clear. The transaction is marked **Approved**.
- **Returned** — the customer's bank rejects the debit. The transaction is marked
  **Failed**, with the return reason recorded against it (for example
  `R01:Insufficient Funds`).

A hard decline at submission time — bad routing number, blocked account — fails
immediately, the same as a card decline.

### How the integration finds out

**Scheduled polling (always on).** The integration re-queries the payment on a schedule
until it reaches a final state. ACH cannot settle in less than a day, so the first
check is **48 hours** after the payment, then daily for up to 9 further checks —
roughly 11 days of cover. A payment that is still unresolved at the end of that is
marked **Unresolved** for manual review rather than being guessed at.

**Webhooks (optional, faster).** If you configure a USAePay webhook, the integration is
notified as soon as the payment settles or is returned, instead of waiting for the
next scheduled check. The webhook only acts as a trigger — the integration always re-reads
the authoritative status from USAePay before changing anything, because USAePay can
deliver events out of order.

Polling is the floor: if a webhook is missed, misconfigured, or fails its signature
check, the scheduled poll still reconciles the payment.

## Setting up the webhook (optional)

Webhooks are configured **per merchant account in the USAePay console** — there is
no API to register them, so this is a manual step for each merchant.

1. In the Merchant Portal (**Configure** > **Payment Processing**), open the
   USAePay connection settings and copy the
   **Webhook URL** shown under **Enable ACH / Bank Transfer**. Save the gateway
   first if the URL is not shown yet. The URL is specific to this gateway. Register
   it in the USAePay console that matches the gateway's **Sandbox** setting (sandbox
   or live), and register it again, with the new Signature Key, if you switch.
2. In the USAePay console, select **Settings**, then **Webhooks** (USAePay asks for
   two-factor authentication), and add a webhook pointing at that URL.
3. Set **Authentication** to *None* and **Signature** to *Signature Key*. USAePay
   generates a key beginning `wsig:`.
4. Subscribe the webhook to the ACH events `ach.settled`, `ach.returned`,
   `ach.voided` and `ach.failed`.
5. Copy the Signature Key into the **Webhook Signature Key** box in the
   USAePay gateway settings, including the `wsig:` prefix, and save.

The integration acts only on those four events. Each one prompts it to re-read the
payment's status from USAePay and update a pending or unresolved payment from that: **Approved**
once settled, **Failed** if returned, voided or failed. Other events, such as
`ach.submitted`, `ach.note_added` and
card transaction events, are acknowledged and ignored, so subscribing to them does
no harm.

The integration verifies the signature on every inbound webhook and ignores anything that
fails, so an incorrect key degrades to polling rather than corrupting a payment.

USAePay retries a failed delivery progressively over 72 hours and requires TLS 1.2.

## Enabling ACH

- Enable ACH on your USAePay account.
- In the Merchant Portal (**Configure** > **Payment Processing**), open the USAePay
  connection settings and turn on **Enable ACH / Bank Transfer**.
- If you take ACH payments by phone or through staff, choose the **ACH Type (MOTO)**
  your bank expects for them, for example *TEL* for one-off debits authorised over
  the phone.
- Select **Save**.
- Optionally set up the webhook and add the **Webhook Signature Key** (see above).

See [Connecting USAePay](/payment-providers/usaepay-connect/) for the rest of the connection
settings.