Final Status of a Transfer
When you initiate a money transfer or a merchant payment, we process it asynchronously. The response to your request does not tell you the outcome. This page explains the states of a transfer, and the two ways to learn its final state.
The States of a Transfer
A transfer that you initiate with the Money Transfers API or the Merchant Payments API is always in one of these states:
| State | Meaning |
|---|---|
PENDING | We have accepted the transfer, and we are processing it. |
POSTED | We have executed the transfer, and the money has left your account. This is a final state. |
REJECTED | We did not execute the transfer. The violations field tells you why. This is a final state. |
REVERSED | The transfer was POSTED, and later the receiving bank returned the money. |
POSTED is final for the transfer, but the receiving bank can still return the money afterwards.
The state then changes to REVERSED.
The receiving bank decides when this happens, as the FAQ explains.
The Response to Your Request Does Not Tell You the Outcome
POST /v2/money-transfers/{transferId} and POST /v2/merchant-payments/{transferId} answer 202 Accepted when we have received your request.
The response does not tell you the outcome of the transfer.
This is also true when you repeat the request with a transferId that already exists.
So do not use the response, or a repeated request, to check the state of a transfer. Use one of the two ways below instead. You can also use both.
Option 1: Subscribe to the Transfer Events
Subscribe to these three event types:
DomesticTransfer.PostedV1DomesticTransfer.RejectedV1DomesticTransfer.ReversedV1
We send the same events for money transfers and for merchant payments.
The webhooks section of each of the two API specifications describes the data of the events.
Creating a Subscription explains how to subscribe. Read it before you start, because it also explains why you need a subscription in the sandbox and another one in production. How We Deliver an Event explains what to expect from a delivery.
Option 2: Poll the Transfer
Call GET /v2/money-transfers/{transferId} or GET /v2/merchant-payments/{transferId} with the transferId you chose.
Repeat the call until transferState is POSTED or REJECTED, and respect our rate limits.
The response has these fields about the outcome:
| Field | When we set it |
|---|---|
transferState | Always. |
finalizedAt | When the transfer is POSTED or REJECTED. For a POSTED transfer, this is the posting time. A reversal does not change it. |
violations, violationReasons | When the transfer is REJECTED. |
reversalReason, reversedAt | Only when the transfer is REVERSED. |
A reversal can happen long after the transfer was posted.
To learn about it without polling for a long time, subscribe to DomesticTransfer.ReversedV1.
A reversal also appears as a new posting on your account, as the FAQ explains.
Reconcile With GET, Even if You Use Webhooks
A webhook delivery can be lost, as When We Give Up explains.
So when a transfer stays PENDING in your system for longer than you expect, call GET to learn its state.