Skip to main content

API Reference

The complete Von Payments Checkout API is documented in OpenAPI 3.1 format.

OpenAPI Spec

openapi.yaml — import into Postman, Insomnia, Redocly, or any OpenAPI tool.

Three front-end integration paths

VORA provides three front-end integration paths. All vault a vp_pmt_* payment method and settle through Payment Intents — the server-side engine that handles authorization, capture, refunds, and voids. Pick the path that fits your integration:

  • Hosted Checkout (Sessions)POST /v1/sessions returns a checkout URL. You redirect the buyer to it; Von Payments hosts the card form, handles 3DS, and redirects back to your successUrl/cancelUrl. Simplest path.
  • Embedded Fields — browser SDK (@vonpay/vora-js) that mounts card / email / address / cardholder elements directly on your page. Submit behavior depends on how the session is configured: under tokenize-only behavior, submit returns a vp_pmt_* token your server charges via Payment Intents; under charge-and-save behavior, submit charges and (with a buyer on the session) vaults a reusable vp_pmt_* in one step, while guest sessions charge once and return no token. On charge-and-save you must not also call POST /v1/payment_intents for that session — doing so double-charges. Uses the publishable-key /v1/public/* endpoints from the browser.
  • Elements (custom) — same @vonpay/vora-js SDK with integrationMode:"elements" on POST /v1/sessions. Discrete card fields you position and style on your page, plus optional standalone Apple Pay / Google Pay buttons. Highest UI control; tokenize to vp_pmt_* and charge via Payment Intents.

Payment Intents (server-side engine)POST /v1/payment_intents creates an intent your server controls directly for authorization → capture → refund → void. All three front-end paths vault a vp_pmt_* and settle through Payment Intents. Best for delayed-capture flows, fraud-check-before-capture, subscriptions, or direct server-driven transactions where no buyer redirect is needed. See the Payment Intents guide.

See Choose your integration for the side-by-side comparison.

Endpoints Summary

Get session status

GET /v1/sessions/{id} returns the full status of a previously-created session. Requires a secret key (vp_sk_*); publishable keys are rejected with auth_key_type_forbidden. See Session Object for the response shape.

Session statuses

A checkout session has one of five statuses: pending, processing, succeeded, failed, or expired. The normal flow is pending → processing → succeeded (or → failed / → expired); a session may also move directly pending → succeeded/failed/expired. Not all transitions are one-way: a processing session can revert to pending, and a failed session can later converge to succeeded on a successful retry (success takes precedence). Only succeeded and expired are terminal. See Session Object — Status Lifecycle.

Payment intent statuses

Payment intents progress through a discrete lifecycle of six statuses: requires_action → authorized → captured → succeeded (or voided / failed). On the manual-capture path, authorized → captured → succeeded runs as three discrete steps; on the automatic-capture path, an authorized intent can move straight to succeeded when settlement is synchronous. See the Payment Intents guide for the full state machine, transition rules, and error envelope.

MethodPathAuthDescription
POST/v1/sessionsPublishable or SecretCreate a checkout session (Hosted Checkout) — the only endpoint publishable keys can call
POST/v1/sessions?dry_run=truePublishable or SecretValidate params without creating a session
GET/v1/sessions/{id}SecretGet session status
POST/v1/payment_intentsSecretCreate a payment intent (auth or auth+capture) — see guide
POST/v1/payment_intents/{id}/captureSecretCapture an authorized intent (full or partial via amount_to_capture)
POST/v1/payment_intents/{id}/voidSecretVoid an authorized intent (before capture)
POST/v1/refundsSecretRefund a succeeded payment intent (full or partial via amount)
POST/v1/tokensSecretMint a vp_pmt_* payment-method token from a provider vault reference (provider_reference)
GET/v1/capabilitiesPublishable or SecretPer-merchant capability matrix (supported_operations, settlement_currencies, rate_limits)
GET/v1/public/sessions/{id}PublishableBrowser-safe session lookup — used by Embedded Fields SDK
POST/v1/public/binder-loadPublishablePer-processor element capability map (Embedded Fields)
POST/v1/public/tokensPublishableBrowser-side vp_pmt_* minting (Embedded Fields)
GET/api/healthNoneHealth check (add ?deep=true for deep variant)

Endpoints marked "internal" are called by the hosted checkout page, not by merchants. Inbound provider-webhook endpoints exist server-side under /api/webhooks/... for processor-to-platform delivery; they are not part of the merchant API surface and integrators never call them.

Authentication

Merchant-facing endpoints use Bearer token auth:

Authorization: Bearer vp_sk_live_xxx

Test keys use the vp_sk_test_ prefix. Live keys use vp_sk_live_.

Most endpoints require a secret key (vp_sk_*). The exceptions are session creation (POST /v1/sessions, including its dry_run variant) and GET /v1/capabilities, which accept either key type, and the /v1/public/* endpoints, which require a publishable key (vp_pk_*). Publishable keys can only create sessions and call the public browser endpoints; they are rejected on secret-only routes with auth_key_type_forbidden (HTTP 403).

Request Headers

HeaderRequiredDescription
AuthorizationYesBearer API key. The accepted key type depends on the endpoint — secret (vp_sk_*) for most routes, publishable (vp_pk_*) for the /v1/public/* endpoints, and either type for session creation and GET /v1/capabilities.
Content-TypeConditionalapplication/json on the browser/public POST endpoints (/v1/public/sessions/{id}/confirm, /v1/public/tokens), which reject a missing or non-JSON type with HTTP 415 unsupported_media_type. The authenticated REST POST endpoints (/v1/sessions, /v1/payment_intents, /v1/refunds, /v1/tokens) parse the JSON body without a Content-Type check, but sending application/json is recommended for all POST requests.
Von-Pay-VersionNoAPI version date string (e.g. 2026-04-14). If omitted, the request uses the current API version. Pin this header to avoid breaking changes when the API evolves.
Idempotency-KeyNoUnique key to prevent duplicate operations. If you retry a request with the same key, the original response is returned instead of creating a duplicate. Recommended for all POST requests in production. Max 255 printable-ASCII characters. See Idempotency below for retention.

Response Headers

Every response includes:

HeaderDescription
X-Request-IdUnique request ID for debugging

The three rate-limit headers X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset are returned on every rate-limited response — both successful responses and 429 responses. Retry-After is returned only on 429 responses. See Rate Limits.

Idempotency

Idempotency-Key is enforced per-resource: a key is unique to (merchant_id, idempotency_key) on the resource it created (session, payment intent, refund). A replayed key with a matching request body returns the original response. A replayed key with a different request body returns HTTP 422 idempotency_replay_incompatible — the SDK surfaces this loudly so a buggy retry that changed amount, cart, or redirect URLs cannot silently inherit a prior resource.

Retention. Idempotency keys are bound to the row they created, not to a separate cache with a fixed TTL. A replayed key returns the same resource for as long as the row is retained on our side — effectively the lifetime of the resource record. Use unique keys per attempt (e.g. order_123_attempt_1, order_123_attempt_2) rather than reusing a key across attempts that could legitimately differ.

Format. Max 255 characters, printable ASCII only (codepoints 0x20–0x7E). Whitespace-only keys are treated as no key.

Errors

session_already_completed is returned as HTTP 409 Conflict, distinct from session_expired's HTTP 410 Gone. The 409 is not returned by POST /v1/sessions (the create endpoint); it is returned by the public completion and read endpoints — GET /v1/public/sessions/{id}, POST /v1/public/tokens, and POST /v1/public/sessions/{id}/confirm — when a duplicate or late completion lands on a session that has already reached succeeded. Branch on code: never create a new session for a 409 (the buyer already paid — that would re-charge), whereas a 410 means the session TTL elapsed and you may create a fresh one.

Rate Limits

Full bucket list and handling rules: Rate Limits.