Connect your checkout.
Create a signed invoice, send your customer to checkout, and receive a verified payment result.
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"
}Operational behavior
- One transfer must contain the exact displayed amount. Partial, overpaid, pre-invoice and late transfers do not automatically fulfill another invoice.
- Only the configured USDT contract on the selected mainnet is accepted.
- BEP20 uses Binance-Peg USDT on BNB Smart Chain; ERC20 uses Ethereum USDT; TRC20 uses TRON USDT.
- Subscriptions govern new invoices. Already-issued invoices remain monitored after expiry of the merchant's subscription.
- Automatic reconciliation covers invoices from the last 48 hours. A longer outage requires operator review and provider backfill before reopening checkout.