@tiun/sdk
v0.9.1
Published
tiun SDK for payments and subscriptions
Maintainers
Readme
tiun SDK
The tiun SDK provides a simple API for integrating payments, subscriptions, and authentication into any website or app.
Installation
npm install @tiun/sdkQuick Start
import { tiun } from '@tiun/sdk';
tiun.init({
snippetId: 'your-snippet-id',
language: 'en', // set to your site's language
});
// Subscription checkout for a specific product
tiun.checkout({ productId: 'prod_monthly' });
// Time-based connect flow
tiun.start();Set
languageto match your site. If omitted, the snippet UI defaults to'en'. See all supported codes in the Init options table below.
The snippet is loaded automatically from the backend when you call tiun.init() with a snippetId. No script tags or extra HTML are required.
Configuration
tiun.init(config)
Initialize the SDK. Call once at app startup.
tiun.init({
snippetId: 'your-snippet-id',
language: 'en', // set to your site's language
tone: 'formal',
debug: false,
sandbox: false,
// Lifecycle callbacks
onReady: () => {},
onPaywallShow: (data) => {},
onPaywallHide: (data) => {},
onError: (error) => {},
// Auth callbacks
onUserChange: (event) => {},
onLogin: (event) => {},
onLogout: () => {}
});Init options
| Option | Type | Default | Description |
| --------------- | ---------------------------------- | ---------- | ------------------------------------------------------------------ |
| snippetId | string | — | Required. Your unique tiun snippet ID from the dashboard. |
| language | string | 'en' | Language for the snippet UI (e.g. 'en', 'de', 'fr'). Set this to match your site; falls back to 'en' if omitted. |
| tone | 'formal' \| 'informal' | 'formal' | UI tone/style. |
| debug | boolean | false | Enable console logging. |
| sandbox | boolean | false | Use sandbox base URL instead of production. |
| onReady | () => void | — | Called when snippet is ready. |
| onPaywallShow | (data: PaywallShowEvent) => void | — | Called when paywall should be shown. |
| onPaywallHide | (data: PaywallHideEvent) => void | — | Called when user has access. |
| onUserChange | (data: UserChangeEvent) => void | — | Called on every user state change (init, login, logout, checkout). |
| onLogin | (data: LoginEvent) => void | — | Called when user logs in. |
| onLogout | () => void | — | Called when user logs out. |
| onError | (error: TiunError) => void | — | Called on errors. |
Authentication
tiun provides built-in passwordless authentication (OTP via SMS/email). Users authenticate once during checkout, and their session persists across visits.
tiun.login()
Open the login modal for returning subscribers.
tiun.login();tiun.logout()
Log the user out and clear the session.
tiun.logout();tiun.getUser()
Returns the cached user state synchronously.
const { isAuthenticated, user } = tiun.getUser();
if (isAuthenticated) {
console.log('Logged in as', user.email);
console.log('Product access:', user.productAccess);
}Returns GetUserResponse:
| Property | Type | Description |
| ----------------- | ------------------ | ----------------------------------------- |
| isAuthenticated | boolean | Whether the user has an active session. |
| user | UserInfo \| null | User details, or null if not logged in. |
UserInfo
| Property | Type | Description |
| --------------- | ---------- | ------------------------------------------- |
| userId | string | Unique user identifier. |
| email | string | User's email address. |
| productAccess | string[] | List of product IDs the user has access to. |
tiun.getUserVerificationToken()
Returns a secure token that can be used for server-to-server user verification. The token is valid for 5 minutes. Returns null if the user is not authenticated.
const token = await tiun.getUserVerificationToken();Your backend can verify the token using your tiun API key from the business dashboard.
Start & Checkout
tiun supports two flows:
- Subscription checkout (
checkout) -- Opens the checkout flow for a specific product. Requires aproductId. - Time-based connect (
start) -- Opens the connect flow without a specific product. Used for time-based access models.
tiun.checkout(options)
Open the subscription checkout flow for a specific product.
tiun.checkout({ productId: 'prod_monthly' });| Option | Type | Description |
| ----------- | -------- | ----------------------------------------------------- |
| productId | string | The product ID to checkout. From your tiun dashboard. |
tiun.start()
Open the time-based connect flow.
tiun.start();Events
Subscribe with tiun.on(). Returns an unsubscribe function.
ready
Fired when the snippet has initialized and is ready to use.
tiun.on('ready', () => {
console.log('tiun is ready');
});userChange
Fired on every user state change -- initialization, login, logout, and checkout. This is the single event to track all user state transitions.
tiun.on('userChange', (event) => {
console.log('Event:', event.event);
console.log('Authenticated:', event.isAuthenticated);
console.log('User:', event.user);
});| Property | Type | Description |
| ----------------- | ------------------ | ---------------------------------------------------------------------------------------- |
| event | string | What triggered the change: 'init', 'login', 'logout', 'checkout', or 'update'. |
| isAuthenticated | boolean | Whether the user is currently authenticated. |
| user | UserInfo \| null | User details, or null. |
login
Fired specifically when a user logs in. Convenience event -- the same data is also available via userChange.
tiun.on('login', (event) => {
console.log('Welcome back,', event.user.email);
});| Property | Type | Description |
| -------- | ---------- | ------------- |
| user | UserInfo | User details. |
logout
Fired when the user logs out.
tiun.on('logout', () => {
console.log('User logged out');
});error
Fired when an error occurs.
tiun.on('error', (error) => {
console.error('tiun error:', error.code, error.message);
});| Property | Type | Description |
| --------- | --------- | ------------------------- |
| code | string | Error code. |
| message | string | Error message. |
| details | unknown | Additional error details. |
All events
| Event | Description |
| ------------- | --------------------------------------------------------------------------------------------------- |
| ready | Snippet has initialized and is ready. |
| userChange | User state changed. Payload: UserChangeEvent. |
| login | User logged in. Payload: LoginEvent. |
| logout | User logged out. No payload. |
| paywallShow | Paywall should be shown (user doesn't have access). Payload: { isConnected: boolean }. |
| paywallHide | Paywall should be hidden (user has access). Payload: { sessionId: string, isConnected: boolean }. |
| error | An error occurred. Payload: TiunError. |
Paywall events (payloads)
paywallShow: { isConnected: boolean }
paywallHide: { sessionId: string, isConnected: boolean }
One-time and unsubscribe
tiun.once('login', (event) => console.log('First login:', event.user.email));
const unsubscribe = tiun.on('userChange', () => {});
unsubscribe();Properties
| Property | Type | Description |
| ---------------------- | ------------------ | ---------------------------------------------- |
| tiun.version | string | SDK version. |
| tiun.isInitialized | boolean | Whether init() has been called. |
| tiun.isReady | boolean | Whether the snippet is ready. |
| tiun.isAuthenticated | boolean | Whether the user has a valid session. |
| tiun.user | UserInfo \| null | Current user info, or null if not logged in. |
Methods
| Method | Description |
| --------------------------------- | ----------------------------------------------------------- |
| tiun.init(config) | Initialize the SDK. Call once at startup. |
| tiun.start() | Open the time-based connect flow. |
| tiun.checkout(options) | Open the subscription checkout flow for a specific product. |
| tiun.login() | Open the login modal for returning subscribers. |
| tiun.logout() | Log the user out and clear the session. |
| tiun.getUser() | Get cached user state (synchronous). |
| tiun.getUserVerificationToken() | Get a secure token for server-to-server verification. |
| tiun.setContent(options) | Update the current content context. |
| tiun.on(event, callback) | Subscribe to an event. Returns unsubscribe function. |
| tiun.once(event, callback) | Subscribe to an event once. Returns unsubscribe function. |
| tiun.destroy() | Destroy the SDK and clean up listeners. |
| tiun.waitForReady() | Wait for the SDK to be ready. Returns a Promise. |
tiun.setContent(options)
Tell tiun what content the user is viewing.
tiun.setContent({
type: 'active',
contentId: 'episode-123',
mediaType: 'audio'
});| Option | Type | Description |
| ----------- | ------------------------------------ | ---------------------------------- |
| type | 'active' \| 'inactive' \| 'paused' | Required. Content state. |
| contentId | string | Unique identifier for the content. |
| mediaType | 'text' \| 'audio' \| 'video' | Type of media. Default: 'text'. |
Framework examples
Vue
<script setup lang="ts">
import { tiun } from '@tiun/sdk';
import { onMounted, onUnmounted } from 'vue';
onMounted(() => {
tiun.init({ snippetId: 'your-snippet-id', language: 'en' });
});
onUnmounted(() => {
tiun.destroy();
});
</script>
<template>
<button @click="tiun.checkout({ productId: 'prod_monthly' })">
Subscribe
</button>
</template>React
import { tiun } from '@tiun/sdk';
import { useEffect } from 'react';
function App() {
useEffect(() => {
tiun.init({ snippetId: 'your-snippet-id', language: 'en' });
return () => tiun.destroy();
}, []);
return (
<div>
<button onClick={() => tiun.checkout({ productId: 'prod_monthly' })}>
Subscribe
</button>
</div>
);
}Vanilla JS
<script src="https://cdn.tiun.io/sdk.js"></script>
<script>
tiun.init({ snippetId: 'your-snippet-id', language: 'en' });
</script>
<button onclick="tiun.checkout({ productId: 'prod_monthly' })">
Subscribe
</button>