Docs

Invoices

The core of a Havala integration. Create a fiat-denominated invoice, check it out onto a chain and token, and follow it through to PAID. Signed with your merchant point credentials.

5 endpoints
POST/api/v1/invoicesCore

Create an invoice in status OPEN. amount is a string of minor units in the fiat currency you name; no chain or token is chosen yet โ€” that happens at checkout. The response carries the CUID id you sign into every later call and a human referenceId of the form INV-YYMMDD-NNNL.

Request Parameters

NameTypeRequiredDescription
orderIdstringRequiredYour own order identifier, max 255 chars. Indexed with merchantId for lookups on your side.
amountstringRequiredAmount in the minor unit of currency (USD cents), sent as a string and stored as BigInt.
currencystringRequiredFiat denomination code, max 10 chars, e.g. USD. This is not the crypto the buyer pays in.
descriptionstringOptionalFree text carried on the invoice, max 500 chars. Defaults to an empty string.
customerEmailstringOptionalBuyer email, validated as an address. Returned as null when omitted.
customerNamestringOptionalBuyer display name, max 255 chars. Returned as null when omitted.
customerMetadataobjectOptionalArbitrary JSON about the buyer. Stored as-is and echoed back unchanged; defaults to {}.
metadataobjectOptionalArbitrary JSON of your own. Stored as-is and echoed back unchanged; defaults to {}.
returnUrlstringOptionalAbsolute URL the buyer lands on after a successful payment. Must parse as a URL.
cancelUrlstringOptionalAbsolute URL the buyer lands on after abandoning the invoice. Must parse as a URL.
expiresInMinutesintegerOptionalInvoice lifetime, 15 to 1440 minutes. Defaults to 60 and sets expiresAt to now plus that window.
JSONRequest Example
{
  "orderId": "order-8814",
  "amount": "12500",
  "currency": "USD",
  "description": "Pro plan, annual billing",
  "customerEmail": "buyer@example.com",
  "customerName": "Ada Lovelace",
  "customerMetadata": {
    "userId": 4471
  },
  "metadata": {
    "internalRef": "sub_2026_08_pro"
  },
  "returnUrl": "https://merchant.example.com/checkout/success",
  "cancelUrl": "https://merchant.example.com/checkout/cancel",
  "expiresInMinutes": 60
}
JSONResponse Example
{
  "id": "clyv3n8x40001qh7m2k9d5b1t",
  "referenceId": "INV-260826-041C",
  "orderId": "order-8814",
  "description": "Pro plan, annual billing",
  "amount": "12500",
  "currency": "USD",
  "status": "OPEN",
  "customerEmail": "buyer@example.com",
  "customerName": "Ada Lovelace",
  "customerMetadata": {
    "userId": 4471
  },
  "metadata": {
    "internalRef": "sub_2026_08_pro"
  },
  "returnUrl": "https://merchant.example.com/checkout/success",
  "cancelUrl": "https://merchant.example.com/checkout/cancel",
  "expiresAt": "2026-08-26T10:14:22.481Z",
  "viewedAt": null,
  "paidAt": null,
  "cancelledAt": null,
  "createdAt": "2026-08-26T09:14:22.481Z"
}
GET/api/v1/invoices/{id}Core

Fetch one invoice by CUID, scoped to the merchant point behind your API key. This is the only invoice route that includes the payments relation: every payment ever opened against the invoice, newest attempts included, each with its leased deposit address.

Request Parameters

NameTypeRequiredDescription
idstringRequiredPath parameter โ€” invoice CUID returned by create. Not the referenceId.
JSONResponse Example
{
  "id": "clyv3n8x40001qh7m2k9d5b1t",
  "referenceId": "INV-260826-041C",
  "orderId": "order-8814",
  "description": "Pro plan, annual billing",
  "amount": "12500",
  "currency": "USD",
  "status": "PAYMENT_PENDING",
  "customerEmail": "buyer@example.com",
  "customerName": "Ada Lovelace",
  "customerMetadata": {
    "userId": 4471
  },
  "metadata": {
    "internalRef": "sub_2026_08_pro"
  },
  "returnUrl": "https://merchant.example.com/checkout/success",
  "cancelUrl": "https://merchant.example.com/checkout/cancel",
  "expiresAt": "2026-08-26T10:14:22.481Z",
  "viewedAt": "2026-08-26T09:16:04.220Z",
  "paidAt": null,
  "cancelledAt": null,
  "createdAt": "2026-08-26T09:14:22.481Z",
  "payments": [
    {
      "id": "clyv4p1c70003qh7m8w2r6z9f",
      "referenceId": "PAY-260826-118A",
      "status": "PENDING",
      "blockchain": "ethereum",
      "currency": "USDT",
      "amount": "12500",
      "receivedAmount": "0",
      "address": "0x7Ae2d4C1f83B90e5A6c7D218Ff43b9C0E15d8a72",
      "createdAt": "2026-08-26T09:14:26.902Z"
    }
  ]
}
GET/api/v1/invoices/{id}/statusCore

Five-field projection of the invoice, cheap enough to poll while the buyer is on the checkout page. Prefer the payment.completed webhook for settlement; use this to reconcile after a missed delivery or to decide whether an unpaid invoice is still inside its window.

Request Parameters

NameTypeRequiredDescription
idstringRequiredPath parameter โ€” invoice CUID. Unknown or out-of-scope ids return INVOICE_NOT_FOUND.
JSONResponse Example
{
  "id": "clyv3n8x40001qh7m2k9d5b1t",
  "referenceId": "INV-260826-041C",
  "status": "PAID",
  "paidAt": "2026-08-26T09:31:47.118Z",
  "expiresAt": "2026-08-26T10:14:22.481Z"
}
POST/api/v1/invoices/{id}/checkoutCore

Pick the chain and token for an OPEN invoice. Havala creates a DIRECT payment, leases a one-time deposit address from the wallet pool for that chain, and moves the invoice to PAYMENT_PENDING. Send the buyer to paymentAddress and watch that payment; the window is 30 minutes or whatever is left of the invoice expiry, whichever ends sooner.

Request Parameters

NameTypeRequiredDescription
idstringRequiredPath parameter โ€” invoice CUID. Must be OPEN and unexpired, otherwise INVOICE_NOT_AVAILABLE or INVOICE_EXPIRED.
blockchainstringRequiredLower-case chain key: ethereum, polygon, bsc, arbitrum, optimism, base, avalanche, bitcoin, tron, solana, ton.
cryptoCurrencystringRequiredToken symbol configured on that chain, e.g. ETH, USDT or USDC on ethereum. An unsupported pair is rejected with INVALID_CURRENCY.
networkstringOptionalOptional testnet selector, written straight to the payment NetworkEnum column: SEPOLIA, GOERLI, HOLESKY, AMOY, MUMBAI, bsc-testnet, FUJI, NILE, TESTNET, DEVNET, testnet-generic. Omit it for mainnet โ€” the payment then defaults to MAINNET and is flagged live.
JSONRequest Example
{
  "blockchain": "ethereum",
  "cryptoCurrency": "USDT"
}
JSONResponse Example
{
  "invoice": {
    "id": "clyv3n8x40001qh7m2k9d5b1t",
    "referenceId": "INV-260826-041C",
    "orderId": "order-8814",
    "description": "Pro plan, annual billing",
    "amount": "12500",
    "currency": "USD",
    "status": "PAYMENT_PENDING",
    "customerEmail": "buyer@example.com",
    "customerName": "Ada Lovelace",
    "customerMetadata": {
      "userId": 4471
    },
    "metadata": {
      "internalRef": "sub_2026_08_pro"
    },
    "returnUrl": "https://merchant.example.com/checkout/success",
    "cancelUrl": "https://merchant.example.com/checkout/cancel",
    "expiresAt": "2026-08-26T10:14:22.481Z",
    "viewedAt": null,
    "paidAt": null,
    "cancelledAt": null,
    "createdAt": "2026-08-26T09:14:22.481Z"
  },
  "payment": {
    "id": "clyv4p1c70003qh7m8w2r6z9f",
    "referenceId": "PAY-260826-118A",
    "paymentAddress": "0x7Ae2d4C1f83B90e5A6c7D218Ff43b9C0E15d8a72",
    "amount": "12500",
    "blockchain": "ethereum",
    "cryptoCurrency": "USDT",
    "status": "PENDING",
    "expiresAt": "2026-08-26T09:44:26.902Z",
    "createdAt": "2026-08-26T09:14:26.902Z"
  }
}
DELETE/api/v1/invoices/{id}Recommended

Soft-cancel an invoice: status becomes CANCELLED and cancelledAt is stamped. Only OPEN and DRAFT invoices qualify โ€” once checkout has opened a payment the invoice is PAYMENT_PENDING and the call fails with INVOICE_CANNOT_BE_CANCELLED. Nothing is deleted; the record and its payments stay queryable.

Request Parameters

NameTypeRequiredDescription
idstringRequiredPath parameter โ€” invoice CUID to cancel.
JSONResponse Example
{
  "id": "clyv3n8x40001qh7m2k9d5b1t",
  "referenceId": "INV-260826-041C",
  "orderId": "order-8814",
  "description": "Pro plan, annual billing",
  "amount": "12500",
  "currency": "USD",
  "status": "CANCELLED",
  "customerEmail": "buyer@example.com",
  "customerName": "Ada Lovelace",
  "customerMetadata": {
    "userId": 4471
  },
  "metadata": {
    "internalRef": "sub_2026_08_pro"
  },
  "returnUrl": "https://merchant.example.com/checkout/success",
  "cancelUrl": "https://merchant.example.com/checkout/cancel",
  "expiresAt": "2026-08-26T10:14:22.481Z",
  "viewedAt": null,
  "paidAt": null,
  "cancelledAt": "2026-08-26T09:22:10.006Z",
  "createdAt": "2026-08-26T09:14:22.481Z"
}

Category Summary

Total Endpoints

5

Base Domain

api2.havala.io