# Re-present an ACH payment

Retrieve the reason a bank transfer payment failed and resubmit it by sending a GET and then a POST request to the Bank Transfer Payments endpoint

**Prerequisites:** [Authentication](/api/authentication)

If an ACH payment has failed, we send an email to the merchant to let them know that the payment has failed. You can integrate with our API return the reason that the payment failed and then re-present the payment.

**Note:** When the merchant views the reason why the payment failed, they might have to contact their customer to fix the issue before they can re-present the payment.

<a id="how-it-works"></a>
## How it works

Each time you re-present a payment, you use a new `paymentId` from the returns object of the retrieved payment, not the `paymentId` you used to retrieve it. You can re-present a payment up to two times.

```mermaid
sequenceDiagram
    participant M as Merchant
    participant GW as Gateway
    participant N as NACHA

    Note over M,N: An ACH payment has failed

    rect rgba(0, 81, 194, 0.4)
        Note over M,GW: Find out why the payment failed
        GW-->>M: Email: the ACH payment failed
        M->>GW: GET /bank-transfer-payments/:paymentId
        GW-->>M: returns[].paymentId and the failure reason
        Note over M: Contact the customer to<br />fix the issue, if needed
    end

    rect rgba(0, 224, 184, 0.3)
        Note over M,N: Re-present the payment
        M->>GW: POST /bank-transfer-payments/:paymentId/represent<br />using the new paymentId from returns
        GW->>N: Submit the re-presentment
        Note over M,N: If the payment fails again, repeat both steps with each new<br />paymentId from the returns object. You can re-present twice.
    end
```

1. We email the merchant to let them know that an ACH payment has failed.
2. Merchant uses their POS to view the details of the payment and the reason the payment has failed.
3. Merchant contacts their customer to fix the issue.
4. Merchant uses their POS to re-present the payment.

<a id="your-integration-journey"></a>
## Your integration journey

1. View the payment details.
2. Re-present the payment.
3. (Optional) Re-present the payment again.

**Note:** You can re-present a payment up to two times.

<a id="things-to-consider"></a>
## Things to consider

When you re-present a payment, don't use the same `paymentId` that you use to retrieve the payment.

In the response of the Retrieve Payment method, our gateway sends a returns object with a new `paymentId`, which you need to send in the Re-present Payment request.

```json
...
"returns": [  
    {  
       "paymentId": "GIJXAU3WUJ",  
       "date": "2025-06-23",  
       "returnCode": "R01",  
       "returnReason": "Insufficient Funds",  
       "represented": false,
       "closed": false,
       "link": {
          "rel": "self",  
          "method": "GET",  
          "href": "https://api.payroc.com/v1/bank-transfer-payments/GIJXAU3WUJ"
       }  
    }  
 ],
...
```

<a id="errors"></a>
## Errors

If your request is unsuccessful, we return an error. For more information about errors, see [Errors](/api/errors).

<a id="step-1-view-the-payment-details"></a>
## Step 1. View the payment details

To view the reason why the payment failed, send a GET request to our Bank Transfer Payments endpoint.

| Environment | URL |
| --- | --- |
| Test | [https://api.uat.payroc.com/v1/bank-transfer-payments/\{paymentId\}](https://api.uat.payroc.com/v1/bank-transfer-payments/%7BpaymentId%7D) |
| Production | [https://api.payroc.com/v1/bank-transfer-payments/\{paymentId\}](https://api.payroc.com/v1/bank-transfer-payments/%7BpaymentId%7D) |

<a id="request-parameters"></a>
### Request parameters

<a id="schema-requestpath"></a>
### Schema (`request.path`)

[Path parameters for `GET /bank-transfer-payments/{paymentId}`](/api/get-bank-transfer-payment)

<a id="example-request"></a>
### Example request

<a id="request"></a>
### Request

GET [https://api.payroc.com/v1/bank-transfer-payments/\{paymentId\}](https://api.payroc.com/v1/bank-transfer-payments/%7BpaymentId%7D)

**`Store Token Bank Transfer Payment`**

```curl
curl https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y \
     -H "Authorization: Bearer <token>"
```

**`Store Token Bank Transfer Payment`**

```python
import requests

url = "https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y"

headers = {"Authorization": "Bearer <token>"}

response = requests.get(url, headers=headers)

print(response.json())
```

**`Store Token Bank Transfer Payment`**

```javascript
const url = 'https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y';
const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

**`Store Token Bank Transfer Payment`**

```go
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("Authorization", "Bearer <token>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

**`Store Token Bank Transfer Payment`**

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'

response = http.request(request)
puts response.read_body
```

**`Store Token Bank Transfer Payment`**

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y")
  .header("Authorization", "Bearer <token>")
  .asString();
```

**`Store Token Bank Transfer Payment`**

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y', [
  'headers' => [
    'Authorization' => 'Bearer <token>',
  ],
]);

echo $response->getBody();
```

**`Store Token Bank Transfer Payment`**

```csharp
using RestSharp;

var client = new RestClient("https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y");
var request = new RestRequest(Method.GET);
request.AddHeader("Authorization", "Bearer <token>");
IRestResponse response = client.Execute(request);
```

**`Store Token Bank Transfer Payment`**

```swift
import Foundation

let headers = ["Authorization": "Bearer <token>"]

let request = NSMutableURLRequest(url: NSURL(string: "https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: \{ (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

<a id="response-fields"></a>
### Response fields

**Important:** Save the `paymentId` from the returns object for the re-presentment.

If your request is successful, our gateway sends a returns object that contains a returnCode field and a returnReason field that indicates the reason the payment failed.

<a id="schema-responsebody"></a>
### Schema (`response.body`)

[Response body schema for `GET /bank-transfer-payments/{paymentId}`](/api/get-bank-transfer-payment)

<a id="example-response"></a>
### Example response

<a id="response-200"></a>
### Response (200)

```json
{
  "paymentId": "E29U8OU8Q4",
  "processingTerminalId": "1234001",
  "order": {
    "amount": 4999,
    "currency": "USD",
    "orderId": "OrderRef7654",
    "breakdown": {
      "subtotal": 4347,
      "taxes": [
        {
          "name": "Sales Tax",
          "rate": 5,
          "amount": 217
        }
      ],
      "tip": {
        "type": "percentage",
        "amount": 435,
        "percentage": 10
      }
    },
    "dateTime": "2024-07-02T15:30:00Z",
    "description": "Large Pepperoni Pizza"
  },
  "bankAccount": {
    "type": "ach",
    "accountNumber": "****1591",
    "nameOnAccount": "Sarah Hazel Hopper",
    "routingNumber": "053200983",
    "secCode": "web"
  },
  "transactionResult": {
    "type": "payment",
    "status": "declined",
    "responseCode": "D",
    "authorizedAmount": 4999,
    "currency": "USD",
    "responseMessage": "Payment Declined",
    "processorResponseCode": "R11"
  },
  "customer": {
    "notificationLanguage": "en",
    "contactMethods": [
      {
        "type": "email",
        "value": "sarah.hopper@example.com"
      }
    ]
  },
  "returns": [
    {
      "paymentId": "M2MJOG6O2Y",
      "date": "2024-07-02",
      "returnCode": "R11",
      "returnReason": "Customer advises not authorized",
      "represented": false,
      "closed": false,
      "link": {
        "rel": "self",
        "method": "GET",
        "href": "https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y"
      }
    }
  ]
}
```

<a id="step-2-re-present-the-payment"></a>
## Step 2. Re-present the payment

To retry the payment, send a POST request to our Bank Transfer Payments endpoint.

| Environment | URL |
| --- | --- |
| Test | [https://api.uat.payroc.com/v1/bank-transfer-payments/\{paymentId\}/represent](https://api.uat.payroc.com/v1/bank-transfer-payments/%7BpaymentId%7D/represent) |
| Production | [https://api.payroc.com/v1/bank-transfer-payments/\{paymentId\}/represent](https://api.payroc.com/v1/bank-transfer-payments/%7BpaymentId%7D/represent) |

<a id="request-parameters-1"></a>
### Request parameters

<a id="schema-requestpath-1"></a>
### Schema (`request.path`)

[Path parameters for `POST /bank-transfer-payments/{paymentId}/represent`](/api/represent-bank-transfer-payment)

<a id="schema-requestbody"></a>
### Schema (`request.body`)

[Request body schema for `POST /bank-transfer-payments/{paymentId}/represent`](/api/represent-bank-transfer-payment)

<a id="example-request-1"></a>
### Example request

<a id="request-1"></a>
### Request

POST [https://api.payroc.com/v1/bank-transfer-payments/\{paymentId\}/represent](https://api.payroc.com/v1/bank-transfer-payments/%7BpaymentId%7D/represent)

**`Representment Bank Transfer Payment`**

```curl
curl -X POST https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y/represent \
     -H "Idempotency-Key: 8e03978e-40d5-43e8-bc93-6894a57f9324" \
     -H "Authorization: Bearer <token>" \
     -H "Content-Type: application/json" \
     -d '{
  "paymentMethod": {
    "type": "ach",
    "accountNumber": "11101010",
    "nameOnAccount": "Sarah Hopper",
    "routingNumber": "053200983",
    "accountType": "checking",
    "secCode": "tel"
  }
}'
```

**`Representment Bank Transfer Payment`**

```python
import requests

url = "https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y/represent"

payload = { "paymentMethod": {
        "type": "ach",
        "accountNumber": "11101010",
        "nameOnAccount": "Sarah Hopper",
        "routingNumber": "053200983",
        "accountType": "checking",
        "secCode": "tel"
    } }
headers = {
    "Idempotency-Key": "8e03978e-40d5-43e8-bc93-6894a57f9324",
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

**`Representment Bank Transfer Payment`**

```javascript
const url = 'https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y/represent';
const options = {
  method: 'POST',
  headers: {
    'Idempotency-Key': '8e03978e-40d5-43e8-bc93-6894a57f9324',
    Authorization: 'Bearer <token>',
    'Content-Type': 'application/json'
  },
  body: '{"paymentMethod":{"type":"ach","accountNumber":"11101010","nameOnAccount":"Sarah Hopper","routingNumber":"053200983","accountType":"checking","secCode":"tel"}}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

**`Representment Bank Transfer Payment`**

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y/represent"

	payload := strings.NewReader("{\n  \"paymentMethod\": {\n    \"type\": \"ach\",\n    \"accountNumber\": \"11101010\",\n    \"nameOnAccount\": \"Sarah Hopper\",\n    \"routingNumber\": \"053200983\",\n    \"accountType\": \"checking\",\n    \"secCode\": \"tel\"\n  }\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324")
	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

**`Representment Bank Transfer Payment`**

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y/represent")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Idempotency-Key"] = '8e03978e-40d5-43e8-bc93-6894a57f9324'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"paymentMethod\": {\n    \"type\": \"ach\",\n    \"accountNumber\": \"11101010\",\n    \"nameOnAccount\": \"Sarah Hopper\",\n    \"routingNumber\": \"053200983\",\n    \"accountType\": \"checking\",\n    \"secCode\": \"tel\"\n  }\n}"

response = http.request(request)
puts response.read_body
```

**`Representment Bank Transfer Payment`**

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y/represent")
  .header("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"paymentMethod\": {\n    \"type\": \"ach\",\n    \"accountNumber\": \"11101010\",\n    \"nameOnAccount\": \"Sarah Hopper\",\n    \"routingNumber\": \"053200983\",\n    \"accountType\": \"checking\",\n    \"secCode\": \"tel\"\n  }\n}")
  .asString();
```

**`Representment Bank Transfer Payment`**

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y/represent', [
  'body' => '{
  "paymentMethod": {
    "type": "ach",
    "accountNumber": "11101010",
    "nameOnAccount": "Sarah Hopper",
    "routingNumber": "053200983",
    "accountType": "checking",
    "secCode": "tel"
  }
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
    'Idempotency-Key' => '8e03978e-40d5-43e8-bc93-6894a57f9324',
  ],
]);

echo $response->getBody();
```

**`Representment Bank Transfer Payment`**

```csharp
using RestSharp;

var client = new RestClient("https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y/represent");
var request = new RestRequest(Method.POST);
request.AddHeader("Idempotency-Key", "8e03978e-40d5-43e8-bc93-6894a57f9324");
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"paymentMethod\": {\n    \"type\": \"ach\",\n    \"accountNumber\": \"11101010\",\n    \"nameOnAccount\": \"Sarah Hopper\",\n    \"routingNumber\": \"053200983\",\n    \"accountType\": \"checking\",\n    \"secCode\": \"tel\"\n  }\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

**`Representment Bank Transfer Payment`**

```swift
import Foundation

let headers = [
  "Idempotency-Key": "8e03978e-40d5-43e8-bc93-6894a57f9324",
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["paymentMethod": [
    "type": "ach",
    "accountNumber": "11101010",
    "nameOnAccount": "Sarah Hopper",
    "routingNumber": "053200983",
    "accountType": "checking",
    "secCode": "tel"
  ]] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.payroc.com/v1/bank-transfer-payments/M2MJOG6O2Y/represent")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: \{ (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```

<a id="response-fields-1"></a>
### Response fields

If your request is successful, our gateway sends the re-presentment to NACHA to retry the payment.

<a id="schema-responsebody-1"></a>
### Schema (`response.body`)

[Response body schema for `POST /bank-transfer-payments/{paymentId}/represent`](/api/represent-bank-transfer-payment)

<a id="example-response-1"></a>
### Example response

<a id="response-200-1"></a>
### Response (200)

```json
{
  "paymentId": "M2MJOG6O2Y",
  "processingTerminalId": "1234001",
  "order": {
    "amount": 4999,
    "currency": "USD",
    "orderId": "OrderRef6543",
    "breakdown": {
      "subtotal": 4347,
      "taxes": [
        {
          "name": "Sales Tax",
          "rate": 5,
          "amount": 217
        }
      ],
      "tip": {
        "type": "percentage",
        "amount": 435,
        "percentage": 10
      }
    },
    "dateTime": "2024-07-02T15:30:00Z",
    "description": "Large Pepperoni Pizza"
  },
  "bankAccount": {
    "type": "ach",
    "accountNumber": "****1010",
    "nameOnAccount": "Sarah Hopper",
    "routingNumber": "053200983",
    "secCode": "tel",
    "secureToken": {
      "secureTokenId": "MREF_abc1de23-f4a5-6789-bcd0-12e345678901fa",
      "customerName": "Sarah Hopper",
      "token": "296753123456",
      "status": "notValidated",
      "link": {
        "rel": "self",
        "method": "GET",
        "href": "https://api.payroc.com/v1/processing-terminals/1234001/secure-tokens/MREF_abc1de23-f4a5-6789-bcd0-12e345678901fa"
      }
    }
  },
  "transactionResult": {
    "type": "payment",
    "status": "ready",
    "responseCode": "A",
    "authorizedAmount": 4999,
    "currency": "USD",
    "responseMessage": "NoError",
    "processorResponseCode": "0"
  },
  "customer": {
    "notificationLanguage": "en",
    "contactMethods": [
      {
        "type": "email",
        "value": "sarah.hopper@example.com"
      }
    ]
  },
  "customFields": [
    {
      "name": "yourCustomField",
      "value": "abc123"
    }
  ]
}
```

<a id="step-3-optional-re-present-the-payment-again"></a>
## Step 3. (Optional) Re-present the payment again

If the re-presentment fails, you can send a second and final re-presentment request. To do this:

1. Save the paymentId from the response in Step 2. This is the paymentId of the failed re-presentment.
2. Use our [Retrieve Payment](https://docs.payroc.com/api/schema/bank-transfer-payments/payments/retrieve) method with the paymentId of the failed re-presentment. In the response, our gateway sends a returns object with a new paymentId.
3. Use our [Re-present Payment](https://docs.payroc.com/api/schema/bank-transfer-payments/payments/represent) method with this new paymentId to re-present the payment for a final time.
