Skip to content

Merchant Guide

This guide shows how to put any HTTP endpoint behind a small EURD payment gate. Two settlement paths are available — include one or both accepts entries in your 402 response.

Start with the euro scheme — it’s the simplest. Add the exact scheme if you want on-chain settlement.


Both you and the payer need a Quantoz managed account. Settlement is instant and off-chain.

  • A Quantoz account with a managed account (your receiving account)
  • A Quantoz API key

When a request arrives without an X-PAYMENT header, call the Quantoz facilitator to create a payment request and return it as a 402.

POST https://mcp.ai.quantozpay.com/x402/pay
X-API-KEY: <your-quantoz-api-key>
Content-Type: application/json
{
"accountCode": "ACC_your_account",
"amount": 0.10,
"message": "Access to premium resource"
}

Response:

{
"paymentRequestCode": "pr_abc123",
"accepts": [
{
"scheme": "euro",
"network": "quantoz:mainnet",
"asset": "EURO",
"amount": "0.10",
"payTo": "ACC_your_account",
"paymentRequestCode": "pr_abc123",
"expiresAt": 1234567890,
"facilitator": "https://mcp.ai.quantozpay.com/x402"
}
]
}

Return as your 402:

{
"x402Version": 2,
"error": "Payment required",
"accepts": [...]
}

When the client retries with an X-PAYMENT header:

POST https://mcp.ai.quantozpay.com/x402/verify
X-API-KEY: <your-quantoz-api-key>
Content-Type: application/json
{ "proof": "<value of X-PAYMENT header>" }
{ "valid": true, "paymentRequestCode": "pr_abc123", "amount": 0.10 }

Replay protection is handled automatically — each payment request code can only be verified once.

app.get("/premium-resource", async (req, res) => {
const xPayment = req.headers["x-payment"];
if (!xPayment) {
const r = await fetch("https://mcp.ai.quantozpay.com/x402/pay", {
method: "POST",
headers: { "X-API-KEY": process.env.QUANTOZ_API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ accountCode: process.env.QUANTOZ_ACCOUNT, amount: 0.10, message: "Premium resource" }),
});
const { accepts } = await r.json();
return res.status(402).json({ x402Version: 2, error: "Payment required", accepts });
}
const r = await fetch("https://mcp.ai.quantozpay.com/x402/verify", {
method: "POST",
headers: { "X-API-KEY": process.env.QUANTOZ_API_KEY, "Content-Type": "application/json" },
body: JSON.stringify({ proof: xPayment }),
});
const result = await r.json();
if (!result.valid) return res.status(402).json({ error: result.reason });
res.json({ data: "Your premium content here" });
});

The exact scheme — on-chain EURD via Algorand

Section titled “The exact scheme — on-chain EURD via Algorand”

Your receiving address must be a KYC-whitelisted Algorand address. Settlement is on-chain.

Agents can pay this scheme either directly (with an Algorand wallet) or via the EURO→Algorand bridge — your merchant side is identical either way.

  • A whitelisted Algorand wallet address (contact Quantoz to get whitelisted)
  • Access to the Algorand x402 facilitator at https://x402algo.ai.quantozpay.com

No API call needed to create a payment request — the payment requirements are self-contained.

const atomicAmount = Math.round(amountEur * 100); // EURD has 2 decimal places
return Response.json({
x402Version: 2,
error: "Payment required",
accepts: [{
scheme: "exact",
network: "algorand:mainnet",
asset: "1221682136",
maxAmountRequired: String(atomicAmount),
payTo: "YOUR_ALGORAND_ADDRESS",
maxTimeoutSeconds: 300,
resource: "your-resource-id",
description: "Access to premium resource",
mimeType: "application/json",
facilitator: "https://x402algo.ai.quantozpay.com",
}]
}, { status: 402 });

Decode the X-PAYMENT header and branch on proof type:

Direct on-chain payment (payload.transaction present) — submit to the facilitator:

const res = await fetch("https://x402algo.ai.quantozpay.com/settle", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
x402Version: 2,
paymentPayload: xPayment,
paymentRequirements: {
scheme: "exact",
network: "algorand:mainnet",
maxAmountRequired: String(atomicAmount),
payTo: "YOUR_ALGORAND_ADDRESS",
asset: "1221682136",
resource: "your-resource-id",
description: "Access to premium resource",
mimeType: "application/json",
maxTimeoutSeconds: 300,
}
})
});
const { success, txHash } = await res.json();
if (success) { /* serve resource */ }

Bridge payment (payload.transactionCode present) — verify the Algorand transaction by ID:

const proof = JSON.parse(Buffer.from(xPayment, "base64url").toString("utf8"));
const { blockchainTxId, payTo, asset } = proof.payload;
const tx = await fetch(
`https://mainnet-idx.algonode.cloud/v2/transactions/${blockchainTxId}`
).then(r => r.json());
const axfer = tx.transaction?.["asset-transfer-transaction"];
if (
String(axfer?.["asset-id"]) === asset &&
axfer?.receiver === payTo &&
axfer?.amount >= atomicAmount
) {
// verified — serve resource
}

Include both accepts entries to accept payment from any agent, regardless of their setup:

return Response.json({
x402Version: 2,
error: "Payment required",
accepts: [
{
// euro scheme — off-chain, instant
scheme: "euro",
network: "quantoz:mainnet",
asset: "EURO",
amount: "0.10",
payTo: "ACC_your_account",
paymentRequestCode: pr.code,
expiresAt: Math.floor(Date.now() / 1000) + 300,
facilitator: "https://mcp.ai.quantozpay.com/x402",
},
{
// exact scheme — on-chain Algorand
scheme: "exact",
network: "algorand:mainnet",
asset: "1221682136",
maxAmountRequired: "10",
payTo: "YOUR_ALGORAND_ADDRESS",
maxTimeoutSeconds: 300,
resource: "your-resource-id",
description: "Access to premium resource",
mimeType: "application/json",
facilitator: "https://x402algo.ai.quantozpay.com",
}
]
}, { status: 402 });

The agent’s withEurPayment() wrapper picks the scheme it can pay and handles the rest.


You set the price. There is no minimum amount.

AmountTypical use case
€0.001High-frequency API calls
€0.01Standard content or API access
€0.10Premium data, reports
€1.00High-value one-off resources

EURAtomic units
0.1010
0.5050
1.00100