API Documentation
Use the Payclave API to create checkout sessions, issue invoices, verify payment records, and deliver signed webhook events while funds move directly from the customer wallet to the merchant wallet.
Getting started
Configure a merchant settlement wallet, create API keys from the dashboard, and send customers to Payclave hosted checkout. Payclave handles checkout orchestration and marks invoices paid only after independent onchain verification.
Quickstart
The recommended production integration starts on your server. Create a checkout session with a secret key, then redirect the customer to the returned hosted checkout URL.
Idempotency-Key when creating checkout sessions so a network retry does not create duplicate merchant-side effects. Reuse it only with the same request payload.Create a checkout session
curl https://api.payclave.com/v1/checkout-sessions \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order_8431" \
-d '{
"amount": "25.00",
"customerEmail": "customer@example.com",
"externalReference": "order_8431",
"successUrl": "https://merchant.example/orders/8431/success",
"cancelUrl": "https://merchant.example/cart",
"metadata": {
"cartId": "cart_8431"
}
}'Payclave SDKs
The recommended way to integrate Payclave checkout is by using one of our official SDKs. Browser libraries cover public-key checkout flows, while the TypeScript server SDK supports backend checkout-session and invoice creation with secret keys.
Install packages
npm install @payclave/sdk-server
npm install @payclave/sdk-js
npm install @payclave/sdk-reactAuthentication
Send API keys as a bearer token in theAuthorizationheader or throughX-API-Key. Publishable keys can create limited checkout sessions. Secret keys are required for server-side invoices, payment reads, and webhook endpoints.
Authenticate a request
curl https://api.payclave.com/v1/invoices/INV-PCLV-17791920002731 \
-H "Authorization: Bearer sk_test_..."
curl https://api.payclave.com/v1/checkout-sessions \
-H "X-API-Key: pk_test_..."- Name
pk_test_*- Description
- Public test key for browser checkout creation.
- Name
sk_test_*- Description
- Secret test key for server-side API calls.
- Name
pk_live_*- Description
- Public live key for live checkout creation.
- Name
sk_live_*- Description
- Secret live key. Keep this on your backend only.
Errors
All API responses include asuccessboolean and a request id inmeta.requestId.
Error response
{
"success": false,
"error": {
"code": "INVALID_AMOUNT",
"message": "Amount must be a positive USDT value with up to 6 decimals.",
"details": {
"field": "amount"
}
},
"meta": {
"requestId": "req_..."
}
}Handling errors
Branch on the stableerror.codevalue, logmeta.requestIdfor support, and keeperror.detailsfor field-level context. Retry only timeout, network, 429, and 5xx failures, and reuse the sameIdempotency-Keyfor retrying a checkout-session or invoice creation request.
RATE_LIMIT_EXCEEDEDresponse can include aRetry-Afterheader. Treat validation, authentication, forbidden, not-found, and state-conflict errors as terminal until the request input or merchant configuration changes.Handle SDK errors
import {
createPayclaveServerClient,
PayclaveError,
} from "@payclave/sdk-server"
const payclave = createPayclaveServerClient({
secretKey: process.env.PAYCLAVE_SECRET_KEY!,
})
try {
const session = await payclave.createCheckoutSession({
amount: "25.00",
externalReference: "order_8431",
idempotencyKey: "order_8431",
})
return Response.json({ checkoutUrl: session.checkoutUrl })
} catch (error) {
if (error instanceof PayclaveError) {
console.error(error.code, error.status, error.requestId, error.details)
if (error.code === "RATE_LIMIT_EXCEEDED" || error.status >= 500) {
// Retry later with the same Idempotency-Key.
}
}
throw error
}API error codes
- Name
API_KEY_REQUIRED- Description
- No API key was sent with a protected merchant API request.
- Name
INVALID_API_KEY- Description
- The API key is malformed, revoked, expired, or not found.
- Name
API_KEY_FORBIDDEN- Description
- The key is valid but cannot access the requested endpoint.
- Name
AUTH_REQUIRED- Description
- A dashboard session is required for this web app request.
- Name
AUTH_FORBIDDEN- Description
- The signed-in user cannot access the selected merchant.
- Name
VALIDATION_ERROR- Description
- The request body or query parameters failed validation.
- Name
INVALID_AMOUNT- Description
- Amount is not a valid positive USDT decimal.
- Name
INVALID_EXPIRY- Description
- Checkout or invoice expiry is outside the accepted range.
- Name
INVALID_IDEMPOTENCY_KEY- Description
- Idempotency-Key is empty, too long, or contains invalid characters.
- Name
IDEMPOTENCY_KEY_CONFLICT- Description
- The same Idempotency-Key was used with a different request.
- Name
DEFAULT_WALLET_REQUIRED- Description
- The merchant must configure an active settlement wallet.
- Name
UNSUPPORTED_DEFAULT_WALLET- Description
- The configured settlement wallet is not supported for this flow.
- Name
WALLET_PAYMENTS_UNAVAILABLE- Description
- Payment orchestration is unavailable in this environment.
- Name
CHECKOUT_SESSION_NOT_PAYABLE- Description
- The checkout is expired, terminal, or not ready for payment.
- Name
NOT_FOUND- Description
- The requested checkout session, invoice, payment, or resource was not found.
- Name
INVOICE_NOT_FOUND- Description
- The invoice record could not be found.
- Name
INVOICE_STATE_MISMATCH- Description
- The invoice changed state before the requested operation completed.
- Name
INVOICE_TRANSITION_GUARD_FAILED- Description
- The requested invoice status transition is not allowed.
- Name
INVALID_WALLET_ADDRESS- Description
- A wallet or token address is not a valid EVM address.
- Name
INVALID_TX_HASH- Description
- The transaction hash is not a valid EVM transaction hash.
- Name
INVALID_WALLET_PAYMENT_ATTEMPT- Description
- Wallet payment intent, signature, source token, or source chain input is invalid.
- Name
INVALID_DEPOSIT_NETWORK- Description
- The requested scan-or-copy deposit network is not supported.
- Name
SCAN_OR_COPY_UNAVAILABLE- Description
- Scan-or-copy payment instructions are temporarily unavailable for the selected route.
- Name
REQUEST_ERROR- Description
- An upstream provider request failed or returned an unusable response.
- Name
WEBHOOK_ENDPOINT_NOT_FOUND- Description
- The webhook endpoint could not be found.
- Name
WEBHOOK_DELIVERY_NOT_FOUND- Description
- The webhook delivery could not be found.
- Name
WEBHOOK_EVENT_UNSUPPORTED- Description
- The webhook event type is unsupported or not enabled for the endpoint.
- Name
WEBHOOK_SIGNATURE_INVALID- Description
- A received provider webhook signature is missing or invalid.
- Name
RATE_LIMIT_EXCEEDED- Description
- The request exceeded the current endpoint or key rate limit.
- Name
INTERNAL_SERVER_ERROR- Description
- Payclave could not complete the request because of an internal failure.
- Name
INTERNAL_JOB_UNAUTHORIZED- Description
- The internal job runner endpoint was called without valid authorization.
SDK error codes
- Name
INVALID_PUBLIC_KEY- Description
- Browser SDK received an invalid pk_test or pk_live key.
- Name
INVALID_SECRET_KEY- Description
- Server SDK received an invalid sk_test or sk_live key.
- Name
INVALID_API_BASE_URL- Description
- Server SDK apiBaseUrl must be a valid http or https URL without query or hash parts.
- Name
INVALID_TIMEOUT- Description
- Server SDK timeoutMs must be a positive integer number of milliseconds.
- Name
INVALID_ID- Description
- Server SDK lookup helpers require a non-blank resource identifier.
- Name
INVALID_REFERENCE- Description
- Browser checkout input is missing a merchant reference.
- Name
INVALID_AMOUNT- Description
- SDK input amount failed client-side validation.
- Name
INVALID_EXPIRY- Description
- Server SDK expiry input is outside the 5 minute to 24 hour range.
- Name
INVALID_IDEMPOTENCY_KEY- Description
- Server SDK idempotency key failed client-side validation.
- Name
INVALID_METADATA- Description
- Server SDK metadata must be a JSON object.
- Name
INVALID_LIMIT- Description
- Server SDK list limit must be an integer from 1 to 100.
- Name
INVALID_WEBHOOK_URL- Description
- Server SDK webhook endpoint URLs must be valid http or https URLs.
- Name
INVALID_REQUEST_BODY- Description
- Server SDK request payload could not be serialized as JSON.
- Name
INVALID_RESPONSE- Description
- The SDK could not parse Payclave's response shape.
- Name
NETWORK_ERROR- Description
- The SDK request failed before receiving a usable HTTP response.
- Name
TIMEOUT- Description
- The SDK request exceeded its configured timeout.
- Name
ABORTED- Description
- The SDK request was cancelled with an AbortSignal.
- Name
REDIRECT_UNAVAILABLE- Description
- Browser SDK redirectToCheckout was called without a redirect handler outside the browser.
Webhook verification errors
- Name
WEBHOOK_SIGNATURE_INVALID- Description
- Signature header or webhook secret is missing, malformed, or does not match the payload.
- Name
WEBHOOK_TIMESTAMP_INVALID- Description
- The webhook signature timestamp is missing or not a safe integer.
- Name
WEBHOOK_TOLERANCE_INVALID- Description
- The server SDK webhook tolerance option is not a non-negative number.
- Name
WEBHOOK_TIMESTAMP_OUTSIDE_TOLERANCE- Description
- The webhook timestamp is outside the configured replay-protection window.
- Name
WEBHOOK_PAYLOAD_INVALID- Description
- The webhook body is not valid JSON or does not match the Payclave event envelope.
Webhooks
Register webhook endpoints to receive signed events such asinvoice.paid. Payclave stores delivery attempts, response codes, response bodies, and retry state.
Create a webhook endpoint
curl https://api.payclave.com/v1/webhook-endpoints \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://merchant.example/webhooks/payclave",
"eventTypes": ["invoice.paid", "payment.failed"]
}'Security
Each webhook includesX-Payclave-Signature,X-Payclave-Timestamp,X-Payclave-Delivery, andX-Payclave-Event.
Verify with the server SDK
import { constructPayclaveWebhookEvent } from "@payclave/sdk-server"
export async function verifyPayclaveWebhook(request: Request) {
const rawBody = await request.text()
const signature = request.headers.get("X-Payclave-Signature") ?? ""
const event = constructPayclaveWebhookEvent({
payload: rawBody,
signature,
secret: process.env.PAYCLAVE_WEBHOOK_SECRET!,
})
if (event.type === "invoice.paid") {
// Fulfill the order referenced by event.data.
}
return new Response(null, { status: 204 })
}Create a checkout session
Creates a hosted checkout session and a linked invoice. The customer should open the returnedcheckoutUrlto pay through the Payclave-branded checkout.
- Name
amount- Description
- Required positive USDT value with up to 6 decimals.
- Name
customerEmail- Description
- Optional customer email for records.
- Name
externalReference- Description
- Your order or invoice reference.
- Name
successUrl- Description
- Optional URL for successful checkout return.
- Name
cancelUrl- Description
- Optional URL for cancelled checkout return.
- Name
metadata- Description
- Flexible JSON metadata copied to the invoice.
- Name
expiresInMinutes- Description
- Optional expiry from 5 to 1440 minutes.
RATE_LIMIT_EXCEEDED with aRetry-After header.Response
{
"success": true,
"data": {
"id": "chk_pclv_01HY7W9QK3P9M8Z6A4N2B7C1D9",
"checkoutId": "chk_pclv_01HY7W9QK3P9M8Z6A4N2B7C1D9",
"object": "checkout_session",
"mode": "test",
"status": "pending",
"invoiceId": "INV-PCLV-17791920002731",
"invoiceNumber": "INV-PCLV-17791920002731",
"amountDue": "25.00",
"currencyCode": "USDT",
"chainId": 137,
"tokenSymbol": "USDT",
"tokenContract": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
"settlementWalletAddress": "0xMerchantWallet",
"externalReference": "order_8431",
"checkoutUrl": "https://pay.payclave.com/checkout/chk_pclv_01HY7W9QK3P9M8Z6A4N2B7C1D9",
"expiresAt": "2026-05-19T12:30:00Z",
"createdAt": "2026-05-19T12:00:00Z"
},
"meta": {
"requestId": "req_..."
}
}Create an invoice
Create a server-side invoice record without returning a hosted checkout URL. Checkout sessions create linked invoices automatically.
Create an invoice
curl https://api.payclave.com/v1/invoices \
-H "Authorization: Bearer sk_test_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: invoice_8431" \
-d '{
"amount": "25.00",
"externalReference": "invoice_8431",
"metadata": {
"plan": "pro"
}
}'- Name
pending- Description
- Invoice lifecycle status returned by the API and dashboard.
- Name
processing- Description
- Invoice lifecycle status returned by the API and dashboard.
- Name
paid- Description
- Invoice lifecycle status returned by the API and dashboard.
- Name
underpaid- Description
- Invoice lifecycle status returned by the API and dashboard.
- Name
overpaid- Description
- Invoice lifecycle status returned by the API and dashboard.
- Name
expired- Description
- Invoice lifecycle status returned by the API and dashboard.
- Name
failed- Description
- Invoice lifecycle status returned by the API and dashboard.
- Name
cancelled- Description
- Invoice lifecycle status returned by the API and dashboard.
Retrieve a payment
Payment records track detected and verified onchain attempts. Payclave still marks invoices paid only after checking the transaction hash, recipient wallet, token contract, chain ID, amount received, expiry, and duplicate usage.
- Name
detected- Description
- A payment attempt has been captured.
- Name
validating- Description
- Payclave is verifying settlement onchain.
- Name
confirmed- Description
- The payment was confirmed for the invoice.
- Name
failed- Description
- The payment could not be confirmed.
- Name
underpaid- Description
- Received amount is below the invoice amount.
- Name
overpaid- Description
- Received amount is above the invoice amount.
Webhook endpoints
- Name
url- Description
- HTTP or HTTPS endpoint in your application.
- Name
eventTypes- Description
- Optional list of events. Defaults to all supported events.
Webhook deliveries
- Name
pending- Description
- Delivery has been created and scheduled.
- Name
delivering- Description
- A delivery attempt is currently in progress.
- Name
delivered- Description
- The endpoint returned a 2xx response.
- Name
retry_scheduled- Description
- Payclave will retry after a failed attempt.
- Name
failed- Description
- Retries were exhausted or the endpoint is disabled.