Documentation
Payments

Subscription Plans

Add and sell monthly/yearly plans with simple UI actions.

AI Skill for payments

Prompt: Type /payments in your Copilot / Cursor or other chat to use skill with the provided context.
/payments Update subscription plans or payment callbacks.

When to use

Configure plans

Enable billing

Open src/config/app.ts and set billing.plans.enabled: true.

Add subscription plans

Under plans.items, add your subscription plans with their respective descriptions, features, and pricing details.

Plan properties

  • id — Stripe product id
  • name — Display name for the plan
  • description — Brief description of the plan
  • features — List of features included in the plan. Will be displayed on the pricing page
  • prices — List of pricing options for the plan:
    • priceId — Stripe product price id
    • interval — Billing interval (e.g., month, year)
    • amount — Billing amount
    • currency — Billing currency

Example

Example for 2 subscription plans, with a monthly/yearly switcher. Users get a discount when subscribing for 1 year.

src/config/app.ts
plans: {
  enabled: false,
  items: [
    {
      id: 'prod_U9rrny3QZOfZ91',
      name: 'Basic',
      description: 'Basic usage with no recurring charge',
      features: [
        'Basic features included',
        'Up to 5 projects',
        'Community support',
        'Standard response time',
      ],
      prices: [
        {
          priceId: 'price_1TBY7jEG4PIIRhjwrCXoy1pg',
          interval: 'month',
          amount: 3,
          currency: 'usd',
        },
        {
          priceId: 'price_1TBY7jEG4PIIRhjwrCXoy1ph',
          interval: 'year',
          amount: 30,
          currency: 'usd',
        },
      ],
    },
    {
      id: 'prod_U9rHeMAaUjvLIU',
      name: 'Pro',
      description: 'Recurring subscription for professional usage',
      isRecommended: true,
      features: [
        'All Basic features',
        'Unlimited projects',
        'Priority 24/7 support',
        'Premium response time',
        'Custom domain support',
      ],
      prices: [
        {
          priceId: 'price_1TBXYrEG4PIIRhjwtC2MvxZL',
          interval: 'month',
          amount: 5,
          currency: 'usd',
        },
        {
          priceId: 'price_1TBcbDEG4PIIRhjwGr5qxvsi',
          interval: 'year',
          amount: 50,
          currency: 'usd',
        },
      ],
    },
  ]
},

Payment callbacks

You can add your callbacks to Stripe payment events to implement extra logic (e.g., 3rd party API calls, logging, metadata updates). Review the callback service in src/features/common/payments/service/payment-callback.service.ts.

Subscription Success

Called after a subscription is activated (new or upgraded). Add custom logic here: webhooks, CRM updates, 3rd-party integrations, etc.

export async function onSubscriptionSuccess(
  payload: SubscriptionSuccessPayload,
): Promise<void> {
  // Available fields in payload:
  // userId, email, name, planId, planName, amountText
  console.log('[subscription] success', payload);
}

Subscription Cancelled

Called after a subscription is cancelled. Add custom logic here: offboarding flows, CRM updates, retention hooks, etc.

export async function onSubscriptionCancelled(
  payload: SubscriptionCancelledPayload,
): Promise<void> {
  // Available fields in payload:
  // userId, email, name, periodEndText
  console.log('[subscription] cancelled', payload);
}

Emails

The system automatically sends emails based on subscription lifecycle events.

  • Subscription Success: src/shared/emails/subscription-success.tsx
  • Subscription Cancelled: src/shared/emails/subscription-cancelled.tsx

On this page