What this protection does
Some bank corridors protect a destination after a recent bank rejection. When the same normalized destination was rejected recently, CBPay stops the next create before it creates a payout, debits the balance, or consumes the idempotency key. The protection is scoped to the account and the normalized combination ofbank_code, account_number, and tax_id. Changing capitalization or
formatting does not bypass it.
Safe sequence
- If the first response is ambiguous, replay the exact request with the same
idempotency_key. This returns the original resource withidempotency_hit: true; it never creates a second payout. - If the response is
destination_recently_rejected, the original key was not consumed. Review the bank rejection and decide whether the destination should be retried. - A deliberate retry uses a new idempotency key and
options.destination_retry_ackset to the most recent rejected payout ID. - Reusing the old key with changed options returns
409 idempotency_conflict; it never changes the original operation. - A destination with no recent rejection, or a payout on another corridor, follows its normal validation and dispatch path.
Deliberate retry request
Response examples
Recent rejection
Changed options with the old key
States and actions
FAQ
Does the 422 create a payout?
Does the 422 create a payout?
No. The guard runs before payout insertion and before the debit. It also does
not consume the submitted idempotency key.
Can I retry with the same key after the 422?
Can I retry with the same key after the 422?
Yes, if you are replaying the exact original request. A deliberate retry after
reviewing the rejection must use a new key and the acknowledgement option.
Why does changing only options return 409?
Why does changing only options return 409?
Request options are part of the idempotency payload. Reusing a key with changed
options is a different request, so CBPay rejects it instead of silently
changing the original operation.
Does this apply to every payout corridor?
Does this apply to every payout corridor?
No. The protection is applied only where the corridor enables it. Other rails
and destinations without a recent matching rejection follow their existing
validation and dispatch flow.