Skip to main content

Flutter SDK+ Integration Guide

This page explains how to implement the Flutter SDK+ for Rokt Ecommerce. Select your target platform to see the full integration guide for that platform.

tip

Work with your Rokt account manager to first implement the SDK+ in a development environment so you can thoroughly test before going live.

1. Add the Rokt SDK to Your iOS AppDirect link to 1. Add the Rokt SDK to Your iOS App

Rokt SDK+ requires a minimum deployment target of iOS 15.0.

Add the following pods to your ios/Podfile:

ios/Podfile
pod 'mParticle-Apple-SDK', '~> 9.0'
pod 'mParticle-Rokt', '~> 9.0'
pod 'RoktPaymentExtension', '~> 1.0'

2. Initialize the Rokt SDKDirect link to 2. Initialize the Rokt SDK

Insert the following initialization snippet in your AppDelegate file. Replace your-key and your-secret with the values provided by your Rokt team.

AppDelegate initialization
import mParticle_Apple_SDK
import RoktPaymentExtension

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Initialize the SDK
let options = MParticleOptions(key: "your-key",
secret: "your-secret")
// Specify the data environment with environment:
// Set it to .development if you are still testing your integration.
// Set it to .production if your integration is ready for production data.
// The default is .autoDetect which attempts to detect the environment automatically
options.environment = .development
// Identify the current user:
let identifyRequest = MPIdentityApiRequest.withEmptyUser()

// If you're using an un-hashed email address, set it in 'email'.
identifyRequest.email = "j.smith@example.com"

// If you're using a hashed email address, set it in 'other' instead of email
identifyRequest.setIdentity("sha256 hashed email goes here", identityType: .other)

// If the user is identified with their email address, set additional user attributes.
options.identifyRequest = identifyRequest
options.onIdentifyComplete = {(result: MPIdentityApiResult?, error: Error?) in
if let user = result?.user {
user.setUserAttribute("example attribute key", value: "example attribute value")
}
}
MParticle.sharedInstance().start(with: options)

// Register after MParticle.sharedInstance().start(), before selectShoppableAds
if let paymentExt = RoktPaymentExtension(
applePayMerchantId: "merchant.com.yourapp.rokt"
) {
MParticle.sharedInstance().rokt.registerPaymentExtension(paymentExt)
}
return true
}

When inserting the initialization snippet, you will see customizable fields for:

  1. Entering your Rokt key and secret.

    Set key and secret to the values provided by your Rokt account manager.

  2. Setting your data environment.

    Set environment to .development (Swift) or MPEnvironmentDevelopment (Objective-C) while testing to route data to the Development environment, and .production or MPEnvironmentProduction to send live customer activity to Production.

  3. Identifying your user and setting attributes.

    In identifyRequest, pass the user's raw, un-hashed email in the email property. Once identified, use the onIdentifyComplete callback to set additional user attributes.

    note

    Always include identifyRequest in the initialization snippet. If you don't have the user's email at initialization, omit the assignment — the SDK will still initialize, and you can identify the user later via Step 4: Identify the User. See Appendix C: Error Handling for how to handle identity failures — without error handling you may see data consistency issues at scale.

  4. Registering the payment extension.

    Register RoktPaymentExtension after MParticle.sharedInstance().start() and before selectShoppableAds to enable Apple Pay. See Step 8: Configure Apple Pay.

3. Add the Flutter PackageDirect link to 3. Add the Flutter Package

Add the mparticle_flutter_sdk package to your Flutter project:

flutter pub add mparticle_flutter_sdk

After adding the dependency, the following (or similar) lines are added to your pubspec.yaml:

dependencies:
mparticle_flutter_sdk: ^2.0.0

Import the package into your Dart code and get an instance of mParticle:

import 'package:mparticle_flutter_sdk/mparticle_flutter_sdk.dart';

MparticleFlutterSdk? mpInstance = await MparticleFlutterSdk.getInstance();

4. Identify the UserDirect link to 4. Identify the User

Call the identify method with a fresh identityRequest any time the user provides their email address after the SDK has initialized (for example, when they log in, create an account, or make a purchase). This ensures event data is attributed to the correct user.

Supported User IdentifiersDirect link to Supported User Identifiers

Show supported user identifiers
IdentifierTypeDescription
emailstringPass the customer's raw, unhashed email address.
mobile_numberstringPass the customer's phone number in E.164 format.
customerIdstringPass your internal customer/account identifier. Send on every screen for logged-in users.
otherstringPass a SHA-256-hashed email. Only use when the raw email cannot be provided — do not pass both email and other.
other2stringPass a SHA-256-hashed mobile number. Only use when the raw mobile number cannot be provided — do not pass both mobile_number and other2.

To identify the user:

  1. Create an identityRequest object to contain the user's identifiers. You should integrate the user's raw, unhashed email address into the email field.

  2. To set additional user attributes, use the then success handler on the identify call. If the identityRequest succeeds, any user attributes you set inside the handler are assigned to the identified user.

  3. After creating the identityRequest, call the identify method, passing in the request object.

    For example, to identify a user named Jane Smith with the email address j.smith@example.com, mobile number +13125551515, and customer ID cust_10482, you would use:

    Identify Jane Smith
    import 'package:mparticle_flutter_sdk/identity/identity_type.dart';
    import 'package:mparticle_flutter_sdk/identity/identity_api_result.dart';
    import 'package:mparticle_flutter_sdk/identity/identity_api_error_response.dart';

    // 1. Create the identityRequest object
    var identityRequest = MparticleFlutterSdk.identityRequest;
    // Preferred: pass the customer's raw, unhashed email.
    // If you can only provide a SHA-256-hashed email, remove the Email line and use IdentityType.Other instead — do not pass both.
    identityRequest.setIdentity(identityType: IdentityType.Email, value: 'j.smith@example.com');
    identityRequest.setIdentity(identityType: IdentityType.Other, value: 'SHA-256 hashed email'); // only if raw email unavailable
    // If you can only provide a SHA-256-hashed mobile number, use IdentityType.Other2 instead of MobileNumber — do not pass both.
    identityRequest.setIdentity(identityType: IdentityType.Other2, value: 'SHA-256 hashed mobile number'); // only if raw mobile unavailable
    identityRequest.setIdentity(identityType: IdentityType.MobileNumber, value: '+13125551515');
    identityRequest.setIdentity(identityType: IdentityType.CustomerId, value: 'cust_10482');

    // 2. User attributes are set in the success handler
    // 3. Call the identify method
    mpInstance?.identity
    .identify(identityRequest: identityRequest)
    .then(
    (IdentityApiResult successResponse) {
    successResponse.user.setUserAttribute('first_name', 'Jane');
    successResponse.user.setUserAttribute('last_name', 'Smith');
    },
    onError: (error) {
    var failureResponse = error as IdentityAPIErrorResponse;
    print("Failure Response: $failureResponse");
    }
    );

5. Set User AttributesDirect link to 5. Set User Attributes

Set user attributes progressively as the user navigates your app, not just at checkout. The more attributes you set, the better Rokt can resolve the customer and deliver relevant offers.

Set user attributes
import 'package:mparticle_flutter_sdk/mparticle_flutter_sdk.dart';

// Retrieve the current user. This will only succeed if you have identified the user during SDK initialization or by calling the identify method.
var currentUser = await mpInstance?.getCurrentUser();

// Once you have successfully set the current user to `currentUser`, you can set user attributes with:
currentUser?.setUserAttribute(key: 'custom-attribute-name', value: 'custom-attribute-value');
// Note: all user attributes (including list attributes and tags) must have distinct names.

// Rokt recommends setting as many of the following user attributes as possible:
currentUser?.setUserAttribute(key: 'first_name', value: 'John');
currentUser?.setUserAttribute(key: 'last_name', value: 'Doe');
// Phone numbers can be formatted either as '1234567890', or '+1 (234) 567-8901'
currentUser?.setUserAttribute(key: 'mobile', value: '3125551515');
currentUser?.setUserAttribute(key: 'age', value: '33');
currentUser?.setUserAttribute(key: 'gender', value: 'M');
currentUser?.setUserAttribute(key: 'city', value: 'Brooklyn');
currentUser?.setUserAttribute(key: 'state', value: 'NY');
currentUser?.setUserAttribute(key: 'zip', value: '123456');
currentUser?.setUserAttribute(key: 'dob', value: 'yyyymmdd');
currentUser?.setUserAttribute(key: 'title', value: 'Mr');
currentUser?.setUserAttribute(key: 'language', value: 'en');
currentUser?.setUserAttribute(key: 'lifetime_value', value: '52.25');
currentUser?.setUserAttribute(key: 'predicted_ltv', value: '136.23');

// You can create a user attribute to contain a list of values
var attributeList = <String>[];
attributeList.add('documentary');
attributeList.add('comedy');
attributeList.add('romance');
attributeList.add('drama');
currentUser?.setUserAttributeArray(key: 'favorite-genres', value: attributeList);

// To remove a user attribute, call removeUserAttribute and pass in the attribute name. All user attributes share the same key space.
currentUser?.removeUserAttribute(key: 'attribute-to-remove');

User AttributesDirect link to User Attributes

Set as many of the following as you can collect:

Show all user attributes
AttributeTypeDescription
first_namestringCustomer's first name. Used for personalization.
last_namestringCustomer's last name. Used for personalization.
mobilestringPhone number formatted as 1112345678 or +1 (222) 345-6789. Used for identity resolution and relevance.
ageintegerCustomer's age. Alternate to dob. Used for eligibility and relevance.
dobstringDate of birth, yyyymmdd. Alternate to age. Used for eligibility and relevance.
genderstringCustomer's gender. For example, M, F, Male, or Female. Used for relevance.
titlestringHonorific. For example, Mr, Mrs, Ms. Used for personalization.
languagestringISO 639-1 language code associated with the purchase. Used for relevance.
citystringBilling city. Used for relevance.
statestringBilling state / province / region. Used for relevance and eligibility.
zipstringFull ZIP or postcode (US preference is ZIP+4). Used for identity resolution and relevance.
countrystringISO 3166-1 alpha-2 country code (e.g. US, GB, AU). Used for eligibility and relevance.
new_customerbooleanWhether this is a first-time buyer. Used for relevance.
customer_typestringWhether the user is authenticated (guest / logged_in). Used for relevance.
loyalty_tierstringPartner loyalty program tier. Used for relevance and eligibility.
loyalty_idstringLoyalty program member ID. Used for identity resolution.
lifetime_valuedecimalCustomer's cumulative purchase value, as a string (e.g. "52.25"). Used for relevance.
predicted_ltvdecimalPredicted total lifetime value, typically from a partner ML model. Distinct from lifetime_value. Used for relevance.
subscription_statusstringSubscription state if applicable (active, trial, churned, paused, none). Used for relevance and eligibility.
customer_segmentstringPartner internal segmentation (e.g. vip, at_risk, new, reactivated). Used for relevance.
utm_sourcestringMarketing attribution source. Used for relevance.
utm_mediumstringMarketing attribution medium. Used for relevance.
utm_campaignstringMarketing attribution campaign. Used for relevance.

All user attributes (including list attributes) must have distinct names.

6. Track Funnel EventsDirect link to 6. Track Funnel Events

Track screen views, account lifecycle events, commerce events, and custom events so Rokt can maintain identity continuity and understand where each customer is in their journey.

Screen ViewsDirect link to Screen Views

Call mpInstance?.logScreenEvent() with the name of the screen (e.g. 'homepage', 'product detail page'). Include any additional custom attributes in the event's customAttributes map.

Log a screen view
import 'package:mparticle_flutter_sdk/events/screen_event.dart';

ScreenEvent screenEvent = ScreenEvent(eventName: 'homepage')
..customAttributes = {'custom-attribute': 'custom-value'};
mpInstance?.logScreenEvent(screenEvent);

Account Lifecycle EventsDirect link to Account Lifecycle Events

Log account lifecycle events when the user signs up, logs in, or logs out so Rokt can maintain identity continuity across sessions and devices. Signup and login events accept a method attribute describing how the user signed up or logged in.

Supported lifecycle event typesDirect link to Supported lifecycle event types

Show lifecycle event types
Lifecycle Event TypeWhen to triggerSupported method values
sign_upNew account createdemail, social, guest
loginUser logs inemail, social, sso
logoutUser logs outNot applicable.

Example lifecycle eventsDirect link to Example lifecycle events

Signup, login, logout
import 'package:mparticle_flutter_sdk/events/event_type.dart';
import 'package:mparticle_flutter_sdk/events/mp_event.dart';

// Signup event
MPEvent signupEvent = MPEvent(
eventName: 'sign_up',
eventType: EventType.Other)
..customAttributes = {'method': 'email'};
mpInstance?.logEvent(signupEvent);

// Login event
MPEvent loginEvent = MPEvent(
eventName: 'login',
eventType: EventType.Other)
..customAttributes = {'method': 'email'};
mpInstance?.logEvent(loginEvent);

// Logout event
MPEvent logoutEvent = MPEvent(
eventName: 'logout',
eventType: EventType.Other);
mpInstance?.logEvent(logoutEvent);

Commerce EventsDirect link to Commerce Events

Commerce events carry product-level details for the user's journey. Trigger a separate commerce event for each product action the customer takes.

Investing in full commerce event coverage is one of the highest-leverage things you can do during your integration. Each event tells Rokt something different about where the customer is in their journey: a product view signals exploration, an add-to-cart signals consideration, a checkout start signals purchase intent, and a completed purchase confirms conversion. With a richer signal, Rokt can personalize offers more effectively, measure placement performance accurately, and attribute conversions to the right touchpoints. Doing this work during your initial integration also avoids a retrofit later. The signal compounds over time: each event Rokt receives adds context used to sharpen personalization, improve attribution accuracy, and better resolve and segment your customer base on future visits.

Commerce events are logged with CommerceEvent, using a ProductActionType that identifies the customer action (viewing a product, adding to cart, starting checkout, completing a purchase, etc.). The sections below list the supported action types and walk through assembling the event.

Product action typesDirect link to Product action types

Show all product action types
Customer actionProduct action constant
Product detail page viewedProductActionType.ViewDetail
Product clickedProductActionType.Click
Item added to cartProductActionType.AddToCart
Item removed from cartProductActionType.RemoveFromCart
Item added to wishlistProductActionType.AddToWishList
Item removed from wishlistProductActionType.RemoveFromWishlist
Checkout flow initiatedProductActionType.Checkout
Checkout option selectedProductActionType.CheckoutOption
Order confirmedProductActionType.Purchase
Order refundedProductActionType.Refund

Tracking a commerce event requires three steps:

1. Define the productDirect link to 1. Define the product

Create a Product with the product's name, SKU, and price. Set additional fields as needed.

Define a product
import 'package:mparticle_flutter_sdk/events/product.dart';

// Create an optional map of custom attributes for the product
final customAttributes = {
'ocean-view': 'true',
'balcony': 'false',
};

Product product = Product(
name: 'Double Room - Econ Rate',
sku: 'econ-1',
price: 100.00,
);
product.quantity = 4;

// Include the map of custom attributes
product.attributes = customAttributes;

2. Summarize the transactionDirect link to 2. Summarize the transaction

Create a TransactionAttributes object for ProductActionType.Purchase, ProductActionType.Checkout, and ProductActionType.CheckoutOption events. Include shipping and coupon code when applicable — order-level coupons belong here, not on individual products.

Summarize the transaction
import 'package:mparticle_flutter_sdk/events/transaction_attributes.dart';

final TransactionAttributes transactionAttributes = TransactionAttributes(
transactionID: 'ORDER-12345',
revenue: 149.99,
tax: 12.50,
shipping: 5.99,
couponCode: 'SUMMER20',
);

3. Log the commerce eventDirect link to 3. Log the commerce event

Create a CommerceEvent with a product action constant from the table above, attach the transactionAttributes, and log it.

Log a Purchase commerce event
import 'package:mparticle_flutter_sdk/events/commerce_event.dart';
import 'package:mparticle_flutter_sdk/events/product_action_type.dart';

CommerceEvent event = CommerceEvent.withProduct(
productActionType: ProductActionType.Purchase,
product: product,
);
event.transactionAttributes = transactionAttributes;

// Optional custom attributes for the purchase event
event.customAttributes = {'sale': 'true'};

mpInstance?.logCommerceEvent(event);

The same structure applies to every product action constant — swap ProductActionType.Purchase for the action that matches the customer behavior you're logging. See the Product action types table for the full list.

Custom EventsDirect link to Custom Events

Track custom events using MPEvent, passing an event name, event type, and optional custom attributes.

Supported custom event typesDirect link to Supported custom event types

Show custom event types
TypeUse for
EventType.NavigationUser navigation flows and screen transitions within your app.
EventType.LocationLocation-based interactions and movements.
EventType.SearchSearch queries and search-related actions.
EventType.TransactionFinancial transactions and purchase-related activity.
EventType.UserContentUser-generated content like reviews, comments, or posts.
EventType.UserPreferenceUser settings, preferences, and customization choices.
EventType.SocialSocial media interactions and sharing activities.
EventType.OtherAnything that doesn't fit the categories above.

Example custom eventDirect link to Example custom event

Log a custom event
import 'package:mparticle_flutter_sdk/events/event_type.dart';
import 'package:mparticle_flutter_sdk/events/mp_event.dart';

MPEvent event = MPEvent(
eventName: 'Video Watched',
eventType: EventType.Navigation)
..customAttributes = {
'category': 'Destination Intro',
'title': 'Paris',
};
mpInstance?.logEvent(event);

7. Show a PlacementDirect link to 7. Show a Placement

Call selectPlacements on every payment and confirmation screen you want Rokt to render content on. Include one of the following page identifiers to specify the screen type and whether it's for testing or production:

  • stg.rokt.conf: A confirmation screen in a staging (or testing) environment.
  • prod.rokt.conf: A confirmation screen in a production environment.
  • stg.rokt.payments: A payments screen in a staging (or testing) environment.
  • prod.rokt.payments: A payments screen in a production environment.

Placement AttributesDirect link to Placement Attributes

Pass these attributes in the attributes map of selectPlacements. Always supply the most recent value — attributes passed here override any earlier setUserAttribute calls.

Show all placement attributes
AttributeTypeDescription
emailstringCustomer email (unhashed). Used for identity resolution.
first_namestringCustomer first name. Used for personalization.
last_namestringCustomer last name. Used for personalization.
mobilestringCustomer mobile number in E.164 format. Used for identity resolution.
confirmation_refstringOrder / confirmation reference number. Used for relevance and deduplication.
currencystringTransaction currency (ISO 4217, e.g. USD, GBP, AUD). Used for relevance.
countrystringISO 3166-1 alpha-2 country code. Used for eligibility and relevance.
languagestringCustomer's preferred language (ISO 639-1). Used for relevance.
total_pricedecimalTotal cart value including tax and shipping. Used for relevance.
amountstringCart subtotal before tax and shipping. Distinct from total_price. Used for relevance and Shoppable Ads.
cart_item_countintegerNumber of items in the cart. Used for relevance.
coupon_codestringPromo code applied to the order, if any. Used for relevance.
new_customerbooleanWhether this is a first-time buyer. Used for relevance.
customer_typestringguest or logged_in. Used for relevance.
lifetime_valuedecimalCustomer's cumulative purchase value (e.g. "2340.00"). Used for relevance.
subscription_statusstringSubscription state if applicable (active, trial, churned, paused, none). Used for relevance and eligibility.
customer_segmentstringPartner internal segmentation (e.g. vip, at_risk, new, reactivated). Used for relevance.
payment_typestringPayment method selected (credit_card, paypal, apple_pay, etc.). Used for Pay+ eligibility and Shoppable Ads payment method prioritization.
payment_service_providerstringPayment services offered on the page (apple_pay, paypal, card). Used for Pay+ eligibility.
ccbinstringCredit card BIN (first 6 digits). Used for relevance.
billing_address1stringBilling street address. Used for identity resolution and relevance.
billing_address2stringBilling apartment / unit. Used for identity resolution.
billing_citystringBilling city. Used for relevance.
billing_statestringBilling state or province. Used for relevance.
billing_zipcodestringBilling ZIP / postcode. Used for identity resolution and relevance.
shipping_methodstringShipping method selected (standard, express, next_day). Used for relevance.
shipping_address1stringShipping street address. Used for relevance and Shoppable Ads order fulfillment.
shipping_citystringShipping city. Used for relevance and Shoppable Ads order fulfillment.
shipping_statestringShipping state or province. Used for relevance and Shoppable Ads order fulfillment.
shipping_zipcodestringShipping ZIP or postcode. Used for relevance and Shoppable Ads order fulfillment.
shipping_countrystringShipping country (ISO 3166-1 alpha-2). Used for relevance and Shoppable Ads order fulfillment.
ads_experiencestringPass "shoppable" when deliberately selecting a Shoppable Ads experience.

Overlay PlacementsDirect link to Overlay Placements

Overlay placements render on top of your confirmation screen in a Rokt-managed container, requiring no changes to your app's existing layout.

To insert an overlay placement, call selectPlacements once the confirmation screen loads:

Overlay placement
import 'package:mparticle_flutter_sdk/mparticle_flutter_sdk.dart';

final attributes = {
// Identity
'email': 'j.smith@example.com',
'first_name': 'Jenny',
'last_name': 'Smith',
'mobile': '+13125551515',

// Transaction
'confirmation_ref': '54321',
'currency': 'USD',
'country': 'US',
'language': 'en',
'total_price': '149.99',
'cart_item_count': '2',
'coupon_code': 'SUMMER20',

// Customer context
'new_customer': 'false',
'customer_type': 'logged_in',
'lifetime_value': '2340.00',
'subscription_status': 'active',
'customer_segment': 'vip',

// Payment (include payment_type and payment_service_provider for Pay+)
'payment_type': 'credit_card',
'payment_service_provider': 'card',
'ccbin': '411112',

// Billing address
'billing_address1': '123 Main St',
'billing_city': 'Brooklyn',
'billing_state': 'NY',
'billing_zipcode': '11201',

// Shipping
'shipping_method': 'express',
'shipping_address1': '175 Varick St',
'shipping_city': 'New York',
'shipping_state': 'NY',
'shipping_zipcode': '10014',
'shipping_country': 'US',
};

final roktConfig = RoktConfig(
colorMode: ColorMode.light,
);

mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
roktConfig: roktConfig,
);

Embedded PlacementsDirect link to Embedded Placements

Embedded placements render inline at a fixed position in your app that you control (for example, above the payment options on a cart screen). Both Thanks and Pay+ use embedded placements, but Pay+ must use embedded placements.

Use the RoktLayout widget to embed a placement in your Flutter UI. The onLayoutCreated callback fires when the widget is created.

Embedded placement with RoktLayout
import 'package:mparticle_flutter_sdk/mparticle_flutter_sdk.dart';

final attributes = {
'email': 'j.smith@example.com',
'first_name': 'Jenny',
'last_name': 'Smith',
'billing_zipcode': '90210',
'confirmation_ref': '54321',
};

const RoktLayout(
placeholderName: 'RoktEmbedded1',
onLayoutCreated: () {
// Layout created
}
);

mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
);
Pay+

For Pay+ placements, include payment_type and payment_service_provider in the selectPlacements call on each screen. payment_service_provider communicates what payment methods are available on the payment screen; payment_type communicates what method the user paid with.

Interstitial Placements (iOS Only)Direct link to Interstitial Placements (iOS Only)

Interstitial placements are rendered between the payment and confirmation screens, allowing customers to purchase additional products. Interstitial placements are used by Shoppable Ads.

note

Interstitial placements (Shoppable Ads) are supported on iOS only in the Flutter SDK. The Android path does not support interstitial placements.

Requires SDK+ 2.0

Shoppable Ads require mparticle_flutter_sdk 2.0.0 or later and mParticle-Apple-SDK ~> 9.0. If you are still on 1.x, follow the SDK+ 2.0 migration guide before proceeding.

iOS native setupDirect link to iOS native setup

Add the Stripe payment extension to your iOS Podfile:

ios/Podfile
pod 'RoktStripePaymentExtension', '~> 0.1'

Register the payment extension in your AppDelegate.swift after SDK initialization:

ios/Runner/AppDelegate.swift
import mParticle_Apple_SDK
import RoktStripePaymentExtension

// In application(_:didFinishLaunchingWithOptions:), after MParticle.sharedInstance().start(with: options)
if let stripeExt = RoktStripePaymentExtension(applePayMerchantId: "merchant.com.yourapp.rokt") {
MParticle.sharedInstance().rokt.registerPaymentExtension(stripeExt)
}
note

The Stripe publishable key is automatically provided from the mParticle dashboard configuration. You only need to provide the Apple Pay merchant ID.

caution

You must call registerPaymentExtension after SDK initialization and before calling selectShoppableAds from your Dart code. If no payment extension is registered, selectShoppableAds will fire a PlacementFailure event.

Display Shoppable AdsDirect link to Display Shoppable Ads

Call selectShoppableAds from your Dart code once all required attributes are available. Shoppable Ads always display as an overlay — no embedded views are needed.

Interstitial placement (iOS only)
final attributes = {
'email': 'j.smith@example.com',
'first_name': 'Jenny',
'last_name': 'Smith',
'confirmation_ref': 'ORD-12345',
'amount': '52.25',
'currency': 'USD',
'payment_type': 'visa',
'shipping_address1': '123 Main St',
'shipping_city': 'New York',
'shipping_state': 'NY',
'shipping_zipcode': '10001',
'shipping_country': 'US',
};

mpInstance?.rokt.selectShoppableAds(
identifier: 'ConfirmationPage',
attributes: attributes,
);

Shoppable Ads events are delivered via the MPRoktEvents EventChannel — see the Events API section below.

Optional FunctionsDirect link to Optional Functions

FunctionPurpose
Rokt.close()Auto-close overlay placements.

Additional ConfigurationDirect link to Additional Configuration

Pass optional parameters such as RoktConfig to customize the placement UI (e.g. dark/light mode, caching). Font file paths can also be supplied as a map of PostScript names to asset paths.

selectPlacements with RoktConfig and font typefaces
// If you want to use custom fonts for your placement, create a fontTypefaces map
final fontTypefaces = {'Arial-Bold': 'fonts/Arial-Bold.ttf'};

final roktConfig = RoktConfig(
colorMode: ColorMode.light,
);

mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
fontFilePathMap: fontTypefaces,
roktConfig: roktConfig,
);
note

If you want to update the identifier RoktExperience or embedded identifier RoktEmbedded1 with a different value, contact your Rokt account manager to ensure Rokt placements are configured consistently.

Events APIDirect link to Events API

The SDK provides placement lifecycle events as a stream through the MPRoktEvents EventChannel. Subscribe to this stream to respond to placement load state, engagement, failures, and Shoppable Ads purchase flows.

Subscribe to placement events
final EventChannel roktEventChannel = EventChannel('MPRoktEvents');
roktEventChannel.receiveBroadcastStream().listen((dynamic event) {
debugPrint('rokt_event: $event');
});

Standard eventsDirect link to Standard events

Show all standard events
EventDescriptionParams
ShowLoadingIndicatorTriggered before the SDK calls the Rokt backend.
HideLoadingIndicatorTriggered when the SDK receives a success or failure from the Rokt backend.
PlacementInteractiveTriggered when a placement has been rendered and is interactable.identifier: String
PlacementReadyTriggered when a placement is ready to display but has not rendered content yet.identifier: String
OfferEngagementTriggered when the user engages with the offer.identifier: String
PositiveEngagementTriggered when the user positively engages with the offer.identifier: String
FirstPositiveEngagementTriggered when the user positively engages with the offer for the first time.identifier: String, fulfillmentAttributes: FulfillmentAttributes
OpenUrlTriggered when the user presses a URL that is configured to be sent to the partner app.identifier: String, url: String
PlacementClosedTriggered when a placement is closed by the user.identifier: String
PlacementCompletedTriggered when the offer progression reaches the end and no more offers are available to display. Also triggered when cache is hit but the retrieved placement will not be displayed as it has previously been dismissed.identifier: String
PlacementFailureTriggered when a placement could not be displayed due to some failure or when no placements are available to show.identifier: String (optional)
EmbeddedSizeChangedTriggered when an embedded placement's height changes.identifier: String, selectedHeight: Double
CartItemInstantPurchaseTriggered when the catalog item purchase is initiated by the user.identifier: String, catalogItemId: String, cartItemId: String, totalPrice: String, currency: String
CartItemInstantPurchaseInitiatedPurchase flow started — user tapped "Buy" (Shoppable Ads, iOS only).identifier: String, catalogItemId: String, cartItemId: String
CartItemInstantPurchaseFailurePurchase failed (Shoppable Ads, iOS only).identifier: String, catalogItemId: String, cartItemId: String, error: String
CartItemDevicePayApple Pay / device payment triggered (Shoppable Ads, iOS only).identifier: String, catalogItemId: String, cartItemId: String, paymentProvider: String
InstantPurchaseDismissalUser dismissed the purchase overlay (Shoppable Ads, iOS only).identifier: String

8. Configure Apple Pay (iOS Only)Direct link to 8. Configure Apple Pay (iOS Only)

Apple Pay is required for Shoppable Ads on iOS. If you are not using Shoppable Ads, skip this step.

Before registering a payment extension, you need to create an Apple Pay merchant ID, configure your Xcode project, and generate a Payment Processing Certificate.

Follow the steps in Apple Pay — iOS setup, then ensure your AppDelegate calls registerPaymentExtension after MParticle.sharedInstance().start() and before selectShoppableAds. The registration snippet is included in the initialization code above.

9. Test Your IntegrationDirect link to 9. Test Your Integration

To confirm the SDK initializes and events log correctly:

  1. Enable verbose SDK logging before initialization so you can see what's being sent.
  2. Build and run your app with the development environment set: environment = .development (Swift) or MPEnvironmentDevelopment (Objective-C).
  3. Trigger selectPlacements on the screen where the placement should render and confirm the placement loads.
  4. Verify events appear in your mParticle workspace's Live Stream, and confirm the identify call succeeds.
  5. Check the Xcode console for Rokt SDK log output.
Enable verbose SDK logging
// Enable mParticle debug logging at the Dart level
MparticleFlutterSdk.setLogLevel(LogLevel.verbose);

TroubleshootingDirect link to Troubleshooting

If the placement doesn't render or events don't appear, check the Xcode console for Rokt SDK errors. Common issues:

Initialization errorsDirect link to Initialization errors

  • Confirm the key and secret match the values from your Rokt account manager.
  • Confirm native SDK initialization runs before any selectPlacements or logEvent call from your Dart code.
  • For Shoppable Ads on iOS, confirm RoktStripePaymentExtension is registered after SDK initialization and before selectShoppableAds.

Identity errorsDirect link to Identity errors

If the identify call's onError handler fires, inspect the IdentityAPIErrorResponse for the status code and retry the request according to your business logic. Without error handling you may see data consistency issues at scale.

Placement not renderingDirect link to Placement not rendering

  • Confirm the placement identifier (e.g. RoktExperience) matches what your Rokt account manager configured.
  • For embedded placements, confirm the embedded view identifier (e.g. RoktEmbedded1) matches the layout configuration.
  • Check that the attributes map contains at least email, first_name, last_name, billing_zipcode, and confirmation_ref.

AppendixDirect link to Appendix

Appendix A: App ConfigurationDirect link to Appendix A: App Configuration

Applications can pass configuration settings through RoktConfig so the SDK uses your app's custom configuration instead of system defaults.

ColorMode objectDirect link to ColorMode object

ValueDescription
lightApplication is in Light Mode
darkApplication is in Dark Mode
systemApplication defaults to System Color Mode
RoktConfig with ColorMode
final roktConfig = RoktConfig(
colorMode: ColorMode.light,
);

mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
roktConfig: roktConfig,
);

CacheConfig objectDirect link to CacheConfig object

ParameterDescription
cacheDurationInSecondsOptional duration in seconds for which the Rokt SDK should cache the experience. Maximum allowed value is 90 minutes; default is 90 minutes if not provided or invalid.
cacheAttributesOptional attributes to be used as cache key. If null, all attributes sent in selectPlacements will be used as the cache key.
Cache for 1200 seconds
// Cache the experience for 1200 seconds, using email and orderNumber as the cache key.
final roktConfig = RoktConfig(
cacheConfig: CacheConfig(
cacheDurationInSeconds: 1200,
cacheAttributes: {'email': 'j.smith@example.com', 'orderNumber': '123'},
),
);

mpInstance?.rokt.selectPlacements(
identifier: 'RoktExperience',
attributes: attributes,
roktConfig: roktConfig,
);

Appendix B: SwiftUI Support with MPRoktLayoutDirect link to Appendix B: SwiftUI Support with MPRoktLayout

If your app is primarily written in SwiftUI, the MPRoktLayout component provides a more modern, declarative approach to integrating Rokt placements in your iOS app.

The MPRoktLayout class provides a SwiftUI-compatible way to display Rokt placements without manually calling selectPlacements, supporting both overlay and embedded placement types.

SwiftUI placement with MPRoktLayout
import SwiftUI
import mParticle_Apple_SDK
import mParticle_Rokt_Swift

struct OrderConfirmationView: View {
let attributes = [
"email": "test@gmail.com",
"first_name": "Jenny",
"last_name": "Smith",
"billing_zipcode": "07762",
"confirmation_ref": "54321"
]

@State private var sdkTriggered = true

var body: some View {
VStack(alignment: .leading) {
// Other UI components
Text("Order Confirmation")
.font(.title)

// Rokt placement using SwiftUI
MPRoktLayout(
sdkTriggered: $sdkTriggered,
identifier: "RoktExperience",
locationName: "RoktEmbedded1", // For embedded placements
attributes: attributes,
config: roktConfig, // Optional RoktConfig
onEvent: { roktEvent in
// Optional: Handle different event types see above
}
).roktLayout
}
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
}
}
ParameterTypeDescription
sdkTriggeredBoolControls when the placement should be triggered.
identifierStringThe Rokt placement identifier (e.g., "RoktExperience").
locationNameString?Optional location name for embedded placements (e.g., "RoktEmbedded1").
attributes[String: String]Dictionary of attributes to pass to the placement.
configRoktConfig?Optional configuration object for color mode, caching, etc.
onEvent((RoktEvent) -> Void)?Optional callback to handle all placement events.

Appendix C: Error HandlingDirect link to Appendix C: Error Handling

The IDSync API is intended to be central to your app's state and is designed to be fast and highly-available. Similar to how your app may prevent users from logging in, logging out, or modifying their state without an internet connection — treat these APIs as gating operations to maintain a consistent user state. The SDK will not retry API calls automatically, but provides callback APIs so you can do so according to your business logic.

If you do not implement error handling, you may see data consistency issues at scale.

IDSync error handling
import 'package:mparticle_flutter_sdk/identity/identity_api_result.dart';
import 'package:mparticle_flutter_sdk/identity/identity_api_error_response.dart';

mpInstance?.identity
.identify(identityRequest: identityRequest)
.then(
(IdentityApiResult successResponse) {
// Proceed with the identified user
},
onError: (error) {
var failureResponse = error as IdentityAPIErrorResponse;
// Inspect failureResponse.statusCode to determine the error type:
// - Check for network errors (device offline) and retry the request
// - Check for throttle errors (429) and retry with backoff
print('Identity error: $failureResponse');
}
);

Client-side error codesDirect link to Client-side error codes

The MPIdentityErrorResponseCode enum defines the following client-side codes:

MPIdentityErrorResponseCodeDescription
MPIdentityErrorResponseCodeRequestInProgressThe IDSync HTTP request was not performed as there is already an IDSync HTTP request in progress.
MPIdentityErrorResponseCodeClientSideTimeoutThe IDSync HTTP request failed due to a TCP connection timeout.
MPIdentityErrorResponseCodeClientNoConnectionThe IDSync HTTP request failed due to lack of network coverage.
MPIdentityErrorResponseCodeSSLErrorThe IDSync HTTP request failed due to an SSL configuration issue.
MPIdentityErrorResponseCodeOptOutThe IDSync HTTP request was not performed due to the SDK being disabled due to opt-out.
MPIdentityErrorResponseCodeUnknownThe IDSync HTTP request failed due to an unknown error.

HTTP status codesDirect link to HTTP status codes

ValueDescription
400The IDSync HTTP call failed due to an invalid request body.
401The IDSync HTTP call failed due to an authentication error. Verify that your API key is correct.
429The IDSync HTTP call was throttled and should be retried.
5xxThe IDSync HTTP call failed due to an mParticle server-side issue.

Appendix D: Passing Session ID from Web to NativeDirect link to Appendix D: Passing Session ID from Web to Native

When a user journey spans both web and native platforms, you can maintain a consistent Rokt session by passing the session ID from the Web SDK to the mParticle Flutter SDK. This is useful for hybrid flows where users complete an action in a WebView (such as a payment page) and return to the native app for confirmation.

Getting the session ID from Web SDKDirect link to Getting the session ID from Web SDK

After calling selectPlacements, the session ID is available on the selection context:

Retrieve sessionId from the selection context
const selection = await launcher.selectPlacements({
identifier: "checkout",
attributes: {
email: "user@example.com",
// ... other attributes
}
});

const sessionId = await selection.context.sessionId;

Pass the session ID to your native app using a deep link:

Deep-link to native app
const deepLink = `myapp://confirmation?sessionId=${encodeURIComponent(sessionId)}`;
window.location.href = deepLink;

Setting the session ID on iOSDirect link to Setting the session ID on iOS

Extract the session ID from the deep link and pass it to the native mParticle SDK before calling selectPlacements. Add this to your AppDelegate.swift:

Handle deep link and set sessionId (iOS)
func handleDeepLink(url: URL) {
let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
if let sessionId = components?.queryItems?.first(where: { $0.name == "sessionId" })?.value {
MParticle.sharedInstance().rokt.setSessionId(sessionId: sessionId)
}
// Proceed with your confirmation flow
}

NotesDirect link to Notes

  • Call setSessionId before selectPlacements to ensure the session is used.
  • Empty strings are ignored and will not update the session.
  • Always URL-encode the session ID when passing as a query parameter.
Was this article helpful?
Last updated May 4, 2026