API reference
REST endpoints for the DHRU plugin and direct integrations.
API reference
Base URL: https://triapay.net. Server-to-server requests authenticate with Authorization: Bearer <api_key>. Browser sessions use the cookie set by /auth/login plus a CSRF token from /auth/csrf.
Authentication
Two key tiers per account:
| Prefix | Use |
|---|---|
pk_live_* |
Production. Cannot be revealed after creation. Rotate to replace. |
pk_test_* |
Sandbox. Revealable from the dashboard. Sandbox-only endpoints. |
Rotate keys and webhook secrets from the Integration page. Rotation requires email OTP.
Create order
POST /api/v1/orders
Authorization: Bearer pk_live_...
Content-Type: application/json
{
"invoiceId": 12345,
"userId": 678,
"baseAmount": "10.00",
"currency": "USD",
"chain": "bep20",
"asset": "USDT",
"idempotencyKey": "01HT8X1V...-uuid",
"returnUrl": "https://shop.example.com/orders/12345"
}
| Field | Type | Notes |
|---|---|---|
invoiceId |
int | Your DHRU invoice id. |
userId |
int | DHRU user id for credit attribution. |
baseAmount |
string | Decimal string. A small amount-suffix is added for crypto chains. |
currency |
string | Source currency. |
chain |
enum | trc20 | bep20 | binance_pay. BEP20 and TRC20 also accept Binance internal (off-chain) transfers to the same deposit address. |
asset |
enum | USDT | USDC. TRC20 is USDT-only. |
idempotencyKey |
string | UUID. Repeated requests with the same payload return the same order. |
returnUrl |
string | Redirect target after the order ends. |
Response
{
"orderId": 4711,
"checkoutToken": "ck_a8f3...",
"checkoutUrl": "https://triapay.net/checkout/ck_a8f3...",
"expectedAmount": "10.0001",
"matchCode": 1,
"expiresAt": "2026-05-08T05:30:00Z",
"status": "pending"
}
Redirect the customer to checkoutUrl. Use expectedAmount as the exact amount the customer must send.
Order status
GET /api/v1/orders/{idempotencyKey}/status
Authorization: Bearer pk_live_...
{
"orderId": 4711,
"status": "credited",
"txHash": "0xabc...",
"matchedAmount": "10.0001",
"creditedAt": "2026-05-08T05:18:42Z"
}
Order states form a black-box state machine:
pending— awaiting payment.matched— funds received, credit in progress.credited— terminal success. Webhook acknowledged.expired— terminal. Customer did not pay in time.failed— terminal. Webhook delivery exhausted retries.overpaid— terminal. Customer sent more than expected. Order is credited; flagged for manual review.
Late arrivals (chain settlement after expiresAt) are not auto-credited. Recover them from Admin → Orphan transactions.
Sandbox helpers
Available with pk_test_* only. Force terminal states without waiting for chain settlement:
POST /api/v1/sandbox/orders/{idempotencyKey}/force-match
POST /api/v1/sandbox/orders/{idempotencyKey}/force-credit
POST /api/v1/sandbox/orders/{idempotencyKey}/force-expire
POST /api/v1/sandbox/webhook/replay
Empty body. Returns the updated order. Sandbox webhooks include X-Payment-Mode: sandbox; the bundled DHRU plugin short-circuits these without crediting any invoice.
Customer-facing checkout
Token-only auth. Used by the hosted checkout page:
GET /api/v1/checkout/{token}/status
GET /api/v1/checkout/{token}/methods
POST /api/v1/checkout/{token}/select-method
select-method body: {"chain": "bep20", "asset": "USDT"}. Returns the order with deposit address, expected amount, QR data URI, and match code.
Errors
JSON envelope, HTTP status reflects the class:
{ "error": "invalid_credentials", "code": "unauthorized" }
| HTTP | code |
When |
|---|---|---|
| 400 | validation_error |
Bad payload shape, missing required fields. |
| 401 | unauthorized |
Missing or invalid bearer / session. |
| 403 | forbidden |
IP not allowlisted, sandbox-only on a live key. |
| 404 | not_found |
Token expired, idempotency key unknown. |
| 409 | conflict |
Idempotency-key reused with a different payload. |
| 429 | rate_limited |
Honor the Retry-After header (seconds). |
| 500 | internal |
Server error. Retry with backoff. |
Rate limits are enforced per account. Respect Retry-After on every 429.
Idempotency
Every state-changing request takes an idempotencyKey. Repeating the same key with the same payload returns the original order. Repeating the same key with a different payload returns:
{ "error": "idempotency_payload_mismatch", "code": "conflict" }
Generate the key as a UUIDv4 per invoice and persist it on your side so retries after a network failure do not double-charge.
Need more?
Anything beyond this page is available under partner agreement. Reach us via WhatsApp on the homepage.