@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.
- package/dist/administrator/payments.d.ts +47 -1
- package/dist/administrator/payments.js +34 -0
- package/dist/administrator/payments.js.map +1 -1
- package/dist/payments.d.ts +28 -2
- package/dist/payments.js +24 -0
- package/dist/payments.js.map +1 -1
- package/docs/payments.md +301 -0
- package/package.json +2 -2
- package/src/administrator/payments.ts +74 -1
- package/src/payments.ts +38 -2
|
@@ -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":"AACA,OAAO,OAAO,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"payments.js","sourceRoot":"","sources":["../../src/administrator/payments.ts"],"names":[],"mappings":"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"}
|
package/dist/payments.d.ts
CHANGED
|
@@ -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
|
-
|
|
6
|
-
|
|
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',
|
package/dist/payments.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"payments.js","sourceRoot":"","sources":["../src/payments.ts"],"names":[],"mappings":"AACA,OAAO,OAAO,MAAM,YAAY,CAAC;
|
|
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"}
|
package/docs/payments.md
ADDED
|
@@ -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.
|
|
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.
|
|
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
|
-
|
|
7
|
-
|
|
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`,
|