Account Linking
This guide provides a brief overview for how to get started using Account Linking
.
Initialize the SDK
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
}
}
Note
A licenseKey
or prodIntelKey
can be obtained by emailing blinkreceipt@microblink.com.
Create account connection
Account Linking offers two UI/UX experiences when linking and verifying a merchant’s connection.
1. Host App Authentication
Using this flow, a host app can provide a native prompt for users to populate credentials. All other interactions with the merchant are done with the webview hidden in a background with exception when 2FA, Captcha or other user input is required.
Use collected credentials to create BRAccountLinkingConnection object.
let username = "user@domain.com"
let password = "secure-password"
let connection = BRAccountLinkingConnection(retailer: .walmart, username: username, password: password)
connection.configuration.dayCutoff = 30
2. Retailer Webview Authentication
This flow eliminates the need for a host app to provide any native UX to collect credentials. Instead, the SDK presents a webview with the merchant’s regular authentication protocol. The webview stays populated as the user completes whatever authentication flow is required by the merchant. The webview disappears after a successful authentication is complete.
Create BRAccountLinkingConnection object by only specifying the retailer
let connection = BRAccountLinkingConnection(retailer: .walmart)
connection.configuration.dayCutoff = 30
Already linked connections can be switched back and forth by updating the webviewAuthEnabled value
if let connection = BRAccountLinkingManager.shared().getLinkedRetailerConnection(.walmart) {
connection.webviewAuthEnabled = true // Enable `Retailer Webview Authentication`
connection.webviewAuthEnabled = false // Disable `Retailer Webview Authentication`
BRAccountLinkingManager.shared().update(connection)
}
Link a connection
let error = BRAccountLinkingManager.shared().linkRetailer(with: connection)
if (error == .none) {
// Success
}
Verifying a connection
let username = "user@domain.com"
let password = "secure-password"
let connection = BRAccountLinkingConnection(retailer: .walmart, username: username, password: password)
connection.configuration.dayCutoff = 30
let taskId = BRAccountLinkingManager.shared().verifyRetailer(with: connection, withCompletion: { error, viewController, sessionId in
if (error == .verificationNeeded) {
// Display UIViewController for 2FA verification, CAPTCHA or other user input
} else if (error == .verificationCompleted) {
// Dismiss the previously presented UIViewController
} else {
if (error == .noCredentials) {
// Error: Credentials have not been provided
} else if (error == .internal) {
// Error: Unexpected error
} else if (error == .parsingFail) {
// Error: General error
} else if (error == .invalidCredentials) {
// Error: Probable cause of the failure is invalid credentials
} else if (error == .cancelled) {
// Operation has been cancelled.
// Dismiss any previously presented user input UIViewController
} else if (error == .webViewClosed) {
// Operation has been terminated due to dismissing of the webview.
// Dismiss any previously presented user input UIViewController
} else if (error == .unsupportedRetailer) {
// Error: An attempt to verify account with invalid retailer
}
// Verification completed successfully
// Account can be linked
BRAccountLinkingManager.shared().linkRetailer(with: connection)
}
})
Grab New Orders
Once credentials are verified and a retailer is linked, we will search for purchases in a user’s account.
let taskId = BRAccountLinkingManager.shared().grabNewOrders(for: .walmart) { retailer, order, remaining, viewController, errorCode, sessionID in
if (errorCode == .verificationNeeded) {
// Display UIViewController for 2FA verification, CAPTCHA or other user input
} else if errorCode == .verificationCompleted {
// Dismiss the previously presented UIViewController
} else if errorCode == .none {
// Orders will be returned here
if (remaining <= 0) {
// Grab Orders completed successfully
// No more orders to fetch
}
} else if (error == .webViewClosed) {
// Operation has been terminated due to dismissing of the webview.
// Dismiss any previously presented user input UIViewController
} else if (error == .unsupportedRetailer) {
// Error: An attempt to verify account with invalid retailer
} else {
// Grab Orders Failed. Check error for more info
}
}
Note
The SDK will maintain an internal date of the last successful search for each retailer so that each time you attempt to retrieve new messages, you will only get messages since the last successful check, and subject to the day cutoff that you set (default is 15 days).
Grab New Orders (App In Background)
Account Linking also provides an option for apps to periodically check for new orders while the app is in background. Follow the steps below if you want to enable background fetch in your app.
Create task identifier by adding background task support in your app. More info here
Enable background fetch by using the task identifier from step 1
BRAccountLinkingManager.shared().enableBackgroundFetch(withIdentifier: taskIdentifier)
Implement
backgroundFetchCompletion
callback so the app can receive messages from the background jobBRAccountLinkingManager.shared().backgroundFetchCompletion = { retailer, errorCode, sessionId, order in }
Example:
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"
// Enable background fetch
let taskIdentifier = "Host App Background Task Identifier"
BRAccountLinkingManager.shared().enableBackgroundFetch(withIdentifier: taskIdentifier)
// Background fetch callback
BRAccountLinkingManager.shared().backgroundFetchCompletion = { retailer, errorCode, sessionId, order in
// Same flow as Grab Orders above
}
return true
}
}
Migration from BRAmazonManager
If you had previously integrated Amazon parsing, you will find that BRAmazonManager
is no longer accessible in the BlinkEReceipt SDK. Instead, Amazon has been incorporated into Account Linking.
Here is a table detailing the functionality from the previous Amazon integration and how to achieve the same thing in the new framework:
Old Amazon Integration | New Account Linking Integration |
---|---|
BRAmazonManager.amazonDayCutoff |
BRAccountLinkingConnection.configuration.dayCutoff |
[BRAmazonManager storeCredentials:password:] |
Create a BRAccountLinkingConnection object and link with BRAccountLinkingManager.shared().linkRetailer(with: connection) |
[BRAmazonManager clearAmazonCredentials] |
Call BRAccountLinkingManager.shared().unlinkAccount(for: .amazon, withCompletion: {}) |
[BRAmazonManager hasCredentials] |
Call BRAccountLinkingManager.shared().getLinkedRetailers() and iterate over the results looking for BRAccountLinkingRetailerAmazon |
[BRAmazonManager resetAmazonOrders] |
Call BRAccountLinkingManager.shared().resetHistory(for: .amazon) |
[BRAmazonManager verifyAmazonAccount:] |
Call BRAccountLinkingManager.shared().verifyRetailer(with: connection, withCompletion: {} |
[BRAmazonManager grabNewAmazonOrders:] |
Call BRAccountLinkingManager.shared().grabNewOrders(for: .amazonBeta) {} |
As noted above, the method for handling 2FA and other user-input scenarios is slightly different now. Whereas previously you would trap the error code BRAmazonErrorVerificationNeeded
and then invoke [BRAmazonManager showBrowserFromViewController:withCompletion:]
, the new paradigm is that verifyRetailer
and grabNewOrders
will return the error code BRAccountLinkingErrorVerificationNeeded
as well as the actual view controller for you to display. Once the user has successfully authenticated, the same callback will be invoked with the code BRAccountLinkingErrorVerificationCompleted
which is the trigger for you to dismiss the view controller.