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
Example · server.js · sample prices
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);
Example flow · person in a browser · Stripe test mode
# 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": "…" }
Example flow · AI agent · x402 on Base Sepolia
# 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.

Terminal · start the demo
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.

  1. 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.

  2. Request without payment

    A browser is redirected to Stripe Checkout. An AI agent gets 402 Payment Required with the x402 payment requirements.

  3. Payment, then response

    Stripe or an x402 facilitator handles the payment, Meterdoor verifies it. Euros land in your Stripe account, USDC in your wallet.

What each payment path gets you

Time-limited access

Person in a browser · euros via Stripe

  1. Request without payment: redirect to Stripe Checkout
  2. Pay once in euros (sample price: €0.50)
  3. Access to exactly this endpoint for the configured duration from payment (example: 1 hour)
  4. Unlimited requests until expiry; redeeming again does not extend it

Pay per request

AI agent · USDC via x402

  1. Request without payment: 402 with payment requirements
  2. Agent pays (sample price: 0.01 USDC) and sends the proof in the X-PAYMENT header
  3. Response for exactly this request
  4. 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.

  1. Install

    In your app's folder, next to the cloned meterdoor folder. Meterdoor is an ES module: your package.json needs "type": "module".

    Terminal · in your app's folder
    npm init -y   # only for a new app
    npm pkg set type=module
    npm install express@4 ../meterdoor
  2. Protect a route

    Save the code from the Express tab as server.js. In an existing app, the import and the paywall() block in front of your route are enough; behind a proxy, also add app.set("trust proxy", 1).

    If you only want one payment path, leave out the other price: without eur no Stripe key is needed, without usdc no wallet.

  3. 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_… or rk_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 use curl.exe) returns 402 with 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: only exact with 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: base only with the explicit allowMainnet option.

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.

FeaturePartStatusLocal evidence
Euros via Stripe Checkout, time-limited access to one endpointCoretested 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 SepoliaCoretested locally (simulated); real test payment (testnet, no value) against the public facilitator tested externally on 25 Oct 2026npm test, demo
One endpoint detects browser or agentCoretested locally (simulated)npm test, demo
Replay of the same proof without a second chargeCoretested locally (simulated)npm test, demo
Resolving unclear settlements via the chainCoretested locally (simulated)npm test, demo
File store for restartsCoretested locally (simulated)npm test
Binding to parameters or bodyCoretested locally (simulated)npm test
Demo without keysCoretested locally in a browsernpm run test:demo
USDC per request via x402 version 2 (PAYMENT-SIGNATURE), Base SepoliaCoretested locally (simulated); real test payment (testnet, no value) with the official client @x402/fetch tested externally on 25 Oct 2026npm test
Quotas and bundles (e.g. 100 requests)Protested locally (simulated) in the pre-release; not shippedpre-release tests, not public
Log of all payments on both paths as CSVProtested locally (simulated) in the pre-release; not shippedpre-release tests, not public
Reconciliation with Stripe webhooksProtested locally with simulated webhook events; not shippedpre-release tests, not public
Delivery of Pro, 12 months of updates and e-mail supportProplanned: 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.

Core

€0
Open source, Apache 2.0
  • Both payment paths
  • Express
  • Source code on GitHub
View repository

Pro early bird

€49
incl. 19% German VAT · one-time · 1 project · later €79
  • Everything in Core
  • Quotas, CSV log, webhook reconciliation
  • 12 months of updates and support
  • Delivery within 3 weeks of payment, otherwise full refund
Buy for €49

Team

€179
incl. 19% German VAT · one-time · up to 5 projects
  • Everything in Pro
  • For agencies with several clients
Ask us

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.

Your API, two checkouts, one endpoint.