Skip to main content
Accept crypto payments in your Express v4 API with a single middleware function.

Installation

# npm
npm install @armory-sh/middleware-express-v4

# yarn
yarn add @armory-sh/middleware-express-v4

# pnpm
pnpm add @armory-sh/middleware-express-v4

# bun
bun add @armory-sh/middleware-express-v4

Quick Start

import express from 'express';
import { paymentMiddleware } from '@armory-sh/middleware-express-v4';

const app = express();

app.use(paymentMiddleware({
  requirements: {
    scheme: 'exact',
    network: 'eip155:8453',
    amount: '1000000',
    asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
    payTo: '0xYourWalletAddress...',
    maxTimeoutSeconds: 3600,
    extra: {}
  }
}));

app.get('/api/protected', (req, res) => {
  console.log(req.payment);
  res.json({ message: 'Payment verified!' });
});

app.listen(3000);

Express v4 vs v5

This package is specifically for Express v4. The API differs slightly from the v5 package:
FeatureExpress v4 PackageExpress v5 Package
Package@armory-sh/middleware-express-v4@armory-sh/middleware-express
RequirementsUses scheme, network, assetUses chainId, assetId
AmountString ("1000000")BigInt (1000000n)
For full documentation on configuration options, accessing payment info, and error responses, see the Express middleware documentation.

Route-Aware Middleware

Configure different payment requirements for different routes:
import { routeAwarePaymentMiddleware } from '@armory-sh/middleware-express-v4';

app.use(routeAwarePaymentMiddleware({
  '/api/basic': {
    requirements: {
      scheme: 'exact',
      network: 'eip155:8453',
      amount: '1000000',
      asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
      payTo: '0xYourAddress...',
      maxTimeoutSeconds: 300,
      extra: {}
    }
  },
  '/api/premium': {
    requirements: {
      scheme: 'exact',
      network: 'eip155:8453',
      amount: '5000000',
      asset: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
      payTo: '0xYourAddress...',
      maxTimeoutSeconds: 300,
      extra: {}
    }
  }
}));

Advanced Mix-and-Match Example

For fully custom combinations, define explicit requirements and route-specific facilitator URLs:
import { routeAwarePaymentMiddleware } from "@armory-sh/middleware-express-v4";

app.use(
  routeAwarePaymentMiddleware({
    "/api/basic": {
      requirements: {
        scheme: "exact",
        network: "eip155:8453",
        amount: "1000000",
        asset: "0x833589fCD6eDb6E08f4c7C32D4f71B54bdA02913",
        payTo: "0x1234567890123456789012345678901234567890",
        maxTimeoutSeconds: 300,
      },
      facilitatorUrl: "https://payai.example",
    },
    "/api/skale-premium": {
      requirements: {
        scheme: "exact",
        network: "eip155:1187947933",
        amount: "2500000",
        asset: "0x5f9beea3f6f22be1f4f8efc120f5095f58dbb8a2",
        payTo: "0x1234567890123456789012345678901234567890",
        maxTimeoutSeconds: 300,
      },
      facilitatorUrl: "https://kobaru.example",
    },
  }),
);
For v4, the cleanest way to mix facilitator+amount by token/network is to define separate requirements per route, each with its own facilitatorUrl.

Migration to Express v5

When upgrading to Express v5, switch to @armory-sh/middleware-express:
# npm
npm uninstall @armory-sh/middleware-express-v4
npm install @armory-sh/middleware-express

# yarn
yarn remove @armory-sh/middleware-express-v4
yarn add @armory-sh/middleware-express

# pnpm
pnpm remove @armory-sh/middleware-express-v4
pnpm add @armory-sh/middleware-express

# bun
bun remove @armory-sh/middleware-express-v4
bun add @armory-sh/middleware-express
Then update your code to use the v5 API format (BigInt amounts, chainId/assetId instead of network/asset).