@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.
- package/LICENSE +21 -0
- package/lib/domain/index.d.mts +189 -0
- package/lib/domain/index.d.ts +189 -0
- package/lib/domain/index.js +231 -0
- package/lib/domain/index.mjs +201 -0
- package/lib/eject/domain/schemas/billingPortal.schema.ts +37 -0
- package/lib/eject/domain/schemas/checkoutSession.schema.ts +74 -0
- package/lib/eject/domain/schemas/index.ts +5 -0
- package/lib/eject/domain/schemas/paymentLink.schema.ts +62 -0
- package/lib/eject/domain/schemas/plan.schema.ts +68 -0
- package/lib/eject/domain/schemas/subscription.schema.ts +78 -0
- package/lib/eject/services/billingPortal.service.ts +185 -0
- package/lib/eject/services/checkoutSession.service.ts +179 -0
- package/lib/eject/services/index.ts +6 -0
- package/lib/eject/services/paymentLink.service.ts +239 -0
- package/lib/eject/services/plan.service.ts +219 -0
- package/lib/eject/services/subscription.service.ts +285 -0
- package/lib/eject/services/webhook.service.ts +272 -0
- package/lib/eject/types/index.ts +2 -0
- package/lib/eject/types/stripe.dto.types.ts +214 -0
- package/lib/eject/types/stripe.entity.types.ts +83 -0
- package/lib/schemas/index.d.mts +376 -0
- package/lib/schemas/index.d.ts +376 -0
- package/lib/schemas/index.js +704 -0
- package/lib/schemas/index.mjs +737 -0
- package/lib/services/index.d.mts +223 -0
- package/lib/services/index.d.ts +223 -0
- package/lib/services/index.js +788 -0
- package/lib/services/index.mjs +776 -0
- package/lib/types/index.d.mts +121 -0
- package/lib/types/index.d.ts +121 -0
- package/lib/types/index.js +18 -0
- package/lib/types/index.mjs +0 -0
- 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,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
|
+
}
|