Atomic logo
Transact SDK

PayLink Transact SDK Reference

The Atomic Transact SDK is a UI designed to securely handle interactions with our products while performing the heavy-lifting of integration.

We recommend installing the Transact iOS SDK with Swift Package Manager by using the Package URL: https://github.com/atomicfi/atomic-transact-ios.

Requirements

  • Xcode 16.4 or greater
  • iOS 15.0 or greater

Swift Package Manager

Inside Xcode, go to Project Settings -> Project -> Package Dependencies and click the + to add a new Package.

Swift Package Installation
Enter the Package URL
https://github.com/atomicfi/atomic-transact-ios

GitHub Release Artifacts

If you are unable to use Swift Package Manager, we also provide framework artifacts on GitHub releases. You will need to link MuppetIOS, QuantumIOS, and AtomicTransact into your project. Dynamic versions are available instead if needed.

CocoaPods (Deprecated)

CocoaPods support is deprecated. We will continue publishing to the CocoaPods Trunk while we are able to, which ideally is through November, but our deployments to Trunk have become very unreliable and we can't make guarantees we will continue to ship new versions there.

We strongly recommend migrating to Swift Package Manager if you have not already.

If you must continue to use CocoaPods, we recommend pointing to our git repository directly rather than pulling updates from the CocoaPods Trunk. See the CocoaPods documentation for more information.

Installation
pod 'AtomicSDK', :git => "https://github.com/atomicfi/atomic-transact-ios.git"
Use the AtomicConfig struct to customize the Transact experience with any of the Transact SDK Parameters.
SwiftUI Example
import SwiftUI
import AtomicTransact

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)],
                theme: Theme(
                  brandColor: "#9460FE",
                  dark: false
                ),
                language: "en",
                deeplink: Deeplink(
                  step: "login-company",
                  companyId: "64ecca15ec669e000851d5d2"
                ),
                search: Search(
                  ruleId: "67571ed7b278a518d7d8abdf"
                ),
                metadata: [
                  "version": "1.2.1",
                  "test": "New User Experience", 
                  "testVariant": "B"
                ]
             )},
            onDataRequest: { request in
              // Handle data request for additional information
              print("Data request: \(request.fields)")
            },
            onAuthStatusUpdate: { status in
              print("Auth status: \(status.status)")
            },
            onTaskStatusUpdate: { task in
              print("Task \(task.taskId) status: \(task.status)")
            },
            onError: { error in
              print("Error: \(error)")
            },
            onCompletion: { result in
              switch result {
              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()
    }
}
UIKit Example
import AtomicTransact

let config = AtomicConfig(
  publicToken: "PUBLIC_TOKEN", 
  scope: .payLink,
  tasks: [.init(operation: .switch)],
  theme: Theme(
    brandColor: "#9460FE",
    dark: false
  ),
  language: "en",
  deferredPaymentMethodStrategy: .sdk, // optional
  deeplink: Deeplink(
    step: "login-company",
    companyId: "64ecca15ec669e000851d5d2"
  ),
  search: Search(
    ruleId: "67571ed7b278a518d7d8abdf"
  ),
  metadata: [
    "version": "1.2.1",
    "test": "New User Experience",
    "testVariant": "B"
  ]
)

Atomic.presentTransact(
    from: self, 
    config: config,
    onDataRequest: { request in
      // Handle data request for additional information
      print("Data request: \(request.fields)")

      // Example of sending card data
      // Use a Basis Theory sandbox test card when testing Switch in sandbox.
      // Replace this with your actual data collection logic in production.
      let card = TransactDataResponse.CardData(
          number: "5100000000000008",
          expiry: "03/29",
          cvv: "111"
      )

      let identity = TransactDataResponse.Identity(
          firstName: "John ",
          lastName: "Doe",
          postalCode: "12345",
          address: "123 Main St",
          city: "New York",
          state: "NY",
          phone: "5551234567",
          email: "john.doe@example.com"
      )
      let errors = identity.validate()

      if !errors.isEmpty {
          for error in errors {
              print("Validation error: (error)")
          }
      }

      if !identity.isValid() {
          // Handle invalid identity
      }

      return TransactDataResponse(card: card, identity: identity)
    },
    onAuthStatusUpdate: { status in
      print("Auth status: \(status.status)")
    },
    onTaskStatusUpdate: { task in
      print("Task \(task.taskId) status: \(task.status)")
    },
    onError: { error in
      print("Error: \(error)")
    },
    onInteraction: { interaction in
      print("Interaction event: \(interaction.name) \(interaction.value)")
  }, 
  onCompletion: { result in
    switch result {
      case .closed(let response):
        print("Close event: \(response.reason)")
      case .error(let error):
        print("Transact returned with error: \(error)")
  }
})

The Atomic Android SDK is available via Maven Central.

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.

build.gradle (Project-level)
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 Maven Central.

build.gradle (App-level)
android {
  defaultConfig {
    minSdkVersion 23 // 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.

build.gradle (App-level)
 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")
          }
      }
  }
Use the Config class to customize the Transact experience with any of the Transact SDK Parameters.

Change the Transact theme

You have the ability to modify your theme by adding an activity tag. Add the following snippet to your manifest:

Themed TransactActivity
<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:

Themed TransactActivity with Tool
<activity
  android:name="financial.atomic.transact.activity.TransactActivity"
  android:theme="@style/Theme.You.Want"
  tools:replace="theme"
  />
Kotlin Example
import org.json.JSONObject
import financial.atomic.transact.*
import financial.atomic.transact.receiver.TransactBroadcastReceiver

val config = Config(
  publicToken = "PUBLIC_TOKEN",
  scope = Config.Scope.PAY_LINK,
  tasks = listOf(Config.Task(operation = Config.Operation.SWITCH)),
  theme = Config.Theme(
    brandColor = "#9460FE",
    dark = false
  ),
  language = "en",
  deferredPaymentMethodStrategy: .sdk, // optional
  deeplink = Config.Deeplink(
    step = "login-company",
    companyId = "64ecca15ec669e000851d5d2"
  ),
  search = Config.Search(
    ruleId = "67571ed7b278a518d7d8abdf"
  ),
  metadata = mapOf(
    "version" to "1.2.1",
    "test" to "New User Experience",
    "testVariant" to "B"
  )
)

Transact.registerReceiver(context, object: TransactBroadcastReceiver() {
  override fun onDataRequest(data: JSONObject) {
    // Handle data request for additional information
    Log.d("APP", "Data request: ${data.getJSONArray("fields")}")

    // Example of sending card data through the SDK.
    // Use a Basis Theory sandbox test card when testing Switch in sandbox.
    // If you are passing this info through the API, disregard this line.
    val card = Config.TransactDataResponse.CardData("5100000000000008", "03/29", "111")

    val identity =
        Config.TransactDataResponse.Identity(
            "John",
            "Doe",
            "12345",
            "123 Main St",
            "Apt 4B",
            "New York",
            "NY",
            "5551234567",
            "john.doe@example.com",
        )

    val dataResponse = Config.TransactDataResponse(card, identity)

    Transact.sendData(this@MainActivity, dataResponse)
  }
  override fun onAuthStatusUpdate(data: JSONObject) {
    Log.d("APP", "Auth status: ${data.getString("status")}")
  }
  override fun onTaskStatusUpdate(data: JSONObject) {
    Log.d("APP", "Task ${data.getString("taskId")} status: ${data.getString("status")}")
  }
  override fun onError(data: JSONObject) {
    Log.d("APP", "Error: ${data.getString("error")}")
  }
  override fun onInteraction(data: JSONObject) {
    Log.d("APP", "Interaction event: ${data.getString("name")} ${data.getJSONObject("value")}")
  }
  override fun onClose(data: JSONObject) {
    Log.d("APP", "Close event: ${data.getString("reason")}")
  }
})

Transact.present(context, config)
Java Example
import android.content.Context;
import android.util.Log;
import org.json.JSONObject;
import java.util.Arrays;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
import financial.atomic.transact.*;
import financial.atomic.transact.receiver.TransactBroadcastReceiver;

public class TransactJavaImplementation {
   public static void initializeTransact(Context context) {
    Map<String, String> metadata = new HashMap<>();
    metadata.put("version", "1.2.1");
    metadata.put("test", "New User Experience");
    metadata.put("testVariant", "B");

    Config config = new Config(
        "PUBLIC_TOKEN",
        Config.Scope.PAY_LINK,
        Arrays.asList(new Config.Task(Config.Operation.SWITCH)),
        new Config.Theme("#9460FE", false),
        "en",
        new Config.Deeplink("login-company", "64ecca15ec669e000851d5d2"),
        new Config.Search("67571ed7b278a518d7d8abdf"),
        metadata
    );

    Transact.Companion.registerReceiver(context, new TransactBroadcastReceiver() {
        @Override
        public void onDataRequest(JSONObject data) {
            // Handle data request for additional information
            Log.d("APP", "Data request: " + data.optJSONArray("fields"));
        }

        @Override
        public void onAuthStatusUpdate(JSONObject data) {
            Log.d("APP", "Auth status: " + data.optString("status"));
        }

        @Override
        public void onTaskStatusUpdate(JSONObject data) {
            Log.d("APP", "Task " + data.optString("taskId") + " status: " + data.optString("status"));
        }

        @Override
        public void onError(JSONObject data) {
            Log.d("APP", "Error: " + data.optString("error"));
        }

        @Override
        public void onInteraction(JSONObject data) {
            Log.d("APP", "Interaction event: " + data.optString("name") + " " + data.optJSONObject("value"));
        }

        @Override
        public void onClose(JSONObject data) {
            Log.d("APP", "Close event: " + data.optString("reason"));
        }
    });

    Transact.Companion.present(context, config);
  }
}

The Atomic React Native SDK is availble via npm.

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.

Installation
yarn add @atomicfi/transact-react-native

iOS Setup

  • Xcode 16.4 or greater
  • iOS 15.0 or greater
Install CocoaPods Dependencies
(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.

Customize the Transact experience by passing in parameters to the config object. Refer to the Transact SDK Parameters section for more details.
React Native Example
import { Atomic, Operation } from "@atomicfi/transact-react-native"

Atomic.transact({
  config: {
    scope: "pay-link",
    publicToken: "PUBLIC_TOKEN",
    tasks: [{ operation: "switch" }],
    theme: {
      brandColor: "#9460FE",
      dark: false
    },
    language: "en",
    deeplink: {
      step: "login-company",
      companyId: "64ecca15ec669e000851d5d2"
    },
    search: {
      ruleId: "67571ed7b278a518d7d8abdf"
    },
    metadata: {
      version: "1.2.1",
      test: "New User Experience",
      testVariant: "B"
    }
  },
  onDataRequest: request => {
    // Handle data request for additional information
    console.log('Data request:', request.fields)
  },
  onAuthStatusUpdate: status => {
    console.log('Auth status:', status.status)
  },
  onTaskStatusUpdate: task => {
    console.log('Task', task.taskId, 'status:', task.status)
  },
  onError: error => {
    console.log('Error:', error)
  },
  onInteraction: interaction => {
    console.log('Interaction event:', interaction.name, interaction.value)
  },
  onClose: data => {
    console.log('Close event:', data.reason)
  }
})

A Flutter plugin that wraps the native Atomic Transact SDKs. The deployed package is available on pub.dev. Plus, you can view the plugin with a code example on Github

Add atomic_transact_flutter as a dependency in your pubspec.yaml file

Dependency in pubspec.yaml file
dependencies:
  ...
  atomic_transact_flutter: <version>

iOS Requirements

  • Xcode 16.4 or greater
  • iOS 15.0 or greater
  • For a how-to on updating the minimum iOS deployment version, see the Flutter Deployment documentation.

Android Requirements

Set the minSdkVersion in android/app/build.gradle

Minimum SDK Version
android {
  defaultConfig {
    minSdkVersion 23 // or greater
  }
}
Use the AtomicConfig class to customize the Transact experience with any of the Transact SDK Parameters.
Flutter Example
import 'package:atomic_transact_flutter/atomic_transact_flutter.dart';

Atomic.transact(
  config: AtomicConfig(
    publicToken: "PUBLIC_TOKEN",
    scope: "pay-link",
    tasks: [AtomicTask(operation: AtomicOperationType.switchPayment)],
    theme: AtomicTheme(
      brandColor: "#9460FE",
      dark: false,
    ),
    language: "en",
    deeplink: AtomicDeeplink.step(
      DeeplinkStep.loginCompany(companyId: "64ecca15ec669e000851d5d2"),
    ),
    search: AtomicSearch(ruleId: "67571ed7b278a518d7d8abdf"),
    deferredPaymentMethodStrategy: AtomicDeferredPaymentMethodStrategy.sdk, // optional
    metadata: {
      "version": "1.2.1",
      "test": "New User Experience",
      "testVariant": "B",
    },
  ),
  onDataRequest: (request) {
    // Handle data request for additional information
    print("Data request: ${request.fields}");

    // Example of sending card data through the SDK.
    // Use a Basis Theory sandbox test card when testing Switch in sandbox.
    // If you are passing this info through the API, disregard this return.
    return AtomicTransactDataResponse(
      card: AtomicTransactCardData(
        number: "5100000000000008",
        expiry: "03/29",
        cvv: "111",
      ),
      identity: AtomicTransactIdentity(
        firstName: "John",
        lastName: "Doe",
        postalCode: "12345",
        address: "123 Main St",
        address2: "Apt 4B",
        city: "New York",
        state: "NY",
        phone: "5551234567",
        email: "john.doe@example.com",
      ),
    );
  },
  onAuthStatusUpdate: (status) {
    print("Auth status: ${status.status}");
  },
  onTaskStatusUpdate: (task) {
    print("Task ${task.taskId} status: ${task.status}");
  },
  onInteraction: (interaction) {
    print("Interaction event: ${interaction.name} ${interaction.value}");
  },
  onCompletion: (type, response, error) {
    print("Completion event: $type");
  },
);

The Atomic Capacitor plugin is available via npm and wraps the native iOS and Android SDKs for Ionic apps. A full example app is available on GitHub.

Transact can be launched by importing TransactPlugin and calling presentTransact with a configuration object.

Installation
npm install @atomicfi/transact-capacitor && npx cap sync

iOS Setup

  • Xcode 16.4 or greater
  • iOS 15.0 or greater

CocoaPods dependencies are installed automatically by npx cap sync.

Android Setup

Set the minSdkVersion to 23 or greater in android/variables.gradle. Capacitor handles autolinking when building.

Customize the Transact experience by passing in parameters to the config object. Refer to the Transact SDK Parameters section for more details.
Capacitor Example
import { TransactPlugin } from '@atomicfi/transact-capacitor'

await TransactPlugin.addListener('onInteraction', (event) => {
  console.log('Interaction event:', event.name, event.value)
})
await TransactPlugin.addListener('onAuthStatusUpdate', (event) => {
  console.log('Auth status:', event.status)
})
await TransactPlugin.addListener('onTaskStatusUpdate', (event) => {
  console.log('Task', event.taskId, 'status:', event.status)
})
await TransactPlugin.addListener('onClose', (event) => {
  console.log('Close event:', event.reason)
})
await TransactPlugin.addListener('onDataRequest', async (event) => {
  // Handle data request for additional information
  console.log('Data request:', event.fields)
  await TransactPlugin.resolveDataRequest({ /* provide required data */ })
})

await TransactPlugin.presentTransact({
  config: {
    scope: 'pay-link',
    publicToken: 'PUBLIC_TOKEN',
    tasks: [{ operation: 'switch' }],
    theme: {
      brandColor: '#9460FE',
      dark: false
    },
    language: 'en',
    deeplink: {
      step: 'login-company',
      companyId: '64ecca15ec669e000851d5d2'
    },
    metadata: {
      version: '1.2.1',
      test: 'New User Experience',
      testVariant: 'B'
    }
  },
  environment: { environment: 'production' }
})

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. You can also customize how users enter the experience through deeplinks, Single Switch, and custom search experiences.

publicTokenstring
The public token returned during AccessToken creation.
scopeenum
Specifies the product suite to be launched within Transact, determining the features available to the user. For PayLink operations, such as switch, this value will be pay-link.
tasks[TaskConfiguration]
Defines configuration for the Tasks you wish to execute as part of the Task Workflow.
Child Properties
operationenum
Specifies the operation with which to initialize Transact. Options are switch, present, or action for PayLink use cases.
headlessboolean
Whether to run the specified operation in the background. By default (or when explicitly set to false), the Transact UI will be displayed. Only allowed when operation is action; Transact rejects the configuration if it is set for any other operation.
themeobject
Object containing properties to customize the look of Transact.
Child Properties
brandColorstring
Accepts valid values for use with the color CSS property. For example: #FF0000 or rgb(255, 0, 0). This property will be applied to buttons on the consent page and exit confirmation prompt.
darkboolean
Change the overall theme to be dark mode.
overlayColorstring
Accepts valid values for use with the 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.
deeplinkobject
Object containing properties to deeplink users into a specific step in the Atomic experience. Use it to start the standard search flow, open a specific company login flow, or initialize Single Switch after your backend has validated merchant capabilities with GET /company/:companyId/details.
Child Properties
stepstring
Acceptable values are search-company and login-company. Use search-company to deeplink into the standard company search flow. Use login-company to deeplink directly into a specific company login flow, or pair it with singleSwitch: true to initialize Single Switch.
companyIdstring
Accepts the ID of the company. Required when `step` is `login-company`, unless the task `operation` is `switch`. Use this when deeplinking directly to a company login flow, including Single Switch. If you do not already know the company ID, you can look it up with the Company Search API. Before launching Single Switch, call the Company Details API to get the latest company information.
singleSwitchboolean
Marks the launch as Single Switch, where Transact opens one preselected merchant flow instead of sending the user through the broader Switch experience. Set this to true alongside deeplink.step = "login-company" and the target companyId.
languagestring
Optionally pass in a language. Acceptable values: en for English, es for Spanish, and fr for French.

Default value: en

metadataobject
Optionally pass data to Transact that will be returned to you in webhook events. Common use-cases for this include application version, build number, or commit hash for issue tracking and test name and variant for A/B testing.
searchobject
Optionally, enforce search queries.
Child Properties
ruleIdstring
The unique identifier of a custom search rule configured in the Atomic Console. This allows customers to define and apply specific Search Experiences tailored to their needs.
deferredPaymentMethodStrategyenum
Allows you to defer providing a payment method until the user starts a Task. Transact will emit a DataRequest event when the payment method is needed.

Acceptable values: sdk, api
Sample SDK parameters
{
  "publicToken": "PUBLIC_TOKEN",
  "scope": "pay-link",
  "tasks": [
    {
      "operation": "switch"
    }
  ],
  "theme": {
    "brandColor": "#1b1464",
    "overlayColor": "#CCCCCC"
  },
  "deeplink": {
    "step": "login-company",
    "companyId": "64ecca15ec669e000851d5d2",
    "singleSwitch": true
  },
  "search": {
    "ruleId": "67571ed7b278a518d7d8abdf"
  },
  "language": "en",
  "metadata": {
    "version": "1.2.1",
    "test": "New User Experience",
    "testVariant": "B"
  }
}

The host app controls how the Transact SDK is shown and dismissed over time. Calling Present Transact opens the SDK and keeps it visible until the user completes the flow, or manually exits, or the app programmatically hides or pauses the SDK.

The controls below define how your app can transition Transact between visible, backgrounded, and paused states.

Use Present Transact to start an interactive Transact session in your app. See the specific platform section for code examples and required parameters.

Hide removes the Transact UI from view while allowing any started tasks to continue processing in the background.

iOS Hide
Atomic.hideTransact()

Calling .pauseTransact returns a reference object to the hidden Transact view. Call .resume on that object to resume the flow.

iOS Pause And Resume
do {
  let pausedRef = try await Atomic.pauseTransact(animated: true)

  // ... show your app UI while Transact is paused ...

  pausedRef.resume(source: self, animated: true)
} catch Atomic.PauseTransactError.transactNotPresented {
  print("No Transact view is currently presented")
}
React Native and Capacitor currently expose hide controls only.

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.

Triggered when the Transact SDK presents an Action to the user via presentAction. Use this event to set in-progress UI state in your application, such as disabling the originating CTA or displaying a loading indicator while the Action runs. The data passed with the event includes the id of the Action being presented (the same value you passed to presentAction) and the user's identifier.

Triggered in several different instances:

  1. 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' }.
  2. 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' }.
  3. At any point if the user clicks on the x the data passed with the event will be { reason: 'unknown' }.

The event payload includes the following properties:

reasonenum
The reason the user exited Transact. Common values are zero-search-results, manual-fallback, task-pending, expired-token, unauthorized, or unknown.. This list is not exhaustive; handle unrecognized values gracefully.
actionObjectOptional
Information about the Action that was being executed when the user exited.
Child Properties
accountIdstring
The unique identifier for the Account the Action was executed against. Use this to correlate the event with a specific Account in the Atomic system.
typeenum
The type of Action that was executed. Possible values include refresh, connect-account, disconnect-account, switch, change-plan, cancel-plan, or pause-plan..

Triggered when the user reaches the success screen and closes Transact. The event payload will include the following properties:

identifierstring
The unique identifier for the user.
actionObjectOptional
Information about the Action that was executed.
Child Properties
accountIdstring
The unique identifier for the Account the Action was executed against. Use this to correlate the event with a specific Account in the Atomic system.
typeenum
The type of Action that was executed. Possible values include refresh, connect-account, disconnect-account, switch, change-plan, cancel-plan, or pause-plan..
taskIdstring
The unique identifier for the Task.
taskWorkflowIdstring
The unique identifier for the Task workflow.
companyObject
The company into whose system the user has authenticated.
Child Properties
_idstring
The unique identifier for the company.
namestring
The name of the company.
brandingObjectOptional
The branding information for the company.
Child Properties
logoObject
The logo for the company.
Child Properties
urlstring
The URL of the logo.
backgroundColorstring
The background color of the logo.
colorstring
The company's branding color.

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:

OnDataRequest Example
{
  "fields": [
    "identity",
    "card"
  ],
  "userId": "ATOMIC_USER_ID",
  "taskId": "TASK_ID",
  "identifier": "YOUR_IDENTIFIER",
  "taskWorkflowId": "TASK_WORKFLOW_ID",
  "company": {
    "_id": "COMPANY_ID",
    "name": "COMPANY_NAME"
  },
  "properties": {
    "lastFour": "1234",
    "title": "Personal Visa",
    "externalId": "CARD_123"
  }
}

The array of fields will contain a list of missing entities, with possible values of account, card, and identity.

The properties object describes the payment method the user selected, so you can match it to your own records before responding. For a card it may contain lastFour, title, and externalId; for a bank account it may contain accountNumberLastFour, title, and externalId. Each key is present only when you supplied that value during access token creation. When no payment method was selected, properties is an empty object.

When fields includes card or account, send one Update User request for the selected requested method. Use properties.externalId to map the selected card or bank account in your system. If you did not set an externalId, match on the remaining properties instead — but note that lastFour alone is not guaranteed to be unique across a user's payment methods.

Choose one of the following strategies to provide the requested data. This strategy must be specified using the deferredPaymentMethodStrategy SDK parameter.

  • api - send the the data to the Update User endpoint.
  • sdk - send a response message via the SDK. See the UIKit, Kotlin, and Flutter examples for how to return data for the sdk flow.

Triggered when the user's authentication status in the service provider's system changes. The event payload will include the following properties:

companyObject
The company into whose system the user has authenticated.
Child Properties
_idstring
The unique identifier for the company.
namestring
The name of the company.
brandingObjectOptional
The branding information for the company.
Child Properties
logoObject
The logo for the company.
Child Properties
urlstring
The URL of the logo.
backgroundColorstring
The background color of the logo.
colorstring
The company's branding color.
statusenum
The user's authentication status in the service provider's system. Currently the only value is authenticated.

Triggered when the status of a task changes. The event payload will include the following properties:

taskIdstring
The unique identifier for the Task.
productenum
The product relevant to the executed Task. Possible values are switch and action.
companyObject
The company into whose system the user has authenticated.
Child Properties
_idstring
The unique identifier for the company.
namestring
The name of the company.
brandingObjectOptional
The branding information for the company.
Child Properties
logoObject
The logo for the company.
Child Properties
urlstring
The URL of the logo.
backgroundColorstring
The background color of the logo.
colorstring
The company's branding color.
statusenum
The current state of the Task. Options are processing, failed and completed. Failed and completed are final states indicating either a successful or unsuccessful Task.
actionTypeenumOptional
The type of Action being executed. Present when product is action. Possible values are refresh, connect-account, disconnect-account, switch, or cancel-plan..
switchDataObjectOptional
Data associated with a switch Task. Present when product is switch.
Child Properties
paymentMethodObject
The payment method used to update the user's account.
Child Properties
_idstring
The unique identifier for the payment method.
titlestring
The title of the payment method. May be an empty string for bank accounts without a title.
typeenum
The type of payment method. Options are card and bank.
brandstring
The brand of the payment method.
expirystring
The expiry date of the payment method.
lastFourstring
The last 4 digits of the payment method.
accountTypeenum
The type of account. Options are checking and savings.
routingNumberstring
The routing number of the payment method.
lastFourAccountNumberstring
The last 4 digits of the account number.
failReasonenumOptional
For Tasks that failed, this is the reason why the Task failed. These are enumerated in the Task Failures section of the PayLink webhooks reference.
managedBy.companyObjectOptional
When failReason is subscription-managed-by-partner-provider, this object contains information about the system that manages the user's account.
Child Properties
_idstring
The unique identifier for the company.
namestring
The name of the company.
brandingObjectOptional
The branding information for the company.
Child Properties
logoObject
The logo for the company.
Child Properties
urlstring
The URL of the logo.
backgroundColorstring
The background color of the logo.
colorstring
The company's branding color.

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 similar to the following:

OnInteraction Example
{
  "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.

This list is not intended to be all-inclusive.
Viewed Search By Company Page
User viewed the company search page
Selected Company From Search By Company Page
User selected a company from the company search page
Viewed Zero Search Results From Search By Company Page
User searched for a company and saw no results
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
Viewed Login Page
User viewed the login page
Viewed Authentication Success Page
User viewed the authentication success 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 Try Again From Task Failed Page
User clicked try again on the task failed page
Sample interaction event
{
  "name": "Changed Payment Method",
  "value": {
    "customer": "Atomic",
    "language": "en",
    "product": "switch"
  }
}

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. Metadata is not included in client-side SDK 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.

Do not store any sensitive information (bank account numbers, card details, etc.) as metadata.
Sample metadata
{
  "order_id": "1234567890",
  "campaign_id": "email-marketing-campaign"
}

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.

In Sandbox flows that use TrueAuth, enter the test credential and wait a moment after typing. This pause gives Atomic's automations time to start the test flow.

Test where the user's credentials are correct and the task completes. When answering MFA questions, any answer will be accepted.

UsernameDescription
test-goodTest a successful operation.
test-custom-success-messageTest a user whose payment method was successfully updated, and a custom success message was delivered.

Test where the user encounters an issue connecting to the third-party system.

UsernameDescription
test-unknown-failureTest the user experience when there is an unexpected error.

Test where there is an error that occurs due to an action of the user.

UsernameDescription
test-subscription-inactiveTest a user who doesn't have an active subscription with the service provider.
test-bundle-wrong-providerTest a user whose subscription bundle is managed by another service.
test-payment-method-lockedTest a user whose service provider has temporarily disallowed updates to the user's payment method.
test-payment-method-declinedDuring the pre-authorization or prenote transaction, the payment method was declined by the service provider.
test-payment-method-limit-reachedThe maximum number of payment methods has been reached for the merchant. The user will need to remove an existing payment method before adding a new one.
test-payment-method-insufficient-fundsThe selected payment method lacks sufficient funds when the merchant attempts a pre-authorization or prenote transaction.
test-payment-method-device-disconnectedThe device used to start the task is no longer connected.

Test where the user encounters an issue originating from the service provider.

UsernameDescription
test-payment-method-not-supportedTest a user whose chosen payment method isn't supported by the service provider.
test-payment-switch-unsuccessfulTest a user whose payment method could not be updated. We use this generic fail reason when none of the other fail reasons apply.
When testing Switch in sandbox, only use card numbers from Basis Theory's test card list .

These sample PANs come from Basis Theory's test card docs . Refer there for the full sandbox card list and scenario details. The CVV values shown below are example values only.

Card NumberCVVCard Brand
5100000000000008234 (or any 3 digits)Mastercard
3700000000000023456 (or any 4 digits)American Express
4000000000000002123 (or any 3 digits)Visa