npmhttps://www.npmjs.com/package/@bsv/402-payv0.1.3betaAPI reference (TypeDoc) ↗

@bsv/402-pay

BRC-121 HTTP 402 Payment Required handler for client and server. Client-side: auto-pays 402 responses. Server-side: middleware/validation for accepting BSV micropayments over HTTP.

Install

bash
npm install @bsv/402-pay

Quick start

typescript
// ===== SERVER SIDE =====
import express from 'express'
import { createPaymentMiddleware } from '@bsv/402-pay/server'

const app = express()

app.use('/articles/:slug', createPaymentMiddleware({
  wallet,
  calculatePrice: (path) => {
    if (path.includes('/premium/')) return 1000
    return undefined
  }
}))

app.get('/articles/:slug', (req, res) => {
  if (req.payment) {
    res.json({ article: 'Paid content here', paidBy: req.payment.senderIdentityKey })
  } else {
    res.json({ article: 'Free content' })
  }
})

// ===== CLIENT SIDE =====
import { create402Fetch } from '@bsv/402-pay/client'

const fetch402 = create402Fetch({
  wallet,
  cacheTimeoutMs: 30 * 60 * 1000
})

const response = await fetch402('https://example.com/articles/foo')
const article = await response.json()
console.log(article)

What it provides

Server

  • createPaymentMiddleware — Express middleware for automatic 402 handling
  • validatePayment — Validate incoming payment headers
  • send402 — Send 402 response with payment request headers

Client

  • create402Fetch — Fetch wrapper that auto-handles 402 responses
  • constructPaymentHeaders — Build payment headers manually
  • clearCache — Clear cached paid content

Types & Constants

  • PaymentMiddlewareOptions — Middleware configuration
  • PaymentResult — Parsed payment with satoshisPaid, senderIdentityKey, and txid
  • PaymentHeaders — Five required headers (BEEF, SENDER, NONCE, TIME, VOUT)
  • HEADERS — Header names enum
  • BRC29_PROTOCOL_ID — Protocol ID for payment key derivation

Common patterns

Server low-level API

typescript
import express from 'express'
import { validatePayment, send402 } from '@bsv/402-pay/server'

const app = express()

app.get('/premium', async (req, res) => {
  const price = 100
  const result = await validatePayment(req, wallet, price)
  if (!result || !result.accepted) {
    send402(res, serverIdentityKey, price)
    return
  }
  res.json({
    content: 'Premium stuff',
    tx: result.txid,
    paidBy: result.senderIdentityKey
  })
})

Client manual headers

typescript
import { constructPaymentHeaders } from '@bsv/402-pay/client'

const headers = await constructPaymentHeaders(
  wallet,
  'https://example.com/articles/foo',
  100,  // 100 sats
  serverPublicKey
)

const res = await fetch('https://example.com/articles/foo', { headers })

Client with cache management

typescript
const fetch402 = create402Fetch({
  wallet,
  cacheTimeoutMs: 30 * 60 * 1000  // Cache for 30 minutes
})

// Make requests — auto-pays 402s with caching
const response = await fetch402('https://api.example.com/content')
const data = await response.json()

// Clear cache between sessions
fetch402.clearCache()

Key concepts

  • 402 Payment Required — HTTP status code for micropayments (BRC-121)
  • Server Headers (402 response)x-bsv-sats, x-bsv-server for payment request
  • Client Headers (payment request) — BEEF, sender, nonce, time, vout for payment proof
  • Replay Protection — Timestamp freshness (30 seconds) + transaction uniqueness
  • Key Derivation — BRC-29 using server identity key + nonce + timestamp
  • Caching — Client caches paid content per URL to avoid re-payment
  • P2PKH Script — Payment always P2PKH: OP_DUP OP_HASH160 <hash> OP_EQUALVERIFY OP_CHECKSIG

When to use this

  • Building clients that interact with paid APIs
  • Creating applications that need to pay for content on-demand
  • Implementing automatic payment for API access
  • Building smart clients that handle 402 gracefully
  • Testing payment-gated services
  • Monetizing APIs with micropayments

When NOT to use this

  • Routes that already require BRC-31 HTTP auth — use @bsv/payment-express-middleware with @bsv/auth-express-middleware
  • Manual payment control needed — don't use auto-handler
  • Subscription-based access — use authentication instead
  • Large bulk payments — use dedicated payment processing

Spec conformance

  • BRC-121 — HTTP 402 Payment Required micropayments
  • BRC-29 — Key derivation (payment pubkey via nonce + timestamp)
  • BRC-42 — Public key derivation
  • BRC-100 — Wallet interface
  • P2PKH — Standard Bitcoin SV locking script
  • BEEF — Transaction proof format

Common pitfalls

  1. Timestamp must be fresh — If x-bsv-time is >30 seconds old, payment is rejected
  2. Server identity key required — Server must send its identity public key in 402 response
  3. Transaction uniqueness — Replaying same BEEF twice is rejected; nonce must be different
  4. Cache timeout too long — If cached, same content served without payment check
  5. BEEF must be valid — Malformed or invalid BEEF transaction is rejected
  6. Wallet not available — Client-side create402Fetch requires working WalletClient
  7. calculatePrice undefined — If returns undefined, payment is skipped (content is free)
  8. Server clock skew — If clocks differ by >30 seconds, payment fails; use NTP
  • @bsv/payment-express-middleware — Server-side payment gating with Express
  • @bsv/auth-express-middleware — HTTP authentication (often paired with 402)
  • @bsv/sdk — WalletClient, PublicKey, Utils for payment construction

Reference