Coinme Risk SDK for iOS Native Apps
Introduction
The iOS Coinme Risk Engine SDK is a Swift library, distributed privately via Cloudsmith, that allows you to interact with the Coinme Risk Engine from your application. It provides utilities that allow you to integrate against the Coinme risk engine for the various transactional flows in your application so that Coinme may appropriately assess transactional risk when processing transactions.
Note:In order to utilize Coinme transactional services from within your application, you must implement and use the Coinme risk engine SDK.
What is it?
The Coinme risk engine aggregates data about user behavior for your application. It collects:
- Device data such as the type of device, OS name and version, etc.
- Location data such as where the user is connecting from.
- Connection data such as if the user is using a proxy or VPN, etc.
- Behavioral data such as how a user is interacting with your application, how quickly they are entering data into fields, use of clipboard functions, etc.
This data is used to determine the relative riskiness of the user / transaction.
Why is Risk Tagging Important?Risk tagging allows the SDK to track user interactions tied to specific actions within your application. When an element is tagged, the risk engine can better assess whether a user is behaving normally or if suspicious automation patterns are detected.
As an example, if the risk engine determines that the user location changes suddenly via a VPN to access a region restricted transaction type, then the engine may determine automation is at play and may rank the transaction as high risk.
Implementing the iOS SDK
This package is not publicYou will need an auth token in order to install it. You may obtain this by working with the Coinme business development team.
What You'll Need to Get Started
Before integrating the SDK, you will need the following credentials from the Coinme business development team:
| Credential | Required For | Notes |
|---|---|---|
| Cloudsmith auth token | Accessing the library | Required to access the private library in Cloudsmith |
clientId | RiskEngineSetupOptions | Environment-specific — you will need one for development and one for production |
partnerId | getPartnerSessionTag() | Passed via GetPartnerSessionTagOptions, this is your Partner identifier needed for integration with Coinme APIs |
⚠️ You will need two clientIds, one for your development builds and one for your prod builds; you may obtain these from the Coinme business development team. It is very important that you pass the correct mode and clientId properties into the risk engine based on development or production usage, otherwise you may not stream your behavioral data to the correct environment, which can severely impact the risk engine’s ability to assess risk. This would ultimately negatively impact your transaction approvals.
Installation
Set Your Entitlement Token
Create a coinme.properties file in your project root directory:
COINME_TOKEN=<YOUR_ENTITLEMENT_TOKEN>Replace <YOUR_ENTITLEMENT_TOKEN> with the token provided by the Coinme business development team. Do not commit this file to version control.
Important: Add coinme.properties to your .gitignore to keep your token secure:
coinme.propertiesAdd the SDK Repository and Dependency to your project
Update your Podfile:
source 'https://github.com/CocoaPods/Specs.git'
# Read token from properties file
def read_token
properties_file = File.join(File.dirname(__FILE__), 'coinme.properties')
if File.exist?(properties_file)
File.foreach(properties_file) do |line|
key, value = line.split('=')
return value.strip if key.strip == 'COINME_TOKEN'
end
end
ENV['COINME_TOKEN'] || ''
end
token = read_token
plugin 'cocoapods-cloudsmith', {
'source' => "https://dl.cloudsmith.io/#{token}/coinme/coinme-sdk-mobile/cocoapods/index.json"
}
target 'YourApp' do
use_frameworks!
pod 'CoinmeRiskSDK', '~> 1.0.0'
end
source 'https://github.com/CocoaPods/Specs.git'
token = ENV['COINME_TOKEN'] || ''
plugin 'cocoapods-cloudsmith', {
'source' => "https://dl.cloudsmith.io/#{token}/coinme/coinme-sdk-mobile/cocoapods/index.json"
}
target 'YourApp' do
use_frameworks!
pod 'CoinmeRiskSDK', '~> 1.0.0'
end
If installing via an Environment Variable, you will also need to set the environment variable in your shell
export COINME_TOKEN=<YOUR_ENTITLEMENT_TOKEN>App Store Requirements
Before releasing your application with the Coinme Risk SDK, update your App Store Connect settings in your Apple developer portal.
App Privacy — Data Collection
In App Store Connect > App Privacy, declare the following:
-
Data Collection: Select "Yes, we collect data from this app"
-
Location:
- Select Coarse Location and/or Precise Location (depending on your app settings)
- Purpose: App Functionality
- Reason: Required for fraud detection and prevention
-
Identifiers — Device ID:
- Purpose: App Functionality
- Check: Yes, device ID is linked to user identity
Privacy Policy
Update your App Store privacy policy to include the following disclosure:
Required Privacy Policy LanguageFor fraud protection purposes only, (1) we collect your Battery Usage, Device Identifier, Device Storage, and location information; (2) we also collect enough information to determine if you are trying to fake your current location by using a VPN or other location-spoofing tools.
Required Permissions
Add location permissions to your Info.plist:
<dict>
...
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>We use your location to verify transactions and prevent fraud.</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>We use your location to verify transactions and prevent fraud.</string>
</dict>
This is a required permission for fraud detection and should be requested at runtime. Ensure your app handles the permission request appropriately for optimal risk assessment and to avoid issues from App Store Review.
Implementation
Privacy & Compliance Notice
Important: If you use the Behavior Biometrics feature (enableBehaviourBiometrics = true), please ensure that your end users agree to your privacy policy before you begin collecting their Behavior Biometric data. This is required for compliance with privacy regulations.
Configuration Options
RiskEngineSetupOptions
| Option | Type | Required | Description |
|---|---|---|---|
mode | Mode | Yes | Used to point to environment .test or .prod |
clientId | String | Yes | Your environment-specific Client ID |
partnerId | String | Yes | Partner Identifier |
customerId | String? | No | Customer/User's identifier |
sessionKey | String? | No | Session key (automatically generated if not provided) |
flow | FlowType? | No | Current User flow (Onboarding, CardTransaction, or CardLinking) |
region | AppRegion | No | Your app's region of service (.default(US), .ca, .eu, .au, .in) |
enableBehaviorBiometrics | Bool | No | Enabled behavior tracking (default: true) |
enableClipboardTracking | Bool | No | Enable clipboard tracking (default: false) |
enableFieldTracking | Bool | No | Enable automatic field tracking (default: true) |
setCloudEntitlements | Bool | No | Enable iCloud feature (default: false, requires additional setup) |
FlowType Options
FlowType.Onboarding- New user registration flowFlowType.CardTransaction- Payment/card transaction flowFlowType.CardLinking- Adding payment methods flow
sessionKey
The sessionKey is a unique identifier for tracking a specific user session.
Once a key is provided for the set up, it will be cached for the duration of the app's active session. If no value is provided, the key will be automatically generated.
You will want to invoke .getPartnerSessionTag() to get an updated value that our backend will use to associate collected user data and risk score. Failure to call this and get the expected session key value may result in loss of data for accurate risk assessment.
Using .updateCoinmeRiskEngine() with a new key will override and update the cached value.
To clear a sessionKey, you may call .resetStoredSessionKey()
Important:When you call
getPartnerSessionTag(), the returnedwebSessionIDautomatically becomes the active session key. All subsequent calls toupdateCoinmeRiskEngine()will use this session key unless you explicitly provide a different one.
getPartnerSessionTag()
Retrieve the session tag from the backend API. The resulting webSessionID is automatically used to update the CoinmeRiskEngine configuration.
try await CoinmeRiskEngine.getPartnerSessionTag(options: GetPartnerSessionTagOptions) -> SessionTagDataRequest body parameters for GetPartnerSessionTagOptions:
| Param | Type | Required | Description |
|---|---|---|---|
partnerId | String | Yes | Your partner identifier |
accountId | String | Yes | The customer ID |
fingerprint | String | Yes | The device fingerprint |
additionalHeaders | Dict<String, String> | No | Additional headers that may be included if needed by the backend |
timeout | Int | No | Request timeout in milliseconds (default: 10000) |
Initialize the SDK
Initialize the Risk Engine in your app's initialization:
import CoinmeRiskSDK
let options = RiskEngineSetupOptions(
mode: .prod, // Use .test for testing
clientId: "your-client-id",
enableBehaviourBiometrics: true,
enableFieldTracking: false // Set to false for manual tracking
)
CoinmeRiskEngine.setupCoinmeRiskEngine(options: options)Update the SDK
You can update the configuration with flow, sessionKey and customerId options:
CoinmeRiskEngine.updateCoinmeRiskEngine(
RiskEngineUpdateOptions(
sessionKey: "new-session-key",
flow: .cardTransaction,
customerId: "customer-id"
)
)Submit Data Before Transactions
Submits all collected behavioral and device date to the backend for risk assessment. Use callback version to ensure data is submitted before making subsequent API calls.
CoinmeRiskEngine.submit(
onSuccess: {
// Data successfully submitted - safe to proceed with transaction API call
processPayment()
},
onError: { error in
print("Risk SDK submission failed: \(error)")
handleError(error)
}
)What it collects:
- Sensor data (motion, orientation, pressure)
- Behavioral biometrics (typing patterns, interaction timing)
- Device context (clipboard activity, focus patterns)
- Page/screen engagement metrics
When to call:
- Before payment/transaction API calls
- Before critical actions (login, signup, money transfer)
- After form completion or user interaction flow
Other Utility Methods
Get Current Config
Returns the current runtime configuration.
CoinmeRiskEngine.getCoinmeRiskEngineConfig() -> RiskEngineUpdateOptionsReset Session
Resets the stored session key.
CoinmeRiskEngine.resetStoredSessionKey()Reset SDK
Clears the singleton instance and cleans up resources.
CoinmeRiskEngine.reset()Manual Input Field Tracking
If you choose to manually track input fields, first disabled automatic field tracking in the configuration. This can be done by ensuring
enableFieldTracking = falsewhen you set options for theCoinmeRiskEngine.
How to set up custom TextField for tracking:
import SwiftUI
import CoinmeRiskSDK
struct LoginView: View {
@State private var email = ""
@FocusState private var isEmailFocused: Bool
var body: some View {
TextField("Email", text: $email)
.focused($isEmailFocused)
.onChange(of: email) { newValue in
CoinmeRiskEngine.trackTextChange(viewId: "email", text: newValue)
}
.onChange(of: isEmailFocused) { isFocused in
CoinmeRiskEngine.trackFocusChange(viewId: "email", isFocus: isFocused)
}
}
}// In your UIViewController
class LoginViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var emailTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
emailTextField.delegate = self
}
// UITextFieldDelegate - Track focus changes
func textFieldDidBeginEditing(_ textField: UITextField) {
CoinmeRiskEngine.trackFocusChange(viewId: "email", isFocus: true)
}
func textFieldDidEndEditing(_ textField: UITextField) {
CoinmeRiskEngine.trackFocusChange(viewId: "email", isFocus: false)
}
// UITextFieldDelegate - Track text changes
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange,
replacementString string: String) -> Bool {
let currentText = textField.text ?? ""
let newText = (currentText as NSString).replacingCharacters(in: range, with: string)
CoinmeRiskEngine.trackTextChange(viewId: "email", text: newText)
return true
}
}Be descriptive when assigning a value for viewId ("email", "password", "debitCardNumber", etc)
Tracking Methods
Track text changes to an input field
CoinmeRiskEngine.trackTextChange(viewId: String, text: String)Track focus change to a field
CoinmeRiskEngine.trackFocusChange(viewId: String, isFocus: Bool)Note: Be sure to use the same viewId for both trackTextChange() and trackFocusChange() if they are used to reference the same text field or other custom UI component.
Optional Features
Enable Location Service
Initialize Apple's LocationManager to provide live location updates:
import CoreLocation
class LocationService: NSObject, CLLocationManagerDelegate {
let locationManager: CLLocationManager?
override init() {
locationManager = CLLocationManager()
locationManager?.requestWhenInUseAuthorization()
super.init()
locationManager?.delegate = self
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
if status == .authorizedWhenInUse {
if CLLocationManager.isMonitoringAvailable(for: CLBeaconRegion.self) {
if CLLocationManager.isRangingAvailable() {
let latitude = manager.location?.coordinate.latitude
let longitude = manager.location?.coordinate.longitude
print("Location: \(latitude ?? 0), \(longitude ?? 0)")
}
}
}
}
}Enable Wi-Fi Information Tracking
Wi-Fi BSSID and SSID can provide additional location signals.
- Enable Location Services (required)
- In Xcode:
- Go to your target scheme
- Click Signing & Capabilities
- Click + Capability
- Add Access WiFi Information
Enable iCloud Record ID
iCloud Record ID remains consistent across devices that are associated with the same Apple account.
- In Xcode
-
- Go to your target scheme
- Click Signing & Capabilities
- Click + Capability
- Add iCloud
- Select CloudKit service
- Choose your container
-
- Set the flag in the SDK configuration:
-
let options = RiskEngineSetupOptions( mode: .prod, clientId: "your-client-id", setCloudEntitlements: true // Must be true for iCloud features )
-
Warning: DO NOT set
setCloudEntitlementsto true unless CloudKit is properly configured, or the SDK will crash.
Enable Biometric Authentication Detection
Detect the use of FaceID and TouchID
Update your Info.plist
<dict>
...
<key>NSFaceIDUsageDescription</key>
<string>Face ID is used to verify your identity.</string>
</dict>Updated 18 days ago