@forklaunch/implementation-billing-stripe 0.2.7 → 0.3.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/lib/domain/schemas/index.d.mts +46 -46
- package/lib/domain/schemas/index.d.ts +46 -46
- package/lib/domain/types/index.d.mts +163 -21
- package/lib/domain/types/index.d.ts +163 -21
- package/lib/eject/domain/types/billingPortal.mapper.types.ts +31 -0
- package/lib/eject/domain/types/checkoutSession.mapper.types.ts +32 -0
- package/lib/eject/domain/types/index.ts +5 -0
- package/lib/eject/domain/types/paymentLink.mapper.types.ts +32 -0
- package/lib/eject/domain/types/plan.mapper.types.ts +29 -0
- package/lib/eject/domain/types/subscription.mapper.types.ts +32 -0
- package/lib/eject/services/billingPortal.service.ts +49 -132
- package/lib/eject/services/checkoutSession.service.ts +47 -108
- package/lib/eject/services/paymentLink.service.ts +82 -136
- package/lib/eject/services/plan.service.ts +44 -105
- package/lib/eject/services/subscription.service.ts +74 -151
- package/lib/eject/services/webhook.service.ts +5 -12
- package/lib/services/index.d.mts +82 -330
- package/lib/services/index.d.ts +82 -330
- package/lib/services/index.js +188 -285
- package/lib/services/index.mjs +188 -290
- package/package.json +12 -12
|
@@ -1,19 +1,12 @@
|
|
|
1
|
-
import { IdDto, IdsDto
|
|
1
|
+
import { IdDto, IdsDto } from '@forklaunch/common';
|
|
2
2
|
import {
|
|
3
3
|
MetricsDefinition,
|
|
4
4
|
OpenTelemetryCollector,
|
|
5
5
|
TelemetryOptions
|
|
6
6
|
} from '@forklaunch/core/http';
|
|
7
7
|
import { BaseSubscriptionService } from '@forklaunch/implementation-billing-base/services';
|
|
8
|
+
import { SubscriptionMappers } from '@forklaunch/implementation-billing-base/types';
|
|
8
9
|
import { SubscriptionService } from '@forklaunch/interfaces-billing/interfaces';
|
|
9
|
-
import {
|
|
10
|
-
IdentityRequestMapper,
|
|
11
|
-
IdentityResponseMapper,
|
|
12
|
-
InternalMapper,
|
|
13
|
-
RequestMapperConstructor,
|
|
14
|
-
ResponseMapperConstructor,
|
|
15
|
-
transformIntoInternalMapper
|
|
16
|
-
} from '@forklaunch/internal';
|
|
17
10
|
import { AnySchemaValidator } from '@forklaunch/validator';
|
|
18
11
|
import { EntityManager } from '@mikro-orm/core';
|
|
19
12
|
import Stripe from 'stripe';
|
|
@@ -25,6 +18,7 @@ import {
|
|
|
25
18
|
StripeUpdateSubscriptionDto
|
|
26
19
|
} from '../domain/types/stripe.dto.types';
|
|
27
20
|
import { StripeSubscriptionEntities } from '../domain/types/stripe.entity.types';
|
|
21
|
+
import { StripeSubscriptionMappers } from '../domain/types/subscription.mapper.types';
|
|
28
22
|
|
|
29
23
|
export class StripeSubscriptionService<
|
|
30
24
|
SchemaValidator extends AnySchemaValidator,
|
|
@@ -48,110 +42,55 @@ export class StripeSubscriptionService<
|
|
|
48
42
|
baseSubscriptionService: BaseSubscriptionService<
|
|
49
43
|
SchemaValidator,
|
|
50
44
|
PartyType,
|
|
51
|
-
|
|
45
|
+
BillingProviderEnum,
|
|
52
46
|
Entities,
|
|
53
|
-
|
|
47
|
+
Dto
|
|
54
48
|
>;
|
|
55
|
-
protected
|
|
56
|
-
protected readonly stripe: Stripe;
|
|
49
|
+
protected readonly stripeClient: Stripe;
|
|
57
50
|
protected readonly em: EntityManager;
|
|
58
51
|
protected readonly openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>;
|
|
59
52
|
protected readonly schemaValidator: SchemaValidator;
|
|
60
|
-
protected readonly mappers:
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
>;
|
|
66
|
-
CreateSubscriptionMapper: RequestMapperConstructor<
|
|
67
|
-
SchemaValidator,
|
|
68
|
-
Dto['CreateSubscriptionMapper'],
|
|
69
|
-
Entities['CreateSubscriptionMapper'],
|
|
70
|
-
(
|
|
71
|
-
dto: Dto['CreateSubscriptionMapper'],
|
|
72
|
-
em: EntityManager,
|
|
73
|
-
subscription: Stripe.Subscription
|
|
74
|
-
) => Promise<Entities['CreateSubscriptionMapper']>
|
|
75
|
-
>;
|
|
76
|
-
UpdateSubscriptionMapper: RequestMapperConstructor<
|
|
77
|
-
SchemaValidator,
|
|
78
|
-
Dto['UpdateSubscriptionMapper'],
|
|
79
|
-
Entities['UpdateSubscriptionMapper'],
|
|
80
|
-
(
|
|
81
|
-
dto: Dto['UpdateSubscriptionMapper'],
|
|
82
|
-
em: EntityManager,
|
|
83
|
-
subscription: Stripe.Subscription
|
|
84
|
-
) => Promise<Entities['UpdateSubscriptionMapper']>
|
|
85
|
-
>;
|
|
86
|
-
};
|
|
53
|
+
protected readonly mappers: StripeSubscriptionMappers<
|
|
54
|
+
PartyType,
|
|
55
|
+
Entities,
|
|
56
|
+
Dto
|
|
57
|
+
>;
|
|
87
58
|
|
|
88
59
|
constructor(
|
|
89
|
-
|
|
60
|
+
stripeClient: Stripe,
|
|
90
61
|
em: EntityManager,
|
|
91
62
|
openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>,
|
|
92
63
|
schemaValidator: SchemaValidator,
|
|
93
|
-
mappers:
|
|
94
|
-
SubscriptionMapper: ResponseMapperConstructor<
|
|
95
|
-
SchemaValidator,
|
|
96
|
-
Dto['SubscriptionMapper'],
|
|
97
|
-
Entities['SubscriptionMapper']
|
|
98
|
-
>;
|
|
99
|
-
CreateSubscriptionMapper: RequestMapperConstructor<
|
|
100
|
-
SchemaValidator,
|
|
101
|
-
Dto['CreateSubscriptionMapper'],
|
|
102
|
-
Entities['CreateSubscriptionMapper'],
|
|
103
|
-
(
|
|
104
|
-
dto: Dto['CreateSubscriptionMapper'],
|
|
105
|
-
em: EntityManager,
|
|
106
|
-
subscription: Stripe.Subscription
|
|
107
|
-
) => Promise<Entities['CreateSubscriptionMapper']>
|
|
108
|
-
>;
|
|
109
|
-
UpdateSubscriptionMapper: RequestMapperConstructor<
|
|
110
|
-
SchemaValidator,
|
|
111
|
-
Dto['UpdateSubscriptionMapper'],
|
|
112
|
-
Entities['UpdateSubscriptionMapper'],
|
|
113
|
-
(
|
|
114
|
-
dto: Dto['UpdateSubscriptionMapper'],
|
|
115
|
-
em: EntityManager,
|
|
116
|
-
subscription: Stripe.Subscription
|
|
117
|
-
) => Promise<Entities['UpdateSubscriptionMapper']>
|
|
118
|
-
>;
|
|
119
|
-
},
|
|
64
|
+
mappers: StripeSubscriptionMappers<PartyType, Entities, Dto>,
|
|
120
65
|
readonly options?: {
|
|
121
66
|
telemetry?: TelemetryOptions;
|
|
122
67
|
databaseTableName?: string;
|
|
123
68
|
}
|
|
124
69
|
) {
|
|
125
|
-
this.
|
|
70
|
+
this.stripeClient = stripeClient;
|
|
126
71
|
this.em = em;
|
|
127
72
|
this.openTelemetryCollector = openTelemetryCollector;
|
|
128
73
|
this.schemaValidator = schemaValidator;
|
|
129
74
|
this.mappers = mappers;
|
|
130
|
-
this._mappers = transformIntoInternalMapper(mappers, schemaValidator);
|
|
131
75
|
this.baseSubscriptionService = new BaseSubscriptionService(
|
|
132
76
|
em,
|
|
133
77
|
openTelemetryCollector,
|
|
134
78
|
schemaValidator,
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
>,
|
|
142
|
-
UpdateSubscriptionMapper: IdentityRequestMapper<
|
|
143
|
-
Entities['UpdateSubscriptionMapper']
|
|
144
|
-
>
|
|
145
|
-
},
|
|
79
|
+
mappers as SubscriptionMappers<
|
|
80
|
+
PartyType,
|
|
81
|
+
BillingProviderEnum,
|
|
82
|
+
Entities,
|
|
83
|
+
Dto
|
|
84
|
+
>,
|
|
146
85
|
options
|
|
147
86
|
);
|
|
148
87
|
}
|
|
149
88
|
|
|
150
89
|
async createSubscription(
|
|
151
|
-
subscriptionDto:
|
|
90
|
+
subscriptionDto: StripeCreateSubscriptionDto<PartyType>,
|
|
152
91
|
em?: EntityManager
|
|
153
92
|
): Promise<Dto['SubscriptionMapper']> {
|
|
154
|
-
const subscription = await this.
|
|
93
|
+
const subscription = await this.stripeClient.subscriptions.create({
|
|
155
94
|
...subscriptionDto.stripeFields,
|
|
156
95
|
customer: subscriptionDto.partyId,
|
|
157
96
|
items: [
|
|
@@ -161,22 +100,14 @@ export class StripeSubscriptionService<
|
|
|
161
100
|
]
|
|
162
101
|
});
|
|
163
102
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
em ?? this.em,
|
|
173
|
-
subscription
|
|
174
|
-
),
|
|
175
|
-
em
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
return this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
179
|
-
subscriptionEntity
|
|
103
|
+
return await this.baseSubscriptionService.createSubscription(
|
|
104
|
+
{
|
|
105
|
+
...subscriptionDto,
|
|
106
|
+
externalId: subscription.id,
|
|
107
|
+
billingProvider: 'stripe'
|
|
108
|
+
},
|
|
109
|
+
em ?? this.em,
|
|
110
|
+
subscription
|
|
180
111
|
);
|
|
181
112
|
}
|
|
182
113
|
|
|
@@ -184,24 +115,26 @@ export class StripeSubscriptionService<
|
|
|
184
115
|
idDto: IdDto,
|
|
185
116
|
em?: EntityManager
|
|
186
117
|
): Promise<Dto['SubscriptionMapper']> {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
118
|
+
const subscriptionEntity =
|
|
119
|
+
await this.baseSubscriptionService.getSubscription(idDto, em);
|
|
120
|
+
const stripeSubscription = await this.stripeClient.subscriptions.retrieve(
|
|
121
|
+
idDto.id
|
|
122
|
+
);
|
|
123
|
+
subscriptionEntity.stripeFields = stripeSubscription;
|
|
124
|
+
return subscriptionEntity;
|
|
193
125
|
}
|
|
194
126
|
|
|
195
127
|
async getUserSubscription(
|
|
196
128
|
idDto: IdDto,
|
|
197
129
|
em?: EntityManager
|
|
198
130
|
): Promise<Dto['SubscriptionMapper']> {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
131
|
+
const subscriptionEntity =
|
|
132
|
+
await this.baseSubscriptionService.getUserSubscription(idDto, em);
|
|
133
|
+
const stripeSubscription = await this.stripeClient.subscriptions.retrieve(
|
|
134
|
+
idDto.id
|
|
135
|
+
);
|
|
136
|
+
subscriptionEntity.stripeFields = stripeSubscription;
|
|
137
|
+
return subscriptionEntity;
|
|
205
138
|
}
|
|
206
139
|
|
|
207
140
|
async getOrganizationSubscription(
|
|
@@ -217,22 +150,23 @@ export class StripeSubscriptionService<
|
|
|
217
150
|
if (!id) {
|
|
218
151
|
throw new Error('Subscription not found');
|
|
219
152
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
153
|
+
const subscriptionEntity =
|
|
154
|
+
await this.baseSubscriptionService.getOrganizationSubscription(
|
|
155
|
+
{ id },
|
|
156
|
+
em
|
|
157
|
+
);
|
|
158
|
+
const stripeSubscription = await this.stripeClient.subscriptions.retrieve(
|
|
159
|
+
idDto.id
|
|
160
|
+
);
|
|
161
|
+
subscriptionEntity.stripeFields = stripeSubscription;
|
|
162
|
+
return subscriptionEntity;
|
|
229
163
|
}
|
|
230
164
|
|
|
231
165
|
async updateSubscription(
|
|
232
|
-
subscriptionDto:
|
|
166
|
+
subscriptionDto: StripeUpdateSubscriptionDto<PartyType>,
|
|
233
167
|
em?: EntityManager
|
|
234
168
|
): Promise<Dto['SubscriptionMapper']> {
|
|
235
|
-
const subscription = await this.
|
|
169
|
+
const subscription = await this.stripeClient.subscriptions.update(
|
|
236
170
|
subscriptionDto.id,
|
|
237
171
|
{
|
|
238
172
|
...subscriptionDto.stripeFields,
|
|
@@ -244,23 +178,15 @@ export class StripeSubscriptionService<
|
|
|
244
178
|
}
|
|
245
179
|
);
|
|
246
180
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
em ?? this.em,
|
|
257
|
-
subscription
|
|
258
|
-
),
|
|
259
|
-
em
|
|
260
|
-
);
|
|
261
|
-
|
|
262
|
-
return this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
263
|
-
subscriptionEntity
|
|
181
|
+
return await this.baseSubscriptionService.updateSubscription(
|
|
182
|
+
{
|
|
183
|
+
...subscriptionDto,
|
|
184
|
+
externalId: subscription.id,
|
|
185
|
+
billingProvider: 'stripe',
|
|
186
|
+
providerFields: subscription
|
|
187
|
+
},
|
|
188
|
+
em ?? this.em,
|
|
189
|
+
subscription
|
|
264
190
|
);
|
|
265
191
|
}
|
|
266
192
|
|
|
@@ -268,7 +194,7 @@ export class StripeSubscriptionService<
|
|
|
268
194
|
idDto: { id: string },
|
|
269
195
|
em?: EntityManager
|
|
270
196
|
): Promise<void> {
|
|
271
|
-
await this.
|
|
197
|
+
await this.stripeClient.subscriptions.cancel(idDto.id);
|
|
272
198
|
await this.baseSubscriptionService.deleteSubscription(idDto, em);
|
|
273
199
|
}
|
|
274
200
|
|
|
@@ -277,7 +203,7 @@ export class StripeSubscriptionService<
|
|
|
277
203
|
em?: EntityManager
|
|
278
204
|
): Promise<Dto['SubscriptionMapper'][]> {
|
|
279
205
|
const subscriptions = (
|
|
280
|
-
await this.
|
|
206
|
+
await this.stripeClient.subscriptions.list({
|
|
281
207
|
status: 'active'
|
|
282
208
|
})
|
|
283
209
|
).data.filter((s) => idsDto.ids?.includes(s.id));
|
|
@@ -296,26 +222,23 @@ export class StripeSubscriptionService<
|
|
|
296
222
|
return await Promise.all(
|
|
297
223
|
(await this.baseSubscriptionService.listSubscriptions({ ids }, em)).map(
|
|
298
224
|
async (subscription) => {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
(s) => s.id === subscription.externalId
|
|
305
|
-
)
|
|
306
|
-
};
|
|
225
|
+
const stripeSubscription = subscriptions.find(
|
|
226
|
+
(s) => s.id === subscription.externalId
|
|
227
|
+
)!;
|
|
228
|
+
subscription.stripeFields = stripeSubscription;
|
|
229
|
+
return subscription;
|
|
307
230
|
}
|
|
308
231
|
)
|
|
309
232
|
);
|
|
310
233
|
}
|
|
311
234
|
|
|
312
235
|
async cancelSubscription(idDto: IdDto, em?: EntityManager): Promise<void> {
|
|
313
|
-
await this.
|
|
236
|
+
await this.stripeClient.subscriptions.cancel(idDto.id);
|
|
314
237
|
await this.baseSubscriptionService.cancelSubscription(idDto, em);
|
|
315
238
|
}
|
|
316
239
|
|
|
317
240
|
async resumeSubscription(idDto: IdDto, em?: EntityManager): Promise<void> {
|
|
318
|
-
await this.
|
|
241
|
+
await this.stripeClient.subscriptions.resume(idDto.id);
|
|
319
242
|
await this.baseSubscriptionService.resumeSubscription(idDto, em);
|
|
320
243
|
}
|
|
321
244
|
}
|
|
@@ -114,8 +114,7 @@ export class StripeWebhookService<
|
|
|
114
114
|
id: event.data.object.id,
|
|
115
115
|
customerId: event.data.object.customer,
|
|
116
116
|
expiresAt: new Date(event.data.object.created + 5 * 60 * 1000),
|
|
117
|
-
uri: event.data.object.url
|
|
118
|
-
providerFields: event.data.object
|
|
117
|
+
uri: event.data.object.url
|
|
119
118
|
}
|
|
120
119
|
);
|
|
121
120
|
break;
|
|
@@ -147,8 +146,7 @@ export class StripeWebhookService<
|
|
|
147
146
|
paymentMethods: event.data.object
|
|
148
147
|
.payment_method_types as PaymentMethodEnum[],
|
|
149
148
|
status: 'CREATED' as StatusEnum[keyof StatusEnum],
|
|
150
|
-
currency: event.data.object.currency as CurrencyEnum
|
|
151
|
-
providerFields: event.data.object
|
|
149
|
+
currency: event.data.object.currency as CurrencyEnum
|
|
152
150
|
});
|
|
153
151
|
}
|
|
154
152
|
break;
|
|
@@ -164,8 +162,7 @@ export class StripeWebhookService<
|
|
|
164
162
|
paymentMethods: event.data.object
|
|
165
163
|
.payment_method_types as PaymentMethodEnum[],
|
|
166
164
|
status: 'UPDATED' as StatusEnum[keyof StatusEnum],
|
|
167
|
-
currency: event.data.object.currency as CurrencyEnum
|
|
168
|
-
providerFields: event.data.object
|
|
165
|
+
currency: event.data.object.currency as CurrencyEnum
|
|
169
166
|
});
|
|
170
167
|
break;
|
|
171
168
|
}
|
|
@@ -187,8 +184,7 @@ export class StripeWebhookService<
|
|
|
187
184
|
? event.data.object.product
|
|
188
185
|
: event.data.object.product?.id,
|
|
189
186
|
price: event.data.object.amount,
|
|
190
|
-
externalId: event.data.object.id
|
|
191
|
-
providerFields: event.data.object
|
|
187
|
+
externalId: event.data.object.id
|
|
192
188
|
});
|
|
193
189
|
} else {
|
|
194
190
|
throw new Error('Invalid plan');
|
|
@@ -213,8 +209,7 @@ export class StripeWebhookService<
|
|
|
213
209
|
? event.data.object.product
|
|
214
210
|
: event.data.object.product?.id,
|
|
215
211
|
price: event.data.object.amount,
|
|
216
|
-
externalId: event.data.object.id
|
|
217
|
-
providerFields: event.data.object
|
|
212
|
+
externalId: event.data.object.id
|
|
218
213
|
});
|
|
219
214
|
} else {
|
|
220
215
|
throw new Error('Invalid plan');
|
|
@@ -240,7 +235,6 @@ export class StripeWebhookService<
|
|
|
240
235
|
description: event.data.object.description ?? undefined,
|
|
241
236
|
active: true,
|
|
242
237
|
productId: event.data.object.items.data[0].plan.id,
|
|
243
|
-
providerFields: event.data.object,
|
|
244
238
|
externalId: event.data.object.id,
|
|
245
239
|
billingProvider: BillingProviderEnum.STRIPE,
|
|
246
240
|
startDate: new Date(event.data.object.created),
|
|
@@ -262,7 +256,6 @@ export class StripeWebhookService<
|
|
|
262
256
|
partyType: 'USER' as PartyEnum[keyof PartyEnum],
|
|
263
257
|
description: event.data.object.description ?? undefined,
|
|
264
258
|
active: true,
|
|
265
|
-
providerFields: event.data.object,
|
|
266
259
|
externalId: event.data.object.id,
|
|
267
260
|
billingProvider: BillingProviderEnum.STRIPE,
|
|
268
261
|
startDate: new Date(event.data.object.created),
|