API Documentation

Zepharion Pay is an API-first crypto payment gateway. Create a payment, send your customer to the hosted checkout, and receive a signed webhook when the money lands. This page is the complete integration guide.

1. Authentication

Create an API key in your dashboard (API keys → Create key). You get a public key (API key) and a secret key (YOUR_SECRET_KEY). The secret is shown once — store it in your server environment.

Authenticate every API call with the secret key:

Authorization: Bearer YOUR_SECRET_KEY

Use test-mode secret … keys to create test payments that never touch your balance.

2. Create a payment

POST /api/v1/payment
Content-Type: application/json
Authorization: Bearer YOUR_SECRET_KEY

{
  "amount_usd": 49.99,          // required, USD
  "asset": "USDT_TRC20",        // required, see assets table
  "order_id": "INV-1042",       // your reference (optional)
  "description": "Pro plan",    // shown at checkout
  "callback_url": "https://yourstore.com/cb",  // optional per-payment webhook
  "metadata": {"user_id": 7}    // optional, echoed back
}

Response:

{
  "ok": true,
  "payment": {
    "id": "9f0c…-…",                       // payment uuid
    "status": "pending",
    "amount_usd": 49.99,
    "asset": "USDT_TRC20",
    "crypto_amount": 49.507655,            // send exactly this
    "pay_address": "TQrY8bkbpXvFEU8uWK2F…", // receiving address
    "checkout_url": "https://zepharionlabs.com/pay/?id=9f0c…",
    "expires_at": "2026-10-10 18:30:00"
  }
}
Every payment gets a unique crypto_amount (down to the last decimal). That is how deposits are matched automatically — always show the exact amount to your customer.

Then redirect your customer to checkout_url or embed the pay_address + crypto_amount in your own UI.

Check a payment

GET /api/v1/payment/{uuid}        → single payment
GET /api/v1/payments?status=paid  → list (limit, offset)
GET /api/v1/balance               → balance + lifetime summary
GET /api/v1/rates                 → current USD rates

3. Webhooks

Add an endpoint in Dashboard → Webhooks. Each delivery is a JSON POST with these headers:

X-Zepharion-Event: payment.paid
X-Zepharion-Delivery: 1234
X-Zepharion-Timestamp: 1791647621
X-Zepharion-Signature: HMAC-SHA256 hex of  timestamp + "." + rawBody  with your endpoint secret

Events: payment.paid, payment.expired, payment.underpaid, payment.overpaid, payment.cancelled. Failed deliveries are retried with backoff (1m, 5m, 30m, 2h, 12h, 24h; max attempts configurable).

Verifying the signature (PHP)

$raw = file_get_contents('php://input');
$ts = $_SERVER['HTTP_X_ZEPHARION_TIMESTAMP'];
$expected = hash_hmac('sha256', $ts . '.' . $raw, $MY_ENDPOINT_SECRET);
if (!hash_equals($expected, $_SERVER['HTTP_X_ZEPHARION_SIGNATURE'])) {
    http_response_code(401); exit('bad signature');
}
$event = json_decode($raw, true);
if ($event['event'] === 'payment.paid') {
    // order_id: $event['data']['payment']['order_id']
    // amount:   $event['data']['payment']['amount_usd']
    markOrderPaid($event['data']['payment']['order_id']);
}
echo '{"ok":true}';

Verifying the signature (Node.js)

const crypto = require('crypto');
const expected = crypto.createHmac('sha256', process.env.ZP_WEBHOOK_SECRET)
  .update(req.headers['x-zepharion-timestamp'] + '.' + rawBody)
  .digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(req.headers['x-zepharion-signature']))) {
  return res.status(401).end();
}

4. Payment statuses

StatusMeaning
pendingWaiting for the customer to send funds.
confirmingFunds detected, waiting for network confirmations.
paidConfirmed and credited. Webhook fired. Fulfil the order.
underpaidCustomer sent less than required. Support will resolve.
overpaidCustomer sent more. The order is credited at the original amount.
expiredPayment window closed before funds arrived.
cancelled / failedCancelled by you or unrecoverable provider error.

5. Assets

CodeNetworkNotes
USDT_TRC20TronRecommended — low fees, fast.
USDT_ERC20EthereumHigh gas fees.
USDT_BEP20BNB ChainLow fees.
BTCBitcoinOn-chain confirmations required.
ETHEthereum—
USDTExchange (Binance/OKX/Bybit/BingX)Internal transfer, instant.

The available list is returned by GET /api/v1/assets — it reflects which providers the operator has enabled.

6. Errors

HTTPMeaning
400Validation error — see error in the JSON body.
401Missing/invalid API key.
402No active subscription on the merchant account.
404Payment not found (or not yours).
429Rate limited — slow down.

7. How to implement it on your website

Five steps, any platform (custom store, WordPress, DHRU, anything):

  1. Create an API key — Dashboard → API keys. You get a 40-character API key and a 64-character secret key.
  2. Create a payment server-side — POST /api/v1/payment with the amount and asset (section 2 above).
  3. Redirect the customer to checkout_url (hosted page with QR, address, live status).
  4. Receive the webhook — payment.paid arrives at your endpoint. Verify the signature (section 3), then mark your order paid.
  5. Test — do it with a test-mode key first, then with a small real payment.

8. Drop-in files & downloads

Your dashboard ships ready-to-use code so you never start from a blank page:

9. Platform modules

DHRU

DHRU uses its own Gateway Development Kit format (two files, renamed from customgateway.php / customgatewaycallback.php). Ready-made files and step-by-step instructions live in examples/dhru/ in the repository. Flow: DHRU invoice → module calls our API and redirects to the checkout → customer pays → payment.paid webhook marks the DHRU invoice paid.

WooCommerce & WHMCS

Ready-made modules ship in examples/woocommerce/ and examples/whmcs/ — also downloadable from the dashboard → Developers. The module creates the payment, redirects the customer to the hosted checkout, and a signed webhook marks the order or invoice paid automatically.

Everything else

Use the REST API + signed webhooks described in sections 2–4. Full developer guide: docs/INTEGRATION.md in the repository.

10. Support

Questions: support@zepharionlabs.com. Status page and changelog coming soon.