Skip to main content

IOS SDK

The Accrue Savings IOS SDK is available as a package for your company to integrate the Accrue Wallet.

It simplifies the integration by combining the Wallet lifecycle and deep linking into a single package.

Installation​

Your package is available as a Swift Package Manager package.

The repository URL is https://github.com/accrue-savings/ios-sdk

Swift Package Manager​

To add the Accrue Savings SDK to your Xcode project, select File > Swift Packages > Add Package Dependency and enter the repository URL.

Usage​

Here is an example of how to embed the widget in a IOS (swift) application:

import AccrueIosSDK
import SwiftUI
import WebKit

struct ContentView: View {
// Initialize context data with user information
@StateObject private var contextData = AccrueContextData(
userData: AccrueUserData(
// Deprecated — use stableReferenceId instead
referenceId: "yourReferenceId",
// Always set for new integrations (immutable once set). Legacy merchants may omit during transition.
stableReferenceId: "yourStableReferenceId",
// User's email
email: "email@example.com",
// User's phone number
phoneNumber: "+12125559999",
// Additional data to be attached to the user profile stored with Accrue
additionalData: ["firstName": "John", "lastName": "Doe"]
),
// Optional settings data
settingsData: AccrueSettingsData(
// Should the widget inherit the authentication from the parent app
shouldInheritAuthentication: true
)
)

@StateObject private var walletManager = WalletManager()

var body: some View {
VStack {
if let wallet = walletManager.accrueWallet {
wallet
} else {
ProgressView() // Loading indicator
}
}
.onAppear {
walletManager.initializeWallet(contextData: contextData)
}
}
}

class WalletManager: ObservableObject {
@Published var accrueWallet: AccrueWallet?

func initializeWallet(contextData: AccrueContextData) {
accrueWallet = AccrueWallet(
// Your Accrue merchant ID
merchantId: "your-merchant-id",
// Redirection token for deep linking
redirectionToken: "your-token",
// Set to false for production
isSandbox: true,
contextData: contextData,
onAction: { action in
// Handle user actions from the wallet
print("Wallet action: \(action)")
}
)
}
}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

Props​

The following props are available for the AccrueWallet component:

merchantId
RequiredYes
TypeString
DescriptionMerchant ID (received from Accrue)
DefaultN/A
Example724a57f2-1670-42de-b1f0-a94425fb60cf
redirectionToken
RequiredNo
TypeString
DescriptionRedirection token for the deep linking. This token will be used to redirect the user to a specific screen within the Accrue Savings Widget
Defaultnil
Example61a77652-14ae-4ed4-9bb3-cdb31312869e
isSandbox
RequiredNo
TypeBool
DescriptionFlag to enable the sandbox mode. If set to true, the widget will use the sandbox environment
Defaulttrue
Exampletrue
contextData
Requiredyes
TypeContextData(userData: AccrueUserData, settingsData: AccrueSettingsData)
DescriptionYour own user data to be attached to the user profile stored with Accrue. AccrueUserData supports stableReferenceId (required for new integrations; immutable once set), referenceId (deprecated), email, phoneNumber, and additionalData.
Defaultnil
ExampleContextData(userData: AccrueUserData(referenceId: "legacy-id", stableReferenceId: "stable-abc-123", email: "a@b.com", phoneNumber: "+12125559999", additionalData: ["firstName": "John", "lastName": "Doe"]), settingsData: AccrueSettingsData())
onAction
RequiredNo
Type((String) -> Void)?
DescriptionCallback with actions triggered by the user
Defaultnil
Example{ print("action with data: (action)") }

ContextData​

The ContextData struct is used to pass the user data and settings data to the widget.

AccrueUserData​

The AccrueUserData struct is used to pass the user data to the widget. The following fields are available:

referenceId
RequiredNo
TypeString
DescriptionDeprecated. Use stableReferenceId instead. A unique reference id for the user. Immutable once set.
DefaultN/A
Example123e4567-e89b-12d3-a456-426614174000
stableReferenceId
RequiredYes
TypeString
DescriptionStable merchant-scoped user ID. All new integrations must provide this (immutable once set). Omit only while completing migration from referenceId. When set, becomes the effectiveReferenceId.
DefaultN/A
Examplestable-abc-123
email
RequiredNo
TypeString
DescriptionUser email
DefaultN/A
Exampleemail@example.com
phoneNumber
RequiredYes
TypeString
DescriptionUser US phone number
DefaultN/A
Example+12125559999
additionalData
RequiredNo
TypeDictionary<String, String>
DescriptionAdditional data to be attached to the user profile stored with Accrue
Defaultnil
Example["firstName": "John", "lastName": "Doe"]

⚠️ Important: The additionalData will accept the following fields:

  • firstName
  • lastName

AccrueSettingsData​

The AccrueSettingsData struct is used to pass the settings data to the widget. The following fields are available:

shouldInheritAuthentication
RequiredNo
TypeBool
DescriptionShould the widget inherit the authentication from the parent app
Defaulttrue
Exampletrue

⚠️ Important: Keep in mind that the shouldInheritAuthentication will change the behavior of the widget.

The following UX changes will occur:

  • We will use the phoneNumber passed as props to auto-send the OTP to the user if not already authenticated on the widget.
  • We will use the referenceId and/or stableReferenceId you pass as the merchant-side user identity. If either is present, we consider the user authenticated on your side; otherwise we consider them unauthenticated.
  • Once user confirms the OTP, we will consider the user as authenticated on the widget.
  • If referenceId or stableReferenceId changes, the user will be logged out from the widget.

Considerations:

  • The user would not be able to change the phone number in the widget.
  • The user would not be able to logout from the widget (unless the merchant identity you pass changes — referenceId or stableReferenceId).
  • The user would not be able to change the email in the widget.
  • All phoneNumber/email changes should be handled on the merchant side.

Actions​

Actions are emitted from the webview in the form of a string. The onAction callback will be triggered with the action string as a parameter.

The following actions are available:

  • AccrueWallet::SignInButtonClicked: The user clicked the sign-in button
  • AccrueWallet::RegisterButtonClicked: The user clicked the register button
  • AccrueWallet::SignInPerformed: The user completed wallet sign-in successfully

The string will contain the action key and any additional data in the following format:

{
"action": "AccrueWallet::SignInButtonClicked",
"data": {}
}

Sign-in completion event​

When wallet sign-in completes, iOS receives the AccrueWallet::SignInPerformed event through onAction.

onAction: { action in
guard let data = action.data(using: .utf8),
let envelope = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
let key = envelope["key"] as? String,
key == "AccrueWallet::SignInPerformed",
let payload = envelope["data"] as? [String: Any] else {
return
}

// payload fields:
// id (String)
// isNewUser (Bool)
// referenceId (String?)
// stableReferenceId (String?)
// effectiveReferenceId (String?)
}

The sign-in payload includes:

  • id: Accrue user ID
  • isNewUser: true on first successful sign-in
  • referenceId: legacy merchant user identifier (if provided)
  • stableReferenceId: stable merchant user identifier (if provided)
  • effectiveReferenceId: stableReferenceId when present, otherwise referenceId

Sending events to the widget​

You can send events to the widget by calling the handleEvent method on the AccrueWallet instance. It will send a javascript event to the webview that will be handled by the embedded widget.

Currently, supported events are:

  • AccrueTabPressed: The user pressed the tab button in the app where the widget is embedded.