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