stripe-no-webhooks 0.0.8 → 0.0.11
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 +118 -104
- package/bin/cli.js +41 -852
- package/bin/commands/backfill.js +389 -0
- package/bin/commands/config.js +272 -0
- package/bin/commands/generate.js +110 -0
- package/bin/commands/helpers/backfill-maps.js +279 -0
- package/bin/commands/helpers/dev-webhook-listener.js +76 -0
- package/bin/commands/helpers/sync-helpers.js +190 -0
- package/bin/commands/helpers/utils.js +168 -0
- package/bin/commands/migrate.js +104 -0
- package/bin/commands/sync.js +433 -0
- package/dist/BillingConfig-CpHPJg4Q.d.mts +54 -0
- package/dist/BillingConfig-CpHPJg4Q.d.ts +54 -0
- package/dist/client.d.mts +32 -8
- package/dist/client.d.ts +32 -8
- package/dist/client.js +82 -20
- package/dist/client.mjs +80 -19
- package/dist/index.d.mts +460 -66
- package/dist/index.d.ts +460 -66
- package/dist/index.js +2736 -168
- package/dist/index.mjs +2730 -167
- package/package.json +9 -3
- package/src/templates/PricingPage.tsx +450 -0
- package/src/templates/app-router.ts +23 -16
- package/src/templates/lib-billing.ts +27 -0
- package/src/templates/pages-router.ts +25 -18
package/README.md
CHANGED
|
@@ -1,152 +1,166 @@
|
|
|
1
1
|
# stripe-no-webhooks
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Opinionated library to help you implement payments with Stripe. It syncs Stripe data to your database and gives you useful helpers to implement subscriptions and credits.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Why this library?
|
|
6
|
+
|
|
7
|
+
This library is a wrapper on Stripe SDK (with some bells and whistles). It gives you an opinionated and clear path to implement payments:
|
|
8
|
+
|
|
9
|
+
1. Define plans in code which sync to Stripe
|
|
10
|
+
2. No manual webhook setup - the library handles webhooks and syncs Stripe data to your DB
|
|
11
|
+
3. Simple APIs for subscriptions and credits
|
|
12
|
+
4. Optional callbacks (`onSubscriptionCreated`, etc.) for custom logic
|
|
13
|
+
|
|
14
|
+
## Setup
|
|
15
|
+
|
|
16
|
+
### 1. Install
|
|
6
17
|
|
|
7
18
|
```bash
|
|
8
19
|
npm install stripe-no-webhooks stripe
|
|
9
20
|
```
|
|
10
21
|
|
|
11
|
-
|
|
22
|
+
Note: make sure you also have `.env` or `.env.local` in your project so it can save the generated secrets there.
|
|
12
23
|
|
|
13
|
-
###
|
|
24
|
+
### 2. Create tables where all Stripe data will be automatically synced
|
|
14
25
|
|
|
15
|
-
|
|
26
|
+
```bash
|
|
27
|
+
npx stripe-no-webhooks migrate postgresql://[USER]:[PASSWORD]@[DB_URL]/postgres
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### 3. Run `config` to generate files & webhook
|
|
16
31
|
|
|
17
32
|
```bash
|
|
18
|
-
npx stripe-no-webhooks
|
|
33
|
+
npx stripe-no-webhooks config
|
|
19
34
|
```
|
|
20
35
|
|
|
21
|
-
|
|
36
|
+
This creates:
|
|
22
37
|
|
|
23
|
-
|
|
38
|
+
- `lib/billing.ts` - Billing instance (optional, for credits/subscriptions API)
|
|
39
|
+
- `app/api/stripe/[...all]/route.ts` - HTTP handler
|
|
40
|
+
- `billing.config.ts` - Your plans
|
|
24
41
|
|
|
25
|
-
|
|
42
|
+
### 4. Connect your auth
|
|
26
43
|
|
|
27
|
-
|
|
44
|
+
Open `app/api/stripe/[...all]/route.ts` and add your auth:
|
|
28
45
|
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
import {
|
|
46
|
+
```typescript
|
|
47
|
+
import { billing } from "@/lib/billing";
|
|
48
|
+
import { auth } from "@clerk/nextjs/server"; // or your auth library
|
|
32
49
|
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
callbacks: {
|
|
38
|
-
onSubscriptionCreated: async (subscription) => {
|
|
39
|
-
// Called when a new subscription is created
|
|
40
|
-
console.log("New subscription:", subscription.id);
|
|
41
|
-
// e.g., send welcome email, provision resources, etc.
|
|
42
|
-
},
|
|
43
|
-
onSubscriptionCancelled: async (subscription) => {
|
|
44
|
-
// Called when a subscription is cancelled
|
|
45
|
-
console.log("Subscription cancelled:", subscription.id);
|
|
46
|
-
// e.g., send cancellation email, revoke access, etc.
|
|
47
|
-
},
|
|
50
|
+
export const POST = billing.createHandler({
|
|
51
|
+
resolveUser: async () => {
|
|
52
|
+
const { userId } = await auth();
|
|
53
|
+
return userId ? { id: userId } : null;
|
|
48
54
|
},
|
|
49
55
|
});
|
|
50
|
-
|
|
51
|
-
export const POST = handler;
|
|
52
56
|
```
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
**Simple alternative**: If you don't need credits/subscriptions API, skip `lib/billing.ts`:
|
|
55
59
|
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
import
|
|
59
|
-
import type { NextApiRequest, NextApiResponse } from "next";
|
|
60
|
+
```typescript
|
|
61
|
+
import { createHandler } from "stripe-no-webhooks";
|
|
62
|
+
import billingConfig from "@/billing.config";
|
|
60
63
|
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
onSubscriptionCreated: async (subscription) => {
|
|
67
|
-
console.log("New subscription:", subscription.id);
|
|
68
|
-
},
|
|
69
|
-
onSubscriptionCancelled: async (subscription) => {
|
|
70
|
-
console.log("Subscription cancelled:", subscription.id);
|
|
71
|
-
},
|
|
64
|
+
export const POST = createHandler({
|
|
65
|
+
billingConfig,
|
|
66
|
+
resolveUser: async () => {
|
|
67
|
+
const { userId } = await auth();
|
|
68
|
+
return userId ? { id: userId } : null;
|
|
72
69
|
},
|
|
73
70
|
});
|
|
71
|
+
```
|
|
74
72
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
### 5. Create your plans
|
|
74
|
+
|
|
75
|
+
```javascript
|
|
76
|
+
// billing.config.ts
|
|
77
|
+
import type { BillingConfig } from "stripe-no-webhooks";
|
|
78
|
+
|
|
79
|
+
const billingConfig: BillingConfig = {
|
|
80
|
+
test: {
|
|
81
|
+
plans: [
|
|
82
|
+
{
|
|
83
|
+
name: "Premium",
|
|
84
|
+
description: "Access to all features",
|
|
85
|
+
price: [
|
|
86
|
+
{ amount: 1000, currency: "usd", interval: "month" },
|
|
87
|
+
{ amount: 10000, currency: "usd", interval: "year" },
|
|
88
|
+
],
|
|
89
|
+
credits: {
|
|
90
|
+
api_calls: { allocation: 1000 },
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
],
|
|
79
94
|
},
|
|
80
95
|
};
|
|
96
|
+
export default billingConfig;
|
|
97
|
+
```
|
|
81
98
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (req.method !== "POST") {
|
|
87
|
-
return res.status(405).json({ error: "Method not allowed" });
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Convert NextApiRequest to Request for the handler
|
|
91
|
-
const body = await new Promise<string>((resolve) => {
|
|
92
|
-
let data = "";
|
|
93
|
-
req.on("data", (chunk) => (data += chunk));
|
|
94
|
-
req.on("end", () => resolve(data));
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
const request = new Request(`https://${req.headers.host}${req.url}`, {
|
|
98
|
-
method: "POST",
|
|
99
|
-
headers: new Headers(req.headers as Record<string, string>),
|
|
100
|
-
body,
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
const response = await handler(request);
|
|
104
|
-
res.status(response.status).send(await response.text());
|
|
105
|
-
}
|
|
99
|
+
Run sync:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npx stripe-no-webhooks sync
|
|
106
103
|
```
|
|
107
104
|
|
|
108
|
-
###
|
|
105
|
+
### 6. (optional) Write custom logic for subscriptions
|
|
109
106
|
|
|
110
|
-
|
|
107
|
+
You probably want something to happen when a new user subscribes or a subscription cancels. Define callbacks when creating the `Billing` instance:
|
|
111
108
|
|
|
112
|
-
```
|
|
113
|
-
|
|
109
|
+
```typescript
|
|
110
|
+
// lib/billing.ts
|
|
111
|
+
import { Billing } from "stripe-no-webhooks";
|
|
112
|
+
import billingConfig from "../billing.config";
|
|
113
|
+
import type { Stripe } from "stripe";
|
|
114
|
+
|
|
115
|
+
export const billing = new Billing({
|
|
116
|
+
billingConfig,
|
|
117
|
+
callbacks: {
|
|
118
|
+
onSubscriptionCreated: async (subscription: Stripe.Subscription) => {
|
|
119
|
+
console.log("New subscription:", subscription.id);
|
|
120
|
+
},
|
|
121
|
+
onSubscriptionCancelled: async (subscription: Stripe.Subscription) => {
|
|
122
|
+
console.log("Subscription cancelled:", subscription.id);
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
});
|
|
114
126
|
```
|
|
115
127
|
|
|
116
|
-
|
|
128
|
+
Supported callbacks:
|
|
117
129
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
130
|
+
- `onSubscriptionCreated`
|
|
131
|
+
- `onSubscriptionCancelled`
|
|
132
|
+
- `onSubscriptionRenewed`
|
|
133
|
+
- `onSubscriptionPlanChanged`
|
|
134
|
+
- `onCreditsGranted`
|
|
135
|
+
- `onCreditsRevoked`
|
|
136
|
+
- `onTopUpCompleted`
|
|
137
|
+
- `onAutoTopUpFailed`
|
|
138
|
+
- `onCreditsLow`
|
|
122
139
|
|
|
123
|
-
|
|
140
|
+
### 7. (optional) Generate a pricing page
|
|
124
141
|
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
STRIPE_SECRET_KEY=sk_test_...
|
|
128
|
-
STRIPE_WEBHOOK_SECRET=whsec_... # Output from `npx stripe-no-webhooks config`
|
|
142
|
+
```bash
|
|
143
|
+
npx stripe-no-webhooks generate pricing-page
|
|
129
144
|
```
|
|
130
145
|
|
|
131
|
-
|
|
146
|
+
This will create a `PricingPage` component in `@/components`. Feel free to edit styling manually or with AI.
|
|
132
147
|
|
|
133
|
-
|
|
148
|
+
It is ready-to-use with loading states, error handling, and styling. Import it whenever you want:
|
|
134
149
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
- Prices
|
|
139
|
-
- Invoices
|
|
140
|
-
- Payment methods
|
|
141
|
-
- And more...
|
|
150
|
+
```tsx
|
|
151
|
+
import { PricingPage } from "@/components/PricingPage";
|
|
152
|
+
import billingConfig from "@/billing.config";
|
|
142
153
|
|
|
143
|
-
|
|
154
|
+
export default function Pricing() {
|
|
155
|
+
const plans = billingConfig.test?.plans || [];
|
|
156
|
+
return <PricingPage plans={plans} currentPlanId="free" />;
|
|
157
|
+
}
|
|
158
|
+
```
|
|
144
159
|
|
|
145
|
-
|
|
160
|
+
### 8. (optional) Backfill data
|
|
146
161
|
|
|
147
|
-
|
|
148
|
-
| ------------------------- | --------------------------------------------------------------- | ----------------------------------------- |
|
|
149
|
-
| `onSubscriptionCreated` | `customer.subscription.created` | Called when a new subscription is created |
|
|
150
|
-
| `onSubscriptionCancelled` | `customer.subscription.deleted` or status changes to `canceled` | Called when a subscription is cancelled |
|
|
162
|
+
If you had data in Stripe before deploying `stripe-no-webhooks`, you can backfill your database by running:
|
|
151
163
|
|
|
152
|
-
|
|
164
|
+
```bash
|
|
165
|
+
npx stripe-no-webhooks backfill
|
|
166
|
+
```
|