go_trust_mobile_sdk 1.0.7
go_trust_mobile_sdk: ^1.0.7 copied to clipboard
A Flutter mobile SDK for GoTrust consent and preference management.
— Integration Guide #
Overview #
The GoTrust Flutter SDK (go_trust_mobile_sdk) enables cross-platform mobile applications to present consent-collection forms and preference centers natively within Flutter UI trees for compliant privacy and consent management.
Requirements #
-
Flutter SDK: 3.19.0 or higher
-
Dart SDK: 3.3.0 or higher
-
Target Platforms: Android (minSdkVersion 24), iOS (iOS 14.0 or higher)
-
Package Source: pub.dev/packages/go_trust_mobile_sdk
Step 1 — Add SDK Dependency #
Add the latest version of go_trust_mobile_sdk to your project's pubspec.yaml file:
YAML
dependencies: flutter: sdk: flutter go_trust_mobile_sdk: ^
Fetch the package:
Bash
flutter pub get
Step 2 — Configure Environment Parameters #
Store tenant credentials securely using environment configurations or remote configuration services rather than hardcoding them inside UI widgets.
Dart
abstract class GoTrustConfig {
static const String baseUrl = " ";
static const String sourceId = "YOUR_SOURCE_ID"; static const String preferenceFormId = "YOUR_PREFERENCE_FORM_ID"; static const String customerId = "YOUR_CUSTOMER_ID"; static const String pfToken = "YOUR_PREREFENCE_CENTER_TOKEN"; static const String consentUserToken = "YOUR_CONSENT_USER_TOKEN"; // minor/token-flow, consent form static const String pfUserToken = "YOUR_PREFERENCE_USER_TOKEN"; // minor/token-flow, preference center
}
Step 3 — Define Subject Identity & Parameters #
Declare the target subject's identity as key-value pairs matching your GoTrust dashboard field configuration (e.g., "107" for phone, "10085" for email).
Dart
// Required: Subject identity key-value map static const Map<String, dynamic> subjectIdentityValues = { "107": "9891737651", "10085": " ",
};
// Optional: Extra prefill data (not used for identity lookup) — keyed by field-id, same convention as subjectIdentityValues static const Map<String, dynamic> additionalParams = <String, dynamic>{ "2": "Jane Doe", "6": "1994-07-21", };
Step 4 — Implementation & Flow Control #
Important: Always execute the consent check before presenting the UI to avoid unnecessary popups when a valid consent record already exists.
1. Check Consent Requirement
Use GoTrustSdkHelper.showConsentForm to verify if the consent form should be rendered for the specified subject identity. Parameters are now named — pass sourceId + subjectIdentityValues for the standard flow, or a token for the token flow (see 2.2 below), never both.
Dart
final bool shouldShowConsent = await GoTrustSdkHelper.showConsentForm( baseUrl: GoTrustConfig.baseUrl, sourceId: GoTrustConfig.sourceId, subjectIdentityValues: subjectIdentityValues, );
Note: showConsentForm also accepts a userSpecificToken parameter as an alternative to sourceId/subjectIdentityValues — see 2.2 below. It also accepts an optional fallback — see 2.1.
-
true — No valid record found; present ConsentFormPage.
-
false — Valid consent already on record; skip display.
2. Render Consent Form
Standard Integration
If consent is required, navigate to ConsentFormPage passing the standard configuration and the callbacks structure:
Dart
if (shouldShowConsent == true && context.mounted) {
await Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => ConsentFormPage(
sourceId: GoTrustConfig.sourceId,
initialSubjectValues: subjectIdentityValues,
additionalParams: additionalParams,
baseUrl: GoTrustConfig.baseUrl,
enableCaptcha: false,
callbacks: ConsentCallbacks(
onSuccess: (
int? statusCode, String? message, List<Map<String, dynamic>>? data,
debugPrint('Consent Submitted! Status: $statusCode');
if (data != null) { print("Received data: $data");
}
},
onError: (int? statusCode, String? message) { debugPrint('Consent Failed! Status: $statusCode, Message: $message'); }, onClose: (String? message) { debugPrint('Consent Form Closed by User: $message');
},
),
),
), ); }
2.1 Render Consent Form (Using Fallback)
To gracefully handle scenarios where the primary GoTrust API is unreachable, define a FallbackConfig. This configuration must be passed to both the verification API (showConsentForm) and the UI component (ConsentFormPage).
A. Define Fallback Configuration:
Dart
final fallbackConfig = FallbackConfig(
displayUrl: ' ',
submitUrl: ' ',
headers: {
'X-Client-Api-Key': 'your-api-key',
'X-Client-Id': 'your-client-id',
'X-CSRF-Token': 'initial-csrf-token',
'Cookie': '_bb_mid=xyz; CSRF-TOKEN=initial-csrf-token;',
},
csrfHeaderName: 'X-CSRF-Token',
csrfCookieName: 'CSRF-TOKEN',
refreshCsrfToken: () async {
final response = await yourApiService.refreshCsrf();
return response.headers['x-csrf-token'];
},
);
B. Verify Consent with Fallback:
Dart
Future<bool?> _shouldOpenConsentForm(Map<String, dynamic> subjectIdentityValues) async { return GoTrustSdkHelper.showConsentForm( baseUrl: GoTrustConfig.baseUrl, sourceId: GoTrustConfig.sourceId, subjectIdentityValues: subjectIdentityValues, fallback: fallbackConfig, ); }
C. Render Consent Form with Fallback:
Dart
if (shouldShowConsent == true && context.mounted) { await Navigator.of(context).push( MaterialPageRoute(
builder: (_) => ConsentFormPage(
sourceId: GoTrustConfig.sourceId,
initialSubjectValues: subjectIdentityValues, additionalParams: additionalParams,
// Unreachable host -> verification API or getConsentFormData throws ->
// switches to fallback.
baseUrl: GoTrustConfig.baseUrl, fallback: fallbackConfig, enableCaptcha: false,
callbacks: ConsentCallbacks(
int? statusCode,
String? message,
List<Map<String, dynamic>>? data,
'Consent Submitted! Status: $statusCode');
if (data != null) {
print("Received data: $data");
int? statusCode, String? message) {
'Consent Failed! Status: $statusCode, Message: $message');
String? message) {
'Consent Form Closed by User: $message');
2.2 Render Consent Form (Using Token)
The consent form supports a second, mutually-exclusive integration mode. Instead of resolving and passing sourceId / initialSubjectValues / additionalParams yourself (the flow in 1 and 2 above), issue a single pre-generated token and pass only that — omit sourceId, initialSubjectValues, and additionalParams entirely.
This token is not something the client constructs — it's issued ahead of time by calling GoTrust's own token-generation API for the consent flow. The client only ever supplies the resulting token value here; the SDK resolves source_id, customer_id, pf_id, is_minor, subject_identity_values, and pii_list from it server-side. ConsentFormPage uses these resolved values to drive the check, form display, and submit — it never handles the underlying IDs or PII you'd otherwise pass in.
Dart
final bool shouldShowConsent = await GoTrustSdkHelper.showConsentForm( baseUrl: GoTrustConfig.baseUrl, userSpecificToken: GoTrustConfig.consentUserToken, // resolves sourceId/subjectIdentityValues server-side );
if (shouldShowConsent == true && context.mounted) { await Navigator.of(context).push( MaterialPageRoute( builder: (_) => ConsentFormPage( baseUrl: GoTrustConfig.baseUrl, token: GoTrustConfig.consentUserToken, // only identifier the client supplies enableCaptcha: false, callbacks: ConsentCallbacks( onSuccess: (statusCode, message, data) { /* ... / }, onError: (statusCode, message) { / ... / }, onClose: (message) { / ... */ }, ), ), ), ); }
ConsentFormPage internally branches on whether a token was supplied. In that mode it ignores any initialSubjectValues/additionalParams passed in and instead populates them from the decrypted subject_identity_values/pii_list returned server-side — so don't pass those params alongside a token.
Precedence: if both sourceId and token/userSpecificToken are supplied, the token wins. This is the path used for the minor-consent flow, where a guardian-issued token overrides the plain sourceId lookup.
3. Render Preference Center
Standard Integration
Present LoginPage to allow users to update their stored preferences from app settings. Launching LoginPage is all a host app does — OTP verification and the preference dashboard are handled internally by the SDK:
-
LoginPage resolves the customer/preference-form identity, then on submit sends an OTP to the identified subject. If the resolved configuration has authentication disabled, OTP is skipped and the flow goes straight to step 3.
-
OTP verification — the SDK internally navigates to its own OTP screen and verifies the code entered by the user; this screen is not something you construct directly.
-
Preference Dashboard — once verified (or if OTP was skipped), the SDK shows a tabbed dashboard: Privacy Notice, Consent Preferences, DSR, Consent Flow, and Audit Logs (each tab shown only if enabled for the form). Saving preferences here fires the same onSuccess/onError/onClose callbacks passed to LoginPage.
(a) When customerId and preferenceFormId are known:
Dart
void openPreferenceCenter(BuildContext context) { Navigator.push( context, MaterialPageRoute( builder: (_) => LoginPage( baseUrl: GoTrustConfig.baseUrl, customerId: GoTrustConfig.customerId, preferenceFormId: GoTrustConfig.preferenceFormId, initialSubjectValues: subjectIdentityValues, additionalParams: additionalParams, enableCaptcha: true, onSuccess: (String? message, List<Map<String, dynamic>>? data) { // Preferences successfully updated }, onError: (String? message) { // Preference update failed }, onClose: (String? message) { // Preference center closed without saving }, ), ), ); }
(b) When customerId and preferenceFormId are not available: pass pfToken alone instead — the SDK resolves both server-side from it.
Dart
void openPreferenceCenter(BuildContext context) { Navigator.push( context, MaterialPageRoute( builder: (_) => LoginPage( baseUrl: GoTrustConfig.baseUrl, pfToken: GoTrustConfig.pfToken, initialSubjectValues: subjectIdentityValues, additionalParams: additionalParams, enableCaptcha: true, onSuccess: (String? message, List<Map<String, dynamic>>? data) { // Preferences successfully updated }, onError: (String? message) { // Preference update failed }, onClose: (String? message) { // Preference center closed without saving }, ), ), ); }
Note: onSuccess/onError/onClose on LoginPage are plain function parameters, not a wrapped callbacks object — and they're the only place you attach them; the OTP and dashboard screens the SDK navigates to internally forward them automatically. consentId is an accepted but currently unused/legacy parameter — safe to omit.
3.1 Render Preference Center (Using Token)
Just like the consent form, the preference center supports a token-only integration mode. Issue a single pre-generated token and pass only that — omit customerId, preferenceFormId, pfToken, and consentId entirely.
This token is not something the client constructs — it's issued ahead of time by calling GoTrust's own token-generation API for the preference center. The client only ever supplies the resulting token value here; the SDK resolves customer_id, pf_id, is_minor, subject_identity_values, and pii_list from it server-side. In this mode, any initialSubjectValues/additionalParams you pass are ignored and overridden by the resolved values — so don't pass those alongside a token either. The rest of the flow (OTP → dashboard) is identical to the standard integration above.
Dart
Navigator.push( context, MaterialPageRoute( builder: (_) => LoginPage( baseUrl: GoTrustConfig.baseUrl, token: GoTrustConfig.pfUserToken, // resolves customerId + preferenceFormId server-side enableCaptcha: true, onSuccess: (message, data) { // Preferences successfully updated }, onError: (message) { // Preference update failed }, onClose: (message) { // Preference center closed without saving }, ), ), ); }
Precedence: if both token and pfToken are supplied, token wins — but the documented pattern is token-only, don't supply both. This is the path used for the minor-consent flow, where a guardian-issued token overrides a plain pfToken lookup — the same precedence rule applies on the consent form side (token over sourceId), see 2.2.
| Field | Where Used | Notes |
|---|---|---|
| token | ConsentFormPage, GoTrustSdkHelper.showConsentForm |
Resolves sourceId + subject identity via the decryptor |
| token | LoginPage | Resolves customerId + preferenceFormId; takes precedence over pfToken |
| pfToken | LoginPage | Alternative to customerId/preferenceFormId; overridden by token if both are supplied |
Parameter Reference #
| Parameter | Type | Required | Description |
|---|---|---|---|
| baseUrl | String | Yes | Target GoTrust API environment domain URL. |
| consentId / sourceId |
String | Yes | Unique consent form source identifier. On LoginPage, consentId is optional/legacy — currently unused internally; omit it, especially when using token. |
| token | String | Conditional | Token pre-issued by GoTrust's token- generation API (not constructed by the client). When supplied, the client omits sourceId/subjectIdentity Values (consent form) or customerId/preferenceFo rmId/pfToken/consentId (preference center) entirely; the SDK resolves all of them server-side. Takes precedence over sourceId/pfToken when both are given — used for the minor-consent flow. |
| initialSubjectValues | Map<String, dynamic> |
Yes | Key-value pairs matching dashboard field IDs identifying the user. Omit when using token — resolved server- side instead. |
| callbacks | ConsentCallbacks | Yes | ConsentFormPage only: object wrapping onSuccess,onError, and onClose. LoginPage uses plain onSuccess/onError /onClose function parameters instead. |
| fallback | FallbackConfig | Optional | Configuration to gracefully handle server/API unreachability. Passed to both the verify |
| check and the UI widget. Consent form only — not available for the preference center. |
|||
|---|---|---|---|
| additionalParams | Map<String, dynamic> |
Optional | Supplementary key- value pairs for form field prefilling. Omit when using token. |
| showCrossButton | bool | Optional | Toggles dismiss button visibility (default: true). |
| enableCaptcha | bool | Optional | Toggles CAPTCHA verification on submit/save. |
| pfToken | String | Optional | Preference center access token (alternative to preferenceFormId and customerId). Superseded by token when present — omit if using token. |
| customerId | String | Conditional | Customer ID for Preference Center authentication. Omit when using token. |
| preferenceFormId | String | Conditional | Preference Form ID for Preference Center lookup. Omit when using token. |
Troubleshooting & Best Practices #
-
Prevent Duplicate Presentation: Maintain a local state flag (e.g., bool _isFormActive = false) during navigation to prevent triggering multiple modal overlays on rapid taps.
-
Platform-Specific Setup: Verify that both android/app/build.gradle (minSdkVersion 24) and ios/Podfile (platform :ios, '14.0') meet baseline requirements.
-
Identity Key Mapping: Double-check that field ID keys in initialSubjectValues (e.g., "107") match string field IDs generated in the GoTrust Admin Dashboard.
-
Token Freshness: Build a fresh token per session, same as other single-use configs. An invalid or expired token causes the decryptor call to fail, and the SDK will not resolve sourceId/subject identity — this surfaces as a failed consent check or an empty preference center.
-
Preference Center Callbacks Live on LoginPage Only: onSuccess/onError/onClose are set once on LoginPage and are forwarded automatically through the internal OTP and dashboard screens — you cannot (and don't need to) attach separate callbacks to those intermediate screens.
Document 3.2: SOP — Flutter SDK Lifecycle Management & Release Workflow #
| Document ID |
SOP-FLUTTER-SDK-001 | Effective Date |
August 2026 |
|---|---|---|---|
| Subject | GoTrust Flutter SDK Maintenance & Update Cycle |
Target Audience |
Mobile Engineering & Compliance Teams |
1. Purpose & Scope #
The GoTrust Flutter SDK (go_trust_mobile_sdk) handles privacy compliance across both iOS and Android releases from a single codebase. Because regulatory consent mandates apply universally across platforms, version updates must follow standardized ingestion, verification, and deployment protocols.
2. Update Classifications & SLAs #
| Classification | Trigger Criteria | Action Required | Targeted Deployment SLA |
|---|---|---|---|
| Compliance- Critical |
Legal or regulatory mandate changes, critical security patch, required presentation flow change. |
Fast-track integration. Out-of- band release creation across Android and iOS binaries. |
Fast-Track Push:< 5 Business Days |
| Routine | Minor bug fixes, performance updates, non-breaking UI improvements, optional API parameters. |
Ingested into normal engineering backlog and sprint cycles. |
Standard Release: Next scheduled app release cycle |
3. Client App Release & Integration Workflow #
Plaintext
[GoTrust Package Update Published / Notified] │ ▼ [Assess Classification] / \ / \ (Compliance-Critical) (Routine) │ │ ▼ ▼ [Fast-Track: Out-of-Band] [Backlog: Standard Sprint] │ │ └─────────── ┬ ───────────────┘ │ ▼ [Step 1: Bump version in pubspec.yaml & run flutter pub get] │ ▼ [Step 2: Review pub.dev changelog & parameter updates] │ ▼
[Step 3: Perform Dual-Platform QA in Sandbox]
├ ── Android Build Verification (minSdkVersion 24+)
├ ── iOS Build Verification (iOS 14.0+)
├ ── Verify Async Check (GoTrustSdkHelper.showConsentForm)
├ ── Verify ConsentFormPage Navigation & Callbacks
└── Verify Preference Center Flow
│
▼
[Validation Successful?]
/ </mark>
(Yes) (No) ── ► [Escalate to GoTrust Support] │
▼
[Step 4: Build Release Binaries (AAB / IPA) & Deploy]
4. Operational Step-by-Step Execution Guide #
When a new version of go_trust_mobile_sdk is released:
- Designate Release Owner: Assign a designated Flutter developer to track package updates and release notes on pub.dev.
2. Dependency Update:
-
a. Update pubspec.yaml with the new version constraint.
-
b. Run flutter pub get and check for any transitive dependency conflicts.
3. Dual-Platform Testing:
-
a. Point baseUrl parameters to your staging/sandbox environment.
-
b. Execute test suites on both physical Android and iOS devices or emulators.
-
c. Confirm callback behavior (onSuccess, onError, onClose) across both operating systems.
4. App Store & Google Play Deployment:
-
a. Package release builds (flutter build appbundle and flutter build ipa).
-
b. Deploy updates according to the prescribed classification SLA (FastTrack vs. Standard Release).