> ## Documentation Index
> Fetch the complete documentation index at: https://flutterwaveinc.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# ACH Payment

> Learn how you can accept payment with ACH.

<Info>
  We recommend checking out the [introductory section](/payment-api/introduction)
  to understand the basics of direct charge first. This guide assumes you've
  read that.
</Info>

## Charging bank accounts

Direct account charge allows you to collect payments directly from your customers' bank accounts.

There are three "flavours" of direct bank account charges, depending on the bank account's currency/country:

1. Direct debit (for Nigerian accounts): The customer authorizes the payment with their bank, and the money is debited from their account.
2. UK (GBP accounts): The customer logs in to their bank's Internet/mobile banking and makes a transfer to a generated bank account.
3. ACH payment (for USD and ZAR accounts).

This guide covers ACH payments. See the guides for [NG accounts](/payment-api/bank-accounts/nigeria) and [UK accounts](/payment-api/bank-accounts/uk-and-eu).

<Warning>
  **Approval Required**

  To receive payments from US accounts, your merchant account needs to be approved. Contact us at [hi@flutterwavego.com](mailto:hi@flutterwavego.com) for approval.
</Warning>

## The Process

To charge a bank account in the US or South Africa:

1. You send the payment details to the charge endpoint.
2. The customer then makes the transfer from their bank's Internet banking platform, and we notify you when it's done.
3. You can then call our API to verify that the payment was successful before giving value (the verify transaction endpoint).

<img src="https://mintcdn.com/flutterwaveinc/8LJ4mpYLmd_SNb9Z/images/ach.png?fit=max&auto=format&n=8LJ4mpYLmd_SNb9Z&q=85&s=8826ae9645e8290193e2999f4d044fd1" alt="ach" width="5760" height="10668" data-path="images/ach.png" />

## Initiating the Payment

To initiate the charge, you'll need to specify `amount`, `currency`, `email`, and a unique `tx_ref`. You can also specify additional information like customer's `phone_number` and custom `meta` information.

<Warning>
  **Selecting Supported Currencies and Banks**

  This payment method only supports `USD` and `ZAR` payments.

  For South African ACH payments, you can specify the bank by passing `sa_bank_code` in your payment request. Please retrieve the correct bank code from the [get banks endpoint](/api-reference/banks/get-all-banks).
</Warning>

Next, you'll end these payment details to the [charge via ACH endpoint](/api-reference/charges#ach-payments). Here are some examples with our SDKs:

<CodeGroup>
  ```javascript Node.js theme={null}
  // Install with: npm i flutterwave-node-v3

  const Flutterwave = require('flutterwave-node-v3');
  const flw = new Flutterwave(
  	process.env.FLW_PUBLIC_KEY,
  	process.env.FLW_SECRET_KEY
  );
  const payload = {
  	amount: 250,
  	currency: 'USD',
  	email: 'user@example.com',
  	tx_ref: this.generateTransactionReference(),
  };
  await flw.Charge.ach(payload);
  ```

  ```php PHP theme={null}
  // Install with: composer require flutterwavedev/flutterwave-v3

  $flw = new \Flutterwave\Rave(getenv('FLW_SECRET_KEY'));
  // Set `PUBLIC_KEY` as an environment variable
  $achChargeService = new \Flutterwave\Ach();
  $payload = [
      "type" => "ach_payment",
      "amount" => 250,
      "currency" => 'USD',
      "email" => 'user@example.com',
      "tx_ref" => $this->generateTransactionReference(),
  ];
  $response = $achChargeService->achCharge($payload);
  ```

  ```ruby Ruby theme={null}
  # Install with: gem install flutterwave_sdk

  require 'flutterwave_sdk'

  flw = Flutterwave.new(ENV["FLW_PUBLIC_KEY"], ENV["FLW_SECRET_KEY"], ENV["FLW_ENCRYPTION_KEY"])
  account_payment = AccountPayment.new(flw)
  payload = {
      amount: 250,
      currency: 'USD',
      email: 'user@example.com',
      tx_ref: generate_transaction_reference,
  }
  # Automatically uses the right endpoint based on the currency
  response = account_payment.initiate_charge payload
  ```

  ```json cURL theme={null}
  # US Account
  curl --request POST \
     --url https://api.flutterwave.com/v3/charges?type=ach_payment \
     --header 'Authorization: Bearer YOUR_SECRET_KEY' \
     --header 'content-type: application/json' \
     --data '{
       "amount": 250,
       "currency": "USD",
       "email": "user@example.com",
       "tx_ref": "ACH1234567x01"
  }'
  ```
</CodeGroup>

## Handling the Response

If all goes well, you'll get a response that looks like this:

<CodeGroup>
  ```json Sample Response (USD) theme={null}
  {
  	"status": "success",
  	"message": "Charge initiated",
  	"data": {
  		"id": 4962269,
  		"tx_ref": "ACH1234567x01",
  		"flw_ref": "FKYJ50811710276768063172919",
  		"device_fingerprint": "62wd23423rq324323qew1",
  		"amount": 100,
  		"charged_amount": 100,
  		"app_fee": 3.4,
  		"merchant_fee": 0,
  		"processor_response": "Request Accepted",
  		"auth_model": "AUTH",
  		"currency": "USD",
  		"ip": "54.75.161.64",
  		"narration": "Flutterwave Developers",
  		"status": "pending",
  		"auth_url": "https://mx-middleware.dev-flutterwave.com/transactions?reference=FKYJ50811710276768063172919",
  		"payment_type": "account-ach-us",
  		"fraud_status": "ok",
  		"charge_type": "normal",
  		"created_at": "2024-03-12T20:52:47.000Z",
  		"account_id": 20937,
  		"customer": {
  			"id": 2006690,
  			"phone_number": "0902620185",
  			"name": "Yolande Aglaé",
  			"email": "user@example.com",
  			"created_at": "2023-03-21T14:22:25.000Z"
  		},
  		"meta": {
  			"authorization": {
  				"mode": "redirect",
  				"redirect": "https://mx-middleware.dev-flutterwave.com/transactions?reference=FKYJ50811710276768063172919",
  				"validate_instructions": ""
  			}
  		}
  	}
  }
  ```

  ```json Sample Response (ZAR) theme={null}
  {
  	"status": "success",
  	"message": "Charge initiated",
  	"data": {
  		"id": 593421312,
  		"tx_ref": "ref-1585230ew9v5050e8-abcdefg-10",
  		"flw_ref": "ACH64190164701343961",
  		"device_fingerprint": "N/A",
  		"amount": 10,
  		"charged_amount": 10.25,
  		"app_fee": 0.25,
  		"merchant_fee": 0,
  		"processor_response": "Transaction in progress",
  		"auth_model": "AUTH",
  		"currency": "ZAR",
  		"ip": "52.18.161.235",
  		"narration": "Globus Technologies",
  		"status": "pending",
  		"auth_url": "https://pay.ozow.com/6ab3a781-1b4f-490d-964b-e07bda58a105/Secure",
  		"payment_type": "account",
  		"fraud_status": "ok",
  		"created_at": "2022-03-11T15:43:59.000Z",
  		"account_id": 82913,
  		"customer": {
  			"id": 223898841,
  			"phone_number": "0902620185",
  			"name": "Yemi Desola",
  			"email": "user@flw.com",
  			"created_at": "2020-09-17T13:07:36.000Z"
  		},
  		"account": {
  			"account_number": "0000000000",
  			"bank_code": "000",
  			"first_name": "Yemi",
  			"last_name": "Desola"
  		},
  		"meta": {
  			"authorization": {
  				"mode": "redirect",
  				"redirect": "https://pay.ozow.com/6ab3a781-1b4f-490d-964b-e07bda58a105/Secure",
  				"validate_instructions": ""
  			}
  		}
  	}
  }
  ```
</CodeGroup>

## Completing the Payment

To complete the payment, the customer makes the transfer, typically from their bank's Internet banking platform.

When the payment is completed, we'll send you a webhook notification. Here's what that looks like:

```json Sample Webhook theme={null}
{
	"event": "charge.completed",
	"data": {
		"id": 593416278,
		"tx_ref": "ref-1585230ew9v5050e8-abcdefg-10",
		"flw_ref": "ACH97785164701281024",
		"device_fingerprint": "N/A",
		"amount": 100,
		"currency": "ZAR",
		"charged_amount": 102.5,
		"app_fee": 2.5,
		"merchant_fee": 0,
		"processor_response": "Transaction cancelled by user",
		"auth_model": "AUTH",
		"ip": "54.154.184.168",
		"narration": "Globus Technologies",
		"status": "failed",
		"payment_type": "account",
		"created_at": "2022-03-11T15:33:30.000Z",
		"account_id": 82913,
		"customer": {
			"id": 223898841,
			"name": "Yemi Desola",
			"phone_number": "0902620185",
			"email": "user@flw.com",
			"created_at": "2020-09-17T13:07:36.000Z"
		},
		"account": {
			"account_name": "Yemi Desola",
			"account_number": "0000000000",
			"bank_code": "000"
		}
	},
	"meta_data": {},
	"event.type": "ACCOUNT_TRANSACTION"
}
```

In your webhook handler, you can then verify the payment and credit your customers with whatever they paid for. See our guide to [transaction verification](/transaction-verification) for details.
