Docs

Checkout

The unauthenticated API behind the hosted payment page. Read an invoice as the buyer sees it, pick a chain and currency, and poll the payment that comes back. Possession of the invoice id is the capability โ€” nothing is signed.

5 endpoints
GET/checkout/api/v1/invoices/{id}Recommended

Everything the payment page renders: the merchant company name in full, the buyer email and name masked, the amount, and the blockchain/currency matrix the buyer picks from. Stamps viewedAt on the first call. Returns 400 with code INVOICE_EXPIRED or INVOICE_CANCELLED โ€” not 200 โ€” when the invoice is no longer payable, and 404 INVOICE_NOT_FOUND otherwise.

Request Parameters

NameTypeRequiredDescription
idstringRequiredPath parameter โ€” invoice CUID, as returned by the gateway create-invoice call
JSONResponse Example
{
  "id": "clx7k2p9a0001qz8fh3n2v4m6",
  "referenceId": "INV-260826-041B",
  "amount": "12500",
  "currency": "USD",
  "description": "Order #4471 โ€” annual plan",
  "merchant": {
    "name": "Northwind Digital LLC"
  },
  "availableBlockchains": [
    "ethereum",
    "polygon",
    "bsc",
    "bitcoin",
    "tron",
    "solana",
    "ton",
    "arbitrum",
    "optimism",
    "base",
    "avalanche"
  ],
  "availableCurrencies": {
    "ethereum": [
      "ETH",
      "USDT",
      "USDC"
    ],
    "polygon": [
      "POL",
      "USDT",
      "USDC"
    ],
    "bsc": [
      "BNB",
      "USDT",
      "USDC"
    ],
    "bitcoin": [
      "BTC"
    ],
    "tron": [
      "TRX",
      "USDT"
    ],
    "solana": [
      "SOL",
      "USDC"
    ],
    "ton": [
      "TON",
      "USDT"
    ],
    "arbitrum": [
      "ETH",
      "USDT",
      "USDC"
    ],
    "optimism": [
      "ETH",
      "USDT",
      "USDC"
    ],
    "base": [
      "ETH",
      "USDC"
    ],
    "avalanche": [
      "AVAX",
      "USDT",
      "USDC"
    ]
  },
  "customerEmail": "a***@example.com",
  "customerName": "A*** N***",
  "status": "OPEN",
  "expiresAt": "2026-08-26T14:30:00.000Z",
  "returnUrl": "https://shop.example.com/orders/4471/thanks",
  "cancelUrl": "https://shop.example.com/orders/4471"
}
GET/checkout/api/v1/invoices/{id}/statusRecommended

Three-field polling projection for the payment page: the invoice status, the id of the most recently created payment (null before the buyer picks a coin), and paidAt. Unlike the full invoice read this stays 200 for EXPIRED and CANCELLED invoices, so it is the safe thing to poll on a timer.

Request Parameters

NameTypeRequiredDescription
idstringRequiredPath parameter โ€” invoice CUID
JSONResponse Example
{
  "status": "PAYMENT_PENDING",
  "paymentId": "clx7k2p9a0007qz8f1d0s9k2r",
  "paidAt": null
}
POST/checkout/api/v1/invoices/{id}/checkoutRecommended

Locks the invoice to one blockchain/currency pair and returns the instructions the buyer needs to pay. For method "direct" the payment carries paymentAddress โ€” a one-time address leased from the wallet pool; for "web3" and "havala_wallet" it carries contractAddress, externalId (the bytes32 form), externalIdUuid, treasuryWallet, tokenAddress (null for the chain native coin) and chainId instead, and "havala_wallet" adds requiresConfirmation: true. The payment window is min(now + 30 minutes, invoice expiry) and checkout always runs on MAINNET.

Request Parameters

NameTypeRequiredDescription
idstringRequiredPath parameter โ€” invoice CUID; must currently be OPEN and unexpired
blockchainstringRequiredLowercase chain key from availableBlockchains: ethereum, polygon, bsc, bitcoin, tron, solana, ton, arbitrum, optimism, base, avalanche
cryptoCurrencystringRequiredToken symbol that the chosen chain supports (see availableCurrencies); rejected with INVALID_CURRENCY otherwise
methodstringRequireddirect | web3 | havala_wallet. web3 and havala_wallet are EVM-only (ethereum, polygon, bsc, arbitrum, optimism, base, avalanche) and fail with BLOCKCHAIN_NOT_SUPPORTED elsewhere
JSONRequest Example
{
  "blockchain": "ethereum",
  "cryptoCurrency": "USDT",
  "method": "direct"
}
JSONResponse Example
{
  "payment": {
    "id": "clx7k2p9a0007qz8f1d0s9k2r",
    "referenceId": "PAY-260826-118A",
    "method": "direct",
    "paymentAddress": "0xe58b081006f7e3dfc967a64cb14028d512c9791e",
    "amount": "12500",
    "cryptoCurrency": "USDT",
    "blockchain": "ethereum",
    "network": "MAINNET",
    "decimals": 6,
    "expiresAt": "2026-08-26T14:12:00.000Z"
  }
}
GET/checkout/api/v1/payments/{id}/statusRecommended

Confirmation progress for one payment: status, confirmations against requiredConfirmations (12 on Ethereum mainnet, 128 on Polygon, 3 on Bitcoin, and so on per chain), the transaction hash, and the address the buyer was told to pay. transactionHash stays null until a transaction is matched; paymentAddress is the leased pool address on a direct payment and the treasury wallet on a smart-contract one.

Request Parameters

NameTypeRequiredDescription
idstringRequiredPath parameter โ€” payment CUID, from the create-payment response or the invoice status poll
JSONResponse Example
{
  "status": "CONFIRMING",
  "confirmations": 7,
  "requiredConfirmations": 12,
  "transactionHash": "0xa4c123b1612dd272d1371c17149d439536b3216fdaeeb975729fae923d5a4fd1",
  "blockchain": "ethereum",
  "amount": "12500",
  "cryptoCurrency": "USDT",
  "paymentAddress": "0xe58b081006f7e3dfc967a64cb14028d512c9791e",
  "expiresAt": "2026-08-26T14:12:00.000Z"
}
POST/checkout/api/v1/payments/{id}/confirmOptional

Attaches a client-signed transaction hash to a SMART_CONTRACT payment, verifies the receipt on chain, moves the payment to PROCESSING, and starts confirmation tracking. Idempotent: a payment already PROCESSING, CONFIRMING or COMPLETED returns its current state with message "Payment is already being processed" instead of an error. Rejects an unmined hash with TX_NOT_FOUND, so retry after a few seconds rather than treating it as fatal.

Request Parameters

NameTypeRequiredDescription
idstringRequiredPath parameter โ€” payment CUID; must be PENDING and of paymentType SMART_CONTRACT (created with method web3 or havala_wallet)
txHashstringRequiredTransaction hash of the signed payment, matching ^0x[a-fA-F0-9]{64}$
JSONRequest Example
{
  "txHash": "0xcc3fc1626e53a13043b026c48bbf33feff9243a8f506b40928b5b7a767c76fb0"
}
JSONResponse Example
{
  "status": "PROCESSING",
  "transactionHash": "0xcc3fc1626e53a13043b026c48bbf33feff9243a8f506b40928b5b7a767c76fb0",
  "confirmations": 0,
  "requiredConfirmations": 12,
  "message": "Payment confirmed, tracking confirmations"
}

Category Summary

Total Endpoints

5

Base Domain

api2.havala.io