@misterhomer1992/miit-bot-payment 1.0.1 → 1.0.3
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/README.md +262 -146
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/modules/invoice/const.d.ts +4 -0
- package/dist/modules/invoice/const.d.ts.map +1 -0
- package/dist/modules/invoice/const.js +8 -0
- package/dist/modules/invoice/const.js.map +1 -0
- package/dist/modules/invoice/index.d.ts +5 -0
- package/dist/modules/invoice/index.d.ts.map +1 -0
- package/dist/modules/invoice/index.js +21 -0
- package/dist/modules/invoice/index.js.map +1 -0
- package/dist/modules/invoice/repository.d.ts +34 -0
- package/dist/modules/invoice/repository.d.ts.map +1 -0
- package/dist/modules/invoice/repository.js +68 -0
- package/dist/modules/invoice/repository.js.map +1 -0
- package/dist/modules/invoice/service.d.ts +29 -0
- package/dist/modules/invoice/service.d.ts.map +1 -0
- package/dist/modules/invoice/service.js +61 -0
- package/dist/modules/invoice/service.js.map +1 -0
- package/dist/modules/invoice/types.d.ts +14 -0
- package/dist/modules/invoice/types.d.ts.map +1 -0
- package/dist/modules/invoice/types.js +3 -0
- package/dist/modules/invoice/types.js.map +1 -0
- package/dist/modules/logger/types.d.ts +4 -4
- package/dist/modules/logger/types.d.ts.map +1 -1
- package/dist/modules/payments/api.d.ts +34 -0
- package/dist/modules/payments/api.d.ts.map +1 -0
- package/dist/modules/payments/api.js +63 -0
- package/dist/modules/payments/api.js.map +1 -0
- package/dist/modules/payments/index.d.ts +6 -0
- package/dist/modules/payments/index.d.ts.map +1 -0
- package/dist/modules/payments/index.js +22 -0
- package/dist/modules/payments/index.js.map +1 -0
- package/dist/modules/payments/repository.d.ts +1 -4
- package/dist/modules/payments/repository.d.ts.map +1 -1
- package/dist/modules/payments/repository.js +46 -84
- package/dist/modules/payments/repository.js.map +1 -1
- package/dist/modules/payments/service.d.ts +96 -0
- package/dist/modules/payments/service.d.ts.map +1 -0
- package/dist/modules/payments/service.js +207 -0
- package/dist/modules/payments/service.js.map +1 -0
- package/dist/modules/payments/utils.d.ts +9 -0
- package/dist/modules/payments/utils.d.ts.map +1 -0
- package/dist/modules/payments/utils.js +7 -0
- package/dist/modules/payments/utils.js.map +1 -0
- package/dist/modules/subscription/const.d.ts +4 -0
- package/dist/modules/subscription/const.d.ts.map +1 -0
- package/dist/modules/subscription/const.js +10 -0
- package/dist/modules/subscription/const.js.map +1 -0
- package/dist/modules/subscription/index.d.ts +5 -0
- package/dist/modules/subscription/index.d.ts.map +1 -0
- package/dist/modules/subscription/index.js +23 -0
- package/dist/modules/subscription/index.js.map +1 -0
- package/dist/modules/subscription/repository.d.ts +91 -0
- package/dist/modules/subscription/repository.d.ts.map +1 -0
- package/dist/modules/subscription/repository.js +146 -0
- package/dist/modules/subscription/repository.js.map +1 -0
- package/dist/modules/subscription/service.d.ts +101 -0
- package/dist/modules/subscription/service.d.ts.map +1 -0
- package/dist/modules/subscription/service.js +205 -0
- package/dist/modules/subscription/service.js.map +1 -0
- package/dist/modules/subscription/subscriptionPlan.d.ts +4 -0
- package/dist/modules/subscription/subscriptionPlan.d.ts.map +1 -0
- package/dist/modules/subscription/subscriptionPlan.js +63 -0
- package/dist/modules/subscription/subscriptionPlan.js.map +1 -0
- package/dist/modules/subscription/types.d.ts +37 -0
- package/dist/modules/subscription/types.d.ts.map +1 -0
- package/dist/modules/subscription/types.js +3 -0
- package/dist/modules/subscription/types.js.map +1 -0
- package/dist/modules/subscription/utils.d.ts +5 -0
- package/dist/modules/subscription/utils.d.ts.map +1 -0
- package/dist/modules/subscription/utils.js +16 -0
- package/dist/modules/subscription/utils.js.map +1 -0
- package/package.json +3 -2
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Logger } from '../logger/types';
|
|
2
|
+
import { UpdateDBPaymentFields } from './repository';
|
|
3
|
+
import { PaymentEntity } from './types';
|
|
4
|
+
import { AppNamespace } from '../app/types';
|
|
5
|
+
/**
|
|
6
|
+
* PaymentService class handles business logic related to payments.
|
|
7
|
+
* Acts as an intermediary between controllers/handlers and the repository layer.
|
|
8
|
+
*/
|
|
9
|
+
export declare class PaymentService {
|
|
10
|
+
private readonly logger;
|
|
11
|
+
private readonly repository;
|
|
12
|
+
/**
|
|
13
|
+
* Creates an instance of PaymentService.
|
|
14
|
+
* @param logger - Application logger instance for logging operations
|
|
15
|
+
*/
|
|
16
|
+
constructor(logger: Logger);
|
|
17
|
+
/**
|
|
18
|
+
* Retrieves a payment by its order reference.
|
|
19
|
+
* @param orderReference - The unique order reference identifier
|
|
20
|
+
* @returns Promise resolving to PaymentEntity or null if not found
|
|
21
|
+
*/
|
|
22
|
+
getByOrderReference(orderReference: string): Promise<PaymentEntity | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Retrieves all payments for a specific user.
|
|
25
|
+
* @param params - Query parameters
|
|
26
|
+
* @param params.userId - The user's unique identifier
|
|
27
|
+
* @param params.appNamespace - The application namespace/platform
|
|
28
|
+
* @param params.status - Optional payment status filter
|
|
29
|
+
* @returns Promise resolving to array of PaymentEntity
|
|
30
|
+
*/
|
|
31
|
+
getByUserId(params: {
|
|
32
|
+
userId: string;
|
|
33
|
+
appNamespace: AppNamespace;
|
|
34
|
+
status?: PaymentEntity['status'];
|
|
35
|
+
}): Promise<PaymentEntity[]>;
|
|
36
|
+
/**
|
|
37
|
+
* Creates a new payment record in the database.
|
|
38
|
+
* @param paymentData - Payment data without ID (ID will be auto-generated)
|
|
39
|
+
* @returns Promise resolving to created PaymentEntity with ID
|
|
40
|
+
* @throws Error if payment creation fails
|
|
41
|
+
*/
|
|
42
|
+
create(paymentData: Omit<PaymentEntity, 'id'>): Promise<PaymentEntity>;
|
|
43
|
+
/**
|
|
44
|
+
* Updates specific fields of a payment identified by order reference.
|
|
45
|
+
* @param params - Update parameters
|
|
46
|
+
* @param params.orderReference - The order reference to identify the payment
|
|
47
|
+
* @param params.fields - Array of field paths and values to update
|
|
48
|
+
* @throws Error if payment not found or update fails
|
|
49
|
+
*/
|
|
50
|
+
updateFields(params: {
|
|
51
|
+
orderReference: string;
|
|
52
|
+
fields: UpdateDBPaymentFields;
|
|
53
|
+
}): Promise<void>;
|
|
54
|
+
/**
|
|
55
|
+
* Retrieves all pending payments that are older than specified hours.
|
|
56
|
+
* Used for cleaning up expired payment attempts.
|
|
57
|
+
* @param params - Query parameters
|
|
58
|
+
* @param params.hoursOld - Number of hours after which a pending payment is considered expired (default: 24)
|
|
59
|
+
* @returns Promise resolving to array of expired PaymentEntity
|
|
60
|
+
*/
|
|
61
|
+
getExpiredPendingPayments(params?: {
|
|
62
|
+
hoursOld?: number;
|
|
63
|
+
}): Promise<PaymentEntity[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Creates a payment intent for a user subscription.
|
|
66
|
+
* This method orchestrates the payment creation process by:
|
|
67
|
+
* 1. Creating a payment URL via Wayforpay API
|
|
68
|
+
* 2. Storing the payment record in the database
|
|
69
|
+
* 3. Returning the complete payment entity with the payment link
|
|
70
|
+
*
|
|
71
|
+
* @param params - Payment intent parameters
|
|
72
|
+
* @param params.userId - The unique identifier of the user
|
|
73
|
+
* @param params.appNamespace - The application namespace/platform
|
|
74
|
+
* @param params.planId - The subscription plan identifier
|
|
75
|
+
* @param params.productName - The name of the product/plan being purchased
|
|
76
|
+
* @param params.productPrice - The price of the product
|
|
77
|
+
* @param params.currency - The currency code ('UAH' or 'USD')
|
|
78
|
+
* @param params.regularCount - Optional number of regular payments (defaults to 3)
|
|
79
|
+
* @param params.regularMode - Optional payment frequency ('daily', 'weekly', 'monthly', 'yearly')
|
|
80
|
+
* @param params.language - Optional language code for the payment page (defaults to 'UA')
|
|
81
|
+
* @returns Promise resolving to the created PaymentEntity with payment link
|
|
82
|
+
* @throws Error if payment URL generation or database creation fails
|
|
83
|
+
*/
|
|
84
|
+
createPaymentIntent(params: {
|
|
85
|
+
userId: string;
|
|
86
|
+
appNamespace: AppNamespace;
|
|
87
|
+
planId: string;
|
|
88
|
+
productName: string;
|
|
89
|
+
productPrice: number;
|
|
90
|
+
currency: 'UAH' | 'USD';
|
|
91
|
+
regularCount?: number;
|
|
92
|
+
regularMode?: 'daily' | 'weekly' | 'monthly' | 'yearly';
|
|
93
|
+
language?: string;
|
|
94
|
+
}): Promise<PaymentEntity>;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../../src/modules/payments/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAC;AACzC,OAAO,EAAqB,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C;;;GAGG;AACH,qBAAa,cAAc;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAoB;IAE/C;;;OAGG;gBACS,MAAM,EAAE,MAAM;IAK1B;;;;OAIG;IACU,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IAevF;;;;;;;OAOG;IACU,WAAW,CAAC,MAAM,EAAE;QAC7B,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,YAAY,CAAC;QAC3B,MAAM,CAAC,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC;KACpC,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAiB5B;;;;;OAKG;IACU,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC;IAiBnF;;;;;;OAMG;IACU,YAAY,CAAC,MAAM,EAAE;QAAE,cAAc,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,qBAAqB,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB3G;;;;;;OAMG;IACU,yBAAyB,CAClC,MAAM,GAAE;QACJ,QAAQ,CAAC,EAAE,MAAM,CAAC;KAChB,GACP,OAAO,CAAC,aAAa,EAAE,CAAC;IAe3B;;;;;;;;;;;;;;;;;;;OAmBG;IACU,mBAAmB,CAAC,MAAM,EAAE;QACrC,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,YAAY,CAAC;QAC3B,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,QAAQ,EAAE,KAAK,GAAG,KAAK,CAAC;QACxB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;QACxD,QAAQ,CAAC,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,aAAa,CAAC;CAgE7B"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.PaymentService = void 0;
|
|
7
|
+
const moment_1 = __importDefault(require("moment"));
|
|
8
|
+
const repository_1 = require("./repository");
|
|
9
|
+
const api_1 = require("./api");
|
|
10
|
+
/**
|
|
11
|
+
* PaymentService class handles business logic related to payments.
|
|
12
|
+
* Acts as an intermediary between controllers/handlers and the repository layer.
|
|
13
|
+
*/
|
|
14
|
+
class PaymentService {
|
|
15
|
+
/**
|
|
16
|
+
* Creates an instance of PaymentService.
|
|
17
|
+
* @param logger - Application logger instance for logging operations
|
|
18
|
+
*/
|
|
19
|
+
constructor(logger) {
|
|
20
|
+
this.logger = logger;
|
|
21
|
+
this.repository = new repository_1.PaymentRepository();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Retrieves a payment by its order reference.
|
|
25
|
+
* @param orderReference - The unique order reference identifier
|
|
26
|
+
* @returns Promise resolving to PaymentEntity or null if not found
|
|
27
|
+
*/
|
|
28
|
+
async getByOrderReference(orderReference) {
|
|
29
|
+
try {
|
|
30
|
+
return await this.repository.getByOrderReference(orderReference);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
this.logger.error({
|
|
34
|
+
message: 'Error in payment service getByOrderReference',
|
|
35
|
+
payload: {
|
|
36
|
+
orderReference,
|
|
37
|
+
error: JSON.stringify(error),
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Retrieves all payments for a specific user.
|
|
45
|
+
* @param params - Query parameters
|
|
46
|
+
* @param params.userId - The user's unique identifier
|
|
47
|
+
* @param params.appNamespace - The application namespace/platform
|
|
48
|
+
* @param params.status - Optional payment status filter
|
|
49
|
+
* @returns Promise resolving to array of PaymentEntity
|
|
50
|
+
*/
|
|
51
|
+
async getByUserId(params) {
|
|
52
|
+
try {
|
|
53
|
+
return await this.repository.getByUserId(params);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
this.logger.error({
|
|
57
|
+
message: 'Error in payment service getByUserId',
|
|
58
|
+
payload: {
|
|
59
|
+
userId: params.userId,
|
|
60
|
+
appNamespace: params.appNamespace,
|
|
61
|
+
status: params.status,
|
|
62
|
+
error: JSON.stringify(error),
|
|
63
|
+
},
|
|
64
|
+
});
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Creates a new payment record in the database.
|
|
70
|
+
* @param paymentData - Payment data without ID (ID will be auto-generated)
|
|
71
|
+
* @returns Promise resolving to created PaymentEntity with ID
|
|
72
|
+
* @throws Error if payment creation fails
|
|
73
|
+
*/
|
|
74
|
+
async create(paymentData) {
|
|
75
|
+
try {
|
|
76
|
+
return await this.repository.create(paymentData);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
this.logger.error({
|
|
80
|
+
message: 'Error in payment service create',
|
|
81
|
+
payload: {
|
|
82
|
+
orderReference: paymentData.orderReference,
|
|
83
|
+
userId: paymentData.userId,
|
|
84
|
+
error: JSON.stringify(error),
|
|
85
|
+
},
|
|
86
|
+
});
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Updates specific fields of a payment identified by order reference.
|
|
92
|
+
* @param params - Update parameters
|
|
93
|
+
* @param params.orderReference - The order reference to identify the payment
|
|
94
|
+
* @param params.fields - Array of field paths and values to update
|
|
95
|
+
* @throws Error if payment not found or update fails
|
|
96
|
+
*/
|
|
97
|
+
async updateFields(params) {
|
|
98
|
+
try {
|
|
99
|
+
await this.repository.updateFields(params);
|
|
100
|
+
}
|
|
101
|
+
catch (error) {
|
|
102
|
+
this.logger.error({
|
|
103
|
+
message: 'Error in payment service updateFields',
|
|
104
|
+
payload: {
|
|
105
|
+
orderReference: params.orderReference,
|
|
106
|
+
fields: JSON.stringify(params.fields),
|
|
107
|
+
error: JSON.stringify(error),
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Retrieves all pending payments that are older than specified hours.
|
|
115
|
+
* Used for cleaning up expired payment attempts.
|
|
116
|
+
* @param params - Query parameters
|
|
117
|
+
* @param params.hoursOld - Number of hours after which a pending payment is considered expired (default: 24)
|
|
118
|
+
* @returns Promise resolving to array of expired PaymentEntity
|
|
119
|
+
*/
|
|
120
|
+
async getExpiredPendingPayments(params = {}) {
|
|
121
|
+
try {
|
|
122
|
+
return await this.repository.getExpiredPendingPayments(params);
|
|
123
|
+
}
|
|
124
|
+
catch (error) {
|
|
125
|
+
this.logger.error({
|
|
126
|
+
message: 'Error in payment service getExpiredPendingPayments',
|
|
127
|
+
payload: {
|
|
128
|
+
hoursOld: params.hoursOld,
|
|
129
|
+
error: JSON.stringify(error),
|
|
130
|
+
},
|
|
131
|
+
});
|
|
132
|
+
return [];
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Creates a payment intent for a user subscription.
|
|
137
|
+
* This method orchestrates the payment creation process by:
|
|
138
|
+
* 1. Creating a payment URL via Wayforpay API
|
|
139
|
+
* 2. Storing the payment record in the database
|
|
140
|
+
* 3. Returning the complete payment entity with the payment link
|
|
141
|
+
*
|
|
142
|
+
* @param params - Payment intent parameters
|
|
143
|
+
* @param params.userId - The unique identifier of the user
|
|
144
|
+
* @param params.appNamespace - The application namespace/platform
|
|
145
|
+
* @param params.planId - The subscription plan identifier
|
|
146
|
+
* @param params.productName - The name of the product/plan being purchased
|
|
147
|
+
* @param params.productPrice - The price of the product
|
|
148
|
+
* @param params.currency - The currency code ('UAH' or 'USD')
|
|
149
|
+
* @param params.regularCount - Optional number of regular payments (defaults to 3)
|
|
150
|
+
* @param params.regularMode - Optional payment frequency ('daily', 'weekly', 'monthly', 'yearly')
|
|
151
|
+
* @param params.language - Optional language code for the payment page (defaults to 'UA')
|
|
152
|
+
* @returns Promise resolving to the created PaymentEntity with payment link
|
|
153
|
+
* @throws Error if payment URL generation or database creation fails
|
|
154
|
+
*/
|
|
155
|
+
async createPaymentIntent(params) {
|
|
156
|
+
const { userId, appNamespace, planId, productName, productPrice, currency, regularCount, regularMode, language, } = params;
|
|
157
|
+
try {
|
|
158
|
+
// Step 1: Create payment URL from Wayforpay API
|
|
159
|
+
// This also generates a unique order reference
|
|
160
|
+
const paymentResponse = await (0, api_1.createPaymentAPI)({
|
|
161
|
+
userId,
|
|
162
|
+
appNamespace,
|
|
163
|
+
productName,
|
|
164
|
+
productPrice,
|
|
165
|
+
planId,
|
|
166
|
+
currency,
|
|
167
|
+
regularCount,
|
|
168
|
+
regularMode,
|
|
169
|
+
language,
|
|
170
|
+
});
|
|
171
|
+
if (!paymentResponse?.url || !paymentResponse?.orderReference) {
|
|
172
|
+
throw new Error('Failed to get payment URL or order reference from Wayforpay');
|
|
173
|
+
}
|
|
174
|
+
// Step 2: Create payment record in database
|
|
175
|
+
const paymentEntity = await this.repository.create({
|
|
176
|
+
orderReference: paymentResponse.orderReference,
|
|
177
|
+
userId,
|
|
178
|
+
status: 'pending',
|
|
179
|
+
paymentLink: paymentResponse.url,
|
|
180
|
+
planId,
|
|
181
|
+
amount: productPrice,
|
|
182
|
+
currency,
|
|
183
|
+
createdAt: moment_1.default.utc().toISOString(),
|
|
184
|
+
platform: appNamespace,
|
|
185
|
+
provider: 'wayforpay',
|
|
186
|
+
});
|
|
187
|
+
return paymentEntity;
|
|
188
|
+
}
|
|
189
|
+
catch (error) {
|
|
190
|
+
this.logger.error({
|
|
191
|
+
message: 'Error in payment service createPaymentIntent',
|
|
192
|
+
payload: {
|
|
193
|
+
userId,
|
|
194
|
+
appNamespace,
|
|
195
|
+
planId,
|
|
196
|
+
productName,
|
|
197
|
+
productPrice,
|
|
198
|
+
currency,
|
|
199
|
+
error: JSON.stringify(error),
|
|
200
|
+
},
|
|
201
|
+
});
|
|
202
|
+
throw error;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
exports.PaymentService = PaymentService;
|
|
207
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/modules/payments/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AppNamespace } from '../app/types';
|
|
2
|
+
declare function createOrderReference({ userId, appNamespace, planId, utcDate, }: {
|
|
3
|
+
userId: string;
|
|
4
|
+
appNamespace: AppNamespace;
|
|
5
|
+
planId: string;
|
|
6
|
+
utcDate: string;
|
|
7
|
+
}): string;
|
|
8
|
+
export { createOrderReference };
|
|
9
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/modules/payments/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,iBAAS,oBAAoB,CAAC,EAC1B,MAAM,EACN,YAAY,EACZ,MAAM,EACN,OAAO,GACV,EAAE;IACC,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,YAAY,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACnB,GAAG,MAAM,CAET;AAED,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createOrderReference = createOrderReference;
|
|
4
|
+
function createOrderReference({ userId, appNamespace, planId, utcDate, }) {
|
|
5
|
+
return `miia_${appNamespace}_bot_${userId}_${planId}_v1_${utcDate}`;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/modules/payments/utils.ts"],"names":[],"mappings":";;AAgBS,oDAAoB;AAd7B,SAAS,oBAAoB,CAAC,EAC1B,MAAM,EACN,YAAY,EACZ,MAAM,EACN,OAAO,GAMV;IACG,OAAO,QAAQ,YAAY,QAAQ,MAAM,IAAI,MAAM,OAAO,OAAO,EAAE,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"const.d.ts","sourceRoot":"","sources":["../../../src/modules/subscription/const.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE7C,QAAA,MAAM,2BAA2B,EAAE,OAAO,CAAC,kBAAkB,CAI5D,CAAC;AAEF,OAAO,EAAE,2BAA2B,EAAE,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_SUBSCRIPTION_ENTITY = void 0;
|
|
4
|
+
const DEFAULT_SUBSCRIPTION_ENTITY = {
|
|
5
|
+
status: 'active',
|
|
6
|
+
platform: 'telegram',
|
|
7
|
+
provider: 'wayforpay',
|
|
8
|
+
};
|
|
9
|
+
exports.DEFAULT_SUBSCRIPTION_ENTITY = DEFAULT_SUBSCRIPTION_ENTITY;
|
|
10
|
+
//# sourceMappingURL=const.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"const.js","sourceRoot":"","sources":["../../../src/modules/subscription/const.ts"],"names":[],"mappings":";;;AAEA,MAAM,2BAA2B,GAAgC;IAC7D,MAAM,EAAE,QAAQ;IAChB,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,WAAW;CACxB,CAAC;AAEO,kEAA2B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/subscription/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.SUBSCRIPTION_PLAN = void 0;
|
|
18
|
+
__exportStar(require("./utils"), exports);
|
|
19
|
+
__exportStar(require("./types"), exports);
|
|
20
|
+
__exportStar(require("./service"), exports);
|
|
21
|
+
var subscriptionPlan_1 = require("./subscriptionPlan");
|
|
22
|
+
Object.defineProperty(exports, "SUBSCRIPTION_PLAN", { enumerable: true, get: function () { return subscriptionPlan_1.SUBSCRIPTION_PLAN; } });
|
|
23
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/subscription/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,0CAAwB;AACxB,4CAA0B;AAC1B,uDAAuD;AAA9C,qHAAA,iBAAiB,OAAA"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { FieldValue } from 'firebase-admin/firestore';
|
|
2
|
+
import { SubscriptionEntity, SubscriptionFieldPath } from './types';
|
|
3
|
+
import { AppNamespace } from '../app/types';
|
|
4
|
+
export type UpdateDBSubscriptionFields = [
|
|
5
|
+
SubscriptionFieldPath,
|
|
6
|
+
FieldValue | string | number | boolean | Date | [] | {}
|
|
7
|
+
][];
|
|
8
|
+
/**
|
|
9
|
+
* SubscriptionRepository class handles all database operations related to subscriptions.
|
|
10
|
+
* Implements repository pattern for subscription data access.
|
|
11
|
+
*/
|
|
12
|
+
export declare class SubscriptionRepository {
|
|
13
|
+
private readonly db;
|
|
14
|
+
private readonly collectionName;
|
|
15
|
+
/**
|
|
16
|
+
* Creates an instance of SubscriptionRepository.
|
|
17
|
+
*/
|
|
18
|
+
constructor();
|
|
19
|
+
/**
|
|
20
|
+
* Retrieves an active subscription for a specific user.
|
|
21
|
+
* @param params - Query parameters
|
|
22
|
+
* @param params.userId - The user's unique identifier
|
|
23
|
+
* @param params.appNamespace - The application namespace/platform
|
|
24
|
+
* @returns Promise resolving to SubscriptionEntity or null if not found
|
|
25
|
+
*/
|
|
26
|
+
getByUserId(params: {
|
|
27
|
+
userId: string;
|
|
28
|
+
appNamespace: string;
|
|
29
|
+
}): Promise<SubscriptionEntity | null>;
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new subscription record in the database.
|
|
32
|
+
* @param params - Subscription creation parameters
|
|
33
|
+
* @param params.userId - The user's unique identifier
|
|
34
|
+
* @param params.appNamespace - The application namespace/platform
|
|
35
|
+
* @param params.planId - The subscription plan identifier
|
|
36
|
+
* @param params.expiresAt - ISO timestamp when subscription expires
|
|
37
|
+
* @param params.startedAt - ISO timestamp when subscription started
|
|
38
|
+
* @returns Promise resolving to created SubscriptionEntity with ID
|
|
39
|
+
* @throws Error if subscription creation fails
|
|
40
|
+
*/
|
|
41
|
+
create(params: {
|
|
42
|
+
userId: string;
|
|
43
|
+
appNamespace: AppNamespace;
|
|
44
|
+
planId: string;
|
|
45
|
+
expiresAt: string;
|
|
46
|
+
startedAt: string;
|
|
47
|
+
}): Promise<SubscriptionEntity>;
|
|
48
|
+
/**
|
|
49
|
+
* Updates specific fields of a subscription identified by userId and appNamespace.
|
|
50
|
+
* @param params - Update parameters
|
|
51
|
+
* @param params.userId - The user's unique identifier
|
|
52
|
+
* @param params.appNamespace - The application namespace/platform
|
|
53
|
+
* @param params.fields - Array of field paths and values to update
|
|
54
|
+
* @throws Error if subscription not found or update fails
|
|
55
|
+
*/
|
|
56
|
+
updateFieldsByUserId(params: {
|
|
57
|
+
userId: string;
|
|
58
|
+
appNamespace: AppNamespace;
|
|
59
|
+
fields: UpdateDBSubscriptionFields;
|
|
60
|
+
}): Promise<void>;
|
|
61
|
+
/**
|
|
62
|
+
* Retrieves all active subscriptions that have expired.
|
|
63
|
+
* Used for batch processing to update subscription statuses.
|
|
64
|
+
* @returns Promise resolving to array of expired SubscriptionEntity
|
|
65
|
+
*/
|
|
66
|
+
getExpiredActiveSubscriptions(): Promise<SubscriptionEntity[]>;
|
|
67
|
+
/**
|
|
68
|
+
* Updates specific fields of a subscription identified by subscription ID.
|
|
69
|
+
* @param params - Update parameters
|
|
70
|
+
* @param params.subscriptionId - The subscription document ID
|
|
71
|
+
* @param params.fields - Array of field paths and values to update
|
|
72
|
+
* @throws Error if update fails
|
|
73
|
+
*/
|
|
74
|
+
updateFieldsById(params: {
|
|
75
|
+
subscriptionId: string;
|
|
76
|
+
fields: UpdateDBSubscriptionFields;
|
|
77
|
+
}): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Maps a Firestore document to a SubscriptionEntity.
|
|
80
|
+
* @param doc - Firestore document snapshot
|
|
81
|
+
* @returns SubscriptionEntity with document ID
|
|
82
|
+
*/
|
|
83
|
+
private mapDocumentToEntity;
|
|
84
|
+
/**
|
|
85
|
+
* Builds an update object from field tuples.
|
|
86
|
+
* @param fields - Array of field paths and values
|
|
87
|
+
* @returns Object with field paths as keys and values to update
|
|
88
|
+
*/
|
|
89
|
+
private buildUpdateObject;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=repository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.d.ts","sourceRoot":"","sources":["../../../src/modules/subscription/repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAkD,MAAM,0BAA0B,CAAC;AACtG,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEpE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C,MAAM,MAAM,0BAA0B,GAAG;IACrC,qBAAqB;IACrB,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE;CAC1D,EAAE,CAAC;AAEJ;;;GAGG;AACH,qBAAa,sBAAsB;IAC/B,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAY;IAC/B,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAmB;IAElD;;OAEG;;IAKH;;;;;;OAMG;IACU,WAAW,CAAC,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC;IAmB9G;;;;;;;;;;OAUG;IACU,MAAM,CAAC,MAAM,EAAE;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,YAAY,CAAC;QAC3B,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACrB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAwB/B;;;;;;;OAOG;IACU,oBAAoB,CAAC,MAAM,EAAE;QACtC,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,YAAY,CAAC;QAC3B,MAAM,EAAE,0BAA0B,CAAC;KACtC,GAAG,OAAO,CAAC,IAAI,CAAC;IAmBjB;;;;OAIG;IACU,6BAA6B,IAAI,OAAO,CAAC,kBAAkB,EAAE,CAAC;IAgB3E;;;;;;OAMG;IACU,gBAAgB,CAAC,MAAM,EAAE;QAClC,cAAc,EAAE,MAAM,CAAC;QACvB,MAAM,EAAE,0BAA0B,CAAC;KACtC,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjB;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;CAS5B"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SubscriptionRepository = void 0;
|
|
4
|
+
const firestore_1 = require("firebase-admin/firestore");
|
|
5
|
+
const const_1 = require("./const");
|
|
6
|
+
/**
|
|
7
|
+
* SubscriptionRepository class handles all database operations related to subscriptions.
|
|
8
|
+
* Implements repository pattern for subscription data access.
|
|
9
|
+
*/
|
|
10
|
+
class SubscriptionRepository {
|
|
11
|
+
/**
|
|
12
|
+
* Creates an instance of SubscriptionRepository.
|
|
13
|
+
*/
|
|
14
|
+
constructor() {
|
|
15
|
+
this.collectionName = 'subscriptions';
|
|
16
|
+
this.db = (0, firestore_1.getFirestore)();
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Retrieves an active subscription for a specific user.
|
|
20
|
+
* @param params - Query parameters
|
|
21
|
+
* @param params.userId - The user's unique identifier
|
|
22
|
+
* @param params.appNamespace - The application namespace/platform
|
|
23
|
+
* @returns Promise resolving to SubscriptionEntity or null if not found
|
|
24
|
+
*/
|
|
25
|
+
async getByUserId(params) {
|
|
26
|
+
const { userId, appNamespace } = params;
|
|
27
|
+
const querySnapshot = await this.db
|
|
28
|
+
.collection(this.collectionName)
|
|
29
|
+
.where('platform', '==', appNamespace)
|
|
30
|
+
.where('userId', '==', userId)
|
|
31
|
+
.where('status', '==', 'active')
|
|
32
|
+
.limit(1)
|
|
33
|
+
.get();
|
|
34
|
+
if (querySnapshot.empty) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const doc = querySnapshot.docs[0];
|
|
38
|
+
return this.mapDocumentToEntity(doc);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Creates a new subscription record in the database.
|
|
42
|
+
* @param params - Subscription creation parameters
|
|
43
|
+
* @param params.userId - The user's unique identifier
|
|
44
|
+
* @param params.appNamespace - The application namespace/platform
|
|
45
|
+
* @param params.planId - The subscription plan identifier
|
|
46
|
+
* @param params.expiresAt - ISO timestamp when subscription expires
|
|
47
|
+
* @param params.startedAt - ISO timestamp when subscription started
|
|
48
|
+
* @returns Promise resolving to created SubscriptionEntity with ID
|
|
49
|
+
* @throws Error if subscription creation fails
|
|
50
|
+
*/
|
|
51
|
+
async create(params) {
|
|
52
|
+
const { userId, appNamespace, planId, expiresAt, startedAt } = params;
|
|
53
|
+
const subscriptionEntity = {
|
|
54
|
+
...const_1.DEFAULT_SUBSCRIPTION_ENTITY,
|
|
55
|
+
userId,
|
|
56
|
+
platform: appNamespace,
|
|
57
|
+
planId,
|
|
58
|
+
expiresAt,
|
|
59
|
+
startedAt,
|
|
60
|
+
};
|
|
61
|
+
const docRef = await this.db.collection(this.collectionName).add(subscriptionEntity);
|
|
62
|
+
if (!docRef.id) {
|
|
63
|
+
throw new Error(`Failed to create subscription for userId: ${userId}`);
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
id: docRef.id,
|
|
67
|
+
...subscriptionEntity,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Updates specific fields of a subscription identified by userId and appNamespace.
|
|
72
|
+
* @param params - Update parameters
|
|
73
|
+
* @param params.userId - The user's unique identifier
|
|
74
|
+
* @param params.appNamespace - The application namespace/platform
|
|
75
|
+
* @param params.fields - Array of field paths and values to update
|
|
76
|
+
* @throws Error if subscription not found or update fails
|
|
77
|
+
*/
|
|
78
|
+
async updateFieldsByUserId(params) {
|
|
79
|
+
const { userId, appNamespace, fields } = params;
|
|
80
|
+
const updateObject = this.buildUpdateObject(fields);
|
|
81
|
+
const querySnapshot = await this.db
|
|
82
|
+
.collection(this.collectionName)
|
|
83
|
+
.where('platform', '==', appNamespace)
|
|
84
|
+
.where('userId', '==', userId)
|
|
85
|
+
.limit(1)
|
|
86
|
+
.get();
|
|
87
|
+
if (querySnapshot.empty) {
|
|
88
|
+
throw new Error(`Subscription not found for userId: ${userId}`);
|
|
89
|
+
}
|
|
90
|
+
await querySnapshot.docs[0].ref.update(updateObject);
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Retrieves all active subscriptions that have expired.
|
|
94
|
+
* Used for batch processing to update subscription statuses.
|
|
95
|
+
* @returns Promise resolving to array of expired SubscriptionEntity
|
|
96
|
+
*/
|
|
97
|
+
async getExpiredActiveSubscriptions() {
|
|
98
|
+
const now = new Date().toISOString();
|
|
99
|
+
const querySnapshot = await this.db
|
|
100
|
+
.collection(this.collectionName)
|
|
101
|
+
.where('status', '==', 'active')
|
|
102
|
+
.where('expiresAt', '<', now)
|
|
103
|
+
.get();
|
|
104
|
+
if (querySnapshot.empty) {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
return querySnapshot.docs.map((doc) => this.mapDocumentToEntity(doc));
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Updates specific fields of a subscription identified by subscription ID.
|
|
111
|
+
* @param params - Update parameters
|
|
112
|
+
* @param params.subscriptionId - The subscription document ID
|
|
113
|
+
* @param params.fields - Array of field paths and values to update
|
|
114
|
+
* @throws Error if update fails
|
|
115
|
+
*/
|
|
116
|
+
async updateFieldsById(params) {
|
|
117
|
+
const { subscriptionId, fields } = params;
|
|
118
|
+
const updateObject = this.buildUpdateObject(fields);
|
|
119
|
+
await this.db.collection(this.collectionName).doc(subscriptionId).update(updateObject);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Maps a Firestore document to a SubscriptionEntity.
|
|
123
|
+
* @param doc - Firestore document snapshot
|
|
124
|
+
* @returns SubscriptionEntity with document ID
|
|
125
|
+
*/
|
|
126
|
+
mapDocumentToEntity(doc) {
|
|
127
|
+
return {
|
|
128
|
+
id: doc.id,
|
|
129
|
+
...doc.data(),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Builds an update object from field tuples.
|
|
134
|
+
* @param fields - Array of field paths and values
|
|
135
|
+
* @returns Object with field paths as keys and values to update
|
|
136
|
+
*/
|
|
137
|
+
buildUpdateObject(fields) {
|
|
138
|
+
const updateObject = {};
|
|
139
|
+
fields.forEach(([fieldPath, value]) => {
|
|
140
|
+
updateObject[fieldPath] = value;
|
|
141
|
+
});
|
|
142
|
+
return updateObject;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
exports.SubscriptionRepository = SubscriptionRepository;
|
|
146
|
+
//# sourceMappingURL=repository.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repository.js","sourceRoot":"","sources":["../../../src/modules/subscription/repository.ts"],"names":[],"mappings":"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"}
|