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: .paylink,
tasks: [.init(operation: .switch)]
},
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: .switch)]
)
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(operation = Config.Operation.SWITCH)))
)
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: [{ operation: Operation.SWITCH}]
},
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(operation: AtomicProductType.switch)],
),
onInteraction: (AtomicTransactInteraction interaction) {
print("onInteraction");
},
onDataRequest: (AtomicTransactDataRequest request) {
print("onDataRequest");
},
onCompletion: (AtomicTransactCompletionType type,
AtomicTransactResponse? response, AtomicTransactError? error) {
print("onCompletion");
},
);
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"
}
}
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 PayLink Switch Welcome Page
- User viewed the Welcome Page
Clicked Continue From PayLink Switch Welcome Page
- User clicked the Continue From Paylink Switch Welcome Page
Viewed Search PayLink Companies Page
- User viewed the Search PayLink Companies Page
Search PayLink Companies
- User searched PayLink Companies
Expanded PayLink Selection Bar
- User expanded the PayLink Selection Bar
Collapsed PayLink Selection Bar
- User Collapsed the PayLink Selection Bar
Clicked Continue From Search PayLink Companies Page
- User clicked the Continue From Search PayLink Companies Page
Selected Company From Search PayLink Companies Page
- User selected a Company from the Search Paylink Companies Page
Deselected Company From Search PayLink Companies Page
- User de-selected a Company from the Search Paylink Companies Page
Viewed Zero Search Results From Search PayLink Companies Page
- User viewed the Zero Search Reults Page
Viewed PayLink Switch Home Page
- User viewed the PayLink Switch Home Page
Clicked Payment From PayLink Switch Home Page
- User clicked the Payment From PayLink Switch Home Page
Viewed PayLink Interstitial Page
- User viewed the PayLink Interstitial Page
Clicked Change Payment Method Dropdown
- User clicked the Change Payment Method Dropdown
Changed Payment Method
- User changed the Payment Method
Clicked Sign in
- User clicked the sign-in button
Viewed Login Page
- User viewed the Login Page
Viewed Authentication Success Page
- User viewed the Authentication Success Page
Clicked Continue From Task Completed Page
- User clicked the Continue From Paylink Switch Welcome Page
Viewed Add Card Interstitial Page
- User viewed the Add Card Interstitial Page
Clicked Add Card From Add Card Interstitial Page
- User clicked the Add Card button on the Add Card Interstitial Page
Viewed Add Card Page
- User viewed the Add Card Page
Viewed Task Completed Page
- User viewed the Task Completed Page
Viewed Task Failed Page
- User viewed the Task Failed Page
Clicked Skip From Task Failed Page
- User clicked the Continue From Paylink Switch Welcome Page
Clicked Change Payment Method From Task Failed Page
- User clicked the Continue From Paylink Switch Welcome Page
Clicked Continue From Task Failed Page
- User clicked the Continue From Paylink Switch Welcome Page
Viewed Payment Details
- User viewed the Payment Details Page
Closed Payment Details
- User closed the Payment Details
Clicked Update Payment Method
- User clicked the Update Payment Method button
Clicked Select More Payments From PayLink Switch Home Page
- User clicked the Select More Payments From PayLink Switch Home Page
Clicked Payment Try Again From Home Page
- User clicked the Payment Try Again From Home page
Clicked Edit Selections Button
- User clicked the Edit Selections Button
Clicked Remove Payment Button
- User clicked the Remove Payment Button
Swiped Payment Left
- User swiped left on a Payment
Swiped Payment Right
- User swiped right on a Payment
Clicked Remove Payment Button After Swiping
- User clicked the Remove Payment Button After Swiping
Clicked Swiped Payment
- User clicked the Swiped Payment
{
"name": "Clicked Update Payment Method",
"value": {
"customer": "Atomic",
"language": "en",
"product": "switch"
}
}
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. |