> For the complete documentation index, see [llms.txt](https://even-financial.gitbook.io/developer-center/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://even-financial.gitbook.io/developer-center/marketplace-integrations/mobile-sdks/credit-cards/flutter.md).

# Flutter

## Overview

This documentation covers installation, required prerequisites, configuration properties currently surfaced (channel, zone), the prefill props supported for the Credit Cards product type, and a basic usage example.

## Setup Instructions

You’ll need the correct `channel` and `zone` values for your integration. Ask your Partner Manager to provide these values for Flutter Credit Cards.

### Step 1: Request an API Token

Before you can use the Engine SDK, you'll need to request an API token from your Partner Manager. This token is used to authenticate with the Engine API and provides access to different financial institutions. You may want to use multiple API tokens depending on how many entry points your app has into the SDK.

### Step 2: Confirm Software Requirements

* Flutter 3.0.0 or higher
* Dart 3.10.7 or higher

### Step 3: Install the SDK

Install the SDK via pub get:

```yaml
flutter pub add engine_mobile_flutter_sdk
```

Note: This installs the latest compatible SDK version. For a specific version, pin it explicitly in pubspec.yaml.

### Step 4: Initialize the SDK

In your app, initialize the SDK by adding the following imports to any Dart file where you want to use it. The second import exposes the prefill data models (imported with the `engine` prefix to avoid name collisions with Flutter):

```dart
import 'package:engine_mobile_flutter_sdk/engine_mobile_flutter_sdk.dart';
import 'package:engine_mobile_flutter_sdk/api_models.dart' as engine;
```

### Basic Example

Place the `EngineSDK` widget anywhere in your widget tree to render the Credit Cards flow.

```dart
EngineSDK(
  channel: 'your-channel',
  zone: 'your-zone',
  productTypes: const [engine.ProductType.creditCard],
  onExit: (_) {
    debugPrint("Exit triggered from SDK");
    Navigator.pop(context);
  },
  // ...optional event handlers, please see Event Handlers section below
)
```

## Properties

Pass these properties to `EngineSDK`:

<table><thead><tr><th width="220">Prop</th><th width="220">Type</th><th width="130">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>channel</code></td><td><code>String</code></td><td>Yes</td><td>Identifies your integration in Engine. Provided by your Partner Manager (e.g. <code>'direct'</code>).</td></tr><tr><td><code>zone</code></td><td><code>String</code></td><td>Yes</td><td>Identifies the placement or distribution surface for the SDK. Provided by your Partner Manager (e.g. <code>'marketplace'</code>).</td></tr><tr><td><code>productTypes</code></td><td><code>List&#x3C;ProductType></code></td><td>Yes</td><td>Product flow(s) to render. <code>ProductType</code> is imported from the Engine SDK package — use <code>[engine.ProductType.creditCard]</code> for Credit Cards, which maps to the string value <code>"credit_card"</code>.</td></tr><tr><td><code>bearerToken</code></td><td><code>String</code></td><td>For prefill</td><td>API token from your Partner Manager. Required to use the Prefill API (the prefill props below). Without it, the standard non-prefilled flow renders.</td></tr><tr><td><code>personalInformation</code></td><td><code>LeadPersonalInformation</code></td><td>No</td><td>Prefill data (see <a href="#prefilling-lead-data">Prefilling Lead Data</a> below).</td></tr><tr><td><code>financialInformation</code></td><td><code>LeadFinancialInformation</code></td><td>No</td><td>Prefill data (see <a href="#prefilling-lead-data">Prefilling Lead Data</a> below).</td></tr><tr><td><code>creditInformation</code></td><td><code>LeadCreditInformationJson</code></td><td>No</td><td>Prefill data (see <a href="#prefilling-lead-data">Prefilling Lead Data</a> below).</td></tr><tr><td><code>creditCardInformation</code></td><td><code>LeadCreditCardInformationJson</code></td><td>No</td><td>Prefill data (see <a href="#prefilling-lead-data">Prefilling Lead Data</a> below).</td></tr><tr><td><code>clientTags</code></td><td><code>Map&#x3C;String, List&#x3C;String>></code></td><td>No</td><td>Arbitrary key/value tags for reporting and attribution.</td></tr><tr><td><code>onExit</code></td><td><code>OnExitCallback</code></td><td>Yes</td><td>Fired when the user exits the flow.</td></tr><tr><td><code>onInitialize</code>, <code>onCreate</code>, <code>onUpdate</code>, <code>onNavigate</code>, <code>onSubmit</code>, <code>onRateTableRender</code>, <code>onOfferClick</code>, <code>onErrorPageView</code>, <code>onErrorPageRetry</code>, <code>onEmbedError</code>, <code>onEmbedErrorRetry</code></td><td>Callbacks</td><td>No</td><td>Optional tracking hooks. See the Event Handlers page.</td></tr></tbody></table>

## Prefilling Lead Data

This section describes how to prefill any user data you already have into your Flutter Credit Cards SDK implementation. Prefilled data is grouped into typed information classes and passed directly as props on `EngineSDK`. These models come from the `api_models.dart` import (aliased as `engine`).

Prefilling requires a `bearerToken`. Pass only the fields you have — omitted fields are collected from the user in-flow.

### Example

```dart
EngineSDK(
  channel: 'your-channel',
  zone: 'your-zone',
  bearerToken: '{your_token}',
  productTypes: const [engine.ProductType.creditCard],
  personalInformation: engine.LeadPersonalInformation(
    firstName: 'Bob',
    lastName: 'Dylan',
    email: 'bobdylan@gmail.com',
    dateOfBirth: DateTime(1990, 1, 1),
    primaryPhone: '2325624852',
    address1: '1600 Pennsylvania Avenue',
    address2: 'Apt 2',
    city: 'Washington',
    state: engine.State.DC,
    zipcode: '20500',
  ),
  financialInformation: engine.LeadFinancialInformation(
    annualIncome: 20000,
  ),
  creditInformation: engine.LeadCreditInformationJson(
    providedCreditRating: engine.ProvidedCreditRating.good,
  ),
  creditCardInformation: engine.LeadCreditCardInformationJson(
    cardPurposes: const [
      engine.CardPurpose.balanceTransfer,
      engine.CardPurpose.cashBack,
    ],
  ),
  onExit: (_) {},
)
```

### Type Definitions

The information classes accept the following fields for Credit Cards (all fields optional):

```dart
class LeadPersonalInformation {
  final String? firstName;
  final String? lastName;
  final String? email;
  final DateTime? dateOfBirth;
  final String? primaryPhone; // 10 digits, no "+" or "-" chars
  final String? address1;
  final String? address2; // optional apartment / suite
  final String? city;
  final State? state; // enum, 2-letter (e.g. State.DC)
  final String? zipcode;
}

class LeadFinancialInformation {
  final int? annualIncome; // raw integer value (e.g. 20000)
}

class LeadCreditInformationJson {
  final ProvidedCreditRating? providedCreditRating; // enum below
}

class LeadCreditCardInformationJson {
  final List<CardPurpose>? cardPurposes; // enum below
}
```

### Enums / Accepted Values

Fields backed by an enum must use one of the predefined values:

```dart
enum CardPurpose {
  balanceTransfer,
  cashBack,
  earningRewards,
  improveCredit,
  lowInterest,
  newToCredit,
  student,
  travelIncentives,
}

enum ProvidedCreditRating {
  excellent,
  good,
  fair,
  poor,
  limited,
}

// State is a 2-letter US state enum, e.g. State.CA, State.DC, State.NY
```

{% hint style="warning" %}
Do not prefill any fields that are empty or unavailable — omit them so the user is prompted in-flow. Prefilled data must match the type definitions above, and any field backed by an enum must use a valid value. If a value is invalid, that attribute is stripped and the user will have to enter it again manually.
{% endhint %}

## Client Tags for Reporting

The Engine Flutter SDK supports adding your unique Client Tags to track performance of specific campaigns or users. All Client Tag data is attributed to the lead level.

Client Tags can be added by including a **clientTags** attribute at the top level of the EngineSDK widget, where the value is a **Map\<String, List\<String>>**.

We strongly recommend including only one element per list for ease of reporting and attribution—if you want two separate tags, include the second tag under a different key. There is no limit to the number of keys in the **clientTags** map

### Example

```dart
EngineSDK( 
bearerToken: '{your_token}', 
channel: '{your_channel}', 
zone: '{your_zone}', 
productTypes: const [engine.ProductType.loan], 
personalInformation: engine.LeadPersonalInformation(/* ...any data you don't want to ask for again */), 
clientTags: const { 
'clientId': ['client1'], 
'trafficsource': ['email'], 
'campaignId': ['campaign1'], 
}, 
// ...optional Event Handlers, please see Event Handler section 
)
```

**Note**: Client Tags are only sent as part of a prefill request. You must provide both a `bearerToken` and prefill data (via the information-class props such as `personalInformation`). If no prefill data is supplied, the SDK makes no prefill call and any `clientTags` you pass are ignored.

### Supported Client Tag Keys for Reporting

If you plan for the Engine team to set up reporting (i.e., you do not plan to hit the Analytics API), these are the only keys that are currently fully supported. If a different key is needed, please reach out to your partner manager—we may be able to accommodate, but adding nonstandard keys will increase the time it takes Engine to report Client Tag values back to you and is therefore not recommended.

* agentId
* campaignId
* clientId
* deviceid
* medium
* sourceId
* subid
* subid1
* subid2
* subid3
* target
* trafficsource
* userid

See the [GET Lead Client Tags](https://engine.tech/docs/api-reference/#get-lead-client-tags) endpoint for information on attributing lead analytics to your own client tags, if you decide to hit the Analytics API for reporting.

## Event Handlers Implementation

The EngineSDK widget exposes optional event callback props that notify your app when key moments occur during the user's journey, across both the personal loan and credit card flows. All callbacks receive a strongly-typed event object containing a timestamp (ISO 8601 UTC) and event-specific fields. For events that vary by product (onRateTableRender and onOfferClick), each field is tagged as Common, Loan only, or Credit Card only.

### Usage

All callbacks are optional. If a callback is not provided, the SDK will still log the event to the debug console in development mode.

Pass any combination of callbacks when constructing the EngineSDK widget:

```dart
EngineSDK(
channel: 'your_channel',
zone: 'your_zone',
bearerToken: '{your_token}',
onInitialize: (event) {
print('SDK initialized at ${event.timestamp}');
},
onCreate: (event) {
print('Lead created: ${event.leadUuid}');
},
onSubmit: (event) {
print('Lead submitted: ${event.leadUuid}');
},
onOfferClick: (event) {
print('Offer clicked: ${event.offerUuid}');
print('Lender: ${event.financialInstitutionName}');
print('APR: ${event.apr}');
},
onExit: (event) {
print('User exited at ${event.timestamp}');
// Navigate the user back or perform cleanup
},
// ...other callbacks
)
```

### Available Events & Properties

| Callback              | Event Type           | Trigger                          |
| --------------------- | -------------------- | -------------------------------- |
| **onInitialize**      | InitializeEvent      | SDK finished loading             |
| **onCreate**          | CreateEvent          | New lead created                 |
| **onUpdate**          | UpdateEvent          | Lead data updated                |
| **onNavigate**        | NavigateEvent        | Page navigation                  |
| **onSubmit**          | SubmitEvent          | Lead form submitted              |
| **onRateTableRender** | RateTableRenderEvent | Rate table displayed with offers |
| **onOfferClick**      | OfferClickEvent      | User clicked a loan offer        |
| **onErrorPageView**   | ErrorPageViewEvent   | Error page displayed in flow     |
| **onErrorPageRetry**  | ErrorPageRetryEvent  | User retried from error page     |
| **onExit**            | ExitEvent            | User exited the SDK              |
| **onEmbedError**      | EmbedErrorEvent      | Web embed failed to load         |
| **onEmbedErrorRetry** | EmbedErrorRetryEvent | User retried after embed failure |

#### onInitialize

Fired when the SDK finishes loading the embedded experience.

| Field         | Type   | Description                                          |
| ------------- | ------ | ---------------------------------------------------- |
| **timestamp** | String | ISO 8601 UTC timestamp of when the event was emitted |

#### onCreate

Fired when a new lead is created in the system.

| Field           | Type   | Description                                          |
| --------------- | ------ | ---------------------------------------------------- |
| **timestamp**   | String | ISO 8601 UTC timestamp of when the event was emitted |
| **leadUuid**    | String | Unique identifier for the newly created lead         |
| **createPage**  | String | The page where the lead was created                  |
| **editingPage** | String | The page that the user is currently editing          |

#### onUpdate

| Field           | Type   | Description                                          |
| --------------- | ------ | ---------------------------------------------------- |
| **timestamp**   | String | ISO 8601 UTC timestamp of when the event was emitted |
| **leadUuid**    | String | Unique identifier for the lead                       |
| **updatePage**  | String | The page where the update occurred                   |
| **editingPage** | String | The page that the user is currently editing          |

#### onNavigate

Fired on page navigation within the flow.

| Field           | Type   | Description                                          |
| --------------- | ------ | ---------------------------------------------------- |
| **timestamp**   | String | ISO 8601 UTC timestamp of when the event was emitted |
| **leadUuid**    | String | Unique identifier for the lead                       |
| **fromPage**    | String | The page the user is navigating away from            |
| **toPage**      | String | The page the user is navigating to                   |
| **editingPage** | String | The page that the user is currently editing          |

#### onSubmit

Fired when the lead form is submitted for offer matching.

| Field         | Type   | Description                                          |
| ------------- | ------ | ---------------------------------------------------- |
| **timestamp** | String | ISO 8601 UTC timestamp of when the event was emitted |
| **leadUuid**  | String | Unique identifier for the submitted lead             |

#### onRateTableRender

Fired when the rate table is rendered with offers. The offer fields populated depend on the product type:

| Field                | Type   | Description                                                            |
| -------------------- | ------ | ---------------------------------------------------------------------- |
| **timestamp**        | String | ISO 8601 UTC timestamp of when the event was emitted *(Common)*        |
| **rateTableUuid**    | String | Unique identifier for the Engine rate table *(Common)*                 |
| **loanOffers**       | List   | Array of loan offers returned for the lead *(Loan only)*               |
| **specialOffers**    | List   | Array of special offers returned for the lead *(Loan only)*            |
| **creditCardOffers** | List   | Array of credit card offers returned for the lead *(Credit Card only)* |

#### onOfferClick

Fired when the user clicks on an offer. The fields populated depend on the product type:

<table><thead><tr><th>Field</th><th width="221.1666259765625">Type</th><th>Description</th></tr></thead><tbody><tr><td><strong>timestamp</strong></td><td>String</td><td>ISO 8601 UTC timestamp of when the event was emitted <em>(Common)</em></td></tr><tr><td><strong>leadUuid</strong></td><td>String</td><td>Unique identifier for the lead <em>(Common)</em></td></tr><tr><td><strong>offerUuid</strong></td><td>String</td><td>Unique identifier for the clicked offer <em>(Common)</em></td></tr><tr><td><strong>financialInstitutionBrandName</strong></td><td>String</td><td>Brand name of the card issuer <em>(Credit Card only)</em></td></tr><tr><td><strong>cardName</strong></td><td>String</td><td>Name of the credit card <em>(Credit Card only)</em></td></tr><tr><td><strong>isITA</strong></td><td>bool</td><td><em>(Credit Card only)</em></td></tr><tr><td><strong>cardNetwork</strong></td><td>String</td><td><em>(Credit Card only)</em></td></tr><tr><td><strong>financialInstitutionName</strong></td><td>String</td><td>Name of the lending institution <em>(Loan only)</em></td></tr><tr><td><strong>financialInstitutionUuid</strong></td><td>String</td><td>Unique identifier for the lending institution <em>(Loan only)</em></td></tr><tr><td><strong>productType</strong></td><td>String</td><td>Type of product (e.g. "loan") <em>(Loan only)</em></td></tr><tr><td><strong>productSubType</strong></td><td>String</td><td>Sub-type of product <em>(Loan only)</em></td></tr><tr><td><strong>loanAmount</strong></td><td></td><td>Loan amount offered <em>(Loan only)</em></td></tr><tr><td><strong>apr</strong></td><td></td><td>Annual percentage rate <em>(Loan only)</em></td></tr><tr><td><strong>termLength</strong></td><td></td><td>Length of the loan term <em>(Loan only)</em></td></tr><tr><td><strong>monthlyPayment</strong></td><td></td><td>Estimated monthly payment <em>(Loan only)</em></td></tr></tbody></table>

#### onErrorPageView

Fired when the error page is displayed within the embedded flow.

| Field           | Type   | Description                                          |
| --------------- | ------ | ---------------------------------------------------- |
| **timestamp**   | String | ISO 8601 UTC timestamp of when the event was emitted |
| **leadUuid**    | String | Unique identifier for the lead                       |
| **fromPage**    | String | The page the user was on before the error            |
| **editingPage** | String | The page that the user was editing                   |

#### onErrorPageRetry

Fired when the user taps "Retry" on the error page within the embedded flow.

| Field           | Type   | Description                                          |
| --------------- | ------ | ---------------------------------------------------- |
| **timestamp**   | String | ISO 8601 UTC timestamp of when the event was emitted |
| **leadUuid**    | String | Unique identifier for the lead                       |
| **toPage**      | String | The page the user is retrying to navigate to         |
| **editingPage** | String | The page that the user was editing                   |

#### onExit

Fired when the user exits the SDK flow (e.g., taps the close button).

| Field         | Type   | Description                                          |
| ------------- | ------ | ---------------------------------------------------- |
| **timestamp** | String | ISO 8601 UTC timestamp of when the event was emitted |

#### onEmbedError

Fired when the embedded web view fails to load (network error, HTTP 4xx/5xx, etc.).

| Field            | Type   | Description                                          |
| ---------------- | ------ | ---------------------------------------------------- |
| **timestamp**    | String | ISO 8601 UTC timestamp of when the event was emitted |
| **errorMessage** | String | Description of the error that occurred               |

#### onEmbedErrorRetry

Fired when the user taps "Retry" after an embed load failure.

| Field            | Type   | Description                                                |
| ---------------- | ------ | ---------------------------------------------------------- |
| **timestamp**    | String | ISO 8601 UTC timestamp of when the event was emitted       |
| **errorMessage** | String | Description of the original error that triggered the retry |

## Changelog

<details>

<summary>View the full Flutter SDK changelog</summary>

### 1.0.0 (2026-07-21)

* Remove deprecated `prefilledData` prop from Flutter SDK
* Prefill is now done via `personalInformation`, `loanInformation`, `mortgageInformation`, `creditInformation`, `financialInformation`, `employmentInformation`, `legalInformation`, `creditCardInformation`, `educationInformation` props.

### 0.1.1 (2026-07-01)

* Added explicit dependency declaration for improved Flutter SDK compatibility

### 0.1.0 (2026-07-01)

* Added support for credit card process in Flutter SDK
* Integrated OpenAPI specifications for improved API type safety and reliability
* Enhanced embed URL resolution to properly handle partner page prefill URLs

### 0.0.8 (2026-05-19)

* Improved error handling by ensuring users can always exit error states
* Enhanced Flutter SDK navigation by adding exit callback support

### 0.0.7 (21 Apr 2026)

* Minor internal improvements

### 0.0.6 (31 Mar 2026)

* Updated event callbacks with new event model
* Removed unused `onClose` event
* Added key for close button in WebView container
* Code formatting and refactoring improvements

### 0.0.5 (24 Mar 2026)

* Enabled prefill API call and updated `LeadPrefillData` to use typed model instead of raw map
* Added lead prefill enums (`LoanPurpose`, `CreditRating`, `PropertyStatus`, `EducationLevel`, `EmploymentStatus`, `PayFrequency`)
* Added input sanitization for prefill data (phone, email, SSN, address, loan amount, bank routing number)
* Improved `ApiException` with truncated `toString()` for better error messages
* Added loading overlay with progress indicator on WebView

### 0.0.3 (6 Mar 2026)

* Added JavaScript channel for SDK events
* Added props to expose to partner app
* Flatten props and refactor code
* Added constants and functions to build embed URL
* Added leads prefill endpoint integration
* Implemented error state handling and updated nav bar
* Updated README and DEVELOPMENT.md

### 0.0.2 (20 Feb 2026)

* Added WebView widget for rendering the Engine marketplace
* Added leads prefill scaffold with basic data models and service layer

### 0.0.1 (9 Feb 2026)

* Initial release - Basic SDK structure and documentation

</details>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://even-financial.gitbook.io/developer-center/marketplace-integrations/mobile-sdks/credit-cards/flutter.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
