Dart SDK
The feeef Dart package that powers the official merchant app — repositories, auth persistence, realtime and integrations.
The feeef Dart package is the client behind the official Feeef merchant app. It is pure Dart
(no Flutter dependency) built on Dio, with pluggable persistence so it runs in Flutter apps,
CLIs and servers alike.
dart pub add feeef
# or in Flutter
flutter pub add feeefInitialize
The SDK is a singleton. Call init once before touching any repository:
import 'package:feeef/feeef.dart';
await Feeef.instance.init(
baseUrl: 'https://api.feeef.org/v1',
storage: MyFeeefStorage(),
config: FeeefConfig(
baseUrl: 'https://api.feeef.org', // realtime origin
isProduction: true,
debugMode: false,
),
getPushToken: () => FirebaseMessaging.instance.getToken(), // optional
);| Parameter | Purpose |
|---|---|
baseUrl | REST base including /v1 |
storage | Required — a FeeefStorage implementation for persisting the auth token and user (see below) |
config | Realtime origin + environment flags; debugMode enables per-request latency logging (X-Client-Trace-Id) |
getPushToken | Optional callback; when present, sign-in/up sends the push token (e.g. FCM) to the backend. The SDK itself has no Firebase dependency |
FeeefStorage
The SDK persists sessions through an interface you implement — wrap SharedPreferences,
flutter_secure_storage, a file, anything:
class MyFeeefStorage implements FeeefStorage {
@override
Future<String?> read(String key) async => _prefs.getString(key);
@override
Future<void> write(String key, String value) async => _prefs.setString(key, value);
@override
Future<void> delete(String key) async => _prefs.remove(key);
}On init, the SDK restores any saved session automatically (users.init()), so users stay
signed in across app launches.
Repositories
All available on Feeef.instance:
| Property | Resource |
|---|---|
users | Auth (signin/signup/social/passkeys), profile, sessions, connected apps |
stores | Stores + members; storesInvites for invitations |
products, categories | Catalog |
orders | Orders + calculate, status flows, reports (liteOrdersReport) |
productLandingPages, productLandingPageTemplates | Landing pages |
templateComponents, storeTemplates | Storefront template system |
shippingMethods, shippingPrices, shippingPricesResource | Shipping |
inventory, finance | Pro modules |
deposits, transfers, promos, feedbacks | Billing, promos, reviews |
apps, oauth | OAuth clients + token operations |
imageGenerations (ai), imagePromptTemplates | AI imaging |
chat | Realtime-backed chat/support |
currencies, countries, states, cities | Reference data |
configs | Remote config (fetched during init) |
storage, files, actions, analytics | Uploads and service endpoints |
Models are freezed immutable classes with JSON serialization; lists come back as
ListResponse<T> with the same normalization as the JS SDK, and the same
filterator and batch mixins apply.
Authentication
// Email + password (persists token + user via FeeefStorage)
final auth = await Feeef.instance.users.signin(
email: 'me@example.com',
password: 'secret',
);
// Token sign-in (e.g. from an OAuth exchange)
final auth2 = await Feeef.instance.users.signinWithToken(token: accessToken);
// Session state
final user = Feeef.instance.users.user; // currently signed-in user (or null)
await Feeef.instance.users.signout();UserRepository also exposes passkey flows, social sign-in exchanges, email verification and
password reset — the same endpoints listed in Authentication.
Realtime
Feeef.instance.realtime wraps the transmit_client package with automatic reconnection
(exponential backoff, heartbeat) and bearer-authenticated subscriptions:
final sub = await Feeef.instance.realtime.subscribe('stores/$storeId/orders');
sub.listen((message) {
final event = message['event']; // 'created' | 'updated' | 'deleted'
final data = message['data'];
});Repositories with live views (orders, chat) use these channels internally.
File uploads
final url = await Feeef.instance.storage.upload(
file: FeeefUploadFile(bytes: bytes, name: 'photo.png', size: bytes.length),
folder: 'products',
onProgress: (sent, total) => print('$sent/$total'),
);FeeefUploadFile takes either in-memory bytes or a file path — you own the picking UX.
Delivery & marketing integrations
Unique to the Dart SDK — typed clients for store integrations:
| API | Purpose |
|---|---|
EcotrackDeliveryIntegrationApi, NoestDeliveryIntegrationApi, YalidineDeliveryIntegrationApi, ProcolisDeliveryIntegrationApi, CodpilotDeliveryIntegrationApi | Delivery carriers — create parcels from orders, track statuses, bulk send (BulkSendResult) |
GoogleSheetsIntegrationApi | Order sync to spreadsheets |
MetaAdsIntegrationApi (Feeef.instance.metaAds) | Ads reads, KPIs, ad↔product links |
ConnectorsIntegrationApi (Feeef.instance.connectors) | Generic connectors |
IntegrationSubscriptionApi | Manage integration subscriptions |
These call the store-integration endpoints and require the
store.integrations scope.
OAuth for your own Dart apps
// 1. Send the user to consent (accounts origin)
final url = AppRepository.buildAuthorizeUrl(
'https://accounts.feeef.org',
clientId: clientId,
redirectUri: redirectUri,
scope: 'auth',
state: state,
codeChallenge: challenge,
codeChallengeMethod: 'S256',
);
// 2. Exchange the callback code
final token = await Feeef.instance.oauth.exchangeAuthorizationCode(
code: code,
redirectUri: redirectUri,
clientId: clientId,
codeVerifier: verifier,
);
// 3. Sign in with it (persisted via FeeefStorage)
await Feeef.instance.users.signinWithToken(token: token.accessToken);App management (Feeef.instance.apps) mirrors the JS surface:
CRUD, regenerateSecret, and all six data-bucket methods.