Webhook Verification
Webhooks allow NoxPay to push real-time transaction updates directly to your server. Verify that the webhook was genuinely triggered by NoxPay using HMAC-SHA256 Signatures.
The Signature Header​
NoxPay attaches X-NoxPay-Signature to every webhook request.
The Hashing Mechanism​
- NoxPay retrieves your Webhook Secret.
- It computes an HMAC-SHA256 hash from the raw JSON payload body.
- It hex-encodes the hash and attaches it to the request header.
Implementation Guides​
Node.js / Express​
const crypto = require('crypto');
const express = require('express');
const app = express();
const WEBHOOK_SECRET = process.env.NOXPAY_WEBHOOK_SECRET;
app.post('/noxpay-webhook',
express.raw({ type: 'application/json' }),
(req, res) => {
const payload = req.body;
const sig = req.headers['x-noxpay-signature'];
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(payload)
.digest('hex');
try {
const isValid = crypto.timingSafeEqual(
Buffer.from(sig), Buffer.from(expected)
);
if (!isValid) return res.status(401).send('Invalid Signature');
} catch (e) {
return res.status(401).send('Malformed Signature');
}
const event = JSON.parse(payload.toString());
res.status(200).send('OK');
}
);
Python / FastAPI​
import hmac
import hashlib
from fastapi import FastAPI, Request, HTTPException, Header
app = FastAPI()
WEBHOOK_SECRET = "whsec_..."
@app.post("/noxpay-webhook")
async def handle_webhook(
request: Request,
x_noxpay_signature: str = Header(...)
):
raw_payload = await request.body()
expected = hmac.new(
WEBHOOK_SECRET.encode('utf-8'),
raw_payload,
hashlib.sha256
).hexdigest()
if not hmac.compare_digest(expected, x_noxpay_signature):
raise HTTPException(status_code=401, detail="Invalid Signature")
event = await request.json()
return {"status": "success"}
The Payload Structure​
All payment.success webhooks follow this schema:
{
"event_type": "payment.success",
"intent_id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
"amount": 99.50,
"currency": "USDT_TRC20",
"order_id": "INV_298418_XYZ",
"transaction_hash": "25a589255a298bf6...",
"verified_at": "2023-11-20T14:35:12.000Z"
}
important
NoxPay requires your endpoint to return a 200-series HTTP status within 10 seconds. Failed deliveries are retried up to 5 times over 48 hours.