go_trust_mobile_sdk 1.1.1+9 copy "go_trust_mobile_sdk: ^1.1.1+9" to clipboard
go_trust_mobile_sdk: ^1.1.1+9 copied to clipboard

A Flutter mobile SDK for GoTrust consent and preference management.

# GoTrust Mobile SDK for Flutter

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`
- **Dart SDK:** `>= 3.3.0`
- **Android:** `minSdkVersion 24`
- **iOS:** `iOS 14.0` or higher
- **Package:** [pub.dev/packages/go_trust_mobile_sdk](https://pub.dev/packages/go_trust_mobile_sdk)

---

## Getting Started

### Step 1: Add SDK Dependency

Add the latest version of `go_trust_mobile_sdk` to your `pubspec.yaml`:

```yaml
dependencies:
  flutter:
    sdk: flutter
  go_trust_mobile_sdk: ^latest_version

Fetch the package:

flutter pub get


Step 2: Configure Environment Parameters #

Store tenant credentials securely using environment variables or remote configuration rather than hardcoding them inside UI widgets.

abstract class GoTrustConfig {
  static const String baseUrl = "[https://your-environment.gotrust.tech](https://your-environment.gotrust.tech)";
  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_PREFERENCE_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).

// Required: Subject identity key-value map
static const Map<String, dynamic> subjectIdentityValues = {
  "107": "9891737651",
  "10085": "user@example.com",
};

// Optional: Supplementary prefill data (not used for identity lookup)
static const Map<String, dynamic> additionalParams = <String, dynamic>{
  "2": "Jane Doe",
  "6": "1994-07-21",
};


Implementation & Flow Control #

Important: Always execute the consent check before presenting the UI to avoid unnecessary dialogs when a valid consent record already exists.

Use GoTrustSdkHelper.showConsentForm to verify if the form needs to be displayed. Pass sourceId + subjectIdentityValues for the standard flow, or userSpecificToken for the token flow (never both).

final bool shouldShowConsent = await GoTrustSdkHelper.showConsentForm(
  baseUrl: GoTrustConfig.baseUrl,
  sourceId: GoTrustConfig.sourceId,
  subjectIdentityValues: subjectIdentityValues,
);

  • true — No valid record found; present ConsentFormPage.
  • false — Valid consent already on record; skip display.

A. Standard Flow

if (shouldShowConsent == true && context.mounted) {
  await Navigator.of(context).push(
    MaterialPageRoute(
      builder: (_) => ConsentFormPage(
        baseUrl: GoTrustConfig.baseUrl,
        sourceId: GoTrustConfig.sourceId,
        initialSubjectValues: subjectIdentityValues,
        additionalParams: additionalParams,
        enableCaptcha: false,
        callbacks: ConsentCallbacks(
          onSuccess: (int? statusCode, String? message, List<Map<String, dynamic>>? data) {
            debugPrint('Consent Submitted! Status: $statusCode');
            if (data != null) debugPrint('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');
          },
          onNothingTapped: (String? message) {
            debugPrint('Nothing button tap by User: $message');
          },
        ),
      ),
    ),
  );
}

B. Fallback Flow (Handling Server Outages)

Define a FallbackConfig and pass it to both showConsentForm and ConsentFormPage:

final fallbackConfig = FallbackConfig(
  displayUrl: '[https://your-api.example.com/v1/display](https://your-api.example.com/v1/display)',
  submitUrl: '[https://your-api.example.com/v2/submit](https://your-api.example.com/v2/submit)',
  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'];
  },
);

// Verify with fallback
final bool shouldShow = await GoTrustSdkHelper.showConsentForm(
  baseUrl: GoTrustConfig.baseUrl,
  sourceId: GoTrustConfig.sourceId,
  subjectIdentityValues: subjectIdentityValues,
  fallback: fallbackConfig,
);

// Display with fallback
if (shouldShow == true && context.mounted) {
  await Navigator.of(context).push(
    MaterialPageRoute(
      builder: (_) => ConsentFormPage(
        baseUrl: GoTrustConfig.baseUrl,
        sourceId: GoTrustConfig.sourceId,
        initialSubjectValues: subjectIdentityValues,
        additionalParams: additionalParams,
        fallback: fallbackConfig,
        enableCaptcha: false,
        callbacks: ConsentCallbacks(
          onSuccess: (statusCode, message, data) { /* ... */ },
          onError: (statusCode, message) { /* ... */ },
          onClose: (message) { /* ... */ },
          onNothingTapped: (message) { /* ... */ },
        ),
      ),
    ),
  );
}

Pass only the pre-generated token. The SDK resolves IDs and PII server-side. Do not supply sourceId, initialSubjectValues, or additionalParams.

final bool shouldShow = await GoTrustSdkHelper.showConsentForm(
  baseUrl: GoTrustConfig.baseUrl,
  userSpecificToken: GoTrustConfig.consentUserToken,
);

if (shouldShow == true && context.mounted) {
  await Navigator.of(context).push(
    MaterialPageRoute(
      builder: (_) => ConsentFormPage(
        baseUrl: GoTrustConfig.baseUrl,
        token: GoTrustConfig.consentUserToken,
        enableCaptcha: false,
        callbacks: ConsentCallbacks(
          onSuccess: (statusCode, message, data) { /* ... */ },
          onError: (statusCode, message) { /* ... */ },
          onClose: (message) { /* ... */ },
          onNothingTapped: (message) { /* ... */ },
        ),
      ),
    ),
  );
}

Use GoTrustSdkHelper.closeConsentForm() to close the consent form when you want to close it explicitly.

GoTrustSdkHelper.closeConsentForm();


3. Render Preference Center #

Presenting LoginPage is all the host app needs to do. Verification (OTP) and preference dashboards are handled internally by the SDK.

Option A: Known customerId and preferenceFormId

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
        },
      ),
    ),
  );
}

Option B: Using pfToken

void openPreferenceCenter(BuildContext context) {
  Navigator.push(
    context,
    MaterialPageRoute(
      builder: (_) => LoginPage(
        baseUrl: GoTrustConfig.baseUrl,
        pfToken: GoTrustConfig.pfToken,
        initialSubjectValues: subjectIdentityValues,
        additionalParams: additionalParams,
        enableCaptcha: true,
        onSuccess: (message, data) {},
        onError: (message) {},
        onClose: (message) {},
      ),
    ),
  );
}

Option C: Using User-Specific Token

Navigator.push(
  context,
  MaterialPageRoute(
    builder: (_) => LoginPage(
      baseUrl: GoTrustConfig.baseUrl,
      token: GoTrustConfig.pfUserToken,
      enableCaptcha: true,
      onSuccess: (message, data) {},
      onError: (message) {},
      onClose: (message) {},
    ),
  ),
);


Parameter Reference #

Parameter Type Required Description
baseUrl String Yes Target GoTrust API environment domain URL.
sourceId String Conditional Unique consent form identifier. Required unless token is used.
token String Conditional Pre-issued token from GoTrust API. Overrides sourceId/pfToken.
initialSubjectValues Map<String, dynamic> Conditional Dashboard field IDs mapping user identity. Omit when using token.
callbacks ConsentCallbacks Yes ConsentFormPage only: Callbacks for onSuccess, onError, and onClose.
fallback FallbackConfig Optional Outage fallback URLs/headers for ConsentFormPage only.
additionalParams Map<String, dynamic> Optional Form field prefill data. 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. Superseded by token.
customerId String Conditional Customer ID for Preference Center. Omit when using token.
preferenceFormId String Conditional Preference Form ID. Omit when using token.

Troubleshooting & Best Practices #

  • Prevent Duplicate Modals: Maintain a local boolean flag (e.g., bool _isFormActive = false) to guard navigation calls against rapid user taps.
  • Platform Versions: Check that android/app/build.gradle defines minSdkVersion 24 and ios/Podfile specifies platform :ios, '14.0'.
  • Identity Key Mapping: Field IDs in initialSubjectValues must match the string IDs configured in the GoTrust Admin Console.
  • Token Freshness: Generate a fresh single-use token per session. Expired tokens will fail server-side decryption and block rendering.
  • Unified Callbacks: On LoginPage, provide onSuccess, onError, and onClose directly; child views (OTP/dashboard) automatically inherit them.

Appendix: Release Workflow & Lifecycle SLA #

Classification Trigger Criteria Action Required Targeted SLA
Compliance-Critical Legal mandates, security updates, presentation flow changes Out-of-band fast-track release < 5 Business Days
Routine Bug fixes, performance tuning, non-breaking changes Standard sprint backlog ingestion Next app release cycle

Integration Verification Workflow #

[GoTrust Package Update Published]
                 │
                 ▼
      [Assess Classification]
       /                   \
(Compliance-Critical)    (Routine)
       │                     │
       ▼                     ▼
[Fast-Track: Out-of-Band] [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?]
         /                    \
       (Yes)                  (No) ──► [Escalate to GoTrust Support]
         │
         ▼
[Step 4: Build Release Binaries (AAB / IPA) & Deploy]