Documentation
Merchant API Reference
Accept USDT payments on BNB Smart Chain. Customers pay to a unique deposit address per invoice; funds settle to your merchant balance.
Base URL
https://api.krovpay.com
Protocol
HTTPS only
Format
JSON
Response Envelope#
Every response is wrapped in a standard envelope with a success boolean and a data payload.
{
"success": true,
"data": { ... }
}Paginated responses include a meta field:
{
"success": true,
"data": [ ... ],
"meta": {
"page": 1,
"per_page": 20,
"total": 42,
"total_pages": 3
}
}Error responses:
{
"success": false,
"error": {
"code": "Bad Request",
"message": "amount_usdt must be a positive number"
}
}Authentication#
The API supports two authentication methods. Use whichever fits your integration.
Option 1 — JWT Bearer Token#
Log in to receive a JWT token and include it on every request. Best for dashboard sessions and server-side calls.
Authorization: Bearer <token>POST /auth/login.Option 2 — HMAC API Key#
Best for backend integrations. Each request must include three headers:
| Header | Value |
|---|---|
X-API-Key | Your API key (obtained from POST /auth/api-keys) |
X-Timestamp | Current UTC time in RFC 3339 format, e.g. 2024-01-15T10:30:00Z |
X-Signature | HMAC-SHA256 signature (see below) |
Signature construction:
message = METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + BODY
signature = HMAC-SHA256(api_secret, message) # hex-encodedExample (Python):
import hmac, hashlib, time, requests
from datetime import datetime, timezone
api_key = "pgk_..."
api_secret = "your_api_secret"
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
method = "POST"
path = "/invoices"
body = '{"amount_usdt":"100.00","customer_reference":"order_123"}'
message = f"{method}\n{path}\n{timestamp}\n{body}"
signature = hmac.new(api_secret.encode(), message.encode(), hashlib.sha256).hexdigest()
resp = requests.post(
"https://api.krovpay.com/invoices",
data=body,
headers={
"Content-Type": "application/json",
"X-API-Key": api_key,
"X-Timestamp": timestamp,
"X-Signature": signature,
}
)Rate Limits#
| Scope | Limit |
|---|---|
| Auth endpoints (/auth/register, /auth/login) | 10 requests/min per IP |
| All other endpoints | 120 requests/min per IP, plus per-merchant limits |
Rate-limited requests receive 429 Too Many Requests.
Invoices#
An invoice represents a payment request. Each invoice gets a unique BSC deposit address. Once the customer sends the exact USDT amount and 12 block confirmations pass, the invoice is marked paid and your balance is credited.
Create Invoice#
| Field | Type | Required | Description |
|---|---|---|---|
amount_usdt | string | Yes | Amount in USDT, e.g. "100.00" |
customer_reference | string | Yes | Your internal customer ID/customer phone number |
metadata | object | No | Any JSON object — stored and returned as-is |
expiry_minutes | integer | No | Minutes until expiry (default: 60) |
{
"amount_usdt": "100.00",
"customer_reference": "order_7821",
"metadata": { "product": "Pro Plan", "user_id": 42 },
"expiry_minutes": 30
}Response 201:
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440001",
"deposit_address": "0xAbCd...",
"amount_usdt": "100.00",
"status": "pending",
"customer_reference": "order_7821",
"metadata": { "product": "Pro Plan", "user_id": 42 },
"expires_at": "2024-01-15T11:00:00Z",
"created_at": "2024-01-15T10:30:00Z"
}
}Invoice statuses:
| Status | Meaning |
|---|---|
pending | Awaiting payment |
paid | Payment confirmed, balance credited |
expired | Expiry time passed without payment |
underpaid | Payment received but below the required amount |
| Status | Meaning |
|---|---|
400 | Invalid or missing fields |
503 | Payment processing temporarily unavailable (blockchain monitor is down) |
Get Invoice#
Poll this endpoint to check payment status.
Response 200: Same structure as the create response above.
| Status | Meaning |
|---|---|
400 | Invalid UUID format |
404 | Invoice not found or belongs to another merchant |
Deposits#
List Deposits#
Returns on-chain deposit records for your account.
| Param | Default | Max |
|---|---|---|
| page | 1 | — |
| per_page | 20 | 100 |
Response 200:
{
"success": true,
"data": [
{
"id": "...",
"invoice_id": "...",
"tx_hash": "0xabc123...",
"amount_usdt": "100.00",
"confirmations": 12,
"status": "confirmed",
"created_at": "2024-01-15T10:40:00Z"
}
],
"meta": { "page": 1, "per_page": 20, "total": 1, "total_pages": 1 }
}Health#
No authentication required. Returns the status of all backend workers.
Response 200:
{
"success": true,
"data": {
"status": "ok",
"workers": {
"bsc-watcher": "healthy",
"sweep-worker": "healthy",
"withdrawal-worker": "healthy",
"reconciliation": "healthy",
"hot-wallet-monitor": "healthy"
}
}
}bsc-watcher is unhealthy, POST /invoices will return 503 until it recovers.Integration Checklist#
Follow this checklist to ensure a complete and secure integration.
Register and obtain a JWT token (or create an API key for server-to-server use)
Configure a webhook URL and save the secret securely
Verify webhook signatures on every incoming event
Use customer_reference and metadata to link invoices to your orders
Use a unique idempotency_key per withdrawal request
Poll GET /invoices/{id} as a fallback if webhooks are not received
Monitor GET /health to detect platform outages before creating invoices
Ready to start integrating?
Register your merchant account and get your API credentials in minutes.
View Registration Endpoint