x402 on Express (Node)
A minimal 402 challenge for priced routes in Express. Replace the paid check with your receipt verification logic.
Minimal implementation
import express from "express";
const app = express();
app.get("/priced", (req, res) => {
// TODO: verify client receipt here
const paid = false;
if (!paid) {
return res.status(402).json({
detail: "Payment required to access /priced",
payment: {
protocol: "x402",
amount: "1.00",
currency: "USDC",
reference: "order-123"
}
});
}
res.json({ ok: true, data: "secret" });
});
app.listen(3000, () => {
console.log("Server running on port 3000");
});Design note
Keep the 402 response small. Include only what the client needs to pay and retry: amount, currency, and a stable reference your server can match later.
Adding receipt verification
When a client pays, they obtain a receipt and attach it to the retry request. Your server verifies the receipt and grants access:
app.get("/priced", (req, res) => {
const receipt = req.headers["x-receipt"];
if (!receipt) {
return res.status(402).json({
detail: "Payment required to access /priced",
payment: {
protocol: "x402",
amount: "1.00",
currency: "USDC",
reference: "order-123"
}
});
}
// Verify receipt cryptographically or via gateway
const verified = verifyReceipt(receipt);
if (!verified) {
return res.status(403).json({
error: "Invalid or expired receipt"
});
}
res.json({ ok: true, data: "secret" });
});Receipt verification tips
- Check the cryptographic signature or gateway proof
- Match the
referenceto your ledger - Verify the receipt hasn’t expired
- Return
403 Forbiddenfor invalid receipts (not402)
Next steps
Integrate with your payment rail and issue verifiable receipts. See the x402 pillar guide for receipt patterns and comparisons.
Developer Tools