Public merchant API · v1

Build plugins & gateways on CryptoXTS

Create invoices, redirect customers to hosted checkout, and receive signed payment webhooks. Designed for WHMCS, custom shops, and any server-side integration.

https://cryptoxts.com/api/v1 Download OpenAPI

Quick start

  1. Log in to the CryptoXTS panel → Domains.
  2. Create or open your site domain and copy API Key + API Secret (secret is shown once — store it safely).
  3. Call POST /api/v1/invoices from your server.
  4. Redirect the customer to checkout_url.
  5. When paid, CryptoXTS POSTs a signed webhook to your callback_url.
Never put API secrets in browser JavaScript, mobile apps, or public repos. All API calls must run on your backend.

Authentication

Every request requires both credentials. Keys are bound to one domain — you only see invoices for that domain.

X-API-KEY: cxts_xxxxxxxxxxxxxxxx
X-API-SECRET: your_64_character_secret
Accept: application/json
Content-Type: application/json

You may also send the key as Authorization: Bearer cxts_… plus X-API-SECRET.

Origin / referer check

If domain whitelist enforcement is enabled, browser Origin / Referer hosts must match your registered domain (or a subdomain). Server-to-server calls without those headers are fine.

Security rules (read this)

  • HTTPS only for API calls and webhook URLs.
  • Verify every webhook with HMAC-SHA512 before marking an invoice paid in your system.
  • Rotate keys in the panel if a secret may have leaked.
  • Use unique external_invoice_id values so retries stay idempotent.
  • Do not trust checkout page traffic alone — confirm via webhook or GET /invoices/{uuid}.
  • Return 2xx from your webhook endpoint only after you safely processed the event.
This public API cannot withdraw funds, export wallet keys, or access other merchants’ data. Those actions stay inside the secured merchant panel.

Endpoints

GET/api/v1/ping

Health check and credential test.

{
  "ok": true,
  "service": "cryptoxts",
  "domain": "shop.example.com",
  "domain_id": 1,
  "server_time": "2026-08-03T16:00:00+00:00"
}
GET/api/v1/stats

Lightweight revenue snapshot for dashboards.

{
  "revenue_month_usd": "1234.56",
  "pending_count": 3,
  "today": { "count": 2, "amount_usd": "50.00" },
  "synced_at": "2026-08-03T16:00:00+00:00"
}
POST/api/v1/invoices

Create a payment session. Returns 201 with a hosted checkout URL. Reusing the same open external_invoice_id returns the existing invoice.

Body

FieldTypeNotes
amount_usdnumberRequired · min 0.01
external_invoice_idstringYour system’s invoice / order id
callback_urlurlWebhook target (HTTPS)
success_urlurlWhere to send the customer after pay
cancel_urlurlCancel / back link
metaobjectOptional metadata (e.g. client_email, client_name)
curl -X POST "https://cryptoxts.com/api/v1/invoices" \
  -H "X-API-KEY: cxts_..." \
  -H "X-API-SECRET: ..." \
  -H "Content-Type: application/json" \
  -d '{
    "amount_usd": 49.99,
    "external_invoice_id": "ORDER-1001",
    "callback_url": "https://your.site/hooks/cryptoxts",
    "success_url": "https://your.site/orders/1001/thanks",
    "cancel_url": "https://your.site/orders/1001",
    "meta": { "client_email": "[email protected]", "client_name": "Buyer" }
  }'
{
  "uuid": "9b2c…",
  "status": "pending",
  "amount_usd": "49.99",
  "expires_at": "2026-08-03T17:00:00+00:00",
  "checkout_url": "https://cryptoxts.com/checkout/…"
}
GET/api/v1/invoices

List invoices for your domain.

QueryNotes
statuspending, partially_paid, paid, expired, cancelled
from / toDate filters (YYYY-MM-DD)
external_invoice_idExact match
client_emailLooks in meta
per_page1–100 (default 25)
GET/api/v1/invoices/{uuid}

Fetch one invoice. Coin, network, and deposit address appear after the customer selects a coin on checkout.

{
  "uuid": "9b2c…",
  "status": "paid",
  "status_label": "Paid",
  "amount_usd": "49.99",
  "coin": "btc",
  "network": "bitcoin",
  "address": "bc1q…",
  "crypto_amount_locked": "0.00078000",
  "amount_received": "0.00078000",
  "remaining": "0",
  "expires_at": "…",
  "paid_at": "…",
  "created_at": "…",
  "checkout_url": "…",
  "external_invoice_id": "ORDER-1001",
  "client_email": "[email protected]",
  "client_name": "Buyer",
  "txid": "abc…",
  "txids": ["abc…"]
}

Webhooks

On successful payment CryptoXTS POSTs JSON to callback_url (or your domain’s default webhook URL).

Headers

Content-Type: application/json
X-CryptoXTS-Signature: <hmac_sha512_hex>
X-CryptoXTS-Signature-Alg: hmac-sha512

Signature = HMAC-SHA512(raw_request_body, api_secret). Compare using a constant-time equals check.

Payload

{
  "event": "invoice.paid",
  "invoice_uuid": "9b2c…",
  "external_invoice_id": "ORDER-1001",
  "amount_usd": "49.99",
  "coin": "btc",
  "network": "bitcoin",
  "crypto_amount": "0.00078000",
  "amount_received": "0.00078000",
  "txid": "abc…",
  "txids": ["abc…"],
  "paid_at": "2026-08-03T16:12:00+00:00",
  "status": "paid"
}

PHP verify

$raw = file_get_contents('php://input');
$sig = $_SERVER['HTTP_X_CRYPTOXTS_SIGNATURE'] ?? '';
$expect = hash_hmac('sha512', $raw, $apiSecret);
if (!hash_equals($expect, $sig)) {
  http_response_code(401);
  exit('bad signature');
}
// mark invoice paid in your DB
http_response_code(200);

Node.js verify

const crypto = require('crypto');
function ok(rawBody, sig, secret) {
  const expect = crypto
    .createHmac('sha512', secret)
    .update(rawBody)
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(expect),
    Buffer.from(sig || '')
  );
}
Failed deliveries are retried automatically (backoff). Always make your handler idempotent.

Errors & rate limits

CodeMeaning
401Missing or invalid API key / secret
403Domain not allowed (origin whitelist)
404Invoice not found on this domain
422Validation error
429Rate limited — slow down

Limit: about 120 requests / minute per API credential / IP. Use exponential backoff on 429.

Invoice statuses

StatusMeaning
pendingWaiting for payment
partially_paidUnderpaid — still open
paidPaid (webhook fired)
expiredTimed out unpaid
cancelledCancelled

Out of scope (by design)

These are intentionally not in the public API so plugins cannot move or expose funds:

  • Withdrawals / payouts
  • Hot wallet balances or private keys
  • Admin / owner settings
  • Other merchants’ invoices

Need those capabilities? Use the merchant panel (login + 2FA), not this API.