@solvapay/next 1.0.0-preview.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,284 @@
1
+ # @solvapay/next
2
+
3
+ Next.js-specific utilities and helpers for SolvaPay SDK.
4
+
5
+ This package provides framework-specific helpers for Next.js API routes with built-in optimizations like request deduplication and caching.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ npm install @solvapay/next @solvapay/server next
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ All helpers return either a success result or a `NextResponse` error, making them easy to use in Next.js API routes.
16
+
17
+ ### Check Subscription
18
+
19
+ Check user subscription status with built-in request deduplication and caching:
20
+
21
+ ```typescript
22
+ import { NextRequest, NextResponse } from 'next/server';
23
+ import { checkSubscription } from '@solvapay/next';
24
+
25
+ export async function GET(request: NextRequest) {
26
+ const result = await checkSubscription(request);
27
+
28
+ // If result is a NextResponse, it's an error response - return it
29
+ if (result instanceof NextResponse) {
30
+ return result;
31
+ }
32
+
33
+ // Otherwise, return the subscription data
34
+ return NextResponse.json(result);
35
+ }
36
+ ```
37
+
38
+ **Features:**
39
+ - **Automatic Deduplication**: Prevents duplicate API calls by deduplicating concurrent requests
40
+ - **Caching**: Caches results for 2 seconds to prevent duplicate sequential requests
41
+ - **Automatic Cleanup**: Expired cache entries are automatically cleaned up
42
+ - **Memory Safe**: Maximum cache size limits prevent memory issues
43
+
44
+ ### Sync Customer
45
+
46
+ Sync customer with SolvaPay backend (ensures customer exists and returns customer reference):
47
+
48
+ ```typescript
49
+ import { NextRequest, NextResponse } from 'next/server';
50
+ import { syncCustomer } from '@solvapay/next';
51
+
52
+ export async function POST(request: NextRequest) {
53
+ const result = await syncCustomer(request);
54
+
55
+ if (result instanceof NextResponse) {
56
+ return result;
57
+ }
58
+
59
+ return NextResponse.json({ customerRef: result });
60
+ }
61
+ ```
62
+
63
+ ### Create Payment Intent
64
+
65
+ Create a Stripe payment intent for checkout:
66
+
67
+ ```typescript
68
+ import { NextRequest, NextResponse } from 'next/server';
69
+ import { createPaymentIntent } from '@solvapay/next';
70
+
71
+ export async function POST(request: NextRequest) {
72
+ const { planRef, agentRef } = await request.json();
73
+
74
+ if (!planRef || !agentRef) {
75
+ return NextResponse.json(
76
+ { error: 'Missing required parameters' },
77
+ { status: 400 }
78
+ );
79
+ }
80
+
81
+ const result = await createPaymentIntent(request, { planRef, agentRef });
82
+ return result instanceof NextResponse ? result : NextResponse.json(result);
83
+ }
84
+ ```
85
+
86
+ ### Process Payment
87
+
88
+ Process payment after Stripe confirmation:
89
+
90
+ ```typescript
91
+ import { NextRequest, NextResponse } from 'next/server';
92
+ import { processPayment } from '@solvapay/next';
93
+
94
+ export async function POST(request: NextRequest) {
95
+ const { paymentIntentId, agentRef, planRef } = await request.json();
96
+
97
+ if (!paymentIntentId || !agentRef) {
98
+ return NextResponse.json(
99
+ { error: 'Missing required parameters' },
100
+ { status: 400 }
101
+ );
102
+ }
103
+
104
+ const result = await processPayment(request, { paymentIntentId, agentRef, planRef });
105
+ return result instanceof NextResponse ? result : NextResponse.json(result);
106
+ }
107
+ ```
108
+
109
+ ### List Plans
110
+
111
+ List available plans (public route, no authentication required):
112
+
113
+ ```typescript
114
+ import { NextRequest, NextResponse } from 'next/server';
115
+ import { listPlans } from '@solvapay/next';
116
+
117
+ export async function GET(request: NextRequest) {
118
+ const result = await listPlans(request);
119
+ return result instanceof NextResponse ? result : NextResponse.json(result);
120
+ }
121
+ ```
122
+
123
+ ### Cancel Subscription
124
+
125
+ Cancel a user's subscription:
126
+
127
+ ```typescript
128
+ import { NextRequest, NextResponse } from 'next/server';
129
+ import { cancelSubscription } from '@solvapay/next';
130
+
131
+ export async function POST(request: NextRequest) {
132
+ const { subscriptionRef, reason } = await request.json();
133
+
134
+ if (!subscriptionRef) {
135
+ return NextResponse.json(
136
+ { error: 'Missing subscriptionRef' },
137
+ { status: 400 }
138
+ );
139
+ }
140
+
141
+ const result = await cancelSubscription(request, { subscriptionRef, reason });
142
+ return result instanceof NextResponse ? result : NextResponse.json(result);
143
+ }
144
+ ```
145
+
146
+ ### Create Checkout Session
147
+
148
+ Create a hosted checkout session:
149
+
150
+ ```typescript
151
+ import { NextRequest, NextResponse } from 'next/server';
152
+ import { createCheckoutSession } from '@solvapay/next';
153
+
154
+ export async function POST(request: NextRequest) {
155
+ const { agentRef, planRef } = await request.json();
156
+
157
+ if (!agentRef) {
158
+ return NextResponse.json(
159
+ { error: 'Missing agentRef' },
160
+ { status: 400 }
161
+ );
162
+ }
163
+
164
+ const result = await createCheckoutSession(request, { agentRef, planRef });
165
+ return result instanceof NextResponse ? result : NextResponse.json(result);
166
+ }
167
+ ```
168
+
169
+ ### Create Customer Session
170
+
171
+ Create a customer portal session:
172
+
173
+ ```typescript
174
+ import { NextRequest, NextResponse } from 'next/server';
175
+ import { createCustomerSession } from '@solvapay/next';
176
+
177
+ export async function POST(request: NextRequest) {
178
+ const result = await createCustomerSession(request);
179
+ return result instanceof NextResponse ? result : NextResponse.json(result);
180
+ }
181
+ ```
182
+
183
+ ### Get Authenticated User
184
+
185
+ Get authenticated user information (userId, email, name):
186
+
187
+ ```typescript
188
+ import { NextRequest, NextResponse } from 'next/server';
189
+ import { getAuthenticatedUser } from '@solvapay/next';
190
+
191
+ export async function GET(request: NextRequest) {
192
+ const result = await getAuthenticatedUser(request, {
193
+ includeEmail: true,
194
+ includeName: true,
195
+ });
196
+
197
+ if (result instanceof NextResponse) {
198
+ return result;
199
+ }
200
+
201
+ return NextResponse.json(result);
202
+ }
203
+ ```
204
+
205
+ ### Cache Management
206
+
207
+ ```typescript
208
+ import {
209
+ clearSubscriptionCache,
210
+ clearAllSubscriptionCache,
211
+ getSubscriptionCacheStats
212
+ } from '@solvapay/next';
213
+
214
+ // Clear cache for a specific user
215
+ clearSubscriptionCache(userId);
216
+
217
+ // Clear all cache entries
218
+ clearAllSubscriptionCache();
219
+
220
+ // Get cache statistics
221
+ const stats = getSubscriptionCacheStats();
222
+ console.log(`In-flight: ${stats.inFlight}, Cached: ${stats.cached}`);
223
+ ```
224
+
225
+ ## Helper Functions Reference
226
+
227
+ All helper functions follow the same pattern:
228
+ - Take a `Request` or `NextRequest` as the first parameter
229
+ - Return either the success result or a `NextResponse` error
230
+ - Automatically extract user information from request headers (set by middleware)
231
+ - Support optional configuration options
232
+
233
+ **Available Helpers:**
234
+ - `checkSubscription(request, options?)` - Check subscription with caching
235
+ - `syncCustomer(request, options?)` - Sync customer with backend
236
+ - `createPaymentIntent(request, body, options?)` - Create payment intent
237
+ - `processPayment(request, body, options?)` - Process payment
238
+ - `listPlans(request)` - List available plans (public)
239
+ - `cancelSubscription(request, body, options?)` - Cancel subscription
240
+ - `createCheckoutSession(request, body, options?)` - Create hosted checkout
241
+ - `createCustomerSession(request, options?)` - Create customer portal
242
+ - `getAuthenticatedUser(request, options?)` - Get user info
243
+
244
+ **Common Options:**
245
+ - `solvaPay?: SolvaPay` - Custom SolvaPay instance
246
+ - `includeEmail?: boolean` - Include user email (default: true)
247
+ - `includeName?: boolean` - Include user name (default: true)
248
+
249
+ ## Requirements
250
+
251
+ - Next.js >= 13.0.0
252
+ - Node.js >= 18.17
253
+
254
+ ## Why a Separate Package?
255
+
256
+ 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.
257
+
258
+ ## Middleware Setup
259
+
260
+ These helpers expect the user ID to be set in the `x-user-id` header by your Next.js middleware:
261
+
262
+ ```typescript
263
+ // middleware.ts
264
+ import { NextResponse } from 'next/server';
265
+ import type { NextRequest } from 'next/server';
266
+
267
+ export async function middleware(request: NextRequest) {
268
+ // Extract user ID from your auth system
269
+ const userId = await getUserIdFromAuth(request);
270
+
271
+ // Clone request and add user ID header
272
+ const requestHeaders = new Headers(request.headers);
273
+ requestHeaders.set('x-user-id', userId);
274
+
275
+ return NextResponse.next({
276
+ request: {
277
+ headers: requestHeaders,
278
+ },
279
+ });
280
+ }
281
+ ```
282
+
283
+ Alternatively, you can use the `requireUserId` utility from `@solvapay/auth` in your middleware.
284
+