# 

## What is ACH

The Automated Clearing House (ACH) is a US payment network that processes electronic fund transfers between bank accounts. Unlike card payments that authorize in real time through card networks, ACH transactions are batched and cleared through the Federal Reserve or The Clearing House.

Paradise Gateway processes ACH payments through the **Vericheck** processor.

```mermaid
---
config:
  theme: 'neutral'
---
sequenceDiagram
    autonumber
    
    participant App as Your Application
    
    rect rgb(232, 241, 250)
        Note over App, GW: My Paradise Pay (Real-time)
        participant GW as My Paradise Pay
    end
    
    participant Proc as Processor (Vericheck)
    participant ACH as ACH Network
    participant Bank as Person's Bank

    App->>GW: POST /v1/transactions
    activate GW
    GW->>Proc: ACH Request
    activate Proc
    Proc-->>GW: Accepted (Synchronous)
    deactivate Proc
    GW-->>App: 200 OK (authorized)
    deactivate GW

    Note over Proc, Bank: Asynchronous Processing (1-3 Days)
    Proc->>ACH: Batch Submission
    activate ACH
    ACH->>Bank: Debit/Credit Request
    activate Bank
    Bank-->>ACH: Funds Settled
    deactivate Bank
    deactivate ACH
    Note right of Bank: OR Transaction Returned
```

## ACH transaction types

Paradise Gateway supports two ACH Standard Entry Class (SEC) codes that determine how the payment was authorized.

| SEC code | Name | Use case | Authorization method |
|  --- | --- | --- | --- |
| **WEB** | Internet-initiated | Person authorizes payment through a website or app | Online consent form, checkbox, or click-through agreement |
| **PPD** | Prearranged payment and deposit | Recurring payments authorized by written agreement | Signed authorization form (physical or electronic) |


SEC code compliance
Using the correct SEC code is a NACHA requirement. Using the wrong code can result in fines or ACH processing suspension. Use `WEB` for internet-originated transactions and `PPD` for pre-authorized recurring payments with a signed agreement.

## Processing an ACH payment

Send `POST /v1/transactions` with `type: PAYMENT` and the person's bank account details.

### Required fields

| Field | Description | Example |
|  --- | --- | --- |
| `type` | Transaction type | `PAYMENT` |
| `amount` | Amount in cents | `50000` (500.00 USD) |
| `payment_method.type` | Payment method type | `ACH` |
| `payment_method.account_number` | Bank account number | `9876543210` |
| `payment_method.routing_number` | ABA routing number (9 digits) | `021000021` |
| `payment_method.account_type` | Account type | `checking` or `savings` |
| `payment_method.name` | Account holder name | `Montgomery Scott` |
| `payment_method.email` | Account holder email | `scotty@example.com` |


### Example request

```shell cURL
curl -i -X POST \
  https://api.dev.paradisegateway.net/v1/transactions \
  -H 'Api-Key: YOUR_API_KEY_HERE' \
  -H 'Client-Id: CLIENT-01KFDKXMQ637EKEAY410MSQSXB' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "PAYMENT",
    "amount": 50000,
    "payment_method": {
      "type": "ACH",
      "account_number": "9876543210",
      "routing_number": "021000021",
      "account_type": "Checking",
      "name": "Montgomery Scott",
      "email": "scotty@example.com"
    },
    "recurring": false,
    "purchase_description": "Monthly service fee"
  }'
```

### Example response

```json
{
  "id": "TRANSACTION-03LPSC0TTY9ZXQ5MV0H4Y6W8A",
  "object": "transaction",
  "type": "payment",
  "transaction_state": "authorized",
  "response_status": "Approved",
  "response_code": "00",
  "response_message": "The API request is approved.",
  "amount_requested": 50000,
  "amount_authorized": 50000,
  "correlation_id": "d4e5f6a7-b8c9-0123-def0-123456789abc"
}
```

The transaction returns immediately with `authorized` state. This does not mean the funds have been transferred — the ACH network processes the debit asynchronously.

## ACH vs. card payment timeline

ACH transactions settle more slowly than card transactions because the ACH network processes in scheduled batches rather than in real time.

| Event | Card (TSYS) | ACH (Vericheck) |
|  --- | --- | --- |
| Authorization | Real-time (< 3 seconds) | Immediate API response (validation only) |
| Batch submitted | End of business day | Next business day |
| Funds settled | 1–2 business days | 2–3 business days |
| Returns possible | Not applicable (chargebacks instead) | Up to 60 days |


```mermaid
%%{init: { 'flowchart': { 'nodeSpacing': 180, 'rankSpacing': 100 } } }%%
flowchart LR
    %% Phases
    subgraph Day0 [Day 0]
        Req[[API Request]]
    end

    subgraph Day1 [Day 1]
        Proc{{Submit to ACH}}
    end

    subgraph Day2_3 [Day 2-3]
        Settle[/"Funds Settle"\]
    end

    subgraph Window [Days 3-60]
        Risk([Return Window])
    end

    %% Progression
    Req -->|"Synchronous"| Proc
    Proc -->|"Standard Rail"| Settle
    Settle -.->|"Consumer Right to Dispute"| Risk

    %% Styling (aligned with @theme/styles.css)
    classDef brand fill:#1D80C3,color:#fff,stroke:#022D4B,stroke-width:2px
    classDef accent fill:#F05A26,color:#fff,stroke:#022D4B,stroke-width:1px
    classDef neutral fill:#E8F1FA,color:#022D4B,stroke:#1D80C3,stroke-width:1px
    classDef alert fill:#FFF,stroke:#F05A26,stroke-width:2px,stroke-dasharray: 5 5

    class Req,Proc brand
    class Settle accent
    class Risk alert
```

## ACH returns

Unlike card chargebacks, ACH transactions can be **returned** by the receiving bank after settlement. Returns can happen for several reasons.

| Return code | Reason | Timeline |
|  --- | --- | --- |
| R01 | Insufficient funds | 2 business days |
| R02 | Account closed | 2 business days |
| R03 | No account / unable to locate | 2 business days |
| R04 | Invalid account number | 2 business days |
| R08 | Payment stopped | 2 business days |
| R10 | Customer advises not authorized | Up to 60 days |
| R29 | Corporate customer advises not authorized | 2 business days |


Handling returns
Because ACH returns can occur days or weeks after settlement, build your system to handle asynchronous return notifications. Monitor transaction status through `GET /v1/transactions/{id}` or configure webhooks to receive return notifications.

## ACH payouts

In addition to collecting payments, Paradise Gateway supports ACH payouts — sending funds **to** a bank account. Payouts use the same endpoint with a different transaction type.

| Direction | Transaction type | Description |
|  --- | --- | --- |
| Inbound (collect) | `payment` | Debit the person's bank account |
| Outbound (pay) | `payout` | Credit the person's bank account |


### Canceling ACH transactions

ACH transactions can be canceled before settlement using the cancel endpoint.

| Original type | Cancel type |
|  --- | --- |
| `payment` | `cancel` |
| `payout` | `cancel` |


After settlement, ACH reversals go through the ACH return process rather than API-initiated refunds.

## Tokenized ACH payments

To avoid storing sensitive bank account details, tokenize the bank account and use the payment token for subsequent transactions.

```json
{
  "type": "payment",
  "amount": 50000,
  "payment_method": {
    "type": "token",
    "payment_token": "PAYMENT_TOKEN-03LPSC0TTY0AYRNZ5VQXS2G3AB"
  },
  "recurring": true,
  "purchase_description": "Monthly service fee"
}
```

For more information, see [About tokenization](/docs/concepts/tokenization/what-is-tokenization).

## Best practices

* **Validate routing numbers** before submitting. Invalid routing numbers result in R03 or R04 returns.
* **Use the correct SEC code** (WEB for internet, PPD for recurring with signed authorization).
* **Handle returns asynchronously**. Do not treat the initial `authorized` response as final settlement.
* **Set `recurring: true`** for subsequent charges against a stored bank account to comply with NACHA rules.
* **Tokenize bank accounts** for recurring payments rather than storing raw account numbers.


## Further reading

* [About the transaction lifecycle](/docs/concepts/transactions/transaction-lifecycle)
* [About batch settlement](/docs/concepts/transactions/batch-settlement)
* [Supported processors](/docs/get-started/supported-processors)