Skip to main content

Error Codes

All errors return JSON with error, code, fix, and docs fields, plus an X-Request-Id header.

{
"error": "Human-readable error message",
"code": "error_code",
"fix": "Suggested action to resolve the error",
"docs": "https://docs.vonpay.com/reference/error-codes#error_code"
}

HTTP Status Codes

CodeMeaningCommon Causes
400Bad RequestInvalid request body, missing required fields, validation failure
401UnauthorizedMissing or invalid Authorization: Bearer token
404Not FoundSession ID doesn't exist
409ConflictSession is in the wrong state (e.g., already completed)
410GoneSession has expired (30-minute TTL)
429Too Many RequestsRate limit exceeded
500Internal Server ErrorUnexpected server error

Error Codes Reference

CodeHTTPDescription
auth_missing_bearer401No Authorization: Bearer header provided
auth_invalid_key401API key is malformed or does not exist
auth_key_expired401Key has rotated past its grace window or been force-deactivated mid-rotation
auth_key_type_forbidden403Publishable key used on a secret-only endpoint, or sandbox/live mode mismatch
auth_merchant_inactive401Merchant account is disabled or suspended
merchant_not_onboarded403Merchant application is pending_approval or denied — live-key creation blocked until merchant-onboarding review completes
auth_service_unavailable503Authentication service is temporarily unavailable
session_not_found404Session ID does not exist
session_expired410Session has expired (30-minute TTL)
session_wrong_state409Session is in the wrong state for this operation
session_integrity_error500Internal session state mismatch — contact support
validation_error400Request body failed schema validation
validation_missing_field400A required field is missing from the request body
validation_invalid_amount400Amount is not a positive integer or exceeds maximum
merchant_not_configured422Merchant is missing required configuration (e.g., payment provider credentials)
rate_limit_exceeded429Per-IP rate limit — retry after the Retry-After interval
rate_limit_exceeded_per_key429Per-API-key rate limit (30 session-creates/min) — contact support if you need a higher ceiling
provider_unavailable502Upstream payment provider is not responding
provider_attestation_failed403Payment provider rejected the attestation (Vora browser-side token handoff failed)
provider_charge_failed402Card declined or charge rejected by the upstream provider
internal_error500Unexpected server error
webhook_missing_signature401Webhook request is missing the signature header
webhook_invalid_signature401Webhook signature does not match the expected value
webhook_not_configured503Webhook verification secret is not configured on the server
origin_forbidden403Request origin is not in the merchant's allowed origins list
transaction_verification_failed403Transaction could not be verified with the payment provider
unsupported_media_type415Content-Type header is missing or not application/json

27 codes total.

Rate-limit buckets are documented on the Rate Limits page.

Validation Errors (400)

Validation errors include a descriptive message from the schema validator:

{
"error": "Expected number, received string at \"amount\"",
"code": "validation_error",
"fix": "Ensure 'amount' is a positive integer in minor units (e.g., 1499 for $14.99)",
"docs": "https://docs.vonpay.com/reference/error-codes#validation_error"
}

Common validation issues:

FieldRule
amountMust be a positive integer (1–99,999,999)
currencyMust be exactly 3 characters
countryMust be exactly 2 characters
successUrlMust be HTTPS (localhost exempt in sandbox)
lineItemsMax 100 items
metadata valuesMax 500 characters each

Debugging

Every response includes X-Request-Id. When contacting support, include this ID for fast issue resolution.

X-Request-Id: a1b2c3d4e5f6

Per-code reference

Each error code emitted in a response body (docs field) links to its section below. The stub anchors exist today so docs: URLs always resolve to a real page; full content (fix recipes, common causes, SDK behavior) lands in an upcoming release as part of the webhook launch documentation sweep.

auth_missing_bearer

HTTP: 401. The request did not include an Authorization: Bearer <key> header. Add the header with your vp_sk_* or vp_pk_* key.

auth_invalid_key

HTTP: 401. The API key is malformed, unknown, or has been revoked. Check the prefix (vp_sk_test_, vp_sk_live_, vp_pk_test_, vp_pk_live_) and confirm the key exists in /dashboard/developers/api-keys. If you just rotated, double-check the grace window hasn't expired.

auth_key_expired

HTTP: 401. Key rotated past its 24-hour grace window, or was force-deactivated mid-rotation. Distinct from auth_invalid_key so SDKs can detect rotation and fetch a fresh key instead of failing the request. Get a fresh key from /dashboard/developers/api-keys.

auth_key_type_forbidden

HTTP: 403. Primary cause: a publishable key (vp_pk_*) used against a secret-only endpoint like GET /v1/sessions/:id. Also fires on sandbox/live-mode mismatches. The fix field on the response tells you exactly what to switch to.

merchant_not_onboarded

HTTP: 403. You tried to create a live-mode API key (POST /api/merchants/api-keys with mode=live), but your merchant application is still awaiting ops review (pending_approval) or has been denied. Test-mode keys (vp_sk_test_*) remain self-serve at any time via /dashboard/developersCreate sandbox; live-mode key issuance is gated on merchant-application review. If approval is pending, check /dashboard/settings for your application status and any outstanding requirements; if denied, contact Von Payments support with the details provided in your denial notice. Distinct from auth_merchant_inactive (401) which fires on a previously-approved account that has since been deactivated.

auth_merchant_inactive

HTTP: 401. The merchant account has been disabled or suspended. Check /dashboard for status banners; contact support if unexpected.

auth_service_unavailable

HTTP: 503. The authentication service is temporarily unavailable. This is retriable — the SDK auto-retries with backoff.

session_not_found

HTTP: 404. The session ID does not exist. Sessions are scoped to the merchant; you cannot look up another merchant's session with your key. Confirm the ID was created with the same key mode you're now querying with.

session_expired

HTTP: 410. The session has expired (default 30-minute TTL). Create a new session.

session_wrong_state

HTTP: 409. The session is in a state that forbids this operation (e.g. the session already succeeded and cannot be cancelled). Read the response body — the fix field describes the allowed state transitions.

session_integrity_error

HTTP: 500. Internal session state mismatch. Rare; indicates session metadata in the database no longer matches an invariant the runtime expects. Capture the X-Request-Id and contact support — this is not safely retriable without investigation.

validation_error

HTTP: 400. The request body failed schema validation. The response error field contains a human-readable message from the validator, including the path to the bad field.

validation_missing_field

HTTP: 400. A required field is missing. See Create a Session for the required fields.

validation_invalid_amount

HTTP: 400. Amount is not a positive integer, is zero, or exceeds the 99,999,999 maximum. Remember: amounts are in minor units1499 = $14.99, not $1,499.

merchant_not_configured

HTTP: 422. The merchant has not completed onboarding for this operation — usually payment-provider credentials are not yet provisioned. Complete boarding via the merchant dashboard, or contact support.

rate_limit_exceeded

HTTP: 429. Per-IP bucket exceeded. Retry after the Retry-After interval. SDK auto-retries up to maxRetries times.

rate_limit_exceeded_per_key

HTTP: 429. Per-API-key bucket exceeded on POST /v1/sessions (30 session creates/min). A single key should not exceed this under normal traffic. If your integration legitimately does, contact support for a ceiling increase. Distinct from rate_limit_exceeded so SDKs can tell them apart.

provider_unavailable

HTTP: 502. Upstream payment provider is not responding. Retriable — the SDK auto-retries with backoff.

provider_attestation_failed

HTTP: 403. The upstream payment provider rejected the browser-side attestation step during a Vora-orchestrated checkout. Common causes: amount mismatch between the attestation and the session, attestation window expired, session integrity mismatch, or the attested scope (e.g., Aspire "RUO") is not supported for this card. Fix: verify the session amount matches the attestation payload, or create a new session and re-attest. Not safely retriable without investigation when the cause is a scope / integrity mismatch — capture the X-Request-Id before retrying. The specific provider-native reason (e.g. ATTESTATION_EXPIRED, ATTESTATION_INVALID, MERCHANT_MISMATCH) is included in the error message so the buyer can be shown a more specific hint in your UI.

provider_charge_failed

HTTP: 402. The upstream payment provider returned a terminal charge failure — card declined, insufficient funds, fraud-rule block, or a network-side decline (issuer, scheme, or processor). Fix: prompt the buyer to try a different payment method. Retrying the same card/session is unlikely to succeed and may trigger additional issuer-side flags. This is distinct from provider_unavailable (transient infrastructure) and transaction_verification_failed (post-charge reconciliation mismatch).

internal_error

HTTP: 500. Unexpected server error. Capture the X-Request-Id and contact support.

webhook_missing_signature

HTTP: 401. Webhook request did not include the X-VonPay-Signature header. Only relevant if your endpoint rejects the delivery — the error is emitted by your code, not by Von Payments.

webhook_invalid_signature

HTTP: 401. Webhook signature does not match the expected HMAC. Check you're HMAC'ing the raw request body (not the parsed JSON), using the right secret (merchant API key for session webhooks; subscription secret for v2). See Webhook Signature Verification.

webhook_not_configured

HTTP: 503. Webhook verification secret is not configured on the Von Payments server side. This is an infra-level misconfiguration, not a merchant-side issue. Capture the X-Request-Id and contact support.

origin_forbidden

HTTP: 403. The request origin is not in the merchant's allowed-origins list. Add the origin at /dashboard/branding (checkout origin allowlist).

transaction_verification_failed

HTTP: 403. Transaction could not be verified with the payment processor. Contact support with the X-Request-Id — this is not safely retriable without investigation (a transaction either exists on the processor or it doesn't).

unsupported_media_type

HTTP: 415. The Content-Type header is missing or not application/json. Set Content-Type: application/json on all POST/PUT requests.