Skip to main content

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​

Five of these tools move money: on a live key a person approves each call in your MCP host

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:

  1. 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.
  2. On the four payment tools, idempotencyKey must be on the call (from 4.0.0). create_payment_intent, capture_payment_intent, void_payment_intent and create_refund refuse a live-key call without one before confirmLive is 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.
  3. confirmLive: true must 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. Only true counts, never "yes" or 1.
  4. 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.

ParameterTypeRequiredDescription
amountintegerYesAmount in minor units (e.g. 1499 = $14.99)
currencystringYesThree-letter ISO 4217 currency code
countrystringNoTwo-letter ISO 3166-1 alpha-2 country code
descriptionstringNoOrder description (max 500 characters)
successUrlstringNoRedirect URL on success (http/https only)
cancelUrlstringNoRedirect URL on cancel (http/https only)
metadataobjectNoKey-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.

ParameterTypeRequiredDescription
sessionIdstringYesThe 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.

ParameterTypeRequiredDescription
sessionIdstringYesThe session ID to use in the synthetic response (not looked up)
outcomestringYesOne 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.

ParameterTypeRequiredDescription
paymentIntentIdstringYesThe 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).

Charges immediately unless you ask for manual capture

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.

ParameterTypeRequiredDescription
amountintegerYesAmount in minor units (e.g. 1499 = $14.99)
currencystringYesThree-letter ISO 4217 currency code
captureMethodstringNoOne of automatic (default; charges immediately on auth success) or manual (parks at authorized until you call capture)
metadataobjectNoKey-value metadata: up to 50 keys, keys up to 64 characters, values up to 500 characters
mitobjectNoMerchant-initiated transaction block for recurring / saved-card / retry charges. Omit for cardholder-initiated transactions. Capability gate: confirm supportedOperations.mit === true first
idempotencyKeystringLive keySame 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
confirmLivebooleanLive keytrue 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.

Transfers the funds

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.

ParameterTypeRequiredDescription
paymentIntentIdstringYesThe payment intent to capture (vpi_test_* or vpi_live_*)
amountToCaptureintegerNoPartial-capture amount in minor units. Omit to capture the full authorized amount. Partial-capture support is binder-dependent: check supportedOperations.partialCapture first
idempotencyKeystringLive keyIdempotency key for safe retries. Required on a live key
confirmLivebooleanLive keytrue 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.

Releasing the hold cannot be undone

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.

ParameterTypeRequiredDescription
paymentIntentIdstringYesThe payment intent to void (vpi_test_* or vpi_live_*)
idempotencyKeystringLive keyIdempotency key for safe retries. Required on a live key
confirmLivebooleanLive keytrue 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.

A settled refund cannot be reversed

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.

ParameterTypeRequiredDescription
paymentIntentstringOne of the twoThe payment intent to refund (vpi_test_* or vpi_live_*)
transactionstringOne of the twoThe 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
amountintegerNoRefund 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
currencystringNoThree-letter ISO 4217 currency code
reasonstringNoFree-form reason mirrored back on the refund record, for audit trails (max 500 characters)
metadataobjectNoKey-value metadata: up to 50 keys, keys up to 64 characters, values up to 500 characters
idempotencyKeystringLive keyIdempotency key for safe retries. Required on a live key
sessionIdstringLive key, with transactionThe 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
confirmLivebooleanLive keytrue 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.

A reusable scope mints a chargeable credential

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.

ParameterTypeRequiredDescription
setupForFutureUsestringNoReuse 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).
providerReferencestringNoIframe-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).
buyerIdstringNoBuyer to attach the token to (≤128 chars). The server may also infer it from key context.
metadataobjectNoKey-value metadata: up to 50 keys, values up to 500 characters.
idempotencyKeystringNoIdempotency key to make the vault call safely retryable.
confirmLivebooleanLive key + reusable scopetrue 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.

ParameterTypeRequiredDescription
codestringYesThe error code to diagnose (lowercase identifier, e.g. auth_invalid_key, ≤64 chars). Unknown codes return a contact_support fallback.
statusintegerNoThe HTTP status that came with the error (100–599), to help correlate.
requestIdstringNoThe 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:

  1. Call vonpay_checkout_create_session with amount 1499, currency USD
  2. Call vonpay_checkout_simulate_payment with outcome succeeded to preview the success payload shape (this is a synthetic preview; it does not change the real session)
  3. Call vonpay_checkout_get_session to 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:

  1. Create a session
  2. Call vonpay_checkout_simulate_payment with outcome failed to preview the failure payload shape (synthetic; no real payment is attempted)
  3. 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.