@forklaunch/implementation-billing-stripe 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/LICENSE +21 -0
  2. package/lib/domain/index.d.mts +189 -0
  3. package/lib/domain/index.d.ts +189 -0
  4. package/lib/domain/index.js +231 -0
  5. package/lib/domain/index.mjs +201 -0
  6. package/lib/eject/domain/schemas/billingPortal.schema.ts +37 -0
  7. package/lib/eject/domain/schemas/checkoutSession.schema.ts +74 -0
  8. package/lib/eject/domain/schemas/index.ts +5 -0
  9. package/lib/eject/domain/schemas/paymentLink.schema.ts +62 -0
  10. package/lib/eject/domain/schemas/plan.schema.ts +68 -0
  11. package/lib/eject/domain/schemas/subscription.schema.ts +78 -0
  12. package/lib/eject/services/billingPortal.service.ts +185 -0
  13. package/lib/eject/services/checkoutSession.service.ts +179 -0
  14. package/lib/eject/services/index.ts +6 -0
  15. package/lib/eject/services/paymentLink.service.ts +239 -0
  16. package/lib/eject/services/plan.service.ts +219 -0
  17. package/lib/eject/services/subscription.service.ts +285 -0
  18. package/lib/eject/services/webhook.service.ts +272 -0
  19. package/lib/eject/types/index.ts +2 -0
  20. package/lib/eject/types/stripe.dto.types.ts +214 -0
  21. package/lib/eject/types/stripe.entity.types.ts +83 -0
  22. package/lib/schemas/index.d.mts +376 -0
  23. package/lib/schemas/index.d.ts +376 -0
  24. package/lib/schemas/index.js +704 -0
  25. package/lib/schemas/index.mjs +737 -0
  26. package/lib/services/index.d.mts +223 -0
  27. package/lib/services/index.d.ts +223 -0
  28. package/lib/services/index.js +788 -0
  29. package/lib/services/index.mjs +776 -0
  30. package/lib/types/index.d.mts +121 -0
  31. package/lib/types/index.d.ts +121 -0
  32. package/lib/types/index.js +18 -0
  33. package/lib/types/index.mjs +0 -0
  34. package/package.json +74 -0
@@ -0,0 +1,185 @@
1
+ import { IdDto, InstanceTypeRecord } from '@forklaunch/common';
2
+ import { TtlCache } from '@forklaunch/core/cache';
3
+ import {
4
+ MetricsDefinition,
5
+ OpenTelemetryCollector,
6
+ TelemetryOptions
7
+ } from '@forklaunch/core/http';
8
+ import { BaseBillingPortalService } from '@forklaunch/implementation-billing-base/services';
9
+ import { BillingPortalService } from '@forklaunch/interfaces-billing/interfaces';
10
+ import {
11
+ IdentityRequestMapper,
12
+ IdentityResponseMapper,
13
+ InternalMapper,
14
+ RequestMapperConstructor,
15
+ ResponseMapperConstructor,
16
+ transformIntoInternalMapper
17
+ } from '@forklaunch/internal';
18
+ import { AnySchemaValidator } from '@forklaunch/validator';
19
+ import { EntityManager } from '@mikro-orm/core';
20
+ import Stripe from 'stripe';
21
+ import {
22
+ StripeBillingPortalDto,
23
+ StripeBillingPortalDtos,
24
+ StripeCreateBillingPortalDto,
25
+ StripeUpdateBillingPortalDto
26
+ } from '../types/stripe.dto.types';
27
+ import { StripeBillingPortalEntities } from '../types/stripe.entity.types';
28
+
29
+ export class StripeBillingPortalService<
30
+ SchemaValidator extends AnySchemaValidator,
31
+ Entities extends StripeBillingPortalEntities,
32
+ Dto extends StripeBillingPortalDtos = StripeBillingPortalDtos
33
+ > implements
34
+ BillingPortalService<{
35
+ CreateBillingPortalDto: StripeCreateBillingPortalDto;
36
+ UpdateBillingPortalDto: StripeUpdateBillingPortalDto;
37
+ BillingPortalDto: StripeBillingPortalDto;
38
+ IdDto: IdDto;
39
+ }>
40
+ {
41
+ private readonly billingPortalSessionExpiryDurationMs = 5 * 60 * 1000;
42
+
43
+ baseBillingPortalService: BaseBillingPortalService<
44
+ SchemaValidator,
45
+ Entities,
46
+ Entities
47
+ >;
48
+ protected _mappers: InternalMapper<InstanceTypeRecord<typeof this.mappers>>;
49
+
50
+ constructor(
51
+ protected stripeClient: Stripe,
52
+ protected em: EntityManager,
53
+ protected cache: TtlCache,
54
+ protected openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>,
55
+ protected schemaValidator: SchemaValidator,
56
+ protected mappers: {
57
+ BillingPortalMapper: ResponseMapperConstructor<
58
+ SchemaValidator,
59
+ Dto['BillingPortalMapper'],
60
+ Entities['BillingPortalMapper']
61
+ >;
62
+ CreateBillingPortalMapper: RequestMapperConstructor<
63
+ SchemaValidator,
64
+ Dto['CreateBillingPortalMapper'],
65
+ Entities['CreateBillingPortalMapper'],
66
+ (
67
+ dto: Dto['CreateBillingPortalMapper'],
68
+ em: EntityManager,
69
+ session: Stripe.BillingPortal.Session
70
+ ) => Promise<Entities['CreateBillingPortalMapper']>
71
+ >;
72
+ UpdateBillingPortalMapper: RequestMapperConstructor<
73
+ SchemaValidator,
74
+ Dto['UpdateBillingPortalMapper'],
75
+ Entities['UpdateBillingPortalMapper'],
76
+ (
77
+ dto: Dto['UpdateBillingPortalMapper'],
78
+ em: EntityManager,
79
+ session: Stripe.BillingPortal.Session
80
+ ) => Promise<Entities['UpdateBillingPortalMapper']>
81
+ >;
82
+ },
83
+ readonly options?: {
84
+ telemetry?: TelemetryOptions;
85
+ enableDatabaseBackup?: boolean;
86
+ }
87
+ ) {
88
+ this._mappers = transformIntoInternalMapper(mappers, schemaValidator);
89
+ this.baseBillingPortalService = new BaseBillingPortalService(
90
+ em,
91
+ cache,
92
+ openTelemetryCollector,
93
+ schemaValidator,
94
+ {
95
+ BillingPortalMapper: IdentityResponseMapper<
96
+ Entities['BillingPortalMapper']
97
+ >,
98
+ CreateBillingPortalMapper: IdentityRequestMapper<
99
+ Entities['CreateBillingPortalMapper']
100
+ >,
101
+ UpdateBillingPortalMapper: IdentityRequestMapper<
102
+ Entities['UpdateBillingPortalMapper']
103
+ >
104
+ },
105
+ options
106
+ );
107
+ }
108
+
109
+ async createBillingPortalSession(
110
+ billingPortalDto: Dto['CreateBillingPortalMapper']
111
+ ): Promise<Dto['BillingPortalMapper']> {
112
+ const session = await this.stripeClient.billingPortal.sessions.create({
113
+ ...billingPortalDto.stripeFields,
114
+ customer: billingPortalDto.customerId
115
+ });
116
+
117
+ const billingPortalEntity =
118
+ await this.baseBillingPortalService.createBillingPortalSession(
119
+ await this._mappers.CreateBillingPortalMapper.deserializeDtoToEntity(
120
+ {
121
+ ...billingPortalDto,
122
+ id: session.id,
123
+ uri: session.url,
124
+ expiresAt: new Date(
125
+ Date.now() + this.billingPortalSessionExpiryDurationMs
126
+ )
127
+ },
128
+ this.em,
129
+ session
130
+ )
131
+ );
132
+
133
+ return this._mappers.BillingPortalMapper.serializeEntityToDto(
134
+ billingPortalEntity
135
+ );
136
+ }
137
+
138
+ async getBillingPortalSession(
139
+ idDto: IdDto
140
+ ): Promise<Dto['BillingPortalMapper']> {
141
+ const billingPortalEntity =
142
+ await this.baseBillingPortalService.getBillingPortalSession(idDto);
143
+
144
+ return this._mappers.BillingPortalMapper.serializeEntityToDto(
145
+ billingPortalEntity
146
+ );
147
+ }
148
+
149
+ async expireBillingPortalSession(idDto: IdDto): Promise<void> {
150
+ return this.baseBillingPortalService.expireBillingPortalSession(idDto);
151
+ }
152
+
153
+ async updateBillingPortalSession(
154
+ billingPortalDto: Dto['UpdateBillingPortalMapper']
155
+ ): Promise<Dto['BillingPortalMapper']> {
156
+ const existingSession =
157
+ await this.baseBillingPortalService.getBillingPortalSession({
158
+ id: billingPortalDto.id
159
+ });
160
+ const session = await this.stripeClient.billingPortal.sessions.create({
161
+ ...billingPortalDto.stripeFields,
162
+ customer: existingSession.customerId
163
+ });
164
+
165
+ const baseBillingPortalDto =
166
+ await this.baseBillingPortalService.updateBillingPortalSession(
167
+ await this._mappers.UpdateBillingPortalMapper.deserializeDtoToEntity(
168
+ {
169
+ ...billingPortalDto,
170
+ id: session.id,
171
+ uri: session.url,
172
+ expiresAt: new Date(
173
+ Date.now() + this.billingPortalSessionExpiryDurationMs
174
+ )
175
+ },
176
+ this.em,
177
+ session
178
+ )
179
+ );
180
+
181
+ return this._mappers.BillingPortalMapper.serializeEntityToDto(
182
+ baseBillingPortalDto
183
+ );
184
+ }
185
+ }
@@ -0,0 +1,179 @@
1
+ import { IdDto, InstanceTypeRecord } from '@forklaunch/common';
2
+ import { TtlCache } from '@forklaunch/core/cache';
3
+ import {
4
+ MetricsDefinition,
5
+ OpenTelemetryCollector,
6
+ TelemetryOptions
7
+ } from '@forklaunch/core/http';
8
+ import { BaseCheckoutSessionService } from '@forklaunch/implementation-billing-base/services';
9
+ import { CheckoutSessionService } from '@forklaunch/interfaces-billing/interfaces';
10
+ import {
11
+ IdentityRequestMapper,
12
+ IdentityResponseMapper,
13
+ InternalMapper,
14
+ RequestMapperConstructor,
15
+ ResponseMapperConstructor,
16
+ transformIntoInternalMapper
17
+ } from '@forklaunch/internal';
18
+ import { AnySchemaValidator } from '@forklaunch/validator';
19
+ import { EntityManager } from '@mikro-orm/core';
20
+ import Stripe from 'stripe';
21
+ import { CurrencyEnum } from '../domain/enums/currency.enum';
22
+ import { PaymentMethodEnum } from '../domain/enums/paymentMethod.enum';
23
+ import { StripeCheckoutSessionDtos } from '../types/stripe.dto.types';
24
+ import { StripeCheckoutSessionEntities } from '../types/stripe.entity.types';
25
+
26
+ export class StripeCheckoutSessionService<
27
+ SchemaValidator extends AnySchemaValidator,
28
+ StatusEnum,
29
+ Entities extends StripeCheckoutSessionEntities<StatusEnum>,
30
+ Dto extends
31
+ StripeCheckoutSessionDtos<StatusEnum> = StripeCheckoutSessionDtos<StatusEnum>
32
+ > implements
33
+ CheckoutSessionService<
34
+ typeof PaymentMethodEnum,
35
+ typeof CurrencyEnum,
36
+ StatusEnum,
37
+ {
38
+ CreateCheckoutSessionDto: Dto['CreateCheckoutSessionMapper'];
39
+ CheckoutSessionDto: Dto['CheckoutSessionMapper'];
40
+ IdDto: IdDto;
41
+ }
42
+ >
43
+ {
44
+ baseCheckoutSessionService: BaseCheckoutSessionService<
45
+ SchemaValidator,
46
+ typeof PaymentMethodEnum,
47
+ typeof CurrencyEnum,
48
+ StatusEnum,
49
+ Entities,
50
+ Entities
51
+ >;
52
+ protected _mappers: InternalMapper<InstanceTypeRecord<typeof this.mappers>>;
53
+
54
+ constructor(
55
+ protected readonly stripeClient: Stripe,
56
+ protected readonly em: EntityManager,
57
+ protected readonly cache: TtlCache,
58
+ protected readonly openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>,
59
+ protected readonly schemaValidator: SchemaValidator,
60
+ protected readonly mappers: {
61
+ CheckoutSessionMapper: ResponseMapperConstructor<
62
+ SchemaValidator,
63
+ Dto['CheckoutSessionMapper'],
64
+ Entities['CheckoutSessionMapper']
65
+ >;
66
+ CreateCheckoutSessionMapper: RequestMapperConstructor<
67
+ SchemaValidator,
68
+ Dto['CreateCheckoutSessionMapper'],
69
+ Entities['CreateCheckoutSessionMapper'],
70
+ (
71
+ dto: Dto['CreateCheckoutSessionMapper'],
72
+ em: EntityManager,
73
+ session: Stripe.Checkout.Session
74
+ ) => Promise<Entities['CreateCheckoutSessionMapper']>
75
+ >;
76
+ UpdateCheckoutSessionMapper: RequestMapperConstructor<
77
+ SchemaValidator,
78
+ Dto['UpdateCheckoutSessionMapper'],
79
+ Entities['UpdateCheckoutSessionMapper'],
80
+ (
81
+ dto: Dto['UpdateCheckoutSessionMapper'],
82
+ em: EntityManager,
83
+ session: Stripe.Checkout.Session
84
+ ) => Promise<Entities['UpdateCheckoutSessionMapper']>
85
+ >;
86
+ },
87
+ readonly options?: {
88
+ enableDatabaseBackup?: boolean;
89
+ telemetry?: TelemetryOptions;
90
+ }
91
+ ) {
92
+ this._mappers = transformIntoInternalMapper(mappers, schemaValidator);
93
+ this.baseCheckoutSessionService = new BaseCheckoutSessionService(
94
+ em,
95
+ cache,
96
+ openTelemetryCollector,
97
+ schemaValidator,
98
+ {
99
+ CheckoutSessionMapper: IdentityResponseMapper<
100
+ Entities['CheckoutSessionMapper']
101
+ >,
102
+ CreateCheckoutSessionMapper: IdentityRequestMapper<
103
+ Entities['CreateCheckoutSessionMapper']
104
+ >,
105
+ UpdateCheckoutSessionMapper: IdentityRequestMapper<
106
+ Entities['UpdateCheckoutSessionMapper']
107
+ >
108
+ },
109
+ options
110
+ );
111
+ }
112
+
113
+ async createCheckoutSession(
114
+ checkoutSessionDto: Dto['CreateCheckoutSessionMapper']
115
+ ): Promise<Dto['CheckoutSessionMapper']> {
116
+ const session = await this.stripeClient.checkout.sessions.create({
117
+ ...checkoutSessionDto.stripeFields,
118
+ payment_method_types: checkoutSessionDto.paymentMethods,
119
+ currency: checkoutSessionDto.currency as string,
120
+ success_url: checkoutSessionDto.successRedirectUri,
121
+ cancel_url: checkoutSessionDto.cancelRedirectUri
122
+ });
123
+
124
+ const checkoutSessionEntity =
125
+ await this.baseCheckoutSessionService.createCheckoutSession(
126
+ await this._mappers.CreateCheckoutSessionMapper.deserializeDtoToEntity(
127
+ {
128
+ ...checkoutSessionDto,
129
+ id: session.id,
130
+ uri: session.url,
131
+ expiresAt: new Date(Date.now() + 5 * 60 * 1000),
132
+ providerFields: session
133
+ },
134
+ this.em,
135
+ session
136
+ )
137
+ );
138
+
139
+ return this._mappers.CheckoutSessionMapper.serializeEntityToDto(
140
+ checkoutSessionEntity
141
+ );
142
+ }
143
+
144
+ async getCheckoutSession({
145
+ id
146
+ }: IdDto): Promise<Dto['CheckoutSessionMapper']> {
147
+ const databaseCheckoutSession =
148
+ await this.baseCheckoutSessionService.getCheckoutSession({ id });
149
+ return {
150
+ ...this._mappers.CheckoutSessionMapper.serializeEntityToDto(
151
+ databaseCheckoutSession
152
+ ),
153
+ stripeFields: await this.stripeClient.checkout.sessions.retrieve(id)
154
+ };
155
+ }
156
+
157
+ async expireCheckoutSession({ id }: IdDto): Promise<void> {
158
+ await this.stripeClient.checkout.sessions.expire(id);
159
+ await this.baseCheckoutSessionService.expireCheckoutSession({ id });
160
+ }
161
+
162
+ async handleCheckoutSuccess({ id }: IdDto): Promise<void> {
163
+ await this.stripeClient.checkout.sessions.update(id, {
164
+ metadata: {
165
+ status: 'SUCCESS'
166
+ }
167
+ });
168
+ await this.baseCheckoutSessionService.handleCheckoutSuccess({ id });
169
+ }
170
+
171
+ async handleCheckoutFailure({ id }: IdDto): Promise<void> {
172
+ await this.stripeClient.checkout.sessions.update(id, {
173
+ metadata: {
174
+ status: 'FAILED'
175
+ }
176
+ });
177
+ await this.baseCheckoutSessionService.handleCheckoutFailure({ id });
178
+ }
179
+ }
@@ -0,0 +1,6 @@
1
+ export * from './billingPortal.service';
2
+ export * from './checkoutSession.service';
3
+ export * from './paymentLink.service';
4
+ export * from './plan.service';
5
+ export * from './subscription.service';
6
+ export * from './webhook.service';
@@ -0,0 +1,239 @@
1
+ import { IdDto, IdsDto, InstanceTypeRecord } from '@forklaunch/common';
2
+ import { TtlCache } from '@forklaunch/core/cache';
3
+ import {
4
+ MetricsDefinition,
5
+ OpenTelemetryCollector,
6
+ TelemetryOptions
7
+ } from '@forklaunch/core/http';
8
+ import { BasePaymentLinkService } from '@forklaunch/implementation-billing-base/services';
9
+ import { PaymentLinkService } from '@forklaunch/interfaces-billing/interfaces';
10
+ import {
11
+ IdentityRequestMapper,
12
+ IdentityResponseMapper,
13
+ InternalMapper,
14
+ RequestMapperConstructor,
15
+ ResponseMapperConstructor,
16
+ transformIntoInternalMapper
17
+ } from '@forklaunch/internal';
18
+ import { AnySchemaValidator } from '@forklaunch/validator';
19
+ import { EntityManager } from '@mikro-orm/core';
20
+ import Stripe from 'stripe';
21
+ import { CurrencyEnum } from '../domain/enums/currency.enum';
22
+ import { PaymentMethodEnum } from '../domain/enums/paymentMethod.enum';
23
+ import {
24
+ StripeCreatePaymentLinkDto,
25
+ StripePaymentLinkDto,
26
+ StripePaymentLinkDtos,
27
+ StripeUpdatePaymentLinkDto
28
+ } from '../types/stripe.dto.types';
29
+ import { StripePaymentLinkEntities } from '../types/stripe.entity.types';
30
+
31
+ export class StripePaymentLinkService<
32
+ SchemaValidator extends AnySchemaValidator,
33
+ StatusEnum,
34
+ Entities extends StripePaymentLinkEntities<StatusEnum>,
35
+ Dto extends
36
+ StripePaymentLinkDtos<StatusEnum> = StripePaymentLinkDtos<StatusEnum>
37
+ > implements
38
+ PaymentLinkService<
39
+ PaymentMethodEnum,
40
+ CurrencyEnum,
41
+ StatusEnum,
42
+ {
43
+ CreatePaymentLinkDto: StripeCreatePaymentLinkDto<StatusEnum>;
44
+ UpdatePaymentLinkDto: StripeUpdatePaymentLinkDto<StatusEnum>;
45
+ PaymentLinkDto: StripePaymentLinkDto<StatusEnum>;
46
+ IdDto: IdDto;
47
+ IdsDto: IdsDto;
48
+ }
49
+ >
50
+ {
51
+ basePaymentLinkService: BasePaymentLinkService<
52
+ SchemaValidator,
53
+ typeof PaymentMethodEnum,
54
+ typeof CurrencyEnum,
55
+ StatusEnum,
56
+ Entities,
57
+ Entities
58
+ >;
59
+ protected _mappers: InternalMapper<InstanceTypeRecord<typeof this.mappers>>;
60
+
61
+ constructor(
62
+ protected readonly stripeClient: Stripe,
63
+ protected readonly em: EntityManager,
64
+ protected readonly cache: TtlCache,
65
+ protected readonly openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>,
66
+ protected readonly schemaValidator: SchemaValidator,
67
+ protected readonly mappers: {
68
+ PaymentLinkMapper: ResponseMapperConstructor<
69
+ SchemaValidator,
70
+ Dto['PaymentLinkMapper'],
71
+ Entities['PaymentLinkMapper']
72
+ >;
73
+ CreatePaymentLinkMapper: RequestMapperConstructor<
74
+ SchemaValidator,
75
+ Dto['CreatePaymentLinkMapper'],
76
+ Entities['CreatePaymentLinkMapper'],
77
+ (
78
+ dto: Dto['CreatePaymentLinkMapper'],
79
+ em: EntityManager,
80
+ paymentLink: Stripe.PaymentLink
81
+ ) => Promise<Entities['CreatePaymentLinkMapper']>
82
+ >;
83
+ UpdatePaymentLinkMapper: RequestMapperConstructor<
84
+ SchemaValidator,
85
+ Dto['UpdatePaymentLinkMapper'],
86
+ Entities['UpdatePaymentLinkMapper'],
87
+ (
88
+ dto: Dto['UpdatePaymentLinkMapper'],
89
+ em: EntityManager,
90
+ paymentLink: Stripe.PaymentLink
91
+ ) => Promise<Entities['UpdatePaymentLinkMapper']>
92
+ >;
93
+ },
94
+ readonly options?: {
95
+ enableDatabaseBackup?: boolean;
96
+ telemetry?: TelemetryOptions;
97
+ }
98
+ ) {
99
+ this._mappers = transformIntoInternalMapper(mappers, schemaValidator);
100
+ this.basePaymentLinkService = new BasePaymentLinkService(
101
+ em,
102
+ cache,
103
+ openTelemetryCollector,
104
+ schemaValidator,
105
+ {
106
+ PaymentLinkMapper: IdentityResponseMapper<
107
+ Entities['PaymentLinkMapper']
108
+ >,
109
+ CreatePaymentLinkMapper: IdentityRequestMapper<
110
+ Entities['CreatePaymentLinkMapper']
111
+ >,
112
+ UpdatePaymentLinkMapper: IdentityRequestMapper<
113
+ Entities['UpdatePaymentLinkMapper']
114
+ >
115
+ },
116
+ options
117
+ );
118
+ }
119
+
120
+ async createPaymentLink(
121
+ paymentLinkDto: Dto['CreatePaymentLinkMapper']
122
+ ): Promise<Dto['PaymentLinkMapper']> {
123
+ const session = await this.stripeClient.paymentLinks.create({
124
+ ...paymentLinkDto.stripeFields,
125
+ payment_method_types: paymentLinkDto.paymentMethods,
126
+ currency: paymentLinkDto.currency as string
127
+ });
128
+
129
+ const paymentLinkEntity =
130
+ await this.basePaymentLinkService.createPaymentLink(
131
+ await this._mappers.CreatePaymentLinkMapper.deserializeDtoToEntity(
132
+ {
133
+ ...paymentLinkDto,
134
+ id: session.id,
135
+ amount:
136
+ session.line_items?.data.reduce<number>(
137
+ (total, item) => total + item.amount_total,
138
+ 0
139
+ ) ?? 0
140
+ },
141
+ this.em,
142
+ session
143
+ )
144
+ );
145
+
146
+ return this._mappers.PaymentLinkMapper.serializeEntityToDto(
147
+ paymentLinkEntity
148
+ );
149
+ }
150
+
151
+ async updatePaymentLink(
152
+ paymentLinkDto: Dto['UpdatePaymentLinkMapper']
153
+ ): Promise<Dto['PaymentLinkMapper']> {
154
+ const session = await this.stripeClient.paymentLinks.update(
155
+ paymentLinkDto.id,
156
+ {
157
+ ...paymentLinkDto.stripeFields,
158
+ payment_method_types: paymentLinkDto.paymentMethods
159
+ }
160
+ );
161
+
162
+ const paymentLinkEntity =
163
+ await this.basePaymentLinkService.updatePaymentLink(
164
+ await this._mappers.UpdatePaymentLinkMapper.deserializeDtoToEntity(
165
+ {
166
+ ...paymentLinkDto,
167
+ id: session.id,
168
+ amount:
169
+ session.line_items?.data.reduce<number>(
170
+ (total, item) => total + item.amount_total,
171
+ 0
172
+ ) ?? 0
173
+ },
174
+ this.em,
175
+ session
176
+ )
177
+ );
178
+
179
+ return this._mappers.PaymentLinkMapper.serializeEntityToDto(
180
+ paymentLinkEntity
181
+ );
182
+ }
183
+
184
+ async getPaymentLink({ id }: IdDto): Promise<Dto['PaymentLinkMapper']> {
185
+ const databasePaymentLink =
186
+ await this.basePaymentLinkService.getPaymentLink({ id });
187
+ return {
188
+ ...this._mappers.PaymentLinkMapper.serializeEntityToDto(
189
+ databasePaymentLink
190
+ ),
191
+ stripeFields: await this.stripeClient.paymentLinks.retrieve(id)
192
+ };
193
+ }
194
+
195
+ async expirePaymentLink({ id }: IdDto): Promise<void> {
196
+ await this.stripeClient.paymentLinks.update(id, {
197
+ metadata: {
198
+ status: 'EXPIRED'
199
+ }
200
+ });
201
+ await this.basePaymentLinkService.expirePaymentLink({ id });
202
+ }
203
+
204
+ async handlePaymentSuccess({ id }: IdDto): Promise<void> {
205
+ await this.stripeClient.paymentLinks.update(id, {
206
+ metadata: {
207
+ status: 'COMPLETED'
208
+ }
209
+ });
210
+ await this.basePaymentLinkService.handlePaymentSuccess({ id });
211
+ }
212
+
213
+ async handlePaymentFailure({ id }: IdDto): Promise<void> {
214
+ await this.stripeClient.paymentLinks.update(id, {
215
+ metadata: {
216
+ status: 'FAILED'
217
+ }
218
+ });
219
+ await this.basePaymentLinkService.handlePaymentFailure({ id });
220
+ }
221
+
222
+ async listPaymentLinks(idsDto?: IdsDto): Promise<Dto['PaymentLinkMapper'][]> {
223
+ const paymentLinks = await this.stripeClient.paymentLinks.list({
224
+ active: true
225
+ });
226
+ return await Promise.all(
227
+ (await this.basePaymentLinkService.listPaymentLinks(idsDto)).map(
228
+ async (paymentLink) => ({
229
+ ...(await this._mappers.PaymentLinkMapper.serializeEntityToDto(
230
+ paymentLink
231
+ )),
232
+ stripeFields: paymentLinks.data.find(
233
+ (paymentLink) => paymentLink.id === paymentLink.id
234
+ )
235
+ })
236
+ )
237
+ );
238
+ }
239
+ }