API documentation

Base URL: https://cryptomo.net/api/v1. All requests and responses are JSON. Amounts are strings to avoid rounding errors.

  1. Create an account and a store, then wait for the store to be approved.
  2. Open the store in your dashboard and create an API key. Copy the secret key right away; it is shown only once.
  3. Set the store's Webhook URL and copy its webhook secret to verify notifications.

Authentication

Every request needs three headers:

X-Api-KeyYour public key (pk_…)
X-TimestampCurrent unix time in seconds. Must be within 5 minutes of our clock.
X-SignatureHex HMAC-SHA256(timestamp + raw_body, secret_key). For GET requests the body is an empty string.
<?php
$secret = 'sk_...';
$body = json_encode(['amount' => '49.00', 'currency' => 'USD', 'order_id' => '1024']);
$ts = (string) time();
$sig = hash_hmac('sha256', $ts . $body, $secret);

$ch = curl_init('https://cryptomo.net/api/v1/invoices');
curl_setopt_array($ch, [
  CURLOPT_POST => true, CURLOPT_POSTFIELDS => $body, CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ['Content-Type: application/json', 'X-Api-Key: pk_...', "X-Timestamp: $ts", "X-Signature: $sig"],
]);
$invoice = json_decode(curl_exec($ch), true)['data'];
header('Location: ' . $invoice['checkout_url']);
// Node.js 18+
import crypto from 'node:crypto';
const body = JSON.stringify({ amount: '49.00', currency: 'USD', order_id: '1024' });
const ts = Math.floor(Date.now() / 1000).toString();
const sig = crypto.createHmac('sha256', process.env.CRYPTOMO_SECRET).update(ts + body).digest('hex');
const res = await fetch('https://cryptomo.net/api/v1/invoices', { method: 'POST', body,
  headers: { 'Content-Type': 'application/json', 'X-Api-Key': process.env.CRYPTOMO_KEY, 'X-Timestamp': ts, 'X-Signature': sig } });

Create an invoice

POST /invoices201 with {"data": Invoice}. Send the customer to checkout_url.

FieldRequiredDescription
amountyesPrice as a string, e.g. "49.00"
currencynoFiat currency, e.g. USD, EUR, INR. Defaults to the store currency.
order_idnoYour order reference (max 120 chars)
descriptionnoShown to the customer
customer_emailnoWe email the customer a receipt when paid
pay_currencynoSkip the coin picker, e.g. USDT_TRC20 (see codes below)
success_url / cancel_urlnoWhere the "Back to store" buttons go
callback_urlnoOverrides the store webhook URL for this invoice
metadatanoAny JSON (max 4 KB), returned in webhooks

Send an Idempotency-Key header to safely retry: the same key returns the same invoice instead of creating a new one.

Get / list invoices

GET /invoices/{id} returns one invoice. GET /invoices?status=paid&order_id=1024&page=1&limit=25 lists invoices of the store, newest first.

Cancel an invoice

POST /invoices/{id}/cancel cancels an unpaid invoice (body can be empty).

Invoice object

{
  "id": "5b1f…", "store_id": "…", "order_id": "1024", "status": "paid",
  "amount": "49.00", "currency": "USD",
  "pay_currency": "USDT_TRC20", "pay_symbol": "USDT", "network": "TRON",
  "pay_amount": "49.52", "paid_amount": "49.52", "rate": "0.9895",
  "address": "T…", "memo": null,
  "fee_amount": "0.4952", "merchant_amount": "49.0248", "is_late": false,
  "checkout_url": "https://cryptomo.net/pay/5b1f…",
  "transactions": [{ "tx_hash": "…", "amount": "49.52", "status": "credited", "created_at": "…" }],
  "metadata": null, "expires_at": "…", "paid_at": "…", "created_at": "…"
}

Statuses

newCreated; the customer has not picked a coin yet.
waitingCoin chosen, rate locked, waiting for the payment.
partially_paidLess than the amount was received. The customer can send the rest before expiry.
paidPaid in full (within the store's underpayment tolerance). Ship the order.
paid_overPaid more than required. Treat as paid.
paid_latePaid in full after the invoice expired. Treat as paid (the rate may have moved).
expiredTime ran out before full payment. paid_amount shows any partial payment.
cancelledCancelled by you before payment.

Webhooks

We POST JSON to your store's webhook URL on these events: invoice.paid, invoice.partially_paid, invoice.overpaid, invoice.expired, invoice.cancelled. Reply with any 2xx status. Failed deliveries are retried for 24 hours (1m, 5m, 15m, 1h, 3h, 6h, 12h, 24h).

POST /your-webhook
X-Cryptomo-Event: invoice.paid
X-Cryptomo-Timestamp: 1767225600
X-Cryptomo-Signature: hex(HMAC-SHA256(timestamp + "." + raw_body, webhook_secret))

{ "id": "…", "event": "invoice.paid", "created_at": "…", "data": { …Invoice… } }
<?php
$raw = file_get_contents('php://input');
$ts  = $_SERVER['HTTP_X_CRYPTOMO_TIMESTAMP'] ?? '';
$sig = $_SERVER['HTTP_X_CRYPTOMO_SIGNATURE'] ?? '';
$expected = hash_hmac('sha256', $ts . '.' . $raw, 'YOUR_WEBHOOK_SECRET');
if (!hash_equals($expected, $sig) || abs(time() - (int) $ts) > 300) {
    http_response_code(401); exit;
}
$event = json_decode($raw, true);
if (in_array($event['data']['status'], ['paid', 'paid_over', 'paid_late'], true)) {
    // mark order $event['data']['order_id'] as paid (do this idempotently)
}
http_response_code(200);

Always check the invoice status from the payload (or call GET /invoices/{id}) and make your handler idempotent: the same event can arrive more than once.

POST /payment-links with title, optional amount (empty = payer chooses), min_amount, currency, type (payment or donation), description, max_uses. Returns {"data": {"id", "url", …}}. GET /payment-links lists them.

Currencies, rates, balance

GET /currencies — coins your store accepts. GET /rates?currency=USD — current price of 1 coin. GET /balance — your balances. GET /ping — checks your keys.

Errors

HTTP 422
{ "error": { "code": "validation_error", "message": "amount must be a positive number like 25 or 19.99" } }

Codes: missing_auth, timestamp_expired, invalid_api_key, invalid_signature (401), account_inactive (403), not_found (404), cannot_cancel (409), validation_error (422), rate_limited (429, max 120 requests/minute).

Currency codes

CodeCoinNetwork
BTCBitcoinBitcoin
ETHEthereumEthereum (ERC20)
USDT_TRC20Tether (TRC20)Tron (TRC20)
USDT_ERC20Tether (ERC20)Ethereum (ERC20)
USDT_BEP20Tether (BEP20)BNB Smart Chain (BEP20)
USDT_POLYGONTether (Polygon)Polygon
USDC_ERC20USD Coin (ERC20)Ethereum (ERC20)
USDC_BEP20USD Coin (BEP20)BNB Smart Chain (BEP20)
USDC_POLYGONUSD Coin (Polygon)Polygon
TRXTronTron (TRC20)
BNBBNBBNB Smart Chain (BEP20)
POLPolygonPolygon
LTCLitecoinLitecoin
DOGEDogecoinDogecoin
SOLSolanaSolana