@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 CHANGED
@@ -38,9 +38,10 @@ const revenue = createRevenue({
38
38
  });
39
39
 
40
40
  // Create subscription (no organizationId needed)
41
- const { transaction } = await revenue.subscriptions.create({
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.subscriptions.create({
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: 'monthly',
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.subscriptions.create({
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.subscriptions.activate(subscription._id);
168
+ await revenue.monetization.activate(subscription._id);
167
169
 
168
170
  // Renew subscription
169
- await revenue.subscriptions.renew(subscription._id, {
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.subscriptions.pause(subscription._id, { reason: 'Customer request' });
176
- await revenue.subscriptions.resume(subscription._id, { extendPeriod: true });
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.subscriptions.cancel(subscription._id, { immediate: true });
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.subscriptions.create({
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.subscriptions.create({
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.subscriptions.renew(membership.subscriptionId);
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.subscriptions.create({
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.subscriptions.create({
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.subscriptions.create({ ... });
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 { SubscriptionService } from '../services/subscription.service.js';
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 subscription = await revenue.subscriptions.create({
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(txnId);
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
- subscriptions: null,
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
- * Subscription service
127
+ * Monetization service (handles purchases, subscriptions, free items)
126
128
  * Lazy-loaded on first access
127
129
  */
128
- get subscriptions() {
129
- if (!services.subscriptions) {
130
- services.subscriptions = new SubscriptionService(container);
130
+ get monetization() {
131
+ if (!services.monetization) {
132
+ services.monetization = new MonetizationService(container);
131
133
  }
132
- return services.subscriptions;
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 {SubscriptionService} subscriptions - Subscription service
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 subscription = await revenue.subscriptions.create({
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(txnId);
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
- * - Subscription service
73
+ * - Monetization service (purchases, subscriptions, free items)
72
74
  */
73
- subscriptions: SubscriptionService;
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 { SubscriptionService } from '../services/subscription.service.js';
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';
@@ -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 { SubscriptionService } from "./services/subscription.service.js";
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
- * Subscription Service
2
+ * Monetization Service
3
3
  * Uses DI container for all dependencies
4
4
  */
5
- export class SubscriptionService {
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 {Object} params - Subscription parameters
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
- * // With polymorphic reference (recommended)
31
- * await revenue.subscriptions.create({
19
+ * // One-time purchase
20
+ * await revenue.monetization.create({
32
21
  * data: {
33
22
  * organizationId: '...',
34
23
  * customerId: '...',
35
- * referenceId: subscription._id, // Links to entity
36
- * referenceModel: 'Subscription', // Model name
24
+ * referenceId: order._id,
25
+ * referenceModel: 'Order',
37
26
  * },
38
- * gateway: 'bkash', // Any registered provider
27
+ * planKey: 'one_time',
28
+ * monetizationType: 'purchase',
29
+ * gateway: 'bkash',
39
30
  * amount: 1500,
40
- * // ...
41
31
  * });
42
32
  *
43
- * @returns {Promise<Object>} { subscription, transaction, paymentIntent }
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 SubscriptionService;
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
+ };
@@ -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.subscriptions.create({ gateway: 'bkash', ... });
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 { SubscriptionService } from './services/subscription.service.js';
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.1",
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
- * Subscription Service
2
+ * Monetization Service
3
3
  * @classytic/revenue
4
4
  *
5
- * Framework-agnostic subscription management service with DI
6
- * Handles complete subscription lifecycle using provider system
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
- * Subscription Service
52
+ * Monetization Service
28
53
  * Uses DI container for all dependencies
29
54
  */
30
- export class SubscriptionService {
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 {Object} params - Subscription parameters
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
- * // With polymorphic reference (recommended)
58
- * await revenue.subscriptions.create({
71
+ * // One-time purchase
72
+ * await revenue.monetization.create({
59
73
  * data: {
60
74
  * organizationId: '...',
61
75
  * customerId: '...',
62
- * referenceId: subscription._id, // Links to entity
63
- * referenceModel: 'Subscription', // Model name
76
+ * referenceId: order._id,
77
+ * referenceModel: 'Order',
64
78
  * },
65
- * gateway: 'bkash', // Any registered provider
79
+ * planKey: 'one_time',
80
+ * monetizationType: 'purchase',
81
+ * gateway: 'bkash',
66
82
  * amount: 1500,
67
- * // ...
68
83
  * });
69
84
  *
70
- * @returns {Promise<Object>} { subscription, transaction, paymentIntent }
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 SubscriptionService;
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,