Prototype on testnet (Base Sepolia, Stripe test mode) · Pre-sale Pro ships no later than 3 weeks after payment, otherwise full refund (terms, in German).
Express middleware · Open source
One endpoint. People pay in euros, agents pay in USDC.
Your API accepts Stripe Checkout and x402 payments at the same time. Euros go to your Stripe account, USDC to your wallet; Meterdoor never holds any money.
- Core under Apache 2.0
- Demo without accounts and without real payments
- Meterdoor never holds money
import express from "express"; import { paywall } from "meterdoor"; const app = express(); app.set("trust proxy", 1); app.get("/api/report", paywall({ price: { eur: "0.50", usdc: "0.01" }, stripe: { key: process.env.STRIPE_KEY }, x402: { payTo: process.env.WALLET, network: "base-sepolia" }, access: { secret: process.env.ACCESS_SECRET, ttlSeconds: 3600 }, }), (req, res) => res.json({ report: "…" }) ); app.listen(process.env.PORT || 3000);
# 1. Browser requests the route without payment GET /api/report Accept: text/html HTTP/1.1 303 See Other Location: https://checkout.stripe.com/c/pay/cs_test_… # 2. Back from Stripe after payment GET /api/report?pw_session=cs_test_… # Session verified: token with a fixed expiry # (payment time + ttlSeconds, here 3600 s) HTTP/1.1 303 See Other Set-Cookie: pw_token=v2.…; HttpOnly; SameSite=Lax Location: /api/report # 3. Unlimited requests until expiry GET /api/report Cookie: pw_token=v2.… HTTP/1.1 200 OK { "report": "…" }
# 1. Agent requests without payment GET /api/report Accept: application/json HTTP/1.1 402 Payment Required { "x402Version": 1, "accepts": [{ "scheme": "exact", "network": "base-sepolia", "maxAmountRequired": "10000", "payTo": "0x…" }], "checkout": "…/api/report?pw_checkout=1" } # 2. Agent pays 0.01 USDC and retries GET /api/report X-PAYMENT: eyJ4NDAy… # verify → your route → settle HTTP/1.1 200 OK X-PAYMENT-RESPONSE: eyJzdWNj… { "report": "…" } # New request: new payment. Same proof again: # stored response, no second charge.
Prototype for the Base Sepolia testnet and Stripe test mode. There is no npm package yet: install from the repository, see Quickstart.
Try it locally, no keys needed
The demo shows both payment paths on your own machine, before you buy anything or create an account.
Simulation: Stripe, the x402 facilitator and the blockchain are simulated in the same process. You need no accounts and no keys, no money moves, and nothing leaves your machine. There is no public online demo.
Requirements
- Node.js 20 or newer, with npm
- Git
- a browser
Steps
The working directory is the meterdoor folder created by git clone. There, npm run demo starts a server on 127.0.0.1 only; open http://127.0.0.1:8402/. The demo stops after 10 minutes or with Ctrl+C. The demo interface is in German.
You will see five cases: payment required, euros through a simulated checkout, USDC through a simulated agent, replaying the same payment proof without a second charge, and an unclear settlement that is resolved via the (simulated) chain. If environment variables that look like real credentials are set, the demo refuses to start.
git clone https://github.com/WestLabsAI/meterdoor cd meterdoor npm install npm run demo # then open in your browser: # http://127.0.0.1:8402/
How it works
One paywall() call in front of every route that should cost money. Two payment paths behind it.
Configure the middleware
Price in euros and/or USDC, Stripe key, your receiving address, network, and a secret for access tokens. No database required; to survive restarts with replay protection intact, choose the file store.
Request without payment
A browser is redirected to Stripe Checkout. An AI agent gets
402 Payment Requiredwith the x402 payment requirements.Payment, then response
Stripe or an x402 facilitator handles the payment, Meterdoor verifies it. Euros land in your Stripe account, USDC in your wallet.
Time-limited access
Person in a browser · euros via Stripe
- Request without payment: redirect to Stripe Checkout
- Pay once in euros (sample price: €0.50)
- Access to exactly this endpoint for the configured duration from payment (example: 1 hour)
- Unlimited requests until expiry; redeeming again does not extend it
Pay per request
AI agent · USDC via x402
- Request without payment:
402with payment requirements - Agent pays (sample price: 0.01 USDC) and sends the proof in the
X-PAYMENTheader - Response for exactly this request
- New request: new payment. The same proof again (e.g. after a dropped connection): the same response without a second charge, for one hour by default
Prices and duration are sample values from the code example; you set both yourself. Stripe requires at least €0.50 per payment.
Quickstart: add it to your Express app
There is no npm package today. You install Meterdoor into your project from the cloned repository. Tested with Express 4 and Node.js 20 or newer.
-
Install
In your app's folder, next to the cloned
meterdoorfolder. Meterdoor is an ES module: yourpackage.jsonneeds"type": "module".Terminal · in your app's foldernpm init -y # only for a new app npm pkg set type=module npm install express@4 ../meterdoor -
Protect a route
Save the code from the Express tab as
server.js. In an existing app, the import and thepaywall()block in front of your route are enough; behind a proxy, also addapp.set("trust proxy", 1).If you only want one payment path, leave out the other price: without
eurno Stripe key is needed, withoutusdcno wallet. -
Set environment variables and start
Example · .env file (do not commit)STRIPE_KEY=sk_test_… WALLET=0x… ACCESS_SECRET=…
STRIPE_KEY- Stripe test key (
sk_test_…orrk_test_…), for the euro path. WALLET- Your receiving address on Base Sepolia, for the USDC path.
ACCESS_SECRET- Long random string; signs the access tokens of the euro path.
PORT- Optional, default 3000.
Start with
node --env-file=.env server.js(Node 20.6 or newer; otherwise set the variables in your shell).Check:
curl -H "Accept: application/json" http://localhost:3000/api/report(in Windows PowerShell usecurl.exe) returns402with the payment requirements. In a browser, the same request redirects to Stripe Checkout in test mode; this needs a valid test key.
Is Meterdoor a fit for your endpoint?
The main limits before you integrate. Details are in the README in the repository.
Good fit
- Self-contained data responses and reports, e.g. JSON analyses (with x402, up to 1 MiB per response by default)
- Endpoints that people in browsers and programs both call
- Trials on the Base Sepolia testnet and in Stripe test mode
Not a fit
- Actions with side effects such as orders or sending e-mail: with x402, your route runs after verification but before final settlement. If settlement fails, the action has still happened.
- Streaming: with x402, the response is fully buffered and only sent after settlement.
- x402 schemes other than
exact(e.g.upto) and Permit2: onlyexactwith EIP-3009 (USDC) is accepted, in x402 version 1 and 2.
Good to know
- Storage: the default store lives in memory and is lost on restart, together with the responses stored for replays. The bundled file store (
fileStore) survives restarts; multiple processes on the same machine, no network drives. - Refunds: x402 does not refund automatically; the middleware reports open cases.
- Mainnet:
baseonly with the explicitallowMainnetoption.
Features and status
The core is free to use. Pro adds the parts you need in production and is in pre-sale.
Levels: tested locally (simulated) = automated tests with simulated counterparts pass; tested externally = test against the real test service passed (with date); planned = not available yet. Skipped tests do not count as passed. Status: 26 Oct 2026.
| Feature | Part | Status | Local evidence |
|---|---|---|---|
| Euros via Stripe Checkout, time-limited access to one endpoint | Core | tested locally (simulated); Stripe test mode tested externally on 23 Oct 2026 (session creation, unpaid and unknown sessions rejected) | npm test, demo |
USDC per request via x402 version 1 (X-PAYMENT), Base Sepolia | Core | tested locally (simulated); real test payment (testnet, no value) against the public facilitator tested externally on 25 Oct 2026 | npm test, demo |
| One endpoint detects browser or agent | Core | tested locally (simulated) | npm test, demo |
| Replay of the same proof without a second charge | Core | tested locally (simulated) | npm test, demo |
| Resolving unclear settlements via the chain | Core | tested locally (simulated) | npm test, demo |
| File store for restarts | Core | tested locally (simulated) | npm test |
| Binding to parameters or body | Core | tested locally (simulated) | npm test |
| Demo without keys | Core | tested locally in a browser | npm run test:demo |
USDC per request via x402 version 2 (PAYMENT-SIGNATURE), Base Sepolia | Core | tested locally (simulated); real test payment (testnet, no value) with the official client @x402/fetch tested externally on 25 Oct 2026 | npm test |
| Quotas and bundles (e.g. 100 requests) | Pro | tested locally (simulated) in the pre-release; not shipped | pre-release tests, not public |
| Log of all payments on both paths as CSV | Pro | tested locally (simulated) in the pre-release; not shipped | pre-release tests, not public |
| Reconciliation with Stripe webhooks | Pro | tested locally with simulated webhook events; not shipped | pre-release tests, not public |
| Delivery of Pro, 12 months of updates and e-mail support | Pro | planned: no later than 3 weeks after payment | – |
The commands run in the cloned repository without accounts and without keys. Tests against real test services live in integration/ and need your own test credentials; without them they are skipped.
Pricing
Pre-sale: you pay via Stripe and receive Pro by e-mail no later than three weeks after payment. Otherwise we refund the full amount.
Pro early bird
- Everything in Core
- Quotas, CSV log, webhook reconciliation
- 12 months of updates and support
- Delivery within 3 weeks of payment, otherwise full refund
Team
- Everything in Pro
- For agencies with several clients
Sold by a German company in euros; prices include 19% German VAT. For buyers outside Germany we check the VAT treatment before issuing the invoice. Checkout, terms (AGB) and withdrawal policy (Widerruf) are in German; support for Pro is available in English and German.
Frequently asked questions
Is this a payment service?
No. It is software that runs on your server. Euros go through your own Stripe account, USDC directly to your own address; processing is done by Stripe or the x402 facilitator of your choice. We never see or touch your money.
Is there an online demo?
No. The demo runs on your machine, without accounts and without real payments; the steps are under Try it locally, no keys needed.
What is x402?
An open protocol based on the HTTP status code 402. A program or AI agent receives machine-readable payment requirements, pays in stablecoins (usually USDC on Base) and requests the resource again. Payment verification is handled by an x402 facilitator of your choice. Whether your endpoint returns valid payment requirements is shown by the free x402 checker; common mistakes are explained in the article x402-Antwort richtig aufbauen (in German).
Do agents already pay meaningful amounts today?
Not much yet. x402 gets a lot of attention, but real payment volume is still small. That is why the middleware offers both paths: you earn from people today and are ready for agents, without a second integration.
Why not just use @x402/express or Stripe?
For agent-only payments, the official package is often the better choice. Meterdoor pays off when the same endpoint should also serve people paying in euros. A detailed comparison is in the article x402 in Express einbauen (in German).
What does it cost to run besides the license?
Stripe charges its usual fees on your account. For x402, network or facilitator fees may apply, depending on the facilitator you choose. There are no recurring costs from us.
When is Pro delivered?
No later than three weeks after your payment, by e-mail to the address from checkout. If we do not deliver in time, we refund the full amount.
Do you help with tax and legal questions about crypto income?
No. We describe the technology. Please clarify VAT, bookkeeping and sanctions screening for your own income with your tax advisor.