Skip to main content

REST API

For developers not using Node.js. Call the API directly with any HTTP client.

Base URL

https://checkout.vonpay.com

Authentication

All merchant-facing endpoints require a Bearer token:

Authorization: Bearer vp_sk_live_xxx

Endpoints

Create Session

curl -X POST https://checkout.vonpay.com/v1/sessions \
-H "Authorization: Bearer vp_sk_live_xxx" \
-H "Content-Type: application/json" \
-H "Von-Pay-Version: 2026-04-14" \
-H "Idempotency-Key: unique_key_123" \
-d '{
"amount": 1499,
"currency": "USD",
"country": "US",
"successUrl": "https://mystore.com/confirm",
"lineItems": [{"name": "Widget", "quantity": 1, "unitAmount": 1499}]
}'

Response (201):

{
"id": "vp_cs_live_k7x9m2n4p3",
"checkoutUrl": "https://checkout.vonpay.com/checkout?session=vp_cs_live_k7x9m2n4p3",
"expiresAt": "2026-03-31T15:30:00.000Z"
}

Get Session Status

curl https://checkout.vonpay.com/v1/sessions/vp_cs_live_k7x9m2n4p3 \
-H "Authorization: Bearer vp_sk_live_xxx" \
-H "Von-Pay-Version: 2026-04-14"

Health Check

curl https://checkout.vonpay.com/api/health

No authentication required.

The full server-side resource setPOST /v1/payment_intents (+ /capture, /void), POST /v1/refunds, POST /v1/tokens, and GET /v1/capabilities — is documented per-resource in API Reference, Payment Intents, Refunds, Tokens, and Capabilities, and in full in the OpenAPI spec. They're all plain HTTP with the same Bearer-token auth shown above.

Webhook Subscriptions

Programmatically manage your webhook endpoints. Secret key only (vp_sk_*) — publishable keys receive 403. Reads are limited to 100/min per key; writes (create / update / delete / rotate / test) to 30/min per key.

MethodPathDescription
GET/v1/webhook_subscriptionsList subscriptions (cursor pagination)
POST/v1/webhook_subscriptionsCreate a subscription
GET/v1/webhook_subscriptions/{id}Retrieve a subscription
PATCH/v1/webhook_subscriptions/{id}Update a subscription
DELETE/v1/webhook_subscriptions/{id}Delete a subscription
POST/v1/webhook_subscriptions/{id}/rotate_signing_secretRotate the signing secret
POST/v1/webhook_subscriptions/{id}/send_test_eventSend a signed test event
GET/v1/webhook_events/{id}Retrieve a delivered event record

This management API is camelCase end to end (enabledEvents, signingSecret, lastDeliveryAt); the delivered event payload is snake_case (see below). Cross-merchant or cross-mode access returns an opaque 404 (never 403).

Create a subscription

curl -X POST https://checkout.vonpay.com/v1/webhook_subscriptions \
-H "Authorization: Bearer vp_sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"url": "https://mystore.com/webhooks/vonpay",
"enabledEvents": ["charge.succeeded", "charge.refunded"],
"description": "Order fulfillment"
}'

Response (201) — includes the signing secret, returned only once:

{
"id": "b6f2c1a0-3e4d-4c8b-9a1f-2d5e7c9b0a13",
"object": "webhook_subscription",
"url": "https://mystore.com/webhooks/vonpay",
"enabledEvents": ["charge.succeeded", "charge.refunded"],
"status": "active",
"description": "Order fulfillment",
"signingSecret": "whsec_3f9a2b...",
"apiVersion": "2026-04-14",
"lastDeliveryAt": null,
"lastSuccessAt": null,
"lastErrorAt": null,
"createdAt": "2026-06-18T12:00:00.000Z"
}
Save the signing secret now

signingSecret (the whsec_… value) is returned only on create and on rotate_signing_secret — never on reads. Store it immediately; if you lose it, rotate to get a new one. You need it to verify the x-vonpay-signature header on every delivery.

Selectable events

The event types you can pass in enabledEvents:

EventFires when
charge.succeededA charge is captured
charge.failedA charge attempt fails
charge.refundedA charge is refunded (full or partial)
payment_intent.succeededA payment intent reaches succeeded
payment_intent.failedA payment intent fails
payment_intent.cancelledA payment intent is voided / cancelled

Other catalog event types (session.*, dispute.*) are modeled in the SDK's WebhookEvent type so your handler can switch on type forward-compatibly. Always handle an unrecognized type gracefully.

Update, rotate, delete

# Pause without deleting (stops deliveries; keeps the config + secret)
curl -X PATCH https://checkout.vonpay.com/v1/webhook_subscriptions/b6f2c1a0-3e4d-4c8b-9a1f-2d5e7c9b0a13 \
-H "Authorization: Bearer vp_sk_live_xxx" -H "Content-Type: application/json" \
-d '{"status": "paused"}'

# Rotate the signing secret (returns a new whsec_ once)
curl -X POST https://checkout.vonpay.com/v1/webhook_subscriptions/b6f2c1a0-3e4d-4c8b-9a1f-2d5e7c9b0a13/rotate_signing_secret \
-H "Authorization: Bearer vp_sk_live_xxx"

# Delete
curl -X DELETE https://checkout.vonpay.com/v1/webhook_subscriptions/b6f2c1a0-3e4d-4c8b-9a1f-2d5e7c9b0a13 \
-H "Authorization: Bearer vp_sk_live_xxx"

PATCH accepts any of url, enabledEvents, description, and status:

statusBehavior
activeReceives deliveries normally.
pausedStops deliveries; config + signing secret retained. Resume by patching back to active.
disabledSystem-suspended (e.g. after sustained failures / auto-pause). Resume by patching to active once your endpoint is healthy.

Send a test event

curl -X POST https://checkout.vonpay.com/v1/webhook_subscriptions/b6f2c1a0-3e4d-4c8b-9a1f-2d5e7c9b0a13/send_test_event \
-H "Authorization: Bearer vp_sk_live_xxx" -H "Content-Type: application/json" \
-d '{"eventType": "charge.succeeded"}'

The response is synchronous — it reports exactly what your endpoint returned to the signed test delivery:

{
"delivered": true,
"response_status": 200,
"delivery_attempt_id": "vp_wda_test_...",
"signature_preview": "t=1749000000",
"error": null
}

delivered: false with a non-null response_status means your endpoint was reached and returned a non-2xx — useful for confirming your error handling, not a failure of the test itself.

Refund event payload

charge.refunded delivers the following under data (snake_case):

FieldTypeNotes
transaction_idstringSettlement-ledger id of the original charge (vp_tx_*)
refund_idstring | nullIdentifies which refund in a multi-partial sequence (vpr_*)
amountnumberRefund amount in minor units — not the original charge total
currencystringISO-4217, uppercase
reasonstring | nullOne of customer_request, duplicate, fraudulent, other
is_partialboolean | nullTrue when amount < original_charge_amount
original_charge_amountnumber | nullFull charge total before refund — compute remaining refundable balance from this
session_id, payment_intent_idstring | nullSource ids; null on flows where they don't apply

The subscription's apiVersion (pinned at create time) governs the delivered payload shape; the event envelope itself carries no per-event version field. See Webhook events for every event's payload and Signature verification for the x-vonpay-signature contract.

Rate Limits

EndpointLimit
POST /v1/sessions10/min per IP, 30/min per API key
GET /v1/sessions/:id30/min per IP
POST /api/checkout/init, /api/checkout/complete20/min per IP
POST /api/webhooks/* (inbound provider)100/min per IP
GET /v1/webhook_subscriptions, /v1/webhook_subscriptions/:id, /v1/webhook_events/:id100/min per API key
POST/PATCH/DELETE /v1/webhook_subscriptions/* (create / update / delete / rotate / test)30/min per API key

See Rate Limits for the full bucket list.

Rate-limited responses return 429 with Retry-After, X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers.

Error Format

All errors return JSON with a flat envelope. Every error also carries a selfHeal object — machine-readable retry guidance for SDKs and agents:

{
"error": "Human-readable error message",
"code": "validation_invalid_amount",
"fix": "Amount must be a positive integer in minor units (cents). 1499 = $14.99",
"docs": "https://docs.vonpay.com/integration/create-session#required-fields",
"selfHeal": {
"retryable": false,
"nextAction": "fix_request",
"llmHint": "Machine-readable guidance for SDKs and agents."
}
}

Every response includes an X-Request-Id header for debugging. See Error Codes for the full envelope and the selfHeal contract.

OpenAPI Spec

The full API specification is available at checkout.vonpay.com/openapi.yaml. Import it into Postman, Insomnia, or any OpenAPI-compatible tool.