@solvapay/next
v1.0.12
Published
Next.js-specific utilities and helpers for SolvaPay SDK.
Downloads
3,408
Readme
@solvapay/next
Next.js-specific utilities and helpers for SolvaPay SDK.
This package provides framework-specific helpers for Next.js API routes with built-in optimizations like request deduplication and caching.
Installation
npm install @solvapay/next @solvapay/server nextUsage
All helpers return either a success result or a NextResponse error, making them easy to use in Next.js API routes.
Check Purchase
Check user purchase status with built-in request deduplication and caching:
import { NextRequest, NextResponse } from 'next/server'
import { checkPurchase } from '@solvapay/next'
export async function GET(request: NextRequest) {
const result = await checkPurchase(request)
// If result is a NextResponse, it's an error response - return it
if (result instanceof NextResponse) {
return result
}
// Otherwise, return the purchase data
return NextResponse.json(result)
}Features:
- Automatic Deduplication: Prevents duplicate API calls by deduplicating concurrent requests
- Caching: Caches results for 2 seconds to prevent duplicate sequential requests
- Automatic Cleanup: Expired cache entries are automatically cleaned up
- Memory Safe: Maximum cache size limits prevent memory issues
Sync Customer
Sync customer with SolvaPay backend (ensures customer exists and returns customer reference):
import { NextRequest, NextResponse } from 'next/server'
import { syncCustomer } from '@solvapay/next'
export async function POST(request: NextRequest) {
const result = await syncCustomer(request)
if (result instanceof NextResponse) {
return result
}
return NextResponse.json({ customerRef: result })
}Create Payment Intent
Create a Stripe payment intent for checkout:
import { NextRequest, NextResponse } from 'next/server'
import { createPaymentIntent } from '@solvapay/next'
export async function POST(request: NextRequest) {
const { planRef, productRef } = await request.json()
if (!planRef || !productRef) {
return NextResponse.json({ error: 'Missing required parameters' }, { status: 400 })
}
const result = await createPaymentIntent(request, { planRef, productRef })
return result instanceof NextResponse ? result : NextResponse.json(result)
}Process Payment
Process payment after Stripe confirmation:
import { NextRequest, NextResponse } from 'next/server'
import { processPayment } from '@solvapay/next'
export async function POST(request: NextRequest) {
const { paymentIntentId, productRef, planRef } = await request.json()
if (!paymentIntentId || !productRef) {
return NextResponse.json({ error: 'Missing required parameters' }, { status: 400 })
}
const result = await processPayment(request, { paymentIntentId, productRef, planRef })
return result instanceof NextResponse ? result : NextResponse.json(result)
}List Plans
List available plans (public route, no authentication required):
import { NextRequest, NextResponse } from 'next/server'
import { listPlans } from '@solvapay/next'
export async function GET(request: NextRequest) {
const result = await listPlans(request)
return result instanceof NextResponse ? result : NextResponse.json(result)
}Cancel Renewal
Cancel renewal of a user's purchase:
import { NextRequest, NextResponse } from 'next/server'
import { cancelRenewal } from '@solvapay/next'
export async function POST(request: NextRequest) {
const { purchaseRef, reason } = await request.json()
if (!purchaseRef) {
return NextResponse.json({ error: 'Missing purchaseRef' }, { status: 400 })
}
const result = await cancelRenewal(request, { purchaseRef, reason })
return result instanceof NextResponse ? result : NextResponse.json(result)
}Create Checkout Session
Create a hosted checkout session:
import { NextRequest, NextResponse } from 'next/server'
import { createCheckoutSession } from '@solvapay/next'
export async function POST(request: NextRequest) {
const { productRef, planRef } = await request.json()
if (!productRef) {
return NextResponse.json({ error: 'Missing productRef' }, { status: 400 })
}
const result = await createCheckoutSession(request, { productRef, planRef })
return result instanceof NextResponse ? result : NextResponse.json(result)
}Create Customer Session
Create a customer portal session:
import { NextRequest, NextResponse } from 'next/server'
import { createCustomerSession } from '@solvapay/next'
export async function POST(request: NextRequest) {
const result = await createCustomerSession(request)
return result instanceof NextResponse ? result : NextResponse.json(result)
}Get Authenticated User
Get authenticated user information (userId, email, name):
import { NextRequest, NextResponse } from 'next/server'
import { getAuthenticatedUser } from '@solvapay/next'
export async function GET(request: NextRequest) {
const result = await getAuthenticatedUser(request, {
includeEmail: true,
includeName: true,
})
if (result instanceof NextResponse) {
return result
}
return NextResponse.json(result)
}Cache Management
import {
clearPurchaseCache,
clearAllPurchaseCache,
getPurchaseCacheStats,
} from '@solvapay/next'
// Clear cache for a specific user
clearPurchaseCache(userId)
// Clear all cache entries
clearAllPurchaseCache()
// Get cache statistics
const stats = getPurchaseCacheStats()
console.log(`In-flight: ${stats.inFlight}, Cached: ${stats.cached}`)Helper Functions Reference
All helper functions follow the same pattern:
- Take a
RequestorNextRequestas the first parameter - Return either the success result or a
NextResponseerror - Automatically extract user information from request headers (set by middleware)
- Support optional configuration options
Available Helpers:
checkPurchase(request, options?)- Check purchase with cachingsyncCustomer(request, options?)- Sync customer with backendcreatePaymentIntent(request, body, options?)- Create payment intentprocessPayment(request, body, options?)- Process paymentlistPlans(request)- List available plans (public)cancelRenewal(request, body, options?)- Cancel renewalcreateCheckoutSession(request, body, options?)- Create hosted checkoutcreateCustomerSession(request, options?)- Create customer portalgetAuthenticatedUser(request, options?)- Get user info
Common Options:
solvaPay?: SolvaPay- Custom SolvaPay instanceincludeEmail?: boolean- Include user email (default: true)includeName?: boolean- Include user name (default: true)
Requirements
- Next.js >= 13.0.0
- Node.js >= 18.17
Why a Separate Package?
This package is separate from @solvapay/server to keep the server package framework-agnostic. Users who use Express, Fastify, or other frameworks don't need Next.js as a dependency.
Middleware Setup
These helpers expect the user ID to be set in the x-user-id header by your Next.js middleware/proxy.
Quick Setup with Supabase
The easiest way is to use createSupabaseAuthMiddleware:
For Next.js 15:
// middleware.ts (at project root)
import { createSupabaseAuthMiddleware } from '@solvapay/next'
export const middleware = createSupabaseAuthMiddleware({
publicRoutes: ['/api/list-plans'],
})
export const config = {
matcher: ['/api/:path*'],
}For Next.js 16 with src/ folder:
// src/proxy.ts (in src/ folder, not project root)
import { createSupabaseAuthMiddleware } from '@solvapay/next/middleware'
// Use 'proxy' export for Next.js 16 (no deprecation warning)
export const proxy = createSupabaseAuthMiddleware({
publicRoutes: ['/api/list-plans'],
})
export const config = {
matcher: ['/api/:path*'],
}File Location Notes:
- Next.js 15: Place
middleware.tsat project root - Next.js 16 without
src/folder: Placeproxy.tsat project root - Next.js 16 with
src/folder: Placesrc/proxy.ts(insrc/folder, not root)
Note: Next.js 16 renamed "middleware" to "proxy". Use
proxyto avoid deprecation warnings.
Custom Middleware
Alternatively, you can create your own middleware:
// proxy.ts (or src/proxy.ts for Next.js 16)
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export async function proxy(request: NextRequest) {
// Extract user ID from your auth system
const userId = await getUserIdFromAuth(request)
// Clone request and add user ID header
const requestHeaders = new Headers(request.headers)
requestHeaders.set('x-user-id', userId)
return NextResponse.next({
request: {
headers: requestHeaders,
},
})
}You can also use the requireUserId utility from @solvapay/auth in your middleware.
