iOS
The Transact iOS SDK can be installed either with the Swift Package Manager or through CocoaPods.
Requirements
- Xcode 12.0 or greater
- iOS 13.0 or greater
Swift Package Manager
Inside Xcode, go to Project Settings -> Project -> Package Dependencies and click the + to add a new Package.
https://github.com/atomicfi/atomic-transact-ios
CocoaPods
pod 'AtomicSDK'
# pod 'AtomicSDK/SwiftUI'
The AtomicConfig
class can be used to customize the Transact experience using any of the Transact SDK Parameters.
import SwiftUI
import AtomicTransact
// Your implementation goes here
struct ContentView: View {
@State var showingTransact = false
var body: some View {
Button("Launch Transact") {
showingTransact = true
}.atomicTransact(
isPresented: $showingTransact,
config: {
AtomicConfig(
publicToken: "PUBLIC_TOKEN",
scope: .userlink,
tasks: [.init(operation: .deposit)]
},
onCompletion: { result in
switch result {
case .finished(let response):
print("Finish event: (response.taskId) (response.handoff)")
case .closed(let response):
print("Close event: (response.reason)")
case .error(let error):
print("Transact returned with error: (error)")
default:
print("Default case")
}
})
.onReceive(Atomic.interactions) { interaction in
print("Interaction event: (interaction.name) (interaction.value)")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
import AtomicTransact
// Your implementation goes here
let config = AtomicConfig(
publicToken: "PUBLIC_TOKEN",
tasks: [.init(operation: .deposit)]
)
Atomic.presentTransact(
from: self,
config: config,
onInteraction: { interaction in
print("Interaction event: \(interaction.name) \(interaction.value)")
},
onCompletion: { result in
switch result {
case .finished(let response):
print("Finish event: \(response.taskId) \(response.handoff)")
case .closed(let response):
print("Close event: \(response.reason)")
case .error(let error):
print("Transact returned with error: \(error)")
}
})
Android
Update your project plugins
In your root-level (project-level) Gradle file (build.gradle
), add rules to include the Android Gradle plugin. Check that you have Google's Maven repository as well.
buildscript {
repositories {
// Check that you have the following line (if not, add it):
google() // Google's Maven repository
mavenCentral() // Include to import Transact Android SDK
}
dependencies {
// ...
}
}
Add the Transact SDK to your app
In your module (app-level) Gradle file (usually app/build.gradle
), add a line to the bottom of the file. The latest version of the SDK is .
android {
defaultConfig {
minSdkVersion 21 // or greater
}
// Enable Java 8 support for Transact to work
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
// ...
implementation 'financial.atomic:transact:<insert latest version>'
}
If you're using the Transact SDK in a Java environment, add the following configuration to your module (app-level) Gradle file (usually app/build.gradle
). These constraints resolve compatibility issues with Android lifecycle versions above 2.6.
implementation("financial.atomic:transact:<insert latest version>")
constraints {
implementation("androidx.lifecycle:lifecycle-common") {
version {
strictly("2.6.1")
}
}
implementation("androidx.lifecycle:lifecycle-process") {
version {
strictly("2.6.1")
}
}
}
Change the Transact theme
You have the ability to modify your theme by adding an activity
tag. Add the following snippet to your manifest:
<activity
android:name="financial.atomic.transact.activity.TransactActivity"
android:theme="@style/Theme.You.Want"
/>
If you get a Manifest merger failed
error, you can resolve it by adding xmlns:tools="http://schemas.android.com/tools"
to your manifest tag, then updating your TransactActivity to the following:
<activity
android:name="financial.atomic.transact.activity.TransactActivity"
android:theme="@style/Theme.You.Want"
tools:replace="theme"
/>
import org.json.JSONObject
import financial.atomic.transact.*
import financial.atomic.transact.receiver.TransactBroadcastReceiver
// Your implementation goes here
val config = Config(
publicToken = "PUBLIC_TOKEN",
tasks = listOf(Config.Task(product = Config.Product.DEPOSIT)))
)
Transact.registerReceiver(context, object: TransactBroadcastReceiver() {
override fun onClose(data: JSONObject) {
Log.d("APP", "Close event: ${data.getString("reason")}")
}
override fun onFinish(data: JSONObject) {
Log.d("APP", "Finish event: ${data.getString("taskId")} ${data.optString("handoff")}")
}
override fun onInteraction(data: JSONObject) {
Log.d("APP", "Interaction event: ${data.getString("name")} ${data.getJSONObject("value")}")
}
})
Transact.present(context, config)
import android.content.Context;
import android.util.Log;
import org.json.JSONObject;
import java.util.Arrays;
import java.util.List;
import financial.atomic.transact.*;
import financial.atomic.transact.receiver.TransactBroadcastReceiver;
// Your implementation goes here
public class TransactJavaImplementation {
public static void initializeTransact(Context context, String publicToken) {
List<Config.Task> tasks = Arrays.asList(new Config.Task(Config.Product.DEPOSIT, null, null, null));
Config config = new Config(publicToken, tasks);
Transact.Companion.registerReceiver(context, new TransactBroadcastReceiver() {
@Override
public void onClose(JSONObject data) {
Log.d("APP", "Close event: " + data.optString("reason"));
}
@Override
public void onFinish(JSONObject data) {
Log.d("APP", "Finish event: " + data.optString("taskId") + " " + data.optString("handoff"));
}
@Override
public void onInteraction(JSONObject data) {
Log.d("APP", "Interaction event: " + data.optString("name") + " " + data.optJSONObject("value"));
}
});
Transact.Companion.present(context, config);
}
}
React Native
Transact can be initialized by including our React Native SDK in your app and then calling the Atomic.transact
method and passing it a configuration object.
yarn add @atomicfi/transact-react-native
iOS Setup
- Xcode 12.0 or greater
- iOS 13.0 or greater
(cd ios && pod install)
For applications using the Expo managed workflow, see the Expo documentation about using Native Modules.
Android Setup
Autolinking should set up everything when building.
import { Atomic, Product } from "@atomicfi/transact-react-native"
// Your implementation goes here
Atomic.transact({
config: {
publicToken: "PUBLIC_TOKEN",
tasks: [{ product: Product.DEPOSIT }]
},
onInteraction: interaction => {
console.log('Interaction event:', interaction.name, interaction.value)
},
onFinish: data => {
console.log('Finish event:', data.taskId, data.handoff)
},
onClose: data => {
console.log('Close event:', data.reason)
}
})
Flutter
A Flutter plugin that wraps the native Atomic Transact SDKs. View the plugin with a code example on Github
Add atomic_transact_flutter
as a dependency in your pubspec.yaml file
dependencies:
...
atomic_transact_flutter: <version>
iOS Requirements
- Xcode 12.0 or greater
- iOS 13.0 or greater
Android Requirements
Set the minSdkVersion in android/app/build/gradle
android {
defaultConfig {
minSdkVersion 21 // or greater
}
}
import 'package:atomic_transact_flutter/atomic_transact_flutter.dart';
// Your implementation goes here
Atomic.transact(
config: AtomicConfig(
publicToken: "PUBLIC_TOKEN",
tasks: [AtomicTask(product: AtomicProductType.deposit)],
),
onInteraction: (AtomicTransactInteraction interaction) {
print("onInteraction");
},
onDataRequest: (AtomicTransactDataRequest request) {
print("onDataRequest");
},
onCompletion: (AtomicTransactCompletionType type,
AtomicTransactResponse? response, AtomicTransactError? error) {
print("onCompletion");
},
);
Browser
Transact can be initialized by including our JavaScript SDK in your page and then calling the Atomic.transact
method and passing it a configuration object.
npm install @atomicfi/transact-javascript
import { Atomic, Product } from "@atomicfi/transact-javascript"
// Your implementation goes here
Atomic.transact({
config: {
publicToken: "PUBLIC_TOKEN",
tasks: [{ product: Product.DEPOSIT }]
},
onInteraction: interaction => {
console.log('Interaction event:', interaction.name, interaction.value)
},
onFinish: data => {
console.log('Finish event:', data.taskId, data.handoff)
},
onClose: data => {
console.log('Close event:', data.reason)
}
})
WebView
Implementing a WebView means you will not install our SDK directly into your app. Instead, you will use a WebView to load the Transact application into your mobile app or browser experience. The WebView will then communicate with the Atomic API via JavaScript loaded on the page. Within the context of a mobile app, you may use a WebView (for example, WKWebView on iOS) by building a self-hosted wrapper page.
To get use the Transact WebView, you will need to build the /initialize
URL. This URL is composed of the Transact base URL (https://transact.atomicfi.com/initialize/
) and a base64 encoded string. The base64 encoded string is made up of an object containing a publicToken for the session to be intialized and the parameters used within the SDK (excluding onFinish
, onClose
, and onInteraction
). Follow these steps:
- Retrieve a new publicToken from
/access-token
- Add the publicToken to your configuration object
- Stringify and base64 encode the entire configuration object
- Append the resulting string to the Transact base URL to create the
/initialize
URL
{
"publicToken": "\"PUBLIC_TOKEN\"",
"tasks": [
{
"operation": "deposit"
}
]
}
https://transact.atomicfi.com/initialize/YOUR_BASE64_ENCODED_STRING
Parameters
When using the Transact SDK, the configuration object can be customized to change the look and user experience. Below are all of the available options for customization.
You can listen to client-side events using callback functions like onFinish
, onClose
, and onInteraction
. Light branding customizations can be applied through the theme
object, allowing you to set brand colors and toggle dark mode. For Spanish-speaking users, you can set language: 'es'
to display all content in Spanish.
Required Properties
publicToken
string- The public token returned during AccessToken creation.
tasks
[TaskConfiguration]- Defines configuration for the tasks you wish to execute as part of the task workflow.
Child Properties
Required Properties
operation
string- Specifies the operation with which to initialize Transact. One of
deposit
,verify
, ortax
. product
stringDeprecated- One of
deposit
,verify
, ortax
. This is deprecated in favor ofoperation
.product
will be available for the foreseeable future and we will give ample warning when it is planned to be sunset.
Optional Properties
onComplete
stringThe action to take on completion of the task. Can be either "continue" or "finish." To execute the next task, use "continue." To finish the task workflow and not execute any of the subsequent tasks, use "finish."Default value: "continue"
onFail
stringThe action to take on failure of the task. Can be either "continue" or "finish." To execute the next task, use "continue." To finish the task workflow and not execute any of the subsequent tasks, use "finish."Default value: "continue"
distribution
objectOptionally pass in enforced deposit settings. Enforcing deposit settings will eliminate company search results that do not support the distribution settings.Child Properties
Required Properties
type
string- Can be
total
to indicate the remaining balance of their paycheck,fixed
to indicate a specific dollar amount, orpercent
to indicate a percentage of their paycheck.
Optional Properties
amount
numberWhen
distribution.type
isfixed
, it indicates a dollar amount to be used for the distribution. Whendistribution.type
ispercent
, it indicates a percentage of a paycheck. This is not required ifdistribution.type
istotal
.This value cannot be updated by the user unless
canUpdate
is set totrue
.canUpdate
booleanAllows a user to specify any amount they would like, overwriting the defaultamount
.Default value: false
Optional Properties
onFinish
function
data
parameter which contains metadata about the executed task.onClose
function
onInteraction
function
theme
object
Child Properties
Optional Properties
brandColor
string
color
CSS property. For example: #FF0000
or rgb(255, 0, 0)
. This property will mostly be applied to buttons.dark
boolean
display
string
inline
, Transact will be rendered in an iframe. When using inline
, pass the CSS selector for the container element in to the container
parameter and the Transact iframe will be injected into that element.container
string
"inline"
to theme.display
.overlayColor
string
background-color
CSS property. For example: #FF0000
or rgb(255, 0, 0)
. This property will change the overlay background color. This overlay is mainly only seen when Transact is used on a Desktop.navigationOptions
object
Child Properties
Optional Properties
showBackButton
boolean
true
, the back button is displayed, allowing users to navigate to the previous screen. Defaults to true
if no value is provided.showBackButtonText
boolean
true
, a text label will appear alongside the back button. Defaults to false
if no value is provided.showCloseButton
boolean
true
, the close button is available for users to exit the view. Defaults to true
if no value is provided.deeplink
object
handoff
[string]
exit-prompt
, authentication-success
, and high-latency
. See Handoff Pages for more details.language
string
en
for English and es
for Spanish.Default value: en
linkedAccount
string
_id
of a LinkedAccount. When used, Transact will immediately begin authenticating upon opening. This parameter is used when the LinkedAccount's transactRequired
flag is set to true
.conversionToken
string
conversionToken
to initialize Transact for a Conversion opportunity.search
object
metadata
object
experiments
object
inSdk
boolean
false
, close buttons and any user-facing CTAs which require hooking into SDK events, such as manual fallback CTAs, are removed from the UI of the client components.Default value: true
{
"publicToken": "PUBLIC_TOKEN",
"tasks": [
{
"operation": "deposit",
"distribution": {
"type": "fixed",
"amount": 50,
"action": "create"
}
}
],
"theme": {
"brandColor": "#1b1464",
"overlayColor": "#CCCCCC",
"navigationOptions": {
"showBackButton": true,
"showBackButtonText": false,
"showCloseButton": true
}
},
"deeplink": {
"step": "login-company",
"companyId": "5e4c4d18b7d75c37aac54a8f"
},
"language": "en",
"metadata": {
"version": "1.2.1",
"test": "New User Experience",
"testVariant": "B"
}
}
Handoff Pages
The following page names can be added to the handoff
array to allow views to be handled outside of Transact.
exit-prompt
- If the user has reached the login page and decides to exit, they are prompted with a view that asks them to confirm their exit. When
exit-prompt
is passed into thehandoff
array, users will no longer be presented with the exit confirmation. Theatomic-transact-close
event will be triggered in its place. The event will also send the following data:{ handoff: 'exit-prompt' }
. authentication-success
- When authentication is successful, the user is taken to the success view within Transact. When
authentication-success
is passed into thehandoff
array, users will no longer be taken to the success view. Theatomic-transact-finish
event will be triggered in its place. The event will also send the following data:{ handoff: 'authentication-success' }
. high-latency
- When authentication takes much longer than expected, the user is taken to the the high latency view within Transact. When
high-latency
is passed into thehandoff
array, users will no longer be taken to this view. Theatomic-transact-close
event will be triggered in its place. The event will also send the following data:{ handoff: 'high-latency' }
.
Event listeners
When using the SDK, events will be emitted and passed to the native application. Such events allow native applications to react and perform functions as needed. Some events will be passed with a data object with additional information.
onClose
Triggered in several different instances:
- If a user does not find their employer, payroll provider, or service provider, the data passed with the event will be
{ reason: 'zero-search-results' }
.- If the Manual Fallback Call To Action in Console is enabled, the data passed with this event will be
{ reason: 'manual-fallback' }
.
- If the Manual Fallback Call To Action in Console is enabled, the data passed with this event will be
- During the Transact process if a user is prompted to keep waiting or exit and they choose to exit, the data passed with the event will be
{ reason: 'task-pending' }
. - At any point if the user clicks on the x the data passed with the event will be
{ reason: 'unknown' }
.
onFinish
Triggered when the user reaches the success screen and closes Transact. The data passed with the event will include the
taskId
.onDataRequest
- Triggered when additional data is needed to complete a Task. For example, if your implementation is delaying the transit of bank or card data until the user is authenticated. The data passed with the event will be similar to the following:
{ fields: ['account', 'card'], userId: 'ATOMIC_USER_ID', taskId: 'TASK_ID', identifier: 'YOUR_IDENTIFIER', taskWorkflowId: 'TASK_WORKFLOW_ID' }
. The array offields
will contain a list of missing entities, with possible values ofaccount
,card
, andidentity
. You will need to use our Update User endpoint to update the user account with the missing data. onInteraction
- Triggered on interactions within Transact. For example, when a user transitions to a new screen or presses the back button. The data passed with the event will be
{ name: "NAME OF THE EVENT", value: { OBJECT CONTAINING EVENT VALUES } }
. Details can be found below in the interaction events list.
Interaction events
These are some of the event names which can appear in an onInteraction
event.
Viewed Access Unauthorized Page
- User did not have a valid token
Viewed Authentication Failed Page
- User viewed the page indicating authentication failed
Viewed Authentication Paused Page
- User viewed the page indicating authentication paused
Viewed Authentication Success Page
- User viewed the page indicating authentication was successful
Viewed Distribution Confirmation Page
- User viewed the distribution confirmation page
Viewed Expired Token Page
- User has an expired token
Viewed Fixed Deposit Amount Page
- User viewed the fixed deposit amount page
Viewed Fractional Deposit Error Page
- User viewed the fractional deposit error page
Viewed High Latency Page
- User viewed the high latency page
Viewed Learn How You Are Protected Page
- User viewed the learn how you are protected page
Viewed Login Page
- User viewed the login page
Viewed Login Help Page
- User viewed the login help page
Viewed Login Recovery Page
- User viewed the login recovery page
Viewed Manual Deposit Instructions Page
- User viewed manual deposit instructions page
Viewed MFA Page
- User viewed the multi factor authentication page
Viewed Percentage Deposit Amount Page
- User viewed the percentage deposit amount page
Viewed Search By Company Page
- User viewed the search by company page
Viewed Search By Configurable Connector Page
- User viewed the search by configurable connector/payroll provider page
Viewed Search By Payroll Page
- User viewed the search by payroll page
Viewed Select From Deposit Options Page
- User viewed the select from deposit options page
Viewed Select From Multiple Accounts Page
- User viewed the select from multiple accounts page
Viewed Select From Multiple Payroll Providers Page
- User viwed the select from available payroll providers page
Viewed Terms And Conditions Are Required Page
- User viewed the terms and conditions required page
Viewed Terms And Conditions Page
- User viewed the terms and conditions page
Viewed Under Maintenance Page
- User viewed a company/payroll provider that is under maintenance
Viewed Welcome Page
- User viewed the welcome page
{
"name": "Viewed Access Unauthorized Page",
"value": {
"customer": "Atomic",
"language": "en",
"product": "deposit"
}
}
Metadata
When initializing the Transact SDK you can pass in a metadata
parameter. This parameter is used to attach key-value data that will be returned in webhook events and client-side events.
Metadata is useful for storing additional, structured information on a Task. As an example, you could store an order ID from your system to track your user's process with a direct deposit or an identifier for a marketing campaign to track users coming from that content. Metadata is not used by Atomic and won't be seen by your users.
{
"order_id": "1234567890",
"campaign_id": "email-marketing-campaign"
}
Testing
To aid in testing various user experiences, you may use any of these pre-determined "test" credentials for authentication. Any password will work as long as the username is found in these lists. If the authentication requires an email, simply append @example.com
to the end of the chosen username.
Upon submission of your credentials, a test Task is created in Atomic’s system to process the end user’s data. These credentials can be toggled off for production use in the Atomic Console.
These flows operate identically to the way the Atomic system functions in production. Running a test Task will generate the same events and webhooks as a Task run by an end user.
Successful operation
Test where the user's credentials are correct and the task completes. When answering MFA questions, any answer will be accepted.
Username | Phone Number | Description |
---|---|---|
test-good | (555) 555-0100 | Test a successful operation. |
test-code-mfa | (555) 555-0101 | Test an authentication that includes a device code based MFA flow. |
test-push-mfa | (555) 555-0102 | Test an authentication that simulates push-based MFA. |
test-question-mfa | (555) 555-0103 | Test an authentication that simulates question-based MFA. |
Error establishing connection
Test where the user encounters an issue connecting to the third-party system.
Username | Phone Number | Description |
---|---|---|
test-system-unavailable | (555) 555-0104 | Test the user experience during a third-party system outage. |
test-unknown-failure | (555) 555-0105 | Test the user experience when there is an unexpected error. |
test-session-timeout | (555) 555-0106 | Test the user experience when the auth session has timed out. |
test-connection-error | (555) 555-0107 | Test the user experience when there is a connection error caused by a network failure. |
test-high-latency | (555) 555-0108 | Test the flow which occurs when there is high latency communicating with backend systems. |
test-post-auth-delay | (555) 555-0109 | Test the flow when there is a post-auth delay happening. This may occur due to an unanticipated change in the third-party system. |
test-failure | (555) 555-0110 | Test a failure that occurs after a successful authentication. |
Payroll system configuration
Test where the user encounters an issue with their payroll system configuration or access.
Username | Phone Number | Description |
---|---|---|
test-distribution-not-supported | (555) 555-0111 | Test a user who enters an unsupported deposit amount. |
test-routing-number-not-supported | (555) 555-0112 | Test a user whose payroll system rejects the routing number of the target deposit account. |
test-product-not-supported | (555) 555-0113 | Test a user whose payroll system does not allow the operation. |
User issue
Test where there is an error that occurs due to an action of the user.
Username | Phone Number | Description |
---|---|---|
test-bad | (555) 555-0114 | Test an unsuccessful authentication. |
test-lockout | (555) 555-0115 | Test a user who has been locked out of their account. |
test-account-unusable | (555) 555-0116 | Test a user whose payroll account rejects the target deposit account. |
test-enrolled-in-paycard | (555) 555-0117 | Test a user enrolled in a paycard, which prevents payment via direct deposit. |
test-expired | (555) 555-0118 | Test a user whose payroll password has expired. |
test-transaction-pending | (555) 555-0119 | Test a user who already has a direct deposit change in progress. |
test-account-setup-incomplete | (555) 555-0120 | Test a user who has not fully onboarded to their employee payroll system. |
test-work-status-terminated | (555) 555-0121 | Test a user who is not an active employee in the payroll system. |