Accept crypto without touching a blockchain
MeshPaid is a custodial crypto payment gateway. You create a charge, your customer pays, and MeshPaid detects the payment on-chain, settles it to dollar-pegged stablecoins, and notifies your backend by webhook. Your balance is held in USDT/USDC — digital dollars pegged 1:1 to USD — and you can withdraw anytime.
Base URL: https://api.meshpaid.com. All amounts are decimal strings in USD.
Authentication
Server-to-server calls use a secret API key. Create one in the dashboard (Developers, API keys), store it in your backend, and send it as a bearer token. The key is shown once.
Authorization: Bearer sk_live_<prefix>.<secret> The key is scoped to charges only. It never touches your balance, withdrawals or account settings. Keep it secret; never ship it to the browser.
Create a charge
From your backend, create a charge for an amount in USD.
POST /v1/invoices
Authorization: Bearer sk_live_xxx
Content-Type: application/json
{
"value_amount": "50.00",
"reference": "order_1234"
} Response:
{
"id": "019f...",
"status": "pending",
"value_amount": "50.000000000000000000",
"reference": "order_1234",
"expires_at": "2026-08-07T12:00:00+00:00",
"hosted_url": "https://pay.meshpaid.com/i/019f..."
}
Store the id. Send the customer to hosted_url, or build your own
checkout with the public endpoints below. Read the status anytime with
GET /v1/invoices/{id}.
Checkout
Three ways to collect the payment, from least to most custom.
Hosted checkout
Redirect the customer to the hosted_url from the charge. MeshPaid handles the asset choice, address, QR and status.
Embedded widget (inline, no redirect)
Render the checkout inside your page, ideal for apps that block new tabs:
<script type="module" src="https://pay.meshpaid.com/embed/meshpaid-checkout.js"></script>
<meshpaid-checkout invoice-id="019f..." base-url="https://api.meshpaid.com"></meshpaid-checkout> It emits events so your app reacts inline: meshpaid:ready, meshpaid:status, meshpaid:paid, meshpaid:error.
Your own UI (headless)
Build the checkout in your components using the public endpoints (CORS is open):
GET /v1/public/invoices/{id} // assets, address, progress
POST /v1/public/invoices/{id}/quote // { chain, asset } -> address + exact amount
XRP Ledger quirk: all XRP charges share one custodial account, so each invoice is
attributed by a numeric destination_tag instead of a unique address (like
a bank reference number). The quote response carries destination_tag
and a packed x_address (address + tag) for every chain, both null
except on xrpl. If you build your own UI, you must display the tag to the
buyer or the payment cannot be attributed. The hosted checkout and embedded widget above
already handle this for you.
Webhooks
The authoritative signal. MeshPaid POSTs a signed event to your endpoint on every status change. Register your endpoint in the dashboard (Developers, Webhooks) and get a signing secret.
Events: invoice.paid, invoice.overpaid, invoice.partially_paid, invoice.expired.
Headers:
X-MeshPaid-Signature: sha256=<hex>
X-MeshPaid-Timestamp: 1785968626
X-MeshPaid-Event-Id: 019f... // unique per delivery, use for idempotency
X-MeshPaid-Event-Type: invoice.paid Verify the signature before trusting the body (HMAC-SHA256 over "timestamp.raw_body"):
$raw = $request->getContent();
$expected = 'sha256=' . hash_hmac('sha256',
$request->header('X-MeshPaid-Timestamp') . '.' . $raw,
$yourWebhookSecret);
abort_unless(hash_equals($expected, $request->header('X-MeshPaid-Signature')), 401);
Delivery retries with backoff, so dedupe on X-MeshPaid-Event-Id. Return HTTP 2xx
only after you durably accepted the event. Confirmations are handled by MeshPaid; when
invoice.paid arrives, it is final.
Assets and fees
The customer picks the coin and network; you do not need to know any blockchain.
- Stablecoins (USDT, USDC) credit 1:1 with USD. No spread.
- Volatile native assets (TRX, BNB, ETH, SOL, XRP) use a rate frozen at pay time, so the amount is exact.
- Networks: Tron (TRC-20), BNB Smart Chain (BEP-20), Solana, Ethereum (ERC-20) and XRP Ledger.
- Receiving: 1% per payment. Withdrawals: 1% plus the network cost, passed through at cost.
- Amounts are decimal strings. Never use floats for money.