Skip to content

Merchant Guide

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

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


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 Algorand — on-chain EURQ/USDQ

Section titled “The exact scheme on Algorand — on-chain EURQ/USDQ”

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

Agents pay this scheme from their own Algorand wallet holding EURQ/USDQ. (EURO and the on-chain tokens are separate rails — a EURO account cannot pay a blockchain address.)

  • A whitelisted Algorand wallet address (whitelist it in the Quantoz wallet app)
  • The 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 * 1_000_000); // EURQ has 6 decimal places
return Response.json({
x402Version: 2,
error: "Payment required",
accepts: [{
scheme: "exact",
network: "algorand:mainnet",
asset: "2768422954", // EURQ ASA (USDQ: 2768603795)
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 });

Submit the X-PAYMENT value 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: "2768422954",
resource: "your-resource-id",
description: "Access to premium resource",
mimeType: "application/json",
maxTimeoutSeconds: 300,
}
})
});
const { success, txHash } = await res.json();
if (success) { /* serve resource */ }

The exact scheme on Ethereum / Polygon — EURQ/USDQ via permit

Section titled “The exact scheme on Ethereum / Polygon — EURQ/USDQ via permit”

EURQ/USDQ on EVM chains implement EIP-2612 permit. The agent signs a gasless permit naming the facilitator as spender; on your verify call the facilitator executes permit + transferFrom to your address and pays the gas.

  • An EVM address to receive tokens (no whitelisting required)
  • The facilitator’s spender address (its hot wallet — the address agents authorize)

Add one entry per chain you want to accept:

const atomicAmount = Math.round(amountEur * 1_000_000); // EURQ/USDQ have 6 decimals
const evmTokens = {
"eip155:1": "0x8dF723295214Ea6f21026eeEb4382d475f146F9f", // EURQ on Ethereum
"eip155:137": "0xd571edb2ef29df10fcd6200fd6d0ed2389983db3", // EURQ on Polygon
};
const accepts = Object.entries(evmTokens).map(([network, asset]) => ({
scheme: "exact",
network,
asset,
maxAmountRequired: String(atomicAmount),
payTo: "0xYOUR_MERCHANT_ADDRESS",
maxTimeoutSeconds: 300,
resource: "your-resource-id",
description: "Access to premium resource",
mimeType: "application/json",
facilitator: "https://x402algo.ai.quantozpay.com",
extra: { symbol: "EURQ", spender: process.env.EVM_FACILITATOR_SPENDER },
}));

extra.spender must match the facilitator’s actual hot-wallet address — agents sign their permit for exactly that spender. Get the current value from the facilitator operator (or its /supported endpoint).

Same shape as the Algorand settle call — POST the X-PAYMENT value and your requirements to https://x402algo.ai.quantozpay.com/settle; the response returns { success, txHash } once the transfer is confirmed on-chain.


Include multiple accepts entries to accept payment from any agent, regardless of their setup — off-chain EURO, on-chain Algorand, and both EVM chains:

return Response.json({
x402Version: 2,
error: "Payment required",
accepts: [
{
// euro scheme — off-chain, instant
scheme: "euro",
network: "quantoz:mainnet",
asset: "EURO",
amount: "0.50",
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 (EURQ)
scheme: "exact",
network: "algorand:mainnet",
asset: "2768422954",
maxAmountRequired: "500000",
payTo: "YOUR_ALGORAND_ADDRESS",
maxTimeoutSeconds: 300,
facilitator: "https://x402algo.ai.quantozpay.com",
},
{
// exact scheme — EURQ on Ethereum
scheme: "exact",
network: "eip155:1",
asset: "0x8dF723295214Ea6f21026eeEb4382d475f146F9f",
maxAmountRequired: "500000",
payTo: "0xYOUR_MERCHANT_ADDRESS",
maxTimeoutSeconds: 300,
facilitator: "https://x402algo.ai.quantozpay.com",
extra: { symbol: "EURQ", spender: "0xFACILITATOR_SPENDER" },
},
{
// exact scheme — EURQ on Polygon
scheme: "exact",
network: "eip155:137",
asset: "0xd571edb2ef29df10fcd6200fd6d0ed2389983db3",
maxAmountRequired: "500000",
payTo: "0xYOUR_MERCHANT_ADDRESS",
maxTimeoutSeconds: 300,
facilitator: "https://x402algo.ai.quantozpay.com",
extra: { symbol: "EURQ", spender: "0xFACILITATOR_SPENDER" },
}
]
}, { status: 402 });

The agent’s withEurPayment() wrapper picks the scheme it can pay and handles the rest. See the SkipperBrief reference merchant for a complete working implementation of all four entries.


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

EURQ and USDQ use 6 decimal places on every network:

EURAtomic units
0.10100000
0.50500000
1.001000000