Skip to content

Payments SDK

The payments SDK is split into two classes:

  • QlPayments (sdk.payments) — available to any authenticated user. Covers subscribing, checkout, invoices, and coupon validation. Users cannot set prices.
  • QlPaymentsAdmin (adminSdk.managePayments) — available to privileged callers only. Extends the user surface with plan/coupon management, cross-entity subscription control, and the ability to set dynamic amounts.

API reference: Payments API · Detailed docs: Payments

Setup

typescript
import { QelosSDK } from '@qelos/sdk';
import { QelosAdministratorSDK } from '@qelos/sdk/administrator';

const sdk = new QelosSDK({ baseUrl: 'https://your-qelos-instance.com' });
const adminSdk = new QelosAdministratorSDK({ baseUrl: 'https://your-qelos-instance.com' });

Static Plan Checkout (one step)

For plans where the price is fixed, subscribe and pay in a single checkout() call. Qelos creates the pending subscription internally.

typescript
// List available plans
const plans = await sdk.payments.getPlans({ isActive: true });
const plan = plans.find(p => p.name === 'Pro');

// Validate an optional coupon
const coupon = await sdk.payments.validateCoupon('SUMMER20', plan._id);

// Initiate checkout — subscription is created inline
const result = await sdk.payments.checkout({
  planId: plan._id,
  billingCycle: 'monthly',
  couponCode: 'SUMMER20',
  successUrl: 'https://myapp.com/success',
  cancelUrl: 'https://myapp.com/cancel',
});

window.location.href = result.checkoutUrl;

Dynamic Plan Two-Phase Flow

Dynamic plans have variable pricing (e.g. usage-based). The user cannot set the amount — only an admin can. The flow is:

  1. User creates a pending subscription.
  2. Admin reviews usage/context and sets the amount.
  3. User initiates checkout using the subscription ID.

Step 1 — User subscribes

typescript
const subscription = await sdk.payments.subscribeToPlan(
  'dynamic-plan-id',
  'monthly',
);
// subscription.status === 'pending'
// Show the user a "waiting for quote" state and store subscription._id

Step 2 — Admin sets the amount

typescript
// Run server-side or in the admin dashboard
await adminSdk.managePayments.setSubscriptionDynamicAmount(
  subscription._id,
  149.00,  // amount in the plan's currency
);

Step 3 — User completes checkout

typescript
const result = await sdk.payments.checkout({
  subscriptionId: subscription._id,
  successUrl: 'https://myapp.com/success',
  cancelUrl: 'https://myapp.com/cancel',
});

window.location.href = result.checkoutUrl;

Admin convenience shortcut

Admins can collapse all three steps into one call — creates a pending subscription with the given amount and immediately initiates checkout:

typescript
const result = await adminSdk.managePayments.checkout({
  planId: 'dynamic-plan-id',
  billingCycle: 'monthly',
  amount: 149.00,
  billableEntityType: 'workspace',
  billableEntityId: 'workspace-id',
  successUrl: 'https://myapp.com/success',
});

window.location.href = result.checkoutUrl;

Listing Plans and Subscriptions

User SDK

typescript
// Public plan listing (works unauthenticated)
const plans = await sdk.payments.getPlans({ isActive: true });

// Single plan
const plan = await sdk.payments.getPlan('plan-id');

// Current user's active subscription
const subscription = await sdk.payments.getMySubscription();

// User's invoices
const invoices = await sdk.payments.getInvoices();
const invoice = await sdk.payments.getInvoice('invoice-id');

Admin SDK

typescript
// All plans (including inactive)
const allPlans = await adminSdk.managePayments.getPlans();

// Subscriptions with optional filters
const workspaceSubs = await adminSdk.managePayments.getSubscriptions({
  billableEntityType: 'workspace',
  billableEntityId: 'workspace-id',
  status: 'active',
});

// Invoices across entities
const invoices = await adminSdk.managePayments.getInvoices({
  billableEntityType: 'user',
  billableEntityId: 'user-id',
  status: 'paid',
});

Coupon Validation

Validate a coupon before showing it applied in the UI:

typescript
try {
  const coupon = await sdk.payments.validateCoupon('PROMO10', 'plan-id');
  console.log(coupon.discountType);   // 'percentage' | 'fixed'
  console.log(coupon.discountValue);  // e.g. 10 (%)
} catch (err) {
  // err.code: COUPON_NOT_FOUND | COUPON_EXPIRED | COUPON_NOT_APPLICABLE | ...
}

Cancellation

typescript
// User cancels their own subscription
await sdk.payments.cancelSubscription('subscription-id');

// Admin cancels any subscription
await adminSdk.managePayments.cancelSubscription('subscription-id');

Admin Plan Management

typescript
// Create a static plan
const plan = await adminSdk.managePayments.createPlan({
  name: 'Enterprise',
  monthlyPrice: 299,
  yearlyPrice: 2990,
  currency: 'USD',
  dynamic: false,
  isActive: true,
});

// Create a dynamic plan (amount set per-subscription)
const dynamicPlan = await adminSdk.managePayments.createPlan({
  name: 'Usage-Based',
  currency: 'USD',
  dynamic: true,
  isActive: true,
  monthlyPrice: 0,
  yearlyPrice: 0,
});

// Update
await adminSdk.managePayments.updatePlan(plan._id, { monthlyPrice: 349 });

// Delete / deactivate
await adminSdk.managePayments.deletePlan(plan._id);

Admin Coupon Management

typescript
// Create a 20% off coupon
const coupon = await adminSdk.managePayments.createCoupon({
  code: 'SUMMER20',
  discountType: 'percentage',
  discountValue: 20,
  isActive: true,
  applicablePlanIds: ['plan-id'],
  maxRedemptions: 100,
});

// Update
await adminSdk.managePayments.updateCoupon(coupon._id, { isActive: false });

// Delete
await adminSdk.managePayments.deleteCoupon(coupon._id);

QlPayments Reference (User SDK)

MethodDescription
getPlans(query?)List public plans
getPlan(planId)Get a single plan
subscribeToPlan(planId, billingCycle, couponCode?)Create a pending subscription (required first step for dynamic plans)
checkout(params)Initiate a checkout session
getMySubscription()Get the current user's active subscription
cancelSubscription(subscriptionId)Cancel a subscription
getInvoices(query?)List the current user's invoices
getInvoice(invoiceId)Get a single invoice
validateCoupon(code, planId?)Validate a coupon code

QlPaymentsAdmin Reference (Admin SDK)

MethodDescription
getPlans(query?)List all plans
getPlan(planId)Get a single plan
createPlan(data)Create a plan
updatePlan(planId, data)Update a plan
deletePlan(planId)Delete a plan
checkout(params)Initiate checkout with entity overrides and optional amount
getSubscriptions(query?)List subscriptions across all entities
getSubscription(subscriptionId)Get a single subscription
createSubscription(data)Create a pending subscription on behalf of any entity
cancelSubscription(subscriptionId)Cancel any subscription
setSubscriptionDynamicAmount(subscriptionId, amount)Set or update the dynamic amount on a subscription
getInvoices(query?)List invoices across all entities
getInvoice(invoiceId)Get a single invoice
getCoupons(query?)List coupons
getCoupon(couponId)Get a single coupon
createCoupon(data)Create a coupon
updateCoupon(couponId, data)Update a coupon
deleteCoupon(couponId)Delete a coupon

Permissions Summary

ActionUser SDKAdmin SDK
List/get planspublic plans onlyall plans
Create/update/delete plansnoyes
Create subscription (own entity)yesyes
Create subscription (any entity)noyes
Set dynamicAmountnoyes
Initiate checkoutyesyes, with entity override
Set checkout amount directlynoyes (dynamic plans)
List own subscriptions/invoicesyesyes
List all subscriptions/invoicesnoyes
Cancel own subscriptionyesyes
Cancel any subscriptionnoyes
Validate couponyesyes
Manage couponsnoyes

Build SaaS Products Without Limits.