---
# System prepended metadata

title: ACH Direct Debit

---

# ACH Direct Debit

## Introduction 


ACH Direct Debit is a payment method that runs on the ACH (Automated Clearing House) network in the United States. It is a financial network used for electronic payments and money transfers which allows customers to pay for transactions by debiting by directly debiting their bank account instead of using paper checks, credit card networks, wire transfers, or cash. ACH payments are faster and more reliable than checks, thereby helping to automate and streamline accounting.

---
**Note:** The below section provides information on server side implementation for ACH direct debit using GraphQL. If you are new to GraphQL please refer [About GraphQL](https://graphql.braintreepayments.com/guides/#about-graphql) for more information. Also, for details on existing Server Support refer [Server Side Implementation](https://developer.paypal.com/braintree/docs/guides/ach/server-side).
For more information on basic concepts refer [Basic Concepts](https://graphql.braintreepayments.com/guides/#basic-concepts).

---

## Verification Methods 

In order to be able to accept ACH payments from your customers, their bank account information  needs to go through a verification process. The following are the various methods of verifying the customer bank account: 

* [Tokenizing](#Tokenizing)
    * Tokenizing without verification.
    * Tokenizing with verification.
* [Vaulting](#Vaulting)
    * Vaulting with verification.
    * Vaulting without verification.
* Verifying
    * Verification with network check.
    * Verification with micro transfers.
    * Verification with independent check.
* Transacting

## Tokenizing
Tokenizing is a process of exchanging raw payment information for generating a secure, one-time-use token referred to as a payment method nonce. 

### How it works?

ACH Payment Tokenization replaces sensitive account and routing number data with a random string of alpha-numeric data.  This data is called a reference token and is stored in lieu of full sensitive data. When the bank account is future billed, the token is generated and sent. The ACH processor has the full account and routing number securely stored and using the matching token the ACH transaction is processed.

### Methods to tokenize for ACH Integration 
There are two ways to tokenize:

#### 1. Tokenizing without verification
A bank account can be tokenized by following the below steps:

##### Pre-requisites 

As a pre-requisite to tokenize without verification, the one-time token or the nonce needs to be utilized to vault the bank account. The same must be verified successfully to render the resulting nonce transactable.

##### Steps:

After successfully vaulting the bank account, the following information can be collected to tokenize without verification:
* Customers Account Information
* Routing Numbers


#### 2. Tokenizing with verification


### Process to Generate a Token

ACH datapoints consist of a bank account number and routing number. The routing number identifies the consumer or businesses bank. These numbers be replaced with a reference token. The token is then stored with the customer data and when payment is collected or disbursed the reference token is sent as part of the transaction string. 

In order to generate a token follow the steps mentioned below:
1. Utilize the [tokenizeUsBankAccount](https://graphql.braintreepayments.com/reference/#Mutation--tokenizeUsBankAccount) mutation to tokenize a US bank account. 


---

**Note:** The ACH tokenization gateway has the full account and routing numbers vaulted. 


---

2. Provide the bank account details as [input](https://graphql.braintreepayments.com/reference/#input_object--tokenizeusbankaccountinput) in [usBankAccount](https://graphql.braintreepayments.com/reference/#input_object--tokenizeusbanklogininput).  


---

**Note:** The resulting token that represents the bank account can be found in *data.tokenizeUsBankAccount.paymentMethod.id.*  In example above, it's the string with "tokenusbankacct_" prefix.


---

*MutationCodeBlock*

```
mutation TokenizeUsBankAccount($input: TokenizeUsBankAccountInput!) {
  tokenizeUsBankAccount(input: $input) {
    clientMutationId
    paymentMethod {
      id
      usage
      createdAt
      details {
        ... on UsBankAccountDetails {
          accountholderName
          accountType
          bankName
          last4
          routingNumber
          verified
          achMandate {
            acceptedAt
            acceptanceText
          }
        }
      }
    }
  }
}
```
*VariableCodeBlock*
```
{
  "input": {
	  "usBankAccount": {
      "routingNumber": "021000021",
      "accountNumber": "9876543210",
      "accountType": "CHECKING",
      "achMandate": "I agree to give away all my money",
      "individualOwner": {
        "firstName": "Busy",
        "lastName": "Bee"
      },
      "billingAddress": {
        "streetAddress": "111 Main St",
        "extendedAddress": "#7",
        "city": "San Jose",
        "state": "CA",
        "zipCode": "94085"
      }
    }
  }
}
```
*ResponseCodeBlock*
```
{
  "data": {
    "tokenizeUsBankAccount": {
      "clientMutationId": null,
      "paymentMethod": {
        "id": "tokenusbankacct_rest_of_token",
        "usage": "SINGLE_USE",
        "createdAt": "2022-08-10T23:19:17.117000Z",
        "details": {
          "accountholderName": "Busy Bee",
          "accountType": "CHECKING",
          "bankName": "JPMORGAN CHASE",
          "last4": "3210",
          "routingNumber": "021000021",
          "verified": false
        }
      }
    }
  },
  "extensions": {
    "requestId": "cfcc38fe-6e93-4fcf-aa1a-a62e2f37c676"
  }
}
```


## Vaulting
Vaulting is the process of exchanging a one-time-use payment method nonce for a persistent payment method token. Vaulting can be configured with our without verification. Refer the below sections: 

## Vaulting with verification
When vaulting a bank account, you can choose to specify a verification method. This creates a vaulted payment method and initiates a verification in a single step. 


---

**Note:** This method of vaulting a bank account will be transactable only if the verification is successful. If the verification fails, the same method can be repeated to get a successful verification. 


---

### Process
Follow the steps below:
1. Utilize [vaultUsBankAccount](https://graphql.braintreepayments.com/explorer/#:~:text=.-,vaultUsBankAccount,-Mutation) mutation for vaulting.
2. Provide the [input](https://graphql.braintreepayments.com/reference/#input_object--vaultusbankaccountinput). For the input, it is mandatory to provide at least    a single-use ACH [paymentMethod](https://graphql.braintreepayments.com/reference/#scalar--id).  


---

**Note**: You can define any of the supported [Verification Methods](https://graphql.braintreepayments.com/reference/#enum--usbankaccountverificationmethod) for verifying the bank account information. 


---

*MutationCodeBlock*

```
mTo vault an ACH payment method, you should use vaultUsBankAccount mutation.

For input you would provide at least a single-use ACH paymentMethod. Optionally, you can also provide a verificationMethod which specifies the way in which you want the given bank account verified.utation VaultUsBankAccount($input: VaultUsBankAccountInput!) {
  vaultUsBankAccount(input: $input) {
	clientMutationId
    paymentMethod {
      id
      legacyId
      details {
        ... on UsBankAccountDetails {
          accountholderName
          accountType
          bankName
          last4
          routingNumber
          verified
          achMandate {
          	acceptedAt
            acceptanceText
          }
        }
      }
    }
    verification {
      id
      status
    }
  }
}
```
*VariableCodeBlock*
```
{
  "input": {
    "paymentMethodId": "tokenusbankacct_bf_4t32qt_b2p7v9_x7gcpk_q7rjvf_2n3",
    "verificationMerchantAccountId": "paypal",
    "verificationMethod": "MICRO_TRANSFERS"
  }
}
```
*ResponseCodeBlock*
```
{
  "data": {
    "vaultUsBankAccount": {
      "clientMutationId": null,
      "paymentMethod": {
        "id": "cGF5bWVudG1ldGhvZF91c2JfYnQ4a3BrNg",
        "legacyId": "bt8kpk6",
        "details": {
          "accountholderName": "Busy Bee",
          "accountType": "CHECKING",
          "bankName": "JPMORGAN CHASE",
          "last4": "3210",
          "routingNumber": "021000021",
          "verified": false,
          "achMandate": {
            "acceptedAt": "2022-08-11T06:26:34.000000Z",
            "acceptanceText": "I agree to give away all my money today."
          }
        }
      },
      "verification": {
        "id": "dXNiYW5rYWNjb3VudHZlcmlmaWNhdGlvbl85Y3F2M3QzOA",
        "status": "PENDING"
      }
    }
  },
  "extensions": {
    "requestId": "126e6b6f-3205-42c7-b4b7-844c42b333f2"
  }
}
```

## Vaulting without verification

You can also vault a bank account without specifying a verification method. This will vault the payment method as usual, but no verification will be attempted. However, as mentioned in the previous section, this payment method will not be transactable until it has a subsequent successful verification.

If you prefer to perform the verification on your own, the [Verification Method](https://graphql.braintreepayments.com/reference/#enum--usbankaccountverificationmethod) should be set as INDEPENDENT_CHECK.


## Verifying

To verify an US bank account, you should use [verifyUsBankAccount](https://graphql.braintreepayments.com/reference/#Mutation--verifyUsBankAccount) mutation.

For [input](https://graphql.braintreepayments.com/reference/#input_object--verifyusbankaccountinput) you would provide at the minimum [paymentMethodId](https://graphql.braintreepayments.com/reference/#scalar--id) and [verificationMethod](https://graphql.braintreepayments.com/reference/#enum--usbankaccountverificationmethod).

*MutationCodeBlock*
```
mutation VerifyUsBankAccount($input: VerifyUsBankAccountInput!) {
  verifyUsBankAccount(input: $input) {
    clientMutationId
    verification {
      id
      legacyId
      status
      merchantAccountId
      createdAt
      gatewayRejectionReason
      paymentMethod {
        id
      }
      processorResponse {
        legacyCode
        message
        cvvResponse
        avsPostalCodeResponse
        avsStreetAddressResponse
      }
    }
  }
}

```
*VariableCodeBlock*
```
{
  "input": {
    "paymentMethodId": "cGF5bWVudG1ldGhvZF91c2JfNGt4ZjI5Ng",
    "verificationMethod": "INDEPENDENT_CHECK"
  }
}
```
*ResponseCodeBlock*
```
{
  "data": {
    "verifyUsBankAccount": {
      "clientMutationId": null,
      "verification": {
        "id": "dXNiYW5rYWNjb3VudHZlcmlmaWNhdGlvbl9qeTZ2Zjg5eA",
        "legacyId": "jy6vf89x",
        "status": "VERIFIED",
        "merchantAccountId": "paypal",
        "createdAt": "2022-08-11T05:06:10.000000Z",
        "gatewayRejectionReason": null,
        "paymentMethod": {
          "id": "cGF5bWVudG1ldGhvZF91c2JfNGt4ZjI5Ng"
        },
        "processorResponse": {
          "legacyCode": "1000",
          "message": "Approved",
          "cvvResponse": null,
          "avsPostalCodeResponse": null,
          "avsStreetAddressResponse": null
        }
      }
    }
  },
  "extensions": {
    "requestId": "c33bf5ea-e978-4c03-82d2-1a13067f9a78"
  }
}
```


## Methods of Verifying

Braintree’s ACH Direct Debit integration offers the following methods to verify the bank account information provided by the customer for receiving a payment. 

* **Network check** – This method instantly verifies the bank account details by utlizing the bank account and routing number, as well as personal/business information.
* **Micro-transfers** – issues two separate credits of less than a dollar each to the customer’s bank account and requires the customer to confirm the exact amounts once they’re visible in the account.
* **Independent check** – allows you to use your own verification method that is not listed above and manually mark payment methods as verified.

You can use any combination of these methods in order to meet your business needs. For example, one recommended flow is to use network check as an initial verification method with micro-transfers as a backup option.


## Verification with Micro-deposit
The following section provides information on the process of verifying a US bank using micro deposit.
### Prerequisite
To verify an US bank account using micro-deposit perform the below mentioned prerequisite:

Utilize [confirmMicroTransferAmounts](https://graphql.braintreepayments.com/reference/#Mutation--confirmMicroTransferAmounts) mutation to initiate the verification using micro-deposit to random small amounts of your choice. 

For [input](https://graphql.braintreepayments.com/reference/#input_object--verifyusbankaccountinput) you would provide at the minimum [verificationId](https://graphql.braintreepayments.com/reference/#scalar--id) which is vaultUsBankAccount.verification.id (in the response of vaultUsBankAccount mutation) and [amountInCents](https://graphql.braintreepayments.com/reference/#scalar--int) which is an array of integers.  For instance, to specify 17 cents and 44 cents, you would provide [17, 44].

*MutationCodeBlock*
```
mutation ConfirmMicroTransferAmounts($input: ConfirmMicroTransferAmountsInput!) {
  confirmMicroTransferAmounts(input: $input) {
    verification {
      id
      paymentMethod {
        id
        usage
      }
      merchantAccountId
      status
      processorResponse {
        message
        cvvResponse
        avsPostalCodeResponse
        avsStreetAddressResponse
      }
      networkResponse {
        code
        message
      }
      gatewayRejectionReason
    }
    status
  }
}

```
*VariableCodeBlock*
```
{
  "input": {
    "verificationId": "dXNiYW5rYWNjb3VudHZlcmlmaWNhdGlvbl85Y3F2M3QzOA",
    "amountsInCents": [17, 44]
  }
}
```
*ResponseCodeBlock*
```
{
  "data": {
    "confirmMicroTransferAmounts": {
      "verification": {
        "id": "dXNiYW5rYWNjb3VudHZlcmlmaWNhdGlvbl85Y3F2M3QzOA",
        "paymentMethod": {
          "id": "cGF5bWVudG1ldGhvZF91c2JfYnQ4a3BrNg",
          "usage": "MULTI_USE"
        },
        "merchantAccountId": "paypal",
        "status": "PENDING",
        "processorResponse": {
          "message": "Approved",
          "cvvResponse": null,
          "avsPostalCodeResponse": null,
          "avsStreetAddressResponse": null
        },
        "networkResponse": {
          "code": null,
          "message": null
        },
        "gatewayRejectionReason": null
      },
      "status": "AMOUNTS_DO_NOT_MATCH"
    }
  },
  "extensions": {
    "requestId": "6366e6c2-192c-4bac-b87f-3149eecec7b7"
  }
}
```
## Checking verification status

In order to check for successful verification, you must examine [verifyUsBankAccount.verification.processorResponse.message](https://graphql.braintreepayments.com/reference/#object--verificationprocessorresponse) and verify the message to be **"*Approved*"**.  In case of a failure, an alternate message **"*Processor Network Unavailable - Try 

## Retrying verification
Verifcation can be retried in case of a failure by using any of the following two methods:

* Resend the previous request
* Change the [verificationMethod](https://graphql.braintreepayments.com/reference/#enum--usbankaccountverificationmethod) and resend the previous request.
For example, previously, NETWORK_CHECK was used and failed with a message **"*No Data Found - Try Another Verification Method*"**, on a retry, you should change it to MICRO_TRANSFERS as an alternative.
## Common errors
ACH payment method and US bank account are used interchangeably in this document.
Each tokenized US bank account can only be vaulted once.  If you attempt to vault the same token more than once, you will get the following error. 

```
{
  "errors": [
    {
      "message": "Cannot use a single-use payment method more than once.",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "vaultUsBankAccount"
      ],
      "extensions": {
        "errorClass": "VALIDATION",
        "errorType": "user_error",
        "inputPath": [
          "input",
          "paymentMethodId"
        ],
        "legacyCode": "93107"
      }
    }
  ],
  "data": {
    "vaultUsBankAccount": null
  },
  "extensions": {
    "requestId": "ba53c8e6-43b2-464a-b0f8-bc1599b96af7"
  }
}
```

If you do not provide [verificationMethod](https://graphql.braintreepayments.com/reference/#enum--usbankaccountverificationmethod) in the inputs, you will get the following error.
```
{
  "errors": [
    {
      "message": "Variable 'input' has an invalid value: Field 'verificationMethod' has coerced Null value for NonNull type 'UsBankAccountVerificationMethod!'",
      "locations": [
        {
          "line": 1,
          "column": 29
        }
      ]
    }
  ],
  "extensions": {
    "requestId": "7fd3e425-ff70-43bc-8cb5-9014fdedccff"
  }
}
```



