402.md

@402md/gateway

Server-side Express middleware reference

Installation

npm install @402md/gateway

create402Gateway(config)

import { create402Gateway } from '@402md/gateway'

const gateway = create402Gateway({
  apiKey: process.env.FOUROHTWOM_API_KEY!
})

GatewayConfig

FieldTypeRequiredDescription
apiKeystringYesAPI key from 402.md dashboard
apiBaseUrlstringNoOverride API URL. Defaults to 'https://api.402.md'

Middleware methods

gateway.payPerCall(price)

Require payment for each API call.

app.post('/api/analyze', gateway.payPerCall('0.05'), (req, res) => {
  const result = analyzeSentiment(req.body.text)
  res.json(result)
})

402 response when unpaid:

{
  "price": "0.05",
  "description": "Payment required for API access",
  "network": "base"
}

gateway.subscription(config)

Require payment for a subscription.

app.post('/api/subscribe', gateway.subscription({
  price: '49.00',
  durationDays: 30,
  accessUrl: 'https://dashboard.example.com'
}), handler)
FieldTypeRequiredDescription
pricestringYesSubscription price in USDC
durationDaysnumberYesAccess duration in days
accessUrlstringNoURL the subscriber should access

402 response when unpaid:

{
  "price": "49.00",
  "description": "Subscription: 30 day(s) access",
  "durationDays": 30,
  "accessUrl": "https://dashboard.example.com",
  "network": "base"
}

gateway.product(config)

Require payment for a product purchase.

app.post('/api/buy/:id', gateway.product({
  price: '99.99',
  requiresShipping: true
}), handler)
FieldTypeRequiredDescription
pricestringYesProduct price in USDC
requiresShippingbooleanNoWhether shipping info is required

402 response when unpaid:

{
  "price": "99.99",
  "description": "Payment required for product purchase",
  "requiresShipping": true,
  "network": "base"
}

gateway.service(config)

Require payment for a one-time service.

app.post('/api/design', gateway.service({
  price: '25.00'
}), handler)
FieldTypeRequiredDescription
pricestringYesService price in USDC

402 response when unpaid:

{
  "price": "25.00",
  "description": "Payment required for service",
  "network": "base"
}

req.x402

After the middleware verifies a payment, req.x402 is populated with payment data:

FieldTypeAvailable in
txHashstringAll middleware
amountstringAll middleware
typestringsubscription, product, service
durationDaysnumbersubscription
requiresShippingbooleanproduct

Payment header

The middleware accepts payment proof from two header names:

  • X-402-Payment (primary)
  • Payment (fallback)

The header value is a Base64-encoded JSON string containing the transaction hash, amount, token, network, and sender/recipient addresses.

Verification flow

  1. Middleware checks for X-402-Payment or Payment header
  2. If missing → returns HTTP 402 with payment requirements
  3. If present → calls POST /api/verify on the 402.md API with the payment header
  4. If valid → calls next() and populates req.x402 with payment data
  5. If invalid → returns HTTP 402 with "error": "Invalid payment"

If the 402.md API is unreachable, the middleware returns HTTP 500.