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.
/api/v1/invoicesCoreCreate 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
| Name | Type | Required | Description |
|---|---|---|---|
orderId | string | Required | Your own order identifier, max 255 chars. Indexed with merchantId for lookups on your side. |
amount | string | Required | Amount in the minor unit of currency (USD cents), sent as a string and stored as BigInt. |
currency | string | Required | Fiat denomination code, max 10 chars, e.g. USD. This is not the crypto the buyer pays in. |
description | string | Optional | Free text carried on the invoice, max 500 chars. Defaults to an empty string. |
customerEmail | string | Optional | Buyer email, validated as an address. Returned as null when omitted. |
customerName | string | Optional | Buyer display name, max 255 chars. Returned as null when omitted. |
customerMetadata | object | Optional | Arbitrary JSON about the buyer. Stored as-is and echoed back unchanged; defaults to {}. |
metadata | object | Optional | Arbitrary JSON of your own. Stored as-is and echoed back unchanged; defaults to {}. |
returnUrl | string | Optional | Absolute URL the buyer lands on after a successful payment. Must parse as a URL. |
cancelUrl | string | Optional | Absolute URL the buyer lands on after abandoning the invoice. Must parse as a URL. |
expiresInMinutes | integer | Optional | Invoice lifetime, 15 to 1440 minutes. Defaults to 60 and sets expiresAt to now plus that window. |
{
"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
}{
"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"
}/api/v1/invoices/{id}CoreFetch 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
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | Path parameter โ invoice CUID returned by create. Not the referenceId. |
{
"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"
}
]
}/api/v1/invoices/{id}/statusCoreFive-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
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | Path parameter โ invoice CUID. Unknown or out-of-scope ids return INVOICE_NOT_FOUND. |
{
"id": "clyv3n8x40001qh7m2k9d5b1t",
"referenceId": "INV-260826-041C",
"status": "PAID",
"paidAt": "2026-08-26T09:31:47.118Z",
"expiresAt": "2026-08-26T10:14:22.481Z"
}/api/v1/invoices/{id}/checkoutCorePick 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
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | Path parameter โ invoice CUID. Must be OPEN and unexpired, otherwise INVOICE_NOT_AVAILABLE or INVOICE_EXPIRED. |
blockchain | string | Required | Lower-case chain key: ethereum, polygon, bsc, arbitrum, optimism, base, avalanche, bitcoin, tron, solana, ton. |
cryptoCurrency | string | Required | Token symbol configured on that chain, e.g. ETH, USDT or USDC on ethereum. An unsupported pair is rejected with INVALID_CURRENCY. |
network | string | Optional | Optional 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. |
{
"blockchain": "ethereum",
"cryptoCurrency": "USDT"
}{
"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"
}
}/api/v1/invoices/{id}RecommendedSoft-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
| Name | Type | Required | Description |
|---|---|---|---|
id | string | Required | Path parameter โ invoice CUID to cancel. |
{
"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