OverviewAuthentication & environmentsStaging faucetCore conceptsReceive paymentsAuto-detect paymentsConfirm settlementWithdraw fundsContract interactionsReconcile balancesBusiness identitySettings & complianceCustomers & invoicesWithdrawals & treasuryContracts & automationReference data & billingWebhooks & eventsUse-case playbooksErrors & edge casesGo-live guideChangelog
Workflow guide
Confirm settlement
Settlement should be webhook-first. Read APIs are your reconciliation fallback, not the primary source of realtime truth.
Recommended confirmation model
- Receive a webhook and verify its signature against the raw body.
- Apply the event to your order state only after validating the event type and resource ID.
- If the webhook is delayed or disputed, read the invoice detail as fallback.
- Use `paidAmount`, `settledByTolerance`, `toleranceRaw`, and `shortfallRaw` to record the real settled amount.
Webhook envelope example
json{
"id": "evt_2b3f1fa0",
"event": "invoice.paid",
"timestamp": "2026-03-14T13:46:04.903Z",
"data": {
"invoiceId": "inv_123",
"businessId": "biz_123",
"status": "paid",
"amount": {
"raw": "150000000",
"decimals": 6,
"display": "150",
"symbol": "USDC",
"chain": "eth",
"networkId": "base-mainnet"
},
"paidAmount": {
"raw": "149750000",
"decimals": 6,
"display": "149.75",
"symbol": "USDC",
"chain": "eth",
"networkId": "base-mainnet"
},
"settledByTolerance": true,
"toleranceRaw": "500000",
"shortfallRaw": "250000",
"txHash": "0x9ee6..."
}
}Node.js signature verification
tsimport crypto from 'node:crypto';
export function verifyPayChainHQWebhook(rawBody, signatureHex, webhookSecret) {
const expected = crypto.createHmac('sha256', webhookSecret).update(rawBody).digest('hex');
return crypto.timingSafeEqual(Buffer.from(signatureHex, 'hex'), Buffer.from(expected, 'hex'));
}Settlement cases you must support
| Case | What PayChainHQ does | What you should do |
|---|---|---|
| Exact payment | Invoice becomes `paid` after confirmations. | Fulfill normally. |
| Underpayment within tolerance | Invoice becomes `paid` with `settledByTolerance=true`. | Fulfill, but store the true `paidAmount` and shortfall metadata. |
| Underpayment above tolerance | Invoice stays `partially_paid` until top-up or expiry. | Do not fulfill automatically. |
| Overpayment | Invoice becomes `overpaid` and keeps the actual paid amount. | Fulfill and decide your refund or credit policy. |
| Unsupported asset / internal transfer | Invoice does not settle from the wrong asset class. | Do not infer settlement from raw address activity alone. |