Node.js SDK
The Orvion Node.js SDK provides seamless integration with Express for creating payment-protected API endpoints using the x402 protocol.
Installation
npm install @orvion/sdk
Quick Start
import express from 'express'
import { orvionInit, requirePayment } from '@orvion/sdk/express'
const app = express()
// Initialize Orvion
orvionInit({
apiKey: process.env.ORVION_API_KEY!,
})
// Protect an endpoint
app.get('/api/premium',
requirePayment({ amount: '0.10', currency: 'USDC' }),
(req, res) => {
res.json({ message: 'Premium content!', paid: req.payment.amount })
}
)
app.listen(3000)
orvionInit
Initialize the Orvion SDK with your API key and configuration.
Configuration
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
| apiKey | string | Optional | Your Orvion API key (required) | — |
| baseUrl | string? | Optional | Custom API base URL (default: https://api.orvion.sh) | — |
| cacheTtlSeconds | number | Optional | Route cache TTL in seconds (default: 60) | — |
| transactionHeader | string | Optional | Header for transaction ID (default: 'X-Transaction-Id') | — |
| customerHeader | string | Optional | Header for customer ID (default: 'X-Customer-Id') | — |
Example
orvionInit({
apiKey: process.env.ORVION_API_KEY!,
cacheTtlSeconds: 120, // Cache routes for 2 minutes
transactionHeader: 'X-Payment-Id', // Custom header name
})
requirePayment Middleware
Protect Express routes with payment requirements.
Parameters
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
| amount | string? | Optional | Price per request (e.g., '0.10') | — |
| currency | string | Optional | Currency code (default: 'USD') | — |
| allowAnonymous | boolean? | Optional | Allow requests without customer ID (default: true) | — |
| customerResolver | Function? | Optional | Function to extract customer ID from request | — |
| hostedCheckout | boolean | Optional | Redirect to pay.orvion.sh instead of 402 (default: false) | — |
| returnUrl | string? | Optional | Return URL after hosted checkout payment | — |
Examples
// Basic usage
app.get('/api/basic',
requirePayment({ amount: '0.01', currency: 'USDC' }),
(req, res) => {
res.json({ data: '...' })
}
)
// With metadata
app.get('/api/premium',
requirePayment({
amount: '1.00',
currency: 'USDC',
}),
(req, res) => {
res.json({ data: '...', paid: req.payment.amount })
}
)
// Hosted checkout mode
app.get('/premium',
requirePayment({
amount: '1.00',
currency: 'USDC',
hostedCheckout: true,
}),
(req, res) => {
res.json({ message: 'Premium content!' })
}
)
Pre-built Payment Router (NEW in v0.2)
The SDK provides a pre-built router that adds all payment endpoints automatically - no boilerplate needed!
Usage
import { OrvionClient } from '@orvion/sdk'
import { createPaymentRouter } from '@orvion/sdk/express'
const client = new OrvionClient({ apiKey: process.env.ORVION_API_KEY! })
// Add all payment endpoints with one line!
app.use('/api/payments', createPaymentRouter(client))
This adds the following endpoints:
| Endpoint | Method | Description |
|----------|--------|-------------|
| /api/payments/confirm | POST | Confirm wallet payment with tx_hash |
| /api/payments/cancel/:id | POST | Cancel a pending charge |
| /api/payments/state/:id | GET | Get charge state for payment widgets |
| /api/payments/charge/:id | GET | Get full charge details |
Available Routers
import {
createPaymentRouter, // Payment operations
createHealthRouter, // Health check endpoint
createFullRouter, // All endpoints combined
} from '@orvion/sdk/express'
// Payment router only
app.use('/api/payments', createPaymentRouter(client))
// Health router only
app.use('/api', createHealthRouter(client))
// Combined router (payments + health)
app.use('/api/orvion', createFullRouter(client))
OrvionClient
The client provides direct API access for all payment operations.
New Methods (v0.2)
import { OrvionClient } from '@orvion/sdk'
const client = new OrvionClient({ apiKey: 'your-api-key' })
// Health check & API key validation
const health = await client.healthCheck()
console.log(`Organization: ${health.organizationId}`)
console.log(`API Key Valid: ${health.apiKeyValid}`)
// Create a charge
const charge = await client.createCharge({
amount: '0.10',
currency: 'USDC',
description: 'API access',
})
// Get charge details
const chargeDetails = await client.getCharge(charge.id)
// Get charge state (optimized for UI widgets)
const state = await client.getChargeState(charge.id)
console.log(`Status: ${state.status}`)
console.log(`Recipient: ${state.recipientAddress}`)
// Confirm wallet payment
const result = await client.confirmPayment({
transactionId: charge.id,
txHash: 'blockchain_tx_signature...',
})
console.log(`Success: ${result.success}`)
// Cancel a pending charge
const cancelled = await client.cancelCharge(charge.id)
// Verify a payment
const verification = await client.verifyCharge({
transactionId: charge.id,
resourceRef: 'my-resource',
})
All Client Methods
| Method | Description |
|--------|-------------|
| createCharge() | Create a new payment charge |
| verifyCharge() | Verify a payment transaction |
| getCharge() | Get charge details by ID |
| getChargeState() | Get UI-optimized charge state |
| confirmPayment() | Confirm wallet payment with tx_hash |
| cancelCharge() | Cancel a pending charge |
| healthCheck() | Validate API key & get org info |
| getRoutes() | Get protected route configurations |
| matchRoute() | Match a request to a protected route |
TypeScript Types
Core Types
import type {
Charge, // Payment charge
VerifyResult, // Payment verification result
PaymentInfo, // Payment info attached to request
RouteConfig, // Protected route configuration
} from '@orvion/sdk'
New Types (v0.2)
import type {
ConfirmResult, // Result of wallet payment confirmation
ChargeState, // UI state for payment widgets
HealthInfo, // API health & organization info
WalletPaymentInfo, // Wallet payment details
PaymentMethodInfo, // Available payment methods
} from '@orvion/sdk'
Helper Functions
import {
extractWalletPaymentInfo, // Parse wallet info from x402_requirements
extractPaymentMethods, // Get available payment methods
} from '@orvion/sdk'
// Parse payment methods from x402_requirements
const charge = await client.createCharge({ amount: '0.10', currency: 'USDC' })
const methods = extractPaymentMethods(charge.x402Requirements)
console.log(`Available methods: ${methods.methods}`) // ["solana"]
if (methods.solana) {
console.log(`Recipient: ${methods.solana.recipientAddress}`)
console.log(`Token: ${methods.solana.tokenAddress}`)
}
Accessing Payment Info
After successful payment verification, payment details are available on req.payment:
app.get('/api/premium',
requirePayment({ amount: '0.10', currency: 'USDC' }),
(req, res) => {
const { payment } = req
res.json({
transactionId: payment.transactionId,
amount: payment.amount,
currency: payment.currency,
customerRef: payment.customerRef,
})
}
)
PaymentInfo Type
interface PaymentInfo {
transactionId: string
amount: string
currency: string
customerRef?: string
resourceRef?: string
routeId?: string
verifiedAt?: string
}
Complete Example (Minimal)
This example shows how thin your app can be with the SDK:
import express from 'express'
import { OrvionClient } from '@orvion/sdk'
import {
orvionInit,
requirePayment,
createPaymentRouter,
} from '@orvion/sdk/express'
const app = express()
app.use(express.json())
const client = new OrvionClient({ apiKey: process.env.ORVION_API_KEY! })
// Initialize Orvion
orvionInit({ apiKey: process.env.ORVION_API_KEY! })
// Add pre-built payment router (confirm, cancel, state, charge endpoints)
app.use('/api/payments', createPaymentRouter(client))
// Protected endpoint - that's it!
app.get('/api/premium',
requirePayment({ amount: '0.01', currency: 'USDC' }),
(req, res) => {
res.json({ access: 'granted', message: 'Welcome to premium!' })
}
)
app.listen(3000, () => {
console.log('Server running on http://localhost:3000')
})
Error Handling
import { OrvionClient, OrvionAPIError, OrvionAuthError } from '@orvion/sdk'
try {
const client = new OrvionClient({ apiKey: 'your-api-key' })
const charge = await client.createCharge({ amount: '0.10', currency: 'USDC' })
} catch (error) {
if (error instanceof OrvionAuthError) {
console.error('Invalid API key')
} else if (error instanceof OrvionAPIError) {
console.error(`API Error: ${error.statusCode} - ${error.message}`)
} else {
console.error('Unexpected error:', error)
}
}
Request Type Extensions
The SDK extends the Express Request type to include payment info:
declare global {
namespace Express {
interface Request {
payment?: PaymentInfo
orvionClient?: OrvionClient
}
}
}
For TypeScript users, the types are automatically available after importing from @orvion/sdk/express.
Related Documentation
- Protected Routes - Full protected routes guide
- Protected Routes - Node.js - Express integration details
- Hosted Checkout - Redirect-based payment flow
- Charges API - Low-level charge creation
- API Keys - Managing API keys