> For the complete documentation index, see [llms.txt](https://docs.tiun.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tiun.io/guides/subscriptions/monetize-with-subscriptions.md).

# Monetize with subscriptions

This guide walks through wiring up a subscription product — pricing buttons, checkout, and gating content based on what the user has purchased. Login and logout are not covered here; see [authenticating your user](/guides/authentication/authenticate-your-user.md) for those.

***

## 1. Create subscription products

Create one product per plan in the dashboard. The full walkthrough is in [creating your first product](/guides/getting-started/creating-first-product.md) — repeat it for each plan (for example, **Light** and **Pro**) and copy the product IDs.

***

## 2. Install and initialize the SDK

Install `@tiun/sdk` and call `tiun.init` once at app startup. The [Quickstart](/quickstart.md) has the full install commands.

```javascript
import { tiun } from '@tiun/sdk';

tiun.init({
  snippetId: 'YOUR_SNIPPET_ID',
  language: 'en',
});
```

***

## 3. Build a pricing page

Keep product IDs in one place so checkout buttons, gating logic, and analytics all reference the same source. The JS will throw on typos instead of failing silently.

```javascript
const TIUN_PRODUCTS = {
  light: 'p-live-light',
  pro: 'p-live-pro',
};
```

Wire one button per plan, each calling `tiun.checkout()` with the matching product ID:

```javascript
function onClickLight() {
  tiun.checkout({ productId: TIUN_PRODUCTS.light });
}

function onClickPro() {
  tiun.checkout({ productId: TIUN_PRODUCTS.pro });
}
```

When the user clicks, tiun opens the checkout overlay — it collects their email, handles identity verification, processes payment, and grants access in one flow. For what the overlay does behind the scenes, see [Checkout / How it works](/reference/checkout/how-it-works.md) in Reference.

***

## 4. Handle checkout success

After a successful purchase, `userChange` fires with `event: 'checkout'`. The user object includes their email and a `productAccess` array containing the product they just bought. `productAccess` is the canonical source of truth for what the user can access — see [Product access](/reference/checkout/product-access.md) in Reference for how it's populated and updated.

```javascript
tiun.on('userChange', (data) => {
  if (data.event === 'checkout' && data.user) {
    console.log('Subscribed to:', data.user.productAccess);
  }
});
```

For the journey from checkout through renewal and expiration, see [Subscriptions](/reference/checkout/subscriptions.md) in Reference.

***

## 5. Gate content based on access

Use the `productAccess` array to decide what to show. The same `userChange` handler covers checkout success, login, logout, and the initial session restore on page load — so your gates stay in sync without extra work.

```javascript
tiun.on('userChange', (data) => {
  if (!data.isAuthenticated) {
    showPricingPage();
    return;
  }

  const hasProAccess = data.user.productAccess.includes(TIUN_PRODUCTS.pro);
  const hasLightAccess = data.user.productAccess.includes(TIUN_PRODUCTS.light);

  if (hasProAccess) {
    showProContent();
  } else if (hasLightAccess) {
    showLightContent();
  } else {
    showUpgradePrompt();
  }
});
```

***

## 6. Add login and logout

Returning users can sign in without going through checkout again. The setup is covered in [authenticating your user](/guides/authentication/authenticate-your-user.md) — once that's wired up, your subscribers can log back in and the same `userChange` handler picks up their existing `productAccess`.

***

## 7. Go live

If you've been testing in sandbox, set up **live as a separate environment** in the dashboard, then for production traffic:

1. Remove `sandbox: true` from your `tiun.init` (or set it to `false`).
2. Use your **live** snippet ID and live product IDs (prefixed `p-live-`).
3. If you verify server-side, switch to the live API base URL and a live API key.

See [setting up your environment](/guides/getting-started/set-up-environment.md) for the full sandbox / live workflow.

***

## Full example

The subscription-specific integration in one place (login / logout wiring lives in the Auth guide):

```javascript
import { tiun } from '@tiun/sdk';

const TIUN_PRODUCTS = {
  light: 'p-live-light',
  pro: 'p-live-pro',
};

tiun.on('userChange', (data) => {
  if (!data.isAuthenticated) {
    showPricingPage();
    return;
  }

  const hasProAccess = data.user.productAccess.includes(TIUN_PRODUCTS.pro);
  const hasLightAccess = data.user.productAccess.includes(TIUN_PRODUCTS.light);

  if (hasProAccess) {
    showProContent();
  } else if (hasLightAccess) {
    showLightContent();
  } else {
    showUpgradePrompt();
  }
});

tiun.init({
  snippetId: 'YOUR_SNIPPET_ID',
  language: 'en',
});

function checkoutLight() {
  tiun.checkout({ productId: TIUN_PRODUCTS.light });
}

function checkoutPro() {
  tiun.checkout({ productId: TIUN_PRODUCTS.pro });
}
```

***

For framework-specific implementations, see [React](/sdk/examples/react.md), [Vue](/sdk/examples/vue.md), and [Nuxt](/sdk/examples/nuxt.md) in the SDK reference.

If your backend needs to verify the user's subscription before serving protected data, see [server-side subscription verification](/guides/subscriptions/verify-server-side.md).


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.tiun.io/guides/subscriptions/monetize-with-subscriptions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
