Merchant SDK

Merchant SDK

Monetize your API with HTTP 402 paywalls. Add a single middleware to any Express, Next.js, or Fastify endpoint and start earning USDC from AI agent requests.

How It Works

1Agent calls your API

An AI agent sends a request to your protected endpoint

2Gets HTTP 402

Skalor middleware returns 402 with payment details in headers

3Pays via Skalor

Agent pays at the settlement URL and gets a signed receipt

4Gets your data

Agent replays the request with receipt - your handler runs

Quickstart

1

Install

npm install skalor-merchant
2

Get your credentials

Sign up at skalor.xyz to get your SKALOR_JWT_SECRET and SKALOR_AGENT_ID.

3

Add the middleware

Choose your framework:

server.ts
import express from "express"
import { skalorPay } from "skalor-merchant/express"

const app = express()

app.get("/api/data", skalorPay({
  jwtSecret: process.env.SKALOR_JWT_SECRET,
  price: 0.05,
  currency: "USDC",
  receiverAgentId: process.env.SKALOR_AGENT_ID,
  description: "Premium data endpoint",
}), (req, res) => {
  res.json({ data: "your premium content" })
})
4

Test it

curl https://your-api.com/api/data
# Returns 402 Payment Required with X-Skalor-* headers

Configuration

OptionTypeRequiredDescription
jwtSecretstringYesYour Skalor JWT secret for receipt verification
pricenumberYesPrice per request in USDC
currencystringNoDefault: "USDC"
receiverAgentIdstringYesYour merchant agent ID
descriptionstringNoHuman-readable description
settlementUrlstringNoCustom settlement URL

402 Response Headers

When an unauthenticated request hits your endpoint, the middleware returns 402 with these headers:

X-Skalor-AmountPayment amount required (e.g. 0.05)
X-Skalor-CurrencyCurrency for payment (USDC)
X-Skalor-Settlement-UrlURL the agent should POST payment to
X-Skalor-ReceiverMerchant agent ID receiving the payment
X-Skalor-DescriptionHuman-readable description of the resource

Webhooks

Skalor sends webhook events signed with HMAC-SHA256. Events: payment.completed, payment.failed, settlement.confirmed

webhooks.ts
import crypto from "crypto"

app.post("/webhooks/skalor", (req, res) => {
  const signature = req.headers["x-skalor-signature"] as string
  const expected = crypto
    .createHmac("sha256", process.env.SKALOR_WEBHOOK_SECRET!)
    .update(JSON.stringify(req.body))
    .digest("hex")

  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
    return res.status(401).json({ error: "Invalid signature" })
  }

  const { event, data } = req.body
  console.log(`Received ${event}`, data)
  res.json({ received: true })
})