Clearqo API

Accept USDT through Binance Pay, TRC20 and BEP20 from any website, app or bot. Customers pay directly into your own Binance account — Clearqo verifies the payment and notifies you.

Base URL: https://clearqo.com/wp-json/clearqo/v1 · All requests and responses are JSON over HTTPS.

Quickstart

  1. Create an account, connect a read-only Binance key and add at least one payment method.
  2. Create an API key in Dashboard → Developers and keep it on your server.
  3. Create an invoice for your order and redirect the customer to checkout_url.
  4. When you receive the invoice.paid webhook, fulfil the order for paid_price_amount.

Authentication

Authenticate every request with your secret API key in the X-Api-Key header. Keys start with cq_live_. Never put a key in browser or mobile-app code — anyone could read it.

X-Api-Key: cq_live_••••••••••••••••••••••••••••••••••••••••••••••••

Create an invoice

POST/invoices

Creates a payment request. Every invoice receives a unique amount_to_pay (for example 10.0023) — the extra digits identify the payment, so the customer must send exactly that amount.

amountrequiredstringPrice as a string, e.g. "10" or "2800.50", in currency.
currencystringCurrency of amount: USDT (default), USD, or any 3-letter code you set a rate for, e.g. PKR. See Other currencies.
order_idstringYour order or reference ID. Creating again with the same order_id and amount while the invoice is open returns the same invoice, so retries are safe.
descriptionstringInternal description, visible in your dashboard.
customer_emailstringOptional, for your records.
success_urlstringWhere the customer is sent after paying. ?invoice=…&status=paid is appended.
cancel_urlstringShown as “Cancel and return” on the checkout page.
webhook_urlstringOverrides your default webhook endpoint for this invoice. https only.
expires_inintegerMinutes until the invoice expires (10–1440). Default: 30.
curl -X POST https://clearqo.com/wp-json/clearqo/v1/invoices \
  -H "X-Api-Key: $CLEARQO_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":"10","order_id":"1042","success_url":"https://shop.example/thanks"}'

Other currencies

If your prices are in another currency, send it as currency. Set your own fixed rate in Dashboard → Settings → Currencies (for example 1 USDT = 285 PKR). The price is converted when the invoice is created — always rounded up to the next cent, so you never receive less — and that rate stays locked for the invoice.

{
  "amount": "2800",
  "currency": "PKR",
  "order_id": "1042"
}

// 1 USDT = 285 PKR  →  amount: "9.83", amount_to_pay: "9.8323"
A currency without a rate is refused with 400 clq_no_rate — an invoice is never created with a wrong amount. USD is treated as 1:1 with USDT unless you set a USD rate.

The invoice object

{
    "id": "inv_9f2c4e1a7b3d5c6e8f0a1b2c",
    "object": "invoice",
    "status": "pending",
    "amount": "10.00",
    "amount_to_pay": "10.0023",
    "currency": "USDT",
    "price_amount": "10",
    "price_currency": "USD",
    "rate": "1",
    "order_id": "1042",
    "description": "",
    "checkout_url": "https://clearqo.com/pay/inv_9f2c4e1a7b3d5c6e8f0a1b2c/",
    "methods": [
        {
            "type": "binance_pay",
            "value": "123456789",
            "name": "Acme Digital"
        },
        {
            "type": "usdt_trc20",
            "value": "TQ\u2026"
        },
        {
            "type": "usdt_bep20",
            "value": "0x\u2026"
        }
    ],
    "paid_amount": null,
    "paid_price_amount": null,
    "paid_method": null,
    "txid": null,
    "created_at": "2026-10-10T12:00:00+00:00",
    "expires_at": "2026-10-10T12:30:00+00:00",
    "paid_at": null
}
amount_to_paystringThe exact amount the customer must send.
methodsarrayPayment methods you enabled, with the Pay ID or address — useful if you build your own payment UI.
amountstringPrice converted to USDT (before the unique digits).
price_amount · price_currency · ratestringYour original price, its currency and the locked rate (units of price_currency per 1 USDT).
paid_amountstring | nullUSDT actually received.
paid_price_amountstring | nullWhat was received, in your price_currency at the locked rate. Credit your customer with this value.
paid_methodstring | nullpay, trc20, bep20 or manual.
txidstring | nullBinance Pay order ID or blockchain transaction hash.

Retrieve & list

GET/invoices/{id}

Returns the current invoice and triggers a fresh check against Binance. Use it to double-check a payment before fulfilling.

GET/invoices?status=paid&page=1

Lists invoices, newest first, 50 per page. Optional status filter.

curl https://clearqo.com/wp-json/clearqo/v1/invoices/inv_9f2c4e1a7b3d5c6e8f0a1b2c \
  -H "X-Api-Key: $CLEARQO_KEY"

Account

GET/me

Returns your plan, balance, Binance connection status and enabled methods — handy as a connection test.

Statuses

pendingstatusWaiting for the customer to pay.
paidstatusConfirmed on Binance. Safe to fulfil.
expiredstatusTime ran out. An exact late payment within 24 hours still turns it into paid.
reviewstatusA transaction arrived that did not match exactly (e.g. different amount). Approve or reject it in your dashboard.
rejectedstatusYou rejected the payment.

Errors & limits

Errors return a non-2xx status and a JSON body:

{
  "code": "clq_balance",
  "message": "Merchant balance is too low to accept payments. Please top up.",
  "data": { "status": 402 }
}
400Bad requestInvalid parameters, or no exchange rate set for the currency (clq_no_rate).
401UnauthorizedMissing or invalid API key.
402Payment requiredYour balance cannot cover the fee, or your monthly plan limit is reached.
403ForbiddenAccount suspended.
404Not foundInvoice does not exist or belongs to another account.
409ConflictBinance is not connected or no payment method is configured.
429Too many requestsRate limit: 120 requests per minute per API key.

Webhooks

Set your endpoint in Dashboard → Developers. We send a POST with a JSON body for these events:

invoice.paideventPayment confirmed — fulfil the order.
invoice.expiredeventThe invoice expired without payment.
invoice.revieweventA non-matching payment needs your decision.
invoice.rejectedeventYou rejected a payment.
test.pingeventSent from the dashboard to test your endpoint.
{
  "id": "evt_3b7c9d2e4f6a8b1c0d2e4f6a",
  "type": "invoice.paid",
  "created": 1760097600,
  "data": { "id": "inv_9f2c…", "status": "paid", "order_id": "1042", "paid_amount": "10.0023", "paid_price_amount": "10.0023", "…": "…" }
}

Reply with any 2xx status within 8 seconds. Otherwise we retry after 1 minute, 5 minutes, 30 minutes, 2 hours, 6 hours and 24 hours. Events can arrive more than once — process each invoice only once.

Verifying signatures

Every webhook includes X-Clearqo-Signature: t=TIMESTAMP,v1=SIGNATURE, where SIGNATURE = HMAC-SHA256(signing_secret, TIMESTAMP + "." + raw_body) in hex. Always verify it with the raw request body and reject timestamps older than 5 minutes.

<?php
$body   = file_get_contents('php://input');
parse_str(str_replace(',', '&', $_SERVER['HTTP_X_CLEARQO_SIGNATURE'] ?? ''), $sig);
$expected = hash_hmac('sha256', ($sig['t'] ?? '') . '.' . $body, getenv('CLEARQO_WEBHOOK_SECRET'));

if (!hash_equals($expected, $sig['v1'] ?? '') || abs(time() - (int) ($sig['t'] ?? 0)) > 300) {
    http_response_code(400);
    exit;
}
$event = json_decode($body, true);
if ($event['type'] === 'invoice.paid') {
    // fulfil order $event['data']['order_id'] once, for $event['data']['paid_price_amount']
}
http_response_code(200);
For maximum safety, after a valid webhook call GET /invoices/{id} and fulfil only if it returns paid.

WooCommerce

  1. Install the Clearqo for WooCommerce plugin and activate it.
  2. Open WooCommerce → Settings → Payments → Clearqo, enter the platform URL https://clearqo.com, your API key and your webhook signing secret.
  3. Set your webhook URL in the dashboard to the address shown in the plugin settings.
  4. For TeraWallet top-ups, set WooCommerce → Settings → General → Number of decimals to 4 so amounts like 10.0023 are credited in full.

Go-live checklist

Questions? support@clearqo.com