BlitzPayments API
Accept cryptocurrency payments in minutes. Generate a unique receiving address per invoice, let your customer pay on a beautiful hosted page, and get notified the instant funds confirm on-chain via signed webhooks.
Predictable resource URLs, JSON request/response bodies, standard HTTP codes.
BTC, LTC, ETH, BNB, TRX, SOL and stablecoins across TRC20 / ERC20 / BEP20 / SOL.
HMAC-SHA256 signatures so you can trust every event you receive.
Base URL
All API requests are made to the BlitzPayments API server. Every endpoint below is relative to this base.
https://api.blitzpaygate.com
During local development the API server runs on http://localhost:5000.
Quickstart
- 1Get your API key. Sign in to the Merchant Dashboard and copy your key (or rotate a new one).
- 2Create an invoice. Call
POST /api/v1/invoiceswith the coin, network and amount. - 3Redirect to checkout. Send the customer to the hosted payment page using the returned
invoice_id. - 4Handle the webhook. Receive an
invoice.paidevent and fulfil the order.
curl -X POST https://api.blitzpaygate.com/api/v1/invoices \
-H "Authorization: Bearer bp_live_xxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"order_id": "ORDER-5521",
"coin": "USDT",
"network": "TRC20",
"coin_amount": 49.99
}'const res = await fetch("https://api.blitzpaygate.com/api/v1/invoices", {
method: "POST",
headers: {
"Authorization": "Bearer bp_live_xxxxxxxxxxxxxxxx",
"Content-Type": "application/json",
},
body: JSON.stringify({
order_id: "ORDER-5521",
coin: "USDT",
network: "TRC20",
coin_amount: 49.99,
}),
});
const { data } = await res.json();
console.log(data.receiving_address);<?php
$ch = curl_init("https://api.blitzpaygate.com/api/v1/invoices");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer bp_live_xxxxxxxxxxxxxxxx",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode([
"order_id" => "ORDER-5521",
"coin" => "USDT",
"network" => "TRC20",
"coin_amount" => 49.99,
]),
]);
$response = json_decode(curl_exec($ch), true);
echo $response["data"]["receiving_address"];import requests
res = requests.post(
"https://api.blitzpaygate.com/api/v1/invoices",
headers={"Authorization": "Bearer bp_live_xxxxxxxxxxxxxxxx"},
json={
"order_id": "ORDER-5521",
"coin": "USDT",
"network": "TRC20",
"coin_amount": 49.99,
},
)
print(res.json()["data"]["receiving_address"])Authentication
BlitzPayments authenticates requests with a secret API key sent as a Bearer token in the
Authorization header. Keys look like
bp_live_… and are managed from your Merchant Dashboard.
Authorization: Bearer bp_live_xxxxxxxxxxxxxxxx
Requests with a missing or invalid key return 401 Unauthorized. Suspended merchant accounts are also rejected.
Conventions & Errors
Every response is JSON and includes a top-level status field that is either "success" or "error".
{
"status": "success",
"data": { }
}
{
"status": "error",
"message": "Invalid API Key"
}
HTTP status codes
| Code | Meaning |
|---|---|
| 200 | OK — request succeeded. |
| 201 | Created — a new resource (invoice) was created. |
| 400 | Bad Request — missing or invalid parameters. |
| 401 | Unauthorized — missing or invalid API key. |
| 404 | Not Found — the resource does not exist or isn't yours. |
| 500 | Server Error — something went wrong on our side. |
Supported Assets
Use the exact coin and network values below when creating an invoice.
| Asset | coin | network |
|---|---|---|
| Bitcoin | BTC | BTC |
| Litecoin | LTC | LTC |
| Ethereum | ETH | ERC20 |
| BNB Smart Chain | BNB | BEP20 |
| Tron | TRX | TRC20 |
| Solana | SOL | SOL |
| Tether USD | USDT | TRC20 · ERC20 · BEP20 · SOL |
| USD Coin | USDC | TRC20 · ERC20 |
You supply coin_amount yourself using your own exchange rate at invoice time — the API does not fetch prices. The customer must send exactly this amount for the invoice to settle.
Create an Invoice
/api/v1/invoices
Creates a payment request and generates a fresh, single-use receiving address on the chosen network.
Body parameters
| Field | Type | Required | Description |
|---|---|---|---|
| coin | string | required | Asset symbol, e.g. USDT. |
| network | string | required | Network, e.g. TRC20. |
| coin_amount | number | required | Exact crypto amount the customer must send. |
| amount_usd | number | optional | Order value in USD. Automatically calculated from live prices if omitted. |
| order_id | string | optional | Your internal order reference. Echoed back in webhooks. |
| user_uid | string | optional | Your end-user's identifier. |
| activate_modal | boolean | optional | When true, the response adds a checkout object for the embedded modal. See below. |
Response · 201 Created
{
"status": "success",
"data": {
"invoice_id": "48273910",
"order_id": "ORDER-5521",
"coin": "USDT",
"network": "TRC20",
"amount_usd": 49.99,
"coin_amount": 49.99,
"receiving_address": "TJ8x...wxyz",
"expires_at": "2026-06-05T13:00:00.000Z"
}
}
The returned invoice_id is an 8-digit reference (a string, e.g. "48273910") — use it for the hosted checkout URL and to fetch the invoice. Invoices expire 1 hour after creation; persist the id against your order so you can reconcile the webhook later.
Get an Invoice
/api/v1/invoices/{id}
Retrieves the current state of one of your invoices. Poll this to check status, or rely on webhooks (recommended).
Path parameters
| Field | Type | Description |
|---|---|---|
| id | string | The 8-digit invoice_id returned when the invoice was created. |
curl https://api.blitzpaygate.com/api/v1/invoices/48273910 \
-H "Authorization: Bearer bp_live_xxxxxxxxxxxxxxxx"const res = await fetch("https://api.blitzpaygate.com/api/v1/invoices/48273910", {
headers: { "Authorization": "Bearer bp_live_xxxxxxxxxxxxxxxx" },
});
const { data } = await res.json();
console.log(data.status); // "pending" | "paid" | "underpaid" | "expired"Response · 200 OK
{
"status": "success",
"data": {
"id": 124,
"public_id": "48273910",
"merchant_uid": "MERCH_3f9a...",
"user_uid": "user_987654321",
"order_id": "ORDER-5521",
"coin": "USDT",
"network": "TRC20",
"amount_usd": "49.99000000",
"coin_amount": "49.99000000",
"receiving_address": "TJ8x...wxyz",
"status": "paid",
"expires_at": "2026-06-05T13:00:00.000Z",
"created_at": "2026-06-05T12:00:00.000Z"
}
}
Test Webhook
/api/v1/webhooks/test
Triggers a test delivery so you can confirm your endpoint and signature verification are wired up correctly.
curl -X POST https://api.blitzpaygate.com/api/v1/webhooks/test \
-H "Authorization: Bearer bp_live_xxxxxxxxxxxxxxxx"
Health Check
/api/health
A public, unauthenticated endpoint for uptime monitoring.
{ "status": "success", "message": "BlitzPayments API is running" }
Hosted Checkout
The fastest way to collect payment is the BlitzPayments hosted page. After creating an invoice,
redirect the customer using the returned invoice_id. The page renders
the exact amount, a QR code, the receiving address, and a live countdown — and updates automatically
when the payment confirms.
https://your-domain.com/payment.php?id={invoice_id}
Embedded Checkout
Keep customers on your page. Our lightweight JavaScript SDK pops the checkout in a
modal overlay (an iframe over the hosted page) instead of redirecting — and emits
onPaid / onExpired
events as the on-chain status changes live.
checkout object (or just the
invoice_id) to the browser. The SDK never sees your API key.
Step 1 — Create with activate_modal (server-side)
The response now carries a checkout object alongside the usual fields:
{
"status": "success",
"data": {
"invoice_id": "48273910",
"receiving_address": "TJ8x...wxyz",
"hosted_url": "https://your-domain.com/payment.php?id=48273910",
"activate_modal": true,
"checkout": {
"invoiceId": "48273910",
"embed_url": "https://your-domain.com/payment.php?id=48273910&embed=1",
"script_url": "https://your-domain.com/checkout.js"
}
}
}
Step 2 — Open the modal (browser)
Pick whichever fits your stack. Option A writes no JavaScript at all.
Drop in the script once and add a data-blitz-checkout attribute to any button/link. The SDK auto-wires the click, opens the modal, tracks status live, and (optionally) redirects when paid:
<script src="https://your-domain.com/checkout.js"></script>
<!-- invoice_id (48273910) comes from your server's create-invoice call -->
<button data-blitz-checkout="48273910"
data-blitz-success-url="/thank-you">Pay with crypto</button>
Trigger data-* attributes
| Attribute | Description |
|---|---|
| data-blitz-checkout | Required. The 8-digit invoice id to open. |
| data-blitz-success-url | Redirect here once payment confirms (invoice_id is appended as a query param). |
| data-blitz-embed-url | Explicit embed_url from the API response. Overrides the id. |
| data-blitz-base-url | Override the storefront origin (defaults to where checkout.js is served from). |
Need a hook without writing an open() call? The trigger element also fires bubbling DOM events blitz:paid, blitz:expired and blitz:close. Injecting buttons dynamically? Call BlitzCheckout.bind() to wire up new ones.
For full control, pass the checkout object (or an invoiceId) to BlitzCheckout.open():
<script src="https://your-domain.com/checkout.js"></script>
<button id="pay">Pay with crypto</button>
<script>
document.getElementById('pay').onclick = () => {
BlitzCheckout.open({
invoiceId: '48273910', // from your server's create-invoice call
onPaid: (inv) => { window.location = '/thank-you?o=' + inv.order_id; },
onExpired: () => { alert('Invoice expired, please retry.'); },
onClose: (e) => { /* e.settled tells you if it was paid */ },
});
};
</script>
BlitzCheckout.open(options)
| Option | Type | Description |
|---|---|---|
| invoiceId | string | The 8-digit invoice id. Required (unless embed_url is given). |
| embed_url | string | Full embed URL from the API. Overrides invoiceId. |
| onPaid | function | Called with the invoice when payment confirms. |
| onExpired | function | Called when the invoice expires. |
| onClose | function | Called when the modal closes. Receives { reason, settled }. |
The modal can be dismissed with the close button, the backdrop, or Esc, and auto-closes shortly after a paid/expired result. Call BlitzCheckout.close() to dismiss it programmatically.
Invoice Lifecycle
Our blockchain monitor watches each receiving address and advances the invoice's status automatically.
Invoice created, awaiting payment. The default state.
Funds arrived but were less than coin_amount. The customer must top up the difference to the same address.
Full amount confirmed on-chain. Your balance is credited and an invoice.paid webhook fires.
No full payment within the 1-hour window. Create a new invoice to retry.
Webhooks
When an invoice is paid, BlitzPayments sends an HTTP POST to the Webhook URL
configured in your dashboard. Respond with 2xx quickly; do heavy work asynchronously.
Event payload
{
"event": "invoice.paid",
"data": {
"invoice_id": "48273910",
"order_id": "ORDER-5521",
"status": "paid",
"amount_usd": "49.99000000",
"coin": "USDT",
"network": "TRC20",
"tx_hash": "0xabc123..."
},
"timestamp": 1717593600000
}
Verifying signatures
Every request carries an X-BlitzPayments-Signature header: a hex
HMAC-SHA256 of the raw request body keyed with your API key. Recompute it and
compare using a constant-time check before trusting the event.
const crypto = require("crypto");
// IMPORTANT: use the raw body string, exactly as received.
app.post("/webhook", express.raw({ type: "application/json" }), (req, res) => {
const raw = req.body.toString("utf8");
const expected = crypto
.createHmac("sha256", process.env.BLITZ_API_KEY)
.update(raw)
.digest("hex");
const received = req.get("X-BlitzPayments-Signature") || "";
const ok = expected.length === received.length &&
crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received));
if (!ok) return res.status(401).send("bad signature");
const event = JSON.parse(raw);
if (event.event === "invoice.paid") {
// fulfil the order for event.data.order_id
}
res.sendStatus(200);
});<?php
$raw = file_get_contents("php://input");
$expected = hash_hmac("sha256", $raw, getenv("BLITZ_API_KEY"));
$received = $_SERVER["HTTP_X_BLITZPAYMENTS_SIGNATURE"] ?? "";
if (!hash_equals($expected, $received)) {
http_response_code(401);
exit("bad signature");
}
$event = json_decode($raw, true);
if ($event["event"] === "invoice.paid") {
// fulfil the order for $event["data"]["order_id"]
}
http_response_code(200);import hmac, hashlib, os
from flask import Flask, request, abort
app = Flask(__name__)
@app.post("/webhook")
def webhook():
raw = request.get_data() # raw bytes, do not re-serialize
expected = hmac.new(os.environ["BLITZ_API_KEY"].encode(),
raw, hashlib.sha256).hexdigest()
received = request.headers.get("X-BlitzPayments-Signature", "")
if not hmac.compare_digest(expected, received):
abort(401)
event = request.get_json()
if event["event"] == "invoice.paid":
... # fulfil the order
return "", 200Best practices.
- Always verify the signature against the raw body before parsing JSON.
- Make handling idempotent — key on
invoice_idso re-deliveries don't double-fulfil. - Return
2xxfast; queue downstream work. - Treat the webhook as the source of truth, but you can confirm with
GET /invoices/{id}.
Withdrawals & Charges
Paid invoices credit your per-asset balance. You withdraw funds from the Merchant Dashboard (Withdrawals → Request Withdrawal): pick the asset, enter an amount, and provide your destination address for that coin.
Your balance is locked for the requested amount.
A percentage fee is deducted; the rest is your net payout.
An admin processes it: the charge goes to the platform wallet, the net to your address.
Each asset has a minimum withdrawal — requests below it are blocked, and the minimum plus the exact fee are shown live in the request form before you confirm. Your payout address for each coin is remembered for next time. If a request is rejected, the locked balance is refunded in full. A programmatic withdrawals API is on the roadmap.
Error Reference
Common errors and how to resolve them.
| HTTP | Message | Fix |
|---|---|---|
| 400 | Missing required parameters: coin, network, amount_usd, coin_amount | Include all four required fields in the JSON body. |
| 401 | Missing or invalid Authorization header | Send Authorization: Bearer <key>. |
| 401 | Invalid API Key | Check the key; ensure your account is active. |
| 404 | Invoice not found | The id is wrong or belongs to another merchant. |
| 500 | Failed to create invoice | Retry; if it persists, the coin/network may be unsupported. |