Skip to main content
Every failure returns the same body, whichever endpoint was called. It carries the same envelope fields as a successful response, with message in place of data:
Branch on code, not on the message text. The wording may be reworded; the status will not. transaction_id is present when the call reached the source, so a failed call gives you the same reference to quote as a successful one. It is null when the request never got that far, such as a rejected key or a request that failed validation.

Retrying safely

  • 429, 503 and 504 are transient. Retry with exponential backoff.
  • 502 indicates a source-side failure rather than a problem with your request. A retry may work; do not retry in a tight loop.
  • Any other 4xx will not change on retry. Fix the request, or wait for the state to change in the case of 409.
A penny drop moves one rupee into the account being verified. Retrying it repeats that transfer and is charged again. Retry it only when you have received no response at all, and never automatically on a 4xx.

A 200 is not always a yes

Bank verification returns 200 even when the account could not be checked: the transport worked, the verification did not. In those responses message carries the reason and the fields below it are absent:
Read message before anything else, and treat a missing account_exists as “not answered” rather than as “no”. Reasons include an offline beneficiary bank, an unavailable NPCI, a declining source bank, and an account the method cannot reach, such as an NRE account. PAN behaves the same way: a status other than valid with a populated remarks, such as Holder is Deceased, arrives on a successful call.