Продавцы
Назначьте цену HTTP-маршруту в GNK или USDC. Вы отдаёте 402, клиент платит, вы проводите платёж через этот фасилитатор, затем отдаёте работу. Ноду Gonka запускать не нужно.
Цикл сервера
- Если
PAYMENT-SIGNATUREнет или это не валидный base64 JSON, ответьте 402 сPAYMENT-REQUIRED(заголовок и тело). POSTна/settleсpaymentPayload(то, что прислал клиент) иpaymentRequirements(то, что вы объявили).- Если
successложно, снова ответьте 402 и положите причину вerror. - Если
successистинно, сделайте работу и верните 200 сPAYMENT-RESPONSE— base64 результата settle.
В Gonka поток оплаты авансовый. Не отдавайте ресурс после одной только проверки verify. /verify необязателен и только читает. Средства двигает /settle.
Объявить цену
Тело 402 — объект x402 v2 PaymentRequired. Минимально полезная запись accepts:
{
"scheme": "exact",
"network": "cosmos:gonka-mainnet",
"amount": "1000000",
"asset": "ngonka",
"payTo": "gonka1yourmerchantaddress…",
"maxTimeoutSeconds": 60,
"extra": {
"name": "GNK",
"decimals": 9,
"assetTransferMethod": "signed-tx",
"paymentFlow": "upfront"
}
}Добавьте второй объект для USDC: asset — адрес CW-20, decimals — 6, name — USDC. Весь объект PaymentRequired закодируйте стандартным base64 для заголовка. Список полей — в Протоколе.
Settle до выдачи
curl -sS -X POST {{BASE}}/settle \
-H 'Content-Type: application/json' \
-d '{
"x402Version": 2,
"paymentPayload": { "...from PAYMENT-SIGNATURE..." },
"paymentRequirements": { "...your accepts entry..." }
}'При успехе вы получите transaction (hex-хеш), payer, network и amount. При необходимости запишите это в свой леджер; перевод в сети уже ушёл на payTo.
Фасилитатор отклоняет повторный TxRaw (replayed_payment). В приложении всё равно проверяйте это, если реплик несколько и клиент ретраит.
Набросок middleware
async function requirePayment(req, res, next) {
const header = req.get("PAYMENT-SIGNATURE");
const required = paymentRequiredFor(req);
if (!header) return send402(res, required);
const paymentPayload = JSON.parse(Buffer.from(header, "base64").toString());
const settled = await fetch(FACILITATOR + "/settle", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
x402Version: 2,
paymentPayload,
paymentRequirements: paymentPayload.accepted,
}),
}).then((r) => r.json());
res.set("PAYMENT-RESPONSE", Buffer.from(JSON.stringify(settled)).toString("base64"));
if (!settled.success) return send402(res, { ...required, error: settled.errorReason });
next();
}Цены
| GNK | 1 GNK = 1000000000 ngonka. Пример: 0.001 GNK → amount: "1000000". |
|---|---|
| USDC | 1 USDC = 1000000. Пример: $0.01 → amount: "10000". |
| Кто получает | Ваш адрес payTo. Фасилитатор не сводит и не держит платёж. |
Демо-маршрут на этом хосте использует крошечные суммы для тестов. Продакшен-суммы — ваши.
Discovery
Необязательно: публикуйте платные URL, чтобы агенты их находили. Этот фасилитатор отдаёт GET /discovery/resources для своего /demo. Живой каталог ниже и на странице Список ресурсов. Можно вести похожий список на своём API или позже зарегистрироваться в x402 Bazaar. Форма — в HTTP API.