@classytic/revenue 0.2.3 → 1.0.0
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 +498 -499
- package/dist/actions-CwG-b7fR.d.ts +519 -0
- package/dist/core/index.d.ts +884 -0
- package/dist/core/index.js +2941 -0
- package/dist/core/index.js.map +1 -0
- package/dist/enums/index.d.ts +130 -0
- package/dist/enums/index.js +167 -0
- package/dist/enums/index.js.map +1 -0
- package/dist/index-BnJWVXuw.d.ts +378 -0
- package/dist/index-ChVD3P9k.d.ts +504 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.js +4353 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/index.d.ts +132 -0
- package/dist/providers/index.js +122 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/retry-80lBCmSe.d.ts +234 -0
- package/dist/schemas/index.d.ts +894 -0
- package/dist/schemas/index.js +524 -0
- package/dist/schemas/index.js.map +1 -0
- package/dist/schemas/validation.d.ts +309 -0
- package/dist/schemas/validation.js +249 -0
- package/dist/schemas/validation.js.map +1 -0
- package/dist/services/index.d.ts +3 -0
- package/dist/services/index.js +1632 -0
- package/dist/services/index.js.map +1 -0
- package/dist/split.enums-DHdM1YAV.d.ts +255 -0
- package/dist/split.schema-BPdFZMbU.d.ts +958 -0
- package/dist/utils/index.d.ts +24 -0
- package/dist/utils/index.js +1067 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +48 -32
- package/core/builder.js +0 -219
- package/core/container.js +0 -119
- package/core/errors.js +0 -262
- package/dist/types/core/builder.d.ts +0 -97
- package/dist/types/core/container.d.ts +0 -57
- package/dist/types/core/errors.d.ts +0 -122
- package/dist/types/enums/escrow.enums.d.ts +0 -24
- package/dist/types/enums/index.d.ts +0 -69
- package/dist/types/enums/monetization.enums.d.ts +0 -6
- package/dist/types/enums/payment.enums.d.ts +0 -16
- package/dist/types/enums/split.enums.d.ts +0 -25
- package/dist/types/enums/subscription.enums.d.ts +0 -15
- package/dist/types/enums/transaction.enums.d.ts +0 -24
- package/dist/types/index.d.ts +0 -22
- package/dist/types/providers/base.d.ts +0 -126
- package/dist/types/schemas/escrow/hold.schema.d.ts +0 -54
- package/dist/types/schemas/escrow/index.d.ts +0 -6
- package/dist/types/schemas/index.d.ts +0 -506
- package/dist/types/schemas/split/index.d.ts +0 -8
- package/dist/types/schemas/split/split.schema.d.ts +0 -142
- package/dist/types/schemas/subscription/index.d.ts +0 -152
- package/dist/types/schemas/subscription/info.schema.d.ts +0 -128
- package/dist/types/schemas/subscription/plan.schema.d.ts +0 -39
- package/dist/types/schemas/transaction/common.schema.d.ts +0 -12
- package/dist/types/schemas/transaction/gateway.schema.d.ts +0 -86
- package/dist/types/schemas/transaction/index.d.ts +0 -202
- package/dist/types/schemas/transaction/payment.schema.d.ts +0 -145
- package/dist/types/services/escrow.service.d.ts +0 -51
- package/dist/types/services/monetization.service.d.ts +0 -193
- package/dist/types/services/payment.service.d.ts +0 -112
- package/dist/types/services/transaction.service.d.ts +0 -40
- package/dist/types/utils/category-resolver.d.ts +0 -46
- package/dist/types/utils/commission-split.d.ts +0 -56
- package/dist/types/utils/commission.d.ts +0 -29
- package/dist/types/utils/hooks.d.ts +0 -17
- package/dist/types/utils/index.d.ts +0 -6
- package/dist/types/utils/logger.d.ts +0 -12
- package/dist/types/utils/subscription/actions.d.ts +0 -28
- package/dist/types/utils/subscription/index.d.ts +0 -2
- package/dist/types/utils/subscription/period.d.ts +0 -47
- package/dist/types/utils/transaction-type.d.ts +0 -102
- package/enums/escrow.enums.js +0 -36
- package/enums/index.d.ts +0 -116
- package/enums/index.js +0 -110
- package/enums/monetization.enums.js +0 -15
- package/enums/payment.enums.js +0 -64
- package/enums/split.enums.js +0 -37
- package/enums/subscription.enums.js +0 -33
- package/enums/transaction.enums.js +0 -69
- package/index.js +0 -76
- package/providers/base.js +0 -162
- package/schemas/escrow/hold.schema.js +0 -62
- package/schemas/escrow/index.js +0 -15
- package/schemas/index.d.ts +0 -33
- package/schemas/index.js +0 -27
- package/schemas/split/index.js +0 -16
- package/schemas/split/split.schema.js +0 -86
- package/schemas/subscription/index.js +0 -17
- package/schemas/subscription/info.schema.js +0 -115
- package/schemas/subscription/plan.schema.js +0 -48
- package/schemas/transaction/common.schema.js +0 -22
- package/schemas/transaction/gateway.schema.js +0 -69
- package/schemas/transaction/index.js +0 -20
- package/schemas/transaction/payment.schema.js +0 -110
- package/services/escrow.service.js +0 -353
- package/services/monetization.service.js +0 -671
- package/services/payment.service.js +0 -517
- package/services/transaction.service.js +0 -142
- package/utils/category-resolver.js +0 -74
- package/utils/commission-split.js +0 -180
- package/utils/commission.js +0 -83
- package/utils/hooks.js +0 -44
- package/utils/index.d.ts +0 -164
- package/utils/index.js +0 -16
- package/utils/logger.js +0 -36
- package/utils/subscription/actions.js +0 -68
- package/utils/subscription/index.js +0 -20
- package/utils/subscription/period.js +0 -123
- package/utils/transaction-type.js +0 -254
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Subscription Period Utilities
|
|
3
|
-
* @classytic/revenue/utils/subscription
|
|
4
|
-
*
|
|
5
|
-
* Universal period calculation, proration, and date utilities
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Add duration to date
|
|
10
|
-
*/
|
|
11
|
-
export function addDuration(startDate, duration, unit = 'days') {
|
|
12
|
-
const date = new Date(startDate);
|
|
13
|
-
|
|
14
|
-
switch (unit) {
|
|
15
|
-
case 'months':
|
|
16
|
-
case 'month':
|
|
17
|
-
date.setMonth(date.getMonth() + duration);
|
|
18
|
-
return date;
|
|
19
|
-
case 'years':
|
|
20
|
-
case 'year':
|
|
21
|
-
date.setFullYear(date.getFullYear() + duration);
|
|
22
|
-
return date;
|
|
23
|
-
case 'weeks':
|
|
24
|
-
case 'week':
|
|
25
|
-
date.setDate(date.getDate() + (duration * 7));
|
|
26
|
-
return date;
|
|
27
|
-
case 'days':
|
|
28
|
-
case 'day':
|
|
29
|
-
default:
|
|
30
|
-
date.setDate(date.getDate() + duration);
|
|
31
|
-
return date;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Calculate subscription period start/end dates
|
|
37
|
-
*/
|
|
38
|
-
export function calculatePeriodRange({
|
|
39
|
-
currentEndDate = null,
|
|
40
|
-
startDate = null,
|
|
41
|
-
duration,
|
|
42
|
-
unit = 'days',
|
|
43
|
-
now = new Date(),
|
|
44
|
-
}) {
|
|
45
|
-
let periodStart;
|
|
46
|
-
|
|
47
|
-
if (startDate) {
|
|
48
|
-
periodStart = new Date(startDate);
|
|
49
|
-
} else if (currentEndDate) {
|
|
50
|
-
const end = new Date(currentEndDate);
|
|
51
|
-
periodStart = end > now ? end : now;
|
|
52
|
-
} else {
|
|
53
|
-
periodStart = now;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const periodEnd = addDuration(periodStart, duration, unit);
|
|
57
|
-
|
|
58
|
-
return { startDate: periodStart, endDate: periodEnd };
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Calculate prorated refund amount for unused period
|
|
63
|
-
*/
|
|
64
|
-
export function calculateProratedAmount({
|
|
65
|
-
amountPaid,
|
|
66
|
-
startDate,
|
|
67
|
-
endDate,
|
|
68
|
-
asOfDate = new Date(),
|
|
69
|
-
precision = 2,
|
|
70
|
-
}) {
|
|
71
|
-
if (!amountPaid || amountPaid <= 0) return 0;
|
|
72
|
-
|
|
73
|
-
const start = new Date(startDate);
|
|
74
|
-
const end = new Date(endDate);
|
|
75
|
-
const asOf = new Date(asOfDate);
|
|
76
|
-
|
|
77
|
-
const totalMs = end - start;
|
|
78
|
-
if (totalMs <= 0) return 0;
|
|
79
|
-
|
|
80
|
-
const remainingMs = Math.max(0, end - asOf);
|
|
81
|
-
if (remainingMs <= 0) return 0;
|
|
82
|
-
|
|
83
|
-
const ratio = remainingMs / totalMs;
|
|
84
|
-
const amount = amountPaid * ratio;
|
|
85
|
-
|
|
86
|
-
const factor = 10 ** precision;
|
|
87
|
-
return Math.round(amount * factor) / factor;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Convert interval + count to duration/unit
|
|
92
|
-
*/
|
|
93
|
-
export function resolveIntervalToDuration(interval = 'month', intervalCount = 1) {
|
|
94
|
-
const normalized = (interval || 'month').toLowerCase();
|
|
95
|
-
const count = Number(intervalCount) > 0 ? Number(intervalCount) : 1;
|
|
96
|
-
|
|
97
|
-
switch (normalized) {
|
|
98
|
-
case 'year':
|
|
99
|
-
case 'years':
|
|
100
|
-
return { duration: count, unit: 'years' };
|
|
101
|
-
case 'week':
|
|
102
|
-
case 'weeks':
|
|
103
|
-
return { duration: count, unit: 'weeks' };
|
|
104
|
-
case 'quarter':
|
|
105
|
-
case 'quarters':
|
|
106
|
-
return { duration: count * 3, unit: 'months' };
|
|
107
|
-
case 'day':
|
|
108
|
-
case 'days':
|
|
109
|
-
return { duration: count, unit: 'days' };
|
|
110
|
-
case 'month':
|
|
111
|
-
case 'months':
|
|
112
|
-
default:
|
|
113
|
-
return { duration: count, unit: 'months' };
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export default {
|
|
118
|
-
addDuration,
|
|
119
|
-
calculatePeriodRange,
|
|
120
|
-
calculateProratedAmount,
|
|
121
|
-
resolveIntervalToDuration,
|
|
122
|
-
};
|
|
123
|
-
|
|
@@ -1,254 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Transaction Type Detection & Classification
|
|
3
|
-
*
|
|
4
|
-
* Distinguishes between:
|
|
5
|
-
* - Monetization-managed transactions (library-controlled, strict rules)
|
|
6
|
-
* - Manual admin transactions (flexible, admin-controlled)
|
|
7
|
-
*
|
|
8
|
-
* @module @classytic/revenue/utils/transaction-type
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Transaction types with different protection rules
|
|
13
|
-
*/
|
|
14
|
-
export const TRANSACTION_TYPE = {
|
|
15
|
-
MONETIZATION: 'monetization', // Library-managed (subscriptions, purchases)
|
|
16
|
-
MANUAL: 'manual', // Admin-managed (expenses, income, adjustments)
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Default monetization categories
|
|
21
|
-
* Users can extend this via config.categoryMappings
|
|
22
|
-
*/
|
|
23
|
-
const DEFAULT_MONETIZATION_CATEGORIES = [
|
|
24
|
-
'subscription',
|
|
25
|
-
'purchase',
|
|
26
|
-
];
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Check if category is monetization-related
|
|
30
|
-
* @param {string} category - Transaction category
|
|
31
|
-
* @param {Array<string>} additionalCategories - Additional categories from user config
|
|
32
|
-
* @returns {boolean}
|
|
33
|
-
*/
|
|
34
|
-
function isMonetizationCategory(category, additionalCategories = []) {
|
|
35
|
-
const allCategories = [...DEFAULT_MONETIZATION_CATEGORIES, ...additionalCategories];
|
|
36
|
-
return allCategories.includes(category);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Check if transaction is monetization-managed
|
|
41
|
-
*
|
|
42
|
-
* Monetization-managed means:
|
|
43
|
-
* - Created through subscription/purchase flows via the library
|
|
44
|
-
* - Status controlled by payment webhooks/verification
|
|
45
|
-
* - Amount/commission calculated by library
|
|
46
|
-
* - Protected fields: status, amount, commission, gateway, verifiedAt, verifiedBy
|
|
47
|
-
*
|
|
48
|
-
* @param {Object} transaction - Transaction document or data
|
|
49
|
-
* @param {Object} options - Options
|
|
50
|
-
* @param {Array<string>} options.targetModels - Target models from config (default: ['Subscription', 'Membership'])
|
|
51
|
-
* @param {Array<string>} options.additionalCategories - Additional categories from user config
|
|
52
|
-
* @returns {boolean}
|
|
53
|
-
*/
|
|
54
|
-
export function isMonetizationTransaction(transaction, options = {}) {
|
|
55
|
-
const {
|
|
56
|
-
targetModels = ['Subscription', 'Membership'],
|
|
57
|
-
additionalCategories = [],
|
|
58
|
-
} = options;
|
|
59
|
-
|
|
60
|
-
// Check 1: Has referenceModel from registered models
|
|
61
|
-
if (transaction.referenceModel && targetModels.includes(transaction.referenceModel)) {
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Check 2: Category is monetization-related
|
|
66
|
-
if (transaction.category) {
|
|
67
|
-
return isMonetizationCategory(transaction.category, additionalCategories);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Check if transaction is manual admin transaction
|
|
75
|
-
*
|
|
76
|
-
* Manual transactions:
|
|
77
|
-
* - Created directly by admins for operational expenses/income
|
|
78
|
-
* - Can be self-verified by admins
|
|
79
|
-
* - More flexible updates allowed
|
|
80
|
-
* - No commission/gateway complexity
|
|
81
|
-
*
|
|
82
|
-
* @param {Object} transaction - Transaction document or data
|
|
83
|
-
* @param {Object} options - Options (same as isMonetizationTransaction)
|
|
84
|
-
* @returns {boolean}
|
|
85
|
-
*/
|
|
86
|
-
export function isManualTransaction(transaction, options = {}) {
|
|
87
|
-
return !isMonetizationTransaction(transaction, options);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Get transaction type
|
|
92
|
-
*
|
|
93
|
-
* @param {Object} transaction - Transaction document or data
|
|
94
|
-
* @param {Object} options - Options (same as isMonetizationTransaction)
|
|
95
|
-
* @returns {string} TRANSACTION_TYPE.MONETIZATION or TRANSACTION_TYPE.MANUAL
|
|
96
|
-
*/
|
|
97
|
-
export function getTransactionType(transaction, options = {}) {
|
|
98
|
-
return isMonetizationTransaction(transaction, options)
|
|
99
|
-
? TRANSACTION_TYPE.MONETIZATION
|
|
100
|
-
: TRANSACTION_TYPE.MANUAL;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Protected fields for monetization transactions
|
|
105
|
-
* These fields cannot be updated directly by admins
|
|
106
|
-
*/
|
|
107
|
-
export const PROTECTED_MONETIZATION_FIELDS = [
|
|
108
|
-
'status',
|
|
109
|
-
'amount',
|
|
110
|
-
'platformCommission',
|
|
111
|
-
'netAmount',
|
|
112
|
-
'verifiedAt',
|
|
113
|
-
'verifiedBy',
|
|
114
|
-
'gateway',
|
|
115
|
-
'webhook',
|
|
116
|
-
'metadata.commission',
|
|
117
|
-
'metadata.gateway',
|
|
118
|
-
'type',
|
|
119
|
-
'category',
|
|
120
|
-
'referenceModel',
|
|
121
|
-
'referenceId',
|
|
122
|
-
];
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Editable fields for monetization transactions (before verification)
|
|
126
|
-
* These fields can be updated by frontend/customer before payment is verified
|
|
127
|
-
*/
|
|
128
|
-
export const EDITABLE_MONETIZATION_FIELDS_PRE_VERIFICATION = [
|
|
129
|
-
'reference',
|
|
130
|
-
'paymentDetails',
|
|
131
|
-
'notes',
|
|
132
|
-
];
|
|
133
|
-
|
|
134
|
-
/**
|
|
135
|
-
* Allowed fields for manual transaction creation
|
|
136
|
-
*/
|
|
137
|
-
export const MANUAL_TRANSACTION_CREATE_FIELDS = [
|
|
138
|
-
'organizationId',
|
|
139
|
-
'type',
|
|
140
|
-
'category',
|
|
141
|
-
'amount',
|
|
142
|
-
'method',
|
|
143
|
-
'reference',
|
|
144
|
-
'paymentDetails',
|
|
145
|
-
'notes',
|
|
146
|
-
'date', // Transaction date (can be backdated)
|
|
147
|
-
'description',
|
|
148
|
-
];
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Allowed fields for manual transaction updates
|
|
152
|
-
*/
|
|
153
|
-
export const MANUAL_TRANSACTION_UPDATE_FIELDS = [
|
|
154
|
-
'amount',
|
|
155
|
-
'method',
|
|
156
|
-
'reference',
|
|
157
|
-
'paymentDetails',
|
|
158
|
-
'notes',
|
|
159
|
-
'date',
|
|
160
|
-
'description',
|
|
161
|
-
];
|
|
162
|
-
|
|
163
|
-
/**
|
|
164
|
-
* Get allowed update fields based on transaction type and status
|
|
165
|
-
*
|
|
166
|
-
* @param {Object} transaction - Transaction document
|
|
167
|
-
* @param {Object} options - Options for transaction type detection
|
|
168
|
-
* @returns {Array<string>} Allowed field names
|
|
169
|
-
*/
|
|
170
|
-
export function getAllowedUpdateFields(transaction, options = {}) {
|
|
171
|
-
const type = getTransactionType(transaction, options);
|
|
172
|
-
|
|
173
|
-
if (type === TRANSACTION_TYPE.MONETIZATION) {
|
|
174
|
-
// Monetization transactions: only allow pre-verification edits
|
|
175
|
-
if (transaction.status === 'pending') {
|
|
176
|
-
return EDITABLE_MONETIZATION_FIELDS_PRE_VERIFICATION;
|
|
177
|
-
}
|
|
178
|
-
// After verification, no direct updates allowed
|
|
179
|
-
return [];
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
// Manual transactions: more flexible
|
|
183
|
-
if (transaction.status === 'verified' || transaction.status === 'completed') {
|
|
184
|
-
// Once verified/completed, only notes can be updated
|
|
185
|
-
return ['notes'];
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Pending manual transactions can be fully edited
|
|
189
|
-
return MANUAL_TRANSACTION_UPDATE_FIELDS;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* Validate if field update is allowed
|
|
194
|
-
*
|
|
195
|
-
* @param {Object} transaction - Transaction document
|
|
196
|
-
* @param {string} fieldName - Field being updated
|
|
197
|
-
* @param {Object} options - Options for transaction type detection
|
|
198
|
-
* @returns {Object} { allowed: boolean, reason?: string }
|
|
199
|
-
*/
|
|
200
|
-
export function validateFieldUpdate(transaction, fieldName, options = {}) {
|
|
201
|
-
const allowedFields = getAllowedUpdateFields(transaction, options);
|
|
202
|
-
|
|
203
|
-
if (allowedFields.includes(fieldName)) {
|
|
204
|
-
return { allowed: true };
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const type = getTransactionType(transaction, options);
|
|
208
|
-
|
|
209
|
-
if (type === TRANSACTION_TYPE.MONETIZATION) {
|
|
210
|
-
if (PROTECTED_MONETIZATION_FIELDS.includes(fieldName)) {
|
|
211
|
-
return {
|
|
212
|
-
allowed: false,
|
|
213
|
-
reason: `Field "${fieldName}" is protected for monetization transactions. Updates must go through payment flow.`,
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
return {
|
|
219
|
-
allowed: false,
|
|
220
|
-
reason: `Field "${fieldName}" cannot be updated for ${transaction.status} transactions.`,
|
|
221
|
-
};
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
/**
|
|
225
|
-
* Check if transaction can be self-verified by admin
|
|
226
|
-
*
|
|
227
|
-
* @param {Object} transaction - Transaction document
|
|
228
|
-
* @param {Object} options - Options for transaction type detection
|
|
229
|
-
* @returns {boolean}
|
|
230
|
-
*/
|
|
231
|
-
export function canSelfVerify(transaction, options = {}) {
|
|
232
|
-
const type = getTransactionType(transaction, options);
|
|
233
|
-
|
|
234
|
-
// Only manual transactions can be self-verified
|
|
235
|
-
if (type === TRANSACTION_TYPE.MANUAL) {
|
|
236
|
-
return transaction.status === 'pending';
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return false;
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
export default {
|
|
243
|
-
TRANSACTION_TYPE,
|
|
244
|
-
isMonetizationTransaction,
|
|
245
|
-
isManualTransaction,
|
|
246
|
-
getTransactionType,
|
|
247
|
-
PROTECTED_MONETIZATION_FIELDS,
|
|
248
|
-
EDITABLE_MONETIZATION_FIELDS_PRE_VERIFICATION,
|
|
249
|
-
MANUAL_TRANSACTION_CREATE_FIELDS,
|
|
250
|
-
MANUAL_TRANSACTION_UPDATE_FIELDS,
|
|
251
|
-
getAllowedUpdateFields,
|
|
252
|
-
validateFieldUpdate,
|
|
253
|
-
canSelfVerify,
|
|
254
|
-
};
|