Actual Links Account Linking: iOS Developer Guide

This guide covers everything you need to integrate account linking into your iOS app: how it works, authentication, order retrieval, background processing, account management, and references.


How It Works

  1. Connect — The user links their retailer account through your app. The SDK handles authentication, including two-factor authentication and CAPTCHA challenges.
  2. Verify — The SDK verifies the credentials against the retailer.
  3. Retrieve — The SDK fetches purchase history from the linked account and returns structured order data.
  4. Enrich (optional) — If Product Intelligence is enabled, line items are matched against the product catalog for UPC, brand, and category.

Credentials are encrypted and stored locally on the device’s keychain. They never leave the device and are only used when the retailer session expires and re-authentication is required.


Installation

Add the BlinkEReceipt extension SDK to your project:

CocoaPods:

pod 'BlinkEReceipt'

Swift Package Manager:

https://github.com/BlinkReceipt/blinkereceipt-ios

Prerequisites: Xcode 12+, iOS 11.0+ deployment target.

BlinkEReceipt iOS (GitHub)

License Keys

You need two keys: a license key and a Product Intelligence key. Both are available from your account team or by emailing blinkreceipt@microblink.com.

Initialize the SDK

In your AppDelegate, set both keys and initialize the account linking manager:

import UIKit
import BlinkReceipt
import BlinkEReceipt

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, 
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        BRScanManager.shared().licenseKey = "YOUR-LICENSE-KEY"
        BRScanManager.shared().prodIntelKey = "YOUR-PROD-INTEL-KEY"
        BRAccountLinkingManager.shared()
        return true
    }
}

Authentication Options

Account linking offers two authentication experiences.

Option A: Host App Authentication

Your app collects credentials. The SDK handles the rest in a hidden webview, only surfacing a visible webview when the retailer requires additional input (2FA, CAPTCHA, etc.).

let username = "user@domain.com"
let password = "secure-password"
let connection = BRAccountLinkingConnection(retailer: .walmart, username: username, password: password)
connection.configuration.dayCutoff = 30

Option B: Retailer Webview Authentication

No credentials needed. The SDK presents the retailer’s own login page in a webview. The user authenticates directly with the retailer. The webview closes automatically after successful authentication.

let connection = BRAccountLinkingConnection(retailer: .walmart)
connection.configuration.dayCutoff = 30

Switching Authentication Mode

You can switch an already-linked connection between modes:

if let connection = BRAccountLinkingManager.shared().getLinkedRetailerConnection(.walmart) {
    connection.webviewAuthEnabled = true   // Switch to retailer webview
    connection.webviewAuthEnabled = false  // Switch to host app
    BRAccountLinkingManager.shared().update(connection)
}

Link a Retailer

let error = BRAccountLinkingManager.shared().linkRetailer(with: connection)
if error == .none {
    // Success
}

Verify Credentials

Verification confirms the credentials are valid before linking. Recommended but not required.

let taskId = BRAccountLinkingManager.shared().verifyRetailer(with: connection, 
    withCompletion: { error, viewController, sessionId in
    
    if error == .verificationNeeded {
        // Present the view controller for 2FA / CAPTCHA
        self.present(viewController!, animated: true)
        
    } else if error == .verificationCompleted {
        // Dismiss the view controller
        self.dismiss(animated: false)
        
    } else if error == .none {
        // Verification succeeded — safe to link
        BRAccountLinkingManager.shared().linkRetailer(with: connection)
        
    } else {
        // Handle errors: .invalidCredentials, .noCredentials, 
        // .unsupportedRetailer, .cancelled, .webViewClosed, .internal, .parsingFail
    }
})

Retrieve Orders

Once linked and verified, retrieve purchase history:

let taskId = BRAccountLinkingManager.shared().grabNewOrders(for: .walmart) { 
    retailer, order, remaining, viewController, errorCode, sessionID in
    
    if errorCode == .verificationNeeded {
        // Present view controller for 2FA / CAPTCHA
        self.present(viewController!, animated: true)
        
    } else if errorCode == .verificationCompleted {
        // Dismiss the view controller
        self.dismiss(animated: false)
        
    } else if errorCode == .none {
        // Process the order
        if remaining <= 0 {
            // All orders retrieved
        }
        
    } else if errorCode == .webViewClosed {
        // User dismissed the webview
        
    } else {
        // Handle other errors
    }
}

The SDK tracks the last successful retrieval date per retailer. Subsequent calls only return new orders since then, subject to your dayCutoff.

Background Order Retrieval

To check for new orders while the app is in the background:

  1. Add background task support to your app with a task identifier. See Apple’s background tasks guide.
  2. Enable background fetch in the SDK using your task identifier:
BRAccountLinkingManager.shared().enableBackgroundFetch(withIdentifier: taskIdentifier)
  1. Implement the background fetch callback:
BRAccountLinkingManager.shared().backgroundFetchCompletion = { retailer, errorCode, sessionId, order in
    // Same flow as grabNewOrders above
}

Full example in AppDelegate:

import UIKit
import BlinkReceipt
import BlinkEReceipt

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, 
                     didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        BRScanManager.shared().licenseKey = "YOUR-LICENSE-KEY"
        BRScanManager.shared().prodIntelKey = "YOUR-PROD-INTEL-KEY"

        let taskIdentifier = "com.yourapp.account-linking-background"
        BRAccountLinkingManager.shared().enableBackgroundFetch(withIdentifier: taskIdentifier)

        BRAccountLinkingManager.shared().backgroundFetchCompletion = { retailer, errorCode, sessionId, order in
            // Handle background orders
        }
        return true
    }
}

Account Management

Unlink an Account

BRAccountLinkingManager.shared().unlinkAccount(for: .walmart) {
    // Account unlinked
}

Reset Order History

Unlinking does not reset the order history cache. To clear it:

BRAccountLinkingManager.shared().resetHistory(for: .walmart)

Change Credentials

Unlink first, then create and link a new connection:

BRAccountLinkingManager.shared().unlinkAccount(for: .walmart) {
    let newConnection = BRAccountLinkingConnection(retailer: .walmart, username: "new-user", password: "new-pass")
    newConnection.configuration.dayCutoff = 30
    BRAccountLinkingManager.shared().linkRetailer(with: newConnection)
}

It is recommended to call verifyRetailer before linking if you are unsure whether the new credentials are valid.

Multiple Accounts

Linking multiple accounts for the same retailer is not supported. Unlink the existing account before linking a different one for the same retailer.

Order Types

TypeDescription
In-StorePurchases made in a physical store (if visible in the retailer account)
DeliveryOnline purchases shipped to the customer
PickupOnline purchases picked up in store
DigitalMovies, eBooks, songs, digital storage, etc.

Not all order types are available for every retailer. Target, Walmart, and Kroger are examples of retailers that surface in-store purchases through their online accounts.

Order Status

Each order can include status information at three levels:

LevelWhat it tracks
Order statusOverall order status (ordered, completed, cancelled, refunded, returned)
Shipment statusStatus of a specific shipment within the order (delivery orders only)
Product statusStatus of a specific product within the order

Important: Account linking returns each order only once. If an order’s status changes after it has been retrieved (e.g., shipped → delivered), you need to reset the order history and re-retrieve to get the updated status.

Configuration Options

SettingWhat it doesDefault
dayCutoffHow many days of purchase history to retrieve15 days
dateCutoffSpecific earliest date to retrieve fromNone
webviewAuthEnabledUse retailer webview instead of host app credentialsfalse

Error Handling

Common error codes and what they mean:

ErrorDescriptionHow to handle
verificationNeededRetailer requires 2FA, CAPTCHA, or other user inputPresent the provided view controller
verificationCompletedUser successfully completed additional authenticationDismiss the view controller
invalidCredentialsUsername or password is incorrectPrompt the user to re-enter credentials
noCredentialsNo credentials providedEnsure credentials are set on the connection
unsupportedRetailerRetailer is not supportedCheck the supported retailers list
cancelledOperation was cancelledDismiss any presented view controllers
webViewClosedUser dismissed the webviewDismiss any presented view controllers

Full iOS Error Codes Reference

Testing Recommendations

  • Test linking and verification for multiple retailers
  • Test 2FA and CAPTCHA flows (most retailers trigger these intermittently)
  • Test with accounts that have both in-store and online purchase history
  • Verify that dayCutoff controls the retrieval window correctly
  • Test unlinking and re-linking with the same and different credentials
  • Test background order retrieval
  • Remember to call reset history between test runs, or you will only see new orders since the last retrieval
  • Run all account linking operations on the main thread (the SDK is not thread-safe)

Implementation Timeline

ScopeEstimated Dev Time
Standard integration (single retailer)~1 week + QA
Full integration (all retailers + background)~2 weeks + QA

Key Classes & References

ClassWhat it does
BRAccountLinkingManagerMain manager for linking, verifying, and retrieving orders
BRAccountLinkingConnectionRepresents a retailer connection (credentials + config)
BRAccountLinkingConfigurationConfiguration options (dayCutoff, dateCutoff)
BRAccountLinkingErrorError codes
BRAccountLinkingRetailerRetailer enum values

Related

Let’s Turn Proof Into Action 

Your next move should be backed by proof, and we’re here to help you leverage real data for real results. Start turning verified insights into measurable impact today.