Skip to content
Last updated

Payout failures

Subscribe to transfer payout failure event webhook to understand why a payout failed.

Use this event when you want to either understand the reason or guide customers to fix payout issues (for example, incorrect account details). The transfers#state-change and transfers#payout-failure events differ in purpose and most effective when used together.

  • transfers#state-change provides high-level understanding of a transfer's status.
  • transfers#payout-failure provides payout failure details, reason code and description, when failures occur.

Failure reason codes

Code Description
ACCOUNT_CLOSEDThe recipient details are correct, but beneficiary account is closed.
ACCOUNT_FROZENThe recipient details are correct, but beneficiary account is frozen.
ACCOUNT_BLOCKEDThe recipient details are correct, but beneficiary account is blocked.
ACCOUNT_LIMIT_REACHEDThe recipient details are correct, but beneficiary account has a limit that can be unblocked by the recipient.
WRONG_ACCOUNT_NUMBERInvalid account number.
WRONG_CARD_NUMBERInvalid card number.
WRONG_ACCOUNT_DETAILSInvalid account number and/or invalid bank code.
WRONG_ACCOUNT_TYPEIncorrect account type.
WRONG_BANK_CODEInvalid sort/BIC/routing/etc number.
WRONG_BRANCH_CODEInvalid branch code.
WRONG_NAMEAccount number matches, but the name is not 100% correct.
WRONG_PHONE_NUMBERRecipient phone number is incorrect.
WRONG_ID_NUMBERInvalid recipient's ID document number
WRONG_RUT_NUMBERInvalid recipient's RUT (Rol Unico Tributario) number.
TAX_ID_NOT_MATCHINGTax ID doesn't match recipient's name.
TAX_ID_SUSPENDEDTax ID is suspended.
WRONG_REFERENCEInvalid payment reference.
WRONG_PAYMENT_PURPOSEInvalid or not accepted payment purpose.
ACCOUNT_DOES_NOT_EXISTFormat is correct but this account does not exist in recipient bank.
WRONG_CURRENCYRecipient account is in different currency.
WRONG_CARD_TYPERecipient account doesn't support payments to this card type.
CANNOT_ACCEPT_FROM_3RD_PARTYRecipient bank can't accept the payments from 3rd party.
CREDITING_ACCOUNT_FORBIDDENTerms and Conditions of Account do not permit crediting of these funds.
DUPLICATE_ENTRYRecipient bank informs that there has been another payment in the same amount.
FUNDS_NOT_EXPECTED_RETURNEDBeneficiary not expecting funds/instructed return.
MANDATE_NOT_FILLED_INRecipient didn't fill out the mandate form on time or the email address is incorrect.
BUSINESS_PAYMENTS_FORBIDDENPayment to business accounts are not allowed.
SENDER_REQUESTED_TO_CANCELSender requested cancellation.
REQUEST_FOR_INFORMATION_EXPIREDRequest for information expired.
RETURN_REQUESTED_BY_RECIPIENTRecipient requested return.
EXTERNAL_IDENTIFIER_DETAILS_HAVE_CHANGEDExternal identifier details have changed.
TECHNICAL_ISSUE (available v5.0.0 onwards)Payment failed due to a technical issue
TECHNICAL_ISSUE_RETRYABLE (available v5.0.0 onwards)Payment failed due to a technical issue, Wise will retry
REASON_NOT_SPECIFIEDReason not specified.

Notes about payout failures

  • Payout failures can occur while a transfer remains in outgoing_payment_sent. Not every payout failure triggers a transfer state change.
  • A transfer may emit multiple transfers#payout-failure events.
    • Not every rejected transfer (for example bounced_back or funds_refunded) will have a corresponding transfers#payout-failure webhook.
  • Wise may add new failure codes over time. Your system should handle unrecognised codes.

Testing payout failures in the sandbox

Before you can test payout failures, you must create and fund a transfer in the sandbox. Once you have a funded transfer and have the transferID, you can test payout failures using the following steps:

Step 1: Simulate transfer into bounced_back

Use the simulation transfer state change endpoint to move the transfer through states in order:

processingfunds_convertedoutgoing_payment_sentbounced_back

This ensures the transfer is in the correct state for payout failure simulation.

Step 2: Trigger payout failure

Use the simulation payout failure endpoint.

You can do either of the following:

  • Omit the body to get a random failure reason (for the transfer’s route/currency pair).
  • Specify a particular failure_reason_code in the body.
application/json
{}

Step 3: Verify the webhook you receive

After you trigger the simulation, Wise sends a transfers#payout-failure webhook to your subscribed endpoint.

  • Treat failure_reason_code as the stable machine-readable value.
  • Use failure_description for display/logging, but don’t hard-depend on the exact text.
  • Store/trace transfer_id, occurred_at, and (in your logs) the request x-trace-id to simplify support/debugging.
  • Be prepared for new reason codes over time (fallback messaging).