Failure modes
Two rules make this table short. First, the bank refuses a payment it cannot apply before acknowledging it to NIBSS, so a refused payment never moves money and never needs reversing. Second, the bank credits your account before it tries to tell you, so a notification failure is never a money failure.
The NIBSS codes are what the payer’s bank receives; its app shows its own wording for them. 06 is declined, 07 is account not found, 13 is invalid amount, 61 is limit exceeded, 97 is system error.
At name enquiry and credit
Section titled “At name enquiry and credit”| Failure | What the payer sees | What you see | What to do |
|---|---|---|---|
| Expired number (TTL elapsed or you expired it) | Name enquiry 06 once the sweep has run, or a name followed by a refused credit 06 in the minutes before it. |
Number EXPIRED on Virtual accounts. No inflow row. |
Issue a new number with a new external_ref. If the payer insists they paid, ask for their session id; a refusal is on their bank’s side. |
| Single-use number already paid | Name enquiry 06; credit 06. |
Number USED. One inflow row, for the first payment. |
The second payer must be given a fresh number. The first payment stands. |
| Wrong amount on an exact-amount number | Name enquiry succeeds (it carries no amount); credit refused 13. |
Nothing: no inflow row, no notification. | Decide whether the number should have been exact. Recreate with exact_amount: false or the right amount. The payer’s money never left their account. |
| Wrong amount on a partner-maintained band (band fixed or minimum amount, or an amount you enforced at name enquiry) | Credit refused 13. |
Nothing. | Check what you returned at the last enquiry for that number: an amount you forgot to clear refuses every later payment. |
| Unknown number (never issued, or outside any band) | Name enquiry 07; credit 07. |
Nothing. | Confirm the number against Virtual accounts. In the current build a number from createFVA is refused this way on the bank’s bridge path; see the caution on Create a non-expiring virtual account. |
| Settlement account cannot take credits (frozen, closed, restricted, dormant) | Name enquiry may succeed on a bank-issued number; credit refused 06. |
Nothing on Inflows; your account’s status on Accounts. | Contact the bank about the account. Numbers pointing at it start working again when it does. |
| Band suspended or not yet approved | Name enquiry 07; credit 07. |
Numbers you created still list, but nothing lands. | The bank switched the band off. Ask why. A band closed only to new numbers keeps accepting payments on existing ones; that case fails at creation instead, with 0096 No allocatable LOCAL virtual account range. |
| Limit on the receiving customer (velocity or KYC tier cap) | Credit refused 61. |
Nothing. | Raise with the bank; it is a configured limit on the account or tier. |
| Your validation endpoint unreachable (partner-maintained band) | Name enquiry 97. The payer’s bank may retry. |
No credit, no notification. | Fix the endpoint. Enquiries resume as soon as it answers. A decline you returned on purpose is 07, not 97. See Your validation endpoint. |
| NIBSS cannot confirm credits (bank-side) | 91, beneficiary bank unavailable. |
Nothing. | Nothing on your side; the payer retries later. |
After the money has landed
Section titled “After the money has landed”| Failure | What the payer sees | What you see | What to do |
|---|---|---|---|
| Your notification endpoint down (partner-maintained band) | Nothing; their transfer succeeded. | Inflow row present. Notification RETRYING, then FAILED after 48 attempts over about 24 minutes. HTTP status and error text on the row. |
The credit is in your account. Apply it from Inflows, then Resend once the endpoint is back, or let the bank resend. Dedupe on reference. See Your payment notification endpoint. |
| No notification URL on the band | Nothing. | Notification SKIPPED. |
Ask the bank to set the URL. Nothing is retried until it is; use the export meanwhile. |
| Webhook subscription failing (bank-issued band) | Nothing. | Notification FAILED with the webhook outcome. |
See Delivery and retries. A 4xx from you is final; a 5xx is retried for about five days. |
| Notification or webhook received twice | Nothing. | Two deliveries for one reference or X-Webhook-Id (a retry after a slow 2xx, or a resend). |
Answer 2xx both times; credit once. |
| Reversal by the sending bank | Their bank returns the money. | Inflow REVERSED; transaction.reversed webhook on a bank-issued band, nothing on a partner-maintained band. |
Reverse your fulfilment. Include REVERSED rows in every reconciliation run. |
Duplicate external_ref on create |
Nothing; no number was issued. | 0096 VA creation failed: Duplicate external reference. |
The first call succeeded. Look the number up by external_ref on Virtual accounts or via GET /api/virtual-accounts/by-account/{accountNumber}; do not retry with the same reference. |
beneficiary_account that is not yours |
Nothing; the number works. | Payments settle to the account you named. | The create call does not check ownership of this field. Expire the number, issue another with the right account, and contact the bank about money already settled. |
X-Agent-Account you may not read |
Nothing; no number was issued. | 0012 Account ... is not linked to this API client. |
Use your own account or a sub-agent’s you onboarded, with sub-agent access enabled. See Ownership errors. |
In the portal
Section titled “In the portal”Virtual accounts answers whether a number is live. Inflows answers whether money landed and whether you were told, with the HTTP status and error of each attempt on partner-maintained bands and the Resend action.