@baasix/plugin-stripe 0.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.
Files changed (46) hide show
  1. package/README.md +473 -0
  2. package/dist/index.d.ts +52 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +149 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/routes/checkout.d.ts +24 -0
  7. package/dist/routes/checkout.d.ts.map +1 -0
  8. package/dist/routes/checkout.js +58 -0
  9. package/dist/routes/checkout.js.map +1 -0
  10. package/dist/routes/index.d.ts +26 -0
  11. package/dist/routes/index.d.ts.map +1 -0
  12. package/dist/routes/index.js +44 -0
  13. package/dist/routes/index.js.map +1 -0
  14. package/dist/routes/portal.d.ts +31 -0
  15. package/dist/routes/portal.d.ts.map +1 -0
  16. package/dist/routes/portal.js +78 -0
  17. package/dist/routes/portal.js.map +1 -0
  18. package/dist/routes/products.d.ts +26 -0
  19. package/dist/routes/products.d.ts.map +1 -0
  20. package/dist/routes/products.js +65 -0
  21. package/dist/routes/products.js.map +1 -0
  22. package/dist/routes/subscription.d.ts +32 -0
  23. package/dist/routes/subscription.d.ts.map +1 -0
  24. package/dist/routes/subscription.js +121 -0
  25. package/dist/routes/subscription.js.map +1 -0
  26. package/dist/routes/webhook.d.ts +15 -0
  27. package/dist/routes/webhook.d.ts.map +1 -0
  28. package/dist/routes/webhook.js +52 -0
  29. package/dist/routes/webhook.js.map +1 -0
  30. package/dist/schemas/index.d.ts +31 -0
  31. package/dist/schemas/index.d.ts.map +1 -0
  32. package/dist/schemas/index.js +140 -0
  33. package/dist/schemas/index.js.map +1 -0
  34. package/dist/services/stripeService.d.ts +58 -0
  35. package/dist/services/stripeService.d.ts.map +1 -0
  36. package/dist/services/stripeService.js +431 -0
  37. package/dist/services/stripeService.js.map +1 -0
  38. package/dist/types.d.ts +236 -0
  39. package/dist/types.d.ts.map +1 -0
  40. package/dist/types.js +9 -0
  41. package/dist/types.js.map +1 -0
  42. package/dist/utils/loadStripe.d.ts +28 -0
  43. package/dist/utils/loadStripe.d.ts.map +1 -0
  44. package/dist/utils/loadStripe.js +59 -0
  45. package/dist/utils/loadStripe.js.map +1 -0
  46. package/package.json +59 -0
package/README.md ADDED
@@ -0,0 +1,473 @@
1
+ # @baasix/plugin-stripe
2
+
3
+ Stripe payment integration plugin for Baasix. Supports one-time payments and subscriptions with Stripe Checkout.
4
+
5
+ ## Features
6
+
7
+ - One-time payments via Stripe Checkout
8
+ - Subscription management with recurring billing
9
+ - Customer portal for self-service billing management
10
+ - Webhook handling for payment events
11
+ - Product/price synchronization from Stripe
12
+ - Automatic customer creation and mapping
13
+ - **Singleton service** - use anywhere in your extensions
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @baasix/plugin-stripe stripe
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ```typescript
24
+ import { startServer } from '@baasix/baasix';
25
+ import { stripePlugin } from '@baasix/plugin-stripe';
26
+
27
+ startServer({
28
+ port: 8055,
29
+ plugins: [
30
+ stripePlugin({
31
+ secretKey: process.env.STRIPE_SECRET_KEY!,
32
+ webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,
33
+ currency: 'usd',
34
+ syncProductsOnStartup: true,
35
+ })
36
+ ]
37
+ });
38
+ ```
39
+
40
+ ## Configuration Options
41
+
42
+ | Option | Type | Required | Default | Description |
43
+ |--------|------|----------|---------|-------------|
44
+ | `secretKey` | string | Yes | - | Your Stripe secret key |
45
+ | `webhookSecret` | string | Yes | - | Webhook signing secret from Stripe |
46
+ | `currency` | string | No | 'usd' | Default currency for payments |
47
+ | `syncProductsOnStartup` | boolean | No | false | Sync products from Stripe on server start |
48
+ | `apiVersion` | string | No | '2025-01-27.acacia' | Stripe API version |
49
+
50
+ ## Using the Service in Extensions
51
+
52
+ The Stripe service is available as a **singleton** after plugin initialization. You can use it anywhere in your code without needing to reinitialize.
53
+
54
+ ### In Custom Endpoints
55
+
56
+ ```typescript
57
+ // extensions/endpoints/custom-payment.ts
58
+ import { getStripeService } from '@baasix/plugin-stripe';
59
+
60
+ export default (router) => {
61
+ router.post('/custom-checkout', async (req, res) => {
62
+ const stripeService = getStripeService();
63
+ const userId = req.accountability?.user?.id;
64
+
65
+ // Create a custom checkout session
66
+ const session = await stripeService.createCheckoutSession({
67
+ userId,
68
+ priceId: req.body.priceId,
69
+ successUrl: req.body.successUrl,
70
+ cancelUrl: req.body.cancelUrl,
71
+ metadata: { orderId: req.body.orderId },
72
+ });
73
+
74
+ res.json(session);
75
+ });
76
+
77
+ router.get('/my-subscriptions', async (req, res) => {
78
+ const stripeService = getStripeService();
79
+ const userId = req.accountability?.user?.id;
80
+
81
+ const subscriptions = await stripeService.getUserSubscriptions(userId);
82
+ res.json(subscriptions);
83
+ });
84
+ };
85
+ ```
86
+
87
+ ### In Hooks
88
+
89
+ ```typescript
90
+ // extensions/hooks/stripe-hooks.ts
91
+ import { getStripeService } from '@baasix/plugin-stripe';
92
+
93
+ export default {
94
+ // Pre-create Stripe customer when a user registers
95
+ 'items.create.after': async (context) => {
96
+ if (context.collection === 'baasix_User') {
97
+ const stripeService = getStripeService();
98
+ await stripeService.getOrCreateCustomer(context.data.id);
99
+ console.log('Stripe customer created for new user');
100
+ }
101
+ return context;
102
+ },
103
+
104
+ // Clean up when user is deleted (optional)
105
+ 'items.delete': async (context) => {
106
+ if (context.collection === 'baasix_User') {
107
+ // Handle Stripe customer cleanup if needed
108
+ const stripeService = getStripeService();
109
+ const customer = await stripeService.getCustomer(context.id);
110
+ if (customer) {
111
+ // Cancel active subscriptions, etc.
112
+ const subscriptions = await stripeService.getUserSubscriptions(context.id);
113
+ for (const sub of subscriptions) {
114
+ if (sub.status === 'active') {
115
+ await stripeService.manageSubscription(context.id, sub.id, 'cancel');
116
+ }
117
+ }
118
+ }
119
+ }
120
+ return context;
121
+ }
122
+ };
123
+ ```
124
+
125
+ ### In Other Services or Utilities
126
+
127
+ ```typescript
128
+ // services/billing.ts
129
+ import { getStripeService, isStripeServiceInitialized } from '@baasix/plugin-stripe';
130
+
131
+ export async function checkUserSubscription(userId: string) {
132
+ // Optionally check if service is ready
133
+ if (!isStripeServiceInitialized()) {
134
+ throw new Error('Stripe plugin not loaded');
135
+ }
136
+
137
+ const stripeService = getStripeService();
138
+ const subscriptions = await stripeService.getUserSubscriptions(userId);
139
+
140
+ return subscriptions.some(sub =>
141
+ sub.status === 'active' || sub.status === 'trialing'
142
+ );
143
+ }
144
+
145
+ export async function getActiveSubscriptionTier(userId: string) {
146
+ const stripeService = getStripeService();
147
+ const subscriptions = await stripeService.getUserSubscriptions(userId);
148
+
149
+ const active = subscriptions.find(sub => sub.status === 'active');
150
+ if (!active) return null;
151
+
152
+ // Get the product details
153
+ const products = await stripeService.getProducts();
154
+ return products.find(p => p.stripePriceId === active.stripePriceId);
155
+ }
156
+ ```
157
+
158
+ ### Accessing the Stripe SDK Directly
159
+
160
+ ```typescript
161
+ import { getStripeService } from '@baasix/plugin-stripe';
162
+
163
+ async function createCustomPaymentIntent() {
164
+ const stripeService = getStripeService();
165
+
166
+ // Access the Stripe SDK directly for advanced operations
167
+ const stripe = stripeService.stripe;
168
+
169
+ const paymentIntent = await stripe.paymentIntents.create({
170
+ amount: 2000,
171
+ currency: 'usd',
172
+ automatic_payment_methods: { enabled: true },
173
+ });
174
+
175
+ return paymentIntent;
176
+ }
177
+ ```
178
+
179
+ ## Database Tables
180
+
181
+ The plugin creates the following tables:
182
+
183
+ ### baasix_StripeCustomer
184
+
185
+ Maps Baasix users to Stripe customers.
186
+
187
+ | Column | Type | Description |
188
+ |--------|------|-------------|
189
+ | id | UUID | Primary key |
190
+ | user_Id | UUID | Reference to baasix_User |
191
+ | stripeCustomerId | String | Stripe customer ID |
192
+ | email | String | Customer email |
193
+ | metadata | JSON | Additional metadata |
194
+ | createdAt | DateTime | Created timestamp |
195
+ | updatedAt | DateTime | Updated timestamp |
196
+
197
+ ### baasix_StripePayment
198
+
199
+ Records one-time payments.
200
+
201
+ | Column | Type | Description |
202
+ |--------|------|-------------|
203
+ | id | UUID | Primary key |
204
+ | customer_Id | UUID | Reference to StripeCustomer |
205
+ | stripePaymentIntentId | String | Stripe payment intent ID |
206
+ | stripeCheckoutSessionId | String | Stripe checkout session ID |
207
+ | amount | Integer | Amount in cents |
208
+ | currency | String | Currency code |
209
+ | status | Enum | Payment status |
210
+ | metadata | JSON | Additional metadata |
211
+
212
+ ### baasix_StripeSubscription
213
+
214
+ Tracks subscriptions.
215
+
216
+ | Column | Type | Description |
217
+ |--------|------|-------------|
218
+ | id | UUID | Primary key |
219
+ | customer_Id | UUID | Reference to StripeCustomer |
220
+ | stripeSubscriptionId | String | Stripe subscription ID |
221
+ | stripePriceId | String | Stripe price ID |
222
+ | status | Enum | Subscription status |
223
+ | currentPeriodStart | DateTime | Current billing period start |
224
+ | currentPeriodEnd | DateTime | Current billing period end |
225
+ | cancelAtPeriodEnd | Boolean | Whether subscription cancels at period end |
226
+
227
+ ### baasix_StripeProduct
228
+
229
+ Cached products and prices from Stripe.
230
+
231
+ | Column | Type | Description |
232
+ |--------|------|-------------|
233
+ | id | UUID | Primary key |
234
+ | stripeProductId | String | Stripe product ID |
235
+ | stripePriceId | String | Stripe price ID |
236
+ | name | String | Product name |
237
+ | description | Text | Product description |
238
+ | amount | Integer | Price in cents |
239
+ | currency | String | Currency code |
240
+ | interval | Enum | Billing interval |
241
+ | active | Boolean | Whether product is active |
242
+
243
+ ## API Endpoints
244
+
245
+ ### One-Time Payments
246
+
247
+ #### Create Checkout Session
248
+ ```http
249
+ POST /payments/stripe/checkout
250
+ Authorization: Bearer <token>
251
+ Content-Type: application/json
252
+
253
+ {
254
+ "priceId": "price_xxx",
255
+ "quantity": 1,
256
+ "successUrl": "https://example.com/success",
257
+ "cancelUrl": "https://example.com/cancel",
258
+ "metadata": { "orderId": "123" }
259
+ }
260
+ ```
261
+
262
+ **Response:**
263
+ ```json
264
+ {
265
+ "sessionId": "cs_xxx",
266
+ "url": "https://checkout.stripe.com/..."
267
+ }
268
+ ```
269
+
270
+ ### Subscriptions
271
+
272
+ #### Create Subscription Checkout
273
+ ```http
274
+ POST /payments/stripe/subscribe
275
+ Authorization: Bearer <token>
276
+ Content-Type: application/json
277
+
278
+ {
279
+ "priceId": "price_xxx",
280
+ "successUrl": "https://example.com/success",
281
+ "cancelUrl": "https://example.com/cancel",
282
+ "trialDays": 14,
283
+ "metadata": { "plan": "pro" }
284
+ }
285
+ ```
286
+
287
+ #### Manage Subscription
288
+ ```http
289
+ PATCH /payments/stripe/subscription/:id
290
+ Authorization: Bearer <token>
291
+ Content-Type: application/json
292
+
293
+ {
294
+ "action": "cancel" | "resume"
295
+ }
296
+ ```
297
+
298
+ #### Get User's Subscriptions
299
+ ```http
300
+ GET /payments/stripe/subscriptions
301
+ Authorization: Bearer <token>
302
+ ```
303
+
304
+ ### Customer Portal
305
+
306
+ #### Create Portal Session
307
+ ```http
308
+ POST /payments/stripe/portal
309
+ Authorization: Bearer <token>
310
+ Content-Type: application/json
311
+
312
+ {
313
+ "returnUrl": "https://example.com/account"
314
+ }
315
+ ```
316
+
317
+ **Response:**
318
+ ```json
319
+ {
320
+ "url": "https://billing.stripe.com/..."
321
+ }
322
+ ```
323
+
324
+ ### User Data
325
+
326
+ #### Get User's Payments
327
+ ```http
328
+ GET /payments/stripe/payments
329
+ Authorization: Bearer <token>
330
+ ```
331
+
332
+ ### Products
333
+
334
+ #### Get Available Products
335
+ ```http
336
+ GET /payments/stripe/products
337
+ ```
338
+
339
+ #### Sync Products (Admin Only)
340
+ ```http
341
+ POST /payments/stripe/sync-products
342
+ Authorization: Bearer <admin-token>
343
+ ```
344
+
345
+ ### Webhook
346
+
347
+ #### Handle Stripe Events
348
+ ```http
349
+ POST /payments/stripe/webhook
350
+ Stripe-Signature: <signature>
351
+ ```
352
+
353
+ Configure this URL in your Stripe Dashboard under Developers > Webhooks.
354
+
355
+ **Handled Events:**
356
+ - `checkout.session.completed` - Records completed payments
357
+ - `payment_intent.succeeded` - Updates payment status
358
+ - `payment_intent.payment_failed` - Marks payment as failed
359
+ - `customer.subscription.created` - Creates subscription record
360
+ - `customer.subscription.updated` - Updates subscription
361
+ - `customer.subscription.deleted` - Marks subscription as canceled
362
+ - `invoice.payment_succeeded` - Updates subscription after renewal
363
+ - `invoice.payment_failed` - Marks subscription as past_due
364
+
365
+ ## Testing Webhooks Locally
366
+
367
+ Use the Stripe CLI to forward webhooks to your local server:
368
+
369
+ ```bash
370
+ # Install Stripe CLI
371
+ brew install stripe/stripe-cli/stripe
372
+
373
+ # Login to your Stripe account
374
+ stripe login
375
+
376
+ # Forward webhooks to your local server
377
+ stripe listen --forward-to localhost:8055/payments/stripe/webhook
378
+ ```
379
+
380
+ This will output a webhook signing secret to use in your configuration.
381
+
382
+ ## Service API Reference
383
+
384
+ ### getStripeService()
385
+
386
+ Returns the Stripe service singleton. Throws an error if the plugin hasn't been initialized.
387
+
388
+ ```typescript
389
+ import { getStripeService } from '@baasix/plugin-stripe';
390
+
391
+ const stripeService = getStripeService();
392
+ ```
393
+
394
+ ### isStripeServiceInitialized()
395
+
396
+ Check if the Stripe service has been initialized.
397
+
398
+ ```typescript
399
+ import { isStripeServiceInitialized } from '@baasix/plugin-stripe';
400
+
401
+ if (isStripeServiceInitialized()) {
402
+ // Safe to use getStripeService()
403
+ }
404
+ ```
405
+
406
+ ### Service Methods
407
+
408
+ | Method | Description |
409
+ |--------|-------------|
410
+ | `getOrCreateCustomer(userId)` | Get or create a Stripe customer for a user |
411
+ | `getCustomer(userId)` | Get a Stripe customer by user ID |
412
+ | `createCheckoutSession(options)` | Create a checkout session for one-time payment |
413
+ | `createSubscriptionCheckout(options)` | Create a checkout session for subscription |
414
+ | `createPortalSession(userId, returnUrl)` | Create a billing portal session |
415
+ | `manageSubscription(userId, subscriptionId, action)` | Cancel or resume a subscription |
416
+ | `getUserPayments(userId)` | Get a user's payment history |
417
+ | `getUserSubscriptions(userId)` | Get a user's subscriptions |
418
+ | `getProducts()` | Get all active products |
419
+ | `syncProducts()` | Sync products from Stripe |
420
+ | `handleWebhook(event)` | Handle a Stripe webhook event |
421
+ | `syncSubscription(subscription)` | Sync a subscription from Stripe |
422
+ | `stripe` | Access the Stripe SDK instance directly |
423
+
424
+ ## Type Definitions
425
+
426
+ Import types for TypeScript support:
427
+
428
+ ```typescript
429
+ import type {
430
+ StripePluginConfig,
431
+ StripeCustomerRecord,
432
+ StripePaymentRecord,
433
+ StripeSubscriptionRecord,
434
+ StripeProductRecord,
435
+ StripeServiceInterface
436
+ } from '@baasix/plugin-stripe';
437
+ ```
438
+
439
+ ## Plugin Structure
440
+
441
+ ```
442
+ src/
443
+ ├── index.ts # Main entry point & exports
444
+ ├── types.ts # All type definitions
445
+ ├── schemas/
446
+ │ └── index.ts # Database schema definitions
447
+ ├── services/
448
+ │ └── stripeService.ts # Service implementation & singleton
449
+ ├── routes/
450
+ │ ├── index.ts # Routes aggregator
451
+ │ ├── checkout.ts # One-time payment checkout
452
+ │ ├── subscription.ts # Subscription management
453
+ │ ├── portal.ts # Customer portal & payments
454
+ │ ├── products.ts # Product listing & sync
455
+ │ └── webhook.ts # Webhook handler
456
+ └── utils/
457
+ └── loadStripe.ts # Dynamic Stripe SDK loading
458
+ ```
459
+
460
+ ## Creating Your Own Plugin
461
+
462
+ This plugin serves as an example for creating Baasix plugins. Key patterns:
463
+
464
+ 1. **Types** - Define all types in `types.ts`
465
+ 2. **Schemas** - Define database schemas in `schemas/`
466
+ 3. **Services** - Implement business logic in `services/`
467
+ 4. **Routes** - Define API endpoints in `routes/`
468
+ 5. **Singleton** - Use `globalThis` for services that should be accessible everywhere
469
+ 6. **Lifecycle** - Use `onInit`, `onReady`, `onShutdown` for setup/teardown
470
+
471
+ ## License
472
+
473
+ MIT
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Baasix Stripe Plugin
3
+ *
4
+ * A comprehensive Stripe payment integration plugin for Baasix that provides:
5
+ * - One-time payments via Stripe Checkout
6
+ * - Subscription management with recurring billing
7
+ * - Customer portal for self-service billing
8
+ * - Webhook handling for payment events
9
+ * - Product/price synchronization from Stripe
10
+ *
11
+ * @packageDocumentation
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { startServer } from '@baasix/baasix';
16
+ * import { stripePlugin } from '@baasix/plugin-stripe';
17
+ *
18
+ * startServer({
19
+ * port: 8055,
20
+ * plugins: [
21
+ * stripePlugin({
22
+ * secretKey: process.env.STRIPE_SECRET_KEY!,
23
+ * webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,
24
+ * currency: 'usd',
25
+ * syncProductsOnStartup: true,
26
+ * })
27
+ * ]
28
+ * });
29
+ * ```
30
+ */
31
+ import type { PluginDefinition, StripePluginConfig } from "./types.js";
32
+ /**
33
+ * Creates the Stripe plugin
34
+ *
35
+ * @param config - Plugin configuration
36
+ * @returns The plugin definition
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const plugin = stripePlugin({
41
+ * secretKey: 'sk_test_...',
42
+ * webhookSecret: 'whsec_...',
43
+ * });
44
+ * ```
45
+ */
46
+ export declare function stripePlugin(config: StripePluginConfig): PluginDefinition;
47
+ export type { StripePluginConfig, StripeCustomerRecord, StripePaymentRecord, StripeSubscriptionRecord, StripeProductRecord, StripeServiceInterface, } from "./types.js";
48
+ export { stripeSchemas } from "./schemas/index.js";
49
+ export { createStripeService, getStripeService, isStripeServiceInitialized, } from "./services/stripeService.js";
50
+ export { createStripeRoutes, checkoutRoute, subscribeRoute, manageSubscriptionRoute, getUserSubscriptionsRoute, portalRoute, getPaymentsRoute, getProductsRoute, syncProductsRoute, createWebhookRoute, } from "./routes/index.js";
51
+ export { loadStripeSDK, createStripeGetter } from "./utils/loadStripe.js";
52
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAGH,OAAO,KAAK,EAEV,gBAAgB,EAChB,kBAAkB,EAEnB,MAAM,YAAY,CAAC;AA8BpB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,gBAAgB,CAgFzE;AAGD,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,EACxB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGnD,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,0BAA0B,GAC3B,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,uBAAuB,EACvB,yBAAyB,EACzB,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Baasix Stripe Plugin
3
+ *
4
+ * A comprehensive Stripe payment integration plugin for Baasix that provides:
5
+ * - One-time payments via Stripe Checkout
6
+ * - Subscription management with recurring billing
7
+ * - Customer portal for self-service billing
8
+ * - Webhook handling for payment events
9
+ * - Product/price synchronization from Stripe
10
+ *
11
+ * @packageDocumentation
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * import { startServer } from '@baasix/baasix';
16
+ * import { stripePlugin } from '@baasix/plugin-stripe';
17
+ *
18
+ * startServer({
19
+ * port: 8055,
20
+ * plugins: [
21
+ * stripePlugin({
22
+ * secretKey: process.env.STRIPE_SECRET_KEY!,
23
+ * webhookSecret: process.env.STRIPE_WEBHOOK_SECRET!,
24
+ * currency: 'usd',
25
+ * syncProductsOnStartup: true,
26
+ * })
27
+ * ]
28
+ * });
29
+ * ```
30
+ */
31
+ // Schemas
32
+ import { stripeSchemas } from "./schemas/index.js";
33
+ // Services
34
+ import { createStripeService } from "./services/stripeService.js";
35
+ // Routes
36
+ import { createStripeRoutes } from "./routes/index.js";
37
+ // Utils
38
+ import { createStripeGetter } from "./utils/loadStripe.js";
39
+ /**
40
+ * Helper function to define a plugin with validation
41
+ */
42
+ function definePlugin(definition) {
43
+ if (!definition.meta?.name) {
44
+ throw new Error("Plugin must have a name");
45
+ }
46
+ if (!definition.meta?.version) {
47
+ throw new Error("Plugin must have a version");
48
+ }
49
+ if (!definition.meta?.type) {
50
+ throw new Error("Plugin must have a type");
51
+ }
52
+ return definition;
53
+ }
54
+ /**
55
+ * Creates the Stripe plugin
56
+ *
57
+ * @param config - Plugin configuration
58
+ * @returns The plugin definition
59
+ *
60
+ * @example
61
+ * ```typescript
62
+ * const plugin = stripePlugin({
63
+ * secretKey: 'sk_test_...',
64
+ * webhookSecret: 'whsec_...',
65
+ * });
66
+ * ```
67
+ */
68
+ export function stripePlugin(config) {
69
+ // Validate required configuration
70
+ if (!config.secretKey) {
71
+ throw new Error("Stripe plugin requires 'secretKey' configuration");
72
+ }
73
+ if (!config.webhookSecret) {
74
+ throw new Error("Stripe plugin requires 'webhookSecret' configuration");
75
+ }
76
+ // Create lazy Stripe instance getter
77
+ const getStripe = createStripeGetter(config);
78
+ return definePlugin({
79
+ meta: {
80
+ name: "baasix-plugin-stripe",
81
+ version: "1.0.0",
82
+ type: "payment",
83
+ description: "Stripe payment integration with one-time and subscription support",
84
+ },
85
+ // Database schemas
86
+ schemas: stripeSchemas,
87
+ // API routes
88
+ routes: createStripeRoutes(config, getStripe),
89
+ // Services
90
+ services: [
91
+ {
92
+ name: "stripeService",
93
+ factory: (context) => {
94
+ return createStripeService(getStripe, config, context);
95
+ },
96
+ },
97
+ ],
98
+ // Lifecycle: Initialize
99
+ onInit: async (context) => {
100
+ console.log("[Stripe Plugin] Initializing...");
101
+ // Pre-load Stripe SDK to catch errors early
102
+ try {
103
+ await getStripe();
104
+ console.log("[Stripe Plugin] Stripe SDK loaded successfully");
105
+ }
106
+ catch (error) {
107
+ console.error("[Stripe Plugin] Failed to load Stripe SDK:", error);
108
+ throw error;
109
+ }
110
+ // Optionally sync products on startup
111
+ if (config.syncProductsOnStartup) {
112
+ try {
113
+ const stripeService = context.services.stripeService;
114
+ await stripeService.syncProducts();
115
+ }
116
+ catch (error) {
117
+ console.error("[Stripe Plugin] Failed to sync products on startup:", error);
118
+ }
119
+ }
120
+ },
121
+ // Lifecycle: Ready
122
+ onReady: async () => {
123
+ console.log("[Stripe Plugin] Ready!");
124
+ console.log("[Stripe Plugin] Webhook URL: POST /payments/stripe/webhook");
125
+ console.log("[Stripe Plugin] Available endpoints:");
126
+ console.log(" - POST /payments/stripe/checkout (one-time payment)");
127
+ console.log(" - POST /payments/stripe/subscribe (subscription)");
128
+ console.log(" - PATCH /payments/stripe/subscription/:id (manage subscription)");
129
+ console.log(" - POST /payments/stripe/portal (billing portal)");
130
+ console.log(" - GET /payments/stripe/payments (user payments)");
131
+ console.log(" - GET /payments/stripe/subscriptions (user subscriptions)");
132
+ console.log(" - GET /payments/stripe/products (available products)");
133
+ console.log(" - POST /payments/stripe/sync-products (admin: sync from Stripe)");
134
+ },
135
+ // Lifecycle: Shutdown
136
+ onShutdown: async () => {
137
+ console.log("[Stripe Plugin] Shutting down...");
138
+ },
139
+ });
140
+ }
141
+ // Re-export schemas for customization
142
+ export { stripeSchemas } from "./schemas/index.js";
143
+ // Re-export service and singleton getter
144
+ export { createStripeService, getStripeService, isStripeServiceInitialized, } from "./services/stripeService.js";
145
+ // Re-export routes for customization
146
+ export { createStripeRoutes, checkoutRoute, subscribeRoute, manageSubscriptionRoute, getUserSubscriptionsRoute, portalRoute, getPaymentsRoute, getProductsRoute, syncProductsRoute, createWebhookRoute, } from "./routes/index.js";
147
+ // Re-export utilities
148
+ export { loadStripeSDK, createStripeGetter } from "./utils/loadStripe.js";
149
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}