Skip to content

When something fails

The table that settles almost every question

Section titled “The table that settles almost every question”
What you see Retry? How
status: "submitted" No Wait for the webhook. It is already in progress
status: "unknown" NEVER It resolves on its own. Retrying here is how you pay twice
status: "failed" + a data reason Yes, after fixing Fix the beneficiary and request another quote
status: "failed" + a payment network reason Yes Another quote, without changing anything else
502 upstream_error Yes Retry with the same Idempotency-Key
503 no_route_available Yes, later There is no payment network right now for that bank/method
429 rate_limited Yes, slower Respect Retry-After
Validation 4xx Not without fixing The same body will fail the same way

What we do while the payment is in doubt:

  1. Nothing is compensated. The entry stays as it is.

  2. We query the payment network with our reference, with increasing backoff.

  3. It gets resolved: paid → settled; it does not recognize the reference after several queries → it is compensated and ends up failed; returned → reversed.

  4. We notify you by webhook. No polling needed.

To keep an eye on it:

Ventana de terminal
curl -s "$BASE/v1/payments?status=unknown&limit=100" -H "x-api-key: $KEY"

The entry is already reversed and you have not been charged anything (feeAmount: "0", compensated: true). Retry with another quote as soon as you fix the cause, which is in reason:

reason Whose problem it is Useful retry
beneficiary_missing_phone Yours: the beneficiary’s mobile number is missing for pago móvil After adding phone
beneficiary_missing_account Yours: the account is missing After adding it
beneficiary_mismatch Yours: name or national ID do not match the holder After fixing it. No payment network would accept it
invalid_destination_account Yours: the account does not exist or is wrong After fixing it
sender_required Yours: there was no sender By sending the sender block
sender_phone_unsupported The payment network’s: none available accepted the sender’s international phone number With a Venezuelan mobile number for the sender, or later
amount_below_minimum The amount’s: below the payment network’s floor By raising the amount
amount_above_limit The amount’s: above the ceiling By splitting it
bank_unreachable The payment network’s: it does not cover that bank Another one was already tried; check the method’s catalog
payout_insufficient_balance The paying account’s: no balance for the payment and the fee After topping it up, or later
payout_balance_unavailable The payment network’s: the balance could not be read, nothing was sent Yes, in a few seconds
no_route The combination’s: no payment network available Try the other method

If the method you asked for is not available and methodPolicy is preferred (the default), the payment goes out through the other one:

{ "status": "submitted", "method": "transferencia",
"methodRequested": "pago_movil", "methodChanged": true }

The status is still submitted: the method switch already happened, but the transfer is still settling. With methodPolicy: "strict" the payout fails instead of switching method.

Days later, the bank may return a transfer (closed account, wrong data). The event is verified and deduplicated, the entry is reversed —the payment moves to reversed and the funds go back to your balance— and you receive payment.reversed with the reason the bank reported. Your part is to let your user know.

We retry with increasing backoff (5 s → 6 h, 12 attempts). Once they run out, the event goes to your failed queue, queryable and redeliverable.

Ventana de terminal
curl -s "$BASE/v1/events?status=dead" -H "x-api-key: $KEY"
curl -s -X POST "$BASE/v1/events/retry-dead" -H "x-api-key: $KEY"

See webhooks.

Each case can be triggered in the test environment: mode: "reject" with method for the method switch, mode: "timeout_after_submit" for the payment in doubt, /sandbox/bank/payout-settled and /sandbox/bank/payout-returned for late confirmation and return, and /sandbox/webhooks/failing for your retries.

Ventana de terminal
curl -s -X POST $BASE/sandbox/chaos -H 'content-type: application/json' \
-d '{"mode":"timeout_after_submit"}'