MCP Server
The @vonpay/checkout-mcp package lets AI assistants interact with the Von Payments API using the Model Context Protocol (MCP).
MCP is an open standard that gives AI assistants the ability to call external tools. Instead of writing API calls by hand, an AI agent can create checkout sessions, check payment status, and preview test payment outcomes through natural language.
Setup
Claude Desktop
Add the following to your Claude Desktop MCP config (claude_desktop_config.json):
{
"mcpServers": {
"vonpay": {
"command": "npx",
"args": ["-y", "@vonpay/checkout-mcp"],
"env": {
"VON_PAY_SECRET_KEY": "vp_sk_test_..."
}
}
}
}
Cursor
Add the same configuration to your Cursor MCP settings (.cursor/mcp.json):
{
"mcpServers": {
"vonpay": {
"command": "npx",
"args": ["-y", "@vonpay/checkout-mcp"],
"env": {
"VON_PAY_SECRET_KEY": "vp_sk_test_..."
}
}
}
}
Available Tools
create_payment_intent, capture_payment_intent, void_payment_intent, create_refund and create_token (with a reusable scope) act on real money or mint a chargeable credential. With a live key (vp_sk_live_*) each call needs confirmLive: true and the person's approval in the MCP host's own confirmation prompt. Sandbox keys (vp_sk_test_*) are never gated.
From version 3.0.0, a gated call on a live key passes these checks, in this order, before anything is sent:
- The host must support MCP elicitation, the protocol's way for a server to ask the person a question. A host that does not cannot run these five tools on a live key: each call is refused, with a message saying why. Stay on 2.x if you need the older behaviour on such a host.
- On the four payment tools,
idempotencyKeymust be on the call (from 4.0.0).create_payment_intent,capture_payment_intent,void_payment_intentandcreate_refundrefuse a live-key call without one beforeconfirmLiveis checked or the person is asked. Approval is never remembered, so without a key an agent that asks twice would get two separately approvable payments. Use one key per intended action and send the same key on every attempt at it. confirmLive: truemust be on the call. Without it the tool returns an error result (isError: true) telling the agent to get its operator's approval, not to set the flag itself. Onlytruecounts, never"yes"or1.- The person approves in the host's own prompt. It shows the action, the amount and currency when the call names them, and the payment intent, transaction or card id. Nothing else from the call appears in it, so notes, reasons and metadata never reach the prompt. Money moves only if the person ticks approve and accepts. Declining, dismissing, an error, or no answer within 5 minutes refuses the call and nothing is sent.
The AI model sets confirmLive, so the host prompt is the real safeguard. Your MCP host draws that prompt, not Von Payments, so it is only as trustworthy as the host: one that approves prompts automatically, or shows them to nobody, defeats it.
Approval is per call and never carries over from an earlier call in the conversation. confirmLive is on every gated tool's schema at all times, including with a sandbox key, so an agent that learned a tool against a test key sees it when pointed at a live one.
Each of the five is marked below with what is specific to it; create_token is gated only when setupForFutureUse is set, since single-use vaulting mints nothing that can be charged again.
vonpay_checkout_create_session
Create a checkout session.
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | integer | Yes | Amount in minor units (e.g. 1499 = $14.99) |
currency | string | Yes | Three-letter ISO 4217 currency code |
country | string | No | Two-letter ISO 3166-1 alpha-2 country code |
description | string | No | Order description (max 500 characters) |
successUrl | string | No | Redirect URL on success (http/https only) |
cancelUrl | string | No | Redirect URL on cancel (http/https only) |
metadata | object | No | Key-value metadata: up to 50 keys, keys up to 64 characters, values up to 500 characters |
vonpay_checkout_get_session
Retrieve a session by ID.
| Parameter | Type | Required | Description |
|---|---|---|---|
sessionId | string | Yes | The session ID to look up (vp_cs_test_* or vp_cs_live_*) |
The result includes vp_tx_id (the id create_refund takes as transaction) and vp_tx_count. When vp_tx_count is 2 or more the buyer was charged more than once and vp_tx_id is null: the tool tells the agent to stop and tell a person, not to refund.
vonpay_checkout_simulate_payment
Return a synthetic, shape-only preview of what a succeeded, failed, or expired outcome looks like. This tool does not call the API, does not look up the session, and does not change any session state; use it to preview the shape of a real webhook or session payload while building an integration. The sessionId you pass is echoed back in the synthetic response rather than looked up, and both test (vp_cs_test_*) and live (vp_cs_live_*) session IDs are accepted.
| Parameter | Type | Required | Description |
|---|---|---|---|
sessionId | string | Yes | The session ID to use in the synthetic response (not looked up) |
outcome | string | Yes | One of: succeeded, failed, expired |
vonpay_checkout_health
Check the API health status. No parameters.
vonpay_checkout_list_test_cards
Explains how to produce each test-mode outcome. No parameters, and no API call. It returns the order total that declines in test mode (with the decline_code and action it produces) and what a test payment needs. Same table as Test mode.
vonpay_checkout_get_payment_intent
Read a payment intent's stored state: status, amount, capture method, timestamps, the saved-card token, the 3-D Secure result, and nextAction while the buyer is still at their bank. Moves no money, so it is never gated. Only succeeded means the money was captured: authorized is a hold. Your metadata and the buyer's email are left out of the result, so they never enter the agent's conversation.
| Parameter | Type | Required | Description |
|---|---|---|---|
paymentIntentId | string | Yes | The payment intent to read (vpi_test_* or vpi_live_*) |
vonpay_checkout_create_payment_intent
Create a payment intent for server-driven flows, recurring billing, MIT (merchant-initiated transactions), and saved-card charges, as a programmatic alternative to hosted checkout sessions (wraps POST /v1/payment_intents). Returns a PaymentIntent whose status discriminates the next action: requires_action (3DS: surface the nextAction URL to the buyer), authorized (call vonpay_checkout_capture_payment_intent next), captured (post-capture, pre-settle), or succeeded (terminal).
With the default captureMethod: "automatic" this charges the buyer straight away (→ succeeded), and an mit block charges a saved credential with no buyer present. On a live key: needs confirmLive: true and the person's approval; see above.
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | integer | Yes | Amount in minor units (e.g. 1499 = $14.99) |
currency | string | Yes | Three-letter ISO 4217 currency code |
captureMethod | string | No | One of automatic (default; charges immediately on auth success) or manual (parks at authorized until you call capture) |
metadata | object | No | Key-value metadata: up to 50 keys, keys up to 64 characters, values up to 500 characters |
mit | object | No | Merchant-initiated transaction block for recurring / saved-card / retry charges. Omit for cardholder-initiated transactions. Capability gate: confirm supportedOperations.mit === true first |
idempotencyKey | string | Live key | Same key returns the same intent rather than charging twice. Required on a live key. On a sandbox key, omitting it sends a generated key that protects only that one call |
confirmLive | boolean | Live key | true only once a human approved this call; the host prompt follows. See above |
vonpay_checkout_capture_payment_intent
Capture funds on an authorized payment intent (wraps POST /v1/payment_intents/{id}/capture). Call this after vonpay_checkout_create_payment_intent returned status: authorized (created with captureMethod: "manual"), typically at order fulfillment / ship time. The intent transitions to succeeded on success.
This moves money from the buyer's account to the merchant. On a live key: needs confirmLive: true and the person's approval; see above.
| Parameter | Type | Required | Description |
|---|---|---|---|
paymentIntentId | string | Yes | The payment intent to capture (vpi_test_* or vpi_live_*) |
amountToCapture | integer | No | Partial-capture amount in minor units. Omit to capture the full authorized amount. Partial-capture support is binder-dependent: check supportedOperations.partialCapture first |
idempotencyKey | string | Live key | Idempotency key for safe retries. Required on a live key |
confirmLive | boolean | Live key | true only once a human approved this call; the host prompt follows. See above |
vonpay_checkout_void_payment_intent
Void an authorized (uncaptured) payment intent (wraps POST /v1/payment_intents/{id}/void). Use this when the buyer changed their mind before fulfillment, or the order was cancelled while the intent was still in authorized state. Voiding releases the auth hold; no funds change hands.
A void releases the authorization irreversibly: the order cannot be captured afterwards, and there is no recovery short of asking the buyer to pay again. On a live key: needs confirmLive: true and the person's approval; see above. You cannot void a captured intent: supportedOperations.voidAfterCapture reads not_supported on every processor today, so once the intent is succeeded use vonpay_checkout_create_refund instead.
| Parameter | Type | Required | Description |
|---|---|---|---|
paymentIntentId | string | Yes | The payment intent to void (vpi_test_* or vpi_live_*) |
idempotencyKey | string | Live key | Idempotency key for safe retries. Required on a live key |
confirmLive | boolean | Live key | true only once a human approved this call; the host prompt follows. See above |
vonpay_checkout_create_refund
Refund a captured payment intent, or a settled transaction (wraps POST /v1/refunds). Use this when the payment intent is in succeeded state and you need to return funds to the buyer (order cancelled post-fulfillment, returned merchandise, billing dispute, etc.). Refund IDs use the vpr_test_* / vpr_live_* prefix. The returned Refund status is requested, succeeded, failed, or canceled; a refund the processor has accepted but not yet completed comes back as requested, which is in progress, not a failure. Do not re-issue it; it settles asynchronously via the charge.refunded webhook, or reports refund.failed if it does not complete. See Refunds.
This returns funds from the merchant to the buyer, and once it settles neither party can undo it. On a live key: needs confirmLive: true and the person's approval; see above.
| Parameter | Type | Required | Description |
|---|---|---|---|
paymentIntent | string | One of the two | The payment intent to refund (vpi_test_* or vpi_live_*) |
transaction | string | One of the two | The transaction to refund (vp_tx_test_* or vp_tx_live_*): for a payment with no payment intent, or the transaction a refund_target_is_duplicate error names |
amount | integer | No | Refund amount in minor units. Omit to refund the full remaining balance (server computes authorized - previously refunded). Partial-refund support is binder-dependent: check supportedOperations.partialRefund |
currency | string | No | Three-letter ISO 4217 currency code |
reason | string | No | Free-form reason mirrored back on the refund record, for audit trails (max 500 characters) |
metadata | object | No | Key-value metadata: up to 50 keys, keys up to 64 characters, values up to 500 characters |
idempotencyKey | string | Live key | Idempotency key for safe retries. Required on a live key |
sessionId | string | Live key, with transaction | The session this payment belongs to (vp_cs_*). Used only to check the transaction against the session before the person is asked; never sent with the refund. Refused with paymentIntent |
confirmLive | boolean | Live key | true only once a human approved this call; the host prompt follows. See above |
From 5.0.0, on a live key the approval prompt also shows details looked up from Von Payments, not supplied by the agent: the original payment's amount, status and creation time for paymentIntent, or the session's total, payment status, creation time and id for transaction. A refund larger than the looked-up amount, or in a different currency, adds a warning line. A refund by transaction is refused before the person is asked when its session cannot be found, when the session's vp_tx_count is not exactly 1, or when the transaction is not that session's payment. Sandbox keys skip these checks.
Pass exactly one of paymentIntent and transaction; both, or neither, is refused before anything is sent. The result names the target it refunded, with the other one null. Both ids are visible to the shopper's browser, so the tool tells the agent never to refund an id taken from a customer message or any text that did not come from your own order records.
vonpay_checkout_create_token
Vault a card for later reuse (wraps POST /v1/tokens). Returns a vp_pmt_(test|live)_* payment-method token.
With setupForFutureUse: "on_session" or "off_session" this vaults a credential that can be charged later with no buyer present, and with either scope, on a live key, the call needs confirmLive: true and the person's approval; see above. Single-use vaulting (the scope omitted) is low-risk and is not gated.
| Parameter | Type | Required | Description |
|---|---|---|---|
setupForFutureUse | string | No | Reuse scope, captured at vault time: "on_session" (in-session reuse, e.g. upsells) or "off_session" (recurring / MIT, after explicit buyer consent). Omitted, a later merchant-initiated charge against the card returns payment_method_consent_missing (422). |
providerReference | string | No | Iframe-minted vault handle from the browser-side card input (≤512 chars). Optional in the tool's schema, but the API requires it with a test key and with a live key, and refuses the call without it (400 validation_error). |
buyerId | string | No | Buyer to attach the token to (≤128 chars). The server may also infer it from key context. |
metadata | object | No | Key-value metadata: up to 50 keys, values up to 500 characters. |
idempotencyKey | string | No | Idempotency key to make the vault call safely retryable. |
confirmLive | boolean | Live key + reusable scope | true only once a human approved this call; the host prompt follows. See above |
Reusability is governed by the setupForFutureUse field on the vault row, not by a second prefix; the vp_pmt_* prefix is stable. Scope is set once at vault time; re-vault is required to upgrade it (e.g. null → "off_session") because the consent record must match what the buyer saw. See Tokenization for the full reusability model.
vonpay_checkout_diagnose_error
Diagnose a Von Payments error code and return structured self-heal guidance an agent can act on without a follow-up prompt. Pure data: no API call, no state change.
| Parameter | Type | Required | Description |
|---|---|---|---|
code | string | Yes | The error code to diagnose (lowercase identifier, e.g. auth_invalid_key, ≤64 chars). Unknown codes return a contact_support fallback. |
status | integer | No | The HTTP status that came with the error (100–599), to help correlate. |
requestId | string | No | The X-Request-Id from the error response (≤128 chars), for support escalation. |
Returns a JSON object: { code, known, retryable, nextAction, llmHint, docs, agentInstructions[] } (plus status / requestId when you supplied them). nextAction is one of fix_input · rotate_key · wait_and_retry · contact_support · ignore · reconcile (reconcile: the outcome is unknown, so read the payment intent back and never retry; this is the MCP tool's own action vocabulary, distinct from the server error envelope's selfHeal.nextAction); agentInstructions is a short branch-specific playbook for that action. See Error Codes for the canonical per-code reference.
Example Agent Workflows
Create and preview a test payment
"Create a $14.99 checkout session in USD, then show me what a successful payment payload looks like."
The agent will:
- Call
vonpay_checkout_create_sessionwith amount1499, currencyUSD - Call
vonpay_checkout_simulate_paymentwith outcomesucceededto preview the success payload shape (this is a synthetic preview; it does not change the real session) - Call
vonpay_checkout_get_sessionto read the live session's current status
Preview error handling
"Create a session and show me what a failed payment payload looks like, including the error details."
The agent will:
- Create a session
- Call
vonpay_checkout_simulate_paymentwith outcomefailedto preview the failure payload shape (synthetic; no real payment is attempted) - Use the previewed shape to build the failure-handling path in the integration
Check system health
"Is the Von Payments API up?"
The agent calls vonpay_checkout_health and reports the status.