UNPKG

@tiun/sdk

Version:

tiun SDK for payments and subscriptions

381 lines (275 loc) 13.3 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 }); // Subscription checkout for a specific product tiun.checkout({ productId: 'prod_monthly' }); // Time-based connect flow tiun.start(); ``` > **Set `language` to match your site.** If omitted, the snippet UI defaults to `'en'`. See all supported codes in the [Init options](#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. ```typescript 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. ```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`. | ### Paywall events (payloads) **paywallShow:** `{ isConnected: boolean }` **paywallHide:** `{ sessionId: string, isConnected: boolean }` ### 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.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'`. | --- ## 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 ```html <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> ```