Errors
Interpret OmniPay error envelopes, HTTP status codes, and H2H-specific failures.
Errors use a stable JSON envelope:
{
"error": {
"code": "invalid_request",
"message": "amount: Amount must be a plain positive decimal with at most 2 decimal places"
}
}Use error.code for program logic and keep message for logs and operator
display. Messages may become more specific without a version change.
Capture the X-Request-Id response header with every failure. It lets OmniPay
support find the exact request without requiring sensitive credentials or payer
data.
const payload = await response.json();
if (!response.ok) {
const requestId = response.headers.get("X-Request-Id");
console.error("OmniPay request failed", {
requestId,
status: response.status,
code: payload.error?.code,
});
throw new Error(payload.error?.code ?? "omnipay_request_failed");
}Codes
| Code | Typical HTTP | Meaning |
|---|---|---|
invalid_request | 400 | Body, parameter, mode, amount, phone, or request signature input is invalid |
unauthorized | 401 | API key or required H2H signature is missing/invalid |
forbidden | 403 | The organization or feature is not enabled |
insufficient_balance | 403 | Withdrawal balance cannot cover amount plus commission |
not_found | 404 | Resource is absent or belongs to another organization |
transaction_not_found | 404 | Transaction lookup failed |
conflict | 409 | Resource state conflicts with the operation |
merchant_id_exists | 409 | Merchant ID is already used |
method_unavailable | 503 | The requested payment method is temporarily unavailable |
internal_error | 500 | Unexpected server failure |
H2H authentication messages
An H2H 401 may identify:
missing_signature;invalid_timestamp;stale_signature;invalid_signature;- an API key without a rotated H2H signing secret.
Do not fall back to unsigned H2H requests. Fix the signing problem or rotate the credential.
Verification conflicts
The verify endpoint uses 409 when:
- the deposit is terminal or its submission deadline has passed;
- a different verification attempt is active;
- three distinct transaction IDs have already been used;
- the transaction ID was submitted elsewhere for the same payment method;
- the deposit has a
redirectaction, which is confirmed automatically.
These are state conflicts, not transport failures. Read the deposit before deciding whether operator or payer input is needed.
Logging safely
Log request IDs, OmniPay deposit IDs, merchant IDs, status codes, error codes, and attempt IDs. Redact API keys, H2H signing secrets, full Authorization headers, payer credentials, and raw signing inputs that may contain sensitive metadata.