API Documentation (Crypto) (v2)
Accept USDT on BNB Smart Chain (BEP20), Polygon, and TRON with automated block confirmation indexing. Matrix Pay handles all wallet rotation, multi-chain gas estimates, and Web3 event listeners natively.
Quick Start & API Access
Production VerifiedFollow these 4 sequential steps to activate your reseller account and obtain live credentials.
Get your API Keys
Visit your Developer Hub to generate your live Client ID and API Secret Key. Your API key stays strictly server-side — never expose it in frontend code, browser consoles, or git repositories.
Complete Verification (eKYC)
Complete the identity & business verification process in the eKYC tab of your merchant dashboard. API access is unlocked automatically once approved with an active plan.
Receive Client ID & API Key
Once verified, your credentials are live. Your Client ID is passed in HTTP headers as `X-Client-Id`. Your API Secret Key signs every request via HMAC-SHA256 and stays server-side permanently.
Configure IP Whitelisting
In Developer Hub → IP Whitelisting tab, add your server's static outbound IP address(es). Every API request is verified against this whitelist — unlisted IPs receive a 403 IP_RESTRICTED response.
Build with an AI assistant
Latest AI TrendThis documentation sits behind authentication, so ChatGPT, Claude, Cursor, and Copilot cannot browse it directly. Copy the brief below into your assistant instead. It carries the complete specification on its own: every endpoint, payload schema, the order lifecycle, canonical HMAC-SHA256 signature protocol, webhook verification, and common pitfalls assistants get wrong (such as server-to-server only, no browser CORS, and production-first testing).
You are helping me integrate the Matrix Pay Crypto (USDT) payment gateway API into my application. Use only the specification below. Do not guess at endpoints, field names, or behaviour that is not written here, and do not try to fetch the documentation online: it sits behind an authenticated merchant dashboard and is not publicly reachable.
# 1. Non-negotiable constraints
1. This is a SERVER-TO-SERVER API. It enforces strict request validation and rejects browser-origin requests with CORS errors. Never call it from frontend JavaScript, browser applications, or mobile client code. All API calls must originate from my backend server.
2. The base host is https://matrixpay.vercel.app. THIS IS THE LIVE PRODUCTION HOST. There is no sandbox environment and no mock test mode. Testing is performed directly against production using real low-cost transactions of $1 USDT. Every transaction interacts with real on-chain deposit addresses.
3. Every API call is an HTTP POST request with a JSON body and Content-Type: application/json.
4. Authentication is performed via canonical HMAC-SHA256 request signing sent in custom HTTP request headers. Never put the API Secret Key in the JSON request body or URL parameters.
Required headers on every request:
- X-Client-Id: My Merchant Live Client ID
- X-Signature: Hex-encoded HMAC-SHA256 signature
- X-Timestamp: Unix timestamp in seconds (integer string, valid within ±300s window)
- X-Nonce: Cryptographically random unique nonce string (8-16 bytes hex, replay protection)
5. HMAC-SHA256 Request Signing Protocol:
- Canonicalize the JSON body: sort all keys alphabetically (A-Z) recursively, eliminate all whitespace between keys and values.
- Construct signing string: "${canonical_json_body}.${timestamp}.${nonce}"
- Compute HMAC-SHA256 using my API Secret Key as the HMAC key. Output the result as a lowercase hexadecimal string.
6. Supported Chains: TRC20 (Tron), BEP20 (Binance Smart Chain), ERC20 (Ethereum), POLYGON (Matic), SOLANA, ARBITRUM, OPTIMISM. Supported token: USDT.
7. IP Whitelisting: My server's static outbound IP address must be registered in the Developer Hub -> IP Whitelist tab. Requests originating from unlisted IPs are rejected with 403 IP_RESTRICTED.
8. The API Secret Key is confidential. It must never appear in frontend code, version control commits, public repositories, or client-side network inspect tabs. Store it as a secure environment variable on the server.
# 2. Endpoints
All endpoints accept HTTP POST with JSON body and the 4 authentication headers.
## Create Crypto (USDT) Order
POST https://matrixpay.vercel.app/api/v2/payment_gateway/create_crypto_order
Headers:
Content-Type: application/json
X-Client-Id: <client_id>
X-Signature: <hmac_sha256_signature>
X-Timestamp: <timestamp_seconds>
X-Nonce: <unique_nonce>
Request Body:
{
"customer_name": "Customer Name",
"customer_email": "customer@example.com",
"customer_mobile": "9876543210",
"amount": 10.00,
"token": "USDT",
"chain": "TRC20",
"customer_reference": "YOUR_UNIQUE_CRYPTO_REF",
"redirect_url": "https://yourstore.com/checkout/return",
"service_type": "CRYPTO"
}
Response (HTTP 200 or 201):
{
"order_id": "MP_CRYPTO_7JEV_9011",
"customer_reference": "YOUR_UNIQUE_CRYPTO_REF",
"amount": 10.00,
"token": "USDT",
"chain": "TRC20",
"deposit_address": "TQn9Y2khEsLJW1ChVWFMSMeRDow5KcbLSE",
"payment_url": "https://matrixpay.vercel.app/pay/MP_CRYPTO_7JEV_9011",
"status": "pending",
"required_confirmations": 3,
"expires_at": "2026-09-24T12:00:00Z"
}
## Check Crypto Order Status
POST https://matrixpay.vercel.app/api/v2/payment_gateway/check_crypto_order_status
Headers:
Content-Type: application/json
X-Client-Id: <client_id>
X-Signature: <hmac_sha256_signature>
X-Timestamp: <timestamp_seconds>
X-Nonce: <unique_nonce>
Request Body:
{
"order_id": "MP_CRYPTO_7JEV_9011"
}
Response (HTTP 200 or 422):
{
"order_id": "MP_CRYPTO_7JEV_9011",
"customer_reference": "YOUR_UNIQUE_CRYPTO_REF",
"amount": 10.00,
"token": "USDT",
"chain": "TRC20",
"status": "success",
"tx_hash": "0x5b3a4a1c6e1f0e2b9c7d4a3e2f1b0a9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a",
"confirmations": 12,
"paid_at": "2026-09-24T10:15:30Z"
}
# 3. Order Lifecycle & Statuses
The workflow sequence is:
1. Generate unique customer_reference on your server (e.g. CRYPTO_${Date.now()}_${randomUUID()}).
2. Call create_crypto_order with canonical HMAC-SHA256 signature headers.
3. Store order_id, deposit_address, and reference in your database.
4. Display deposit_address and QR code or redirect user to payment_url.
5. Listen for incoming webhook notifications OR poll check_crypto_order_status until confirmed on-chain.
There are exactly four order statuses:
pending Deposit address assigned, awaiting on-chain transaction or confirmations. Not terminal.
success On-chain transaction verified and confirmations reached. Terminal. Grant credit or fulfil goods.
refunded Transaction refunded or returned. Terminal.
failed Order window expired without deposit. Terminal.
# 4. Webhook Handling
Matrix Pay delivers asynchronous HTTP POST event updates to your configured Webhook URL when on-chain confirmations complete.
Incoming Webhook Headers:
Content-Type: application/json
X-Webhook-Signature: <hmac_sha256_hex_signature>
X-Webhook-Event: payment.success | payment.failed | payment.refunded
X-Webhook-Id: <delivery_uuid>
Webhook Payload:
{
"event": "payment.success",
"order_id": "MP_CRYPTO_7JEV_9011",
"customer_reference": "YOUR_UNIQUE_CRYPTO_REF",
"amount": 10.00,
"token": "USDT",
"chain": "TRC20",
"status": "success",
"tx_hash": "0x5b3a4a1c6e1f0e2b9c7d4a3e2f1b0a9c8d7e6f5a4b3c2d1e0f9a8b7c6d5e4f3a",
"confirmations": 12,
"timestamp": 1735689600
}
Signature Verification:
You MUST verify the signature using the raw request body buffer/string before JSON parsing:
expected_sig = HMAC_SHA256(secret = API_KEY, message = raw_request_body_string)
Compare expected_sig with header "X-Webhook-Signature" using a constant-time comparison.
Reject with 401 Unauthorized if signatures do not match. Respond with 200 OK immediately once verified.
# 5. How I want the integration written
- Implement a single, clean backend client class or module (e.g. MatrixPayCryptoClient).
- Keep API credentials strictly in environment variables (MATRIXPAY_CLIENT_ID and MATRIXPAY_API_KEY).
- Persist the customer_reference before sending the request and treat it as the idempotency key.
- Never retry a creation request with a new reference on network timeout — look up the order with check_crypto_order_status instead.
- Implement exponential backoff retry logic for transient errors (HTTP 500, 502, 503).
- Do not retry client errors (HTTP 400, 401, 403, 429).
- Never log raw API secrets or sensitive signing keys.
# 6. What I want from you
Ask me which backend language/framework I am using (e.g. Node.js/TypeScript, Python/FastAPI/Django, PHP/Laravel, Go, Java/Spring, C#/.NET) and whether I prefer webhook delivery or status polling, then write the complete, production-ready integration client and webhook handler.Client Libraries & SDKs
7 Languages SupportedChoose your preferred backend language. All samples use standard HTTP and native cryptographic HMAC-SHA256 libraries.
Works seamlessly with Node 18+, Bun, Deno, Next.js, and Express.
npm install axios cryptoStandard library hmac + hashlib used for canonical signing. Works with FastAPI & Django.
pip install requestsNative hash_hmac('sha256') & ksort() used for strict key canonicalization.
composer require guzzlehttp/guzzleZero external dependencies — uses crypto/hmac, crypto/sha256, and net/http standard library.
go get github.com/matrixpay/go-gatewayCompatible with Java 11+ HttpClient and Spring Boot Microservices.
implementation 'org.apache.httpcomponents.client5:httpclient5'Built for .NET 6, 7, 8 & ASP.NET Core web APIs using HMACSHA256.
dotnet add package System.Net.Http.Json1. Signature Generation & Authentication
Server-side request signing protocol for canonical request authentication.
To enhance security, every request must be signed on your server. The signature is created by serializing the payload into canonical JSON (sorted keys, no whitespace), joining it with a timestamp and a random nonce, and hashing the result with your API key using HMAC-SHA256. The resulting signature is sent alongside the timestamp and nonce in the request headers. This must be done server-side so your API key is never exposed.
# 1. Define API Credentials & Payload
CLIENT_ID="your_client_id"
API_KEY="your_api_secret_key"
# 2. Generate Unix Epoch Timestamp & Random 16-hex Nonce
TIMESTAMP=$(date +%s)
NONCE=$(openssl rand -hex 16)
# 3. Form Canonical JSON (alphabetically sorted keys, compact separators)
PAYLOAD='{"amount":"100.96","customer_email":"john@gmail.com","customer_mobile":"9876543210","customer_name":"John Doe","redirect_url":"https://example.com/success"}'
# 4. Create Signing String: payload.timestamp.nonce
MESSAGE="${PAYLOAD}.${TIMESTAMP}.${NONCE}"
# 5. Compute HMAC-SHA256 Hex Digest
SIGNATURE=$(echo -n "${MESSAGE}" | openssl dgst -sha256 -hmac "${API_KEY}" -hex | sed 's/^.* //')
# 6. Send Request with Required Security Headers
curl -X POST "https://matrixpay.vercel.app/api/v2/payment_gateway/create_upi_order" \
-H "Content-Type: application/json" \
-H "X-Client-Id: ${CLIENT_ID}" \
-H "X-Timestamp: ${TIMESTAMP}" \
-H "X-Nonce: ${NONCE}" \
-H "X-Signature: ${SIGNATURE}" \
-d "${PAYLOAD}"Interactive HMAC-SHA256 Signature Calculator
Canonical Body + Timestamp + Nonce2. Webhook Verification & Handling
Verify incoming webhook event payloads from Matrix Pay servers.
To ensure security, you must verify the X-Webhook-Signature header sent with the webhook request. When an event occurs on your account, such as a successful payment, Matrix Pay will send an HTTP POST request to your configured webhook URL.
Webhook Headers
| Header Name | Type | Required | Description |
|---|---|---|---|
| X-Webhook-Signature | string | Required | The HMAC SHA256 signature generated using your API key to verify the payload integrity. |
| X-Webhook-Event | string | Required | The name of the event that triggered the webhook (e.g., payment.success). |
| X-Webhook-Id | string | Required | A unique identifier for this specific webhook delivery attempt. |
# Test your webhook handler locally from the command line:
API_KEY="your_api_secret_key"
PAYLOAD='{"event":"payment.success","order_id":"MSPGPL260101","amount":"100.96","utr_number":"312345678901","currency":"INR","timestamp":"2026-06-02T21:18:00Z"}'
# 1. Compute HMAC-SHA256 hex digest of RAW request payload
SIGNATURE=$(echo -n "${PAYLOAD}" | openssl dgst -sha256 -hmac "${API_KEY}" -hex | sed 's/^.* //')
# 2. Dispatch simulated webhook event
curl -X POST "http://localhost:5000/webhooks/matrixpay" \
-H "Content-Type: application/json" \
-H "X-Webhook-Signature: ${SIGNATURE}" \
-H "X-Webhook-Event: payment.success" \
-H "X-Webhook-Id: evt_test_12345" \
-d "${PAYLOAD}"Payload Parameters
When an event is triggered, our servers will dispatch a JSON payload to your configured endpoint. Below is a detailed breakdown of the data fields you will receive in the request body.
| Field Name | Type | Required | Description |
|---|---|---|---|
| event | string | Required | The type of event that triggered the webhook. You will receive either payment.success or payment.failed. |
| event_id | string | Required | A unique identifier generated by Matrix Pay for this specific webhook delivery. You can use this to prevent processing duplicate events. It will exactly match the X-Webhook-Id header. |
| order_id | string | Required | The unique Matrix Pay internal identifier for the processed Crypto order (e.g. MSC202606041111111234). |
| txn_hash | string | Required | The official transaction hash confirming the transfer on the blockchain explorer. |
| selected_network | string | Required | The official network through which the transaction is made (e.g. BNB Smart Chain (BEP20), Polygon, or TRON (TRC20)). |
| amount | string | Required | The exact transaction amount that was processed, returned to you as a string. |
| status | string | Required | The final state of the transaction. You will receive the updated status, such as Success or Failed. |
| date_time | string | Optional | The ISO 8601 timestamp representing when the transaction was completed on our system. |
| comment | string | Optional | The optional comment or note you provided during the initial order creation. |
| sent_at | string | Required | The ISO 8601 timestamp recording exactly when our server dispatched this webhook payload to your endpoint. |
Example Webhook JSON Payload
{
"event": "payment.success",
"event_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"order_id": "MSC202606041111111234",
"txn_hash": "0x9c4f682d33451e9bca9a2399201f893e...",
"selected_network": "BNB Smart Chain (BEP20)",
"amount": "100.4812",
"status": "Success",
"date_time": "2026-06-02T21:18:00+05:30",
"comment": "Payment for crypto service",
"sent_at": "2026-06-02T21:18:05+05:30"
}Acknowledging Webhooks
After verifying the signature and processing the payload, your server must acknowledge receipt by returning a 2xx HTTP status code (such as 200 OK) within 5 seconds.
To explicitly confirm that your system successfully handled the event, we strongly recommend responding with a JSON payload containing {"received": true}. If your server responds with a non-2xx status code, or if the request times out, our systems will automatically retry the webhook delivery up to 5 times with increasing delays.
https://matrixpay.vercel.app/api/v2/payment_gateway/create_crypto_orderGenerates a dynamic Web3 USDT payment link and QR code. This endpoint returns a unique URL that you can present to your customers to collect payments via multi-chain crypto wallets.
Headers
| Header | Type | Required | Description |
|---|---|---|---|
| X-Client-Id | string | Required | Your unique Client ID provided by Matrix Pay. |
| X-Signature | string | Required | The HMAC-SHA256 signature generated using your API key and the request payload. Required for authentication. |
| Content-Type | string | Required | Must be set to application/json. |
Body Parameters
[ ] { } ( ), dollar signs $, or angled brackets < > in any of the values.| Field | Type | Required | Rules & Description |
|---|---|---|---|
| amount | string | Required | The exact transaction amount in USDT. Min 1.0000, max of 4 decimal places allowed (e.g. "100.4812"). |
| redirect_url | string | Required | The destination URL where customer will be redirected automatically after completing payment. Localhost restricted. |
| customer_name | string | Required | Min 3 chars. Only letters, spaces, and dots allowed (e.g. "John Doe"). |
| customer_email | string | Required | Must be a valid email address format (e.g. "john@gmail.com"). |
| customer_mobile | string | Required | Range of 10 to 15 digits. Supports international phone formats (e.g. "+14155552671"). |
# 1. Set Credentials & Payload
CLIENT_ID="your_client_id"
API_KEY="your_api_secret_key"
TIMESTAMP=$(date +%s)
NONCE=$(openssl rand -hex 16)
PAYLOAD='{"amount":"10.00","currency":"USDT","chain":"BEP20","customer_email":"john@gmail.com","customer_name":"John Doe","redirect_url":"https://example.com/success"}'
# 2. Compute HMAC Signature
SIGNATURE=$(echo -n "${PAYLOAD}.${TIMESTAMP}.${NONCE}" | openssl dgst -sha256 -hmac "${API_KEY}" -hex | sed 's/^.* //')
# 3. Create Crypto Order
curl -X POST "https://matrixpay.vercel.app/api/v2/payment_gateway/create_crypto_order" \
-H "Content-Type: application/json" \
-H "X-Client-Id: ${CLIENT_ID}" \
-H "X-Timestamp: ${TIMESTAMP}" \
-H "X-Nonce: ${NONCE}" \
-H "X-Signature: ${SIGNATURE}" \
-d "${PAYLOAD}"Response Parameters Table
| Field | Type | Description |
|---|---|---|
| success | boolean | Returns true for success and false for failures. |
| data.order_id | string | Unique Matrix Pay internal identifier generated for this Crypto order. |
| data.status | string | Initial state of order (e.g., Pending). |
| data.amount | string | Requested transaction amount in USDT. |
| data.currency | string | Currency code, fixed to USDT. |
| data.selected_network | string | null | Selected blockchain network (returns null until buyer selects chain on hosted checkout page). |
| data.payment_url | string | Destination URL for customer crypto payment completion. |
Response Example (201 OK)
{
"success": true,
"data": {
"order_id": "MSC202606041111111234",
"status": "Pending",
"amount": "100.4812",
"currency": "USDT",
"selected_network": null,
"payment_url": "https://matrixpay.vercel.app/pay/xyz123"
},
"error": null
}Live Interactive Console — Create Crypto Order
POST /api/v2/payment_gateway/create_crypto_order# 1. Calculate HMAC-SHA256 signature
TIMESTAMP=$(date +%s)
NONCE=$(openssl rand -hex 8)
PAYLOAD='{"amount":"25.0000","selected_network":"BEP20","customer_mobile":"9876543210","customer_name":"Crypto Trader","order_id":"ORD_CRYPTO_5521","redirect_url":"https://example.com/payment/callback"}'
SIGNATURE=$(echo -n "${PAYLOAD}.${TIMESTAMP}.${NONCE}" | openssl dgst -sha256 -hmac "${displayApiKey}" -hex | sed 's/^.* //')
curl -X POST "https://matrixpay.vercel.app/api/v2/payment_gateway/create_crypto_order" \
-H "Content-Type: application/json" \
-H "X-Client-Id: ${displayClientId}" \
-H "X-Signature: ${SIGNATURE}" \
-H "X-Timestamp: ${TIMESTAMP}" \
-H "X-Nonce: ${NONCE}" \
-d "${PAYLOAD}"https://matrixpay.vercel.app/api/v2/payment_gateway/check_crypto_order_statusRetrieve the details of an existing Crypto payment link or transaction status programmatically.
# 1. Set Credentials & Order ID
CLIENT_ID="your_client_id"
API_KEY="your_api_secret_key"
TIMESTAMP=$(date +%s)
NONCE=$(openssl rand -hex 16)
PAYLOAD='{"order_id":"CRYPTO_ORD_5521"}'
# 2. Compute HMAC Signature
SIGNATURE=$(echo -n "${PAYLOAD}.${TIMESTAMP}.${NONCE}" | openssl dgst -sha256 -hmac "${API_KEY}" -hex | sed 's/^.* //')
# 3. Check Crypto Order Status
curl -X POST "https://matrixpay.vercel.app/api/v2/payment_gateway/check_crypto_order_status" \
-H "Content-Type: application/json" \
-H "X-Client-Id: ${CLIENT_ID}" \
-H "X-Timestamp: ${TIMESTAMP}" \
-H "X-Nonce: ${NONCE}" \
-H "X-Signature: ${SIGNATURE}" \
-d "${PAYLOAD}"Order Status Enum Values
| Status Enum | Description |
|---|---|
| Success | Token transfer received on-chain and verified against RPC block confirmations. |
| Refunded | Payment was received and subsequently refunded to buyer wallet address. |
| Pending | Awaiting crypto transfer from buyer. |
| Queue | Transaction detected on-chain, awaiting required block confirmations. |
| Failed | Transaction attempted but failed on-chain. |
| Cancelled | User exited the payment session before transferring tokens. |
| Expired | 30-minute wallet deposit lock expired before payment was detected. |
Selectable Status Response Examples
// HTTP Status: 200 OK
{
"success": true,
"data": {
"order_id": "MSC202606041111111234",
"amount": "100.4812",
"currency": "USDT",
"status": "Success",
"message": "Crypto transfer detected and confirmed on-chain.",
"txn_hash": "0x9c4f682d33451e9bca9a2399201f893e...",
"selected_network": "BNB Smart Chain (BEP20)",
"date_time": "2026-06-02T21:18:00+05:30",
"created_at": "2026-06-02T21:15:00+05:30"
},
"error": null
}Live Interactive Console — Check Crypto Order Status
POST /api/v2/payment_gateway/check_crypto_order_status# 1. Calculate HMAC-SHA256 signature
TIMESTAMP=$(date +%s)
NONCE=$(openssl rand -hex 8)
PAYLOAD='{"order_id":"CRYPTO_1790182512_8391"}'
SIGNATURE=$(echo -n "${PAYLOAD}.${TIMESTAMP}.${NONCE}" | openssl dgst -sha256 -hmac "${displayApiKey}" -hex | sed 's/^.* //')
curl -X POST "https://matrixpay.vercel.app/api/v2/payment_gateway/check_crypto_order_status" \
-H "Content-Type: application/json" \
-H "X-Client-Id: ${displayClientId}" \
-H "X-Signature: ${SIGNATURE}" \
-H "X-Timestamp: ${TIMESTAMP}" \
-H "X-Nonce: ${NONCE}" \
-d "${PAYLOAD}"5. Supported Multi-Chain USDT Standards
Matrix Pay native contract addresses and confirmation thresholds per supported chain.
Contract: 0x55d398326f99059fF775485246999027B3197955
Avg finality: 3 seconds
Contract: 0xc2132D05D31c914a87C6611C10748AEb04B58e8F
Avg finality: 2 seconds
Contract: TR7NHqjeKQxGTCi8q8ZY4pL8otSzgjLj6t
Avg finality: 3 seconds
6. Comprehensive Error Codes Table
Full reference of HTTP status codes and programmatic error codes returned by Matrix Pay APIs.
| HTTP Status | Error Code(s) | Description & Remediation |
|---|---|---|
| 400 Bad Request | INVALID_JSON / INVALID_PAYLOAD / INVALID_AMOUNT / INVALID_CUSTOMER_NAME | Payload is invalid JSON, violates firewall (forbidden symbols), or individual fields failed validation. Amount must have max 4 decimal places for USDT. |
| 401 Unauthorized | AUTH_HEADERS_MISSING / UNAUTHORIZED / STALE_REQUEST | Missing headers (X-Client-Id, X-Signature, X-Timestamp, X-Nonce), invalid credentials, or timestamp outside allowed time window. |
| 403 Forbidden | IP_WHITELIST_EMPTY / IP_RESTRICTED / INVALID_SIGNATURE / SUBSCRIPTION_REQUIRED | Access control violation: IP not whitelisted, invalid HMAC signature, or no active subscription plan on merchant account. |
| 409 Conflict | SERVICE_NOT_AUTHORIZED | Credentials are valid but not authorized for the Payment Gateway service. |
| 429 Too Many Requests | QUOTA_EXCEEDED / VOLUME_LIMIT_EXCEEDED | Plan limit hit. QUOTA_EXCEEDED means monthly order quota is full; VOLUME_LIMIT_EXCEEDED means order amount exceeds plan volume limit. Upgrade plan to continue. |
| 502 Bad Gateway | PAYMENT_LINK_FAILED | Upstream RPC node or deposit link generator failed to generate link. Retry request. |
| 503 Service Unavailable | INACTIVE_MERCHANT / BUSY_MERCHANT | INACTIVE_MERCHANT indicates receiving account is misconfigured. BUSY_MERCHANT indicates assigned wallet nodes are busy, retry after short delay. |
| 500 Internal Error | SERVER_ERROR | Unexpected server-side error. Contact support with your order_id. |
Security Best Practices
Mandatory security guidelines every merchant integration must follow.
Your API Secret Key must only exist in server-side code (Node.js, Python, PHP, Go, Java, C#). It must never be bundled, minified, or embedded in browser-facing code, mobile apps, or HTML.
Never hardcode credentials in source files. Use environment variables (e.g. process.env.MATRIXPAY_API_KEY) and a secrets manager for production. Rotate immediately if exposed.
All API calls must be made over HTTPS (TLS 1.2 minimum, TLS 1.3 recommended). Plain HTTP connections are rejected. Validate SSL certificates — never disable certificate verification.
Rotate your API Secret Key on a regular schedule (recommended every 90 days) or immediately upon suspected compromise. New keys take effect instantly; old keys are invalidated.
Configure your server's static outbound IP address(es) in Developer Hub → IP Whitelist tab. Only whitelisted IPs can call the API. Use dedicated NAT gateway IPs in cloud environments — dynamic IPs will be blocked.
Matrix Pay APIs are server-to-server only. Browser-origin requests via CORS are deliberately blocked. Always proxy API calls through your backend — never call the gateway directly from a browser or mobile app frontend.
Critical Security Notice
If your API Secret Key is ever committed to source control, logged in browser DevTools, or returned in a client-facing response — treat it as compromised immediately. Regenerate your keys from the Developer Hub and audit your logs.
Rate Limits & Plan Quotas
API usage limits are enforced per merchant account based on your active subscription plan.
| Limit Type | Details | Error Code | Action |
|---|---|---|---|
| Monthly Order Quota | Maximum number of orders per calendar month as defined by your plan tier | QUOTA_EXCEEDED (429) | Upgrade your plan or wait for monthly reset |
| Monthly Volume Limit | Maximum total transaction value per calendar month (e.g. ₹25,00,000 / month) | VOLUME_LIMIT_EXCEEDED (429) | Upgrade your plan or reduce order amounts |
| Request Signing Window | Timestamp in X-Timestamp header must be within ±300 seconds of server time | STALE_REQUEST (401) | Sync your server clock with NTP |
| Nonce Reuse | Each X-Nonce value must be globally unique — replay attacks are blocked | UNAUTHORIZED (401) | Generate a fresh cryptographic nonce per request |
| Concurrent Requests | Excessive parallel requests from the same account may be throttled temporarily | 429 / 503 | Implement exponential backoff retry logic |
check_crypto_order_status endpoint to track order state without consuming new creation quota.Error Handling & Automatic Retry Logic
Retrying transient errors with exponential backoff resolves transaction failures safely.
502 PAYMENT_LINK_FAILED— Upstream gateway timeout; retry after 2–5 seconds503 BUSY_MERCHANT— Merchant slot unavailable; retry after 3–10 seconds500 SERVER_ERROR— Transient server error; retry up to 3 times with backoff- Network timeout / connection reset — Retry with a fresh nonce and timestamp
400 INVALID_PAYLOAD— Fix the request body before retrying401 UNAUTHORIZED— Credentials invalid; check keys & signature logic403 IP_RESTRICTED— Add server IP to whitelist first403 SUBSCRIPTION_REQUIRED— Activate a plan before retrying429 QUOTA_EXCEEDED— Upgrade plan before retrying
Recommended Retry Strategy (Backoff Pattern)
async function callWithRetry(fn, maxRetries = 3) {
const retryableStatuses = [500, 502, 503];
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
const res = await fn();
if (!retryableStatuses.includes(res.status)) return res;
if (attempt === maxRetries) return res;
// Exponential backoff: 2s, 4s, 8s
await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 1000));
} catch (err) {
if (attempt === maxRetries) throw err;
await new Promise(r => setTimeout(r, Math.pow(2, attempt) * 1000));
}
}
}
// Always generate a fresh X-Nonce + X-Timestamp on each retry attemptTesting & Production Go-Live
Production-first testing — no sandbox environment needed.
Production Environment — Real-Time Testing
Matrix Pay operates exclusively on a live production environment with no sandbox mode. Testing is done directly against production with real low-cost transactions — no environment switches, no dummy credentials, no mock endpoints required.
What Real Testing Includes
Test with real transactions of $1 USDT
Create a Crypto (USDT) order for the minimum test amount ($1 USDT). Complete a real payment through the generated link. Verify the status endpoint returns `success`.
Get actual API responses and timing
Measure real end-to-end latency from your server to Matrix Pay and back. Validate that your signature logic, header formatting, and JSON canonicalization are correct using real responses.
Validate complete payment workflow
Create order → receive payment link → complete payment → poll status → receive webhook → update your system. Test the full flow end-to-end with real $1 USDT before going live at scale.
No environment switches required
The same API endpoint, same credentials, same response format used for ₹1 testing is identical to production at scale. No staging URLs, no flag toggles, no separate test accounts.
Integration Workflow Checklist
Get your API keys from Developer Hub and configure IP whitelisting
Test HMAC-SHA256 signature generation using the Signature Playground above
Create a Crypto (USDT) order for $1 USDT via the Interactive Console or Floating Console
Validate the payment link opens correctly and complete a real test payment
Poll the status endpoint and verify it returns `status: "success"`
Configure your webhook endpoint and verify you receive the `payment.success` event
Review error codes and implement retry logic for 502/503 responses
Go live — scale up to full production volume with the same integration