Developer documentation · v1

Connect your checkout.

Create a signed invoice, send your customer to checkout, and receive a verified payment result.

This API is ready for a custom adapter. PerfectPanel must approve and implement its native integration. This package does not modify PerfectPanel or require its Admin API.

1. Create your project

Choose a monthly package, save your USDT receiving wallets and create a project. Reveal its API key after identity confirmation.

2. Sign the request

Send all requests over HTTPS. Headers: X-Project-Id, X-Timestamp (Unix seconds), X-Nonce (unique 24–80 character string), X-Signature.

canonical = timestamp + "\n" + nonce + "\n" + "POST" + "\n"
          + "/api/v1/payments" + "\n" + exact_raw_json_body
signature = hex(HMAC-SHA256(canonical, project_api_key))

The timestamp window is 5 minutes. Reusing a nonce is rejected. For a retry, keep the same order ID and request body but generate a fresh timestamp, nonce and signature.

3. Create a payment

POST https://paynicos.com/api/v1/payments
Content-Type: application/json

{
  "amount": "10.00",
  "currency": "USDT",
  "network": "trc20",
  "order_id": "ORDER-123"
}

Networks: bep20, trc20, erc20. Only USDT is supported. USD pricing and exchange-rate conversion are not assumed. Optional callback_url and return_url must be HTTPS URLs on the project domain.

{
  "data": {
    "id": "invoice-uuid",
    "order_id": "ORDER-123",
    "currency": "USDT",
    "amount": "10.000000",
    "pay_amount": "10.004321",
    "network": "trc20",
    "address": "merchant-receiving-address",
    "status": "pending",
    "expires_at": "ISO-8601 timestamp",
    "checkout_url": "https://your-gateway/pay/invoice-uuid"
  }
}

The payable decimal reference above is illustrative. Always use the returned pay_amount, never calculate it yourself. The extra fraction goes to the merchant. A quote is never reused for the same wallet/network. An identical order ID returns its original invoice; changed inputs return HTTP 409. HTTP 402 means no active subscription or quota exhausted. HTTP 422 means invalid input or unavailable network.

4. Check invoice status

POST https://paynicos.com/api/v1/payments/status

{"order_id":"ORDER-123"}

Sign this endpoint with its own path. Statuses are pending, paid and expired. A transfer observed late by the scanner can still settle an expired invoice if its on-chain timestamp was strictly within the invoice window.

5. Verify your webhook

We POST JSON to your HTTPS callback. Verify the exact raw body and these headers:

X-Gateway-Event: stable-event-uuid
X-Gateway-Timestamp: unix-seconds
X-Gateway-Signature: hex-hmac

expected = hex(HMAC-SHA256(timestamp + "." + exact_raw_body, api_key))

Use a constant-time comparison, reject timestamps older than 5 minutes, check the event type and currency, and match the order, invoice and base amount to your stored order. In a database transaction, insert the unique event/invoice ID and credit the order only once. Return HTTP 2xx only after durable processing. Event IDs stay unchanged on retries. Delivery retries up to 12 times with exponential backoff; failed events can be retried from the dashboard.

{
  "event_id":"stable-event-uuid",
  "event":"payment.paid",
  "invoice_id":"invoice-uuid",
  "order_id":"ORDER-123",
  "currency":"USDT",
  "amount":"10.000000",
  "paid_amount":"10.004321",
  "network":"trc20",
  "address":"merchant-receiving-address",
  "status":"paid",
  "tx_hash":"confirmed-transaction-hash",
  "log_index":0,
  "paid_at":"ISO-8601 timestamp"
}
A browser return URL is only navigation. It must never credit an order. Payment completion comes from the verified webhook or authenticated status API.

Operational behavior