import express, { type Express, type Request, type Response } from 'express'
import { createSolvaPay, PaywallError } from '@solvapay/server'
const app: Express = express()
const port = process.env.PORT || 3000
// Middleware
app.use(express.json())
// Initialize SolvaPay
const solvaPay = createSolvaPay({
apiKey: process.env.SOLVAPAY_SECRET_KEY,
})
// Create payable handlers
const payable = solvaPay.payable({
product: 'prd_myapi',
plan: 'pln_premium',
})
// Authentication middleware
function authMiddleware(req: Request, res: Response, next: express.NextFunction) {
const customerRef = req.headers['x-customer-ref'] as string
if (!customerRef) {
return res.status(401).json({ error: 'Missing x-customer-ref header' })
}
req.customerRef = customerRef
next()
}
app.use(authMiddleware)
// Business logic functions
async function createTask(req: Request) {
const { title, description } = req.body
if (!title) {
throw new Error('Title is required')
}
const task = {
id: Date.now().toString(),
title,
description,
createdAt: new Date().toISOString(),
}
return { success: true, task }
}
async function getTask(req: Request) {
const { id } = req.params
// Simulate fetching from database
const task = {
id,
title: 'Sample Task',
description: 'Task description',
}
return { success: true, task }
}
async function listTasks(req: Request) {
const tasks = [
{ id: '1', title: 'Task 1' },
{ id: '2', title: 'Task 2' },
]
return { success: true, tasks, total: tasks.length }
}
// Protected routes
app.post('/api/tasks', payable.http(createTask))
app.get('/api/tasks/:id', payable.http(getTask))
app.get('/api/tasks', payable.http(listTasks))
// Health check (unprotected)
app.get('/health', (req: Request, res: Response) => {
res.json({ status: 'ok' })
})
// Error handling middleware
app.use((error: Error, req: Request, res: Response, next: express.NextFunction) => {
if (error instanceof PaywallError) {
return res.status(402).json({
error: 'Payment required',
message: error.message,
checkoutUrl: error.structuredContent.checkoutUrl,
product: error.structuredContent.product,
})
}
console.error('Error:', error)
res.status(500).json({ error: 'Internal server error' })
})
// Start server
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`)
})