Everything you need to integrate ChainPay into your application.
Accept crypto payments in 3 steps:
Step 1: Create an order
const response = await fetch("https://chainpay.pro/api/v1/orders", {
method: "POST",
headers: {
"Authorization": "Bearer sk_live_your_api_key",
"Content-Type": "application/json"
},
body: JSON.stringify({
amount: 10.00,
currency: "USDT",
chain: "trc20",
externalId: "order_123",
metadata: { userId: "user_456" }
})
})
const order = await response.json()
// order.checkoutUrl — redirect your user here
// order.payAddress — or show address directlyStep 2: Redirect user to checkout
window.location.href = order.checkoutUrlStep 3: Receive webhook when paid
// POST https://your-site.com/webhook
// Headers: X-ChainPay-Signature, X-ChainPay-Event
// Body:
{
"event": "payment.completed",
"orderId": "ord_abc123",
"netAmount": "9.92",
"currency": "USDT",
"chain": "trc20",
"txHash": "abc123..."
}/api/v1/ordersCreate a new payment order. Returns a payment address and checkout URL.
Request Body
{
"amount": 10.00, // USD amount
"currency": "USDT", // USDT | ETH | BTC | SOL
"chain": "trc20", // trc20 | erc20 | btc | sol
"externalId": "ord_123", // optional: your order ID
"metadata": {} // optional: arbitrary JSON
}Response
{
"orderId": "ord_a1b2c3d4e5f6g7h8",
"payAddress": "TXxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"cryptoAmount": "10.00",
"currency": "USDT",
"chain": "trc20",
"checkoutUrl": "https://chainpay.pro/pay/ord_a1b2c3d4",
"expiresAt": "2026-03-21T01:00:00Z"
}/api/v1/orders/:idGet order details by ID. Returns full order info when authenticated, limited info for public checkout.
{
"id": "ord_a1b2c3d4e5f6g7h8",
"amount": "10.00",
"cryptoAmount": "10.00",
"currency": "USDT",
"chain": "trc20",
"status": "completed",
"payAddress": "TXxxx...",
"txHash": "abc123...",
"createdAt": "2026-03-21T00:30:00Z",
"completedAt": "2026-03-21T00:35:00Z"
}/api/v1/ratesGet current cryptocurrency exchange rates (USD).
{
"USDT": 1.0,
"ETH": 3450.00,
"BTC": 87500.00,
"SOL": 145.00
}/api/merchant/webhook/testSend a test webhook event to your configured webhook URL.
// Response
{ "sent": true }ChainPay sends signed webhook events to your configured URL. Verify signatures using HMAC-SHA256.
payment.completed
{
"event": "payment.completed",
"orderId": "ord_a1b2c3d4e5f6g7h8",
"externalId": "order_123",
"amount": "10.00",
"currency": "USDT",
"chain": "trc20",
"txHash": "abc123def456...",
"netAmount": "9.92",
"completedAt": "2026-03-21T00:35:00Z",
"metadata": { "userId": "user_456" }
}payment.expired
{
"event": "payment.expired",
"orderId": "ord_a1b2c3d4e5f6g7h8",
"externalId": "order_123",
"amount": "10.00",
"currency": "USDT",
"chain": "trc20",
"metadata": { "userId": "user_456" }
}Signature Verification
const crypto = require("crypto")
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(payload)
.digest("hex")
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
)
}
// Usage in your webhook handler:
app.post("/webhook", (req, res) => {
const signature = req.headers["x-chainpay-signature"]
const isValid = verifyWebhook(
JSON.stringify(req.body),
signature,
"whsec_your_webhook_secret"
)
if (!isValid) return res.status(401).send("Invalid signature")
// Process the event...
res.status(200).send("OK")
})Use sandbox mode to test your integration without real blockchain transactions. Register with ?mode=test to get a sk_test_ API key.
1. Register a test account
POST /api/auth/register?mode=test
{
"email": "test@example.com",
"password": "your-password"
}
// Returns: { "merchant": { "apiKey": "sk_test_..." } }2. Create orders normally with your test key
POST /api/v1/orders
Authorization: Bearer sk_test_your_key
// Orders are created normally but blockchain polling is skipped3. Simulate a payment
POST /api/v1/sandbox/simulate-payment
Authorization: Bearer sk_test_your_key
{ "orderId": "ord_abc123" }
// Response:
{
"success": true,
"orderId": "ord_abc123",
"txHash": "sandbox_ord_abc123_1711000000000",
"netAmount": "9.92000000"
}
// This marks the order as completed and fires your webhookNote: Sandbox orders use fake transaction hashes prefixed with sandbox_. The simulate-payment endpoint only works with sk_test_ API keys.
| Chain | Currency | Confirmations | Avg Time |
|---|---|---|---|
| TRC20 | USDT | 20 | ~1 min |
| ERC20 | USDT | 12 | ~2 min |
| ERC20 | ETH | 12 | ~2 min |
| Bitcoin | BTC | 3 | ~30 min |
| Solana | SOL | 1 | <1 sec |
Create your account and get your API key in seconds.
Get Started Free