@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,219 @@
|
|
|
1
|
+
import { IdDto, IdsDto, InstanceTypeRecord } from '@forklaunch/common';
|
|
2
|
+
import {
|
|
3
|
+
MetricsDefinition,
|
|
4
|
+
OpenTelemetryCollector,
|
|
5
|
+
TelemetryOptions
|
|
6
|
+
} from '@forklaunch/core/http';
|
|
7
|
+
import { BasePlanService } from '@forklaunch/implementation-billing-base/services';
|
|
8
|
+
import { PlanService } from '@forklaunch/interfaces-billing/interfaces';
|
|
9
|
+
import {
|
|
10
|
+
IdentityRequestMapper,
|
|
11
|
+
IdentityResponseMapper,
|
|
12
|
+
InternalMapper,
|
|
13
|
+
RequestMapperConstructor,
|
|
14
|
+
ResponseMapperConstructor,
|
|
15
|
+
transformIntoInternalMapper
|
|
16
|
+
} from '@forklaunch/internal';
|
|
17
|
+
import { AnySchemaValidator } from '@forklaunch/validator';
|
|
18
|
+
import { EntityManager } from '@mikro-orm/core';
|
|
19
|
+
import Stripe from 'stripe';
|
|
20
|
+
import { BillingProviderEnum } from '../domain/enums/billingProvider.enum';
|
|
21
|
+
import { CurrencyEnum } from '../domain/enums/currency.enum';
|
|
22
|
+
import { PlanCadenceEnum } from '../domain/enums/planCadence.enum';
|
|
23
|
+
import {
|
|
24
|
+
StripeCreatePlanDto,
|
|
25
|
+
StripePlanDto,
|
|
26
|
+
StripePlanDtos,
|
|
27
|
+
StripeUpdatePlanDto
|
|
28
|
+
} from '../types/stripe.dto.types';
|
|
29
|
+
import { StripePlanEntities } from '../types/stripe.entity.types';
|
|
30
|
+
|
|
31
|
+
export class StripePlanService<
|
|
32
|
+
SchemaValidator extends AnySchemaValidator,
|
|
33
|
+
Entities extends StripePlanEntities,
|
|
34
|
+
Dto extends StripePlanDtos = StripePlanDtos
|
|
35
|
+
> implements
|
|
36
|
+
PlanService<
|
|
37
|
+
typeof PlanCadenceEnum,
|
|
38
|
+
typeof CurrencyEnum,
|
|
39
|
+
typeof BillingProviderEnum,
|
|
40
|
+
{
|
|
41
|
+
CreatePlanDto: StripeCreatePlanDto;
|
|
42
|
+
UpdatePlanDto: StripeUpdatePlanDto;
|
|
43
|
+
PlanDto: StripePlanDto;
|
|
44
|
+
IdDto: IdDto;
|
|
45
|
+
IdsDto: IdsDto;
|
|
46
|
+
}
|
|
47
|
+
>
|
|
48
|
+
{
|
|
49
|
+
basePlanService: BasePlanService<
|
|
50
|
+
SchemaValidator,
|
|
51
|
+
typeof PlanCadenceEnum,
|
|
52
|
+
typeof CurrencyEnum,
|
|
53
|
+
typeof BillingProviderEnum,
|
|
54
|
+
Entities,
|
|
55
|
+
Entities
|
|
56
|
+
>;
|
|
57
|
+
protected _mappers: InternalMapper<InstanceTypeRecord<typeof this.mappers>>;
|
|
58
|
+
|
|
59
|
+
constructor(
|
|
60
|
+
protected readonly stripeClient: Stripe,
|
|
61
|
+
protected readonly em: EntityManager,
|
|
62
|
+
protected readonly openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>,
|
|
63
|
+
protected readonly schemaValidator: SchemaValidator,
|
|
64
|
+
protected readonly mappers: {
|
|
65
|
+
PlanMapper: ResponseMapperConstructor<
|
|
66
|
+
SchemaValidator,
|
|
67
|
+
Dto['PlanMapper'],
|
|
68
|
+
Entities['PlanMapper']
|
|
69
|
+
>;
|
|
70
|
+
CreatePlanMapper: RequestMapperConstructor<
|
|
71
|
+
SchemaValidator,
|
|
72
|
+
Dto['CreatePlanMapper'],
|
|
73
|
+
Entities['CreatePlanMapper'],
|
|
74
|
+
(
|
|
75
|
+
dto: Dto['CreatePlanMapper'],
|
|
76
|
+
em: EntityManager,
|
|
77
|
+
plan: Stripe.Plan
|
|
78
|
+
) => Promise<Entities['CreatePlanMapper']>
|
|
79
|
+
>;
|
|
80
|
+
UpdatePlanMapper: RequestMapperConstructor<
|
|
81
|
+
SchemaValidator,
|
|
82
|
+
Dto['UpdatePlanMapper'],
|
|
83
|
+
Entities['UpdatePlanMapper'],
|
|
84
|
+
(
|
|
85
|
+
dto: Dto['UpdatePlanMapper'],
|
|
86
|
+
em: EntityManager,
|
|
87
|
+
plan: Stripe.Plan
|
|
88
|
+
) => Promise<Entities['UpdatePlanMapper']>
|
|
89
|
+
>;
|
|
90
|
+
},
|
|
91
|
+
readonly options?: {
|
|
92
|
+
telemetry?: TelemetryOptions;
|
|
93
|
+
databaseTableName?: string;
|
|
94
|
+
}
|
|
95
|
+
) {
|
|
96
|
+
this._mappers = transformIntoInternalMapper(mappers, schemaValidator);
|
|
97
|
+
this.basePlanService = new BasePlanService(
|
|
98
|
+
em,
|
|
99
|
+
openTelemetryCollector,
|
|
100
|
+
schemaValidator,
|
|
101
|
+
{
|
|
102
|
+
PlanMapper: IdentityResponseMapper<Entities['PlanMapper']>,
|
|
103
|
+
CreatePlanMapper: IdentityRequestMapper<Entities['CreatePlanMapper']>,
|
|
104
|
+
UpdatePlanMapper: IdentityRequestMapper<Entities['UpdatePlanMapper']>
|
|
105
|
+
},
|
|
106
|
+
options
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async createPlan(
|
|
111
|
+
planDto: Dto['CreatePlanMapper'],
|
|
112
|
+
em?: EntityManager
|
|
113
|
+
): Promise<Dto['PlanMapper']> {
|
|
114
|
+
const plan = await this.stripeClient.plans.create({
|
|
115
|
+
...planDto.stripeFields,
|
|
116
|
+
interval: planDto.cadence,
|
|
117
|
+
product: planDto.name,
|
|
118
|
+
currency: planDto.currency as string
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
const planEntity = await this.basePlanService.createPlan(
|
|
122
|
+
await this._mappers.CreatePlanMapper.deserializeDtoToEntity(
|
|
123
|
+
{
|
|
124
|
+
...planDto,
|
|
125
|
+
externalId: plan.id,
|
|
126
|
+
billingProvider: 'stripe'
|
|
127
|
+
},
|
|
128
|
+
em ?? this.em,
|
|
129
|
+
plan
|
|
130
|
+
),
|
|
131
|
+
em
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
return this._mappers.PlanMapper.serializeEntityToDto(planEntity);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async getPlan(idDto: IdDto, em?: EntityManager): Promise<Dto['PlanMapper']> {
|
|
138
|
+
const plan = await this.stripeClient.plans.retrieve(idDto.id);
|
|
139
|
+
const id = (
|
|
140
|
+
await em?.findOne<{ id: string; externalId: string }>(
|
|
141
|
+
this.options?.databaseTableName ?? 'plan',
|
|
142
|
+
{ externalId: idDto.id }
|
|
143
|
+
)
|
|
144
|
+
)?.id;
|
|
145
|
+
if (!id) {
|
|
146
|
+
throw new Error('Plan not found');
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
...(await this._mappers.PlanMapper.serializeEntityToDto(
|
|
150
|
+
await this.basePlanService.getPlan({ id }, em)
|
|
151
|
+
)),
|
|
152
|
+
stripeFields: plan
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async updatePlan(
|
|
157
|
+
planDto: Dto['UpdatePlanMapper'],
|
|
158
|
+
em?: EntityManager
|
|
159
|
+
): Promise<Dto['PlanMapper']> {
|
|
160
|
+
const existingPlan = await this.stripeClient.plans.retrieve(planDto.id);
|
|
161
|
+
const plan = await this.stripeClient.plans.del(planDto.id).then(() =>
|
|
162
|
+
this.stripeClient.plans.create({
|
|
163
|
+
...planDto.stripeFields,
|
|
164
|
+
interval: planDto.cadence ?? existingPlan.interval,
|
|
165
|
+
product: planDto.name,
|
|
166
|
+
currency: planDto.currency ?? existingPlan.currency
|
|
167
|
+
})
|
|
168
|
+
);
|
|
169
|
+
|
|
170
|
+
const planEntity = await this.basePlanService.updatePlan(
|
|
171
|
+
await this._mappers.UpdatePlanMapper.deserializeDtoToEntity(
|
|
172
|
+
{
|
|
173
|
+
...planDto,
|
|
174
|
+
externalId: plan.id,
|
|
175
|
+
billingProvider: 'stripe'
|
|
176
|
+
},
|
|
177
|
+
em ?? this.em,
|
|
178
|
+
plan
|
|
179
|
+
),
|
|
180
|
+
em
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
return this._mappers.PlanMapper.serializeEntityToDto(planEntity);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
async deletePlan(idDto: { id: string }, em?: EntityManager): Promise<void> {
|
|
187
|
+
await this.stripeClient.plans.del(idDto.id);
|
|
188
|
+
await this.basePlanService.deletePlan(idDto, em);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
async listPlans(
|
|
192
|
+
idsDto?: IdsDto,
|
|
193
|
+
em?: EntityManager
|
|
194
|
+
): Promise<Dto['PlanMapper'][]> {
|
|
195
|
+
const plans = await this.stripeClient.plans.list({
|
|
196
|
+
active: true
|
|
197
|
+
});
|
|
198
|
+
const ids = (
|
|
199
|
+
await em?.findAll<{ id: string; externalId: string }>(
|
|
200
|
+
this.options?.databaseTableName ?? 'plan',
|
|
201
|
+
{ where: { externalId: { $in: plans.data.map((plan) => plan.id) } } }
|
|
202
|
+
)
|
|
203
|
+
)
|
|
204
|
+
?.filter((s) => idsDto?.ids?.includes(s.id))
|
|
205
|
+
?.map((s) => s.id);
|
|
206
|
+
|
|
207
|
+
if (!ids) {
|
|
208
|
+
throw new Error('Plans not found');
|
|
209
|
+
}
|
|
210
|
+
return await Promise.all(
|
|
211
|
+
(await this.basePlanService.listPlans({ ids }, em)).map(async (plan) => ({
|
|
212
|
+
...(await this._mappers.PlanMapper.serializeEntityToDto(plan)),
|
|
213
|
+
stripeFields: plans.data.find(
|
|
214
|
+
(stripePlan) => stripePlan.id === plan.externalId
|
|
215
|
+
)
|
|
216
|
+
}))
|
|
217
|
+
);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
import { IdDto, IdsDto, InstanceTypeRecord } from '@forklaunch/common';
|
|
2
|
+
import {
|
|
3
|
+
MetricsDefinition,
|
|
4
|
+
OpenTelemetryCollector,
|
|
5
|
+
TelemetryOptions
|
|
6
|
+
} from '@forklaunch/core/http';
|
|
7
|
+
import { BaseSubscriptionService } from '@forklaunch/implementation-billing-base/services';
|
|
8
|
+
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
|
+
import { AnySchemaValidator } from '@forklaunch/validator';
|
|
18
|
+
import { EntityManager } from '@mikro-orm/core';
|
|
19
|
+
import Stripe from 'stripe';
|
|
20
|
+
import { BillingProviderEnum } from '../domain/enums/billingProvider.enum';
|
|
21
|
+
import {
|
|
22
|
+
StripeCreateSubscriptionDto,
|
|
23
|
+
StripeSubscriptionDto,
|
|
24
|
+
StripeSubscriptionDtos,
|
|
25
|
+
StripeUpdateSubscriptionDto
|
|
26
|
+
} from '../types/stripe.dto.types';
|
|
27
|
+
import { StripeSubscriptionEntities } from '../types/stripe.entity.types';
|
|
28
|
+
|
|
29
|
+
export class StripeSubscriptionService<
|
|
30
|
+
SchemaValidator extends AnySchemaValidator,
|
|
31
|
+
PartyType,
|
|
32
|
+
Entities extends StripeSubscriptionEntities<PartyType>,
|
|
33
|
+
Dto extends
|
|
34
|
+
StripeSubscriptionDtos<PartyType> = StripeSubscriptionDtos<PartyType>
|
|
35
|
+
> implements
|
|
36
|
+
SubscriptionService<
|
|
37
|
+
PartyType,
|
|
38
|
+
typeof BillingProviderEnum,
|
|
39
|
+
{
|
|
40
|
+
CreateSubscriptionDto: StripeCreateSubscriptionDto<PartyType>;
|
|
41
|
+
UpdateSubscriptionDto: StripeUpdateSubscriptionDto<PartyType>;
|
|
42
|
+
SubscriptionDto: StripeSubscriptionDto<PartyType>;
|
|
43
|
+
IdDto: IdDto;
|
|
44
|
+
IdsDto: IdsDto;
|
|
45
|
+
}
|
|
46
|
+
>
|
|
47
|
+
{
|
|
48
|
+
baseSubscriptionService: BaseSubscriptionService<
|
|
49
|
+
SchemaValidator,
|
|
50
|
+
PartyType,
|
|
51
|
+
typeof BillingProviderEnum,
|
|
52
|
+
Entities,
|
|
53
|
+
Entities
|
|
54
|
+
>;
|
|
55
|
+
protected _mappers: InternalMapper<InstanceTypeRecord<typeof this.mappers>>;
|
|
56
|
+
|
|
57
|
+
constructor(
|
|
58
|
+
protected readonly stripe: Stripe,
|
|
59
|
+
protected readonly em: EntityManager,
|
|
60
|
+
protected readonly openTelemetryCollector: OpenTelemetryCollector<MetricsDefinition>,
|
|
61
|
+
protected readonly schemaValidator: SchemaValidator,
|
|
62
|
+
protected readonly mappers: {
|
|
63
|
+
SubscriptionMapper: ResponseMapperConstructor<
|
|
64
|
+
SchemaValidator,
|
|
65
|
+
Dto['SubscriptionMapper'],
|
|
66
|
+
Entities['SubscriptionMapper']
|
|
67
|
+
>;
|
|
68
|
+
CreateSubscriptionMapper: RequestMapperConstructor<
|
|
69
|
+
SchemaValidator,
|
|
70
|
+
Dto['CreateSubscriptionMapper'],
|
|
71
|
+
Entities['CreateSubscriptionMapper'],
|
|
72
|
+
(
|
|
73
|
+
dto: Dto['CreateSubscriptionMapper'],
|
|
74
|
+
em: EntityManager,
|
|
75
|
+
subscription: Stripe.Subscription
|
|
76
|
+
) => Promise<Entities['CreateSubscriptionMapper']>
|
|
77
|
+
>;
|
|
78
|
+
UpdateSubscriptionMapper: RequestMapperConstructor<
|
|
79
|
+
SchemaValidator,
|
|
80
|
+
Dto['UpdateSubscriptionMapper'],
|
|
81
|
+
Entities['UpdateSubscriptionMapper'],
|
|
82
|
+
(
|
|
83
|
+
dto: Dto['UpdateSubscriptionMapper'],
|
|
84
|
+
em: EntityManager,
|
|
85
|
+
subscription: Stripe.Subscription
|
|
86
|
+
) => Promise<Entities['UpdateSubscriptionMapper']>
|
|
87
|
+
>;
|
|
88
|
+
},
|
|
89
|
+
readonly options?: {
|
|
90
|
+
telemetry?: TelemetryOptions;
|
|
91
|
+
databaseTableName?: string;
|
|
92
|
+
}
|
|
93
|
+
) {
|
|
94
|
+
this._mappers = transformIntoInternalMapper(mappers, schemaValidator);
|
|
95
|
+
this.baseSubscriptionService = new BaseSubscriptionService(
|
|
96
|
+
em,
|
|
97
|
+
openTelemetryCollector,
|
|
98
|
+
schemaValidator,
|
|
99
|
+
{
|
|
100
|
+
SubscriptionMapper: IdentityResponseMapper<
|
|
101
|
+
Entities['SubscriptionMapper']
|
|
102
|
+
>,
|
|
103
|
+
CreateSubscriptionMapper: IdentityRequestMapper<
|
|
104
|
+
Entities['CreateSubscriptionMapper']
|
|
105
|
+
>,
|
|
106
|
+
UpdateSubscriptionMapper: IdentityRequestMapper<
|
|
107
|
+
Entities['UpdateSubscriptionMapper']
|
|
108
|
+
>
|
|
109
|
+
},
|
|
110
|
+
options
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async createSubscription(
|
|
115
|
+
subscriptionDto: Dto['CreateSubscriptionMapper'],
|
|
116
|
+
em?: EntityManager
|
|
117
|
+
): Promise<Dto['SubscriptionMapper']> {
|
|
118
|
+
const subscription = await this.stripe.subscriptions.create({
|
|
119
|
+
...subscriptionDto.stripeFields,
|
|
120
|
+
customer: subscriptionDto.partyId,
|
|
121
|
+
items: [
|
|
122
|
+
{
|
|
123
|
+
plan: subscriptionDto.productId
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
const subscriptionEntity =
|
|
129
|
+
await this.baseSubscriptionService.createSubscription(
|
|
130
|
+
await this._mappers.CreateSubscriptionMapper.deserializeDtoToEntity(
|
|
131
|
+
{
|
|
132
|
+
...subscriptionDto,
|
|
133
|
+
externalId: subscription.id,
|
|
134
|
+
billingProvider: 'stripe'
|
|
135
|
+
},
|
|
136
|
+
em ?? this.em,
|
|
137
|
+
subscription
|
|
138
|
+
),
|
|
139
|
+
em
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
return this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
143
|
+
subscriptionEntity
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async getSubscription(
|
|
148
|
+
idDto: IdDto,
|
|
149
|
+
em?: EntityManager
|
|
150
|
+
): Promise<Dto['SubscriptionMapper']> {
|
|
151
|
+
return {
|
|
152
|
+
...(await this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
153
|
+
await this.baseSubscriptionService.getSubscription(idDto, em)
|
|
154
|
+
)),
|
|
155
|
+
stripeFields: await this.stripe.subscriptions.retrieve(idDto.id)
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
async getUserSubscription(
|
|
160
|
+
idDto: IdDto,
|
|
161
|
+
em?: EntityManager
|
|
162
|
+
): Promise<Dto['SubscriptionMapper']> {
|
|
163
|
+
return {
|
|
164
|
+
...(await this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
165
|
+
await this.baseSubscriptionService.getUserSubscription(idDto, em)
|
|
166
|
+
)),
|
|
167
|
+
stripeFields: await this.stripe.subscriptions.retrieve(idDto.id)
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async getOrganizationSubscription(
|
|
172
|
+
idDto: IdDto,
|
|
173
|
+
em?: EntityManager
|
|
174
|
+
): Promise<Dto['SubscriptionMapper']> {
|
|
175
|
+
const id = (
|
|
176
|
+
await em?.findOne<{ id: string; externalId: string }>(
|
|
177
|
+
this.options?.databaseTableName ?? 'subscription',
|
|
178
|
+
{ externalId: idDto.id }
|
|
179
|
+
)
|
|
180
|
+
)?.id;
|
|
181
|
+
if (!id) {
|
|
182
|
+
throw new Error('Subscription not found');
|
|
183
|
+
}
|
|
184
|
+
return {
|
|
185
|
+
...(await this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
186
|
+
await this.baseSubscriptionService.getOrganizationSubscription(
|
|
187
|
+
{ id },
|
|
188
|
+
em
|
|
189
|
+
)
|
|
190
|
+
)),
|
|
191
|
+
stripeFields: await this.stripe.subscriptions.retrieve(idDto.id)
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async updateSubscription(
|
|
196
|
+
subscriptionDto: Dto['UpdateSubscriptionMapper'],
|
|
197
|
+
em?: EntityManager
|
|
198
|
+
): Promise<Dto['SubscriptionMapper']> {
|
|
199
|
+
const subscription = await this.stripe.subscriptions.update(
|
|
200
|
+
subscriptionDto.id,
|
|
201
|
+
{
|
|
202
|
+
...subscriptionDto.stripeFields,
|
|
203
|
+
items: [
|
|
204
|
+
{
|
|
205
|
+
plan: subscriptionDto.productId
|
|
206
|
+
}
|
|
207
|
+
]
|
|
208
|
+
}
|
|
209
|
+
);
|
|
210
|
+
|
|
211
|
+
const subscriptionEntity =
|
|
212
|
+
await this.baseSubscriptionService.updateSubscription(
|
|
213
|
+
await this._mappers.UpdateSubscriptionMapper.deserializeDtoToEntity(
|
|
214
|
+
{
|
|
215
|
+
...subscriptionDto,
|
|
216
|
+
externalId: subscription.id,
|
|
217
|
+
billingProvider: 'stripe',
|
|
218
|
+
providerFields: subscription
|
|
219
|
+
},
|
|
220
|
+
em ?? this.em,
|
|
221
|
+
subscription
|
|
222
|
+
),
|
|
223
|
+
em
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
return this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
227
|
+
subscriptionEntity
|
|
228
|
+
);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async deleteSubscription(
|
|
232
|
+
idDto: { id: string },
|
|
233
|
+
em?: EntityManager
|
|
234
|
+
): Promise<void> {
|
|
235
|
+
await this.stripe.subscriptions.cancel(idDto.id);
|
|
236
|
+
await this.baseSubscriptionService.deleteSubscription(idDto, em);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async listSubscriptions(
|
|
240
|
+
idsDto: IdsDto,
|
|
241
|
+
em?: EntityManager
|
|
242
|
+
): Promise<Dto['SubscriptionMapper'][]> {
|
|
243
|
+
const subscriptions = (
|
|
244
|
+
await this.stripe.subscriptions.list({
|
|
245
|
+
status: 'active'
|
|
246
|
+
})
|
|
247
|
+
).data.filter((s) => idsDto.ids?.includes(s.id));
|
|
248
|
+
|
|
249
|
+
const ids = (
|
|
250
|
+
await em?.findAll<{ id: string; externalId: string }>(
|
|
251
|
+
this.options?.databaseTableName ?? 'subscription',
|
|
252
|
+
{ where: { externalId: { $in: subscriptions.map((s) => s.id) } } }
|
|
253
|
+
)
|
|
254
|
+
)?.map((s) => s.id);
|
|
255
|
+
|
|
256
|
+
if (!ids) {
|
|
257
|
+
throw new Error('Subscriptions not found');
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return await Promise.all(
|
|
261
|
+
(await this.baseSubscriptionService.listSubscriptions({ ids }, em)).map(
|
|
262
|
+
async (subscription) => {
|
|
263
|
+
return {
|
|
264
|
+
...(await this._mappers.SubscriptionMapper.serializeEntityToDto(
|
|
265
|
+
subscription
|
|
266
|
+
)),
|
|
267
|
+
stripeFields: subscriptions.find(
|
|
268
|
+
(s) => s.id === subscription.externalId
|
|
269
|
+
)
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
)
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
async cancelSubscription(idDto: IdDto, em?: EntityManager): Promise<void> {
|
|
277
|
+
await this.stripe.subscriptions.cancel(idDto.id);
|
|
278
|
+
await this.baseSubscriptionService.cancelSubscription(idDto, em);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async resumeSubscription(idDto: IdDto, em?: EntityManager): Promise<void> {
|
|
282
|
+
await this.stripe.subscriptions.resume(idDto.id);
|
|
283
|
+
await this.baseSubscriptionService.resumeSubscription(idDto, em);
|
|
284
|
+
}
|
|
285
|
+
}
|