@classytic/revenue 0.2.1 → 0.2.2
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 +17 -15
- package/core/builder.js +12 -10
- package/dist/types/core/builder.d.ts +7 -5
- package/dist/types/index.d.ts +1 -1
- package/dist/types/services/{subscription.service.d.ts → monetization.service.d.ts} +89 -35
- package/dist/types/services/payment.service.d.ts +32 -0
- package/enums/payment.enums.js +1 -1
- package/index.js +1 -1
- package/package.json +1 -1
- package/services/{subscription.service.js → monetization.service.js} +55 -26
- package/services/payment.service.js +15 -0
package/README.md
CHANGED
|
@@ -38,9 +38,10 @@ const revenue = createRevenue({
|
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
// Create subscription (no organizationId needed)
|
|
41
|
-
const { transaction } = await revenue.
|
|
41
|
+
const { transaction } = await revenue.monetization.create({
|
|
42
42
|
data: { customerId: user._id },
|
|
43
43
|
planKey: 'monthly',
|
|
44
|
+
monetizationType: 'subscription',
|
|
44
45
|
amount: 2999, // $29.99
|
|
45
46
|
gateway: 'manual',
|
|
46
47
|
paymentData: { method: 'card' },
|
|
@@ -54,14 +55,15 @@ await revenue.payments.verify(transaction.gateway.paymentIntentId);
|
|
|
54
55
|
|
|
55
56
|
```javascript
|
|
56
57
|
// Same API, just pass organizationId
|
|
57
|
-
const { transaction } = await revenue.
|
|
58
|
+
const { transaction } = await revenue.monetization.create({
|
|
58
59
|
data: {
|
|
59
60
|
organizationId: vendor._id, // ← Multi-tenant
|
|
60
61
|
customerId: customer._id,
|
|
61
62
|
referenceId: order._id,
|
|
62
63
|
referenceModel: 'Order',
|
|
63
64
|
},
|
|
64
|
-
planKey: '
|
|
65
|
+
planKey: 'one_time',
|
|
66
|
+
monetizationType: 'purchase', // One-time purchase
|
|
65
67
|
amount: 1500,
|
|
66
68
|
gateway: 'manual',
|
|
67
69
|
paymentData: { method: 'bkash' },
|
|
@@ -152,7 +154,7 @@ const schema = new mongoose.Schema({
|
|
|
152
154
|
```javascript
|
|
153
155
|
// Create subscription
|
|
154
156
|
const { subscription, transaction, paymentIntent } =
|
|
155
|
-
await revenue.
|
|
157
|
+
await revenue.monetization.create({
|
|
156
158
|
data: { organizationId, customerId },
|
|
157
159
|
planKey: 'monthly',
|
|
158
160
|
amount: 1500,
|
|
@@ -163,20 +165,20 @@ const { subscription, transaction, paymentIntent } =
|
|
|
163
165
|
|
|
164
166
|
// Verify and activate
|
|
165
167
|
await revenue.payments.verify(transaction.gateway.paymentIntentId);
|
|
166
|
-
await revenue.
|
|
168
|
+
await revenue.monetization.activate(subscription._id);
|
|
167
169
|
|
|
168
170
|
// Renew subscription
|
|
169
|
-
await revenue.
|
|
171
|
+
await revenue.monetization.renew(subscription._id, {
|
|
170
172
|
gateway: 'manual',
|
|
171
173
|
paymentData: { method: 'nagad' },
|
|
172
174
|
});
|
|
173
175
|
|
|
174
176
|
// Pause/Resume
|
|
175
|
-
await revenue.
|
|
176
|
-
await revenue.
|
|
177
|
+
await revenue.monetization.pause(subscription._id, { reason: 'Customer request' });
|
|
178
|
+
await revenue.monetization.resume(subscription._id, { extendPeriod: true });
|
|
177
179
|
|
|
178
180
|
// Cancel
|
|
179
|
-
await revenue.
|
|
181
|
+
await revenue.monetization.cancel(subscription._id, { immediate: true });
|
|
180
182
|
```
|
|
181
183
|
|
|
182
184
|
### Payments
|
|
@@ -267,7 +269,7 @@ const revenue = createRevenue({
|
|
|
267
269
|
});
|
|
268
270
|
|
|
269
271
|
// Usage
|
|
270
|
-
await revenue.
|
|
272
|
+
await revenue.monetization.create({
|
|
271
273
|
entity: 'Order', // Maps to 'order_subscription' category
|
|
272
274
|
monetizationType: 'subscription',
|
|
273
275
|
// ...
|
|
@@ -301,7 +303,7 @@ const revenue = createRevenue({
|
|
|
301
303
|
});
|
|
302
304
|
|
|
303
305
|
// Commission calculated automatically
|
|
304
|
-
const { transaction } = await revenue.
|
|
306
|
+
const { transaction } = await revenue.monetization.create({
|
|
305
307
|
amount: 10000, // $100
|
|
306
308
|
entity: 'ProductOrder', // → 10% commission
|
|
307
309
|
gateway: 'stripe', // → 2.9% fee
|
|
@@ -357,7 +359,7 @@ const refund = calculateProratedAmount({
|
|
|
357
359
|
|
|
358
360
|
// Check eligibility
|
|
359
361
|
if (canRenewSubscription(membership)) {
|
|
360
|
-
await revenue.
|
|
362
|
+
await revenue.monetization.renew(membership.subscriptionId);
|
|
361
363
|
}
|
|
362
364
|
```
|
|
363
365
|
|
|
@@ -369,7 +371,7 @@ if (canRenewSubscription(membership)) {
|
|
|
369
371
|
|
|
370
372
|
```javascript
|
|
371
373
|
// 1. Customer makes purchase
|
|
372
|
-
const { transaction } = await revenue.
|
|
374
|
+
const { transaction } = await revenue.monetization.create({
|
|
373
375
|
amount: 1000,
|
|
374
376
|
gateway: 'stripe',
|
|
375
377
|
// ...
|
|
@@ -464,7 +466,7 @@ Link transactions to any entity (Order, Subscription, Enrollment):
|
|
|
464
466
|
|
|
465
467
|
```javascript
|
|
466
468
|
// Create transaction linked to Order
|
|
467
|
-
const { transaction } = await revenue.
|
|
469
|
+
const { transaction } = await revenue.monetization.create({
|
|
468
470
|
data: {
|
|
469
471
|
organizationId,
|
|
470
472
|
customerId,
|
|
@@ -637,7 +639,7 @@ const revenue: Revenue = createRevenue({
|
|
|
637
639
|
|
|
638
640
|
// All services are fully typed
|
|
639
641
|
const payment = await revenue.payments.verify(id);
|
|
640
|
-
const subscription = await revenue.
|
|
642
|
+
const subscription = await revenue.monetization.create({ ... });
|
|
641
643
|
```
|
|
642
644
|
|
|
643
645
|
## Examples
|
package/core/builder.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { Container } from './container.js';
|
|
10
|
-
import {
|
|
10
|
+
import { MonetizationService } from '../services/monetization.service.js';
|
|
11
11
|
import { PaymentService } from '../services/payment.service.js';
|
|
12
12
|
import { TransactionService } from '../services/transaction.service.js';
|
|
13
13
|
import { EscrowService } from '../services/escrow.service.js';
|
|
@@ -51,11 +51,13 @@ import { ConfigurationError } from './errors.js';
|
|
|
51
51
|
* });
|
|
52
52
|
*
|
|
53
53
|
* // Use any registered gateway by name
|
|
54
|
-
* const
|
|
54
|
+
* const { transaction } = await revenue.monetization.create({
|
|
55
55
|
* gateway: 'bkash', // Use your custom gateway
|
|
56
|
+
* monetizationType: 'purchase',
|
|
57
|
+
* amount: 1500,
|
|
56
58
|
* // ...
|
|
57
59
|
* });
|
|
58
|
-
* await revenue.payments.verify(
|
|
60
|
+
* await revenue.payments.verify(transaction._id);
|
|
59
61
|
* ```
|
|
60
62
|
*/
|
|
61
63
|
export function createRevenue(options = {}) {
|
|
@@ -98,7 +100,7 @@ export function createRevenue(options = {}) {
|
|
|
98
100
|
|
|
99
101
|
// Create service instances (lazy-loaded)
|
|
100
102
|
const services = {
|
|
101
|
-
|
|
103
|
+
monetization: null,
|
|
102
104
|
payments: null,
|
|
103
105
|
transactions: null,
|
|
104
106
|
escrow: null,
|
|
@@ -122,14 +124,14 @@ export function createRevenue(options = {}) {
|
|
|
122
124
|
config,
|
|
123
125
|
|
|
124
126
|
/**
|
|
125
|
-
*
|
|
127
|
+
* Monetization service (handles purchases, subscriptions, free items)
|
|
126
128
|
* Lazy-loaded on first access
|
|
127
129
|
*/
|
|
128
|
-
get
|
|
129
|
-
if (!services.
|
|
130
|
-
services.
|
|
130
|
+
get monetization() {
|
|
131
|
+
if (!services.monetization) {
|
|
132
|
+
services.monetization = new MonetizationService(container);
|
|
131
133
|
}
|
|
132
|
-
return services.
|
|
134
|
+
return services.monetization;
|
|
133
135
|
},
|
|
134
136
|
|
|
135
137
|
/**
|
|
@@ -207,7 +209,7 @@ function validateProvider(name, provider) {
|
|
|
207
209
|
* @property {Container} container - DI container (readonly)
|
|
208
210
|
* @property {Object} providers - Payment providers (readonly, frozen)
|
|
209
211
|
* @property {Object} config - Configuration (readonly, frozen)
|
|
210
|
-
* @property {
|
|
212
|
+
* @property {MonetizationService} monetization - Monetization service (purchases, subscriptions, free items)
|
|
211
213
|
* @property {PaymentService} payments - Payment service
|
|
212
214
|
* @property {TransactionService} transactions - Transaction service
|
|
213
215
|
* @property {EscrowService} escrow - Escrow service
|
|
@@ -36,11 +36,13 @@
|
|
|
36
36
|
* });
|
|
37
37
|
*
|
|
38
38
|
* // Use any registered gateway by name
|
|
39
|
-
* const
|
|
39
|
+
* const { transaction } = await revenue.monetization.create({
|
|
40
40
|
* gateway: 'bkash', // Use your custom gateway
|
|
41
|
+
* monetizationType: 'purchase',
|
|
42
|
+
* amount: 1500,
|
|
41
43
|
* // ...
|
|
42
44
|
* });
|
|
43
|
-
* await revenue.payments.verify(
|
|
45
|
+
* await revenue.payments.verify(transaction._id);
|
|
44
46
|
* ```
|
|
45
47
|
*/
|
|
46
48
|
export function createRevenue(options?: {
|
|
@@ -68,9 +70,9 @@ export type Revenue = {
|
|
|
68
70
|
*/
|
|
69
71
|
config: any;
|
|
70
72
|
/**
|
|
71
|
-
* -
|
|
73
|
+
* - Monetization service (purchases, subscriptions, free items)
|
|
72
74
|
*/
|
|
73
|
-
|
|
75
|
+
monetization: MonetizationService;
|
|
74
76
|
/**
|
|
75
77
|
* - Payment service
|
|
76
78
|
*/
|
|
@@ -89,7 +91,7 @@ export type Revenue = {
|
|
|
89
91
|
getProvider: Function;
|
|
90
92
|
};
|
|
91
93
|
import { Container } from './container.js';
|
|
92
|
-
import {
|
|
94
|
+
import { MonetizationService } from '../services/monetization.service.js';
|
|
93
95
|
import { PaymentService } from '../services/payment.service.js';
|
|
94
96
|
import { TransactionService } from '../services/transaction.service.js';
|
|
95
97
|
import { EscrowService } from '../services/escrow.service.js';
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ export { Container } from "./core/container.js";
|
|
|
3
3
|
export * from "./core/errors.js";
|
|
4
4
|
export * from "./enums/index.js";
|
|
5
5
|
export * from "./schemas/index.js";
|
|
6
|
-
export {
|
|
6
|
+
export { MonetizationService } from "./services/monetization.service.js";
|
|
7
7
|
export { PaymentService } from "./services/payment.service.js";
|
|
8
8
|
export { TransactionService } from "./services/transaction.service.js";
|
|
9
9
|
export { EscrowService } from "./services/escrow.service.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Monetization Service
|
|
3
3
|
* Uses DI container for all dependencies
|
|
4
4
|
*/
|
|
5
|
-
export class
|
|
5
|
+
export class MonetizationService {
|
|
6
6
|
constructor(container: any);
|
|
7
7
|
container: any;
|
|
8
8
|
models: any;
|
|
@@ -11,49 +11,42 @@ export class SubscriptionService {
|
|
|
11
11
|
hooks: any;
|
|
12
12
|
logger: any;
|
|
13
13
|
/**
|
|
14
|
-
* Create a new subscription
|
|
14
|
+
* Create a new monetization (purchase, subscription, or free item)
|
|
15
15
|
*
|
|
16
|
-
* @param {
|
|
17
|
-
* @param {Object} params.data - Subscription data (organizationId, customerId, referenceId, referenceModel, etc.)
|
|
18
|
-
* @param {String} params.planKey - Plan key ('monthly', 'quarterly', 'yearly')
|
|
19
|
-
* @param {Number} params.amount - Subscription amount
|
|
20
|
-
* @param {String} params.currency - Currency code (default: 'BDT')
|
|
21
|
-
* @param {String} params.gateway - Payment gateway name (default: 'manual') - Use ANY registered provider name: 'manual', 'bkash', 'nagad', 'stripe', etc.
|
|
22
|
-
* @param {String} params.entity - Logical entity identifier (e.g., 'Order', 'PlatformSubscription', 'Membership')
|
|
23
|
-
* NOTE: This is NOT a database model name - it's just a logical identifier for categoryMappings
|
|
24
|
-
* @param {String} params.monetizationType - Monetization type ('free', 'subscription', 'purchase')
|
|
25
|
-
* @param {Object} params.paymentData - Payment method details
|
|
26
|
-
* @param {Object} params.metadata - Additional metadata
|
|
27
|
-
* @param {String} params.idempotencyKey - Idempotency key for duplicate prevention
|
|
16
|
+
* @param {MonetizationCreateParams} params - Monetization parameters
|
|
28
17
|
*
|
|
29
18
|
* @example
|
|
30
|
-
* //
|
|
31
|
-
* await revenue.
|
|
19
|
+
* // One-time purchase
|
|
20
|
+
* await revenue.monetization.create({
|
|
32
21
|
* data: {
|
|
33
22
|
* organizationId: '...',
|
|
34
23
|
* customerId: '...',
|
|
35
|
-
* referenceId:
|
|
36
|
-
* referenceModel: '
|
|
24
|
+
* referenceId: order._id,
|
|
25
|
+
* referenceModel: 'Order',
|
|
37
26
|
* },
|
|
38
|
-
*
|
|
27
|
+
* planKey: 'one_time',
|
|
28
|
+
* monetizationType: 'purchase',
|
|
29
|
+
* gateway: 'bkash',
|
|
39
30
|
* amount: 1500,
|
|
40
|
-
* // ...
|
|
41
31
|
* });
|
|
42
32
|
*
|
|
43
|
-
*
|
|
33
|
+
* // Recurring subscription
|
|
34
|
+
* await revenue.monetization.create({
|
|
35
|
+
* data: {
|
|
36
|
+
* organizationId: '...',
|
|
37
|
+
* customerId: '...',
|
|
38
|
+
* referenceId: subscription._id,
|
|
39
|
+
* referenceModel: 'Subscription',
|
|
40
|
+
* },
|
|
41
|
+
* planKey: 'monthly',
|
|
42
|
+
* monetizationType: 'subscription',
|
|
43
|
+
* gateway: 'stripe',
|
|
44
|
+
* amount: 2000,
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* @returns {Promise<MonetizationCreateResult>} Result with subscription, transaction, and paymentIntent
|
|
44
48
|
*/
|
|
45
|
-
create(params:
|
|
46
|
-
data: any;
|
|
47
|
-
planKey: string;
|
|
48
|
-
amount: number;
|
|
49
|
-
currency: string;
|
|
50
|
-
gateway: string;
|
|
51
|
-
entity: string;
|
|
52
|
-
monetizationType: string;
|
|
53
|
-
paymentData: any;
|
|
54
|
-
metadata: any;
|
|
55
|
-
idempotencyKey: string;
|
|
56
|
-
}): Promise<any>;
|
|
49
|
+
create(params: MonetizationCreateParams): Promise<MonetizationCreateResult>;
|
|
57
50
|
/**
|
|
58
51
|
* Activate subscription after payment verification
|
|
59
52
|
*
|
|
@@ -136,4 +129,65 @@ export class SubscriptionService {
|
|
|
136
129
|
*/
|
|
137
130
|
private _triggerHook;
|
|
138
131
|
}
|
|
139
|
-
export default
|
|
132
|
+
export default MonetizationService;
|
|
133
|
+
export type MonetizationCreateParams = {
|
|
134
|
+
/**
|
|
135
|
+
* - Monetization data
|
|
136
|
+
*/
|
|
137
|
+
data: {
|
|
138
|
+
organizationId?: string;
|
|
139
|
+
customerId?: string;
|
|
140
|
+
referenceId?: string;
|
|
141
|
+
referenceModel?: string;
|
|
142
|
+
};
|
|
143
|
+
/**
|
|
144
|
+
* - Plan key ('monthly', 'quarterly', 'yearly', 'one_time', etc.)
|
|
145
|
+
*/
|
|
146
|
+
planKey: string;
|
|
147
|
+
/**
|
|
148
|
+
* - Amount (0 for free)
|
|
149
|
+
*/
|
|
150
|
+
amount: number;
|
|
151
|
+
/**
|
|
152
|
+
* - Currency code
|
|
153
|
+
*/
|
|
154
|
+
currency?: string;
|
|
155
|
+
/**
|
|
156
|
+
* - Payment gateway name
|
|
157
|
+
*/
|
|
158
|
+
gateway?: string;
|
|
159
|
+
/**
|
|
160
|
+
* - Logical entity identifier
|
|
161
|
+
*/
|
|
162
|
+
entity?: string;
|
|
163
|
+
/**
|
|
164
|
+
* - Monetization type
|
|
165
|
+
*/
|
|
166
|
+
monetizationType?: "free" | "subscription" | "purchase";
|
|
167
|
+
/**
|
|
168
|
+
* - Payment method details
|
|
169
|
+
*/
|
|
170
|
+
paymentData?: any;
|
|
171
|
+
/**
|
|
172
|
+
* - Additional metadata
|
|
173
|
+
*/
|
|
174
|
+
metadata?: any;
|
|
175
|
+
/**
|
|
176
|
+
* - Idempotency key
|
|
177
|
+
*/
|
|
178
|
+
idempotencyKey?: string;
|
|
179
|
+
};
|
|
180
|
+
export type MonetizationCreateResult = {
|
|
181
|
+
/**
|
|
182
|
+
* - Subscription record (if Subscription model exists)
|
|
183
|
+
*/
|
|
184
|
+
subscription: any | null;
|
|
185
|
+
/**
|
|
186
|
+
* - Transaction record
|
|
187
|
+
*/
|
|
188
|
+
transaction: any | null;
|
|
189
|
+
/**
|
|
190
|
+
* - Payment intent from provider
|
|
191
|
+
*/
|
|
192
|
+
paymentIntent: any | null;
|
|
193
|
+
};
|
|
@@ -78,3 +78,35 @@ export class PaymentService {
|
|
|
78
78
|
private _triggerHook;
|
|
79
79
|
}
|
|
80
80
|
export default PaymentService;
|
|
81
|
+
export type PaymentVerifyResult = {
|
|
82
|
+
/**
|
|
83
|
+
* - Updated transaction
|
|
84
|
+
*/
|
|
85
|
+
transaction: any;
|
|
86
|
+
/**
|
|
87
|
+
* - Payment result from provider
|
|
88
|
+
*/
|
|
89
|
+
paymentResult: any;
|
|
90
|
+
/**
|
|
91
|
+
* - Payment status
|
|
92
|
+
*/
|
|
93
|
+
status: string;
|
|
94
|
+
};
|
|
95
|
+
export type PaymentRefundResult = {
|
|
96
|
+
/**
|
|
97
|
+
* - Original transaction (updated)
|
|
98
|
+
*/
|
|
99
|
+
transaction: any;
|
|
100
|
+
/**
|
|
101
|
+
* - New refund transaction record
|
|
102
|
+
*/
|
|
103
|
+
refundTransaction: any;
|
|
104
|
+
/**
|
|
105
|
+
* - Refund result from provider
|
|
106
|
+
*/
|
|
107
|
+
refundResult: any;
|
|
108
|
+
/**
|
|
109
|
+
* - Transaction status after refund
|
|
110
|
+
*/
|
|
111
|
+
status: string;
|
|
112
|
+
};
|
package/enums/payment.enums.js
CHANGED
|
@@ -41,7 +41,7 @@ export const PAYMENT_STATUS_VALUES = Object.values(PAYMENT_STATUS);
|
|
|
41
41
|
* });
|
|
42
42
|
*
|
|
43
43
|
* // Use by name
|
|
44
|
-
* await revenue.
|
|
44
|
+
* await revenue.monetization.create({ gateway: 'bkash', ... });
|
|
45
45
|
* ```
|
|
46
46
|
*
|
|
47
47
|
* Reference values:
|
package/index.js
CHANGED
|
@@ -35,7 +35,7 @@ import { PaymentProvider as _PaymentProvider } from './providers/base.js';
|
|
|
35
35
|
// Note: ManualProvider moved to @classytic/revenue-manual (separate package)
|
|
36
36
|
|
|
37
37
|
// ============ SERVICES (ADVANCED USAGE) ============
|
|
38
|
-
export {
|
|
38
|
+
export { MonetizationService } from './services/monetization.service.js';
|
|
39
39
|
export { PaymentService } from './services/payment.service.js';
|
|
40
40
|
export { TransactionService } from './services/transaction.service.js';
|
|
41
41
|
export { EscrowService } from './services/escrow.service.js';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@classytic/revenue",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.2",
|
|
4
4
|
"description": "Enterprise revenue management system with subscriptions, purchases, proration, payment processing, escrow, and multi-party splits",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -1,9 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Monetization Service
|
|
3
3
|
* @classytic/revenue
|
|
4
4
|
*
|
|
5
|
-
* Framework-agnostic
|
|
6
|
-
* Handles
|
|
5
|
+
* Framework-agnostic monetization management service with DI
|
|
6
|
+
* Handles purchases, subscriptions, and free items using provider system
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {Object} MonetizationCreateParams
|
|
11
|
+
* @property {Object} data - Monetization data
|
|
12
|
+
* @property {string} [data.organizationId] - Organization ID (for multi-tenant)
|
|
13
|
+
* @property {string} [data.customerId] - Customer ID
|
|
14
|
+
* @property {string} [data.referenceId] - Reference to entity (Order, Subscription, etc.)
|
|
15
|
+
* @property {string} [data.referenceModel] - Model name for reference
|
|
16
|
+
* @property {string} planKey - Plan key ('monthly', 'quarterly', 'yearly', 'one_time', etc.)
|
|
17
|
+
* @property {number} amount - Amount (0 for free)
|
|
18
|
+
* @property {string} [currency='BDT'] - Currency code
|
|
19
|
+
* @property {string} [gateway='manual'] - Payment gateway name
|
|
20
|
+
* @property {string} [entity] - Logical entity identifier
|
|
21
|
+
* @property {'free'|'subscription'|'purchase'} [monetizationType='subscription'] - Monetization type
|
|
22
|
+
* @property {Object} [paymentData] - Payment method details
|
|
23
|
+
* @property {Object} [metadata] - Additional metadata
|
|
24
|
+
* @property {string} [idempotencyKey] - Idempotency key
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @typedef {Object} MonetizationCreateResult
|
|
29
|
+
* @property {Object|null} subscription - Subscription record (if Subscription model exists)
|
|
30
|
+
* @property {Object|null} transaction - Transaction record
|
|
31
|
+
* @property {Object|null} paymentIntent - Payment intent from provider
|
|
7
32
|
*/
|
|
8
33
|
|
|
9
34
|
import { nanoid } from 'nanoid';
|
|
@@ -24,10 +49,10 @@ import { MONETIZATION_TYPES } from '../enums/monetization.enums.js';
|
|
|
24
49
|
import { TRANSACTION_TYPE } from '../enums/transaction.enums.js';
|
|
25
50
|
|
|
26
51
|
/**
|
|
27
|
-
*
|
|
52
|
+
* Monetization Service
|
|
28
53
|
* Uses DI container for all dependencies
|
|
29
54
|
*/
|
|
30
|
-
export class
|
|
55
|
+
export class MonetizationService {
|
|
31
56
|
constructor(container) {
|
|
32
57
|
this.container = container;
|
|
33
58
|
this.models = container.get('models');
|
|
@@ -38,36 +63,40 @@ export class SubscriptionService {
|
|
|
38
63
|
}
|
|
39
64
|
|
|
40
65
|
/**
|
|
41
|
-
* Create a new subscription
|
|
66
|
+
* Create a new monetization (purchase, subscription, or free item)
|
|
42
67
|
*
|
|
43
|
-
* @param {
|
|
44
|
-
* @param {Object} params.data - Subscription data (organizationId, customerId, referenceId, referenceModel, etc.)
|
|
45
|
-
* @param {String} params.planKey - Plan key ('monthly', 'quarterly', 'yearly')
|
|
46
|
-
* @param {Number} params.amount - Subscription amount
|
|
47
|
-
* @param {String} params.currency - Currency code (default: 'BDT')
|
|
48
|
-
* @param {String} params.gateway - Payment gateway name (default: 'manual') - Use ANY registered provider name: 'manual', 'bkash', 'nagad', 'stripe', etc.
|
|
49
|
-
* @param {String} params.entity - Logical entity identifier (e.g., 'Order', 'PlatformSubscription', 'Membership')
|
|
50
|
-
* NOTE: This is NOT a database model name - it's just a logical identifier for categoryMappings
|
|
51
|
-
* @param {String} params.monetizationType - Monetization type ('free', 'subscription', 'purchase')
|
|
52
|
-
* @param {Object} params.paymentData - Payment method details
|
|
53
|
-
* @param {Object} params.metadata - Additional metadata
|
|
54
|
-
* @param {String} params.idempotencyKey - Idempotency key for duplicate prevention
|
|
68
|
+
* @param {MonetizationCreateParams} params - Monetization parameters
|
|
55
69
|
*
|
|
56
70
|
* @example
|
|
57
|
-
* //
|
|
58
|
-
* await revenue.
|
|
71
|
+
* // One-time purchase
|
|
72
|
+
* await revenue.monetization.create({
|
|
59
73
|
* data: {
|
|
60
74
|
* organizationId: '...',
|
|
61
75
|
* customerId: '...',
|
|
62
|
-
* referenceId:
|
|
63
|
-
* referenceModel: '
|
|
76
|
+
* referenceId: order._id,
|
|
77
|
+
* referenceModel: 'Order',
|
|
64
78
|
* },
|
|
65
|
-
*
|
|
79
|
+
* planKey: 'one_time',
|
|
80
|
+
* monetizationType: 'purchase',
|
|
81
|
+
* gateway: 'bkash',
|
|
66
82
|
* amount: 1500,
|
|
67
|
-
* // ...
|
|
68
83
|
* });
|
|
69
84
|
*
|
|
70
|
-
*
|
|
85
|
+
* // Recurring subscription
|
|
86
|
+
* await revenue.monetization.create({
|
|
87
|
+
* data: {
|
|
88
|
+
* organizationId: '...',
|
|
89
|
+
* customerId: '...',
|
|
90
|
+
* referenceId: subscription._id,
|
|
91
|
+
* referenceModel: 'Subscription',
|
|
92
|
+
* },
|
|
93
|
+
* planKey: 'monthly',
|
|
94
|
+
* monetizationType: 'subscription',
|
|
95
|
+
* gateway: 'stripe',
|
|
96
|
+
* amount: 2000,
|
|
97
|
+
* });
|
|
98
|
+
*
|
|
99
|
+
* @returns {Promise<MonetizationCreateResult>} Result with subscription, transaction, and paymentIntent
|
|
71
100
|
*/
|
|
72
101
|
async create(params) {
|
|
73
102
|
const {
|
|
@@ -641,4 +670,4 @@ export class SubscriptionService {
|
|
|
641
670
|
}
|
|
642
671
|
}
|
|
643
672
|
|
|
644
|
-
export default
|
|
673
|
+
export default MonetizationService;
|
|
@@ -6,6 +6,21 @@
|
|
|
6
6
|
* Handles payment verification, refunds, and status updates
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* @typedef {Object} PaymentVerifyResult
|
|
11
|
+
* @property {Object} transaction - Updated transaction
|
|
12
|
+
* @property {Object} paymentResult - Payment result from provider
|
|
13
|
+
* @property {string} status - Payment status
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* @typedef {Object} PaymentRefundResult
|
|
18
|
+
* @property {Object} transaction - Original transaction (updated)
|
|
19
|
+
* @property {Object} refundTransaction - New refund transaction record
|
|
20
|
+
* @property {Object} refundResult - Refund result from provider
|
|
21
|
+
* @property {string} status - Transaction status after refund
|
|
22
|
+
*/
|
|
23
|
+
|
|
9
24
|
import {
|
|
10
25
|
TransactionNotFoundError,
|
|
11
26
|
ProviderNotFoundError,
|