UNPKG

@tiun/sdk

Version:

tiun SDK for payments and subscriptions

436 lines (313 loc) • 16.9 kB
# tiun SDK The tiun SDK provides a simple API for integrating payments, subscriptions, and authentication into any website or app. --- ## Installation ```bash npm install @tiun/sdk ``` --- ## Quick Start ```typescript import { tiun } from '@tiun/sdk'; tiun.init({ snippetId: 'your-snippet-id', language: 'en', // set to your site's language appearance: 'auto' // 'light' | 'dark' | 'auto' }); // Subscription checkout for a specific product tiun.checkout({ productId: 'prod_monthly' }); // Time-based connect flow tiun.start(); ``` > **Set `language` to match your site.** Supported: `'en'`, `'de'`, `'fr'`. If omitted, the snippet UI defaults to `'en'`. > > **Set `appearance` to match your site's theme.** If omitted, the snippet uses `'light'`. See [Appearance](#appearance). 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. ```typescript tiun.init({ snippetId: 'your-snippet-id', language: 'en', // set to your site's language tone: 'formal', appearance: 'light', 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` | `'en' \| 'de' \| 'fr'` | `'en'` | Language for the snippet UI. Case-insensitive. Set this to match your site; unsupported values fall back to `'en'` with a console warning. | | `tone` | `'formal' \| 'informal'` | `'informal'` | UI tone/style. Case-insensitive. | | `appearance` | `'light' \| 'dark' \| 'auto'` | `'light'` | Color theme for the snippet UI. `'auto'` follows the visitor's OS setting. See [Appearance](#appearance). | | `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. | --- ## Appearance The snippet ships with a light and a dark theme. Pick one at init, or let it follow the visitor's OS setting: ```typescript tiun.init({ snippetId: 'your-snippet-id', appearance: 'auto' }); ``` | Value | Behavior | | --------- | --------------------------------------------------------------------------------------------- | | `'light'` | Light theme. **Default.** | | `'dark'` | Dark theme. | | `'auto'` | Follows the visitor's OS setting (`prefers-color-scheme`) and re-themes live when it changes. | Values are case-insensitive. An unsupported value logs a console warning and is ignored. ### `tiun.setAppearance(appearance)` Switch the theme at runtime without a reload, e.g. when your site's theme toggle flips: ```typescript // From your theme toggle: tiun.setAppearance(isDark ? 'dark' : 'light'); // Or hand control back to the OS setting: tiun.setAppearance('auto'); ``` - Safe to call before `init()` or before the snippet is ready. A value set before `init()` is kept unless `init()` passes its own `appearance`. --- ## 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. ```typescript tiun.login(); ``` ### `tiun.logout()` Log the user out and clear the session. ```typescript tiun.logout(); ``` ### `tiun.getUser()` Returns the cached user state synchronously. ```typescript 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. ```typescript 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 a `productId`. - **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. ```typescript 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. ```typescript tiun.start(); ``` ## Events Subscribe with `tiun.on()`. Returns an unsubscribe function. ### `ready` Fired when the snippet has initialized and is ready to use. ```typescript 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. ```typescript 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`. ```typescript 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. ```typescript tiun.on('logout', () => { console.log('User logged out'); }); ``` ### `error` Fired when an error occurs. ```typescript 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`. | ### One-time and unsubscribe ```typescript 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.setAppearance(appearance)` | Switch the snippet to `'light'`, `'dark'` or `'auto'`. See [Appearance](#appearance). | | `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. ```typescript 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'`. | --- ## TypeScript Types are bundled with the package — no extra install needed: ```typescript import { tiun, type Appearance, type TiunConfig, type UserInfo } from '@tiun/sdk'; ``` Also exported: `CheckoutOptions`, `ContentOptions`, `ContentType`, `MediaType`, `SupportedLanguage`, `TiunError`, `PaywallShowEvent`, `PaywallHideEvent`, `UserChangeEvent`, `LoginEvent`, `GetUserResponse`, `TiunEventType`, `TiunSDK`. --- ## Framework examples ### Vue ```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 ```tsx 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 No bundler? Load the ES module build from a CDN: ```html <button id="subscribe">Subscribe</button> <script type="module"> import { tiun } from 'https://cdn.jsdelivr.net/npm/@tiun/sdk@0/tiun.js'; tiun.init({ snippetId: 'your-snippet-id', language: 'en' }); document.getElementById('subscribe').addEventListener('click', () => { tiun.checkout({ productId: 'prod_monthly' }); }); </script> ```