x402 Progressive Demo · Chapter 3 of 7

Minimal Paywall

What if content is locked behind a payment?
Published 2026-04-16 · Northwoods Software · x402 Payment Protocol

From Transfer to Protocol

Chapters 1 and 2 demonstrated USDC transfers on Solana — a buyer sends stablecoins to a seller's wallet. The transfer worked, the recipient was flexible, and the on-chain verification was solid. But those chapters were fundamentally about moving money. They didn't answer the harder question: what happens after the money moves?

This is where x402 becomes a protocol, not just a transfer mechanism. The "402" in x402 refers to HTTP status code 402 — "Payment Required" — a response code that has been reserved in the HTTP specification since 1997 but was never given a standard implementation. Until now.

Chapter 3 builds the simplest possible paywall: a server that locks content behind a payment, accepts USDC as the key, and remembers that you paid.

The HTTP 402 Flow

The paywall introduces one endpoint that behaves differently depending on what the buyer sends. The buyer's browser calls it up to three times. The USDC transfer itself is identical to Chapters 1 and 2 — the new part is the HTTP layer that wraps around it.

Buyer's Browser Server ────────────── ────── │ │ 1. │ GET /content/article-42 │ │──────────────────────────────▶│ │ │ │ 402 Payment Required │ │ PAYMENT-REQUIRED: │ │ (decodes to: scheme, amount, │ │ asset, payTo, network) │ │◀──────────────────────────────│ │ │ 2. │ (buyer signs USDC transfer │ │ on Solana — same as Ch 1-2) │ │ │ 3. │ GET /content/article-42 │ │ PAYMENT-SIGNATURE: │ │──────────────────────────────▶│ │ │ │ (server checks the transfer │ │ itself, then asks the │ │ facilitator to verify and │ │ settle it) │ │ │ │ 200 OK + Set-Cookie: │ │ x402_access= │ │ PAYMENT-RESPONSE: │ │◀──────────────────────────────│ │ │ 4. │ GET /content/article-42 │ │ Cookie: x402_access=... │ │──────────────────────────────▶│ │ │ │ 200 OK │ │ (full article content) │ │◀──────────────────────────────│ │ │

One Endpoint, Three States

RequestPurposeResponse
GET /content/:id — no cookie, no signature First visit. No valid access cookie, so the server quotes a price instead of serving content. 402 + PAYMENT-REQUIRED
GET /content/:id — PAYMENT-SIGNATURE header Buyer retries with a signed payment. Server checks the transaction, then has the facilitator verify and settle it on-chain. 200 + PAYMENT-RESPONSE + Set-Cookie (settled) or 402 (invalid)
GET /content/:id — access cookie Return visit. Cookie is present and valid. Server serves the full content without requiring payment. 200 (content)
Key insight: The USDC transfer is identical to Chapters 1 and 2. The new part is the HTTP layer: request → 402 → pay → retry with the signature → cookie → unlock. The payment mechanics didn't change. The access control is new.

The Access Cookie

After the server verifies the on-chain payment, it sets a signed cookie — x402_access — with a 24-hour expiration. On subsequent visits, the browser sends this cookie automatically. The server validates the signature, checks the expiration, and serves the content without re-checking the blockchain.

This means:

Why This Replaces Subscription Paywalls

Traditional paywalls force a binary choice on readers: subscribe for $10/month (and get access to everything, whether you read 1 article or 100) or get nothing. This creates two problems:

ProblemSubscription Modelx402 Micropayment Model
Casual reader Bounces — $10/month for one article is absurd Pays $0.25, reads the article, moves on
Heavy reader Great deal at $10/month for 100 articles Pays $25/month — more expensive, but fair
Publisher revenue from casual readers $0 — they never subscribed $0.25 per article — actual revenue from every reader

The x402 paywall captures the 95% of readers who would never subscribe but would happily pay a quarter to read one article. That's the addressable market that subscription paywalls leave on the table.

Server-Side Verification

When the server receives a signed payment, it doesn't trust the buyer's claim. It checks the transaction itself, then has the facilitator verify and settle it against the Solana blockchain, confirming three things:

  1. Amount: Did the transaction transfer at least the required amount of USDC?
  2. Recipient: Did the funds go to the correct wallet address (the publisher's wallet)?
  3. Token: Was the transfer in USDC (the canonical SPL token mint), not some random token?

If all three checks pass, the payment is confirmed. The server doesn't need to trust the buyer, the wallet, or any intermediary. The blockchain is the receipt.

Zero trust, full verification. The server never sees the buyer's private key. The buyer never sends funds to a custodial account. The blockchain is the only arbiter. This is the security model that makes x402 fundamentally different from traditional payment gateways.

What Changed from Chapter 2

LayerChapter 2Chapter 3
Payment (USDC transfer)Buyer selects recipient, signs txIdentical
VerificationClient-side confirmationServer-side on-chain check
Access controlNone — open pageHTTP 402 + cookie-based unlock
Return visitsNot applicableCookie valid for 24 hours
Note: Chapters 2 and beyond require running the x402 gateway locally to try the demos. See the project's README for setup instructions, including Solana devnet configuration and wallet requirements.

What's Next

Chapters 1 through 3 all run on Solana. But real buyers hold USDC on different networks — Base, Polygon, Arbitrum, Ethereum. A publisher can't ask every reader to bridge their funds to Solana first. The payment protocol needs to work across chains.

In Chapter 4: Multi-Chain, we extract the payment logic into a reusable framework with chain adapters — one adapter per network, one unified verification algorithm. Adding a new blockchain becomes a configuration change, not a rewrite.