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-merchant2
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-* headersConfiguration
| Option | Type | Required | Description |
|---|---|---|---|
jwtSecret | string | Yes | Your Skalor JWT secret for receipt verification |
price | number | Yes | Price per request in USDC |
currency | string | No | Default: "USDC" |
receiverAgentId | string | Yes | Your merchant agent ID |
description | string | No | Human-readable description |
settlementUrl | string | No | Custom 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 toX-Skalor-ReceiverMerchant agent ID receiving the paymentX-Skalor-DescriptionHuman-readable description of the resourceWebhooks
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 })
})