@qelos/sdk 4.0.0 → 4.1.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.
@@ -1,6 +1,36 @@
1
1
  import { QelosSDKOptions } from '../types';
2
2
  import BaseSDK from '../base-sdk';
3
- import { IPlan, ISubscription, IInvoice, ICoupon, BillableEntityType, SubscriptionStatus, InvoiceStatus } from '@qelos/global-types';
3
+ import { IPlan, ISubscription, IInvoice, ICoupon, BillableEntityType, SubscriptionStatus, InvoiceStatus, BillingCycle } from '@qelos/global-types';
4
+ export interface AdminCheckoutRequest {
5
+ planId: string;
6
+ billingCycle: BillingCycle;
7
+ /** When omitted, the authenticated user / default billable entity is used (same as public checkout). */
8
+ billableEntityType?: BillableEntityType;
9
+ billableEntityId?: string;
10
+ couponCode?: string;
11
+ successUrl?: string;
12
+ cancelUrl?: string;
13
+ /**
14
+ * Admin-only. For plans with `dynamic: true`, sets the `dynamicAmount` on the
15
+ * pending subscription before initiating checkout. Regular users cannot set this;
16
+ * use `setSubscriptionDynamicAmount()` + a separate `checkout()` call instead.
17
+ */
18
+ amount?: number;
19
+ }
20
+ export interface CreateSubscriptionData {
21
+ planId: string;
22
+ billingCycle: BillingCycle;
23
+ billableEntityType: BillableEntityType;
24
+ billableEntityId: string;
25
+ /** Required for plans with `dynamic: true` before checkout can be initiated. */
26
+ dynamicAmount?: number;
27
+ couponCode?: string;
28
+ }
29
+ export interface AdminCheckoutResponse {
30
+ subscriptionId: string;
31
+ checkoutUrl?: string;
32
+ clientToken?: string;
33
+ }
4
34
  export default class QlPaymentsAdmin extends BaseSDK {
5
35
  private options;
6
36
  constructor(options: QelosSDKOptions);
@@ -11,13 +41,29 @@ export default class QlPaymentsAdmin extends BaseSDK {
11
41
  createPlan(data: Omit<IPlan, '_id' | 'tenant' | 'created'>): Promise<IPlan>;
12
42
  updatePlan(planId: string, data: Partial<IPlan>): Promise<IPlan>;
13
43
  deletePlan(planId: string): Promise<IPlan>;
44
+ /**
45
+ * Start subscription checkout (same as `sdk.payments.checkout`, plus optional billable-entity overrides for admins).
46
+ * For plans with `dynamic: true`, `amount` is required.
47
+ */
48
+ checkout(params: AdminCheckoutRequest): Promise<AdminCheckoutResponse>;
14
49
  getSubscriptions(query?: {
15
50
  billableEntityType?: BillableEntityType;
16
51
  billableEntityId?: string;
17
52
  status?: SubscriptionStatus;
18
53
  }): Promise<ISubscription[]>;
19
54
  getSubscription(subscriptionId: string): Promise<ISubscription>;
55
+ /**
56
+ * Creates a pending subscription on behalf of any billable entity. Admins can
57
+ * also set `dynamicAmount` here for dynamic plans, making the subscription
58
+ * immediately ready for checkout.
59
+ */
60
+ createSubscription(data: CreateSubscriptionData): Promise<ISubscription>;
20
61
  cancelSubscription(subscriptionId: string): Promise<ISubscription>;
62
+ /**
63
+ * Sets or updates the dynamic amount for a pending subscription. Only admins
64
+ * can call this. Must be done before a user can complete checkout on a dynamic plan.
65
+ */
66
+ setSubscriptionDynamicAmount(subscriptionId: string, amount: number): Promise<ISubscription>;
21
67
  getInvoices(query?: {
22
68
  billableEntityType?: BillableEntityType;
23
69
  billableEntityId?: string;
@@ -30,6 +30,17 @@ export default class QlPaymentsAdmin extends BaseSDK {
30
30
  deletePlan(planId) {
31
31
  return this.callJsonApi(`/api/plans/${planId}`, { method: 'delete' });
32
32
  }
33
+ /**
34
+ * Start subscription checkout (same as `sdk.payments.checkout`, plus optional billable-entity overrides for admins).
35
+ * For plans with `dynamic: true`, `amount` is required.
36
+ */
37
+ checkout(params) {
38
+ return this.callJsonApi('/api/checkout', {
39
+ method: 'post',
40
+ headers: { 'content-type': 'application/json' },
41
+ body: JSON.stringify(params),
42
+ });
43
+ }
33
44
  // --- Subscriptions ---
34
45
  getSubscriptions(query) {
35
46
  const qs = query ? `?${new URLSearchParams(query)}` : '';
@@ -38,9 +49,32 @@ export default class QlPaymentsAdmin extends BaseSDK {
38
49
  getSubscription(subscriptionId) {
39
50
  return this.callJsonApi(`/api/subscriptions/${subscriptionId}`);
40
51
  }
52
+ /**
53
+ * Creates a pending subscription on behalf of any billable entity. Admins can
54
+ * also set `dynamicAmount` here for dynamic plans, making the subscription
55
+ * immediately ready for checkout.
56
+ */
57
+ createSubscription(data) {
58
+ return this.callJsonApi('/api/subscriptions', {
59
+ method: 'post',
60
+ headers: { 'content-type': 'application/json' },
61
+ body: JSON.stringify(data),
62
+ });
63
+ }
41
64
  cancelSubscription(subscriptionId) {
42
65
  return this.callJsonApi(`/api/subscriptions/${subscriptionId}/cancel`, { method: 'put' });
43
66
  }
67
+ /**
68
+ * Sets or updates the dynamic amount for a pending subscription. Only admins
69
+ * can call this. Must be done before a user can complete checkout on a dynamic plan.
70
+ */
71
+ setSubscriptionDynamicAmount(subscriptionId, amount) {
72
+ return this.callJsonApi(`/api/subscriptions/${subscriptionId}/dynamic-amount`, {
73
+ method: 'put',
74
+ headers: { 'content-type': 'application/json' },
75
+ body: JSON.stringify({ amount }),
76
+ });
77
+ }
44
78
  // --- Invoices ---
45
79
  getInvoices(query) {
46
80
  const qs = query ? `?${new URLSearchParams(query)}` : '';
@@ -1 +1 @@
1
- {"version":3,"file":"payments.js","sourceRoot":"","sources":["../../src/administrator/payments.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"payments.js","sourceRoot":"","sources":["../../src/administrator/payments.ts"],"names":[],"mappings":"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"}
@@ -2,11 +2,19 @@ import { QelosSDKOptions } from './types';
2
2
  import BaseSDK from './base-sdk';
3
3
  import { IPlan, ISubscription, IInvoice, ICoupon, BillingCycle } from '@qelos/global-types';
4
4
  export interface CheckoutRequest {
5
- planId: string;
6
- billingCycle: BillingCycle;
5
+ /** Required when not providing `subscriptionId`. Must be a non-dynamic plan. */
6
+ planId?: string;
7
+ /** Required when not providing `subscriptionId`. */
8
+ billingCycle?: BillingCycle;
7
9
  couponCode?: string;
8
10
  successUrl?: string;
9
11
  cancelUrl?: string;
12
+ /**
13
+ * Pre-created subscription ID. Required for dynamic plans — the admin must set
14
+ * `dynamicAmount` on the subscription before this checkout call will succeed.
15
+ * When provided, `planId` and `billingCycle` are ignored.
16
+ */
17
+ subscriptionId?: string;
10
18
  }
11
19
  export interface CheckoutResponse {
12
20
  subscriptionId: string;
@@ -22,6 +30,24 @@ export default class QlPayments extends BaseSDK {
22
30
  isActive?: boolean;
23
31
  }): Promise<IPlan[]>;
24
32
  getPlan(planId: string): Promise<IPlan>;
33
+ /**
34
+ * Creates a pending subscription for the authenticated user without initiating
35
+ * payment. Use this as the first step for any plan, and the only step before
36
+ * `checkout()` for dynamic plans (the admin must call `setSubscriptionDynamicAmount`
37
+ * before the user can complete checkout).
38
+ */
39
+ subscribeToPlan(planId: string, billingCycle: BillingCycle, couponCode?: string): Promise<ISubscription>;
40
+ /**
41
+ * Initiates a provider checkout session.
42
+ *
43
+ * **Static plans**: pass `planId` + `billingCycle` (a subscription is created
44
+ * inline).
45
+ *
46
+ * **Dynamic plans**: the user must first call `subscribeToPlan()` to create a
47
+ * pending subscription, then an admin must set the dynamic amount via
48
+ * `setSubscriptionDynamicAmount()`. Only then should this method be called with
49
+ * `subscriptionId` pointing to that pending subscription.
50
+ */
25
51
  checkout(params: CheckoutRequest): Promise<CheckoutResponse>;
26
52
  getMySubscription(): Promise<ISubscription>;
27
53
  cancelSubscription(subscriptionId: string): Promise<ISubscription>;
package/dist/payments.js CHANGED
@@ -11,6 +11,30 @@ export default class QlPayments extends BaseSDK {
11
11
  getPlan(planId) {
12
12
  return this.callJsonApi(`${this.relativePath}/plans/${planId}`);
13
13
  }
14
+ /**
15
+ * Creates a pending subscription for the authenticated user without initiating
16
+ * payment. Use this as the first step for any plan, and the only step before
17
+ * `checkout()` for dynamic plans (the admin must call `setSubscriptionDynamicAmount`
18
+ * before the user can complete checkout).
19
+ */
20
+ subscribeToPlan(planId, billingCycle, couponCode) {
21
+ return this.callJsonApi(`${this.relativePath}/subscriptions`, {
22
+ method: 'post',
23
+ headers: { 'content-type': 'application/json' },
24
+ body: JSON.stringify({ planId, billingCycle, couponCode }),
25
+ });
26
+ }
27
+ /**
28
+ * Initiates a provider checkout session.
29
+ *
30
+ * **Static plans**: pass `planId` + `billingCycle` (a subscription is created
31
+ * inline).
32
+ *
33
+ * **Dynamic plans**: the user must first call `subscribeToPlan()` to create a
34
+ * pending subscription, then an admin must set the dynamic amount via
35
+ * `setSubscriptionDynamicAmount()`. Only then should this method be called with
36
+ * `subscriptionId` pointing to that pending subscription.
37
+ */
14
38
  checkout(params) {
15
39
  return this.callJsonApi(`${this.relativePath}/checkout`, {
16
40
  method: 'post',
@@ -1 +1 @@
1
- {"version":3,"file":"payments.js","sourceRoot":"","sources":["../src/payments.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,YAAY,CAAC;AAmBjC,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IACrC,YAAY,GAAG,MAAM,CAAC;IAE9B,YAAY,OAAwB;QAClC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;IAED,QAAQ,CAAC,KAA8B;QACrC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,eAAe,CAAC,KAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC,WAAW,CAAU,GAAG,IAAI,CAAC,YAAY,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,CAAC,MAAc;QACpB,OAAO,IAAI,CAAC,WAAW,CAAQ,GAAG,IAAI,CAAC,YAAY,UAAU,MAAM,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,QAAQ,CAAC,MAAuB;QAC9B,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,WAAW,EAC/B;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;SAC7B,CACF,CAAC;IACJ,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,WAAW,CAAgB,GAAG,IAAI,CAAC,YAAY,mBAAmB,CAAC,CAAC;IAClF,CAAC;IAED,kBAAkB,CAAC,cAAsB;QACvC,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,kBAAkB,cAAc,SAAS,EAC7D,EAAE,MAAM,EAAE,KAAK,EAAE,CAClB,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,KAA2B;QACrC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,eAAe,CAAC,KAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC,WAAW,CAAa,GAAG,IAAI,CAAC,YAAY,YAAY,EAAE,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,UAAU,CAAC,SAAiB;QAC1B,OAAO,IAAI,CAAC,WAAW,CAAW,GAAG,IAAI,CAAC,YAAY,aAAa,SAAS,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,cAAc,CAAC,IAAY,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,mBAAmB,EACvC;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;SACvC,CACF,CAAC;IACJ,CAAC;CACF"}
1
+ {"version":3,"file":"payments.js","sourceRoot":"","sources":["../src/payments.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,YAAY,CAAC;AA2BjC,MAAM,CAAC,OAAO,OAAO,UAAW,SAAQ,OAAO;IACrC,YAAY,GAAG,MAAM,CAAC;IAE9B,YAAY,OAAwB;QAClC,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;IAED,QAAQ,CAAC,KAA8B;QACrC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,eAAe,CAAC,KAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC,WAAW,CAAU,GAAG,IAAI,CAAC,YAAY,gBAAgB,EAAE,EAAE,CAAC,CAAC;IAC7E,CAAC;IAED,OAAO,CAAC,MAAc;QACpB,OAAO,IAAI,CAAC,WAAW,CAAQ,GAAG,IAAI,CAAC,YAAY,UAAU,MAAM,EAAE,CAAC,CAAC;IACzE,CAAC;IAED;;;;;OAKG;IACH,eAAe,CAAC,MAAc,EAAE,YAA0B,EAAE,UAAmB;QAC7E,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,gBAAgB,EACpC;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,UAAU,EAAE,CAAC;SAC3D,CACF,CAAC;IACJ,CAAC;IAED;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,MAAuB;QAC9B,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,WAAW,EAC/B;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;SAC7B,CACF,CAAC;IACJ,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,WAAW,CAAgB,GAAG,IAAI,CAAC,YAAY,mBAAmB,CAAC,CAAC;IAClF,CAAC;IAED,kBAAkB,CAAC,cAAsB;QACvC,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,kBAAkB,cAAc,SAAS,EAC7D,EAAE,MAAM,EAAE,KAAK,EAAE,CAClB,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,KAA2B;QACrC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,IAAI,eAAe,CAAC,KAAY,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC,WAAW,CAAa,GAAG,IAAI,CAAC,YAAY,YAAY,EAAE,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,UAAU,CAAC,SAAiB;QAC1B,OAAO,IAAI,CAAC,WAAW,CAAW,GAAG,IAAI,CAAC,YAAY,aAAa,SAAS,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,cAAc,CAAC,IAAY,EAAE,MAAe;QAC1C,OAAO,IAAI,CAAC,WAAW,CACrB,GAAG,IAAI,CAAC,YAAY,mBAAmB,EACvC;YACE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;SACvC,CACF,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,301 @@
1
+ # Payments SDK
2
+
3
+ The payments SDK is split into two classes:
4
+
5
+ - **`QlPayments`** (`sdk.payments`) — available to any authenticated user. Covers subscribing, checkout, invoices, and coupon validation. Users cannot set prices.
6
+ - **`QlPaymentsAdmin`** (`adminSdk.payments`) — available to privileged callers only. Extends the user surface with plan/coupon management, cross-entity subscription control, and the ability to set dynamic amounts.
7
+
8
+ ---
9
+
10
+ ## Setup
11
+
12
+ ```typescript
13
+ import { QelosSDK } from '@qelos/sdk';
14
+ import { QelosAdminSDK } from '@qelos/sdk/administrator';
15
+
16
+ const sdk = new QelosSDK({ baseUrl: 'https://your-qelos-instance.com' });
17
+ const adminSdk = new QelosAdminSDK({ baseUrl: 'https://your-qelos-instance.com' });
18
+ ```
19
+
20
+ ---
21
+
22
+ ## Static Plan Checkout (One Step)
23
+
24
+ For plans where the price is fixed, the user can subscribe and pay in a single `checkout()` call. Qelos creates the pending subscription internally.
25
+
26
+ ```typescript
27
+ // List available plans
28
+ const plans = await sdk.payments.getPlans({ isActive: true });
29
+ const plan = plans.find(p => p.name === 'Pro');
30
+
31
+ // Validate an optional coupon
32
+ const coupon = await sdk.payments.validateCoupon('SUMMER20', plan._id);
33
+
34
+ // Initiate checkout — subscription is created inline
35
+ const result = await sdk.payments.checkout({
36
+ planId: plan._id,
37
+ billingCycle: 'monthly',
38
+ couponCode: 'SUMMER20',
39
+ successUrl: 'https://myapp.com/success',
40
+ cancelUrl: 'https://myapp.com/cancel',
41
+ });
42
+
43
+ // Redirect the user
44
+ window.location.href = result.checkoutUrl;
45
+ ```
46
+
47
+ ---
48
+
49
+ ## Dynamic Plan Two-Phase Flow
50
+
51
+ Dynamic plans have variable pricing (e.g., usage-based). The user cannot set the amount — only an admin can. The flow is:
52
+
53
+ 1. User creates a pending subscription.
54
+ 2. Admin reviews usage / context and sets the amount.
55
+ 3. User initiates checkout with the subscription ID.
56
+
57
+ ### Step 1 — User subscribes
58
+
59
+ ```typescript
60
+ const subscription = await sdk.payments.subscribeToPlan(
61
+ 'dynamic-plan-id',
62
+ 'monthly',
63
+ );
64
+ // subscription.status === 'pending'
65
+ // Store subscription._id and show the user a "waiting for quote" state
66
+ ```
67
+
68
+ ### Step 2 — Admin sets the amount
69
+
70
+ ```typescript
71
+ // Admin SDK — run server-side or in the admin dashboard
72
+ await adminSdk.payments.setSubscriptionDynamicAmount(
73
+ subscription._id,
74
+ 149.00, // amount in the plan's currency
75
+ );
76
+ ```
77
+
78
+ ### Step 3 — User completes checkout
79
+
80
+ ```typescript
81
+ const result = await sdk.payments.checkout({
82
+ subscriptionId: subscription._id,
83
+ successUrl: 'https://myapp.com/success',
84
+ cancelUrl: 'https://myapp.com/cancel',
85
+ });
86
+
87
+ window.location.href = result.checkoutUrl;
88
+ ```
89
+
90
+ ### Admin convenience shortcut
91
+
92
+ Admins can collapse steps 1–3 into a single call. This creates a pending subscription with the given amount and immediately initiates checkout:
93
+
94
+ ```typescript
95
+ const result = await adminSdk.payments.checkout({
96
+ planId: 'dynamic-plan-id',
97
+ billingCycle: 'monthly',
98
+ amount: 149.00,
99
+ billableEntityType: 'workspace',
100
+ billableEntityId: 'workspace-id',
101
+ successUrl: 'https://myapp.com/success',
102
+ });
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Listing Plans and Subscriptions
108
+
109
+ ### User SDK
110
+
111
+ ```typescript
112
+ // Public plan listing (unauthenticated)
113
+ const plans = await sdk.payments.getPlans({ isActive: true });
114
+
115
+ // Single plan
116
+ const plan = await sdk.payments.getPlan('plan-id');
117
+
118
+ // Current user's active subscription
119
+ const subscription = await sdk.payments.getMySubscription();
120
+
121
+ // User's invoices
122
+ const invoices = await sdk.payments.getInvoices();
123
+ const invoice = await sdk.payments.getInvoice('invoice-id');
124
+ ```
125
+
126
+ ### Admin SDK
127
+
128
+ ```typescript
129
+ // All plans (including inactive)
130
+ const allPlans = await adminSdk.payments.getPlans();
131
+
132
+ // All subscriptions with optional filters
133
+ const workspaceSubs = await adminSdk.payments.getSubscriptions({
134
+ billableEntityType: 'workspace',
135
+ billableEntityId: 'workspace-id',
136
+ status: 'active',
137
+ });
138
+
139
+ // All invoices across entities
140
+ const invoices = await adminSdk.payments.getInvoices({
141
+ billableEntityType: 'user',
142
+ billableEntityId: 'user-id',
143
+ status: 'paid',
144
+ });
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Coupon Validation
150
+
151
+ Validate a coupon before showing it applied in the UI:
152
+
153
+ ```typescript
154
+ try {
155
+ const coupon = await sdk.payments.validateCoupon('PROMO10', 'plan-id');
156
+ console.log(coupon.discountType); // 'percentage' | 'fixed'
157
+ console.log(coupon.discountValue); // e.g. 10 (%)
158
+ } catch (err) {
159
+ // err.code: COUPON_NOT_FOUND | COUPON_EXPIRED | COUPON_NOT_APPLICABLE | ...
160
+ }
161
+ ```
162
+
163
+ ---
164
+
165
+ ## Invoice Retrieval
166
+
167
+ ```typescript
168
+ // User's own invoices
169
+ const invoices = await sdk.payments.getInvoices({ status: 'paid' });
170
+
171
+ // Single invoice (e.g. for download link)
172
+ const invoice = await sdk.payments.getInvoice('invoice-id');
173
+ console.log(invoice.invoiceUrl);
174
+ ```
175
+
176
+ ---
177
+
178
+ ## Cancellation
179
+
180
+ ```typescript
181
+ // User cancels their own subscription
182
+ await sdk.payments.cancelSubscription('subscription-id');
183
+
184
+ // Admin cancels any subscription
185
+ await adminSdk.payments.cancelSubscription('subscription-id');
186
+ ```
187
+
188
+ ---
189
+
190
+ ## Admin Plan Management
191
+
192
+ ```typescript
193
+ // Create a plan
194
+ const plan = await adminSdk.payments.createPlan({
195
+ name: 'Enterprise',
196
+ monthlyPrice: 299,
197
+ yearlyPrice: 2990,
198
+ currency: 'USD',
199
+ dynamic: false,
200
+ isActive: true,
201
+ });
202
+
203
+ // Create a dynamic plan
204
+ const dynamicPlan = await adminSdk.payments.createPlan({
205
+ name: 'Usage-Based',
206
+ currency: 'USD',
207
+ dynamic: true,
208
+ isActive: true,
209
+ monthlyPrice: 0,
210
+ yearlyPrice: 0,
211
+ });
212
+
213
+ // Update
214
+ await adminSdk.payments.updatePlan(plan._id, { monthlyPrice: 349 });
215
+
216
+ // Delete
217
+ await adminSdk.payments.deletePlan(plan._id);
218
+ ```
219
+
220
+ ---
221
+
222
+ ## Admin Coupon Management
223
+
224
+ ```typescript
225
+ // Create a 20% off coupon
226
+ const coupon = await adminSdk.payments.createCoupon({
227
+ code: 'SUMMER20',
228
+ discountType: 'percentage',
229
+ discountValue: 20,
230
+ isActive: true,
231
+ applicablePlanIds: ['plan-id'],
232
+ maxRedemptions: 100,
233
+ });
234
+
235
+ // Update
236
+ await adminSdk.payments.updateCoupon(coupon._id, { isActive: false });
237
+
238
+ // Delete
239
+ await adminSdk.payments.deleteCoupon(coupon._id);
240
+ ```
241
+
242
+ ---
243
+
244
+ ## `QlPayments` Reference (User SDK)
245
+
246
+ | Method | Description |
247
+ |---|---|
248
+ | `getPlans(query?)` | List public plans |
249
+ | `getPlan(planId)` | Get a single plan |
250
+ | `subscribeToPlan(planId, billingCycle, couponCode?)` | Create a pending subscription (first step for dynamic plans) |
251
+ | `checkout(params)` | Initiate a checkout session |
252
+ | `getMySubscription()` | Get the current user's active subscription |
253
+ | `cancelSubscription(subscriptionId)` | Cancel a subscription |
254
+ | `getInvoices(query?)` | List the current user's invoices |
255
+ | `getInvoice(invoiceId)` | Get a single invoice |
256
+ | `validateCoupon(code, planId?)` | Validate a coupon code |
257
+
258
+ ---
259
+
260
+ ## `QlPaymentsAdmin` Reference (Admin SDK)
261
+
262
+ | Method | Description |
263
+ |---|---|
264
+ | `getPlans(query?)` | List all plans |
265
+ | `getPlan(planId)` | Get a single plan |
266
+ | `createPlan(data)` | Create a plan |
267
+ | `updatePlan(planId, data)` | Update a plan |
268
+ | `deletePlan(planId)` | Delete a plan |
269
+ | `checkout(params)` | Initiate checkout with entity overrides and optional `amount` |
270
+ | `getSubscriptions(query?)` | List subscriptions across all entities |
271
+ | `getSubscription(subscriptionId)` | Get a single subscription |
272
+ | `createSubscription(data)` | Create a pending subscription on behalf of any entity |
273
+ | `cancelSubscription(subscriptionId)` | Cancel any subscription |
274
+ | `setSubscriptionDynamicAmount(subscriptionId, amount)` | Set or update the dynamic amount on a pending subscription |
275
+ | `getInvoices(query?)` | List invoices across all entities |
276
+ | `getInvoice(invoiceId)` | Get a single invoice |
277
+ | `getCoupons(query?)` | List coupons |
278
+ | `getCoupon(couponId)` | Get a single coupon |
279
+ | `createCoupon(data)` | Create a coupon |
280
+ | `updateCoupon(couponId, data)` | Update a coupon |
281
+ | `deleteCoupon(couponId)` | Delete a coupon |
282
+
283
+ ---
284
+
285
+ ## Permissions Summary
286
+
287
+ | Action | User SDK | Admin SDK |
288
+ |---|---|---|
289
+ | List/get plans | public plans only | all plans |
290
+ | Create/update/delete plans | no | yes |
291
+ | Create subscription (own entity) | yes | yes |
292
+ | Create subscription (any entity) | no | yes |
293
+ | Set `dynamicAmount` | no | yes |
294
+ | Initiate checkout | yes | yes, with entity override |
295
+ | Set checkout `amount` directly | no | yes (dynamic plans) |
296
+ | List own subscriptions/invoices | yes | yes |
297
+ | List all subscriptions/invoices | no | yes |
298
+ | Cancel own subscription | yes | yes |
299
+ | Cancel any subscription | no | yes |
300
+ | Validate coupon | yes | yes |
301
+ | Manage coupons | no | yes |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qelos/sdk",
3
- "version": "4.0.0",
3
+ "version": "4.1.0",
4
4
  "description": "SDK for Qelos API",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -102,7 +102,7 @@
102
102
  "access": "public"
103
103
  },
104
104
  "dependencies": {
105
- "@qelos/global-types": "^4.0.0"
105
+ "@qelos/global-types": "^4.1.0"
106
106
  },
107
107
  "devDependencies": {
108
108
  "tsx": "^4.21.0",
@@ -2,9 +2,42 @@ import { QelosSDKOptions } from '../types';
2
2
  import BaseSDK from '../base-sdk';
3
3
  import {
4
4
  IPlan, ISubscription, IInvoice, ICoupon,
5
- BillableEntityType, SubscriptionStatus, InvoiceStatus,
5
+ BillableEntityType, SubscriptionStatus, InvoiceStatus, BillingCycle,
6
6
  } from '@qelos/global-types';
7
7
 
8
+ export interface AdminCheckoutRequest {
9
+ planId: string;
10
+ billingCycle: BillingCycle;
11
+ /** When omitted, the authenticated user / default billable entity is used (same as public checkout). */
12
+ billableEntityType?: BillableEntityType;
13
+ billableEntityId?: string;
14
+ couponCode?: string;
15
+ successUrl?: string;
16
+ cancelUrl?: string;
17
+ /**
18
+ * Admin-only. For plans with `dynamic: true`, sets the `dynamicAmount` on the
19
+ * pending subscription before initiating checkout. Regular users cannot set this;
20
+ * use `setSubscriptionDynamicAmount()` + a separate `checkout()` call instead.
21
+ */
22
+ amount?: number;
23
+ }
24
+
25
+ export interface CreateSubscriptionData {
26
+ planId: string;
27
+ billingCycle: BillingCycle;
28
+ billableEntityType: BillableEntityType;
29
+ billableEntityId: string;
30
+ /** Required for plans with `dynamic: true` before checkout can be initiated. */
31
+ dynamicAmount?: number;
32
+ couponCode?: string;
33
+ }
34
+
35
+ export interface AdminCheckoutResponse {
36
+ subscriptionId: string;
37
+ checkoutUrl?: string;
38
+ clientToken?: string;
39
+ }
40
+
8
41
  export default class QlPaymentsAdmin extends BaseSDK {
9
42
  constructor(private options: QelosSDKOptions) {
10
43
  super(options);
@@ -41,6 +74,18 @@ export default class QlPaymentsAdmin extends BaseSDK {
41
74
  return this.callJsonApi<IPlan>(`/api/plans/${planId}`, { method: 'delete' });
42
75
  }
43
76
 
77
+ /**
78
+ * Start subscription checkout (same as `sdk.payments.checkout`, plus optional billable-entity overrides for admins).
79
+ * For plans with `dynamic: true`, `amount` is required.
80
+ */
81
+ checkout(params: AdminCheckoutRequest) {
82
+ return this.callJsonApi<AdminCheckoutResponse>('/api/checkout', {
83
+ method: 'post',
84
+ headers: { 'content-type': 'application/json' },
85
+ body: JSON.stringify(params),
86
+ });
87
+ }
88
+
44
89
  // --- Subscriptions ---
45
90
 
46
91
  getSubscriptions(query?: {
@@ -56,6 +101,19 @@ export default class QlPaymentsAdmin extends BaseSDK {
56
101
  return this.callJsonApi<ISubscription>(`/api/subscriptions/${subscriptionId}`);
57
102
  }
58
103
 
104
+ /**
105
+ * Creates a pending subscription on behalf of any billable entity. Admins can
106
+ * also set `dynamicAmount` here for dynamic plans, making the subscription
107
+ * immediately ready for checkout.
108
+ */
109
+ createSubscription(data: CreateSubscriptionData) {
110
+ return this.callJsonApi<ISubscription>('/api/subscriptions', {
111
+ method: 'post',
112
+ headers: { 'content-type': 'application/json' },
113
+ body: JSON.stringify(data),
114
+ });
115
+ }
116
+
59
117
  cancelSubscription(subscriptionId: string) {
60
118
  return this.callJsonApi<ISubscription>(
61
119
  `/api/subscriptions/${subscriptionId}/cancel`,
@@ -63,6 +121,21 @@ export default class QlPaymentsAdmin extends BaseSDK {
63
121
  );
64
122
  }
65
123
 
124
+ /**
125
+ * Sets or updates the dynamic amount for a pending subscription. Only admins
126
+ * can call this. Must be done before a user can complete checkout on a dynamic plan.
127
+ */
128
+ setSubscriptionDynamicAmount(subscriptionId: string, amount: number) {
129
+ return this.callJsonApi<ISubscription>(
130
+ `/api/subscriptions/${subscriptionId}/dynamic-amount`,
131
+ {
132
+ method: 'put',
133
+ headers: { 'content-type': 'application/json' },
134
+ body: JSON.stringify({ amount }),
135
+ },
136
+ );
137
+ }
138
+
66
139
  // --- Invoices ---
67
140
 
68
141
  getInvoices(query?: {
package/src/payments.ts CHANGED
@@ -3,11 +3,19 @@ import BaseSDK from './base-sdk';
3
3
  import { IPlan, ISubscription, IInvoice, ICoupon, BillingCycle } from '@qelos/global-types';
4
4
 
5
5
  export interface CheckoutRequest {
6
- planId: string;
7
- billingCycle: BillingCycle;
6
+ /** Required when not providing `subscriptionId`. Must be a non-dynamic plan. */
7
+ planId?: string;
8
+ /** Required when not providing `subscriptionId`. */
9
+ billingCycle?: BillingCycle;
8
10
  couponCode?: string;
9
11
  successUrl?: string;
10
12
  cancelUrl?: string;
13
+ /**
14
+ * Pre-created subscription ID. Required for dynamic plans — the admin must set
15
+ * `dynamicAmount` on the subscription before this checkout call will succeed.
16
+ * When provided, `planId` and `billingCycle` are ignored.
17
+ */
18
+ subscriptionId?: string;
11
19
  }
12
20
 
13
21
  export interface CheckoutResponse {
@@ -34,6 +42,34 @@ export default class QlPayments extends BaseSDK {
34
42
  return this.callJsonApi<IPlan>(`${this.relativePath}/plans/${planId}`);
35
43
  }
36
44
 
45
+ /**
46
+ * Creates a pending subscription for the authenticated user without initiating
47
+ * payment. Use this as the first step for any plan, and the only step before
48
+ * `checkout()` for dynamic plans (the admin must call `setSubscriptionDynamicAmount`
49
+ * before the user can complete checkout).
50
+ */
51
+ subscribeToPlan(planId: string, billingCycle: BillingCycle, couponCode?: string) {
52
+ return this.callJsonApi<ISubscription>(
53
+ `${this.relativePath}/subscriptions`,
54
+ {
55
+ method: 'post',
56
+ headers: { 'content-type': 'application/json' },
57
+ body: JSON.stringify({ planId, billingCycle, couponCode }),
58
+ },
59
+ );
60
+ }
61
+
62
+ /**
63
+ * Initiates a provider checkout session.
64
+ *
65
+ * **Static plans**: pass `planId` + `billingCycle` (a subscription is created
66
+ * inline).
67
+ *
68
+ * **Dynamic plans**: the user must first call `subscribeToPlan()` to create a
69
+ * pending subscription, then an admin must set the dynamic amount via
70
+ * `setSubscriptionDynamicAmount()`. Only then should this method be called with
71
+ * `subscriptionId` pointing to that pending subscription.
72
+ */
37
73
  checkout(params: CheckoutRequest) {
38
74
  return this.callJsonApi<CheckoutResponse>(
39
75
  `${this.relativePath}/checkout`,