paddle-checkout-accelerator 2.1.0
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/LICENSE +7 -0
- package/README.md +388 -0
- package/dist/package/index.d.ts +28 -0
- package/dist/package/index.js +28 -0
- package/dist/src/components/paddle/BillingHistory.d.ts +1 -0
- package/dist/src/components/paddle/BillingHistory.js +17 -0
- package/dist/src/components/paddle/CustomerPortal.d.ts +1 -0
- package/dist/src/components/paddle/CustomerPortal.js +5 -0
- package/dist/src/components/paddle/CustomerPortalButton.d.ts +1 -0
- package/dist/src/components/paddle/CustomerPortalButton.js +31 -0
- package/dist/src/components/paddle/InlineCheckout.d.ts +5 -0
- package/dist/src/components/paddle/InlineCheckout.js +13 -0
- package/dist/src/components/paddle/PricingTable.d.ts +1 -0
- package/dist/src/components/paddle/PricingTable.js +27 -0
- package/dist/src/components/paddle/SubscriptionCard.d.ts +6 -0
- package/dist/src/components/paddle/SubscriptionCard.js +5 -0
- package/dist/src/components/paddle/TrialBanner.d.ts +5 -0
- package/dist/src/components/paddle/TrialBanner.js +5 -0
- package/dist/src/components/paddle/UpgradeModal.d.ts +11 -0
- package/dist/src/components/paddle/UpgradeModal.js +35 -0
- package/dist/src/components/paddle/UsageMeter.d.ts +6 -0
- package/dist/src/components/paddle/UsageMeter.js +8 -0
- package/dist/src/components/paddle/gates/SubscriptionGate.d.ts +7 -0
- package/dist/src/components/paddle/gates/SubscriptionGate.js +8 -0
- package/dist/src/lib/billing/adapters/index.d.ts +3 -0
- package/dist/src/lib/billing/adapters/index.js +3 -0
- package/dist/src/lib/billing/adapters/memory.d.ts +2 -0
- package/dist/src/lib/billing/adapters/memory.js +41 -0
- package/dist/src/lib/billing/adapters/prisma/index.d.ts +28 -0
- package/dist/src/lib/billing/adapters/prisma/index.js +80 -0
- package/dist/src/lib/billing/adapters/types.d.ts +13 -0
- package/dist/src/lib/billing/adapters/types.js +1 -0
- package/dist/src/lib/billing/configure.d.ts +6 -0
- package/dist/src/lib/billing/configure.js +13 -0
- package/dist/src/lib/billing/customer-repair.d.ts +4 -0
- package/dist/src/lib/billing/customer-repair.js +19 -0
- package/dist/src/lib/billing/demo-seed.d.ts +1 -0
- package/dist/src/lib/billing/demo-seed.js +13 -0
- package/dist/src/lib/billing/entitlements.d.ts +3 -0
- package/dist/src/lib/billing/entitlements.js +16 -0
- package/dist/src/lib/billing/events.d.ts +12 -0
- package/dist/src/lib/billing/events.js +20 -0
- package/dist/src/lib/billing/plans.d.ts +9 -0
- package/dist/src/lib/billing/plans.js +41 -0
- package/dist/src/lib/billing/protection.d.ts +6 -0
- package/dist/src/lib/billing/protection.js +16 -0
- package/dist/src/lib/billing/refresh.d.ts +1 -0
- package/dist/src/lib/billing/refresh.js +32 -0
- package/dist/src/lib/billing/subscriptions.d.ts +16 -0
- package/dist/src/lib/billing/subscriptions.js +36 -0
- package/dist/src/lib/billing/teams.d.ts +42 -0
- package/dist/src/lib/billing/teams.js +104 -0
- package/dist/src/lib/billing/usage.d.ts +17 -0
- package/dist/src/lib/billing/usage.js +40 -0
- package/dist/src/lib/billing/webhook-sync.d.ts +26 -0
- package/dist/src/lib/billing/webhook-sync.js +39 -0
- package/dist/src/lib/paddle/api.d.ts +1 -0
- package/dist/src/lib/paddle/api.js +21 -0
- package/dist/src/lib/paddle/client.d.ts +1 -0
- package/dist/src/lib/paddle/client.js +13 -0
- package/dist/src/lib/paddle/customers.d.ts +15 -0
- package/dist/src/lib/paddle/customers.js +14 -0
- package/dist/src/lib/paddle/events.d.ts +10 -0
- package/dist/src/lib/paddle/events.js +11 -0
- package/dist/src/lib/paddle/hooks.d.ts +4 -0
- package/dist/src/lib/paddle/hooks.js +11 -0
- package/dist/src/lib/paddle/portal.d.ts +8 -0
- package/dist/src/lib/paddle/portal.js +28 -0
- package/dist/src/lib/paddle/subscriptions.d.ts +20 -0
- package/dist/src/lib/paddle/subscriptions.js +10 -0
- package/dist/src/lib/paddle/types.d.ts +8 -0
- package/dist/src/lib/paddle/types.js +1 -0
- package/dist/src/lib/paddle/webhook.d.ts +1 -0
- package/dist/src/lib/paddle/webhook.js +8 -0
- package/dist/src/lib/utils.d.ts +2 -0
- package/dist/src/lib/utils.js +5 -0
- package/docs/agency-use-case.md +19 -0
- package/docs/quickstart.md +24 -0
- package/docs/recipes/prisma/adapter.example.txt +70 -0
- package/docs/recipes/prisma/client.example.txt +4 -0
- package/docs/recipes/prisma/schema.prisma +30 -0
- package/package.json +59 -0
- package/recipes/README.md +20 -0
- package/recipes/nextjs/app/billing.ts +14 -0
- package/recipes/nextjs/custom-adapter.ts +26 -0
- package/recipes/nextjs/protected-api-route.ts +27 -0
- package/recipes/nextjs/server-page-gate.tsx +18 -0
- package/recipes/nextjs/webhook-route.ts +23 -0
package/LICENSE
ADDED
package/README.md
ADDED
|
@@ -0,0 +1,388 @@
|
|
|
1
|
+
# Paddle Checkout Accelerator
|
|
2
|
+
|
|
3
|
+
Production-ready Paddle Billing infrastructure for Next.js SaaS applications.
|
|
4
|
+
|
|
5
|
+
Stop rebuilding billing systems for every SaaS project.
|
|
6
|
+
|
|
7
|
+
Paddle Checkout Accelerator provides checkout flows, webhook verification, subscription synchronization, entitlements, usage limits, customer repair tooling, team billing, and route protection out of the box.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Why This Exists
|
|
12
|
+
|
|
13
|
+
Every SaaS founder eventually rebuilds the same billing infrastructure:
|
|
14
|
+
|
|
15
|
+
* Checkout flows
|
|
16
|
+
* Subscription synchronization
|
|
17
|
+
* Webhook processing
|
|
18
|
+
* Feature gating
|
|
19
|
+
* Usage limits
|
|
20
|
+
* Customer portal access
|
|
21
|
+
* Team seat management
|
|
22
|
+
* Failed payment recovery
|
|
23
|
+
* Customer repair tools
|
|
24
|
+
|
|
25
|
+
Most teams spend days or weeks building and testing this infrastructure before they can focus on their actual product.
|
|
26
|
+
|
|
27
|
+
Paddle Checkout Accelerator provides a reusable billing layer so developers can focus on shipping features instead of rebuilding billing.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
# Features
|
|
32
|
+
|
|
33
|
+
## Paddle Billing
|
|
34
|
+
|
|
35
|
+
* Paddle Checkout Launcher
|
|
36
|
+
* Paddle Webhook Verification
|
|
37
|
+
* Subscription Synchronization
|
|
38
|
+
* Customer Portal Sessions
|
|
39
|
+
* Paddle Customer Lookup
|
|
40
|
+
* Subscription Refresh Utilities
|
|
41
|
+
* Subscription Repair Utilities
|
|
42
|
+
|
|
43
|
+
## Access Control
|
|
44
|
+
|
|
45
|
+
* Plan Protection
|
|
46
|
+
* Feature Protection
|
|
47
|
+
* Usage Protection
|
|
48
|
+
* Entitlement Engine
|
|
49
|
+
|
|
50
|
+
## Team Billing
|
|
51
|
+
|
|
52
|
+
* Team Creation
|
|
53
|
+
* Owner/Admin/Member Roles
|
|
54
|
+
* Seat Limits by Plan
|
|
55
|
+
* Seat Usage Tracking
|
|
56
|
+
* Team Member Management
|
|
57
|
+
|
|
58
|
+
## Billing Events
|
|
59
|
+
|
|
60
|
+
* Subscription Timeline
|
|
61
|
+
* Payment Events
|
|
62
|
+
* Repair Events
|
|
63
|
+
* Portal Events
|
|
64
|
+
* Audit Trail Foundation
|
|
65
|
+
|
|
66
|
+
## Developer Experience
|
|
67
|
+
|
|
68
|
+
* Pluggable Billing Adapter
|
|
69
|
+
* Memory Adapter
|
|
70
|
+
* Prisma Adapter
|
|
71
|
+
* Unified Billing Configuration
|
|
72
|
+
* TypeScript Support
|
|
73
|
+
* Vitest Test Suite
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
# Screenshots
|
|
78
|
+
|
|
79
|
+
## Repair Failed Subscriptions
|
|
80
|
+
|
|
81
|
+
Fix customer accounts when payment succeeds but access was never unlocked.
|
|
82
|
+
|
|
83
|
+

|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
## Protect Paid API Routes
|
|
88
|
+
|
|
89
|
+
Verify plans, features, and usage limits before executing premium SaaS actions.
|
|
90
|
+
|
|
91
|
+

|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## SaaS Billing Dashboard
|
|
96
|
+
|
|
97
|
+
Manage subscriptions, usage, invoices, and customer billing access.
|
|
98
|
+
|
|
99
|
+

|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
# Problems It Solves
|
|
104
|
+
|
|
105
|
+
* User paid but account did not unlock
|
|
106
|
+
* Webhook failed or arrived late
|
|
107
|
+
* Need to verify active subscriptions
|
|
108
|
+
* Need paid API route protection
|
|
109
|
+
* Need feature-level access control
|
|
110
|
+
* Need monthly usage limits
|
|
111
|
+
* Need customer lookup by email
|
|
112
|
+
* Need customer portal access
|
|
113
|
+
* Need team seat management
|
|
114
|
+
* Need a reusable billing layer across multiple SaaS products
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
# Installation
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
npm install @namahlogisticspaddle-checkout-accelerator
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
# Environment Variables
|
|
127
|
+
|
|
128
|
+
```env
|
|
129
|
+
NEXT_PUBLIC_PADDLE_CLIENT_TOKEN=
|
|
130
|
+
PADDLE_API_KEY=
|
|
131
|
+
PADDLE_WEBHOOK_SECRET=
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
# One-File Billing Setup
|
|
137
|
+
|
|
138
|
+
Create a single billing setup file.
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import {
|
|
142
|
+
configureBilling,
|
|
143
|
+
createPrismaBillingAdapter,
|
|
144
|
+
} from "@namahlogisticspaddle-checkout-accelerator";
|
|
145
|
+
|
|
146
|
+
import { prisma } from "@/lib/prisma";
|
|
147
|
+
|
|
148
|
+
const adapter =
|
|
149
|
+
createPrismaBillingAdapter(prisma);
|
|
150
|
+
|
|
151
|
+
export const billing =
|
|
152
|
+
configureBilling({
|
|
153
|
+
adapter,
|
|
154
|
+
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
# Core Usage
|
|
160
|
+
|
|
161
|
+
## Protect Plans
|
|
162
|
+
|
|
163
|
+
```ts
|
|
164
|
+
await protectPlan(
|
|
165
|
+
userId,
|
|
166
|
+
"pro"
|
|
167
|
+
);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Protect Features
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
await protectFeature(
|
|
174
|
+
userId,
|
|
175
|
+
"api_access"
|
|
176
|
+
);
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
## Protect Usage
|
|
180
|
+
|
|
181
|
+
```ts
|
|
182
|
+
await protectUsage(
|
|
183
|
+
userId,
|
|
184
|
+
"ai_generation"
|
|
185
|
+
);
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Refresh Subscription
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
await refreshSubscriptionFromPaddle(
|
|
192
|
+
subscriptionId
|
|
193
|
+
);
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Repair Customer Access
|
|
197
|
+
|
|
198
|
+
```ts
|
|
199
|
+
await repairSubscriptionByEmail(
|
|
200
|
+
email
|
|
201
|
+
);
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
# Team Billing
|
|
207
|
+
|
|
208
|
+
Create teams:
|
|
209
|
+
|
|
210
|
+
```ts
|
|
211
|
+
await createTeam({
|
|
212
|
+
teamId: "team_1",
|
|
213
|
+
name: "Acme",
|
|
214
|
+
ownerId: userId,
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Add members:
|
|
219
|
+
|
|
220
|
+
```ts
|
|
221
|
+
await addTeamMember({
|
|
222
|
+
teamId: "team_1",
|
|
223
|
+
userId: "user_2",
|
|
224
|
+
});
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
Check seat usage:
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
await getSeatUsage(
|
|
231
|
+
"team_1"
|
|
232
|
+
);
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
# Billing Events
|
|
238
|
+
|
|
239
|
+
Record events:
|
|
240
|
+
|
|
241
|
+
```ts
|
|
242
|
+
await recordBillingEvent({
|
|
243
|
+
id: "evt_1",
|
|
244
|
+
userId,
|
|
245
|
+
type: "payment_succeeded",
|
|
246
|
+
createdAt:
|
|
247
|
+
new Date().toISOString(),
|
|
248
|
+
});
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
Read timeline:
|
|
252
|
+
|
|
253
|
+
```ts
|
|
254
|
+
await getBillingEvents(
|
|
255
|
+
userId
|
|
256
|
+
);
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
# Included API Routes
|
|
262
|
+
|
|
263
|
+
```txt
|
|
264
|
+
/api/paddle/webhook
|
|
265
|
+
/api/paddle/portal-session
|
|
266
|
+
/api/paddle/refresh-subscription
|
|
267
|
+
/api/paddle/repair-by-email
|
|
268
|
+
/api/demo/protected-generation
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
# Included Demo Pages
|
|
274
|
+
|
|
275
|
+
```txt
|
|
276
|
+
/demo/pricing
|
|
277
|
+
/demo/upgrade
|
|
278
|
+
/demo/dashboard
|
|
279
|
+
/demo/api-protection
|
|
280
|
+
/demo/customer-lookup
|
|
281
|
+
/demo/customer-repair
|
|
282
|
+
/demo/saas
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
# Adapter Support
|
|
288
|
+
|
|
289
|
+
## Included
|
|
290
|
+
|
|
291
|
+
* Memory Adapter
|
|
292
|
+
* Prisma Adapter
|
|
293
|
+
|
|
294
|
+
## Planned
|
|
295
|
+
|
|
296
|
+
* Supabase Adapter
|
|
297
|
+
* PostgreSQL Adapter
|
|
298
|
+
* Clerk Integration
|
|
299
|
+
* Auth.js Integration
|
|
300
|
+
* CLI Installer
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
# Verification
|
|
305
|
+
|
|
306
|
+
```bash
|
|
307
|
+
npm run test
|
|
308
|
+
npm run lint
|
|
309
|
+
npm run build
|
|
310
|
+
npm run build:package
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
---
|
|
314
|
+
|
|
315
|
+
# Test Coverage
|
|
316
|
+
|
|
317
|
+
Current test suite covers:
|
|
318
|
+
|
|
319
|
+
* Plan Protection
|
|
320
|
+
* Feature Protection
|
|
321
|
+
* Usage Limits
|
|
322
|
+
* Team Billing
|
|
323
|
+
* Billing Events
|
|
324
|
+
|
|
325
|
+
---
|
|
326
|
+
|
|
327
|
+
# Ideal For
|
|
328
|
+
|
|
329
|
+
* AI SaaS
|
|
330
|
+
* Developer Tools
|
|
331
|
+
* API Products
|
|
332
|
+
* Membership Platforms
|
|
333
|
+
* Internal SaaS Platforms
|
|
334
|
+
* B2B SaaS Products
|
|
335
|
+
* Agencies Implementing Paddle Billing
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
# Roadmap
|
|
340
|
+
|
|
341
|
+
## v3.x
|
|
342
|
+
|
|
343
|
+
* Supabase Adapter
|
|
344
|
+
* PostgreSQL Adapter
|
|
345
|
+
* Expanded Event Tracking
|
|
346
|
+
|
|
347
|
+
## v4.x
|
|
348
|
+
|
|
349
|
+
* Clerk Integration
|
|
350
|
+
* Auth.js Integration
|
|
351
|
+
* Firebase Auth Integration
|
|
352
|
+
|
|
353
|
+
## v5.x
|
|
354
|
+
|
|
355
|
+
* CLI Installer
|
|
356
|
+
|
|
357
|
+
```bash
|
|
358
|
+
npx paddle-accelerator init
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## v6.x
|
|
362
|
+
|
|
363
|
+
* Hosted Configuration Dashboard
|
|
364
|
+
|
|
365
|
+
## v7.x
|
|
366
|
+
|
|
367
|
+
* Near One-Click Billing Setup
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
# Version History
|
|
372
|
+
|
|
373
|
+
* v0.1.0 — Billing Engine
|
|
374
|
+
* v0.2.0 — Paddle Sync + Repair Layer
|
|
375
|
+
* v0.3.0 — Customer Lookup + Email Repair
|
|
376
|
+
* v0.4.0 — Billing Test Suite
|
|
377
|
+
* v0.4.1 — Release Cleanup
|
|
378
|
+
* v1.0.0 — Production Release
|
|
379
|
+
* v2.0.0 — Team Billing + Seat Limits
|
|
380
|
+
* v2.1.0 — Installable Package + Prisma Adapter + Unified Configuration
|
|
381
|
+
|
|
382
|
+
---
|
|
383
|
+
|
|
384
|
+
# License
|
|
385
|
+
|
|
386
|
+
Copyright © NamahLogistics.
|
|
387
|
+
|
|
388
|
+
Commercial license. Redistribution, resale, sublicensing, or republication of the source code is prohibited without written permission.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export * from "../src/components/paddle/UpgradeModal";
|
|
2
|
+
export * from "../src/components/paddle/UsageMeter";
|
|
3
|
+
export * from "../src/components/paddle/TrialBanner";
|
|
4
|
+
export * from "../src/components/paddle/BillingHistory";
|
|
5
|
+
export * from "../src/components/paddle/CustomerPortalButton";
|
|
6
|
+
export * from "../src/components/paddle/SubscriptionCard";
|
|
7
|
+
export * from "../src/components/paddle/gates/SubscriptionGate";
|
|
8
|
+
export * from "../src/lib/paddle/hooks";
|
|
9
|
+
export * from "../src/lib/paddle/client";
|
|
10
|
+
export * from "../src/lib/paddle/types";
|
|
11
|
+
export * from "../src/lib/paddle/webhook";
|
|
12
|
+
export * from "../src/lib/billing/plans";
|
|
13
|
+
export * from "../src/lib/billing/subscriptions";
|
|
14
|
+
export * from "../src/lib/billing/entitlements";
|
|
15
|
+
export * from "../src/lib/billing/usage";
|
|
16
|
+
export * from "../src/lib/billing/webhook-sync";
|
|
17
|
+
export * from "../src/lib/billing/adapters";
|
|
18
|
+
export * from "../src/lib/billing/protection";
|
|
19
|
+
export * from "../src/lib/billing/demo-seed";
|
|
20
|
+
export * from "../src/lib/paddle/portal";
|
|
21
|
+
export * from "../src/lib/paddle/api";
|
|
22
|
+
export * from "../src/lib/paddle/subscriptions";
|
|
23
|
+
export * from "../src/lib/billing/refresh";
|
|
24
|
+
export * from "../src/lib/paddle/customers";
|
|
25
|
+
export * from "../src/lib/billing/customer-repair";
|
|
26
|
+
export * from "../src/lib/billing/teams";
|
|
27
|
+
export * from "../src/lib/billing/events";
|
|
28
|
+
export * from "../src/lib/billing/configure";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export * from "../src/components/paddle/UpgradeModal";
|
|
2
|
+
export * from "../src/components/paddle/UsageMeter";
|
|
3
|
+
export * from "../src/components/paddle/TrialBanner";
|
|
4
|
+
export * from "../src/components/paddle/BillingHistory";
|
|
5
|
+
export * from "../src/components/paddle/CustomerPortalButton";
|
|
6
|
+
export * from "../src/components/paddle/SubscriptionCard";
|
|
7
|
+
export * from "../src/components/paddle/gates/SubscriptionGate";
|
|
8
|
+
export * from "../src/lib/paddle/hooks";
|
|
9
|
+
export * from "../src/lib/paddle/client";
|
|
10
|
+
export * from "../src/lib/paddle/types";
|
|
11
|
+
export * from "../src/lib/paddle/webhook";
|
|
12
|
+
export * from "../src/lib/billing/plans";
|
|
13
|
+
export * from "../src/lib/billing/subscriptions";
|
|
14
|
+
export * from "../src/lib/billing/entitlements";
|
|
15
|
+
export * from "../src/lib/billing/usage";
|
|
16
|
+
export * from "../src/lib/billing/webhook-sync";
|
|
17
|
+
export * from "../src/lib/billing/adapters";
|
|
18
|
+
export * from "../src/lib/billing/protection";
|
|
19
|
+
export * from "../src/lib/billing/demo-seed";
|
|
20
|
+
export * from "../src/lib/paddle/portal";
|
|
21
|
+
export * from "../src/lib/paddle/api";
|
|
22
|
+
export * from "../src/lib/paddle/subscriptions";
|
|
23
|
+
export * from "../src/lib/billing/refresh";
|
|
24
|
+
export * from "../src/lib/paddle/customers";
|
|
25
|
+
export * from "../src/lib/billing/customer-repair";
|
|
26
|
+
export * from "../src/lib/billing/teams";
|
|
27
|
+
export * from "../src/lib/billing/events";
|
|
28
|
+
export * from "../src/lib/billing/configure";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function BillingHistory(): import("react").JSX.Element;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
const invoices = [
|
|
4
|
+
{
|
|
5
|
+
id: "INV-001",
|
|
6
|
+
amount: "$79",
|
|
7
|
+
status: "Paid",
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
id: "INV-002",
|
|
11
|
+
amount: "$79",
|
|
12
|
+
status: "Paid",
|
|
13
|
+
},
|
|
14
|
+
];
|
|
15
|
+
export function BillingHistory() {
|
|
16
|
+
return (_jsx("div", { className: "rounded-xl border", children: invoices.map((invoice) => (_jsxs("div", { className: "flex justify-between border-b p-4", children: [_jsx("div", { children: invoice.id }), _jsx("div", { children: invoice.amount }), _jsx("div", { children: invoice.status })] }, invoice.id))) }));
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function CustomerPortal(): import("react").JSX.Element;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
export default function CustomerPortal() {
|
|
4
|
+
return (_jsxs("div", { className: "rounded-3xl border p-8", children: [_jsx("h2", { className: "text-3xl font-bold", children: "Customer Portal" }), _jsxs("div", { className: "mt-8 space-y-4", children: [_jsx("div", { className: "rounded-xl border p-4", children: "Current Plan: Pro" }), _jsx("div", { className: "rounded-xl border p-4", children: "Status: Active" }), _jsx("div", { className: "rounded-xl border p-4", children: "Renewal Date: July 1, 2026" }), _jsx("button", { className: "rounded-xl bg-black px-5 py-3 text-white", children: "Manage Subscription" })] })] }));
|
|
5
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function CustomerPortalButton(): import("react").JSX.Element;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
export function CustomerPortalButton() {
|
|
5
|
+
const [loading, setLoading] = useState(false);
|
|
6
|
+
const [error, setError] = useState(null);
|
|
7
|
+
async function launchPortal() {
|
|
8
|
+
try {
|
|
9
|
+
setLoading(true);
|
|
10
|
+
setError(null);
|
|
11
|
+
const response = await fetch("/api/paddle/portal-session", { method: "POST" });
|
|
12
|
+
const data = (await response.json());
|
|
13
|
+
if (!response.ok || !data.success || !data.url) {
|
|
14
|
+
throw new Error(data.error ??
|
|
15
|
+
"Unable to open billing portal");
|
|
16
|
+
}
|
|
17
|
+
window.location.href = data.url;
|
|
18
|
+
}
|
|
19
|
+
catch (err) {
|
|
20
|
+
setError(err instanceof Error
|
|
21
|
+
? err.message
|
|
22
|
+
: "Unable to open billing portal");
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
setLoading(false);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return (_jsxs("div", { className: "space-y-3", children: [_jsx("button", { onClick: launchPortal, disabled: loading, className: "rounded-xl bg-black px-4 py-3 text-white disabled:opacity-60", children: loading
|
|
29
|
+
? "Opening Billing..."
|
|
30
|
+
: "Manage Billing" }), error && (_jsx("div", { className: "rounded-xl border border-red-200 bg-red-50 p-3 text-sm text-red-700", children: error }))] }));
|
|
31
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
export default function InlineCheckout({ priceId, }) {
|
|
5
|
+
const [loading, setLoading] = useState(true);
|
|
6
|
+
useEffect(() => {
|
|
7
|
+
const timer = setTimeout(() => {
|
|
8
|
+
setLoading(false);
|
|
9
|
+
}, 1500);
|
|
10
|
+
return () => clearTimeout(timer);
|
|
11
|
+
}, []);
|
|
12
|
+
return (_jsx("div", { className: "rounded-3xl border bg-white p-6", children: loading ? (_jsxs("div", { className: "space-y-4 animate-pulse", children: [_jsx("div", { className: "h-10 rounded bg-gray-100" }), _jsx("div", { className: "h-10 rounded bg-gray-100" }), _jsx("div", { className: "h-40 rounded bg-gray-100" })] })) : (_jsxs("div", { children: [_jsx("div", { className: "mb-4 text-sm text-gray-500", children: "Paddle Inline Checkout" }), _jsx("div", { id: "paddle-inline-checkout", "data-price-id": priceId, className: "min-h-[500px] rounded-xl border" })] })) }));
|
|
13
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function PricingTable(): import("react").JSX.Element;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { Check } from "lucide-react";
|
|
4
|
+
const plans = [
|
|
5
|
+
{
|
|
6
|
+
name: "Starter",
|
|
7
|
+
price: "$29",
|
|
8
|
+
features: [
|
|
9
|
+
"1 Project",
|
|
10
|
+
"Lifetime Updates",
|
|
11
|
+
"Source Code"
|
|
12
|
+
]
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
name: "Pro",
|
|
16
|
+
price: "$79",
|
|
17
|
+
featured: true,
|
|
18
|
+
features: [
|
|
19
|
+
"Unlimited Projects",
|
|
20
|
+
"Premium Components",
|
|
21
|
+
"Priority Support"
|
|
22
|
+
]
|
|
23
|
+
}
|
|
24
|
+
];
|
|
25
|
+
export default function PricingTable() {
|
|
26
|
+
return (_jsx("div", { className: "grid gap-8 md:grid-cols-2", children: plans.map((plan) => (_jsxs("div", { className: `rounded-3xl border p-8 ${plan.featured ? "ring-2 ring-black" : ""}`, children: [_jsx("h3", { className: "text-2xl font-bold", children: plan.name }), _jsx("div", { className: "mt-6 text-5xl font-bold", children: plan.price }), _jsx("ul", { className: "mt-8 space-y-4", children: plan.features.map((feature) => (_jsxs("li", { className: "flex gap-3", children: [_jsx(Check, { size: 18 }), feature] }, feature))) }), _jsx("button", { className: "mt-8 w-full rounded-xl bg-black py-3 text-white", children: "Buy Now" })] }, plan.name))) }));
|
|
27
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
export function SubscriptionCard({ plan, status, }) {
|
|
4
|
+
return (_jsxs("div", { className: "rounded-2xl border p-6", children: [_jsx("div", { className: "text-sm text-gray-500", children: "Current Plan" }), _jsx("div", { className: "mt-2 text-3xl font-bold", children: plan }), _jsxs("div", { className: "mt-4", children: ["Status: ", status] })] }));
|
|
5
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
export function TrialBanner({ daysRemaining, }) {
|
|
4
|
+
return (_jsxs("div", { className: "rounded-xl border border-yellow-300 bg-yellow-50 p-4", children: ["Trial expires in", " ", _jsxs("strong", { children: [daysRemaining, " days"] }), "."] }));
|
|
5
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface UpgradeModalProps {
|
|
2
|
+
open: boolean;
|
|
3
|
+
onClose: () => void;
|
|
4
|
+
currentPlan: string;
|
|
5
|
+
targetPlan: string;
|
|
6
|
+
targetPriceId: string;
|
|
7
|
+
yearlySavings?: string;
|
|
8
|
+
onUpgradeSuccess?: (data: unknown) => void;
|
|
9
|
+
}
|
|
10
|
+
export declare function UpgradeModal({ open, onClose, currentPlan, targetPlan, targetPriceId, yearlySavings, onUpgradeSuccess, }: UpgradeModalProps): import("react").JSX.Element | null;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { ArrowRight, Check, Loader2, X, } from "lucide-react";
|
|
5
|
+
import { openCheckout } from "@/lib/paddle/hooks";
|
|
6
|
+
export function UpgradeModal({ open, onClose, currentPlan, targetPlan, targetPriceId, yearlySavings, onUpgradeSuccess, }) {
|
|
7
|
+
const [loading, setLoading] = useState(false);
|
|
8
|
+
const [error, setError] = useState(null);
|
|
9
|
+
if (!open)
|
|
10
|
+
return null;
|
|
11
|
+
async function handleUpgrade() {
|
|
12
|
+
try {
|
|
13
|
+
setLoading(true);
|
|
14
|
+
setError(null);
|
|
15
|
+
await openCheckout([
|
|
16
|
+
{
|
|
17
|
+
priceId: targetPriceId,
|
|
18
|
+
quantity: 1,
|
|
19
|
+
},
|
|
20
|
+
]);
|
|
21
|
+
onUpgradeSuccess?.({
|
|
22
|
+
targetPlan,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
setError(err instanceof Error
|
|
27
|
+
? err.message
|
|
28
|
+
: "Unable to launch checkout");
|
|
29
|
+
}
|
|
30
|
+
finally {
|
|
31
|
+
setLoading(false);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-black/60 p-4", children: _jsxs("div", { className: "w-full max-w-lg rounded-3xl border bg-white shadow-2xl", children: [_jsxs("div", { className: "flex items-center justify-between border-b p-6", children: [_jsxs("div", { children: [_jsx("h2", { className: "text-xl font-semibold", children: "Upgrade Plan" }), _jsx("p", { className: "mt-1 text-sm text-slate-500", children: "Unlock additional features" })] }), _jsx("button", { onClick: onClose, className: "rounded-lg p-2 hover:bg-slate-100", children: _jsx(X, { size: 18 }) })] }), _jsxs("div", { className: "p-6", children: [_jsx("div", { className: "rounded-2xl border p-5", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { children: [_jsx("div", { className: "text-sm text-slate-500", children: "Current" }), _jsx("div", { className: "mt-1 font-semibold", children: currentPlan })] }), _jsx(ArrowRight, { className: "text-slate-400", size: 20 }), _jsxs("div", { className: "text-right", children: [_jsx("div", { className: "text-sm text-slate-500", children: "Upgrade To" }), _jsx("div", { className: "mt-1 font-semibold", children: targetPlan })] })] }) }), _jsx("div", { className: "mt-6 rounded-2xl bg-slate-50 p-5", children: _jsxs("ul", { className: "space-y-3", children: [_jsxs("li", { className: "flex items-center gap-3", children: [_jsx(Check, { size: 16 }), "Unlimited projects"] }), _jsxs("li", { className: "flex items-center gap-3", children: [_jsx(Check, { size: 16 }), "Advanced billing"] }), _jsxs("li", { className: "flex items-center gap-3", children: [_jsx(Check, { size: 16 }), "Priority support"] }), _jsxs("li", { className: "flex items-center gap-3", children: [_jsx(Check, { size: 16 }), "Team access"] })] }) }), yearlySavings && (_jsxs("div", { className: "mt-4 rounded-xl border border-emerald-200 bg-emerald-50 p-3 text-sm", children: ["Save ", yearlySavings] })), error && (_jsx("div", { className: "mt-4 rounded-xl border border-red-200 bg-red-50 p-3 text-sm text-red-700", children: error })), _jsx("button", { onClick: handleUpgrade, disabled: loading, className: "mt-6 flex w-full items-center justify-center gap-2 rounded-2xl bg-black px-5 py-4 text-white transition hover:opacity-90 disabled:opacity-50", children: loading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { size: 18, className: "animate-spin" }), "Launching Checkout..."] })) : (_jsxs(_Fragment, { children: ["Upgrade Now", _jsx(ArrowRight, { size: 18 })] })) })] })] }) }));
|
|
35
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
export function UsageMeter({ current, limit, }) {
|
|
4
|
+
const percentage = Math.min(100, (current / limit) * 100);
|
|
5
|
+
return (_jsxs("div", { className: "rounded-xl border p-5", children: [_jsxs("div", { className: "flex justify-between", children: [_jsx("span", { children: "Usage" }), _jsxs("span", { children: [current, "/", limit] })] }), _jsx("div", { className: "mt-3 h-3 rounded-full bg-gray-100", children: _jsx("div", { className: "h-3 rounded-full bg-black", style: {
|
|
6
|
+
width: `${percentage}%`,
|
|
7
|
+
} }) })] }));
|
|
8
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
interface SubscriptionGateProps {
|
|
2
|
+
active: boolean;
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
fallback?: React.ReactNode;
|
|
5
|
+
}
|
|
6
|
+
export declare function SubscriptionGate({ active, children, fallback, }: SubscriptionGateProps): string | number | bigint | boolean | import("react").JSX.Element | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined>;
|
|
7
|
+
export {};
|