Skip to content
Crypto Merchant

Developers

API reference

A small REST API for invoices, payment links, balances and accepted coins. It uses JSON over HTTPS, and every request is made with your secret key.

Base URL

Production
https://cryptomerchant.online/api/v1
Local development
http://localhost:3000/api/v1

Authentication

Send your secret key in the Authorization header of every request, as a Bearer token. Create keys in the portal under Developers.

HTTP
Authorization: Bearer cm_live_…
  • Keys start with cm_live_ on mainnet and cm_test_ on testnet.
  • The full key is shown only once, when you create it. We store only a hash of it, so keep it somewhere safe.
  • Use keys only on your server. Never put them in a web page, a mobile app or a public code repository.
  • If a key may have leaked, revoke it in the portal and create a new one.

Errors

When a request fails, the response has an HTTP error status and a JSON body with a machine-readable code and a human-readable message:

JSON
{
  "error": {
    "code": "amount_too_small",
    "message": "Amount must be at least 0.50 USD."
  }
}

HTTP status

400
The request is not valid, for example a missing field or an amount that is too small.
401
The API key is missing, wrong or revoked.
403
Your account can't do this: it isn't live yet, or it is suspended.
404
The object doesn't exist, or it belongs to another business.
409
The invoice can't do this in its current status, for example cancelling one that already has a payment.
500
Something went wrong on our side. Try again a little later.

Codes you may see

invalid_json
The request body is not a JSON object.
invalid_request
A field is missing or not valid. The message names the field.
unauthorized
The API key is missing, wrong or revoked.
account_suspended
This merchant account is suspended.
merchant_not_live
Your account isn't live yet. Make the go-live payment first.
invalid_amount
The amount is missing, not a number, or not greater than zero.
amount_too_small
The amount is worth less than 0.50 US dollars.
invalid_asset
The coin ID is not a known coin.
asset_not_accepted
You don't accept that coin.
invalid_state
The invoice can't do this in its current status.
not_found
There is no object with that ID.
server_error
Something went wrong on our side.

The invoice object

Invoices have this shape in API responses and in webhooks. Amounts are decimal strings, so no precision is lost.

idstring
Invoice ID, starting with inv_.
objectstring
Always invoice.
statusstring
The current status. See the list of statuses below.
amountstring
The price you asked for, in currency.
currencystring
The currency of the price, for example USD.
amount_usdstring
The price in US dollars.
descriptionstring | null
Your description, shown to the customer.
order_idstring | null
Your own order reference.
customer_emailstring | null
The customer's email, if you gave one.
metadataobject
The object you passed when creating the invoice, returned unchanged.
coinobject | null
The coin the customer chose, with its id, symbol and network. null until a coin is chosen.
pay_addressstring | null
The deposit address for this invoice. null until a coin is chosen.
pay_amountstring | null
The exact amount to send, in the chosen coin.
rate_usdstring | null
The locked price of one unit of the chosen coin, in US dollars.
received_amountstring
How much has arrived so far, in the chosen coin.
received_usdstring
The US dollar value of what has arrived.
overpaid_amountstring
How much more than the invoice asked for was paid, in the chosen coin.
checkout_urlstring
The invoice page. Send your customer here to pay.
redirect_urlstring | null
Where the customer can go after paying.
expires_atISO 8601
When the invoice expires if no payment is seen.
paid_atISO 8601 | null
When the invoice was paid, or null.
created_atISO 8601
When the invoice was created.
invoice
{
  "id": "inv_…",
  "object": "invoice",
  "status": "open",
  "amount": "49.9",
  "currency": "USD",
  "amount_usd": "49.9",
  "description": "Annual plan",
  "order_id": "1042",
  "customer_email": "[email protected]",
  "metadata": { "plan": "annual" },
  "coin": null,
  "pay_address": null,
  "pay_amount": null,
  "rate_usd": null,
  "received_amount": "0",
  "received_usd": "0",
  "overpaid_amount": "0",
  "checkout_url": "https://cryptomerchant.online/pay/i/inv_…",
  "redirect_url": "https://yourstore.example/thanks",
  "expires_at": "2026-10-28T10:00:00.000Z",
  "paid_at": null,
  "created_at": "2026-10-28T09:30:00.000Z"
}

Invoice statuses

openOpen
Created. The customer hasn't picked a coin yet.
awaiting_paymentAwaiting payment
A coin is chosen, the deposit address is assigned and the rate is locked.
confirmingConfirming
A payment was seen on-chain and is waiting for confirmations.
underpaidUnderpaid
The confirmed payment is short by more than your tolerance. The customer can pay the rest or ask for a refund.
paidPaid
Paid and confirmed. The amount, minus the fee, is in your balance.
expiredExpired
Time ran out before any payment was seen.
cancelledCancelled
The invoice was cancelled before any payment was seen.
refundedRefunded
The customer was refunded what they sent on an underpaid invoice.

Create an invoice

POST/invoices

Creates an invoice and returns the invoice object with status 201. Send your customer to its checkout_url.

Body parameters

amountRequirednumber | string
The price, as a number or a decimal string. Must be worth at least 0.50 US dollars.
currencyOptionalstring
The currency of the price, for example USD. Defaults to USD.
descriptionOptionalstring
What the customer is paying for, up to 300 characters. Shown on the invoice page.
order_idOptionalstring
Your own order reference, up to 120 characters, to match the invoice to an order.
customer_emailOptionalstring
The customer's email address. Payments are grouped by customer in the portal.
customer_nameOptionalstring
The customer's name, up to 120 characters.
redirect_urlOptionalstring
A full URL where the customer can go after paying.
metadataOptionalobject
Any JSON object up to 4 KB. Returned unchanged on the invoice and in webhooks.
coinOptionalstring
Pre-select a coin by its ID, for example USDT.TRON. It must be one of your accepted coins.

With a pre-selected coin, the deposit address is assigned and the rate locked straight away, so pay_address and pay_amount are filled in and you can show the payment details in your own interface.

curl
curl https://cryptomerchant.online/api/v1/invoices \
  -H "Authorization: Bearer $CM_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": "49.90",
    "currency": "USD",
    "order_id": "1042",
    "description": "Annual plan",
    "customer_email": "[email protected]",
    "redirect_url": "https://yourstore.example/thanks",
    "metadata": { "plan": "annual" }
  }'
Node.js
const res = await fetch("https://cryptomerchant.online/api/v1/invoices", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.CM_SECRET_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    amount: "49.90",
    currency: "USD",
    order_id: "1042",
    description: "Annual plan",
  }),
});

if (!res.ok) {
  const { error } = await res.json();
  throw new Error(`${error.code}: ${error.message}`);
}

const invoice = await res.json();
// Send the customer to invoice.checkout_url

List invoices

GET/invoices

Returns your invoices, newest first, one page at a time.

Query parameters

statusOptionalstring
Only invoices with this status, for example paid. Must be one of the statuses above.
limitOptionalnumber
How many invoices to return, from 1 to 100. Defaults to 20.
starting_afterOptionalstring
An invoice ID. Returns the invoices that come after it, for the next page.

The invoices are in data. When has_more is true, ask for the next page with starting_after set to the ID of the last invoice you received.

curl
curl "https://cryptomerchant.online/api/v1/invoices?status=paid&limit=20" \
  -H "Authorization: Bearer $CM_SECRET_KEY"
Response
{
  "object": "list",
  "data": [
    { "id": "inv_…", "object": "invoice", "status": "paid", … }
  ],
  "has_more": true
}

Retrieve an invoice

GET/invoices/{id}

Returns one invoice by its ID.

curl
curl https://cryptomerchant.online/api/v1/invoices/$INVOICE_ID \
  -H "Authorization: Bearer $CM_SECRET_KEY"

Cancel an invoice

POST/invoices/{id}/cancel

Cancels an invoice. This only works while the invoice is unpaid and no payment has been seen for it.

curl
curl -X POST https://cryptomerchant.online/api/v1/invoices/$INVOICE_ID/cancel \
  -H "Authorization: Bearer $CM_SECRET_KEY"

Balances

GET/balances

Returns what your business holds in each coin, the total in US dollars, and your gas balance.

data[].coin
The coin ID, for example USDT.TRON.
data[].symbol
The coin symbol, for example USDT.
data[].network
The network the coin is on.
data[].amount
How much of the coin you hold, as a decimal string.
data[].usd
Its value in US dollars at the current price.
total_usd
The value of all your coins in US dollars.
gas_balance_usd
Your gas balance in US dollars, used to pay network fees.
curl
curl https://cryptomerchant.online/api/v1/balances \
  -H "Authorization: Bearer $CM_SECRET_KEY"
Response
{
  "object": "balance",
  "data": [
    { "coin": "USDT.TRON", "symbol": "USDT", "network": "Tron", "amount": "…", "usd": "…" }
  ],
  "total_usd": "…",
  "gas_balance_usd": "…"
}

Accepted coins

GET/coins

Returns the coins you accept right now, each with its id, symbol, name, network and decimals. Use the id as coin when you create an invoice. For example:

curl
curl https://cryptomerchant.online/api/v1/coins \
  -H "Authorization: Bearer $CM_SECRET_KEY"
Response
{
  "object": "list",
  "data": [
    {
      "id": "ETH.ETH",
      "symbol": "ETH",
      "name": "Ethereum",
      "network": "Ethereum",
      "decimals": 18
    },
    {
      "id": "USDT.ETH",
      "symbol": "USDT",
      "name": "Tether USD",
      "network": "Ethereum",
      "decimals": 6
    },
    {
      "id": "USDC.ETH",
      "symbol": "USDC",
      "name": "USD Coin",
      "network": "Ethereum",
      "decimals": 6
    }
  ]
}

POST/payment-links

Creates a payment link and returns it with status 201, including its id and its shareable url.

Body parameters

titleRequiredstring
The name of what the customer pays for, up to 120 characters.
amountOptionalnumber | string
A fixed price. Leave it out to let the customer enter the amount.
currencyOptionalstring
The currency of the price. Defaults to USD.
descriptionOptionalstring
More detail shown to the customer, up to 300 characters.
curl
curl https://cryptomerchant.online/api/v1/payment-links \
  -H "Authorization: Bearer $CM_SECRET_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Consulting hour",
    "amount": "80",
    "currency": "USD"
  }'
Response
{
  "id": "…",
  "object": "payment_link",
  "title": "Consulting hour",
  "description": null,
  "amount": "80",
  "currency": "USD",
  "active": true,
  "url": "https://cryptomerchant.online/pay/l/…",
  "created_at": "2026-10-28T09:30:00.000Z"
}

GET/payment-links

Returns your 100 most recent payment links, newest first, in data.

curl
curl https://cryptomerchant.online/api/v1/payment-links \
  -H "Authorization: Bearer $CM_SECRET_KEY"
Next, set up webhooks so your server hears about payments the moment they happen.