Docs/Merchants

Charge per API call

Wrap one Express route with pay.charge() and your API starts quoting prices in USDC, returning x402 challenges to unpaid clients, and verifying confidential payments on-chain in the same request. Your server holds no signing key — you only receive funds.

Time to first verified payment: ~5 minutes.

Grab your merchant ETA address

  1. Sign in and pick API provider during onboarding.
  2. Your dashboard shows a merchant ETA address — the deterministic Solana pubkey of your Umbra encrypted token account, registered on chain at signup. Click the copy button.
  3. Paste it into your server's environment:
your-api/.env·bash
MERCHANT_ETA_ADDRESS=7xK3r…NhGP
HELIUS_RPC_URL=https://devnet.helius-rpc.com/?api-key=…

Wrap a route

Create server.ts and paste this in. The charge middleware goes before your handler — it intercepts payment-less requests with a 402, and verifies payment-bearing requests on-chain before letting them through.

server.ts·ts
import express from "express";
import { obscura } from "@obscura-app/merchant-sdk";

const pay = obscura({
merchantEtaAddress: process.env.MERCHANT_ETA_ADDRESS!,
network: "solana-devnet",
rpcUrl: process.env.HELIUS_RPC_URL,
});

const app = express();

app.get(
"/article/:id",
pay.charge({ amount: "10000", description: "News article" }),
(req, res) => {
  res.json({
    id: req.params.id,
    headline: `Article #${req.params.id}`,
    body: "Full article text here…",
  });
},
);

app.listen(3001, () =>
console.log("Paid API on http://localhost:3001"),
);

Run it:

terminal·bash
npx tsx server.ts
# → Paid API on http://localhost:3001

Watch payments land

With the server running, point any x402 client — the agent quickstart works — at your route. On your merchant dashboard the payment shows up within a second via real-time SSE, with the on-chain queue signature linked to Solscan. The encrypted-balance credit follows asynchronously after the claim daemon picks it up (next 2-minute tick).

What's next

  • How it works — every step of the two-phase x402 handshake.
  • Settlement receipts — reading res.locals.obscuraSettlement + the X-Payment-Response header.
  • Pricing & assets — per-route prices, custom mints, mainnet switching.
  • Deploy — where this SDK runs best.