@magnet-cms/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.
@@ -0,0 +1,2257 @@
1
+ import { Field, Prop, Schema, InjectModel } from '@magnet-cms/common';
2
+ import { Plugin, InjectPluginOptions, DatabaseModule, RestrictedRoute, EmailService } from '@magnet-cms/core';
3
+ import { Logger, HttpException, HttpStatus, Injectable, Module, Post, Body, Get, Param, Controller, HttpCode, Req, Headers, Optional } from '@nestjs/common';
4
+ import Stripe from 'stripe';
5
+
6
+ var __defProp = Object.defineProperty;
7
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
8
+ var __getOwnPropNames = Object.getOwnPropertyNames;
9
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
10
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
11
+ var __esm = (fn, res) => function __init() {
12
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
13
+ };
14
+ var __export = (target, all) => {
15
+ for (var name in all)
16
+ __defProp(target, name, { get: all[name], enumerable: true });
17
+ };
18
+ var __copyProps = (to, from, except, desc) => {
19
+ if (from && typeof from === "object" || typeof from === "function") {
20
+ for (let key of __getOwnPropNames(from))
21
+ if (!__hasOwnProp.call(to, key) && key !== except)
22
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
23
+ }
24
+ return to;
25
+ };
26
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
+ function _ts_decorate(decorators, target, key, desc) {
28
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
29
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
30
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
31
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
32
+ }
33
+ function _ts_metadata(k, v) {
34
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
35
+ }
36
+ var StripeCustomer;
37
+ var init_customer_schema = __esm({
38
+ "src/schemas/customer.schema.ts"() {
39
+ __name(_ts_decorate, "_ts_decorate");
40
+ __name(_ts_metadata, "_ts_metadata");
41
+ StripeCustomer = class {
42
+ static {
43
+ __name(this, "StripeCustomer");
44
+ }
45
+ /** Stripe Customer ID (cus_...) */
46
+ stripeCustomerId;
47
+ /** Customer email address */
48
+ email;
49
+ /** Customer display name */
50
+ name;
51
+ /** Reference to the Magnet user ID */
52
+ userId;
53
+ /** Arbitrary metadata from Stripe */
54
+ metadata;
55
+ /** When the customer was created in Stripe */
56
+ createdAt;
57
+ };
58
+ _ts_decorate([
59
+ Field.Text({
60
+ required: true,
61
+ unique: true
62
+ }),
63
+ _ts_metadata("design:type", String)
64
+ ], StripeCustomer.prototype, "stripeCustomerId", void 0);
65
+ _ts_decorate([
66
+ Field.Email({
67
+ required: true
68
+ }),
69
+ _ts_metadata("design:type", String)
70
+ ], StripeCustomer.prototype, "email", void 0);
71
+ _ts_decorate([
72
+ Field.Text(),
73
+ _ts_metadata("design:type", String)
74
+ ], StripeCustomer.prototype, "name", void 0);
75
+ _ts_decorate([
76
+ Field.Text(),
77
+ _ts_metadata("design:type", String)
78
+ ], StripeCustomer.prototype, "userId", void 0);
79
+ _ts_decorate([
80
+ Prop({
81
+ type: Object
82
+ }),
83
+ _ts_metadata("design:type", typeof Record === "undefined" ? Object : Record)
84
+ ], StripeCustomer.prototype, "metadata", void 0);
85
+ _ts_decorate([
86
+ Field.Date({
87
+ required: true,
88
+ default: /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "default")
89
+ }),
90
+ _ts_metadata("design:type", typeof Date === "undefined" ? Object : Date)
91
+ ], StripeCustomer.prototype, "createdAt", void 0);
92
+ StripeCustomer = _ts_decorate([
93
+ Schema({
94
+ versioning: false,
95
+ i18n: false,
96
+ visible: false
97
+ })
98
+ ], StripeCustomer);
99
+ }
100
+ });
101
+ function _ts_decorate2(decorators, target, key, desc) {
102
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
103
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
104
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
105
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
106
+ }
107
+ function _ts_metadata2(k, v) {
108
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
109
+ }
110
+ var StripePayment;
111
+ var init_payment_schema = __esm({
112
+ "src/schemas/payment.schema.ts"() {
113
+ __name(_ts_decorate2, "_ts_decorate");
114
+ __name(_ts_metadata2, "_ts_metadata");
115
+ StripePayment = class {
116
+ static {
117
+ __name(this, "StripePayment");
118
+ }
119
+ /** Stripe PaymentIntent ID (pi_...) or Invoice ID (in_...) */
120
+ stripePaymentIntentId;
121
+ /** Reference to StripeCustomer.stripeCustomerId */
122
+ customerId;
123
+ /** Payment amount in the smallest currency unit (e.g., cents) */
124
+ amount;
125
+ /** Three-letter ISO currency code */
126
+ currency;
127
+ /** Payment status */
128
+ status;
129
+ /** URL for the payment receipt */
130
+ receiptUrl;
131
+ /** Stripe Invoice ID if payment is from an invoice */
132
+ invoiceId;
133
+ /** When the payment was created */
134
+ createdAt;
135
+ };
136
+ _ts_decorate2([
137
+ Field.Text({
138
+ required: true,
139
+ unique: true
140
+ }),
141
+ _ts_metadata2("design:type", String)
142
+ ], StripePayment.prototype, "stripePaymentIntentId", void 0);
143
+ _ts_decorate2([
144
+ Field.Text({
145
+ required: true
146
+ }),
147
+ _ts_metadata2("design:type", String)
148
+ ], StripePayment.prototype, "customerId", void 0);
149
+ _ts_decorate2([
150
+ Field.Number({
151
+ required: true
152
+ }),
153
+ _ts_metadata2("design:type", Number)
154
+ ], StripePayment.prototype, "amount", void 0);
155
+ _ts_decorate2([
156
+ Field.Text({
157
+ required: true
158
+ }),
159
+ _ts_metadata2("design:type", String)
160
+ ], StripePayment.prototype, "currency", void 0);
161
+ _ts_decorate2([
162
+ Field.Select({
163
+ required: true,
164
+ options: [
165
+ {
166
+ label: "Succeeded",
167
+ value: "succeeded"
168
+ },
169
+ {
170
+ label: "Failed",
171
+ value: "failed"
172
+ },
173
+ {
174
+ label: "Refunded",
175
+ value: "refunded"
176
+ },
177
+ {
178
+ label: "Pending",
179
+ value: "pending"
180
+ }
181
+ ]
182
+ }),
183
+ _ts_metadata2("design:type", String)
184
+ ], StripePayment.prototype, "status", void 0);
185
+ _ts_decorate2([
186
+ Field.Text(),
187
+ _ts_metadata2("design:type", String)
188
+ ], StripePayment.prototype, "receiptUrl", void 0);
189
+ _ts_decorate2([
190
+ Field.Text(),
191
+ _ts_metadata2("design:type", String)
192
+ ], StripePayment.prototype, "invoiceId", void 0);
193
+ _ts_decorate2([
194
+ Field.Date({
195
+ required: true,
196
+ default: /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "default")
197
+ }),
198
+ _ts_metadata2("design:type", typeof Date === "undefined" ? Object : Date)
199
+ ], StripePayment.prototype, "createdAt", void 0);
200
+ StripePayment = _ts_decorate2([
201
+ Schema({
202
+ versioning: false,
203
+ i18n: false,
204
+ visible: false
205
+ })
206
+ ], StripePayment);
207
+ }
208
+ });
209
+ function _ts_decorate3(decorators, target, key, desc) {
210
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
211
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
212
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
213
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
214
+ }
215
+ function _ts_metadata3(k, v) {
216
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
217
+ }
218
+ var StripePrice;
219
+ var init_price_schema = __esm({
220
+ "src/schemas/price.schema.ts"() {
221
+ __name(_ts_decorate3, "_ts_decorate");
222
+ __name(_ts_metadata3, "_ts_metadata");
223
+ StripePrice = class {
224
+ static {
225
+ __name(this, "StripePrice");
226
+ }
227
+ /** Stripe Price ID (price_...) */
228
+ stripePriceId;
229
+ /** Reference to the StripeProduct.stripeProductId */
230
+ productId;
231
+ /** Price amount in the smallest currency unit (e.g., cents) */
232
+ unitAmount;
233
+ /** Three-letter ISO currency code (e.g., 'usd') */
234
+ currency;
235
+ /** Pricing type */
236
+ type;
237
+ /** Billing interval for recurring prices */
238
+ interval;
239
+ /** Number of intervals between billings */
240
+ intervalCount;
241
+ /** Whether this price is currently active */
242
+ active = true;
243
+ };
244
+ _ts_decorate3([
245
+ Field.Text({
246
+ required: true,
247
+ unique: true
248
+ }),
249
+ _ts_metadata3("design:type", String)
250
+ ], StripePrice.prototype, "stripePriceId", void 0);
251
+ _ts_decorate3([
252
+ Field.Text({
253
+ required: true
254
+ }),
255
+ _ts_metadata3("design:type", String)
256
+ ], StripePrice.prototype, "productId", void 0);
257
+ _ts_decorate3([
258
+ Field.Number({
259
+ required: true
260
+ }),
261
+ _ts_metadata3("design:type", Number)
262
+ ], StripePrice.prototype, "unitAmount", void 0);
263
+ _ts_decorate3([
264
+ Field.Text({
265
+ required: true
266
+ }),
267
+ _ts_metadata3("design:type", String)
268
+ ], StripePrice.prototype, "currency", void 0);
269
+ _ts_decorate3([
270
+ Field.Select({
271
+ required: true,
272
+ options: [
273
+ {
274
+ label: "One-time",
275
+ value: "one_time"
276
+ },
277
+ {
278
+ label: "Recurring",
279
+ value: "recurring"
280
+ }
281
+ ]
282
+ }),
283
+ _ts_metadata3("design:type", String)
284
+ ], StripePrice.prototype, "type", void 0);
285
+ _ts_decorate3([
286
+ Field.Select({
287
+ options: [
288
+ {
289
+ label: "Day",
290
+ value: "day"
291
+ },
292
+ {
293
+ label: "Week",
294
+ value: "week"
295
+ },
296
+ {
297
+ label: "Month",
298
+ value: "month"
299
+ },
300
+ {
301
+ label: "Year",
302
+ value: "year"
303
+ }
304
+ ]
305
+ }),
306
+ _ts_metadata3("design:type", String)
307
+ ], StripePrice.prototype, "interval", void 0);
308
+ _ts_decorate3([
309
+ Field.Number(),
310
+ _ts_metadata3("design:type", Number)
311
+ ], StripePrice.prototype, "intervalCount", void 0);
312
+ _ts_decorate3([
313
+ Field.Boolean({
314
+ default: true
315
+ })
316
+ ], StripePrice.prototype, "active", void 0);
317
+ StripePrice = _ts_decorate3([
318
+ Schema({
319
+ versioning: false,
320
+ i18n: false,
321
+ visible: false
322
+ })
323
+ ], StripePrice);
324
+ }
325
+ });
326
+ function _ts_decorate4(decorators, target, key, desc) {
327
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
328
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
329
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
330
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
331
+ }
332
+ function _ts_metadata4(k, v) {
333
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
334
+ }
335
+ var StripeProcessedEvent;
336
+ var init_processed_event_schema = __esm({
337
+ "src/schemas/processed-event.schema.ts"() {
338
+ __name(_ts_decorate4, "_ts_decorate");
339
+ __name(_ts_metadata4, "_ts_metadata");
340
+ StripeProcessedEvent = class {
341
+ static {
342
+ __name(this, "StripeProcessedEvent");
343
+ }
344
+ /** Stripe Event ID (evt_...) — unique to prevent reprocessing */
345
+ stripeEventId;
346
+ /** Event type (e.g., 'invoice.paid', 'customer.subscription.updated') */
347
+ eventType;
348
+ /** When this event was processed */
349
+ processedAt;
350
+ };
351
+ _ts_decorate4([
352
+ Field.Text({
353
+ required: true,
354
+ unique: true
355
+ }),
356
+ _ts_metadata4("design:type", String)
357
+ ], StripeProcessedEvent.prototype, "stripeEventId", void 0);
358
+ _ts_decorate4([
359
+ Field.Text({
360
+ required: true
361
+ }),
362
+ _ts_metadata4("design:type", String)
363
+ ], StripeProcessedEvent.prototype, "eventType", void 0);
364
+ _ts_decorate4([
365
+ Field.Date({
366
+ required: true,
367
+ default: /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "default")
368
+ }),
369
+ _ts_metadata4("design:type", typeof Date === "undefined" ? Object : Date)
370
+ ], StripeProcessedEvent.prototype, "processedAt", void 0);
371
+ StripeProcessedEvent = _ts_decorate4([
372
+ Schema({
373
+ versioning: false,
374
+ i18n: false,
375
+ visible: false
376
+ })
377
+ ], StripeProcessedEvent);
378
+ }
379
+ });
380
+ function _ts_decorate5(decorators, target, key, desc) {
381
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
382
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
383
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
384
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
385
+ }
386
+ function _ts_metadata5(k, v) {
387
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
388
+ }
389
+ var StripeProduct;
390
+ var init_product_schema = __esm({
391
+ "src/schemas/product.schema.ts"() {
392
+ __name(_ts_decorate5, "_ts_decorate");
393
+ __name(_ts_metadata5, "_ts_metadata");
394
+ StripeProduct = class {
395
+ static {
396
+ __name(this, "StripeProduct");
397
+ }
398
+ /** Stripe Product ID (prod_...) */
399
+ stripeProductId;
400
+ /** Product name */
401
+ name;
402
+ /** Product description */
403
+ description;
404
+ /** Whether the product is currently active in Stripe */
405
+ active = true;
406
+ /** Arbitrary metadata from Stripe */
407
+ metadata;
408
+ /** Product image URLs */
409
+ images;
410
+ /** When the product was last synced */
411
+ updatedAt;
412
+ };
413
+ _ts_decorate5([
414
+ Field.Text({
415
+ required: true,
416
+ unique: true
417
+ }),
418
+ _ts_metadata5("design:type", String)
419
+ ], StripeProduct.prototype, "stripeProductId", void 0);
420
+ _ts_decorate5([
421
+ Field.Text({
422
+ required: true
423
+ }),
424
+ _ts_metadata5("design:type", String)
425
+ ], StripeProduct.prototype, "name", void 0);
426
+ _ts_decorate5([
427
+ Field.Text(),
428
+ _ts_metadata5("design:type", String)
429
+ ], StripeProduct.prototype, "description", void 0);
430
+ _ts_decorate5([
431
+ Field.Boolean({
432
+ default: true
433
+ })
434
+ ], StripeProduct.prototype, "active", void 0);
435
+ _ts_decorate5([
436
+ Prop({
437
+ type: Object
438
+ }),
439
+ _ts_metadata5("design:type", typeof Record === "undefined" ? Object : Record)
440
+ ], StripeProduct.prototype, "metadata", void 0);
441
+ _ts_decorate5([
442
+ Prop({
443
+ type: [
444
+ String
445
+ ]
446
+ }),
447
+ _ts_metadata5("design:type", Array)
448
+ ], StripeProduct.prototype, "images", void 0);
449
+ _ts_decorate5([
450
+ Field.Date({
451
+ required: true,
452
+ default: /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "default")
453
+ }),
454
+ _ts_metadata5("design:type", typeof Date === "undefined" ? Object : Date)
455
+ ], StripeProduct.prototype, "updatedAt", void 0);
456
+ StripeProduct = _ts_decorate5([
457
+ Schema({
458
+ versioning: false,
459
+ i18n: false,
460
+ visible: false
461
+ })
462
+ ], StripeProduct);
463
+ }
464
+ });
465
+ function _ts_decorate6(decorators, target, key, desc) {
466
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
467
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
468
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
469
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
470
+ }
471
+ function _ts_metadata6(k, v) {
472
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
473
+ }
474
+ var StripeSubscription;
475
+ var init_subscription_schema = __esm({
476
+ "src/schemas/subscription.schema.ts"() {
477
+ __name(_ts_decorate6, "_ts_decorate");
478
+ __name(_ts_metadata6, "_ts_metadata");
479
+ StripeSubscription = class {
480
+ static {
481
+ __name(this, "StripeSubscription");
482
+ }
483
+ /** Stripe Subscription ID (sub_...) */
484
+ stripeSubscriptionId;
485
+ /** Reference to StripeCustomer.stripeCustomerId */
486
+ customerId;
487
+ /** Reference to StripePrice.stripePriceId */
488
+ priceId;
489
+ /** Subscription status from Stripe */
490
+ status;
491
+ /** Start of the current billing period */
492
+ currentPeriodStart;
493
+ /** End of the current billing period */
494
+ currentPeriodEnd;
495
+ /** Whether the subscription will be canceled at the end of the period */
496
+ cancelAtPeriodEnd = false;
497
+ /** When the trial ends (null if no trial) */
498
+ trialEnd;
499
+ /** When the subscription was last synced */
500
+ updatedAt;
501
+ };
502
+ _ts_decorate6([
503
+ Field.Text({
504
+ required: true,
505
+ unique: true
506
+ }),
507
+ _ts_metadata6("design:type", String)
508
+ ], StripeSubscription.prototype, "stripeSubscriptionId", void 0);
509
+ _ts_decorate6([
510
+ Field.Text({
511
+ required: true
512
+ }),
513
+ _ts_metadata6("design:type", String)
514
+ ], StripeSubscription.prototype, "customerId", void 0);
515
+ _ts_decorate6([
516
+ Field.Text({
517
+ required: true
518
+ }),
519
+ _ts_metadata6("design:type", String)
520
+ ], StripeSubscription.prototype, "priceId", void 0);
521
+ _ts_decorate6([
522
+ Field.Select({
523
+ required: true,
524
+ options: [
525
+ {
526
+ label: "Active",
527
+ value: "active"
528
+ },
529
+ {
530
+ label: "Past Due",
531
+ value: "past_due"
532
+ },
533
+ {
534
+ label: "Canceled",
535
+ value: "canceled"
536
+ },
537
+ {
538
+ label: "Incomplete",
539
+ value: "incomplete"
540
+ },
541
+ {
542
+ label: "Incomplete Expired",
543
+ value: "incomplete_expired"
544
+ },
545
+ {
546
+ label: "Trialing",
547
+ value: "trialing"
548
+ },
549
+ {
550
+ label: "Unpaid",
551
+ value: "unpaid"
552
+ },
553
+ {
554
+ label: "Paused",
555
+ value: "paused"
556
+ }
557
+ ]
558
+ }),
559
+ _ts_metadata6("design:type", String)
560
+ ], StripeSubscription.prototype, "status", void 0);
561
+ _ts_decorate6([
562
+ Field.Date({
563
+ required: true
564
+ }),
565
+ _ts_metadata6("design:type", typeof Date === "undefined" ? Object : Date)
566
+ ], StripeSubscription.prototype, "currentPeriodStart", void 0);
567
+ _ts_decorate6([
568
+ Field.Date({
569
+ required: true
570
+ }),
571
+ _ts_metadata6("design:type", typeof Date === "undefined" ? Object : Date)
572
+ ], StripeSubscription.prototype, "currentPeriodEnd", void 0);
573
+ _ts_decorate6([
574
+ Field.Boolean({
575
+ default: false
576
+ })
577
+ ], StripeSubscription.prototype, "cancelAtPeriodEnd", void 0);
578
+ _ts_decorate6([
579
+ Field.Date(),
580
+ _ts_metadata6("design:type", typeof Date === "undefined" ? Object : Date)
581
+ ], StripeSubscription.prototype, "trialEnd", void 0);
582
+ _ts_decorate6([
583
+ Field.Date({
584
+ required: true,
585
+ default: /* @__PURE__ */ __name(() => /* @__PURE__ */ new Date(), "default")
586
+ }),
587
+ _ts_metadata6("design:type", typeof Date === "undefined" ? Object : Date)
588
+ ], StripeSubscription.prototype, "updatedAt", void 0);
589
+ StripeSubscription = _ts_decorate6([
590
+ Schema({
591
+ versioning: false,
592
+ i18n: false,
593
+ visible: false
594
+ })
595
+ ], StripeSubscription);
596
+ }
597
+ });
598
+ function _ts_decorate7(decorators, target, key, desc) {
599
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
600
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
601
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
602
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
603
+ }
604
+ function _ts_metadata7(k, v) {
605
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
606
+ }
607
+ function _ts_param(paramIndex, decorator) {
608
+ return function(target, key) {
609
+ decorator(target, key, paramIndex);
610
+ };
611
+ }
612
+ var StripeService;
613
+ var init_stripe_service = __esm({
614
+ "src/stripe.service.ts"() {
615
+ __name(_ts_decorate7, "_ts_decorate");
616
+ __name(_ts_metadata7, "_ts_metadata");
617
+ __name(_ts_param, "_ts_param");
618
+ StripeService = class _StripeService {
619
+ static {
620
+ __name(this, "StripeService");
621
+ }
622
+ config;
623
+ logger;
624
+ stripe;
625
+ constructor(config) {
626
+ this.config = config;
627
+ this.logger = new Logger(_StripeService.name);
628
+ this.stripe = null;
629
+ }
630
+ onModuleInit() {
631
+ if (!this.config.secretKey) {
632
+ throw new Error("[StripePlugin] Missing secretKey in plugin options. Configure it via: { plugin: StripePlugin, options: { secretKey: process.env.STRIPE_SECRET_KEY } }");
633
+ }
634
+ this.stripe = new Stripe(this.config.secretKey, {
635
+ apiVersion: "2025-02-24.acacia"
636
+ });
637
+ if (this.config.webhookSecret) {
638
+ this.logger.debug("Webhook secret configured. Ensure rawBody is enabled in NestFactory.create() for signature verification.");
639
+ }
640
+ }
641
+ /** Get the initialized Stripe client */
642
+ get client() {
643
+ if (!this.stripe) {
644
+ throw new Error("[StripePlugin] Stripe client not initialized. Ensure the module has been initialized.");
645
+ }
646
+ return this.stripe;
647
+ }
648
+ /** Get the plugin configuration */
649
+ get pluginConfig() {
650
+ return this.config;
651
+ }
652
+ /**
653
+ * Verify that raw body is available on the request.
654
+ * Must be called before webhook signature verification.
655
+ * Consumers must enable `rawBody: true` in NestFactory.create().
656
+ */
657
+ verifyRawBodyAvailable(req) {
658
+ if (!req.rawBody) {
659
+ throw new HttpException("[StripePlugin] Raw request body not available. Enable rawBody in your NestJS bootstrap: NestFactory.create(AppModule, { rawBody: true }). This is required for Stripe webhook signature verification.", HttpStatus.INTERNAL_SERVER_ERROR);
660
+ }
661
+ }
662
+ };
663
+ StripeService = _ts_decorate7([
664
+ Injectable(),
665
+ _ts_param(0, InjectPluginOptions("stripe")),
666
+ _ts_metadata7("design:type", Function),
667
+ _ts_metadata7("design:paramtypes", [
668
+ typeof StripePluginConfig === "undefined" ? Object : StripePluginConfig
669
+ ])
670
+ ], StripeService);
671
+ }
672
+ });
673
+ function _ts_decorate8(decorators, target, key, desc) {
674
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
675
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
676
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
677
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
678
+ }
679
+ function _ts_metadata8(k, v) {
680
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
681
+ }
682
+ function _ts_param2(paramIndex, decorator) {
683
+ return function(target, key) {
684
+ decorator(target, key, paramIndex);
685
+ };
686
+ }
687
+ var StripeCustomerService;
688
+ var init_customer_service = __esm({
689
+ "src/services/customer.service.ts"() {
690
+ init_customer_schema();
691
+ __name(_ts_decorate8, "_ts_decorate");
692
+ __name(_ts_metadata8, "_ts_metadata");
693
+ __name(_ts_param2, "_ts_param");
694
+ StripeCustomerService = class {
695
+ static {
696
+ __name(this, "StripeCustomerService");
697
+ }
698
+ customerModel;
699
+ constructor(customerModel) {
700
+ this.customerModel = customerModel;
701
+ }
702
+ /**
703
+ * Upsert a Stripe customer record from a Stripe Customer object.
704
+ */
705
+ async upsertFromStripe(stripeCustomer) {
706
+ const data = {
707
+ stripeCustomerId: stripeCustomer.id,
708
+ email: stripeCustomer.email ?? "",
709
+ name: stripeCustomer.name ?? void 0,
710
+ metadata: stripeCustomer.metadata
711
+ };
712
+ const existing = await this.customerModel.findOne({
713
+ stripeCustomerId: stripeCustomer.id
714
+ });
715
+ if (existing) {
716
+ return this.customerModel.update({
717
+ stripeCustomerId: stripeCustomer.id
718
+ }, data);
719
+ }
720
+ return this.customerModel.create(data);
721
+ }
722
+ /**
723
+ * Delete a customer record by Stripe Customer ID.
724
+ */
725
+ async deleteByStripeId(stripeCustomerId) {
726
+ await this.customerModel.delete({
727
+ stripeCustomerId
728
+ });
729
+ }
730
+ /**
731
+ * Find a customer by Magnet user ID.
732
+ */
733
+ async findByUserId(userId) {
734
+ return this.customerModel.findOne({
735
+ userId
736
+ });
737
+ }
738
+ /**
739
+ * Find a customer by Stripe Customer ID.
740
+ */
741
+ async findByStripeId(stripeCustomerId) {
742
+ return this.customerModel.findOne({
743
+ stripeCustomerId
744
+ });
745
+ }
746
+ /**
747
+ * List all customers.
748
+ */
749
+ async findAll() {
750
+ return this.customerModel.find();
751
+ }
752
+ /**
753
+ * Link a Stripe customer to a Magnet user.
754
+ */
755
+ async linkToUser(stripeCustomerId, userId) {
756
+ return this.customerModel.update({
757
+ stripeCustomerId
758
+ }, {
759
+ userId
760
+ });
761
+ }
762
+ };
763
+ StripeCustomerService = _ts_decorate8([
764
+ Injectable(),
765
+ _ts_param2(0, InjectModel(StripeCustomer)),
766
+ _ts_metadata8("design:type", Function),
767
+ _ts_metadata8("design:paramtypes", [
768
+ typeof Model === "undefined" ? Object : Model
769
+ ])
770
+ ], StripeCustomerService);
771
+ }
772
+ });
773
+ function _ts_decorate9(decorators, target, key, desc) {
774
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
775
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
776
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
777
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
778
+ }
779
+ function _ts_metadata9(k, v) {
780
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
781
+ }
782
+ function _ts_param3(paramIndex, decorator) {
783
+ return function(target, key) {
784
+ decorator(target, key, paramIndex);
785
+ };
786
+ }
787
+ var StripeSubscriptionService;
788
+ var init_subscription_service = __esm({
789
+ "src/services/subscription.service.ts"() {
790
+ init_subscription_schema();
791
+ init_stripe_service();
792
+ __name(_ts_decorate9, "_ts_decorate");
793
+ __name(_ts_metadata9, "_ts_metadata");
794
+ __name(_ts_param3, "_ts_param");
795
+ StripeSubscriptionService = class {
796
+ static {
797
+ __name(this, "StripeSubscriptionService");
798
+ }
799
+ subscriptionModel;
800
+ stripeService;
801
+ constructor(subscriptionModel, stripeService) {
802
+ this.subscriptionModel = subscriptionModel;
803
+ this.stripeService = stripeService;
804
+ }
805
+ /**
806
+ * Upsert a subscription from a Stripe Subscription object.
807
+ */
808
+ async syncSubscription(stripeSub) {
809
+ const customerId = typeof stripeSub.customer === "string" ? stripeSub.customer : stripeSub.customer.id;
810
+ const priceId = stripeSub.items.data[0]?.price?.id ?? "";
811
+ const data = {
812
+ stripeSubscriptionId: stripeSub.id,
813
+ customerId,
814
+ priceId,
815
+ status: stripeSub.status,
816
+ currentPeriodStart: new Date(stripeSub.current_period_start * 1e3),
817
+ currentPeriodEnd: new Date(stripeSub.current_period_end * 1e3),
818
+ cancelAtPeriodEnd: stripeSub.cancel_at_period_end,
819
+ trialEnd: stripeSub.trial_end ? new Date(stripeSub.trial_end * 1e3) : void 0,
820
+ updatedAt: /* @__PURE__ */ new Date()
821
+ };
822
+ const existing = await this.subscriptionModel.findOne({
823
+ stripeSubscriptionId: stripeSub.id
824
+ });
825
+ if (existing) {
826
+ return this.subscriptionModel.update({
827
+ stripeSubscriptionId: stripeSub.id
828
+ }, data);
829
+ }
830
+ return this.subscriptionModel.create(data);
831
+ }
832
+ /**
833
+ * Delete a subscription record by Stripe Subscription ID.
834
+ */
835
+ async deleteByStripeId(stripeSubscriptionId) {
836
+ await this.subscriptionModel.delete({
837
+ stripeSubscriptionId
838
+ });
839
+ }
840
+ /**
841
+ * Find active subscription for a customer.
842
+ */
843
+ async findActiveByCustomerId(customerId) {
844
+ return this.subscriptionModel.findOne({
845
+ customerId,
846
+ status: "active"
847
+ });
848
+ }
849
+ /**
850
+ * List all subscriptions.
851
+ */
852
+ async findAll() {
853
+ return this.subscriptionModel.find();
854
+ }
855
+ /**
856
+ * Cancel a subscription via the Stripe API.
857
+ */
858
+ async cancel(stripeSubscriptionId) {
859
+ await this.stripeService.client.subscriptions.cancel(stripeSubscriptionId);
860
+ }
861
+ };
862
+ StripeSubscriptionService = _ts_decorate9([
863
+ Injectable(),
864
+ _ts_param3(0, InjectModel(StripeSubscription)),
865
+ _ts_metadata9("design:type", Function),
866
+ _ts_metadata9("design:paramtypes", [
867
+ typeof Model === "undefined" ? Object : Model,
868
+ typeof StripeService === "undefined" ? Object : StripeService
869
+ ])
870
+ ], StripeSubscriptionService);
871
+ }
872
+ });
873
+ function _ts_decorate10(decorators, target, key, desc) {
874
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
875
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
876
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
877
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
878
+ }
879
+ function _ts_metadata10(k, v) {
880
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
881
+ }
882
+ function _ts_param4(paramIndex, decorator) {
883
+ return function(target, key) {
884
+ decorator(target, key, paramIndex);
885
+ };
886
+ }
887
+ var StripeAccessService;
888
+ var init_access_service = __esm({
889
+ "src/services/access.service.ts"() {
890
+ init_price_schema();
891
+ init_product_schema();
892
+ init_stripe_service();
893
+ init_customer_service();
894
+ init_subscription_service();
895
+ __name(_ts_decorate10, "_ts_decorate");
896
+ __name(_ts_metadata10, "_ts_metadata");
897
+ __name(_ts_param4, "_ts_param");
898
+ StripeAccessService = class {
899
+ static {
900
+ __name(this, "StripeAccessService");
901
+ }
902
+ stripeService;
903
+ customerService;
904
+ subscriptionService;
905
+ priceModel;
906
+ productModel;
907
+ constructor(stripeService, customerService, subscriptionService, priceModel, productModel) {
908
+ this.stripeService = stripeService;
909
+ this.customerService = customerService;
910
+ this.subscriptionService = subscriptionService;
911
+ this.priceModel = priceModel;
912
+ this.productModel = productModel;
913
+ }
914
+ /**
915
+ * Get subscription access info for a user.
916
+ * Returns subscription status, plan name, and feature flags.
917
+ */
918
+ async getAccess(userId) {
919
+ const noAccess = {
920
+ hasActiveSubscription: false,
921
+ plan: null,
922
+ expiresAt: null,
923
+ features: []
924
+ };
925
+ const customer = await this.customerService.findByUserId(userId);
926
+ if (!customer) {
927
+ return noAccess;
928
+ }
929
+ const subscription = await this.subscriptionService.findActiveByCustomerId(customer.stripeCustomerId);
930
+ if (!subscription) {
931
+ return noAccess;
932
+ }
933
+ const price = await this.priceModel.findOne({
934
+ stripePriceId: subscription.priceId
935
+ });
936
+ let planName = null;
937
+ if (price) {
938
+ const product = await this.productModel.findOne({
939
+ stripeProductId: price.productId
940
+ });
941
+ planName = product?.name ?? null;
942
+ }
943
+ const features = this.resolveFeaturesForPlan(planName);
944
+ return {
945
+ hasActiveSubscription: true,
946
+ plan: planName,
947
+ expiresAt: subscription.currentPeriodEnd,
948
+ features
949
+ };
950
+ }
951
+ /**
952
+ * Resolve feature flags for a plan name from plugin config.
953
+ */
954
+ resolveFeaturesForPlan(planName) {
955
+ if (!planName) return [];
956
+ const featuresConfig = this.stripeService.pluginConfig.features;
957
+ if (!featuresConfig) return [];
958
+ const normalizedPlan = planName.toLowerCase();
959
+ for (const [key, features] of Object.entries(featuresConfig)) {
960
+ if (key.toLowerCase() === normalizedPlan) {
961
+ return features;
962
+ }
963
+ }
964
+ return [];
965
+ }
966
+ };
967
+ StripeAccessService = _ts_decorate10([
968
+ Injectable(),
969
+ _ts_param4(3, InjectModel(StripePrice)),
970
+ _ts_param4(4, InjectModel(StripeProduct)),
971
+ _ts_metadata10("design:type", Function),
972
+ _ts_metadata10("design:paramtypes", [
973
+ typeof StripeService === "undefined" ? Object : StripeService,
974
+ typeof StripeCustomerService === "undefined" ? Object : StripeCustomerService,
975
+ typeof StripeSubscriptionService === "undefined" ? Object : StripeSubscriptionService,
976
+ typeof Model === "undefined" ? Object : Model,
977
+ typeof Model === "undefined" ? Object : Model
978
+ ])
979
+ ], StripeAccessService);
980
+ }
981
+ });
982
+ function _ts_decorate11(decorators, target, key, desc) {
983
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
984
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
985
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
986
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
987
+ }
988
+ function _ts_metadata11(k, v) {
989
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
990
+ }
991
+ var StripeCheckoutService;
992
+ var init_checkout_service = __esm({
993
+ "src/services/checkout.service.ts"() {
994
+ init_stripe_service();
995
+ __name(_ts_decorate11, "_ts_decorate");
996
+ __name(_ts_metadata11, "_ts_metadata");
997
+ StripeCheckoutService = class {
998
+ static {
999
+ __name(this, "StripeCheckoutService");
1000
+ }
1001
+ stripeService;
1002
+ constructor(stripeService) {
1003
+ this.stripeService = stripeService;
1004
+ }
1005
+ /**
1006
+ * Create a Stripe Checkout session.
1007
+ */
1008
+ async createCheckoutSession(dto) {
1009
+ const config = this.stripeService.pluginConfig;
1010
+ const session = await this.stripeService.client.checkout.sessions.create({
1011
+ mode: "subscription",
1012
+ payment_method_types: [
1013
+ "card"
1014
+ ],
1015
+ line_items: [
1016
+ {
1017
+ price: dto.priceId,
1018
+ quantity: 1
1019
+ }
1020
+ ],
1021
+ success_url: dto.successUrl,
1022
+ cancel_url: dto.cancelUrl,
1023
+ currency: config.currency ?? "usd",
1024
+ metadata: dto.metadata,
1025
+ client_reference_id: dto.userId
1026
+ });
1027
+ return {
1028
+ sessionId: session.id,
1029
+ url: session.url ?? ""
1030
+ };
1031
+ }
1032
+ };
1033
+ StripeCheckoutService = _ts_decorate11([
1034
+ Injectable(),
1035
+ _ts_metadata11("design:type", Function),
1036
+ _ts_metadata11("design:paramtypes", [
1037
+ typeof StripeService === "undefined" ? Object : StripeService
1038
+ ])
1039
+ ], StripeCheckoutService);
1040
+ }
1041
+ });
1042
+ function _ts_decorate12(decorators, target, key, desc) {
1043
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1044
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1045
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1046
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1047
+ }
1048
+ function _ts_metadata12(k, v) {
1049
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1050
+ }
1051
+ function _ts_param5(paramIndex, decorator) {
1052
+ return function(target, key) {
1053
+ decorator(target, key, paramIndex);
1054
+ };
1055
+ }
1056
+ var StripeMetricsService;
1057
+ var init_metrics_service = __esm({
1058
+ "src/services/metrics.service.ts"() {
1059
+ init_payment_schema();
1060
+ init_subscription_schema();
1061
+ init_stripe_service();
1062
+ __name(_ts_decorate12, "_ts_decorate");
1063
+ __name(_ts_metadata12, "_ts_metadata");
1064
+ __name(_ts_param5, "_ts_param");
1065
+ StripeMetricsService = class {
1066
+ static {
1067
+ __name(this, "StripeMetricsService");
1068
+ }
1069
+ paymentModel;
1070
+ subscriptionModel;
1071
+ stripeService;
1072
+ constructor(paymentModel, subscriptionModel, stripeService) {
1073
+ this.paymentModel = paymentModel;
1074
+ this.subscriptionModel = subscriptionModel;
1075
+ this.stripeService = stripeService;
1076
+ }
1077
+ /**
1078
+ * Get dashboard metrics — hybrid of live Stripe API and local DB data.
1079
+ */
1080
+ async getMetrics() {
1081
+ const [mrr, activeSubscriptions, revenueThisMonth, recentPayments] = await Promise.all([
1082
+ this.calculateMRR(),
1083
+ this.countActiveSubscriptions(),
1084
+ this.calculateRevenueThisMonth(),
1085
+ this.getRecentPayments()
1086
+ ]);
1087
+ const revenueByMonth = await this.getRevenueByMonth();
1088
+ const churnRate = await this.calculateChurnRate();
1089
+ return {
1090
+ mrr,
1091
+ revenueThisMonth,
1092
+ activeSubscriptions,
1093
+ churnRate,
1094
+ revenueByMonth,
1095
+ recentPayments
1096
+ };
1097
+ }
1098
+ /**
1099
+ * Calculate MRR from active subscriptions via live Stripe API.
1100
+ */
1101
+ async calculateMRR() {
1102
+ try {
1103
+ const subscriptions = await this.stripeService.client.subscriptions.list({
1104
+ status: "active",
1105
+ limit: 100
1106
+ });
1107
+ let mrr = 0;
1108
+ for (const sub of subscriptions.data) {
1109
+ for (const item of sub.items.data) {
1110
+ const amount = item.price?.unit_amount ?? 0;
1111
+ const interval = item.price?.recurring?.interval;
1112
+ switch (interval) {
1113
+ case "year":
1114
+ mrr += Math.round(amount / 12);
1115
+ break;
1116
+ case "month":
1117
+ mrr += amount;
1118
+ break;
1119
+ case "week":
1120
+ mrr += Math.round(amount * 4.33);
1121
+ break;
1122
+ case "day":
1123
+ mrr += Math.round(amount * 30);
1124
+ break;
1125
+ }
1126
+ }
1127
+ }
1128
+ return mrr;
1129
+ } catch {
1130
+ return 0;
1131
+ }
1132
+ }
1133
+ async countActiveSubscriptions() {
1134
+ const subs = await this.subscriptionModel.findMany({
1135
+ status: "active"
1136
+ });
1137
+ return subs.length;
1138
+ }
1139
+ async calculateRevenueThisMonth() {
1140
+ const payments = await this.paymentModel.findMany({
1141
+ status: "succeeded"
1142
+ });
1143
+ const now = /* @__PURE__ */ new Date();
1144
+ const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
1145
+ return payments.filter((p) => new Date(p.createdAt) >= startOfMonth).reduce((sum, p) => sum + p.amount, 0);
1146
+ }
1147
+ async calculateChurnRate() {
1148
+ const allSubs = await this.subscriptionModel.find();
1149
+ if (allSubs.length === 0) return 0;
1150
+ const canceled = allSubs.filter((s) => s.status === "canceled");
1151
+ return Math.round(canceled.length / allSubs.length * 100);
1152
+ }
1153
+ async getRevenueByMonth() {
1154
+ const payments = await this.paymentModel.findMany({
1155
+ status: "succeeded"
1156
+ });
1157
+ const monthMap = /* @__PURE__ */ new Map();
1158
+ const now = /* @__PURE__ */ new Date();
1159
+ for (let i = 11; i >= 0; i--) {
1160
+ const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
1161
+ const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
1162
+ monthMap.set(key, 0);
1163
+ }
1164
+ for (const payment of payments) {
1165
+ const d = new Date(payment.createdAt);
1166
+ const key = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, "0")}`;
1167
+ if (monthMap.has(key)) {
1168
+ monthMap.set(key, (monthMap.get(key) ?? 0) + payment.amount);
1169
+ }
1170
+ }
1171
+ return Array.from(monthMap.entries()).map(([month, revenue]) => ({
1172
+ month,
1173
+ revenue
1174
+ }));
1175
+ }
1176
+ async getRecentPayments() {
1177
+ const payments = await this.paymentModel.find();
1178
+ return payments.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()).slice(0, 10).map((p) => ({
1179
+ id: p.id,
1180
+ amount: p.amount,
1181
+ currency: p.currency,
1182
+ status: p.status,
1183
+ customerEmail: p.customerId,
1184
+ createdAt: p.createdAt.toISOString()
1185
+ }));
1186
+ }
1187
+ };
1188
+ StripeMetricsService = _ts_decorate12([
1189
+ Injectable(),
1190
+ _ts_param5(0, InjectModel(StripePayment)),
1191
+ _ts_param5(1, InjectModel(StripeSubscription)),
1192
+ _ts_metadata12("design:type", Function),
1193
+ _ts_metadata12("design:paramtypes", [
1194
+ typeof Model === "undefined" ? Object : Model,
1195
+ typeof Model === "undefined" ? Object : Model,
1196
+ typeof StripeService === "undefined" ? Object : StripeService
1197
+ ])
1198
+ ], StripeMetricsService);
1199
+ }
1200
+ });
1201
+ function _ts_decorate13(decorators, target, key, desc) {
1202
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1203
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1204
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1205
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1206
+ }
1207
+ function _ts_metadata13(k, v) {
1208
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1209
+ }
1210
+ var StripePortalService;
1211
+ var init_portal_service = __esm({
1212
+ "src/services/portal.service.ts"() {
1213
+ init_stripe_service();
1214
+ init_customer_service();
1215
+ __name(_ts_decorate13, "_ts_decorate");
1216
+ __name(_ts_metadata13, "_ts_metadata");
1217
+ StripePortalService = class {
1218
+ static {
1219
+ __name(this, "StripePortalService");
1220
+ }
1221
+ stripeService;
1222
+ customerService;
1223
+ constructor(stripeService, customerService) {
1224
+ this.stripeService = stripeService;
1225
+ this.customerService = customerService;
1226
+ }
1227
+ /**
1228
+ * Create a Stripe Customer Portal session.
1229
+ */
1230
+ async createPortalSession(dto) {
1231
+ let customerId = dto.customerId;
1232
+ if (!customerId && dto.userId) {
1233
+ const customer = await this.customerService.findByUserId(dto.userId);
1234
+ if (!customer) {
1235
+ throw new HttpException("No Stripe customer found for this user", HttpStatus.NOT_FOUND);
1236
+ }
1237
+ customerId = customer.stripeCustomerId;
1238
+ }
1239
+ if (!customerId) {
1240
+ throw new HttpException("Either customerId or userId must be provided", HttpStatus.BAD_REQUEST);
1241
+ }
1242
+ const session = await this.stripeService.client.billingPortal.sessions.create({
1243
+ customer: customerId,
1244
+ return_url: dto.returnUrl
1245
+ });
1246
+ return {
1247
+ sessionId: session.id,
1248
+ url: session.url
1249
+ };
1250
+ }
1251
+ };
1252
+ StripePortalService = _ts_decorate13([
1253
+ Injectable(),
1254
+ _ts_metadata13("design:type", Function),
1255
+ _ts_metadata13("design:paramtypes", [
1256
+ typeof StripeService === "undefined" ? Object : StripeService,
1257
+ typeof StripeCustomerService === "undefined" ? Object : StripeCustomerService
1258
+ ])
1259
+ ], StripePortalService);
1260
+ }
1261
+ });
1262
+ function _ts_decorate14(decorators, target, key, desc) {
1263
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1264
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1265
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1266
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1267
+ }
1268
+ function _ts_metadata14(k, v) {
1269
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1270
+ }
1271
+ function _ts_param6(paramIndex, decorator) {
1272
+ return function(target, key) {
1273
+ decorator(target, key, paramIndex);
1274
+ };
1275
+ }
1276
+ var StripeProductService;
1277
+ var init_product_service = __esm({
1278
+ "src/services/product.service.ts"() {
1279
+ init_price_schema();
1280
+ init_product_schema();
1281
+ __name(_ts_decorate14, "_ts_decorate");
1282
+ __name(_ts_metadata14, "_ts_metadata");
1283
+ __name(_ts_param6, "_ts_param");
1284
+ StripeProductService = class {
1285
+ static {
1286
+ __name(this, "StripeProductService");
1287
+ }
1288
+ productModel;
1289
+ priceModel;
1290
+ constructor(productModel, priceModel) {
1291
+ this.productModel = productModel;
1292
+ this.priceModel = priceModel;
1293
+ }
1294
+ /**
1295
+ * Upsert a product from a Stripe Product object.
1296
+ */
1297
+ async syncProduct(stripeProduct) {
1298
+ const data = {
1299
+ stripeProductId: stripeProduct.id,
1300
+ name: stripeProduct.name,
1301
+ description: stripeProduct.description ?? void 0,
1302
+ active: stripeProduct.active,
1303
+ metadata: stripeProduct.metadata,
1304
+ images: stripeProduct.images,
1305
+ updatedAt: /* @__PURE__ */ new Date()
1306
+ };
1307
+ const existing = await this.productModel.findOne({
1308
+ stripeProductId: stripeProduct.id
1309
+ });
1310
+ if (existing) {
1311
+ return this.productModel.update({
1312
+ stripeProductId: stripeProduct.id
1313
+ }, data);
1314
+ }
1315
+ return this.productModel.create(data);
1316
+ }
1317
+ /**
1318
+ * Upsert a price from a Stripe Price object.
1319
+ */
1320
+ async syncPrice(stripePrice) {
1321
+ const productId = typeof stripePrice.product === "string" ? stripePrice.product : stripePrice.product.id;
1322
+ const data = {
1323
+ stripePriceId: stripePrice.id,
1324
+ productId,
1325
+ unitAmount: stripePrice.unit_amount ?? 0,
1326
+ currency: stripePrice.currency,
1327
+ type: stripePrice.type,
1328
+ interval: stripePrice.recurring?.interval,
1329
+ intervalCount: stripePrice.recurring?.interval_count,
1330
+ active: stripePrice.active
1331
+ };
1332
+ const existing = await this.priceModel.findOne({
1333
+ stripePriceId: stripePrice.id
1334
+ });
1335
+ if (existing) {
1336
+ return this.priceModel.update({
1337
+ stripePriceId: stripePrice.id
1338
+ }, data);
1339
+ }
1340
+ return this.priceModel.create(data);
1341
+ }
1342
+ /**
1343
+ * Delete a product by Stripe Product ID.
1344
+ */
1345
+ async deleteProduct(stripeProductId) {
1346
+ await this.productModel.delete({
1347
+ stripeProductId
1348
+ });
1349
+ }
1350
+ /**
1351
+ * Delete a price by Stripe Price ID.
1352
+ */
1353
+ async deletePrice(stripePriceId) {
1354
+ await this.priceModel.delete({
1355
+ stripePriceId
1356
+ });
1357
+ }
1358
+ /**
1359
+ * List all active products with their prices.
1360
+ */
1361
+ async findActiveProductsWithPrices() {
1362
+ const products = await this.productModel.findMany({
1363
+ active: true
1364
+ });
1365
+ const result = [];
1366
+ for (const product of products) {
1367
+ const prices = await this.priceModel.findMany({
1368
+ productId: product.stripeProductId,
1369
+ active: true
1370
+ });
1371
+ result.push({
1372
+ product,
1373
+ prices
1374
+ });
1375
+ }
1376
+ return result;
1377
+ }
1378
+ /**
1379
+ * List all products.
1380
+ */
1381
+ async findAllProducts() {
1382
+ return this.productModel.find();
1383
+ }
1384
+ /**
1385
+ * List all prices.
1386
+ */
1387
+ async findAllPrices() {
1388
+ return this.priceModel.find();
1389
+ }
1390
+ };
1391
+ StripeProductService = _ts_decorate14([
1392
+ Injectable(),
1393
+ _ts_param6(0, InjectModel(StripeProduct)),
1394
+ _ts_param6(1, InjectModel(StripePrice)),
1395
+ _ts_metadata14("design:type", Function),
1396
+ _ts_metadata14("design:paramtypes", [
1397
+ typeof Model === "undefined" ? Object : Model,
1398
+ typeof Model === "undefined" ? Object : Model
1399
+ ])
1400
+ ], StripeProductService);
1401
+ }
1402
+ });
1403
+ function _ts_decorate15(decorators, target, key, desc) {
1404
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1405
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1406
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1407
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1408
+ }
1409
+ function _ts_metadata15(k, v) {
1410
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1411
+ }
1412
+ function _ts_param7(paramIndex, decorator) {
1413
+ return function(target, key) {
1414
+ decorator(target, key, paramIndex);
1415
+ };
1416
+ }
1417
+ var StripeApiController;
1418
+ var init_stripe_api_controller = __esm({
1419
+ "src/stripe-api.controller.ts"() {
1420
+ init_payment_schema();
1421
+ init_access_service();
1422
+ init_checkout_service();
1423
+ init_customer_service();
1424
+ init_metrics_service();
1425
+ init_portal_service();
1426
+ init_product_service();
1427
+ init_subscription_service();
1428
+ init_stripe_service();
1429
+ __name(_ts_decorate15, "_ts_decorate");
1430
+ __name(_ts_metadata15, "_ts_metadata");
1431
+ __name(_ts_param7, "_ts_param");
1432
+ StripeApiController = class {
1433
+ static {
1434
+ __name(this, "StripeApiController");
1435
+ }
1436
+ accessService;
1437
+ checkoutService;
1438
+ customerService;
1439
+ metricsService;
1440
+ paymentModel;
1441
+ portalService;
1442
+ productService;
1443
+ stripeService;
1444
+ subscriptionService;
1445
+ constructor(accessService, checkoutService, customerService, metricsService, paymentModel, portalService, productService, stripeService, subscriptionService) {
1446
+ this.accessService = accessService;
1447
+ this.checkoutService = checkoutService;
1448
+ this.customerService = customerService;
1449
+ this.metricsService = metricsService;
1450
+ this.paymentModel = paymentModel;
1451
+ this.portalService = portalService;
1452
+ this.productService = productService;
1453
+ this.stripeService = stripeService;
1454
+ this.subscriptionService = subscriptionService;
1455
+ }
1456
+ /**
1457
+ * Create a Stripe Checkout session.
1458
+ * POST /stripe/checkout
1459
+ */
1460
+ async createCheckout(dto) {
1461
+ try {
1462
+ return await this.checkoutService.createCheckoutSession(dto);
1463
+ } catch (error) {
1464
+ if (error instanceof HttpException) throw error;
1465
+ throw new HttpException(error instanceof Error ? error.message : "Failed to create checkout session", HttpStatus.INTERNAL_SERVER_ERROR);
1466
+ }
1467
+ }
1468
+ /**
1469
+ * Create a Stripe Customer Portal session.
1470
+ * POST /stripe/portal
1471
+ */
1472
+ async createPortal(dto) {
1473
+ try {
1474
+ return await this.portalService.createPortalSession(dto);
1475
+ } catch (error) {
1476
+ if (error instanceof HttpException) throw error;
1477
+ throw new HttpException(error instanceof Error ? error.message : "Failed to create portal session", HttpStatus.INTERNAL_SERVER_ERROR);
1478
+ }
1479
+ }
1480
+ /**
1481
+ * List active products with their prices.
1482
+ * GET /stripe/products
1483
+ */
1484
+ async listProducts() {
1485
+ return this.productService.findActiveProductsWithPrices();
1486
+ }
1487
+ /**
1488
+ * Get a user's active subscription.
1489
+ * GET /stripe/subscription/:userId
1490
+ */
1491
+ async getUserSubscription(userId) {
1492
+ const customer = await this.customerService.findByUserId(userId);
1493
+ if (!customer) {
1494
+ return {
1495
+ subscription: null
1496
+ };
1497
+ }
1498
+ const subscription = await this.subscriptionService.findActiveByCustomerId(customer.stripeCustomerId);
1499
+ return {
1500
+ subscription
1501
+ };
1502
+ }
1503
+ /**
1504
+ * Get subscription access info and feature flags for a user.
1505
+ * GET /stripe/access/:userId
1506
+ */
1507
+ async getAccess(userId) {
1508
+ return this.accessService.getAccess(userId);
1509
+ }
1510
+ // =========================================================================
1511
+ // Admin Endpoints
1512
+ // =========================================================================
1513
+ /**
1514
+ * Get dashboard metrics (MRR, revenue, subscriptions).
1515
+ * GET /stripe/admin/metrics
1516
+ */
1517
+ async getMetrics() {
1518
+ return this.metricsService.getMetrics();
1519
+ }
1520
+ /**
1521
+ * List all customers (admin).
1522
+ * GET /stripe/admin/customers
1523
+ */
1524
+ async listCustomers() {
1525
+ return this.customerService.findAll();
1526
+ }
1527
+ /**
1528
+ * List all subscriptions (admin).
1529
+ * GET /stripe/admin/subscriptions
1530
+ */
1531
+ async listSubscriptions() {
1532
+ return this.subscriptionService.findAll();
1533
+ }
1534
+ /**
1535
+ * Cancel a subscription (admin).
1536
+ * POST /stripe/admin/subscriptions/:id/cancel
1537
+ */
1538
+ async cancelSubscription(stripeSubscriptionId) {
1539
+ await this.subscriptionService.cancel(stripeSubscriptionId);
1540
+ return {
1541
+ canceled: true
1542
+ };
1543
+ }
1544
+ /**
1545
+ * List all products (admin).
1546
+ * GET /stripe/admin/products
1547
+ */
1548
+ async listAllProducts() {
1549
+ return this.productService.findAllProducts();
1550
+ }
1551
+ /**
1552
+ * Sync products and prices from Stripe (admin).
1553
+ * POST /stripe/admin/sync-products
1554
+ */
1555
+ async syncProducts() {
1556
+ let productCount = 0;
1557
+ for await (const product of this.stripeService.client.products.list({
1558
+ active: true
1559
+ })) {
1560
+ await this.productService.syncProduct(product);
1561
+ productCount++;
1562
+ }
1563
+ let priceCount = 0;
1564
+ for await (const price of this.stripeService.client.prices.list({
1565
+ active: true
1566
+ })) {
1567
+ await this.productService.syncPrice(price);
1568
+ priceCount++;
1569
+ }
1570
+ return {
1571
+ synced: true,
1572
+ products: productCount,
1573
+ prices: priceCount
1574
+ };
1575
+ }
1576
+ /**
1577
+ * List all payments (admin).
1578
+ * GET /stripe/admin/payments
1579
+ */
1580
+ async listPayments() {
1581
+ return this.paymentModel.find();
1582
+ }
1583
+ /**
1584
+ * Refund a payment (admin).
1585
+ * POST /stripe/admin/payments/:id/refund
1586
+ */
1587
+ async refundPayment(paymentIntentId) {
1588
+ try {
1589
+ await this.stripeService.client.refunds.create({
1590
+ payment_intent: paymentIntentId
1591
+ });
1592
+ } catch (error) {
1593
+ const message = error instanceof Error ? error.message : "Refund failed";
1594
+ throw new HttpException(message, HttpStatus.BAD_REQUEST);
1595
+ }
1596
+ await this.paymentModel.update({
1597
+ stripePaymentIntentId: paymentIntentId
1598
+ }, {
1599
+ status: "refunded"
1600
+ });
1601
+ return {
1602
+ refunded: true
1603
+ };
1604
+ }
1605
+ };
1606
+ _ts_decorate15([
1607
+ Post("checkout"),
1608
+ _ts_param7(0, Body()),
1609
+ _ts_metadata15("design:type", Function),
1610
+ _ts_metadata15("design:paramtypes", [
1611
+ typeof CreateCheckoutDto === "undefined" ? Object : CreateCheckoutDto
1612
+ ]),
1613
+ _ts_metadata15("design:returntype", Promise)
1614
+ ], StripeApiController.prototype, "createCheckout", null);
1615
+ _ts_decorate15([
1616
+ Post("portal"),
1617
+ _ts_param7(0, Body()),
1618
+ _ts_metadata15("design:type", Function),
1619
+ _ts_metadata15("design:paramtypes", [
1620
+ typeof CreatePortalDto === "undefined" ? Object : CreatePortalDto
1621
+ ]),
1622
+ _ts_metadata15("design:returntype", Promise)
1623
+ ], StripeApiController.prototype, "createPortal", null);
1624
+ _ts_decorate15([
1625
+ Get("products"),
1626
+ _ts_metadata15("design:type", Function),
1627
+ _ts_metadata15("design:paramtypes", []),
1628
+ _ts_metadata15("design:returntype", Promise)
1629
+ ], StripeApiController.prototype, "listProducts", null);
1630
+ _ts_decorate15([
1631
+ Get("subscription/:userId"),
1632
+ _ts_param7(0, Param("userId")),
1633
+ _ts_metadata15("design:type", Function),
1634
+ _ts_metadata15("design:paramtypes", [
1635
+ String
1636
+ ]),
1637
+ _ts_metadata15("design:returntype", Promise)
1638
+ ], StripeApiController.prototype, "getUserSubscription", null);
1639
+ _ts_decorate15([
1640
+ Get("access/:userId"),
1641
+ RestrictedRoute(),
1642
+ _ts_param7(0, Param("userId")),
1643
+ _ts_metadata15("design:type", Function),
1644
+ _ts_metadata15("design:paramtypes", [
1645
+ String
1646
+ ]),
1647
+ _ts_metadata15("design:returntype", Promise)
1648
+ ], StripeApiController.prototype, "getAccess", null);
1649
+ _ts_decorate15([
1650
+ Get("admin/metrics"),
1651
+ RestrictedRoute(),
1652
+ _ts_metadata15("design:type", Function),
1653
+ _ts_metadata15("design:paramtypes", []),
1654
+ _ts_metadata15("design:returntype", Promise)
1655
+ ], StripeApiController.prototype, "getMetrics", null);
1656
+ _ts_decorate15([
1657
+ Get("admin/customers"),
1658
+ RestrictedRoute(),
1659
+ _ts_metadata15("design:type", Function),
1660
+ _ts_metadata15("design:paramtypes", []),
1661
+ _ts_metadata15("design:returntype", Promise)
1662
+ ], StripeApiController.prototype, "listCustomers", null);
1663
+ _ts_decorate15([
1664
+ Get("admin/subscriptions"),
1665
+ RestrictedRoute(),
1666
+ _ts_metadata15("design:type", Function),
1667
+ _ts_metadata15("design:paramtypes", []),
1668
+ _ts_metadata15("design:returntype", Promise)
1669
+ ], StripeApiController.prototype, "listSubscriptions", null);
1670
+ _ts_decorate15([
1671
+ Post("admin/subscriptions/:id/cancel"),
1672
+ RestrictedRoute(),
1673
+ _ts_param7(0, Param("id")),
1674
+ _ts_metadata15("design:type", Function),
1675
+ _ts_metadata15("design:paramtypes", [
1676
+ String
1677
+ ]),
1678
+ _ts_metadata15("design:returntype", Promise)
1679
+ ], StripeApiController.prototype, "cancelSubscription", null);
1680
+ _ts_decorate15([
1681
+ Get("admin/products"),
1682
+ RestrictedRoute(),
1683
+ _ts_metadata15("design:type", Function),
1684
+ _ts_metadata15("design:paramtypes", []),
1685
+ _ts_metadata15("design:returntype", Promise)
1686
+ ], StripeApiController.prototype, "listAllProducts", null);
1687
+ _ts_decorate15([
1688
+ Post("admin/sync-products"),
1689
+ RestrictedRoute(),
1690
+ _ts_metadata15("design:type", Function),
1691
+ _ts_metadata15("design:paramtypes", []),
1692
+ _ts_metadata15("design:returntype", Promise)
1693
+ ], StripeApiController.prototype, "syncProducts", null);
1694
+ _ts_decorate15([
1695
+ Get("admin/payments"),
1696
+ RestrictedRoute(),
1697
+ _ts_metadata15("design:type", Function),
1698
+ _ts_metadata15("design:paramtypes", []),
1699
+ _ts_metadata15("design:returntype", Promise)
1700
+ ], StripeApiController.prototype, "listPayments", null);
1701
+ _ts_decorate15([
1702
+ Post("admin/payments/:id/refund"),
1703
+ RestrictedRoute(),
1704
+ _ts_param7(0, Param("id")),
1705
+ _ts_metadata15("design:type", Function),
1706
+ _ts_metadata15("design:paramtypes", [
1707
+ String
1708
+ ]),
1709
+ _ts_metadata15("design:returntype", Promise)
1710
+ ], StripeApiController.prototype, "refundPayment", null);
1711
+ StripeApiController = _ts_decorate15([
1712
+ Controller("stripe"),
1713
+ _ts_param7(4, InjectModel(StripePayment)),
1714
+ _ts_metadata15("design:type", Function),
1715
+ _ts_metadata15("design:paramtypes", [
1716
+ typeof StripeAccessService === "undefined" ? Object : StripeAccessService,
1717
+ typeof StripeCheckoutService === "undefined" ? Object : StripeCheckoutService,
1718
+ typeof StripeCustomerService === "undefined" ? Object : StripeCustomerService,
1719
+ typeof StripeMetricsService === "undefined" ? Object : StripeMetricsService,
1720
+ typeof Model === "undefined" ? Object : Model,
1721
+ typeof StripePortalService === "undefined" ? Object : StripePortalService,
1722
+ typeof StripeProductService === "undefined" ? Object : StripeProductService,
1723
+ typeof StripeService === "undefined" ? Object : StripeService,
1724
+ typeof StripeSubscriptionService === "undefined" ? Object : StripeSubscriptionService
1725
+ ])
1726
+ ], StripeApiController);
1727
+ }
1728
+ });
1729
+ function _ts_decorate16(decorators, target, key, desc) {
1730
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1731
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1732
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1733
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1734
+ }
1735
+ function _ts_metadata16(k, v) {
1736
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1737
+ }
1738
+ function _ts_param8(paramIndex, decorator) {
1739
+ return function(target, key) {
1740
+ decorator(target, key, paramIndex);
1741
+ };
1742
+ }
1743
+ var StripeWebhookService;
1744
+ var init_stripe_webhook_service = __esm({
1745
+ "src/stripe-webhook.service.ts"() {
1746
+ init_payment_schema();
1747
+ init_processed_event_schema();
1748
+ init_customer_service();
1749
+ init_product_service();
1750
+ init_subscription_service();
1751
+ __name(_ts_decorate16, "_ts_decorate");
1752
+ __name(_ts_metadata16, "_ts_metadata");
1753
+ __name(_ts_param8, "_ts_param");
1754
+ StripeWebhookService = class _StripeWebhookService {
1755
+ static {
1756
+ __name(this, "StripeWebhookService");
1757
+ }
1758
+ processedEventModel;
1759
+ paymentModel;
1760
+ customerService;
1761
+ productService;
1762
+ subscriptionService;
1763
+ emailService;
1764
+ logger;
1765
+ constructor(processedEventModel, paymentModel, customerService, productService, subscriptionService, emailService) {
1766
+ this.processedEventModel = processedEventModel;
1767
+ this.paymentModel = paymentModel;
1768
+ this.customerService = customerService;
1769
+ this.productService = productService;
1770
+ this.subscriptionService = subscriptionService;
1771
+ this.emailService = emailService;
1772
+ this.logger = new Logger(_StripeWebhookService.name);
1773
+ }
1774
+ /**
1775
+ * Process a verified Stripe event with idempotency.
1776
+ * Returns silently if the event was already processed.
1777
+ */
1778
+ async processEvent(event) {
1779
+ const existing = await this.findProcessedEvent(event.id);
1780
+ if (existing) {
1781
+ this.logger.log(`Event ${event.id} already processed, skipping`);
1782
+ return;
1783
+ }
1784
+ try {
1785
+ await this.dispatchEvent(event);
1786
+ await this.recordProcessedEvent(event.id, event.type);
1787
+ } catch (error) {
1788
+ this.logger.error(`Failed to process event ${event.id} (${event.type}): ${error instanceof Error ? error.message : String(error)}`);
1789
+ }
1790
+ }
1791
+ /**
1792
+ * Dispatch event to the appropriate handler.
1793
+ */
1794
+ async dispatchEvent(event) {
1795
+ switch (event.type) {
1796
+ case "checkout.session.completed":
1797
+ await this.handleCheckoutCompleted(event.data.object);
1798
+ break;
1799
+ case "customer.created":
1800
+ case "customer.updated":
1801
+ await this.customerService.upsertFromStripe(event.data.object);
1802
+ break;
1803
+ case "customer.deleted":
1804
+ await this.customerService.deleteByStripeId(event.data.object.id);
1805
+ break;
1806
+ case "customer.subscription.created":
1807
+ case "customer.subscription.updated":
1808
+ await this.subscriptionService.syncSubscription(event.data.object);
1809
+ break;
1810
+ case "customer.subscription.deleted":
1811
+ await this.subscriptionService.deleteByStripeId(event.data.object.id);
1812
+ break;
1813
+ case "invoice.paid":
1814
+ await this.handleInvoicePaid(event.data.object);
1815
+ break;
1816
+ case "invoice.payment_failed":
1817
+ await this.handleInvoicePaymentFailed(event.data.object);
1818
+ break;
1819
+ case "product.created":
1820
+ case "product.updated":
1821
+ await this.productService.syncProduct(event.data.object);
1822
+ break;
1823
+ case "product.deleted":
1824
+ await this.productService.deleteProduct(event.data.object.id);
1825
+ break;
1826
+ case "price.created":
1827
+ case "price.updated":
1828
+ await this.productService.syncPrice(event.data.object);
1829
+ break;
1830
+ case "price.deleted":
1831
+ await this.productService.deletePrice(event.data.object.id);
1832
+ break;
1833
+ default:
1834
+ this.logger.log(`Unhandled event type: ${event.type}`);
1835
+ }
1836
+ }
1837
+ // =========================================================================
1838
+ // Event Handlers — complex events that touch multiple services
1839
+ // =========================================================================
1840
+ async handleCheckoutCompleted(session) {
1841
+ this.logger.log(`checkout.session.completed: ${session.id}`);
1842
+ if (session.customer) {
1843
+ const customerId = typeof session.customer === "string" ? session.customer : session.customer.id;
1844
+ this.logger.log(`Checkout customer: ${customerId}`);
1845
+ }
1846
+ if (session.payment_intent && session.amount_total !== null) {
1847
+ const paymentIntentId = typeof session.payment_intent === "string" ? session.payment_intent : session.payment_intent.id;
1848
+ const customerId = typeof session.customer === "string" ? session.customer : session.customer?.id ?? "";
1849
+ await this.paymentModel.create({
1850
+ stripePaymentIntentId: paymentIntentId,
1851
+ customerId,
1852
+ amount: session.amount_total,
1853
+ currency: session.currency ?? "usd",
1854
+ status: "succeeded",
1855
+ createdAt: /* @__PURE__ */ new Date()
1856
+ });
1857
+ }
1858
+ }
1859
+ async handleInvoicePaid(invoice) {
1860
+ this.logger.log(`invoice.paid: ${invoice.id}`);
1861
+ const customerId = typeof invoice.customer === "string" ? invoice.customer : invoice.customer?.id ?? "";
1862
+ if (invoice.payment_intent) {
1863
+ const paymentIntentId = typeof invoice.payment_intent === "string" ? invoice.payment_intent : invoice.payment_intent.id;
1864
+ const existing = await this.paymentModel.findOne({
1865
+ stripePaymentIntentId: paymentIntentId
1866
+ });
1867
+ if (!existing) {
1868
+ await this.paymentModel.create({
1869
+ stripePaymentIntentId: paymentIntentId,
1870
+ customerId,
1871
+ amount: invoice.amount_paid,
1872
+ currency: invoice.currency,
1873
+ status: "succeeded",
1874
+ receiptUrl: invoice.hosted_invoice_url ?? void 0,
1875
+ invoiceId: invoice.id ?? void 0,
1876
+ createdAt: /* @__PURE__ */ new Date()
1877
+ });
1878
+ }
1879
+ }
1880
+ await this.sendReceiptEmail(invoice);
1881
+ }
1882
+ async handleInvoicePaymentFailed(invoice) {
1883
+ this.logger.log(`invoice.payment_failed: ${invoice.id}`);
1884
+ const customerId = typeof invoice.customer === "string" ? invoice.customer : invoice.customer?.id ?? "";
1885
+ if (invoice.payment_intent) {
1886
+ const paymentIntentId = typeof invoice.payment_intent === "string" ? invoice.payment_intent : invoice.payment_intent.id;
1887
+ const existing = await this.paymentModel.findOne({
1888
+ stripePaymentIntentId: paymentIntentId
1889
+ });
1890
+ if (!existing) {
1891
+ await this.paymentModel.create({
1892
+ stripePaymentIntentId: paymentIntentId,
1893
+ customerId,
1894
+ amount: invoice.amount_due,
1895
+ currency: invoice.currency,
1896
+ status: "failed",
1897
+ invoiceId: invoice.id ?? void 0,
1898
+ createdAt: /* @__PURE__ */ new Date()
1899
+ });
1900
+ }
1901
+ }
1902
+ await this.sendPaymentFailedEmail(invoice);
1903
+ }
1904
+ // =========================================================================
1905
+ // Email Helpers
1906
+ // =========================================================================
1907
+ async sendReceiptEmail(invoice) {
1908
+ if (!this.emailService) return;
1909
+ const email = typeof invoice.customer_email === "string" ? invoice.customer_email : null;
1910
+ if (!email) return;
1911
+ try {
1912
+ await this.emailService.send(email, "Payment Receipt", "stripe-receipt", {
1913
+ amount: (invoice.amount_paid / 100).toFixed(2),
1914
+ currency: invoice.currency.toUpperCase(),
1915
+ invoiceUrl: invoice.hosted_invoice_url ?? "",
1916
+ date: (/* @__PURE__ */ new Date()).toLocaleDateString()
1917
+ });
1918
+ } catch (error) {
1919
+ this.logger.warn(`Failed to send receipt email: ${error instanceof Error ? error.message : String(error)}`);
1920
+ }
1921
+ }
1922
+ async sendPaymentFailedEmail(invoice) {
1923
+ if (!this.emailService) return;
1924
+ const email = typeof invoice.customer_email === "string" ? invoice.customer_email : null;
1925
+ if (!email) return;
1926
+ try {
1927
+ await this.emailService.send(email, "Payment Failed", "stripe-payment-failed", {
1928
+ amount: (invoice.amount_due / 100).toFixed(2),
1929
+ currency: invoice.currency.toUpperCase(),
1930
+ invoiceUrl: invoice.hosted_invoice_url ?? "",
1931
+ date: (/* @__PURE__ */ new Date()).toLocaleDateString()
1932
+ });
1933
+ } catch (error) {
1934
+ this.logger.warn(`Failed to send payment failed email: ${error instanceof Error ? error.message : String(error)}`);
1935
+ }
1936
+ }
1937
+ // =========================================================================
1938
+ // Idempotency Helpers
1939
+ // =========================================================================
1940
+ async findProcessedEvent(eventId) {
1941
+ const result = await this.processedEventModel.findOne({
1942
+ stripeEventId: eventId
1943
+ });
1944
+ return result !== null;
1945
+ }
1946
+ async recordProcessedEvent(eventId, eventType) {
1947
+ try {
1948
+ await this.processedEventModel.create({
1949
+ stripeEventId: eventId,
1950
+ eventType,
1951
+ processedAt: /* @__PURE__ */ new Date()
1952
+ });
1953
+ } catch (error) {
1954
+ this.logger.warn(`Failed to record processed event ${eventId}: ${error instanceof Error ? error.message : String(error)}`);
1955
+ }
1956
+ }
1957
+ };
1958
+ StripeWebhookService = _ts_decorate16([
1959
+ Injectable(),
1960
+ _ts_param8(0, InjectModel(StripeProcessedEvent)),
1961
+ _ts_param8(1, InjectModel(StripePayment)),
1962
+ _ts_param8(5, Optional()),
1963
+ _ts_metadata16("design:type", Function),
1964
+ _ts_metadata16("design:paramtypes", [
1965
+ typeof Model === "undefined" ? Object : Model,
1966
+ typeof Model === "undefined" ? Object : Model,
1967
+ typeof StripeCustomerService === "undefined" ? Object : StripeCustomerService,
1968
+ typeof StripeProductService === "undefined" ? Object : StripeProductService,
1969
+ typeof StripeSubscriptionService === "undefined" ? Object : StripeSubscriptionService,
1970
+ typeof EmailService === "undefined" ? Object : EmailService
1971
+ ])
1972
+ ], StripeWebhookService);
1973
+ }
1974
+ });
1975
+ function _ts_decorate17(decorators, target, key, desc) {
1976
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1977
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1978
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1979
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
1980
+ }
1981
+ function _ts_metadata17(k, v) {
1982
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
1983
+ }
1984
+ function _ts_param9(paramIndex, decorator) {
1985
+ return function(target, key) {
1986
+ decorator(target, key, paramIndex);
1987
+ };
1988
+ }
1989
+ var StripeWebhookController;
1990
+ var init_stripe_webhook_controller = __esm({
1991
+ "src/stripe-webhook.controller.ts"() {
1992
+ init_stripe_webhook_service();
1993
+ init_stripe_service();
1994
+ __name(_ts_decorate17, "_ts_decorate");
1995
+ __name(_ts_metadata17, "_ts_metadata");
1996
+ __name(_ts_param9, "_ts_param");
1997
+ StripeWebhookController = class {
1998
+ static {
1999
+ __name(this, "StripeWebhookController");
2000
+ }
2001
+ stripeService;
2002
+ webhookService;
2003
+ constructor(stripeService, webhookService) {
2004
+ this.stripeService = stripeService;
2005
+ this.webhookService = webhookService;
2006
+ }
2007
+ async handleWebhook(req, signature) {
2008
+ this.stripeService.verifyRawBodyAvailable(req);
2009
+ const { webhookSecret } = this.stripeService.pluginConfig;
2010
+ if (!webhookSecret) {
2011
+ throw new Error("[StripePlugin] webhookSecret is required for webhook verification");
2012
+ }
2013
+ const event = this.stripeService.client.webhooks.constructEvent(req.rawBody, signature, webhookSecret);
2014
+ await this.webhookService.processEvent(event);
2015
+ return {
2016
+ received: true
2017
+ };
2018
+ }
2019
+ };
2020
+ _ts_decorate17([
2021
+ Post(),
2022
+ HttpCode(200),
2023
+ _ts_param9(0, Req()),
2024
+ _ts_param9(1, Headers("stripe-signature")),
2025
+ _ts_metadata17("design:type", Function),
2026
+ _ts_metadata17("design:paramtypes", [
2027
+ Object,
2028
+ String
2029
+ ]),
2030
+ _ts_metadata17("design:returntype", Promise)
2031
+ ], StripeWebhookController.prototype, "handleWebhook", null);
2032
+ StripeWebhookController = _ts_decorate17([
2033
+ Controller("stripe/webhooks"),
2034
+ _ts_metadata17("design:type", Function),
2035
+ _ts_metadata17("design:paramtypes", [
2036
+ typeof StripeService === "undefined" ? Object : StripeService,
2037
+ typeof StripeWebhookService === "undefined" ? Object : StripeWebhookService
2038
+ ])
2039
+ ], StripeWebhookController);
2040
+ }
2041
+ });
2042
+
2043
+ // src/stripe.module.ts
2044
+ var stripe_module_exports = {};
2045
+ __export(stripe_module_exports, {
2046
+ StripeModule: () => StripeModule
2047
+ });
2048
+ function _ts_decorate18(decorators, target, key, desc) {
2049
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2050
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2051
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2052
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2053
+ }
2054
+ var StripeModule;
2055
+ var init_stripe_module = __esm({
2056
+ "src/stripe.module.ts"() {
2057
+ init_customer_schema();
2058
+ init_payment_schema();
2059
+ init_price_schema();
2060
+ init_processed_event_schema();
2061
+ init_product_schema();
2062
+ init_subscription_schema();
2063
+ init_access_service();
2064
+ init_checkout_service();
2065
+ init_customer_service();
2066
+ init_metrics_service();
2067
+ init_portal_service();
2068
+ init_product_service();
2069
+ init_subscription_service();
2070
+ init_stripe_api_controller();
2071
+ init_stripe_webhook_controller();
2072
+ init_stripe_webhook_service();
2073
+ init_stripe_service();
2074
+ __name(_ts_decorate18, "_ts_decorate");
2075
+ StripeModule = class {
2076
+ static {
2077
+ __name(this, "StripeModule");
2078
+ }
2079
+ };
2080
+ StripeModule = _ts_decorate18([
2081
+ Module({
2082
+ imports: [
2083
+ DatabaseModule.forFeature(StripeCustomer),
2084
+ DatabaseModule.forFeature(StripeProduct),
2085
+ DatabaseModule.forFeature(StripePrice),
2086
+ DatabaseModule.forFeature(StripeSubscription),
2087
+ DatabaseModule.forFeature(StripePayment),
2088
+ DatabaseModule.forFeature(StripeProcessedEvent)
2089
+ ],
2090
+ controllers: [
2091
+ StripeApiController,
2092
+ StripeWebhookController
2093
+ ],
2094
+ providers: [
2095
+ StripeService,
2096
+ StripeWebhookService,
2097
+ StripeCustomerService,
2098
+ StripeProductService,
2099
+ StripeSubscriptionService,
2100
+ StripeCheckoutService,
2101
+ StripePortalService,
2102
+ StripeAccessService,
2103
+ StripeMetricsService
2104
+ ],
2105
+ exports: [
2106
+ StripeService,
2107
+ StripeCustomerService,
2108
+ StripeProductService,
2109
+ StripeSubscriptionService,
2110
+ StripeCheckoutService,
2111
+ StripePortalService,
2112
+ StripeAccessService
2113
+ ]
2114
+ })
2115
+ ], StripeModule);
2116
+ }
2117
+ });
2118
+ function _ts_decorate19(decorators, target, key, desc) {
2119
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
2120
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
2121
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
2122
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
2123
+ }
2124
+ __name(_ts_decorate19, "_ts_decorate");
2125
+ var StripePlugin = class _StripePlugin {
2126
+ static {
2127
+ __name(this, "StripePlugin");
2128
+ }
2129
+ /** Environment variables used by this plugin */
2130
+ static envVars = [
2131
+ {
2132
+ name: "STRIPE_SECRET_KEY",
2133
+ required: true,
2134
+ description: "Stripe API secret key"
2135
+ },
2136
+ {
2137
+ name: "STRIPE_WEBHOOK_SECRET",
2138
+ required: true,
2139
+ description: "Stripe webhook signing secret"
2140
+ },
2141
+ {
2142
+ name: "STRIPE_PUBLISHABLE_KEY",
2143
+ required: false,
2144
+ description: "Stripe publishable key"
2145
+ }
2146
+ ];
2147
+ /**
2148
+ * Create a configured plugin provider for MagnetModule.forRoot().
2149
+ * Auto-resolves secret values from environment variables if not provided.
2150
+ *
2151
+ * @example
2152
+ * ```typescript
2153
+ * MagnetModule.forRoot([
2154
+ * StripePlugin.forRoot({ currency: 'usd' }),
2155
+ * ])
2156
+ * ```
2157
+ */
2158
+ static forRoot(config) {
2159
+ const resolvedConfig = {
2160
+ secretKey: config?.secretKey ?? process.env.STRIPE_SECRET_KEY,
2161
+ webhookSecret: config?.webhookSecret ?? process.env.STRIPE_WEBHOOK_SECRET,
2162
+ publishableKey: config?.publishableKey ?? process.env.STRIPE_PUBLISHABLE_KEY,
2163
+ syncProducts: config?.syncProducts,
2164
+ portalEnabled: config?.portalEnabled,
2165
+ currency: config?.currency,
2166
+ features: config?.features
2167
+ };
2168
+ return {
2169
+ type: "plugin",
2170
+ plugin: _StripePlugin,
2171
+ options: resolvedConfig,
2172
+ envVars: _StripePlugin.envVars
2173
+ };
2174
+ }
2175
+ };
2176
+ StripePlugin = _ts_decorate19([
2177
+ Plugin({
2178
+ name: "stripe",
2179
+ description: "Stripe payments plugin for Magnet CMS",
2180
+ version: "0.1.0",
2181
+ module: /* @__PURE__ */ __name(() => (init_stripe_module(), __toCommonJS(stripe_module_exports)).StripeModule, "module"),
2182
+ frontend: {
2183
+ routes: [
2184
+ {
2185
+ path: "stripe",
2186
+ componentId: "StripeDashboard",
2187
+ requiresAuth: true,
2188
+ children: [
2189
+ {
2190
+ path: "",
2191
+ componentId: "StripeDashboard"
2192
+ },
2193
+ {
2194
+ path: "customers",
2195
+ componentId: "StripeCustomers"
2196
+ },
2197
+ {
2198
+ path: "products",
2199
+ componentId: "StripeProducts"
2200
+ },
2201
+ {
2202
+ path: "subscriptions",
2203
+ componentId: "StripeSubscriptions"
2204
+ },
2205
+ {
2206
+ path: "payments",
2207
+ componentId: "StripePayments"
2208
+ }
2209
+ ]
2210
+ }
2211
+ ],
2212
+ sidebar: [
2213
+ {
2214
+ id: "stripe",
2215
+ title: "Stripe Payments",
2216
+ url: "/stripe",
2217
+ icon: "CreditCard",
2218
+ order: 30,
2219
+ items: [
2220
+ {
2221
+ id: "stripe-dashboard",
2222
+ title: "Dashboard",
2223
+ url: "/stripe",
2224
+ icon: "BarChart3"
2225
+ },
2226
+ {
2227
+ id: "stripe-customers",
2228
+ title: "Customers",
2229
+ url: "/stripe/customers",
2230
+ icon: "Users"
2231
+ },
2232
+ {
2233
+ id: "stripe-products",
2234
+ title: "Products",
2235
+ url: "/stripe/products",
2236
+ icon: "Package"
2237
+ },
2238
+ {
2239
+ id: "stripe-subscriptions",
2240
+ title: "Subscriptions",
2241
+ url: "/stripe/subscriptions",
2242
+ icon: "RefreshCw"
2243
+ },
2244
+ {
2245
+ id: "stripe-payments",
2246
+ title: "Payments",
2247
+ url: "/stripe/payments",
2248
+ icon: "Receipt"
2249
+ }
2250
+ ]
2251
+ }
2252
+ ]
2253
+ }
2254
+ })
2255
+ ], StripePlugin);
2256
+
2257
+ export { StripeAccessService, StripeCheckoutService, StripeCustomer, StripeCustomerService, StripeMetricsService, StripeModule, StripePayment, StripePlugin, StripePortalService, StripePrice, StripeProcessedEvent, StripeProduct, StripeProductService, StripeService, StripeSubscription, StripeSubscriptionService, init_access_service, init_checkout_service, init_customer_schema, init_customer_service, init_metrics_service, init_payment_schema, init_portal_service, init_price_schema, init_processed_event_schema, init_product_schema, init_product_service, init_stripe_module, init_stripe_service, init_subscription_schema, init_subscription_service };