One API. Every USDT network.
A 100% NTPAY-compatible REST API: two endpoints, signed callbacks and a hosted checkout. Already on NTPAY? Change the base URL and you're done.
Getting started
Overview
Cradex is a non-custodial USDT gateway. You create an invoice from your server, redirect the customer to the hosted checkout, and the payment goes straight to your own wallet. We watch the chain, then notify your callback_url.
1. Create
Call AddInvoice with the amount and your order ID.
2. Redirect
Send the customer to url_payment to pay on any network.
3. Confirm
Receive a signed callback or poll GetInvoiceStatus.
| Base URL | https://cradex.net/api |
| Methods | GET and POST (query string, form-encoded or JSON) |
| Response | JSON, always HTTP 200 — check the status field |
| Encoding | UTF-8 |
| CORS | Allowed — but never call the API from a browser (it exposes your api_key) |
Security
Authentication
Every request carries two parameters: merchant_id and api_key. Create a merchant in your Business dashboard, add at least one receiving wallet and copy the credentials from the API credentials tab.
- The merchant must be Active.
- It must have at least one enabled receiving wallet.
- Your account needs a positive USD balance to cover gateway fees.
Endpoint
Create invoice
Creates a new USDT invoice and returns the hosted checkout link to redirect the customer to.
| Parameter | Type | Required | Description |
|---|---|---|---|
| merchant_id | string | Required | Your merchant ID (max 50 chars). |
| api_key | string | Required | Secret API key of the merchant (max 255 chars). |
| name | string | Required | Invoice title shown at checkout, e.g. “Order #4821” (max 255). |
| description | string | Required | Invoice details (max 500). |
| amount | float | Required | Amount in USDT. Minimum 1. |
| request_id | string | Optional | Your own unique order ID, echoed back in responses and callbacks (max 100). |
| callback_url | url | Optional | Where Cradex sends status callbacks. |
| success_url | url | Optional | Where the customer returns after a successful payment. |
| cancel_url | url | Optional | Where the customer returns if the invoice expires or is cancelled. |
curl -X POST https://cradex.net/api/AddInvoice \
-d merchant_id=YOUR_MERCHANT_ID \
-d api_key=YOUR_API_KEY \
-d name="Order #4821" \
-d description="Premium plan – 12 months" \
-d amount=249 \
-d request_id=ORDER_4821 \
-d callback_url=https://shop.example.com/webhooks/cradex \
-d success_url=https://shop.example.com/thank-you \
-d cancel_url=https://shop.example.com/cartResponse
{
"status": "success",
"msg": "Invoice creation successful!",
"data": {
"trans_id": "TX2604571052543841",
"request_id": "ORDER_4821",
"amount": "249.013",
"status": "waiting",
"url_payment": "https://cradex.net/payment/TX2604571052543841"
}
}Endpoint
Get invoice status
Returns the current state of an invoice. Use it to double-check a callback or to poll when callbacks are not an option.
| Parameter | Type | Required | Description |
|---|---|---|---|
| merchant_id | string | Required | Your merchant ID. |
| api_key | string | Required | Secret API key of the merchant. |
| trans_id | string | Required | Transaction ID returned by AddInvoice. |
curl "https://cradex.net/api/GetInvoiceStatus?merchant_id=YOUR_MERCHANT_ID&api_key=YOUR_API_KEY&trans_id=TX2604571052543841"Response
{
"status": "success",
"msg": "Get invoice status successful!",
"data": {
"trans_id": "TX2604571052543841",
"request_id": "ORDER_4821",
"amount": "249",
"received": "249.013",
"status": "completed",
"from_address": "TXyz123abc456def789ghi",
"transaction_id": "abc123def456…0123456789ab",
"create_gettime": "2026-10-31 10:30:00",
"update_gettime": "2026-10-31 10:41:22"
}
}Webhooks
Callbacks
When an invoice becomes completed or expired, Cradex calls your callback_url with these 9 fields — exactly like NTPAY. Fields are sent as a GET query string; if your URL contains type=HostBill they are sent as a POST form instead.
| Field | Description |
|---|---|
| request_id | Your order ID from AddInvoice. |
| trans_id | Cradex transaction ID. |
| merchant_id | Your merchant ID. |
| api_key | Your merchant API key (for NTPAY compatibility). |
| amount | Original requested amount. |
| received | Amount actually received (0 when expired). |
| status | completed or expired. |
| from_address | Sender wallet address (empty when expired). |
| transaction_id | On-chain transaction hash (empty when expired). |
GET https://shop.example.com/webhooks/cradex
?request_id=ORDER_4821
&trans_id=TX2604571052543841
&merchant_id=YOUR_MERCHANT_ID
&api_key=YOUR_API_KEY
&amount=249
&received=249.013
&status=completed
&from_address=TXyz123abc456def789ghi
&transaction_id=abc123def456…0123456789ab
X-Cradex-Timestamp: 1793442082
X-Cradex-Signature: sha256=5f0c1a…e9b2Only an HTTP 2xx response counts as delivered. Anything else (or a timeout) is retried on this schedule, up to 8 attempts in total:
Every attempt is logged on the invoice page in your dashboard, where you can also resend a callback manually. Make your handler idempotent — the same invoice may be delivered more than once.
Webhooks
Verifying signatures
On top of the NTPAY fields, each callback carries two headers so you can prove it came from Cradex — without relying on the api_key parameter alone:
X-Cradex-Timestamp: <unix seconds>
X-Cradex-Signature: sha256=HMAC_SHA256(webhookSecret, timestamp + "." + trans_id + "." + status + "." + received)The webhookSecret is shown next to your API key in the dashboard. Compare signatures in constant time and reject timestamps older than a few minutes to block replays.
<?php
// webhooks/cradex.php — xác minh chữ ký trước khi xử lý đơn
$secret = getenv('CRADEX_WEBHOOK_SECRET');
$data = $_SERVER['REQUEST_METHOD'] === 'POST' ? $_POST : $_GET;
$timestamp = $_SERVER['HTTP_X_CRADEX_TIMESTAMP'] ?? '';
$signature = $_SERVER['HTTP_X_CRADEX_SIGNATURE'] ?? '';
$payload = $timestamp . '.' . $data['trans_id'] . '.' . $data['status'] . '.' . $data['received'];
$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);
// Chống replay: từ chối callback cũ hơn 5 phút
if (!hash_equals($expected, $signature) || abs(time() - (int) $timestamp) > 300) {
http_response_code(401);
exit('Invalid signature');
}
if ($data['status'] === 'completed') {
// markOrderPaid($data['request_id'], $data['received'], $data['transaction_id']);
}
http_response_code(200); // chỉ 2xx mới được tính là thành công
echo 'OK';Reference
Invoice statuses
Created, waiting for the customer to pay.
No callback
The exact amount was received on-chain.
Callback sent
Lifetime ended without payment, or cancelled.
Callback sent
The hosted checkout may briefly show confirming while the transaction gathers confirmations; the API reports it as waiting until it is final. Invoices cancelled from the dashboard are reported as expired.
Reference
Error messages
Errors return HTTP 200 with { "status": "error", "msg": "…" }. The messages are identical to NTPAY so existing integrations keep working.
| msg | Cause |
|---|---|
| Please configure merchant_id | merchant_id is missing. |
| Please configure api_key | api_key is missing. |
| Merchant does not exist in the system | merchant_id or api_key is wrong. |
| This merchant is under maintenance | The merchant is disabled in your dashboard. |
| This merchant does not support the Crypto payment gateway | The merchant isn't set up for crypto payments. |
| This merchant does not have a wallet to receive money | Add and enable at least one receiving wallet. |
| User does not exist in the system | The owner account is locked or no longer exists. |
| Please enter the invoice name | name is missing. |
| Please enter the invoice description | description is missing. |
| Please enter the deposit amount | amount is missing. |
| The minimum amount is 1$ | amount is below 1 USDT. |
| Please do not SPAM | More than 4 identical invoices (name + description + amount) are waiting. |
| Please enter the transaction ID | trans_id is missing (GetInvoiceStatus). |
| Invoice does not exist in the system | Unknown trans_id or it belongs to another merchant. |
Reference
Rate limits & security
- Wrong API key. More than 15 failed attempts per minute temporarily blocks the calling IP.
- Duplicate invoices. At most 4 identical invoices (name + description + amount) can be waiting at the same time.
- Minimum amount. 1 USDT per invoice.
- Balance. The merchant owner must keep a positive USD balance to pay gateway fees.
- Use trans_id. Always look invoices up by trans_id, not request_id.
Integrations
WooCommerce & WHMCS
Because the API is NTPAY-compatible, any existing NTPAY / USDT plugin for WooCommerce, WHMCS or HostBill works with Cradex. You only point it at our base URL.
WooCommerce
- 1Install your NTPAY-compatible USDT gateway plugin.
- 2WooCommerce → Settings → Payments → USDT.
- 3Set the API URL to https://cradex.net/api.
- 4Paste your merchant_id and api_key, then save.
WHMCS
- 1Upload the NTPAY-compatible gateway module to /modules/gateways.
- 2Setup → Payments → Payment Gateways → activate it.
- 3Set the API URL to https://cradex.net/api.
- 4Enter merchant_id and api_key; callbacks are configured automatically.
type=HostBill in your callback URL — Cradex will then deliver callbacks as a POST form, as HostBill expects.Integrations
Migrating from NTPAY
Endpoints, parameters, responses, error messages and callback fields are identical. Migration is a one-line change:
// Before
$base_url = 'https://your-ntpay-domain.com';
// After
$base_url = 'https://cradex.net';- Create a merchant in Cradex and add your existing receiving wallets.
- Replace
merchant_idandapi_keywith your Cradex credentials. - Optionally verify the new
X-Cradex-Signatureheader for stronger security. - Return HTTP 2xx from your callback handler so deliveries are marked successful.
Ready to integrate?
Create a Business account, add a wallet and get your API keys in minutes.