Developer Documentation

Everything you need to integrate ChainPay into your application.

Quick Start

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 directly

Step 2: Redirect user to checkout

window.location.href = order.checkoutUrl

Step 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 Reference

POST/api/v1/orders

Create 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"
}
GET/api/v1/orders/:id

Get 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"
}
GET/api/v1/rates

Get current cryptocurrency exchange rates (USD).

{
  "USDT": 1.0,
  "ETH": 3450.00,
  "BTC": 87500.00,
  "SOL": 145.00
}
POST/api/merchant/webhook/test

Send a test webhook event to your configured webhook URL.

// Response
{ "sent": true }

Webhook Events

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")
})

Sandbox / Test Mode

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 skipped

3. 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 webhook

Note: Sandbox orders use fake transaction hashes prefixed with sandbox_. The simulate-payment endpoint only works with sk_test_ API keys.

Supported Chains

ChainCurrencyConfirmationsAvg Time
TRC20USDT20~1 min
ERC20USDT12~2 min
ERC20ETH12~2 min
BitcoinBTC3~30 min
SolanaSOL1<1 sec

Ready to integrate?

Create your account and get your API key in seconds.

Get Started Free