About x402-payments
x402-payments is a skill for implementing pay-per-use HTTP resources on Hedera using native HBAR transfers. It describes the 402 challenge, signed client retry, and facilitator verification and settlement, while keeping facilitator keys out of the resource server.
Key features
- 01HTTP 402 payment flow
- 02Native HBAR settlement
- 03Facilitator verification and settlement
- 04Tinybar-denominated prices
- 05Client signing and retry pattern
Use cases
- 01Charging for protected HTTP resources
- 02Building a client that handles 402 challenges
- 03Separating payment settlement keys from a resource server
Install
Copy the command and run it in a terminal.
npx skills add https:/ / github.com/ hedera-dev/ hedera-skills --skill x402-paymentsAfter installing, type/x402-paymentsin Claude Code to confirm it loaded.
Bundled filesreferences/examples.mdreferences/facilitator.md
Details
From the project READMEx402 Payments (Hedera)
Pay-per-use pattern: store protected bytes off-chain, record access terms separately (on-chain or config), gate HTTP resources with HTTP 402 + a self-hosted Hedera facilitator that verifies and settles native HBAR transfers.
Buyer → GET protected resource
├─ free / public → resource
└─ paid → 402 PAYMENT-REQUIRED
→ client signs HBAR transfer
→ retry with PAYMENT-SIGNATURE
→ resource server verify + settle via facilitator
→ PAYMENT-RESPONSE + resource
The resource server never holds facilitator keys. Settlement uses a funded ECDSA fee-payer account on the facilitator process.
Quick Reference
| Piece | Role |
|---|---|
| Payment asset | "0.0.0" — native HBAR; amounts in tinybars (1 HBAR = 1e8) |
| Resource server | @x402/core + ExactHederaScheme → talks to facilitator over HTTP |
| Facilitator | GET /supported, POST /verify, POST /settle, GET /health |
| Client | Request → read 402 → sign → retry with PAYMENT-SIGNATURE (legacy X-PAYMENT also accepted) |
| Wallet | ECDSA Hedera account (e.g. HashPack via WalletConnect / UniversalProvider) |
See references/examples.md for server/client snippets. See references/facilitator.md for env vars and settle semantics.
Critical: Facilitator Fee Payer
Hedera x402 settles with native TransferTransactions. The buyer partially signs (authorize buyer → seller). The facilitator must:
- Verify the signed payload against payment requirements
- Co-sign as the advertised fee payer (
/supported) - Pay network fees and submit until
SUCCESS
Requires FACILITATOR_ACCOUNT_ID + FACILITATOR_PRIVATE_KEY on a funded ECDSA account — separate from deployer/seller keys. Do not put that key in the resource-server process.
Critical: Prices Are Tinybars
Payment requirements use tinybars. Convert in UIs with 8-decimal helpers; never float.
const TINYBAR_PER_HBAR = 100_000_000n;
// hbar "1.5" → 150_000_000n tinybars
Resource Server Flow (paid resource)
- Load access terms for the resource — if missing → 404
- If free/public → return the resource
- Else build payment requirements:
payTo= seller Hedera account id,amountin tinybars, asset0.0.0, network (e.g.hedera:testnet) - No payment header → 402 with
PAYMENT-REQUIREDheader + JSON body - With payment header →
verifyPaymentthensettlePayment; only on success return resource +PAYMENT-RESPONSE
const facilitator = new HTTPFacilitatorClient({ url: FACILITATOR_URL });
const server = new x402ResourceServer(facilitator)
.register(X402_NETWORK, new ExactHederaScheme());
await server.initialize(); // pulls fee-payer from /supported
Client Flow
const first = await fetch(resourceUrl);
if (first.status === 402) {
const paymentRequired = httpClient.getPaymentRequiredResponse(...);
const payload = await httpClient.createPaymentPayload(paymentRequired);
const headers = httpClient.encodePaymentSignatureHeader(payload);
const paid = await fetch(resourceUrl, { headers });
// processResponse → resource + settle receipt
}
Machine-to-machine clients use a key-based signer instead of a browser wallet.
Checklist
- Resource server has no facilitator private key
- Client and server share the same
X402_NETWORK(e.g.hedera:testnet) - Amounts are tinybars; asset id is
0.0.0 - 402 challenge → signed retry → verify → settle → resource only after success
- Fee-payer account is ECDSA and funded for network fees
- Facilitator
/healthOK before testing paid requests -
payTois a Hedera account id string (e.g.0.0.1234), not an EVM address
References
- references/examples.md — resource server wiring, client retry loop, tinybar helpers
- references/facilitator.md — endpoints, env vars, fee-payer role
- x402 docs
@x402/hedera