Skip to main content

Create Checkout

Create a Checkout to request payment. There are two endpoints available depending on your integration type.

API Endpoints

Use this endpoint for server-to-server integrations like kiosks, POS systems, or backend services.

POST /v1/checkouts
HeaderRequiredDescription
x-api-keyYesYour Server Key (volr_server_...)
Content-TypeYesapplication/json
Server Key Only

This endpoint requires a Server Key (volr_server_...), not an API Key. Using an API Key will result in an INVALID_KEY_TYPE error.

Dashboard API

Use this endpoint when creating checkouts from the Dashboard or authenticated web applications.

POST /dashboard/projects/{projectId}/checkouts
HeaderRequiredDescription
AuthorizationYesBearer JWT token
Content-TypeYesapplication/json

Request Body

Token Amount (Direct)

Specify the exact token amount you want to receive.

{
"chainId": 8453,
"tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"merchantAddress": "0xYourMerchantWalletAddress",
"amount": "10000000",
"itemName": "Americano",
"referenceId": "ORDER-12345"
}

Fiat Amount (Fiat Price)

Specify the fiat value and let Volr calculate the token amount.

{
"chainId": 8453,
"tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"merchantAddress": "0xYourMerchantWalletAddress",
"fiatAmount": "4.50",
"fiatCurrency": "EUR",
"itemName": "Americano",
"referenceId": "ORDER-12345"
}

Parameters

ParameterTypeRequiredDescription
chainIdnumberYesChain ID (e.g., 8453=Base)
tokenAddressstringYesERC-20 token address (converted to lowercase)
merchantAddressstringYes (Server API)Merchant wallet address to receive payments. Required for /v1/checkouts. Auto-filled for Dashboard API.
amountstringConditionalToken amount in smallest unit (wei). Required if fiatAmount not used
fiatAmountstringConditionalFiat amount (e.g., "5000"). Required if amount not used
fiatCurrencystringConditionalFiat currency code (e.g., USD, EUR, KRW). Required when using fiatAmount. See Public Endpoints for supported currencies
amountModestringNoAmount mode: FIXED (default), MINIMUM, OPEN
minAmountstringNoMinimum amount (for MINIMUM mode)
maxAmountstringNoMaximum amount
expiryMinutesnumberNoExpiry time in minutes. Default: 30, Min: 5, Max: 1440. Max 30 for fiat payments
customerEmailstringNoCustomer email
customerNamestringNoCustomer name
itemNamestringNoItem name
itemDescriptionstringNoItem description
itemImageUrlstringNoItem image URL
referenceIdstringNoClient order ID (unique per project, used for deduplication)
metadataobjectNoCustom metadata (JSON)
successUrlstringNoRedirect URL on payment success
cancelUrlstringNoRedirect URL on payment cancel

Response

Success (201 Created)

{
"ok": true,
"data": {
"id": "cm5xyz123abc",
"projectId": "project_id",
"chainId": 8453,
"tokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
"amount": "3703703",
"amountMode": "FIXED",
"depositAddress": "0xabc123def456...",
"salt": "0x...",
"merchantAddress": "0xmerchant...",
"feeBps": 50,
"fixedFeeAmount": "0",
"status": "PENDING",
"expiresAt": "2026-01-30T11:00:00.000Z",
"createdAt": "2026-01-30T10:30:00.000Z",
"updatedAt": "2026-01-30T10:30:00.000Z",
"itemName": "Americano",
"referenceId": "ORDER-12345",
"fiatAmount": "4.50",
"fiatCurrency": "EUR",
"exchangeRateUsed": "0.92",
"exchangeRateAt": "2026-01-30T10:30:00.000Z"
}
}

Response Fields

FieldTypeDescription
idstringUnique checkout ID (CUID format)
depositAddressstringAddress where customer sends payment (CREATE2 generated)
amountstringToken amount in smallest unit
statusstringPENDING, DETECTED, PAID, SETTLED, EXPIRED, LATE_PAID, CANCELLED
expiresAtstringISO 8601 timestamp when checkout expires
feeBpsnumberFee in basis points (50 = 0.5%)
exchangeRateUsedstringExchange rate used for fiat conversion (null if direct amount)

Error Responses

Authentication Errors

Missing Server Key

{
"ok": false,
"error": {
"code": "SERVER_KEY_REQUIRED",
"message": "Server API key is required"
}
}

Invalid Key Type

{
"ok": false,
"error": {
"code": "INVALID_KEY_TYPE",
"message": "This endpoint requires a server key (volr_server_...)"
}
}

Project Not Found

{
"ok": false,
"error": {
"code": "PROJECT_NOT_FOUND",
"message": "Project not found"
}
}

Validation Errors

Missing Amount

{
"ok": false,
"error": {
"code": "AMOUNT_OR_FIAT_REQUIRED",
"message": "Either amount or fiatAmount must be provided"
}
}

Missing Fiat Currency

{
"ok": false,
"error": {
"code": "FIAT_CURRENCY_REQUIRED",
"message": "fiatCurrency is required when using fiatAmount"
}
}

Unsupported Token for Fiat

{
"ok": false,
"error": {
"code": "UNSUPPORTED_TOKEN_FOR_FIAT",
"message": "Token ETH is not supported for fiat conversion. Supported: USDC, USDT"
}
}

Exchange Rate Unavailable

{
"ok": false,
"error": {
"code": "EXCHANGE_RATE_UNAVAILABLE",
"message": "Unable to fetch exchange rate. Please try again later."
}
}

Amount Too Small

{
"ok": false,
"error": {
"code": "AMOUNT_TOO_SMALL",
"message": "Amount too small. Minimum amount required to cover fees: 1000000"
}
}

Supported Chains & Tokens

Mainnet

ChainChain IDSupported Tokens
Base8453USDC, USDT

Token Addresses

TokenChainAddress
USDCBase0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Coming Soon

Support for additional networks (Arbitrum, Polygon) is planned for future releases.

Examples

Server API (cURL)

curl -X POST https://api.volr.io/v1/checkouts \
-H "x-api-key: volr_server_xxx" \
-H "Content-Type: application/json" \
-d '{
"chainId": 8453,
"tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"merchantAddress": "0xYourMerchantWallet",
"fiatAmount": "4.50",
"fiatCurrency": "EUR",
"itemName": "Americano",
"referenceId": "ORDER-12345"
}'

Server API (Node.js)

const SERVER_KEY = process.env.VOLR_SERVER_KEY; // volr_server_xxx
const MERCHANT_ADDRESS = process.env.VOLR_MERCHANT_ADDRESS;

const createCheckout = async (priceEUR, itemName) => {
const response = await fetch('https://api.volr.io/v1/checkouts', {
method: 'POST',
headers: {
'x-api-key': SERVER_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
chainId: 8453,
tokenAddress: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
merchantAddress: MERCHANT_ADDRESS,
fiatAmount: priceEUR.toString(),
fiatCurrency: 'EUR',
itemName,
referenceId: `ORDER-${Date.now()}`,
}),
});

const { ok, data, error } = await response.json();

if (!ok) {
throw new Error(error.message);
}

return data;
};

Server API (Python)

import requests
import os
import time

SERVER_KEY = os.environ['VOLR_SERVER_KEY'] # volr_server_xxx
MERCHANT_ADDRESS = os.environ['VOLR_MERCHANT_ADDRESS']

def create_checkout(price_eur: float, item_name: str):
response = requests.post(
"https://api.volr.io/v1/checkouts",
headers={
"x-api-key": SERVER_KEY,
"Content-Type": "application/json",
},
json={
"chainId": 8453,
"tokenAddress": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"merchantAddress": MERCHANT_ADDRESS,
"fiatAmount": str(price_eur),
"fiatCurrency": "EUR",
"itemName": item_name,
"referenceId": f"ORDER-{int(time.time())}",
},
)

result = response.json()

if not result["ok"]:
raise Exception(result["error"]["message"])

return result["data"]