Events & statuses

This guide explains different transfer failure scenarios, responses, statuses and how Moov handles them.

In an ideal world, every transfer initiated in Moov’s platform would complete seamlessly as expected. However, there are instances in which something goes wrong. In every situation, Moov will provide more information - a failure reason, detailed responses, or status updates. You can also set up webhooks to be notified when certain events occur, like a failed transfer.

Transfer failures

A transfer’s status changes from pending to failed if the funds don’t reach their intended destination. A transfer could fail for a few reasons:

  • The source account (bank account or linked card) does not have sufficient funds for the amount of the transfer
  • The source account or transfer recipient closed their account (bank account or linked card) so it no longer exists
  • The issuer of the linked card denies the transfer attempt for a number of reasons (see the declines guide)
  • An phone number or email was reused when linking a card (these must be unique to each cardholder)
A transfer’s status can change from pending to failed within 2 business days of when it was initiated.

Failure reasons

When a transfer fails, we communicate the reason for the transfer failure through the failureReason field in API response for a get a transfer request. See a list of possible failure reasons below:

Status Description
source-payment-error A failure occurred at the source. The failure code is provided in the rail details under the source object.
destination-payment-error A failure occurred at the destination. The failure code is provided in the rail details under the destination object.
wallet-insufficient-funds Transfer failed due to insufficient funds in the source wallet.
rejected-high-risk Transfer was flagged with potential fraud and rejected by Moov.
processing-error Moov encountered an unexpected error processing the transfer.

Transfer reversals

A transfer’s status changes from completed to reversed if the funds made it to the destination, but need to be returned. A reversal scenario can occur when:

  • A fraudulent, unauthorized, or unrecognized charge was made
  • Someone used the wrong bank details to pay for goods or services

In the case of a reversal, Moov routes the funds back to the party that made an unintentional payment or was accidentally/fraudulently charged. To accomplish this, we deduct from the Moov wallet of the account that received the funds. The recipient of a transfer that’s being reversed is responsible for funding the wallet to cover the negative balance.

A transfer’s status can change from completed to reversed within 60 calendar days of when it was initiated.

Transfer responses

Moov uses standard HTTP status codes to communicate the outcome of all Moov API requests. The following table summarizes the possible responses after submitting a Create transfer POST /transfers request.

Receiving a 2xx response code does not indicate that the payment was successful. Use the X-Wait-For: rail-response header in your POST request to get the full response from the payment network and be prepared to handle timeouts.
HTTP code Moov status message Description
200
OK
Successfully created a transfer If you included the X-Wait-For header in your request, you will receive a synchronous response with transfer details from the payment network. Subscribe to the transfer.updated webhook event for updates on the transfer status and rail-specific details as they become available.
201
Created
Transfer was successfully created but an error occurred while getting the synchronous response. The asynchronous response object will be returned. Moov is currently unable return the full transfer object as a response, so you will only receive the asynchronous response object. To retrieve full rail-specific details at a later time, use the transfers GET endpoint. Subscribe to the transfer.updated webhook event for updates.
202
Accepted
A transfer or refund was successfully created but a timeout occurred while waiting for a synchronous response. Rail-specific details may be missing from the response object. A timeout occurred with the payment network, so you will only receive the asynchronous response object. To retrieve full rail-specific details at a later time, use the transfers GET endpoint. Subscribe to the transfer.updated webhook event for updates.
400
Bad request
Invalid request, an error message will be available in the response body. There was an issue with the request payload. Follow the error message instructions and double check your request against the request body schema in the API reference.
409
Conflict
Attempted to create a transfer using duplicate X-Idempotency-Key header Retry the request with a different X-Idempotency-Key header
422
Unprocessable content
The request body could not be processed The error message will let you know how long to wait (in milliseconds) before you can retry
429
Too many requests
Request was refused due to rate limiting The error message will let you know how long to wait (in milliseconds) before you can retry
If you receive a 202 response, do not mark the transfer as successful. For payments related to physical goods, make sure that nothing ships until rail-specific transfer details are available. Either perform a subsequent GET for the transfer details or subscribe to the transfer.updated webhook event.

Transfer statuses

A transfer can have the following statuses:

Status Description
created A transfer has been created
queued A transfer that is part of a group will have the queued status until the preceding transfer has successfully completed
pending The transfer is in progress, but not yet completed
completed The transfer has completed
canceled A transfer that is part of a group can fail and subsequent transfers will be marked as canceled
failed The transfer did not succeed
reversed The transfer completed, but funds were returned to the source

Rail specific statuses are also available under the source and destination. You can view rail-specific statuses in our other guides:

Transfer event webhooks

Every transfer status change is an event in Moov, so you can set up webhooks to stay updated on transfer events such as transfer creation or status updates (pending, completed, failed, reversed). See our webhooks guide to learn more.

Summary Beta