TSOJ Flutter Client
A Flutter/Dart client library for interacting with TSOJ services. This package provides a type-safe, easy-to-use interface for authentication, billing, and other TSOJ API features using Dio for HTTP requests.
Features
- 🔐 Authentication: Sign up, sign in, magic link, and password-based authentication
- 🍪 Cookie Support: Full HTTP-only cookie support for session management (like Axios
withCredentials) - 💳 Billing: Payment gateway integration, invoice creation, and order management
- 🛡️ Type Safety: Strongly typed request/response models
- 🔑 API Key Support: Supports both API keys and publishable keys
- 🌐 HTTP Client: Built on Dio for reliable HTTP communication
- 📝 Error Handling: Comprehensive error handling with typed responses
Installation
Add this to your package's pubspec.yaml file:
dependencies:
tsoj_flutter_client: ^0.0.1
Then run:
flutter pub get
Usage
Basic Setup
Create a client instance with your publishable key:
import 'package:tsoj_flutter_client/tsoj_flutter_client.dart';
void main() {
final client = createTsojClient(
publishableKey: 'your-publishable-key-here',
baseURL: 'https://id.tsoj.com', // Optional, can use TSOJ_BASE_URL env var
);
}
Authentication
Sign Up with Password
final result = await client.auth.passwordSignup(
PasswordSignupRequestPayload(
email: 'user@example.com',
password: 'securePassword123',
passwordRepeat: 'securePassword123',
name: 'John Doe',
),
);
if (result.status == 200) {
print('Success: ${result.data.message}');
} else {
print('Error: ${result.data.message}');
}
Sign In with Password
final result = await client.auth.passwordSignin(
PasswordSigninRequestPayload(
email: 'user@example.com',
password: 'securePassword123',
),
);
if (result.status == 200) {
print('Signed in successfully!');
}
Magic Link Sign In
final result = await client.auth.magicSignin(
MagicSigninRequestPayload(
email: 'user@example.com',
),
);
print(result.data.message);
Cookie Management
The client automatically handles HTTP-only cookies set by your backend (equivalent to Axios withCredentials: true). This is perfect for session-based authentication:
// Cookies are automatically stored and sent with each request
await client.auth.passwordSignin(...); // Backend sets session cookie
// All subsequent requests automatically include the session cookie
final gateways = await client.getAvailableGateways();
// Clear all cookies (logout)
await client.api.clearCookies();
Important: Your backend must set proper CORS headers:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: <your-origin> (not *)
Using TSOJ Cookies with Your Own Backend
You can create a custom API client that shares the same cookies as the TSOJ client. This is useful when you want to call your own backend and verify the TSOJ session:
// 1. Authenticate with TSOJ
await client.auth.passwordSignin(
PasswordSigninRequestPayload(
email: 'user@example.com',
password: 'password123',
),
);
// TSOJ sets session cookie
// 2. Create a client for your backend that shares TSOJ cookies
final myBackendClient = client.createCustomBackendClient(
baseURL: 'https://my-backend.com/api',
);
// 3. Call your backend - TSOJ cookies will be included!
final response = await myBackendClient.get('/user/profile');
final userData = await myBackendClient.post('/user/settings', data: {...});
Your Backend Setup:
Your backend can verify the TSOJ session cookie:
// Node.js/Express example
app.get("/user/profile", async (req, res) => {
const tsojSession = req.cookies["accessToken"]; // TSOJ cookie
// Verify with TSOJ or use it to identify the user
// ...
});
// Dart/Shelf example
Response handler(Request request) {
final tsojSession = request.headers['cookie']; // Contains TSOJ cookies
// Parse and verify the session
// ...
}
Configuration Options
TsojClientConfig
publishableKey(required): Your publishable key for client-side authenticationbaseURL(optional): The base URL for the API. Falls back toTSOJ_BASE_URLenvironment variable if not provided
Cookie Support
The client includes built-in cookie management:
- Automatic: Cookies are automatically stored and sent with requests
- HTTP-only: Supports HTTP-only cookies set by your backend
- Persistent: Cookies persist across requests (in-memory by default)
- Clear: Use
client.api.clearCookies()to clear all stored cookies
For persistent cookies across app restarts, you can provide a custom CookieJar (see Advanced Usage below).
API Reference
Authentication Methods
| Method | Description |
|---|---|
signUp(SignupRequestPayload) |
Sign up a new user |
signIn(SigninRequestPayload) |
Sign in an existing user |
passwordSignup(PasswordSignupRequestPayload) |
Sign up with email and password |
passwordSignin(PasswordSigninRequestPayload) |
Sign in with email and password |
magicSignin(MagicSigninRequestPayload) |
Sign in with magic link (email only) |
Client Methods
| Method | Description |
|---|---|
getAvailableGateways() |
Get list of available payment gateways |
getBankTransferDetails() |
Get bank transfer details for manual payments |
Types
Authentication Types
AccountProvider- Enum:email,passwordSignupRequestPayloadSigninRequestPayloadPasswordSignupRequestPayloadPasswordSigninRequestPayloadMagicSigninRequestPayloadPasswordSignupResponsePayloadPasswordSigninResponsePayload
Advanced Usage
Persistent Cookies
By default, cookies are stored in memory and cleared when the app closes. For persistent cookies across app restarts, use PersistCookieJar:
import 'package:cookie_jar/cookie_jar.dart';
import 'package:path_provider/path_provider.dart';
// Get app directory
final appDocDir = await getApplicationDocumentsDirectory();
final cookieJar = PersistCookieJar(
storage: FileStorage('${appDocDir.path}/.cookies/'),
);
// Pass custom cookie jar to ApiClient
final client = TsojClientFactory(
TsojClientConfig(
publishableKey: 'your-key',
baseURL: 'https://id.tsoj.com',
),
);
// Note: To use custom CookieJar, you'll need to modify the implementation
Custom Cookie Management
// Access the cookie jar
final cookies = await client.api.cookieJar.loadForRequest(
Uri.parse('https://id.tsoj.com'),
);
// Clear all cookies (useful for logout)
await client.api.clearCookies();
Multiple Backend Clients with Shared Session
// Create multiple clients for different backends, all sharing the same session
final tsojClient = createTsojClient(
publishableKey: 'your-key',
baseURL: 'https://id.tsoj.mn',
);
// Authenticate once
await tsojClient.auth.passwordSignin(...);
// Create clients for different services
final apiClient = tsojClient.createCustomBackendClient(
baseURL: 'https://api.myapp.com',
);
final analyticsClient = tsojClient.createCustomBackendClient(
baseURL: 'https://analytics.myapp.com',
);
// All requests include the same TSOJ session cookies
await apiClient.get('/user/data');
await analyticsClient.post('/events', data: {...});
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Support
For issues, questions, or contributions, please visit our GitHub repository.
Libraries
- tsoj_flutter_client
- A Dart client library for TSOJ API