# CNIXPay > Accept USDT and USDC on TRON, BSC, Ethereum, Polygon and Solana through one API. Dedicated deposit addresses, real-time confirmation, signed callbacks, merchant balance and withdrawals. CNIXPay is a stablecoin payment gateway for merchants. A merchant creates an order through a server-side REST API, the customer pays USDT or USDC (or a native coin) on a supported network, and the platform confirms the deposit on-chain, credits the merchant balance and sends a signed webhook. Every order gets dedicated deposit addresses; one order may offer up to 10 network × token options at once. ## Supported networks and tokens - TRON (`tron`, TRC20): USDT - BNB Smart Chain (`bsc`, BEP20): USDT, USDC - Ethereum (`eth`, ERC20): USDT, USDC - Polygon (`polygon`, ERC20): USDT, USDC - Solana (`solana`, SPL): USDT, USDC ## Key facts (Merchant API V2, current) - Base URL: `https://api.cnixpay.com/api/v2`. OpenAPI 3.1: https://api.cnixpay.com/api/v2/openapi.json (public). - Authentication: `Authorization: Bearer ` (live keys only; test keys return 401). The API secret is only used to verify webhook signatures. - Endpoints: `POST /orders` (create), `GET /orders/{orderNo}`, `GET /orders` (list newest first with `page`; batch lookup by up to 100 `merchantOrderNo` values, the recommended webhook fallback), `POST /orders/{orderNo}/payment-options`, `POST /orders/{orderNo}/close`. - Response body: `{ code, message, data, requestId }`; `code = 0` is success. HTTP status follows the error type (error code / 100, e.g. 40001 → 400, 40901 → 409). Rate limits per app, 429 with `Retry-After`. - Currency: `USD` (paid in USDT/USDC at 1:1) or a native coin (TRX, BNB, ETH, POL, SOL). No fiat quotes in V2. - Amounts are decimal strings in requests and responses (JSON numbers are rejected). USD has 2 decimals, booked in cents. - Order statuses: `pending` (wait), `paid` (fulfil; never changes again), `underpaid` (grace period ended with part paid), `closed` (nothing received; `closeReason` timeout or merchant). `underpaid` and `closed` are final except after a manual credit by the platform, which may turn them into `paid` (or `closed` into `underpaid`) and sends the matching event. Each order has a `version` that increases on every visible change. - Webhook events: `order.partially_paid`, `order.paid`, `order.underpaid`, `order.closed`. Body `{ id, event, createTime, data: }`. Any 2xx counts as delivered (5s timeout, redirects not followed); retried for about 22 hours (15s, 1m, 5m, 10m, 30m, 1h, 2h, 6h, 12h). - Webhook signature: headers `X-Webhook-Id`, `X-Webhook-Timestamp`, `X-Webhook-Signature` = `v2=` + lowercase hex HMAC-SHA256(API secret, timestamp + "." + raw body). Reject timestamps older than 5 minutes; compare in constant time. Webhook source IPs are not fixed; rely on the signature, not an IP allowlist. - Duplicate `merchantOrderNo` returns 409 / 40901 with the existing `data.orderNo`; never retry a timed-out create with a new order number. ## Documentation - [Integration guide, Merchant API V2 (English)](https://cnixpay.com/docs/): authentication, response format, amounts, order object, statuses, create/query/list/add options/close, webhook events, signature verification, error codes, OpenAPI, best practices. - [接入指南,商户接口 V2(简体中文)](https://cnixpay.com/zh/docs/) - [Full V2 documentation as plain text](https://cnixpay.com/llms-full.txt) ## Blog (English) - [Underpaid, paid in parts, or overpaid — what happens to the order](https://cnixpay.com/blog/handling-partial-payments/): The most common "wrong amount" situations in stablecoin payments, and how running totals, the grace period, the underpaid status and webhook events handle each of them. - [Callback verification and idempotency, ready to copy](https://cnixpay.com/blog/callback-verification-and-idempotency/): The webhook endpoint is the easiest thing to forge and to hit twice. The signature algorithm, code in five languages, and handling duplicates, ordering and missed webhooks. - [Hosted checkout or your own? A decision you can make in an afternoon](https://cnixpay.com/blog/hosted-vs-custom-checkout/): The two CNIXPay integration modes differ by one field when creating an order. Who each one suits, what each one requires, and how to move from one to the other without touching your backend. - [Which networks should you enable for USDT / USDC? A practical comparison](https://cnixpay.com/blog/choosing-a-network/): TRON, BSC, Ethereum, Polygon and Solana compared by audience, fee level, address format and integration gotchas — and why the answer is usually "enable several and let the customer choose". ## 博客(简体中文) - [用户少付、分几次付、付多了,订单怎么处理](https://cnixpay.com/zh/blog/handling-partial-payments/): 稳定币收款里最常见的几种“金额不对”场景,以及 CNIXPay 的累计到账、宽限期、underpaid 状态和回调事件分别是怎么兜住它们的。 - [回调验签与幂等:一份可以直接抄的实现](https://cnixpay.com/zh/blog/callback-verification-and-idempotency/): 支付回调是你系统里最容易被伪造、也最容易重复的入口。这篇给出 CNIXPay 回调的签名算法、五种语言的验签代码,以及去重、乱序与兜底查询的完整做法。 - [自建收银台还是用平台收银台?一个下午能做完的决定](https://cnixpay.com/zh/blog/hosted-vs-custom-checkout/): CNIXPay 的两种接入方式差别只在创建订单时传不传 paymentOptions。这篇讲清楚各自适合谁、各自要做什么,以及怎么从一种平滑切到另一种。 - [收 USDT / USDC 该开哪几条网络?五条链的实用对比](https://cnixpay.com/zh/blog/choosing-a-network/): TRON、BSC、Ethereum、Polygon、Solana 各自的用户群、手续费量级、地址格式和接入注意事项,以及为什么答案通常是“多开几条,让用户选”。 ## Pages - [Home (English)](https://cnixpay.com/) - [首页(简体中文)](https://cnixpay.com/zh/) - [Merchant dashboard](https://app.cnixpay.com) ## FAQ (English) - **Which networks and tokens are supported?** USDT and USDC on TRON, BNB Smart Chain, Ethereum, Polygon and Solana (USDT only on TRON). Available combinations are configured by the platform and returned by the API. - **Do I need to manage wallets or private keys?** No. Deposit addresses are derived and monitored by the platform. Once an order completes, funds are credited to your merchant balance and you can withdraw to your own on-chain address any time. - **What if a customer underpays or pays in several transfers?** The order stays pending and keeps adding up, sending order.partially_paid for each transfer; once the total reaches the amount due it becomes paid and order.paid is sent. If it is still short when the grace period after expiry ends, the amount received is credited, the order becomes underpaid and order.underpaid is sent for you to handle. - **How do I reliably know an order is paid?** Rely on status == "paid" in the webhook order, always verify the signature, dedupe by X-Webhook-Id and keep the highest version. You can also get the order before shipping to double-check. - **Which quote currencies are supported?** Orders are quoted in USD and paid in USDT or USDC at 1:1. You can also quote in a native coin (TRX, BNB, ETH, POL, SOL), in which case only that coin is accepted. Fiat quotes such as CNY are not supported. - **Is there a sandbox?** There is no simulated sandbox. We recommend integrating with small real orders on a live network. - **What are the fees?** Fees and the minimum withdrawal amount are shown in the merchant dashboard. The exact fee and net amount are displayed before you confirm each withdrawal. - **How do I get an API key?** Create a merchant account, then create an app in the dashboard and submit it to go live. The app page shows your API key and API secret. Send the key as Authorization: Bearer; the secret is only used to verify webhook signatures — never put it in requests or front-end code. - **When does an order expire, and what if the customer pays late?** 30 minutes by default; set expireMinutes (5–1440) when creating the order, and it is returned as expireTime. A grace period follows expiry during which deposits and top-ups still count; funds arriving after that are handled manually by the platform. - **What if the customer overpays?** Once the total received meets the amount due, the order is paid. The actual amount received is returned as paidAmount, and any overpayment is credited to your merchant balance as well. - **Can I close an order?** Yes. A pending order that has not received any payment can be closed, after which deposits are no longer credited automatically. Orders that received a payment, or have one still confirming on-chain, cannot be closed. - **Can I set a callback URL per order?** Yes. Pass callbackUrl when creating the order to override the app default; both must use https. Any HTTP 2xx from your endpoint counts as delivered. - **What order statuses are there?** Just four: pending — no outcome yet, wait; paid — paid in full, fulfil; underpaid — only part paid when the grace period ended, handle manually; closed — nothing received, the order is closed. - **Can one account run several stores or products?** Yes. A merchant account can have multiple apps, each with its own API key / secret, callback URL and IP allowlist. Orders and statistics are kept separate per app. - **Are refunds supported?** The merchant payment API does not currently include a refund endpoint. If you need to refund, send the funds from your own wallet to the customer address. ## 常见问题(简体中文) - **支持哪些网络和币种?** 目前支持 TRON、BNB Smart Chain、Ethereum、Polygon、Solana 上的 USDT 与 USDC(TRON 为 USDT)。具体可用组合由平台配置,以接口返回为准。 - **我需要自己管理钱包或私钥吗?** 不需要。收款地址由平台 HD 钱包派生并监听,订单完成后款项记入你的商户余额,你可以在后台随时提现到自己的链上地址。 - **用户少付了,或者分几次转账怎么办?** 订单保持 pending 并继续累计,每笔到账都推送 order.partially_paid;累计达到应付即变为 paid 并推送 order.paid。过期后宽限期结束仍未付足,按实收入账,订单变为 underpaid 并推送 order.underpaid,由你人工处理。 - **如何可靠地判断一笔订单已支付?** 以回调事件里订单的 status == "paid" 为准,务必校验签名、按 X-Webhook-Id 去重、按 version 取最新。发货前可调用查询订单接口再确认一次。 - **支持哪些报价币种?** 订单以 USD 报价,用户用 USDT 或 USDC 按 1:1 支付;也可以用 TRX、BNB、ETH、POL、SOL 原生币报价,此时只收该币。暂不支持人民币等法币报价。 - **有测试环境吗?** 平台不提供模拟沙箱,建议用小额订单在真实网络上完成联调。 - **费率和提现手续费是多少?** 费用与最小提现金额以商户后台展示为准,提现前会明确显示本次手续费与到账金额。 - **如何获取 API Key?** 注册商户账号后,在后台创建应用并提交上线,应用详情里会显示 API Key 与 API Secret。API Key 放在请求头 Authorization: Bearer 里;API Secret 只用于验证回调签名,不要放进请求或前端代码。 - **订单多久过期?过期后用户才付款怎么办?** 默认 30 分钟,创建订单时可用 expireMinutes 指定(5–1440 分钟),并以 expireTime 返回。过期后还有一段宽限期,期间到账或补足仍会计入订单;宽限期之后才到的钱由平台人工处理。 - **用户多付了怎么办?** 累计到账达到应付金额,订单即为 paid;实际到账以 paidAmount 返回,多付部分同样计入你的商户余额。 - **可以主动关闭订单吗?** 可以。还没收到付款的 pending 订单可以调用关闭订单接口,关闭后不再自动入账。已收到付款或有链上确认中到账的订单不能关闭。 - **回调地址可以按订单指定吗?** 可以。创建订单时传 callbackUrl 即按订单指定,不传则使用应用的默认回调地址,都必须是 https。你的接口返回任意 HTTP 2xx 即算送达。 - **订单有哪些状态?** 只有 4 个:pending 还没有结果,等待即可;paid 已付足,可以发货;underpaid 宽限期结束只收到部分款,需要人工处理;closed 没收到钱,订单已关闭。 - **一个账号可以接多个店铺或产品吗?** 可以。一个商户账号下可以创建多个应用,每个应用有独立的 API Key / Secret、回调地址与 IP 白名单,订单和统计也按应用区分。 - **支持退款吗?** 商户支付 API 目前不包含退款接口。如需退款,请由你的系统从自有钱包向用户地址转账处理。