Skip to main content

Overview

ACH Save recovers eligible declined debit card transactions by retrying them over ACH. Many card declines are recoverable — issuers routinely decline legitimate transactions due to outdated risk rules, expired cards, or system errors. ACH Save lets the user re-authorize the same purchase through an authenticated bank flow.

How it works

  1. Invoke ACH save from your existing card processing flow when an eligible transaction is declined.
  2. Push evaluates the transaction’s risk and, if approved, returns a link where the user can login to their bank.
  3. After the user authenticates and links their checking account, Push re-authorizes the transaction and originates the payment over ACH.
ACH Save is a pilot program on eligible BIN ranges and risk thresholds. Reach out to your Push Cash representative for details about what transactions qualify for ACH Saves.

Integration overview

The steps below show an overview of how to integrate ACH Save.
  1. Register the user. Call the create-user endpoint with the user’s name, email, address, and phone number.
    • Retain the returned user id for the Authorization call (see step 3)
    • Register each user only once
  2. Generate a token. Call the tokenize-card endpoint with the user’s pan
    • Retain the returned token for the Authorization call (see step 3)
    • To avoid sharing the full card number, mask the middle digits 8–12 with XXXX and only transmit the BIN and last four of the user’s card.
  3. Authorize the payment. Call the authorize-payment endpoint with the amount, currency, direction: cash_in, type: ach_save, user_id, the token from the previous step, and a redirect_url. Handle the response by its HTTP status code:
    • 202 Accepted — the user must complete bank authentication. Persist the returned intent id, then continue to step 4 using the returned url.
    • 200 OK — the payment was approved immediately (i.e. for a returning user whose bank is already linked). Notify the user that the deposit succeeded.
    • 401 Unauthorized — the payment was declined (e.g. due to transaction risk)
  4. Direct the user to complete bank authentication Navigate the user to the url returned from the Authorize call. When the flow completes, the user is returned to your application via the redirect_url you set on the authorize request.
  5. Retrieve the ACH authorization result. Call the get-an-intent endpoint and inspect the status field.
    • If status is approved, Push authorized the payment and automatically originates it over ACH. Update your internal transaction record and display a message to the user that the payment succeeded.
    • If status is declined, Push could not approve the payment for ACH (e.g. due to insufficient balance).
curl --request POST \
  --url https://sandbox.pushcash.com/user \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "name": {
    "first": "Alfred",
    "last": "Hitchcock"
  },
  "email": "alfred@imdb.com",
  "address": {
    "address_line_1": "1609 10th Ave",
    "locality": "Bodega Bay",
    "administrative_area": "CA",
    "postal_code": "94923",
    "country": "US"
  },
  "phone_number": "(555) 681-3485",
  "tag": "4c8e6b4f"
}
'
curl --request POST \
  --url https://sandbox-tokens.pushcash.com/tokenize \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "pan": "55555555XXXX4444"
}
'
curl --request POST \
  --url https://sandbox.pushcash.com/authorize \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "amount": 45000,
  "currency": "USD",
  "direction": "cash_in",
  "type": "ach_save",
  "user_id": "user_lVpbPL0K1XIiHx0DxipRbD",
  "token": "token_mbDRHFi3dxIZEtykHsgUGC",
  "redirect_url": "https://yourapp.com/checkout/?29080389002"
}
'
curl --request GET \
  --url https://sandbox.pushcash.com/intent/intent_sandbox_dMggQ93ZYH6DH9LBhVeijE \
  --header 'Authorization: Bearer <token>'
{
  "id": "user_lVpbPL0K1XIiHx0DxipRbD"
}
{
  "token": "token_mbDRHFi3dxIZEtykHsgUGC"
}
{
  "id": "intent_sandbox_dMggQ93ZYH6DH9LBhVeijE",
  "url": "https://cdn.pushcash.com/ux/intent_sandbox_dMggQ93ZYH6DH9LBhVeijE"
}
{
  "id": "intent_sandbox_dMggQ93ZYH6DH9LBhVeijE",
  "amount": 45000,
  "direction": "cash_in",
  "currency": "USD",
  "credential": {
    "display_name": "Chase Checking",
    "last4": "6018"
  }
}
{
  "id": "intent_sandbox_dMggQ93ZYH6DH9LBhVeijE",
  "decline_category": "insufficient_funds"
}
{
  "id": "intent_sandbox_dMggQ93ZYH6DH9LBhVeijE",
  "status": "approved"
}
{
  "id": "intent_sandbox_dMggQ93ZYH6DH9LBhVeijE",
  "status": "declined"
}

Next steps

Set up webhooks to receive intent.approved and decline notifications asynchronously. See the enabling webhooks guide.