@forklaunch/implementation-billing-stripe 0.2.4 → 0.2.6
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/lib/domain/enum/index.d.mts +119 -112
- package/lib/domain/enum/index.d.ts +119 -112
- package/lib/domain/enum/index.js +124 -119
- package/lib/domain/enum/index.mjs +109 -109
- package/lib/domain/schemas/index.d.mts +2908 -317
- package/lib/domain/schemas/index.d.ts +2908 -317
- package/lib/domain/schemas/index.js +257 -181
- package/lib/domain/schemas/index.mjs +131 -130
- package/lib/domain/types/index.d.mts +231 -72
- package/lib/domain/types/index.d.ts +231 -72
- package/lib/domain/types/index.js +8 -4
- package/lib/services/index.d.mts +709 -194
- package/lib/services/index.d.ts +709 -194
- package/lib/services/index.js +356 -241
- package/lib/services/index.mjs +295 -202
- package/package.json +9 -9
package/lib/services/index.mjs
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
// services/billingPortal.service.ts
|
|
2
|
-
import { BaseBillingPortalService } from
|
|
2
|
+
import { BaseBillingPortalService } from '@forklaunch/implementation-billing-base/services';
|
|
3
3
|
import {
|
|
4
4
|
IdentityRequestMapper,
|
|
5
5
|
IdentityResponseMapper,
|
|
6
6
|
transformIntoInternalMapper
|
|
7
|
-
} from
|
|
7
|
+
} from '@forklaunch/internal';
|
|
8
8
|
var StripeBillingPortalService = class {
|
|
9
|
-
constructor(
|
|
9
|
+
constructor(
|
|
10
|
+
stripeClient,
|
|
11
|
+
em,
|
|
12
|
+
cache,
|
|
13
|
+
openTelemetryCollector,
|
|
14
|
+
schemaValidator,
|
|
15
|
+
mappers,
|
|
16
|
+
options
|
|
17
|
+
) {
|
|
10
18
|
this.options = options;
|
|
11
19
|
this.stripeClient = stripeClient;
|
|
12
20
|
this.em = em;
|
|
@@ -42,26 +50,28 @@ var StripeBillingPortalService = class {
|
|
|
42
50
|
...billingPortalDto.stripeFields,
|
|
43
51
|
customer: billingPortalDto.customerId
|
|
44
52
|
});
|
|
45
|
-
const billingPortalEntity =
|
|
46
|
-
await this.
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
Date
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
53
|
+
const billingPortalEntity =
|
|
54
|
+
await this.baseBillingPortalService.createBillingPortalSession(
|
|
55
|
+
await this._mappers.CreateBillingPortalMapper.deserializeDtoToEntity(
|
|
56
|
+
{
|
|
57
|
+
...billingPortalDto,
|
|
58
|
+
id: session.id,
|
|
59
|
+
uri: session.url,
|
|
60
|
+
expiresAt: new Date(
|
|
61
|
+
Date.now() + this.billingPortalSessionExpiryDurationMs
|
|
62
|
+
)
|
|
63
|
+
},
|
|
64
|
+
this.em,
|
|
65
|
+
session
|
|
66
|
+
)
|
|
67
|
+
);
|
|
59
68
|
return this._mappers.BillingPortalMapper.serializeEntityToDto(
|
|
60
69
|
billingPortalEntity
|
|
61
70
|
);
|
|
62
71
|
}
|
|
63
72
|
async getBillingPortalSession(idDto) {
|
|
64
|
-
const billingPortalEntity =
|
|
73
|
+
const billingPortalEntity =
|
|
74
|
+
await this.baseBillingPortalService.getBillingPortalSession(idDto);
|
|
65
75
|
return this._mappers.BillingPortalMapper.serializeEntityToDto(
|
|
66
76
|
billingPortalEntity
|
|
67
77
|
);
|
|
@@ -70,27 +80,29 @@ var StripeBillingPortalService = class {
|
|
|
70
80
|
return this.baseBillingPortalService.expireBillingPortalSession(idDto);
|
|
71
81
|
}
|
|
72
82
|
async updateBillingPortalSession(billingPortalDto) {
|
|
73
|
-
const existingSession =
|
|
74
|
-
|
|
75
|
-
|
|
83
|
+
const existingSession =
|
|
84
|
+
await this.baseBillingPortalService.getBillingPortalSession({
|
|
85
|
+
id: billingPortalDto.id
|
|
86
|
+
});
|
|
76
87
|
const session = await this.stripeClient.billingPortal.sessions.create({
|
|
77
88
|
...billingPortalDto.stripeFields,
|
|
78
89
|
customer: existingSession.customerId
|
|
79
90
|
});
|
|
80
|
-
const baseBillingPortalDto =
|
|
81
|
-
await this.
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
Date
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
const baseBillingPortalDto =
|
|
92
|
+
await this.baseBillingPortalService.updateBillingPortalSession(
|
|
93
|
+
await this._mappers.UpdateBillingPortalMapper.deserializeDtoToEntity(
|
|
94
|
+
{
|
|
95
|
+
...billingPortalDto,
|
|
96
|
+
id: session.id,
|
|
97
|
+
uri: session.url,
|
|
98
|
+
expiresAt: new Date(
|
|
99
|
+
Date.now() + this.billingPortalSessionExpiryDurationMs
|
|
100
|
+
)
|
|
101
|
+
},
|
|
102
|
+
this.em,
|
|
103
|
+
session
|
|
104
|
+
)
|
|
105
|
+
);
|
|
94
106
|
return this._mappers.BillingPortalMapper.serializeEntityToDto(
|
|
95
107
|
baseBillingPortalDto
|
|
96
108
|
);
|
|
@@ -98,14 +110,22 @@ var StripeBillingPortalService = class {
|
|
|
98
110
|
};
|
|
99
111
|
|
|
100
112
|
// services/checkoutSession.service.ts
|
|
101
|
-
import { BaseCheckoutSessionService } from
|
|
113
|
+
import { BaseCheckoutSessionService } from '@forklaunch/implementation-billing-base/services';
|
|
102
114
|
import {
|
|
103
115
|
IdentityRequestMapper as IdentityRequestMapper2,
|
|
104
116
|
IdentityResponseMapper as IdentityResponseMapper2,
|
|
105
117
|
transformIntoInternalMapper as transformIntoInternalMapper2
|
|
106
|
-
} from
|
|
118
|
+
} from '@forklaunch/internal';
|
|
107
119
|
var StripeCheckoutSessionService = class {
|
|
108
|
-
constructor(
|
|
120
|
+
constructor(
|
|
121
|
+
stripeClient,
|
|
122
|
+
em,
|
|
123
|
+
cache,
|
|
124
|
+
openTelemetryCollector,
|
|
125
|
+
schemaValidator,
|
|
126
|
+
mappers,
|
|
127
|
+
options
|
|
128
|
+
) {
|
|
109
129
|
this.options = options;
|
|
110
130
|
this.stripeClient = stripeClient;
|
|
111
131
|
this.em = em;
|
|
@@ -143,27 +163,27 @@ var StripeCheckoutSessionService = class {
|
|
|
143
163
|
success_url: checkoutSessionDto.successRedirectUri,
|
|
144
164
|
cancel_url: checkoutSessionDto.cancelRedirectUri
|
|
145
165
|
});
|
|
146
|
-
const checkoutSessionEntity =
|
|
147
|
-
await this.
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
166
|
+
const checkoutSessionEntity =
|
|
167
|
+
await this.baseCheckoutSessionService.createCheckoutSession(
|
|
168
|
+
await this._mappers.CreateCheckoutSessionMapper.deserializeDtoToEntity(
|
|
169
|
+
{
|
|
170
|
+
...checkoutSessionDto,
|
|
171
|
+
id: session.id,
|
|
172
|
+
uri: session.url,
|
|
173
|
+
expiresAt: new Date(Date.now() + 5 * 60 * 1e3),
|
|
174
|
+
providerFields: session
|
|
175
|
+
},
|
|
176
|
+
this.em,
|
|
177
|
+
session
|
|
178
|
+
)
|
|
179
|
+
);
|
|
159
180
|
return this._mappers.CheckoutSessionMapper.serializeEntityToDto(
|
|
160
181
|
checkoutSessionEntity
|
|
161
182
|
);
|
|
162
183
|
}
|
|
163
|
-
async getCheckoutSession({
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
const databaseCheckoutSession = await this.baseCheckoutSessionService.getCheckoutSession({ id });
|
|
184
|
+
async getCheckoutSession({ id }) {
|
|
185
|
+
const databaseCheckoutSession =
|
|
186
|
+
await this.baseCheckoutSessionService.getCheckoutSession({ id });
|
|
167
187
|
return {
|
|
168
188
|
...this._mappers.CheckoutSessionMapper.serializeEntityToDto(
|
|
169
189
|
databaseCheckoutSession
|
|
@@ -178,7 +198,7 @@ var StripeCheckoutSessionService = class {
|
|
|
178
198
|
async handleCheckoutSuccess({ id }) {
|
|
179
199
|
await this.stripeClient.checkout.sessions.update(id, {
|
|
180
200
|
metadata: {
|
|
181
|
-
status:
|
|
201
|
+
status: 'SUCCESS'
|
|
182
202
|
}
|
|
183
203
|
});
|
|
184
204
|
await this.baseCheckoutSessionService.handleCheckoutSuccess({ id });
|
|
@@ -186,7 +206,7 @@ var StripeCheckoutSessionService = class {
|
|
|
186
206
|
async handleCheckoutFailure({ id }) {
|
|
187
207
|
await this.stripeClient.checkout.sessions.update(id, {
|
|
188
208
|
metadata: {
|
|
189
|
-
status:
|
|
209
|
+
status: 'FAILED'
|
|
190
210
|
}
|
|
191
211
|
});
|
|
192
212
|
await this.baseCheckoutSessionService.handleCheckoutFailure({ id });
|
|
@@ -194,14 +214,22 @@ var StripeCheckoutSessionService = class {
|
|
|
194
214
|
};
|
|
195
215
|
|
|
196
216
|
// services/paymentLink.service.ts
|
|
197
|
-
import { BasePaymentLinkService } from
|
|
217
|
+
import { BasePaymentLinkService } from '@forklaunch/implementation-billing-base/services';
|
|
198
218
|
import {
|
|
199
219
|
IdentityRequestMapper as IdentityRequestMapper3,
|
|
200
220
|
IdentityResponseMapper as IdentityResponseMapper3,
|
|
201
221
|
transformIntoInternalMapper as transformIntoInternalMapper3
|
|
202
|
-
} from
|
|
222
|
+
} from '@forklaunch/internal';
|
|
203
223
|
var StripePaymentLinkService = class {
|
|
204
|
-
constructor(
|
|
224
|
+
constructor(
|
|
225
|
+
stripeClient,
|
|
226
|
+
em,
|
|
227
|
+
cache,
|
|
228
|
+
openTelemetryCollector,
|
|
229
|
+
schemaValidator,
|
|
230
|
+
mappers,
|
|
231
|
+
options
|
|
232
|
+
) {
|
|
205
233
|
this.options = options;
|
|
206
234
|
this.stripeClient = stripeClient;
|
|
207
235
|
this.em = em;
|
|
@@ -237,20 +265,22 @@ var StripePaymentLinkService = class {
|
|
|
237
265
|
payment_method_types: paymentLinkDto.paymentMethods,
|
|
238
266
|
currency: paymentLinkDto.currency
|
|
239
267
|
});
|
|
240
|
-
const paymentLinkEntity =
|
|
241
|
-
await this.
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
268
|
+
const paymentLinkEntity =
|
|
269
|
+
await this.basePaymentLinkService.createPaymentLink(
|
|
270
|
+
await this._mappers.CreatePaymentLinkMapper.deserializeDtoToEntity(
|
|
271
|
+
{
|
|
272
|
+
...paymentLinkDto,
|
|
273
|
+
id: session.id,
|
|
274
|
+
amount:
|
|
275
|
+
session.line_items?.data.reduce(
|
|
276
|
+
(total, item) => total + item.amount_total,
|
|
277
|
+
0
|
|
278
|
+
) ?? 0
|
|
279
|
+
},
|
|
280
|
+
this.em,
|
|
281
|
+
session
|
|
282
|
+
)
|
|
283
|
+
);
|
|
254
284
|
return this._mappers.PaymentLinkMapper.serializeEntityToDto(
|
|
255
285
|
paymentLinkEntity
|
|
256
286
|
);
|
|
@@ -263,26 +293,29 @@ var StripePaymentLinkService = class {
|
|
|
263
293
|
payment_method_types: paymentLinkDto.paymentMethods
|
|
264
294
|
}
|
|
265
295
|
);
|
|
266
|
-
const paymentLinkEntity =
|
|
267
|
-
await this.
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
296
|
+
const paymentLinkEntity =
|
|
297
|
+
await this.basePaymentLinkService.updatePaymentLink(
|
|
298
|
+
await this._mappers.UpdatePaymentLinkMapper.deserializeDtoToEntity(
|
|
299
|
+
{
|
|
300
|
+
...paymentLinkDto,
|
|
301
|
+
id: session.id,
|
|
302
|
+
amount:
|
|
303
|
+
session.line_items?.data.reduce(
|
|
304
|
+
(total, item) => total + item.amount_total,
|
|
305
|
+
0
|
|
306
|
+
) ?? 0
|
|
307
|
+
},
|
|
308
|
+
this.em,
|
|
309
|
+
session
|
|
310
|
+
)
|
|
311
|
+
);
|
|
280
312
|
return this._mappers.PaymentLinkMapper.serializeEntityToDto(
|
|
281
313
|
paymentLinkEntity
|
|
282
314
|
);
|
|
283
315
|
}
|
|
284
316
|
async getPaymentLink({ id }) {
|
|
285
|
-
const databasePaymentLink =
|
|
317
|
+
const databasePaymentLink =
|
|
318
|
+
await this.basePaymentLinkService.getPaymentLink({ id });
|
|
286
319
|
return {
|
|
287
320
|
...this._mappers.PaymentLinkMapper.serializeEntityToDto(
|
|
288
321
|
databasePaymentLink
|
|
@@ -293,7 +326,7 @@ var StripePaymentLinkService = class {
|
|
|
293
326
|
async expirePaymentLink({ id }) {
|
|
294
327
|
await this.stripeClient.paymentLinks.update(id, {
|
|
295
328
|
metadata: {
|
|
296
|
-
status:
|
|
329
|
+
status: 'EXPIRED'
|
|
297
330
|
}
|
|
298
331
|
});
|
|
299
332
|
await this.basePaymentLinkService.expirePaymentLink({ id });
|
|
@@ -301,7 +334,7 @@ var StripePaymentLinkService = class {
|
|
|
301
334
|
async handlePaymentSuccess({ id }) {
|
|
302
335
|
await this.stripeClient.paymentLinks.update(id, {
|
|
303
336
|
metadata: {
|
|
304
|
-
status:
|
|
337
|
+
status: 'COMPLETED'
|
|
305
338
|
}
|
|
306
339
|
});
|
|
307
340
|
await this.basePaymentLinkService.handlePaymentSuccess({ id });
|
|
@@ -309,7 +342,7 @@ var StripePaymentLinkService = class {
|
|
|
309
342
|
async handlePaymentFailure({ id }) {
|
|
310
343
|
await this.stripeClient.paymentLinks.update(id, {
|
|
311
344
|
metadata: {
|
|
312
|
-
status:
|
|
345
|
+
status: 'FAILED'
|
|
313
346
|
}
|
|
314
347
|
});
|
|
315
348
|
await this.basePaymentLinkService.handlePaymentFailure({ id });
|
|
@@ -321,9 +354,9 @@ var StripePaymentLinkService = class {
|
|
|
321
354
|
return await Promise.all(
|
|
322
355
|
(await this.basePaymentLinkService.listPaymentLinks(idsDto)).map(
|
|
323
356
|
async (paymentLink) => ({
|
|
324
|
-
...await this._mappers.PaymentLinkMapper.serializeEntityToDto(
|
|
357
|
+
...(await this._mappers.PaymentLinkMapper.serializeEntityToDto(
|
|
325
358
|
paymentLink
|
|
326
|
-
),
|
|
359
|
+
)),
|
|
327
360
|
stripeFields: paymentLinks.data.find(
|
|
328
361
|
(paymentLink2) => paymentLink2.id === paymentLink2.id
|
|
329
362
|
)
|
|
@@ -334,14 +367,21 @@ var StripePaymentLinkService = class {
|
|
|
334
367
|
};
|
|
335
368
|
|
|
336
369
|
// services/plan.service.ts
|
|
337
|
-
import { BasePlanService } from
|
|
370
|
+
import { BasePlanService } from '@forklaunch/implementation-billing-base/services';
|
|
338
371
|
import {
|
|
339
372
|
IdentityRequestMapper as IdentityRequestMapper4,
|
|
340
373
|
IdentityResponseMapper as IdentityResponseMapper4,
|
|
341
374
|
transformIntoInternalMapper as transformIntoInternalMapper4
|
|
342
|
-
} from
|
|
375
|
+
} from '@forklaunch/internal';
|
|
343
376
|
var StripePlanService = class {
|
|
344
|
-
constructor(
|
|
377
|
+
constructor(
|
|
378
|
+
stripeClient,
|
|
379
|
+
em,
|
|
380
|
+
openTelemetryCollector,
|
|
381
|
+
schemaValidator,
|
|
382
|
+
mappers,
|
|
383
|
+
options
|
|
384
|
+
) {
|
|
345
385
|
this.options = options;
|
|
346
386
|
this.stripeClient = stripeClient;
|
|
347
387
|
this.em = em;
|
|
@@ -380,7 +420,7 @@ var StripePlanService = class {
|
|
|
380
420
|
{
|
|
381
421
|
...planDto,
|
|
382
422
|
externalId: plan.id,
|
|
383
|
-
billingProvider:
|
|
423
|
+
billingProvider: 'stripe'
|
|
384
424
|
},
|
|
385
425
|
em ?? this.em,
|
|
386
426
|
plan
|
|
@@ -391,24 +431,25 @@ var StripePlanService = class {
|
|
|
391
431
|
}
|
|
392
432
|
async getPlan(idDto, em) {
|
|
393
433
|
const plan = await this.stripeClient.plans.retrieve(idDto.id);
|
|
394
|
-
const id = (
|
|
395
|
-
this.options?.databaseTableName ??
|
|
396
|
-
|
|
397
|
-
|
|
434
|
+
const id = (
|
|
435
|
+
await em?.findOne(this.options?.databaseTableName ?? 'plan', {
|
|
436
|
+
externalId: idDto.id
|
|
437
|
+
})
|
|
438
|
+
)?.id;
|
|
398
439
|
if (!id) {
|
|
399
|
-
throw new Error(
|
|
440
|
+
throw new Error('Plan not found');
|
|
400
441
|
}
|
|
401
442
|
return {
|
|
402
|
-
...await this._mappers.PlanMapper.serializeEntityToDto(
|
|
443
|
+
...(await this._mappers.PlanMapper.serializeEntityToDto(
|
|
403
444
|
await this.basePlanService.getPlan({ id }, em)
|
|
404
|
-
),
|
|
445
|
+
)),
|
|
405
446
|
stripeFields: plan
|
|
406
447
|
};
|
|
407
448
|
}
|
|
408
449
|
async updatePlan(planDto, em) {
|
|
409
450
|
const existingPlan = await this.stripeClient.plans.retrieve(planDto.id);
|
|
410
|
-
const plan = await this.stripeClient.plans.del(planDto.id).then(
|
|
411
|
-
|
|
451
|
+
const plan = await this.stripeClient.plans.del(planDto.id).then(() =>
|
|
452
|
+
this.stripeClient.plans.create({
|
|
412
453
|
...planDto.stripeFields,
|
|
413
454
|
interval: planDto.cadence ?? existingPlan.interval,
|
|
414
455
|
product: planDto.name,
|
|
@@ -420,7 +461,7 @@ var StripePlanService = class {
|
|
|
420
461
|
{
|
|
421
462
|
...planDto,
|
|
422
463
|
externalId: plan.id,
|
|
423
|
-
billingProvider:
|
|
464
|
+
billingProvider: 'stripe'
|
|
424
465
|
},
|
|
425
466
|
em ?? this.em,
|
|
426
467
|
plan
|
|
@@ -437,16 +478,19 @@ var StripePlanService = class {
|
|
|
437
478
|
const plans = await this.stripeClient.plans.list({
|
|
438
479
|
active: true
|
|
439
480
|
});
|
|
440
|
-
const ids = (
|
|
441
|
-
this.options?.databaseTableName ??
|
|
442
|
-
|
|
443
|
-
|
|
481
|
+
const ids = (
|
|
482
|
+
await em?.findAll(this.options?.databaseTableName ?? 'plan', {
|
|
483
|
+
where: { externalId: { $in: plans.data.map((plan) => plan.id) } }
|
|
484
|
+
})
|
|
485
|
+
)
|
|
486
|
+
?.filter((s) => idsDto?.ids?.includes(s.id))
|
|
487
|
+
?.map((s) => s.id);
|
|
444
488
|
if (!ids) {
|
|
445
|
-
throw new Error(
|
|
489
|
+
throw new Error('Plans not found');
|
|
446
490
|
}
|
|
447
491
|
return await Promise.all(
|
|
448
492
|
(await this.basePlanService.listPlans({ ids }, em)).map(async (plan) => ({
|
|
449
|
-
...await this._mappers.PlanMapper.serializeEntityToDto(plan),
|
|
493
|
+
...(await this._mappers.PlanMapper.serializeEntityToDto(plan)),
|
|
450
494
|
stripeFields: plans.data.find(
|
|
451
495
|
(stripePlan) => stripePlan.id === plan.externalId
|
|
452
496
|
)
|
|
@@ -456,14 +500,21 @@ var StripePlanService = class {
|
|
|
456
500
|
};
|
|
457
501
|
|
|
458
502
|
// services/subscription.service.ts
|
|
459
|
-
import { BaseSubscriptionService } from
|
|
503
|
+
import { BaseSubscriptionService } from '@forklaunch/implementation-billing-base/services';
|
|
460
504
|
import {
|
|
461
505
|
IdentityRequestMapper as IdentityRequestMapper5,
|
|
462
506
|
IdentityResponseMapper as IdentityResponseMapper5,
|
|
463
507
|
transformIntoInternalMapper as transformIntoInternalMapper5
|
|
464
|
-
} from
|
|
508
|
+
} from '@forklaunch/internal';
|
|
465
509
|
var StripeSubscriptionService = class {
|
|
466
|
-
constructor(
|
|
510
|
+
constructor(
|
|
511
|
+
stripe,
|
|
512
|
+
em,
|
|
513
|
+
openTelemetryCollector,
|
|
514
|
+
schemaValidator,
|
|
515
|
+
mappers,
|
|
516
|
+
options
|
|
517
|
+
) {
|
|
467
518
|
this.options = options;
|
|
468
519
|
this.stripe = stripe;
|
|
469
520
|
this.em = em;
|
|
@@ -500,53 +551,55 @@ var StripeSubscriptionService = class {
|
|
|
500
551
|
}
|
|
501
552
|
]
|
|
502
553
|
});
|
|
503
|
-
const subscriptionEntity =
|
|
504
|
-
await this.
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
554
|
+
const subscriptionEntity =
|
|
555
|
+
await this.baseSubscriptionService.createSubscription(
|
|
556
|
+
await this._mappers.CreateSubscriptionMapper.deserializeDtoToEntity(
|
|
557
|
+
{
|
|
558
|
+
...subscriptionDto,
|
|
559
|
+
externalId: subscription.id,
|
|
560
|
+
billingProvider: 'stripe'
|
|
561
|
+
},
|
|
562
|
+
em ?? this.em,
|
|
563
|
+
subscription
|
|
564
|
+
),
|
|
565
|
+
em
|
|
566
|
+
);
|
|
515
567
|
return this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
516
568
|
subscriptionEntity
|
|
517
569
|
);
|
|
518
570
|
}
|
|
519
571
|
async getSubscription(idDto, em) {
|
|
520
572
|
return {
|
|
521
|
-
...await this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
573
|
+
...(await this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
522
574
|
await this.baseSubscriptionService.getSubscription(idDto, em)
|
|
523
|
-
),
|
|
575
|
+
)),
|
|
524
576
|
stripeFields: await this.stripe.subscriptions.retrieve(idDto.id)
|
|
525
577
|
};
|
|
526
578
|
}
|
|
527
579
|
async getUserSubscription(idDto, em) {
|
|
528
580
|
return {
|
|
529
|
-
...await this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
581
|
+
...(await this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
530
582
|
await this.baseSubscriptionService.getUserSubscription(idDto, em)
|
|
531
|
-
),
|
|
583
|
+
)),
|
|
532
584
|
stripeFields: await this.stripe.subscriptions.retrieve(idDto.id)
|
|
533
585
|
};
|
|
534
586
|
}
|
|
535
587
|
async getOrganizationSubscription(idDto, em) {
|
|
536
|
-
const id = (
|
|
537
|
-
this.options?.databaseTableName ??
|
|
538
|
-
|
|
539
|
-
|
|
588
|
+
const id = (
|
|
589
|
+
await em?.findOne(this.options?.databaseTableName ?? 'subscription', {
|
|
590
|
+
externalId: idDto.id
|
|
591
|
+
})
|
|
592
|
+
)?.id;
|
|
540
593
|
if (!id) {
|
|
541
|
-
throw new Error(
|
|
594
|
+
throw new Error('Subscription not found');
|
|
542
595
|
}
|
|
543
596
|
return {
|
|
544
|
-
...await this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
597
|
+
...(await this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
545
598
|
await this.baseSubscriptionService.getOrganizationSubscription(
|
|
546
599
|
{ id },
|
|
547
600
|
em
|
|
548
601
|
)
|
|
549
|
-
),
|
|
602
|
+
)),
|
|
550
603
|
stripeFields: await this.stripe.subscriptions.retrieve(idDto.id)
|
|
551
604
|
};
|
|
552
605
|
}
|
|
@@ -562,19 +615,20 @@ var StripeSubscriptionService = class {
|
|
|
562
615
|
]
|
|
563
616
|
}
|
|
564
617
|
);
|
|
565
|
-
const subscriptionEntity =
|
|
566
|
-
await this.
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
618
|
+
const subscriptionEntity =
|
|
619
|
+
await this.baseSubscriptionService.updateSubscription(
|
|
620
|
+
await this._mappers.UpdateSubscriptionMapper.deserializeDtoToEntity(
|
|
621
|
+
{
|
|
622
|
+
...subscriptionDto,
|
|
623
|
+
externalId: subscription.id,
|
|
624
|
+
billingProvider: 'stripe',
|
|
625
|
+
providerFields: subscription
|
|
626
|
+
},
|
|
627
|
+
em ?? this.em,
|
|
628
|
+
subscription
|
|
629
|
+
),
|
|
630
|
+
em
|
|
631
|
+
);
|
|
578
632
|
return this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
579
633
|
subscriptionEntity
|
|
580
634
|
);
|
|
@@ -584,23 +638,26 @@ var StripeSubscriptionService = class {
|
|
|
584
638
|
await this.baseSubscriptionService.deleteSubscription(idDto, em);
|
|
585
639
|
}
|
|
586
640
|
async listSubscriptions(idsDto, em) {
|
|
587
|
-
const subscriptions = (
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
641
|
+
const subscriptions = (
|
|
642
|
+
await this.stripe.subscriptions.list({
|
|
643
|
+
status: 'active'
|
|
644
|
+
})
|
|
645
|
+
).data.filter((s) => idsDto.ids?.includes(s.id));
|
|
646
|
+
const ids = (
|
|
647
|
+
await em?.findAll(this.options?.databaseTableName ?? 'subscription', {
|
|
648
|
+
where: { externalId: { $in: subscriptions.map((s) => s.id) } }
|
|
649
|
+
})
|
|
650
|
+
)?.map((s) => s.id);
|
|
594
651
|
if (!ids) {
|
|
595
|
-
throw new Error(
|
|
652
|
+
throw new Error('Subscriptions not found');
|
|
596
653
|
}
|
|
597
654
|
return await Promise.all(
|
|
598
655
|
(await this.baseSubscriptionService.listSubscriptions({ ids }, em)).map(
|
|
599
656
|
async (subscription) => {
|
|
600
657
|
return {
|
|
601
|
-
...await this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
658
|
+
...(await this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
602
659
|
subscription
|
|
603
|
-
),
|
|
660
|
+
)),
|
|
604
661
|
stripeFields: subscriptions.find(
|
|
605
662
|
(s) => s.id === subscription.externalId
|
|
606
663
|
)
|
|
@@ -621,7 +678,7 @@ var StripeSubscriptionService = class {
|
|
|
621
678
|
|
|
622
679
|
// domain/enum/billingProvider.enum.ts
|
|
623
680
|
var BillingProviderEnum = {
|
|
624
|
-
STRIPE:
|
|
681
|
+
STRIPE: 'stripe'
|
|
625
682
|
};
|
|
626
683
|
|
|
627
684
|
// services/webhook.service.ts
|
|
@@ -635,7 +692,17 @@ var StripeWebhookService = class {
|
|
|
635
692
|
paymentLinkService;
|
|
636
693
|
planService;
|
|
637
694
|
subscriptionService;
|
|
638
|
-
constructor(
|
|
695
|
+
constructor(
|
|
696
|
+
stripeClient,
|
|
697
|
+
em,
|
|
698
|
+
schemaValidator,
|
|
699
|
+
openTelemetryCollector,
|
|
700
|
+
billingPortalService,
|
|
701
|
+
checkoutSessionService,
|
|
702
|
+
paymentLinkService,
|
|
703
|
+
planService,
|
|
704
|
+
subscriptionService
|
|
705
|
+
) {
|
|
639
706
|
this.stripeClient = stripeClient;
|
|
640
707
|
this.em = em;
|
|
641
708
|
this.schemaValidator = schemaValidator;
|
|
@@ -648,11 +715,11 @@ var StripeWebhookService = class {
|
|
|
648
715
|
}
|
|
649
716
|
async handleWebhookEvent(event) {
|
|
650
717
|
if (this.openTelemetryCollector) {
|
|
651
|
-
this.openTelemetryCollector.info(
|
|
718
|
+
this.openTelemetryCollector.info('Handling webhook event', event);
|
|
652
719
|
}
|
|
653
720
|
const eventType = event.type;
|
|
654
721
|
switch (eventType) {
|
|
655
|
-
case
|
|
722
|
+
case 'billing_portal.session.created': {
|
|
656
723
|
this.billingPortalService.baseBillingPortalService.createBillingPortalSession(
|
|
657
724
|
{
|
|
658
725
|
id: event.data.object.id,
|
|
@@ -664,94 +731,113 @@ var StripeWebhookService = class {
|
|
|
664
731
|
);
|
|
665
732
|
break;
|
|
666
733
|
}
|
|
667
|
-
case
|
|
734
|
+
case 'checkout.session.expired': {
|
|
668
735
|
this.checkoutSessionService.handleCheckoutFailure({
|
|
669
736
|
id: event.data.object.id
|
|
670
737
|
});
|
|
671
738
|
break;
|
|
672
739
|
}
|
|
673
|
-
case
|
|
740
|
+
case 'checkout.session.completed': {
|
|
674
741
|
this.checkoutSessionService.handleCheckoutSuccess({
|
|
675
742
|
id: event.data.object.id
|
|
676
743
|
});
|
|
677
744
|
break;
|
|
678
745
|
}
|
|
679
|
-
case
|
|
746
|
+
case 'payment_link.created':
|
|
680
747
|
{
|
|
681
748
|
this.paymentLinkService.basePaymentLinkService.createPaymentLink({
|
|
682
749
|
id: event.data.object.id,
|
|
683
|
-
amount:
|
|
684
|
-
(
|
|
685
|
-
|
|
686
|
-
|
|
750
|
+
amount:
|
|
751
|
+
event.data.object.line_items?.data.reduce(
|
|
752
|
+
(total, item) => total + item.amount_total,
|
|
753
|
+
0
|
|
754
|
+
) ?? 0,
|
|
687
755
|
paymentMethods: event.data.object.payment_method_types,
|
|
688
|
-
status:
|
|
756
|
+
status: 'CREATED',
|
|
689
757
|
currency: event.data.object.currency,
|
|
690
758
|
providerFields: event.data.object
|
|
691
759
|
});
|
|
692
760
|
}
|
|
693
761
|
break;
|
|
694
|
-
case
|
|
762
|
+
case 'payment_link.updated': {
|
|
695
763
|
this.paymentLinkService.basePaymentLinkService.updatePaymentLink({
|
|
696
764
|
id: event.data.object.id,
|
|
697
|
-
amount:
|
|
698
|
-
(
|
|
699
|
-
|
|
700
|
-
|
|
765
|
+
amount:
|
|
766
|
+
event.data.object.line_items?.data.reduce(
|
|
767
|
+
(total, item) => total + item.amount_total,
|
|
768
|
+
0
|
|
769
|
+
) ?? 0,
|
|
701
770
|
paymentMethods: event.data.object.payment_method_types,
|
|
702
|
-
status:
|
|
771
|
+
status: 'UPDATED',
|
|
703
772
|
currency: event.data.object.currency,
|
|
704
773
|
providerFields: event.data.object
|
|
705
774
|
});
|
|
706
775
|
break;
|
|
707
776
|
}
|
|
708
|
-
case
|
|
709
|
-
if (
|
|
777
|
+
case 'plan.created': {
|
|
778
|
+
if (
|
|
779
|
+
typeof event.data.object.product === 'object' &&
|
|
780
|
+
event.data.object.product != null &&
|
|
781
|
+
event.data.object.amount != null
|
|
782
|
+
) {
|
|
710
783
|
this.planService.basePlanService.createPlan({
|
|
711
784
|
id: event.data.object.id,
|
|
712
785
|
billingProvider: BillingProviderEnum.STRIPE,
|
|
713
786
|
cadence: event.data.object.interval,
|
|
714
787
|
currency: event.data.object.currency,
|
|
715
788
|
active: true,
|
|
716
|
-
name:
|
|
789
|
+
name:
|
|
790
|
+
typeof event.data.object.product === 'string'
|
|
791
|
+
? event.data.object.product
|
|
792
|
+
: event.data.object.product?.id,
|
|
717
793
|
price: event.data.object.amount,
|
|
718
794
|
externalId: event.data.object.id,
|
|
719
795
|
providerFields: event.data.object
|
|
720
796
|
});
|
|
721
797
|
} else {
|
|
722
|
-
throw new Error(
|
|
798
|
+
throw new Error('Invalid plan');
|
|
723
799
|
}
|
|
724
800
|
break;
|
|
725
801
|
}
|
|
726
|
-
case
|
|
727
|
-
if (
|
|
802
|
+
case 'plan.updated': {
|
|
803
|
+
if (
|
|
804
|
+
typeof event.data.object.product === 'object' &&
|
|
805
|
+
event.data.object.product != null &&
|
|
806
|
+
event.data.object.amount != null
|
|
807
|
+
) {
|
|
728
808
|
this.planService.basePlanService.updatePlan({
|
|
729
809
|
id: event.data.object.id,
|
|
730
810
|
billingProvider: BillingProviderEnum.STRIPE,
|
|
731
811
|
cadence: event.data.object.interval,
|
|
732
812
|
currency: event.data.object.currency,
|
|
733
813
|
active: true,
|
|
734
|
-
name:
|
|
814
|
+
name:
|
|
815
|
+
typeof event.data.object.product === 'string'
|
|
816
|
+
? event.data.object.product
|
|
817
|
+
: event.data.object.product?.id,
|
|
735
818
|
price: event.data.object.amount,
|
|
736
819
|
externalId: event.data.object.id,
|
|
737
820
|
providerFields: event.data.object
|
|
738
821
|
});
|
|
739
822
|
} else {
|
|
740
|
-
throw new Error(
|
|
823
|
+
throw new Error('Invalid plan');
|
|
741
824
|
}
|
|
742
825
|
break;
|
|
743
826
|
}
|
|
744
|
-
case
|
|
827
|
+
case 'plan.deleted': {
|
|
745
828
|
this.planService.deletePlan({
|
|
746
829
|
id: event.data.object.id
|
|
747
830
|
});
|
|
748
831
|
break;
|
|
749
832
|
}
|
|
750
|
-
case
|
|
833
|
+
case 'customer.subscription.created': {
|
|
751
834
|
this.subscriptionService.baseSubscriptionService.createSubscription({
|
|
752
835
|
id: event.data.object.id,
|
|
753
|
-
partyId:
|
|
754
|
-
|
|
836
|
+
partyId:
|
|
837
|
+
typeof event.data.object.customer === 'string'
|
|
838
|
+
? event.data.object.customer
|
|
839
|
+
: event.data.object.customer.id,
|
|
840
|
+
partyType: 'USER',
|
|
755
841
|
description: event.data.object.description ?? void 0,
|
|
756
842
|
active: true,
|
|
757
843
|
productId: event.data.object.items.data[0].plan.id,
|
|
@@ -759,41 +845,48 @@ var StripeWebhookService = class {
|
|
|
759
845
|
externalId: event.data.object.id,
|
|
760
846
|
billingProvider: BillingProviderEnum.STRIPE,
|
|
761
847
|
startDate: new Date(event.data.object.created),
|
|
762
|
-
endDate: event.data.object.cancel_at
|
|
848
|
+
endDate: event.data.object.cancel_at
|
|
849
|
+
? new Date(event.data.object.cancel_at)
|
|
850
|
+
: /* @__PURE__ */ new Date(Infinity),
|
|
763
851
|
status: event.data.object.status
|
|
764
852
|
});
|
|
765
853
|
break;
|
|
766
854
|
}
|
|
767
|
-
case
|
|
855
|
+
case 'customer.subscription.updated': {
|
|
768
856
|
this.subscriptionService.baseSubscriptionService.updateSubscription({
|
|
769
857
|
id: event.data.object.id,
|
|
770
|
-
partyId:
|
|
771
|
-
|
|
858
|
+
partyId:
|
|
859
|
+
typeof event.data.object.customer === 'string'
|
|
860
|
+
? event.data.object.customer
|
|
861
|
+
: event.data.object.customer.id,
|
|
862
|
+
partyType: 'USER',
|
|
772
863
|
description: event.data.object.description ?? void 0,
|
|
773
864
|
active: true,
|
|
774
865
|
providerFields: event.data.object,
|
|
775
866
|
externalId: event.data.object.id,
|
|
776
867
|
billingProvider: BillingProviderEnum.STRIPE,
|
|
777
868
|
startDate: new Date(event.data.object.created),
|
|
778
|
-
endDate: event.data.object.cancel_at
|
|
869
|
+
endDate: event.data.object.cancel_at
|
|
870
|
+
? new Date(event.data.object.cancel_at)
|
|
871
|
+
: /* @__PURE__ */ new Date(Infinity),
|
|
779
872
|
productId: event.data.object.items.data[0].plan.id,
|
|
780
873
|
status: event.data.object.status
|
|
781
874
|
});
|
|
782
875
|
break;
|
|
783
876
|
}
|
|
784
|
-
case
|
|
877
|
+
case 'customer.subscription.deleted': {
|
|
785
878
|
this.subscriptionService.deleteSubscription({
|
|
786
879
|
id: event.data.object.id
|
|
787
880
|
});
|
|
788
881
|
break;
|
|
789
882
|
}
|
|
790
|
-
case
|
|
883
|
+
case 'customer.subscription.paused': {
|
|
791
884
|
this.subscriptionService.cancelSubscription({
|
|
792
885
|
id: event.data.object.id
|
|
793
886
|
});
|
|
794
887
|
break;
|
|
795
888
|
}
|
|
796
|
-
case
|
|
889
|
+
case 'customer.subscription.resumed': {
|
|
797
890
|
this.subscriptionService.resumeSubscription({
|
|
798
891
|
id: event.data.object.id
|
|
799
892
|
});
|
|
@@ -801,7 +894,7 @@ var StripeWebhookService = class {
|
|
|
801
894
|
}
|
|
802
895
|
default:
|
|
803
896
|
this.openTelemetryCollector.info(
|
|
804
|
-
|
|
897
|
+
'Unprocessed stripe event type',
|
|
805
898
|
eventType
|
|
806
899
|
);
|
|
807
900
|
break;
|