PayintoDocs

Error handling

Understand error responses and how to react to them.

Errors share one shape, and the HTTP status tells you what kind of problem occurred:

{
  "status": "error",
  "message": "Could not find the account.",
  "timestamp": 1793404800000
}

Show message to developers, not end users, and don't match on its exact wording because it can change.

Status codes

StatusMeaningWhat to do
200, 201SuccessRead data
400The request could not be completed, or a record was not foundRead message and fix the request
401The key is missing, invalid, or expiredCheck your key
403The key is not allowedCheck message, your IP allowlist, and your modules
404The record or route does not existCheck the ID and the environment
409The merchant_reference was already used with different dataUse a new reference, or resend the original request
422One or more fields are invalidFix the fields listed in errors
429You hit the rate limitWait for Retry-After, then retry
500Payinto or a provider failedQuery the status, then retry if it's safe

A status to watch

Several lookups, such as GET /customers/{id}, return 400 rather than 404 when a record doesn't exist.

Validation errors

A 422 lists each invalid field under errors:

{
  "status": "error",
  "message": "One or more of the given data has an error.",
  "errors": {
    "account_number": ["The account number field must be 10 digits."]
  },
  "timestamp": 1793404800000
}

Retrying money movement safely

A timeout or a 500 doesn't tell you whether the money moved. Never retry a payment blindly.

Send a merchant_reference with every transfer and bill payment.

If the request fails with a timeout or a 500, call GET /transactions/tsq/{reference} with your merchant_reference.

If the transaction exists, use its status. If you get 404, retry with the same merchant_reference and the same payload.

Repeating a merchant_reference is safe because Payinto returns the original result instead of paying twice.

Transaction statuses

GET /transactions/tsq/{reference} returns one of these in data.status:

StatusMeaning
pendingStill processing. Check again later, or wait for a webhook.
successfulComplete.
failedDid not complete.
reversedCompleted and later reversed.

On this page