> For the complete documentation index, see [llms.txt](https://slippay.gitbook.io/slippay-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://slippay.gitbook.io/slippay-docs/integrations/x402.md).

# x402 protocol

* **status:** shipped in v0.2 · live on testnet
* **commit:** see `supabase/functions/api/routes/x402.ts` and `supabase/migrations/20260516170000_x402_resources.sql`
* **author:** Manuel Galmanus
* **date:** 2026-05-16
* **deadline driver:** Stellar Build Award Sprint 2 Hackathon

## what x402 is

Coinbase's HTTP 402-based payment protocol. Servers reply `402 Payment Required` to gate a resource; clients (wallets or AI agents) read the structured payment requirements, sign a stablecoin payment with the issued memo, and retry to unlock the resource.

Live on Stellar via Coinbase + SDF since 2025-05; SDF reports millions of payments processed through the rail (stellar.org/blog/foundation-news/x402-on-stellar).

## why slippay shipped it

Slippay v0.1 already had every load-bearing component x402 needs: memo discipline, Horizon stream listener, asset+address matcher, the orders table. The integration is a **thin route + one migration**, under 200 LOC total, reusing audited primitives (audit-002/003/004 fixes apply unchanged). Selection criterion for the Stellar Rio trip weighs ecosystem alignment — shipping x402 is a low-cost, high-signal demonstration that the Slippay backbone runs both **subscription push** AND **per-call pull** payment patterns on the same code path.

## how it works

```
   merchant (API key)                client (browser/agent)         Stellar (testnet)
       │                                    │                              │
       │ POST /v1/x402-resources            │                              │
       │   { slug, usd_amount, content }    │                              │
       ├───────────────────────────────────►│                              │
       │ ◄── 201 { url: .../v1/x402/<slug> }│                              │
       │                                    │                              │
       │                                    │ GET /v1/x402/<slug>          │
       │                                    ├─────────────────────────────►│
       │ slippay api:                       │                              │
       │   create pending order             │                              │
       │   memo = sha256(random)            │                              │
       │   ◄── 402 + x402 body:             │                              │
       │      { accepts: [{ scheme:exact,   │                              │
       │        asset: USDC:<issuer>,       │                              │
       │        payTo: <merchant_addr>,     │                              │
       │        maxAmountRequired, memo}]}  │                              │
       │                                    │                              │
       │                                    │ stellar tx: payment          │
       │                                    │   asset=USDC                 │
       │                                    │   destination=merchant_addr  │
       │                                    │   memo=<hash from 402>       │
       │                                    │   amount=usd_amount          │
       │                                    ├─────────────────────────────►│
       │ slippay listener:                  │                              │
       │   horizon stream → matcher matches │                              │
       │   memo+asset+addr → marks order paid                              │
       │                                    │                              │
       │                                    │ GET /v1/x402/<slug> (retry)  │
       │                                    ├─────────────────────────────►│
       │ slippay api:                       │                              │
       │   order.status = paid              │                              │
       │   ◄── 200 + content                │                              │
```

## what's in the patch

* **`supabase/migrations/20260516170000_x402_resources.sql`** — new table `x402_resources` (merchant\_id, slug, usd\_amount, content fields) plus two columns on `orders` (`x402_resource_id`, `x402_client_id`) so the listener-side reconciler can stay untouched.
* **`supabase/functions/api/routes/x402.ts`** — three endpoints:
  * `POST /v1/x402-resources` (merchant auth) — register a resource
  * `GET /v1/x402-resources` (merchant auth) — list own resources
  * `GET /v1/x402/:slug` (public) — the x402 endpoint itself
* **`supabase/functions/api/index.ts`** — route mounting
* **rate limit** — public endpoint runs under the global limiter (audit-004 C6) plus a per-IP x402-scoped bucket (30 req burst, refill 0.5/s) so abuse can't drive listener load.

## payer-side example (curl)

```bash
# 1. Merchant registers a $0.10 gated resource
curl -X POST https://api.slippay.cc/api/v1/x402-resources \
  -H "Authorization: Bearer sk_test_..." \
  -H "Content-Type: application/json" \
  -d '{"slug":"weather-rio","usd_amount":"0.10",
       "inline_content":"{\"city\":\"Rio de Janeiro\",\"tempC\":28}",
       "description":"weather report, USDC gated"}'

# 2. Anyone GETs the resource — gets 402 with payment instructions
curl -i https://api.slippay.cc/api/v1/x402/weather-rio
# HTTP/1.1 402 Payment Required
# x-payment-required: true
# x-payment-memo: <32-byte hex>
# x-payment-network: testnet
#
# {"x402Version":1,"accepts":[{
#   "scheme":"exact","network":"stellar-testnet",
#   "asset":"USDC:GBBD47IF...",
#   "payTo":"<merchant_stellar_address>",
#   "maxAmountRequired":"0.10",
#   "payload":{"memo":"<hex>","memoType":"hash",
#              "recipient":"<merchant_stellar_address>",
#              "amount":"0.10","assetCode":"USDC",
#              "assetIssuer":"GBBD47IF...",
#              "horizon":"https://horizon-testnet.stellar.org"}
# }]}

# 3. Client signs Stellar USDC payment with the memo
#    (via Freighter, WalletConnect, stellar-sdk, or any wallet)

# 4. Listener picks it up, marks order paid, retry:
curl -i https://api.slippay.cc/api/v1/x402/weather-rio
# HTTP/1.1 200 OK
# content-type: application/json
# {"city":"Rio de Janeiro","tempC":28}
```

## verification (post-deploy)

* [ ] migration applied: `select count(*) from x402_resources;` returns 0 rows after deploy, no schema error
* [ ] register a test resource as the operator merchant
* [ ] GET returns 402 with parseable JSON + memo header
* [ ] sign a real testnet USDC payment with the memo, wait <10s, retry GET
* [ ] retry GET returns 200 with the inline content
* [ ] same client retry with different memo → 402 (new intent)

## what x402 does NOT replace

Slippay's recurring subscription primitive (`contracts/subscription/`) keeps being the right tool for fixed-period, fixed-amount billing between humans and merchants. x402 is the right tool for one-shot, agent-driven, per-call billing. The two share the listener, the matcher, and the merchant address — they're surfaces over the same settlement backbone.

## falsifiable · 30 days

If x402 ships and zero payments hit it in 30 days, the integration is ceremony, not load-bearing. Threshold: ≥1 successful x402 payment via a real client (human or agent) within 30 days → real demand exists, expand. Zero payments → revisit the prioritization at Sprint 5 with better discovery story.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://slippay.gitbook.io/slippay-docs/integrations/x402.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
