Handle bill payment API errors by their effect on the order

Distinguish invalid input, access problems and uncertain purchase outcomes so API errors lead to a useful customer action and safe order recovery.

Already registered? Open API settings and follow the business-access steps. Sandbox purchases do not deliver real services.

Reviewed

The same 'Try again' button is a poor response to every payment error. A mistyped decoder number needs correction. A disabled API key needs an operator. A purchase whose response was lost needs investigation before another submission.

Separate transport status from order status

First check whether you received a usable HTTP response. Then inspect the documented error envelope or transaction body. An accepted purchase can still have data.attributes.status set to pending, while a network timeout may leave you without any transaction body at all.

Keep an explicit unresolved state in your own order model for cases where you cannot yet determine the outcome. Do not convert an unknown result into failed merely to make the screen simpler.

SituationApplication response
Invalid recipient or missing required inputLet the customer correct it before a new authorized submission
Missing scope, disabled access or invalid credentialsAlert an operator; do not ask the customer to fix the API key
Product unavailableOffer current choices and obtain a new confirmation
Rate limit reachedDelay work within a bounded retry policy
Duplicate referenceRetrieve the existing transaction and reconcile it
Timeout or unusable purchase responsePreserve the order and look up its saved reference

Use codes for decisions

Read error.code when a valid error envelope is present. Handle known codes deliberately and use a conservative fallback for an unrecognized response. Keep the raw technical detail in access-controlled diagnostics, with secrets and customer data redacted.

Customer copy should describe what your application actually knows. Say that a purchase is still being checked when it is unresolved. Say that money has been refunded only when the relevant refund or ledger record supports that claim. A provider failure alone is not proof that your own customer's payment has been returned.

Make recovery find the original order

Persist the external reference before submission. When a purchase response is lost, use /account/transactions/YOUR_STORED_REFERENCE to find the record; if you already saved the transaction ID, read /purchases/:id. Match the result to the authorized local order before changing its state.

If a lookup cannot establish an outcome, retain the unresolved order and escalate according to your support process. Do not generate another reference just to get past uncertainty or a date-boundary validation.

Test a non-JSON response, an unknown error code, a missing transaction body and a duplicate reference. Verify that none of these cases displays raw exception text, invents a refund or silently sends another purchase.