Use your own card form. Your backend sends card details straight to the card vault and gives Wegopay only an opaque token for one payment.
Activation required
Hosted checkout is the default. Card capture must be enabled for your merchant, separately for sandbox and live. Your backend handles card data, so it must meet the card-handling requirements agreed during onboarding.
The payment ID. Returns short-lived capture access.
3. Capture the card
Your backend → card vault
Raw card fields. Returns a token and reference.
4. Pay
Your backend → Wegopay
The token and reference
5. 3D Secure, if required
Customer browser → action URL
Nothing; the existing challenge resumes
6. Verify and fulfill
Your backend ↔ Wegopay
Payment reads and signed webhooks
Raw card data never reaches a Wegopay endpoint. Your API key, the capture secret and the token stay on your backend. Only the action URL goes to the customer’s browser.
Create the payment as usual with a stored Idempotency-Key, adding "checkoutMode": "custom". Until capture is enabled for your merchant and environment, this returns 422. Save data.id against the order.
Merchant and environment scoped custom checkout state and capture coordinates.
dataobject
paymentIdstring <uuid>
amountCentsinteger500–100000000
currencystring
AlwaysUSD
referencestring1–255 chars
statusstring
One ofopenprocessingrequiresActionpaidfailed_retryableexpired
expiresAtstring <date-time>
attemptsLeftinteger0–5
environmentstring
Immutable provider account selection derived from the API key. Omit environment on creation or provide the same environment as the key; a mismatch is rejected. Test keys can only access sandbox payments and live keys can only access live payments.
One ofsandboxlive
pciConfigobject
providerstring
AlwayspciVault
captureUrlstring <uri>1–2048 chars
Absolute URL parsed by a standards-compliant URL parser. Production permits HTTPS only. HTTP is accepted only when the hostname is exactly localhost, 127.0.0.1, or ::1 in development. Credentials and fragments are forbidden; hostnames are canonicalized before validation.
vaultIdstring1–31 chars
Random payment-scoped capture reference; never your order reference. The server-owned dedicated vault key establishes payment isolation.
allowedOriginstring <uri>
iframeUrlstring <uri>optional1–2048 chars
Present only with a hosted form configured for the merchant checkout origin. Direct capture credentials are returned by POST capture.
terminalReasonstringoptional
Why a checkout closed. A provider failure is not a local link timeout.
One ofcheckout_expiredattempts_exhaustedprovider_failed
actionUrlstring <uri>optional1–2048 chars
Open in the customer browser only when payment requiresAction; existing checkout resumes the challenge without card collection.
captureobjectoptional
urlstring <uri>1–2048 chars
Absolute URL parsed by a standards-compliant URL parser. Production permits HTTPS only. HTTP is accepted only when the hostname is exactly localhost, 127.0.0.1, or ::1 in development. Credentials and fragments are forbidden; hostnames are canonicalized before validation.
secretstring16–4096 chars
Write-only capture secret. Keep on your backend; never log.
referencestring1–31 chars
expiresAtstring <date-time>
Malformed path, header, or strict JSON request.
Error codesinvalid_request
errorobject
codestring
Alwaysinvalid_request
messagestring
Missing, malformed, unknown, revoked, or disabled-merchant API key.
Error codesunauthorized
HeadersWWW-Authenticate
errorobject
codestring
Alwaysunauthorized
messagestring
Unknown or unauthorized resource/token, without existence disclosure.
Error codesnot_found
errorobject
codestring
Alwaysnot_found
messagestring
Existing checkout fence prevents another charge attempt.
data.capture holds the url, secret, reference and expiresAt. Access ends at most ten minutes after the payment was created, or earlier if checkout expires.
Retrying returns the same access; it does not extend it.
Never log this response or return it to a browser.
From your backend, post the card to capture.url with the capture secret. This request goes to the card vault, not to Wegopay.
Node.js · your backend → card vault
const response = await fetch(prepared.capture.url, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-PCIVault-Capture-Secret': prepared.capture.secret,
},
body: JSON.stringify({
card_number: card.number,
card_cvv: card.cvv,
card_expiry_month: card.month, // "MM"
card_expiry_year: card.year, // "YY", not "YYYY"
}),
redirect: 'error',
})
if (!response.ok) thrownew Error('Card capture rejected')
const captured = await response.json()
if (captured.reference !== prepared.capture.reference) thrownew Error('Capture reference mismatch')
// Store captured.token and captured.reference encrypted against this payment// before submitting them. Never store the raw card.
Use the exact URL and secret Wegopay returned. The capture reference is not your order reference; do not change it. See the vault capture API for the response format.
Wegopay checks that the token belongs to this payment, merchant and environment, and revokes capture access. Tokens from another payment are rejected. A payment accepts one card: to use a different card, wait for a final non-paid outcome and create a new payment.
The response data.status is paid, requiresAction or failed (with attemptsLeft). It is the result of this attempt; read the payment for the final status.
When the status is requiresAction, redirect the customer’s browser to data.actionUrl (also available from GET /v1/payments/{id}/checkout). The Wegopay page resumes the challenge without asking for the card again, including after a reload. Your backend cannot complete the challenge itself.
Prefer the action page. If Wegopay has approved your own action handling, call POST /v1/payments/{id}/confirm with {} after the customer completes the action.
Poll GET /v1/payments/{id}/status from your backend with backoff (for example 2s, 5s, then 10s). Stop when checkout is closed or a customer action is required, and respect 429. Then read GET /v1/payments/{id} and fulfill only on a verified paid match, as with hosted checkout.
Retry with the identical body and the original idempotency key. Never create another payment for a lost response.
Capture times out or no token
Do not pay or capture again blindly. Keep the payment and contact Wegopay.
Pay times out, 409 or 503
Poll the payment first. Keep the original token and reference for recovery; do not switch cards.
Capture expired, 410
Access cannot be refreshed. Settle the existing attempt before creating a new payment.
Definitive retryable decline
Retry only with the same token, within expiry and the attempt limit.
404
Check the ID, environment and activation. Unknown, foreign and hosted payments look the same.
Keep secrets out of logs
Disable request and response body logging for these calls in your backend, proxies, tracing and error reporting. Card details, tokens, capture secrets and action URLs must never be logged.
Download the Node.js backend example. It validates the capture destination, expiry and reference, stores the token before paying, polls status, and verifies before fulfillment. It makes no requests when imported. Plug in your own order storage and redirect handling.
With a sandbox key, capture 4242 4242 4242 4242 for a payment without 3D Secure and 4000 0025 0000 3155 for one with a challenge. Use a new payment for each. See sandbox testing.