@venturekit-pro/billing 0.0.0-dev.20260323005827

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.
Files changed (47) hide show
  1. package/LICENSE +19 -0
  2. package/README.md +93 -0
  3. package/dist/gating/feature-gate.d.ts +53 -0
  4. package/dist/gating/feature-gate.d.ts.map +1 -0
  5. package/dist/gating/feature-gate.js +92 -0
  6. package/dist/gating/feature-gate.js.map +1 -0
  7. package/dist/index.d.ts +37 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +43 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/invoices/generator.d.ts +70 -0
  12. package/dist/invoices/generator.d.ts.map +1 -0
  13. package/dist/invoices/generator.js +190 -0
  14. package/dist/invoices/generator.js.map +1 -0
  15. package/dist/plans/index.d.ts +124 -0
  16. package/dist/plans/index.d.ts.map +1 -0
  17. package/dist/plans/index.js +116 -0
  18. package/dist/plans/index.js.map +1 -0
  19. package/dist/subscriptions/manager.d.ts +98 -0
  20. package/dist/subscriptions/manager.d.ts.map +1 -0
  21. package/dist/subscriptions/manager.js +245 -0
  22. package/dist/subscriptions/manager.js.map +1 -0
  23. package/dist/types/config.d.ts +36 -0
  24. package/dist/types/config.d.ts.map +1 -0
  25. package/dist/types/config.js +8 -0
  26. package/dist/types/config.js.map +1 -0
  27. package/dist/types/index.d.ts +8 -0
  28. package/dist/types/index.d.ts.map +1 -0
  29. package/dist/types/index.js +8 -0
  30. package/dist/types/index.js.map +1 -0
  31. package/dist/types/invoice.d.ts +78 -0
  32. package/dist/types/invoice.d.ts.map +1 -0
  33. package/dist/types/invoice.js +5 -0
  34. package/dist/types/invoice.js.map +1 -0
  35. package/dist/types/payment.d.ts +33 -0
  36. package/dist/types/payment.d.ts.map +1 -0
  37. package/dist/types/payment.js +8 -0
  38. package/dist/types/payment.js.map +1 -0
  39. package/dist/types/subscription.d.ts +87 -0
  40. package/dist/types/subscription.d.ts.map +1 -0
  41. package/dist/types/subscription.js +5 -0
  42. package/dist/types/subscription.js.map +1 -0
  43. package/dist/usage/tracker.d.ts +75 -0
  44. package/dist/usage/tracker.d.ts.map +1 -0
  45. package/dist/usage/tracker.js +91 -0
  46. package/dist/usage/tracker.js.map +1 -0
  47. package/package.json +39 -0
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Plans & Feature Mapping
3
+ *
4
+ * Defines plans with feature limits and provides a generic mapping
5
+ * between app features and invoice line items.
6
+ *
7
+ * The feature_key is the bridge:
8
+ * - billing_plan_features.feature_key defines what a plan includes
9
+ * - billing_invoice_items.feature_key links usage to the line item
10
+ *
11
+ * This is generic enough to cover most apps:
12
+ * - SaaS seats: feature_key = 'seats'
13
+ * - Storage: feature_key = 'storage_gb'
14
+ * - API calls: feature_key = 'api_calls'
15
+ * - Custom: feature_key = 'whatever_you_need'
16
+ */
17
+ import type { BillingInterval } from '../types/index.js';
18
+ /**
19
+ * A plan feature with its limit and pricing for invoicing.
20
+ */
21
+ export interface PlanFeature {
22
+ /** Unique key identifying the feature (e.g. 'seats', 'storage_gb') */
23
+ featureKey: string;
24
+ /** Whether this feature is enabled in this plan */
25
+ enabled: boolean;
26
+ /** Usage limit (null = unlimited) */
27
+ limit?: number | null;
28
+ /** Unit price for overage/metered billing (in smallest currency unit) */
29
+ unitPrice?: number;
30
+ /** Human-readable description for invoice line items */
31
+ description: string;
32
+ }
33
+ /**
34
+ * A plan definition with its features.
35
+ */
36
+ export interface PlanDefinition {
37
+ id: string;
38
+ name: string;
39
+ description?: string;
40
+ price: number;
41
+ currency: string;
42
+ interval: BillingInterval;
43
+ intervalCount?: number;
44
+ trialDays?: number;
45
+ active: boolean;
46
+ features: PlanFeature[];
47
+ }
48
+ /**
49
+ * Define a set of plans for your application.
50
+ *
51
+ * @example
52
+ * ```typescript
53
+ * const plans = definePlans([
54
+ * {
55
+ * id: 'free',
56
+ * name: 'Free',
57
+ * price: 0,
58
+ * currency: 'USD',
59
+ * interval: 'month',
60
+ * active: true,
61
+ * features: [
62
+ * { featureKey: 'seats', enabled: true, limit: 1, description: 'Team seats' },
63
+ * { featureKey: 'storage_gb', enabled: true, limit: 1, description: 'Storage (GB)' },
64
+ * { featureKey: 'api_calls', enabled: true, limit: 1000, description: 'API calls / month' },
65
+ * ],
66
+ * },
67
+ * {
68
+ * id: 'pro',
69
+ * name: 'Pro',
70
+ * price: 2900, // $29.00
71
+ * currency: 'USD',
72
+ * interval: 'month',
73
+ * active: true,
74
+ * features: [
75
+ * { featureKey: 'seats', enabled: true, limit: 10, unitPrice: 500, description: 'Team seats' },
76
+ * { featureKey: 'storage_gb', enabled: true, limit: 50, description: 'Storage (GB)' },
77
+ * { featureKey: 'api_calls', enabled: true, limit: 100000, description: 'API calls / month' },
78
+ * { featureKey: 'priority_support', enabled: true, description: 'Priority support' },
79
+ * ],
80
+ * },
81
+ * ]);
82
+ * ```
83
+ */
84
+ export declare function definePlans(plans: PlanDefinition[]): PlanDefinition[];
85
+ /**
86
+ * Look up a feature limit for a given plan.
87
+ * Returns the limit (number), null (unlimited), or undefined (feature not in plan).
88
+ */
89
+ export declare function getFeatureLimit(plan: PlanDefinition, featureKey: string): number | null | undefined;
90
+ /**
91
+ * Check if a feature is enabled for a plan.
92
+ */
93
+ export declare function hasFeature(plan: PlanDefinition, featureKey: string): boolean;
94
+ /**
95
+ * Map feature usage to invoice line items.
96
+ *
97
+ * Given a plan and a usage record (featureKey → quantity used),
98
+ * generates invoice line items. This is the bridge between
99
+ * "what the customer did" and "what we charge them".
100
+ *
101
+ * For features within limits, generates a line item at the plan's base rate.
102
+ * For metered/overage features with unitPrice, generates overage items.
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * const items = mapUsageToLineItems(proPlan, {
107
+ * seats: 12, // 10 included, 2 overage at $5 each
108
+ * storage_gb: 30, // within limit
109
+ * api_calls: 95000, // within limit
110
+ * });
111
+ * // Returns:
112
+ * // [
113
+ * // { featureKey: 'seats', description: 'Team seats (2 extra)', quantity: 2, unitPrice: 500, amount: 1000 },
114
+ * // ]
115
+ * ```
116
+ */
117
+ export declare function mapUsageToLineItems(plan: PlanDefinition, usage: Record<string, number>): Array<{
118
+ featureKey: string;
119
+ description: string;
120
+ quantity: number;
121
+ unitPrice: number;
122
+ amount: number;
123
+ }>;
124
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plans/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAoB,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAE3E;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,sEAAsE;IACtE,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,OAAO,EAAE,OAAO,CAAC;IACjB,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,eAAe,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,cAAc,EAAE,CAErE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,cAAc,EACpB,UAAU,EAAE,MAAM,GACjB,MAAM,GAAG,IAAI,GAAG,SAAS,CAI3B;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAG5E;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,cAAc,EACpB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,KAAK,CAAC;IACP,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC,CA2BD"}
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Plans & Feature Mapping
3
+ *
4
+ * Defines plans with feature limits and provides a generic mapping
5
+ * between app features and invoice line items.
6
+ *
7
+ * The feature_key is the bridge:
8
+ * - billing_plan_features.feature_key defines what a plan includes
9
+ * - billing_invoice_items.feature_key links usage to the line item
10
+ *
11
+ * This is generic enough to cover most apps:
12
+ * - SaaS seats: feature_key = 'seats'
13
+ * - Storage: feature_key = 'storage_gb'
14
+ * - API calls: feature_key = 'api_calls'
15
+ * - Custom: feature_key = 'whatever_you_need'
16
+ */
17
+ /**
18
+ * Define a set of plans for your application.
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const plans = definePlans([
23
+ * {
24
+ * id: 'free',
25
+ * name: 'Free',
26
+ * price: 0,
27
+ * currency: 'USD',
28
+ * interval: 'month',
29
+ * active: true,
30
+ * features: [
31
+ * { featureKey: 'seats', enabled: true, limit: 1, description: 'Team seats' },
32
+ * { featureKey: 'storage_gb', enabled: true, limit: 1, description: 'Storage (GB)' },
33
+ * { featureKey: 'api_calls', enabled: true, limit: 1000, description: 'API calls / month' },
34
+ * ],
35
+ * },
36
+ * {
37
+ * id: 'pro',
38
+ * name: 'Pro',
39
+ * price: 2900, // $29.00
40
+ * currency: 'USD',
41
+ * interval: 'month',
42
+ * active: true,
43
+ * features: [
44
+ * { featureKey: 'seats', enabled: true, limit: 10, unitPrice: 500, description: 'Team seats' },
45
+ * { featureKey: 'storage_gb', enabled: true, limit: 50, description: 'Storage (GB)' },
46
+ * { featureKey: 'api_calls', enabled: true, limit: 100000, description: 'API calls / month' },
47
+ * { featureKey: 'priority_support', enabled: true, description: 'Priority support' },
48
+ * ],
49
+ * },
50
+ * ]);
51
+ * ```
52
+ */
53
+ export function definePlans(plans) {
54
+ return plans;
55
+ }
56
+ /**
57
+ * Look up a feature limit for a given plan.
58
+ * Returns the limit (number), null (unlimited), or undefined (feature not in plan).
59
+ */
60
+ export function getFeatureLimit(plan, featureKey) {
61
+ const feature = plan.features.find((f) => f.featureKey === featureKey);
62
+ if (!feature || !feature.enabled)
63
+ return undefined;
64
+ return feature.limit ?? null;
65
+ }
66
+ /**
67
+ * Check if a feature is enabled for a plan.
68
+ */
69
+ export function hasFeature(plan, featureKey) {
70
+ const feature = plan.features.find((f) => f.featureKey === featureKey);
71
+ return feature?.enabled ?? false;
72
+ }
73
+ /**
74
+ * Map feature usage to invoice line items.
75
+ *
76
+ * Given a plan and a usage record (featureKey → quantity used),
77
+ * generates invoice line items. This is the bridge between
78
+ * "what the customer did" and "what we charge them".
79
+ *
80
+ * For features within limits, generates a line item at the plan's base rate.
81
+ * For metered/overage features with unitPrice, generates overage items.
82
+ *
83
+ * @example
84
+ * ```typescript
85
+ * const items = mapUsageToLineItems(proPlan, {
86
+ * seats: 12, // 10 included, 2 overage at $5 each
87
+ * storage_gb: 30, // within limit
88
+ * api_calls: 95000, // within limit
89
+ * });
90
+ * // Returns:
91
+ * // [
92
+ * // { featureKey: 'seats', description: 'Team seats (2 extra)', quantity: 2, unitPrice: 500, amount: 1000 },
93
+ * // ]
94
+ * ```
95
+ */
96
+ export function mapUsageToLineItems(plan, usage) {
97
+ const items = [];
98
+ for (const [featureKey, used] of Object.entries(usage)) {
99
+ const feature = plan.features.find((f) => f.featureKey === featureKey);
100
+ if (!feature || !feature.enabled)
101
+ continue;
102
+ // If feature has a limit and usage exceeds it, and there's a unit price for overage
103
+ if (feature.limit != null && used > feature.limit && feature.unitPrice) {
104
+ const overage = used - feature.limit;
105
+ items.push({
106
+ featureKey,
107
+ description: `${feature.description} (${overage} extra)`,
108
+ quantity: overage,
109
+ unitPrice: feature.unitPrice,
110
+ amount: overage * feature.unitPrice,
111
+ });
112
+ }
113
+ }
114
+ return items;
115
+ }
116
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/plans/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAoCH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,IAAoB,EACpB,UAAkB;IAElB,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;IACvE,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO;QAAE,OAAO,SAAS,CAAC;IACnD,OAAO,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAoB,EAAE,UAAkB;IACjE,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;IACvE,OAAO,OAAO,EAAE,OAAO,IAAI,KAAK,CAAC;AACnC,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAoB,EACpB,KAA6B;IAQ7B,MAAM,KAAK,GAMN,EAAE,CAAC;IAER,KAAK,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACvD,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC;QACvE,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO;YAAE,SAAS;QAE3C,oFAAoF;QACpF,IAAI,OAAO,CAAC,KAAK,IAAI,IAAI,IAAI,IAAI,GAAG,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;YACvE,MAAM,OAAO,GAAG,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC;gBACT,UAAU;gBACV,WAAW,EAAE,GAAG,OAAO,CAAC,WAAW,KAAK,OAAO,SAAS;gBACxD,QAAQ,EAAE,OAAO;gBACjB,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS;aACpC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * VentureKit Subscription Manager
3
+ *
4
+ * Manages subscription lifecycle: create, upgrade, downgrade,
5
+ * cancel, pause, resume, and trial management.
6
+ *
7
+ * Storage backend is pluggable via SubscriptionStore interface.
8
+ */
9
+ import type { Subscription, CreateSubscriptionInput } from '../types/subscription.js';
10
+ import type { PlanDefinition } from '../plans/index.js';
11
+ /**
12
+ * Subscription store interface
13
+ */
14
+ export interface SubscriptionStore {
15
+ create(subscription: Subscription): Promise<Subscription>;
16
+ get(id: string): Promise<Subscription | null>;
17
+ getByCustomer(customerId: string): Promise<Subscription | null>;
18
+ update(id: string, updates: Partial<Subscription>): Promise<void>;
19
+ delete(id: string): Promise<void>;
20
+ }
21
+ /**
22
+ * Subscription manager options
23
+ */
24
+ export interface SubscriptionManagerOptions {
25
+ store: SubscriptionStore;
26
+ plans: PlanDefinition[];
27
+ /** Default trial days if plan doesn't specify */
28
+ defaultTrialDays?: number;
29
+ }
30
+ /**
31
+ * Proration calculation result
32
+ */
33
+ export interface ProrationResult {
34
+ /** Credit for unused time on current plan */
35
+ credit: number;
36
+ /** Charge for remaining time on new plan */
37
+ charge: number;
38
+ /** Net amount (charge - credit, can be negative) */
39
+ netAmount: number;
40
+ /** Days remaining in current period */
41
+ daysRemaining: number;
42
+ /** Total days in current period */
43
+ totalDays: number;
44
+ }
45
+ /**
46
+ * Calculate proration for a mid-cycle plan change
47
+ */
48
+ export declare function calculateProration(currentPlan: PlanDefinition, newPlan: PlanDefinition, periodStart: Date, periodEnd: Date, changeDate?: Date): ProrationResult;
49
+ /**
50
+ * Create a subscription manager
51
+ */
52
+ export declare function createSubscriptionManager(options: SubscriptionManagerOptions): {
53
+ /**
54
+ * Create a new subscription
55
+ */
56
+ create(input: CreateSubscriptionInput): Promise<Subscription>;
57
+ /**
58
+ * Get a subscription by ID
59
+ */
60
+ get(id: string): Promise<Subscription | null>;
61
+ /**
62
+ * Get a customer's active subscription
63
+ */
64
+ getByCustomer(customerId: string): Promise<Subscription | null>;
65
+ /**
66
+ * Change plan (upgrade or downgrade)
67
+ */
68
+ changePlan(subscriptionId: string, newPlanId: string, options?: {
69
+ immediate?: boolean;
70
+ }): Promise<{
71
+ subscription: Subscription;
72
+ proration?: ProrationResult;
73
+ }>;
74
+ /**
75
+ * Cancel subscription
76
+ */
77
+ cancel(subscriptionId: string, options?: {
78
+ immediate?: boolean;
79
+ reason?: string;
80
+ }): Promise<Subscription>;
81
+ /**
82
+ * Pause subscription
83
+ */
84
+ pause(subscriptionId: string): Promise<Subscription>;
85
+ /**
86
+ * Resume a paused subscription
87
+ */
88
+ resume(subscriptionId: string): Promise<Subscription>;
89
+ /**
90
+ * Calculate proration for a plan change
91
+ */
92
+ previewProration(subscriptionId: string, newPlanId: string): Promise<ProrationResult>;
93
+ };
94
+ /**
95
+ * In-memory subscription store (for dev/testing)
96
+ */
97
+ export declare function createMemorySubscriptionStore(): SubscriptionStore;
98
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/subscriptions/manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,YAAY,EAEZ,uBAAuB,EAExB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC1D,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAC9C,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAChE,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClE,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,KAAK,EAAE,iBAAiB,CAAC;IACzB,KAAK,EAAE,cAAc,EAAE,CAAC;IACxB,iDAAiD;IACjD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,MAAM,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,SAAS,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,aAAa,EAAE,MAAM,CAAC;IACtB,mCAAmC;IACnC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,cAAc,EAC3B,OAAO,EAAE,cAAc,EACvB,WAAW,EAAE,IAAI,EACjB,SAAS,EAAE,IAAI,EACf,UAAU,GAAE,IAAiB,GAC5B,eAAe,CAqBjB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,0BAA0B;IAezE;;OAEG;kBACiB,uBAAuB,GAAG,OAAO,CAAC,YAAY,CAAC;IAmDnE;;OAEG;YACW,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAInD;;OAEG;8BAC6B,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC;IAIrE;;OAEG;+BAEe,MAAM,aACX,MAAM,YACP;QAAE,SAAS,CAAC,EAAE,OAAO,CAAA;KAAE,GAChC,OAAO,CAAC;QAAE,YAAY,EAAE,YAAY,CAAC;QAAC,SAAS,CAAC,EAAE,eAAe,CAAA;KAAE,CAAC;IAyCvE;;OAEG;2BAEe,MAAM,YACZ;QAAE,SAAS,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GACjD,OAAO,CAAC,YAAY,CAAC;IA2BxB;;OAEG;0BACyB,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAa1D;;OAEG;2BAC0B,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAa3D;;OAEG;qCAEe,MAAM,aACX,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC;EAe9B;AAED;;GAEG;AACH,wBAAgB,6BAA6B,IAAI,iBAAiB,CA6BjE"}
@@ -0,0 +1,245 @@
1
+ /**
2
+ * VentureKit Subscription Manager
3
+ *
4
+ * Manages subscription lifecycle: create, upgrade, downgrade,
5
+ * cancel, pause, resume, and trial management.
6
+ *
7
+ * Storage backend is pluggable via SubscriptionStore interface.
8
+ */
9
+ /**
10
+ * Calculate proration for a mid-cycle plan change
11
+ */
12
+ export function calculateProration(currentPlan, newPlan, periodStart, periodEnd, changeDate = new Date()) {
13
+ const totalMs = periodEnd.getTime() - periodStart.getTime();
14
+ const elapsedMs = changeDate.getTime() - periodStart.getTime();
15
+ const remainingMs = totalMs - elapsedMs;
16
+ const totalDays = Math.max(1, Math.round(totalMs / (1000 * 60 * 60 * 24)));
17
+ const daysRemaining = Math.max(0, Math.round(remainingMs / (1000 * 60 * 60 * 24)));
18
+ const dailyRateCurrent = currentPlan.price / totalDays;
19
+ const dailyRateNew = newPlan.price / totalDays;
20
+ const credit = Math.round(dailyRateCurrent * daysRemaining);
21
+ const charge = Math.round(dailyRateNew * daysRemaining);
22
+ return {
23
+ credit,
24
+ charge,
25
+ netAmount: charge - credit,
26
+ daysRemaining,
27
+ totalDays,
28
+ };
29
+ }
30
+ /**
31
+ * Create a subscription manager
32
+ */
33
+ export function createSubscriptionManager(options) {
34
+ const { store, plans, defaultTrialDays } = options;
35
+ function getPlan(planId) {
36
+ const plan = plans.find(p => p.id === planId);
37
+ if (!plan)
38
+ throw new Error(`Plan '${planId}' not found`);
39
+ if (!plan.active)
40
+ throw new Error(`Plan '${planId}' is not active`);
41
+ return plan;
42
+ }
43
+ function generateId() {
44
+ return `sub-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
45
+ }
46
+ return {
47
+ /**
48
+ * Create a new subscription
49
+ */
50
+ async create(input) {
51
+ // Check for existing active subscription
52
+ const existing = await store.getByCustomer(input.customerId);
53
+ if (existing && !['canceled', 'unpaid'].includes(existing.status)) {
54
+ throw new Error(`Customer '${input.customerId}' already has an active subscription`);
55
+ }
56
+ const plan = getPlan(input.planId);
57
+ const now = new Date();
58
+ const trialDays = input.trialDays ?? plan.trialDays ?? defaultTrialDays ?? 0;
59
+ const isTrialing = trialDays > 0;
60
+ const periodEnd = new Date(now);
61
+ if (isTrialing) {
62
+ periodEnd.setDate(periodEnd.getDate() + trialDays);
63
+ }
64
+ else {
65
+ // Set period based on interval
66
+ switch (plan.interval) {
67
+ case 'day':
68
+ periodEnd.setDate(periodEnd.getDate() + (plan.intervalCount ?? 1));
69
+ break;
70
+ case 'week':
71
+ periodEnd.setDate(periodEnd.getDate() + 7 * (plan.intervalCount ?? 1));
72
+ break;
73
+ case 'month':
74
+ periodEnd.setMonth(periodEnd.getMonth() + (plan.intervalCount ?? 1));
75
+ break;
76
+ case 'year':
77
+ periodEnd.setFullYear(periodEnd.getFullYear() + (plan.intervalCount ?? 1));
78
+ break;
79
+ }
80
+ }
81
+ const subscription = {
82
+ id: generateId(),
83
+ customerId: input.customerId,
84
+ planId: input.planId,
85
+ status: isTrialing ? 'trialing' : 'active',
86
+ currentPeriodStart: now,
87
+ currentPeriodEnd: periodEnd,
88
+ cancelAtPeriodEnd: false,
89
+ trialStart: isTrialing ? now : undefined,
90
+ trialEnd: isTrialing ? periodEnd : undefined,
91
+ createdAt: now,
92
+ updatedAt: now,
93
+ metadata: input.metadata,
94
+ };
95
+ return store.create(subscription);
96
+ },
97
+ /**
98
+ * Get a subscription by ID
99
+ */
100
+ async get(id) {
101
+ return store.get(id);
102
+ },
103
+ /**
104
+ * Get a customer's active subscription
105
+ */
106
+ async getByCustomer(customerId) {
107
+ return store.getByCustomer(customerId);
108
+ },
109
+ /**
110
+ * Change plan (upgrade or downgrade)
111
+ */
112
+ async changePlan(subscriptionId, newPlanId, options) {
113
+ const sub = await store.get(subscriptionId);
114
+ if (!sub)
115
+ throw new Error(`Subscription '${subscriptionId}' not found`);
116
+ if (sub.status === 'canceled')
117
+ throw new Error('Cannot change plan on a canceled subscription');
118
+ const currentPlan = getPlan(sub.planId);
119
+ const newPlan = getPlan(newPlanId);
120
+ if (sub.planId === newPlanId) {
121
+ throw new Error('Already on this plan');
122
+ }
123
+ const immediate = options?.immediate ?? true;
124
+ if (immediate) {
125
+ const proration = calculateProration(currentPlan, newPlan, sub.currentPeriodStart, sub.currentPeriodEnd);
126
+ await store.update(subscriptionId, {
127
+ planId: newPlanId,
128
+ updatedAt: new Date(),
129
+ });
130
+ const updated = await store.get(subscriptionId);
131
+ return { subscription: updated, proration };
132
+ }
133
+ // Schedule change at period end (no proration)
134
+ await store.update(subscriptionId, {
135
+ metadata: { ...sub.metadata, pendingPlanId: newPlanId },
136
+ updatedAt: new Date(),
137
+ });
138
+ const updated = await store.get(subscriptionId);
139
+ return { subscription: updated };
140
+ },
141
+ /**
142
+ * Cancel subscription
143
+ */
144
+ async cancel(subscriptionId, options) {
145
+ const sub = await store.get(subscriptionId);
146
+ if (!sub)
147
+ throw new Error(`Subscription '${subscriptionId}' not found`);
148
+ if (sub.status === 'canceled')
149
+ throw new Error('Subscription is already canceled');
150
+ const immediate = options?.immediate ?? false;
151
+ const now = new Date();
152
+ if (immediate) {
153
+ await store.update(subscriptionId, {
154
+ status: 'canceled',
155
+ canceledAt: now,
156
+ cancelAtPeriodEnd: false,
157
+ updatedAt: now,
158
+ metadata: { ...sub.metadata, cancelReason: options?.reason },
159
+ });
160
+ }
161
+ else {
162
+ await store.update(subscriptionId, {
163
+ cancelAtPeriodEnd: true,
164
+ updatedAt: now,
165
+ metadata: { ...sub.metadata, cancelReason: options?.reason },
166
+ });
167
+ }
168
+ return (await store.get(subscriptionId));
169
+ },
170
+ /**
171
+ * Pause subscription
172
+ */
173
+ async pause(subscriptionId) {
174
+ const sub = await store.get(subscriptionId);
175
+ if (!sub)
176
+ throw new Error(`Subscription '${subscriptionId}' not found`);
177
+ if (sub.status !== 'active')
178
+ throw new Error('Can only pause active subscriptions');
179
+ await store.update(subscriptionId, {
180
+ status: 'paused',
181
+ updatedAt: new Date(),
182
+ });
183
+ return (await store.get(subscriptionId));
184
+ },
185
+ /**
186
+ * Resume a paused subscription
187
+ */
188
+ async resume(subscriptionId) {
189
+ const sub = await store.get(subscriptionId);
190
+ if (!sub)
191
+ throw new Error(`Subscription '${subscriptionId}' not found`);
192
+ if (sub.status !== 'paused')
193
+ throw new Error('Can only resume paused subscriptions');
194
+ await store.update(subscriptionId, {
195
+ status: 'active',
196
+ updatedAt: new Date(),
197
+ });
198
+ return (await store.get(subscriptionId));
199
+ },
200
+ /**
201
+ * Calculate proration for a plan change
202
+ */
203
+ async previewProration(subscriptionId, newPlanId) {
204
+ const sub = await store.get(subscriptionId);
205
+ if (!sub)
206
+ throw new Error(`Subscription '${subscriptionId}' not found`);
207
+ const currentPlan = getPlan(sub.planId);
208
+ const newPlan = getPlan(newPlanId);
209
+ return calculateProration(currentPlan, newPlan, sub.currentPeriodStart, sub.currentPeriodEnd);
210
+ },
211
+ };
212
+ }
213
+ /**
214
+ * In-memory subscription store (for dev/testing)
215
+ */
216
+ export function createMemorySubscriptionStore() {
217
+ const subscriptions = new Map();
218
+ return {
219
+ async create(subscription) {
220
+ subscriptions.set(subscription.id, { ...subscription });
221
+ return subscription;
222
+ },
223
+ async get(id) {
224
+ return subscriptions.get(id) ?? null;
225
+ },
226
+ async getByCustomer(customerId) {
227
+ for (const sub of subscriptions.values()) {
228
+ if (sub.customerId === customerId && sub.status !== 'canceled') {
229
+ return sub;
230
+ }
231
+ }
232
+ return null;
233
+ },
234
+ async update(id, updates) {
235
+ const existing = subscriptions.get(id);
236
+ if (existing) {
237
+ subscriptions.set(id, { ...existing, ...updates });
238
+ }
239
+ },
240
+ async delete(id) {
241
+ subscriptions.delete(id);
242
+ },
243
+ };
244
+ }
245
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/subscriptions/manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA+CH;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAChC,WAA2B,EAC3B,OAAuB,EACvB,WAAiB,EACjB,SAAe,EACf,aAAmB,IAAI,IAAI,EAAE;IAE7B,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC;IAC5D,MAAM,SAAS,GAAG,UAAU,CAAC,OAAO,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC;IAC/D,MAAM,WAAW,GAAG,OAAO,GAAG,SAAS,CAAC;IAExC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3E,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;IAEnF,MAAM,gBAAgB,GAAG,WAAW,CAAC,KAAK,GAAG,SAAS,CAAC;IACvD,MAAM,YAAY,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;IAE/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,gBAAgB,GAAG,aAAa,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,aAAa,CAAC,CAAC;IAExD,OAAO;QACL,MAAM;QACN,MAAM;QACN,SAAS,EAAE,MAAM,GAAG,MAAM;QAC1B,aAAa;QACb,SAAS;KACV,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,yBAAyB,CAAC,OAAmC;IAC3E,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC;IAEnD,SAAS,OAAO,CAAC,MAAc;QAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,aAAa,CAAC,CAAC;QACzD,IAAI,CAAC,IAAI,CAAC,MAAM;YAAE,MAAM,IAAI,KAAK,CAAC,SAAS,MAAM,iBAAiB,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC;IACd,CAAC;IAED,SAAS,UAAU;QACjB,OAAO,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IACvE,CAAC;IAED,OAAO;QACL;;WAEG;QACH,KAAK,CAAC,MAAM,CAAC,KAA8B;YACzC,yCAAyC;YACzC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAC7D,IAAI,QAAQ,IAAI,CAAC,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClE,MAAM,IAAI,KAAK,CAAC,aAAa,KAAK,CAAC,UAAU,sCAAsC,CAAC,CAAC;YACvF,CAAC;YAED,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACnC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,IAAI,gBAAgB,IAAI,CAAC,CAAC;YAC7E,MAAM,UAAU,GAAG,SAAS,GAAG,CAAC,CAAC;YAEjC,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC;YAChC,IAAI,UAAU,EAAE,CAAC;gBACf,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,CAAC;YACrD,CAAC;iBAAM,CAAC;gBACN,+BAA+B;gBAC/B,QAAQ,IAAI,CAAC,QAAQ,EAAE,CAAC;oBACtB,KAAK,KAAK;wBACR,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,CAAC;wBACnE,MAAM;oBACR,KAAK,MAAM;wBACT,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,CAAC;wBACvE,MAAM;oBACR,KAAK,OAAO;wBACV,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,CAAC;wBACrE,MAAM;oBACR,KAAK,MAAM;wBACT,SAAS,CAAC,WAAW,CAAC,SAAS,CAAC,WAAW,EAAE,GAAG,CAAC,IAAI,CAAC,aAAa,IAAI,CAAC,CAAC,CAAC,CAAC;wBAC3E,MAAM;gBACV,CAAC;YACH,CAAC;YAED,MAAM,YAAY,GAAiB;gBACjC,EAAE,EAAE,UAAU,EAAE;gBAChB,UAAU,EAAE,KAAK,CAAC,UAAU;gBAC5B,MAAM,EAAE,KAAK,CAAC,MAAM;gBACpB,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ;gBAC1C,kBAAkB,EAAE,GAAG;gBACvB,gBAAgB,EAAE,SAAS;gBAC3B,iBAAiB,EAAE,KAAK;gBACxB,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS;gBACxC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;gBAC5C,SAAS,EAAE,GAAG;gBACd,SAAS,EAAE,GAAG;gBACd,QAAQ,EAAE,KAAK,CAAC,QAAQ;aACzB,CAAC;YAEF,OAAO,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QACpC,CAAC;QAED;;WAEG;QACH,KAAK,CAAC,GAAG,CAAC,EAAU;YAClB,OAAO,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvB,CAAC;QAED;;WAEG;QACH,KAAK,CAAC,aAAa,CAAC,UAAkB;YACpC,OAAO,KAAK,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACzC,CAAC;QAED;;WAEG;QACH,KAAK,CAAC,UAAU,CACd,cAAsB,EACtB,SAAiB,EACjB,OAAiC;YAEjC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAC5C,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,cAAc,aAAa,CAAC,CAAC;YACxE,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU;gBAAE,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;YAEhG,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACxC,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;YAEnC,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;YAC1C,CAAC;YAED,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC;YAE7C,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,SAAS,GAAG,kBAAkB,CAClC,WAAW,EACX,OAAO,EACP,GAAG,CAAC,kBAAkB,EACtB,GAAG,CAAC,gBAAgB,CACrB,CAAC;gBAEF,MAAM,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE;oBACjC,MAAM,EAAE,SAAS;oBACjB,SAAS,EAAE,IAAI,IAAI,EAAE;iBACtB,CAAC,CAAC;gBAEH,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;gBAChD,OAAO,EAAE,YAAY,EAAE,OAAQ,EAAE,SAAS,EAAE,CAAC;YAC/C,CAAC;YAED,+CAA+C;YAC/C,MAAM,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE;gBACjC,QAAQ,EAAE,EAAE,GAAG,GAAG,CAAC,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE;gBACvD,SAAS,EAAE,IAAI,IAAI,EAAE;aACtB,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAChD,OAAO,EAAE,YAAY,EAAE,OAAQ,EAAE,CAAC;QACpC,CAAC;QAED;;WAEG;QACH,KAAK,CAAC,MAAM,CACV,cAAsB,EACtB,OAAkD;YAElD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAC5C,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,cAAc,aAAa,CAAC,CAAC;YACxE,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU;gBAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;YAEnF,MAAM,SAAS,GAAG,OAAO,EAAE,SAAS,IAAI,KAAK,CAAC;YAC9C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;YAEvB,IAAI,SAAS,EAAE,CAAC;gBACd,MAAM,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE;oBACjC,MAAM,EAAE,UAAU;oBAClB,UAAU,EAAE,GAAG;oBACf,iBAAiB,EAAE,KAAK;oBACxB,SAAS,EAAE,GAAG;oBACd,QAAQ,EAAE,EAAE,GAAG,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE;iBAC7D,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE;oBACjC,iBAAiB,EAAE,IAAI;oBACvB,SAAS,EAAE,GAAG;oBACd,QAAQ,EAAE,EAAE,GAAG,GAAG,CAAC,QAAQ,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE;iBAC7D,CAAC,CAAC;YACL,CAAC;YAED,OAAO,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAE,CAAC;QAC5C,CAAC;QAED;;WAEG;QACH,KAAK,CAAC,KAAK,CAAC,cAAsB;YAChC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAC5C,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,cAAc,aAAa,CAAC,CAAC;YACxE,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;YAEpF,MAAM,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE;gBACjC,MAAM,EAAE,QAAQ;gBAChB,SAAS,EAAE,IAAI,IAAI,EAAE;aACtB,CAAC,CAAC;YAEH,OAAO,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAE,CAAC;QAC5C,CAAC;QAED;;WAEG;QACH,KAAK,CAAC,MAAM,CAAC,cAAsB;YACjC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAC5C,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,cAAc,aAAa,CAAC,CAAC;YACxE,IAAI,GAAG,CAAC,MAAM,KAAK,QAAQ;gBAAE,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;YAErF,MAAM,KAAK,CAAC,MAAM,CAAC,cAAc,EAAE;gBACjC,MAAM,EAAE,QAAQ;gBAChB,SAAS,EAAE,IAAI,IAAI,EAAE;aACtB,CAAC,CAAC;YAEH,OAAO,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAE,CAAC;QAC5C,CAAC;QAED;;WAEG;QACH,KAAK,CAAC,gBAAgB,CACpB,cAAsB,EACtB,SAAiB;YAEjB,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;YAC5C,IAAI,CAAC,GAAG;gBAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,cAAc,aAAa,CAAC,CAAC;YAExE,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;YACxC,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;YAEnC,OAAO,kBAAkB,CACvB,WAAW,EACX,OAAO,EACP,GAAG,CAAC,kBAAkB,EACtB,GAAG,CAAC,gBAAgB,CACrB,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,6BAA6B;IAC3C,MAAM,aAAa,GAAG,IAAI,GAAG,EAAwB,CAAC;IAEtD,OAAO;QACL,KAAK,CAAC,MAAM,CAAC,YAAY;YACvB,aAAa,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,GAAG,YAAY,EAAE,CAAC,CAAC;YACxD,OAAO,YAAY,CAAC;QACtB,CAAC;QACD,KAAK,CAAC,GAAG,CAAC,EAAE;YACV,OAAO,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;QACvC,CAAC;QACD,KAAK,CAAC,aAAa,CAAC,UAAU;YAC5B,KAAK,MAAM,GAAG,IAAI,aAAa,CAAC,MAAM,EAAE,EAAE,CAAC;gBACzC,IAAI,GAAG,CAAC,UAAU,KAAK,UAAU,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,EAAE,CAAC;oBAC/D,OAAO,GAAG,CAAC;gBACb,CAAC;YACH,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO;YACtB,MAAM,QAAQ,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACvC,IAAI,QAAQ,EAAE,CAAC;gBACb,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,GAAG,QAAQ,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC;YACrD,CAAC;QACH,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,EAAE;YACb,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3B,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Billing Configuration Types
3
+ *
4
+ * This package handles invoicing, plans, usage tracking, and feature gating.
5
+ * Payment processing is NOT included — integrate any provider separately.
6
+ */
7
+ import type { SubscriptionPlan } from './subscription.js';
8
+ /**
9
+ * Billing configuration
10
+ */
11
+ export interface BillingConfig {
12
+ /** Default currency (ISO 4217) */
13
+ defaultCurrency: string;
14
+ /** Available plans */
15
+ plans?: SubscriptionPlan[];
16
+ /** Tax rate as percentage (e.g., 20 for 20%) */
17
+ taxRate?: number;
18
+ /** Tax ID label (e.g., "VAT", "ICE" for Morocco) */
19
+ taxIdLabel?: string;
20
+ /** Invoice number prefix (e.g., "INV-") */
21
+ invoicePrefix?: string;
22
+ /** Default payment terms in days (default: 30) */
23
+ paymentTermsDays?: number;
24
+ }
25
+ /**
26
+ * Billing config input (partial for overrides)
27
+ */
28
+ export interface BillingConfigInput {
29
+ defaultCurrency?: string;
30
+ plans?: SubscriptionPlan[];
31
+ taxRate?: number;
32
+ taxIdLabel?: string;
33
+ invoicePrefix?: string;
34
+ paymentTermsDays?: number;
35
+ }
36
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,kCAAkC;IAClC,eAAe,EAAE,MAAM,CAAC;IAExB,sBAAsB;IACtB,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAE3B,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,oDAAoD;IACpD,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB,kDAAkD;IAClD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Billing Configuration Types
3
+ *
4
+ * This package handles invoicing, plans, usage tracking, and feature gating.
5
+ * Payment processing is NOT included — integrate any provider separately.
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}