Skip to content

REST API / v1

Build something
without borders.

Create an invoice from your server, redirect the customer to the checkout URL, and listen for the webhook.

Base URL https://api.coinavio.com/v1

Authentication

Create an API key in Dashboard → Developers. Send it as a bearer token. Keep it on your server; never expose it in a browser.

API reference / v1
Authorization: Bearer gw_xxxxxxxxxxxxxxxxxxxx.<secret>

1. Create an invoice

Prices are always in USD. The customer chooses the coin and network on the checkout page.

API reference / v1
POST https://api.coinavio.com/v1/invoices
Content-Type: application/json
Authorization: Bearer <apiKey>

{
  "priceAmount": "49.99",
  "orderId": "order-1001",
  "description": "Pro plan, 1 year",
  "successUrl": "https://shop.example.com/thanks?order=1001",
  "cancelUrl": "https://shop.example.com/cart",
  "metadata": { "customerId": "c_42" }
}

→ 201
{
  "id": "inv_...",
  "status": "NEW",
  "price": { "amount": "49.99", "currency": "USD" },
  "checkoutUrl": "https://pay.example.com/pay/inv_...",
  "expiresAt": "2026-01-01T12:30:00.000Z",
  ...
}

Redirect the customer to checkoutUrl. Sending the same orderId twice returns the same invoice.

2. Read an invoice

API reference / v1
GET https://api.coinavio.com/v1/invoices/{id}
GET https://api.coinavio.com/v1/invoices?status=PAID&limit=20&cursor=<lastId>

Statuses: NEW → PENDING → CONFIRMING → PAID | OVERPAID | UNDERPAID | EXPIRED | CANCELLED. Treat PAID and OVERPAID as success. UNDERPAID means the customer sent less than required after the deadline; the received amount is still credited to your balance.

3. Webhooks

Set your endpoint in Dashboard → Developers. We POST a JSON event and retry with exponential backoff for about two hours until you return a 2xx.

API reference / v1
POST https://shop.example.com/webhooks/paygate
X-Webhook-Id: evt_...
X-Webhook-Timestamp: 1735732800000
X-Webhook-Signature: t=1735732800000,v1=<hex hmac>

{
  "id": "evt_...",
  "type": "invoice.paid",
  "createdAt": "...",
  "data": { "invoice": { ...same shape as GET /v1/invoices/{id} } }
}

Event types: invoice.pending, invoice.confirming, invoice.paid, invoice.overpaid, invoice.underpaid, invoice.expired, invoice.payment_confirmed, withdrawal.completed, withdrawal.failed, withdrawal.rejected.

Verifying the signature (Node.js)

API reference / v1
import { createHmac, timingSafeEqual } from "crypto";

export function verify(secret, header, rawBody) {
  if (typeof header !== "string") return false;
  const parts = Object.fromEntries(header.split(",").map((kv) => kv.split("=")));
  if (!parts.t || !parts.v1 || !Number.isFinite(Number(parts.t))) return false;
  if (Math.abs(Date.now() - Number(parts.t)) > 5 * 60_000) return false;
  const expected = createHmac("sha256", secret).update(`${parts.t}.${rawBody}`).digest("hex");
  return expected.length === parts.v1.length &&
    timingSafeEqual(Buffer.from(expected), Buffer.from(parts.v1));
}

Always verify against the raw request body, and make your handler idempotent on the event id.

Supported assets

API reference / v1
GET https://api.coinavio.com/v1/assets   (public)

USDT is available on Ethereum, BNB Chain, TRON and TON. Native ETH, BNB, TRX and TON are also supported. Always use the selected network when sending a payment.