Push Provisioning SDK
The Unit Push Provisioning SDK wraps the Visa Digital Enablement (VDE) SDK so you can add a Unit-issued card to Apple Wallet from within your app — without implementing the Visa push-provisioning flow yourself. The SDK handles initialization, fetching the mobile-wallet payload from Unit, checking supported wallets, and presenting Apple's add-card sheet.
Platform
Requirements
- Requires iOS 15.0+
- Visa Digital Enablement (VDE) SDK 5.6.0 — the Visa frameworks you embed must be this version (provided by Unit). The SDK is built and tested against 5.6.0.
- A physical device and a TestFlight build — Apple Pay provisioning does not run on the Simulator, and the full flow should be tested with a build distributed through TestFlight.
Before you start
Complete the program enablement in the Add to Mobile Wallet guide with your Unit point of contact. This covers Visa Debit Processing Service (DPS) program setup, brand approval, and Apple Pay onboarding. You will also need:
- The Apple Pay In-App Provisioning entitlement and the Wallet capability on your app — see Apple Pay Prerequirements.
- Your Visa App ID (provided by Unit).
- A Unit customer token and the card ID to provision.
Installation
1. Add the UnitPushProvisioning Swift Package
In Xcode, choose File → Add Package Dependencies…, enter the package URL, and add the UnitPushProvisioning product to your app target:
https://github.com/unit-finance/unit-ios-push-provisioning
UnitPushProvisioning is a dynamic framework, so it must be embedded in your app. In your app target, open General → Frameworks, Libraries, and Embedded Content and set UnitPushProvisioning to Embed & Sign.
2. Add the Visa frameworks
Add the Visa Digital Enablement frameworks to your app target (Embed & Sign), as described in the integration steps:
VisaPushProvisioning.xcframeworkVisaInAppModuleCore.xcframeworkVisaAnalytics.xcframeworkVisaFeatureModuleCore.xcframeworkVisaMobileFoundation.xcframeworkRLTMXProfiling.xcframeworkRLTMXProfilingConnections.xcframework
The manager
All calls go through UnitPushProvisioningSDK.manager. Every method is available as a throwing Swift call and with a completion handler: configure is synchronous (throws), and walletStatus and startCardProvisioning are async throws. Each example below shows both styles.
Configure
Configure the SDK once, after your app has initialized. Pass the environment and your Visa App ID. The same environment is used for both Unit and Visa:
- throws
- Completion handler
import UnitPushProvisioning
do {
try UnitPushProvisioningSDK.manager.configure(
environment: .production, // .production or .sandbox
visaAppId: "YOUR_VISA_APP_ID"
)
} catch {
print(error.localizedDescription)
}
import UnitPushProvisioning
UnitPushProvisioningSDK.manager.configure(
environment: .production, // .production or .sandbox
visaAppId: "YOUR_VISA_APP_ID"
) { result in
if case .failure(let error) = result {
print(error.localizedDescription)
}
}
Visa keeps the first environment it is configured with until the app restarts. Configure the SDK with the environment you will provision in. Calling configure again with a different environment fails.
Set the customer token
Set the customer token once, before checking the wallet status or adding a card. Set it again whenever the token changes, for example after it is refreshed:
UnitPushProvisioningSDK.manager.customerToken = customerToken
Check wallet status
You can check whether the card can be provisioned on this device — for example, to decide whether to show an "Add to Wallet" button:
- async / await
- Completion handler
let status = try await UnitPushProvisioningSDK.manager.walletStatus(cardId: cardId)
switch status {
case .ReadyToProvision: break // show the Add to Wallet button
case .AlreadyProvisioned: break // the card is already in the wallet
case .NotAvailable: break // hide the button
@unknown default: break
}
UnitPushProvisioningSDK.manager.walletStatus(cardId: cardId) { result in
switch result {
case .success(.ReadyToProvision): break // show the Add to Wallet button
case .success: break // already in the wallet, or not available
case .failure(let error): print(error.localizedDescription)
}
}
Add the card to the wallet
When the customer taps your "Add to Wallet" button, start provisioning. The SDK presents Apple's add-card sheet and returns the resulting status for this device:
- async / await
- Completion handler
let status = try await UnitPushProvisioningSDK.manager.startCardProvisioning(cardId: cardId)
UnitPushProvisioningSDK.manager.startCardProvisioning(cardId: cardId) { result in
switch result {
case .success(let status): print(status)
case .failure(let error): print(error.localizedDescription)
}
}
Handling errors
Every method throws a UNPushProvisioningError, or delivers it in the completion handler. Match on its reason to decide what to do, and log its description, which includes the operation and the details:
do {
let status = try await UnitPushProvisioningSDK.manager.walletStatus(cardId: cardId)
} catch let error as UNPushProvisioningError {
switch error.reason {
case .missingCustomerToken:
break // set the customer token and try again
case .networkFailed:
break // show a "try again" message
default:
break
}
print(error.description) // e.g. "Error in walletStatus: the Unit API request failed (HTTP 401: ...)"
}
Error callback
Some errors are not the result of a call you made, so there is nothing to throw them from. Register a callback to receive them:
UnitPushProvisioningSDK.manager.addErrorCallback { error in
switch error.reason {
case .visaSDKMissing:
break // add the Visa frameworks to your app
case .unsupportedVisaVersion:
break // embed the supported Visa SDK version
case .missingProvisioningEntitlement:
break // add the Apple Pay In-App Provisioning entitlement
default:
break // for example, a failed call made by the Components SDK
}
print(error.description)
}
The callback is called on the main thread. You can register more than one.
Errors thrown from a call you make yourself are not repeated in the callback.
Types
UNPushProvisioningError
| Property | Type | Description |
|---|---|---|
| operation | UNPushProvisioningError.Operation | The call or check that failed. |
| reason | UNPushProvisioningError.Reason | Why it failed. Match on this to handle errors. |
| details | String? | Specifics for logs and support, such as the HTTP status and response body. Not meant for matching; the text can change. |
| underlyingError | Error? | The original error, for example a UNNetworkError, URLError, or Visa VPError. |
UNPushProvisioningError.Operation
| Case | Meaning |
|---|---|
| configure | configure(environment:visaAppId:) |
| walletStatus | walletStatus(cardId:) |
| startCardProvisioning | startCardProvisioning(cardId:) |
| requirementsCheck | The checks the SDK runs at app launch. Reported through the error callback. |
UNPushProvisioningError.Reason
| Case | When |
|---|---|
| notConfigured | configure wasn't called, or didn't succeed. |
| missingCustomerToken | No customer token is set. |
| noPresentingViewController | No view controller was available to present Apple's add-card sheet. |
| networkFailed | The Unit API request failed, for example an invalid or expired customer token, an unknown card ID, or no connection. |
| visaFailed | The Visa SDK reported a failure, including rejecting the configuration. |
| visaSDKMissing | The Visa frameworks are not linked in your app. Reported through the error callback. |
| unsupportedVisaVersion | One or more embedded Visa frameworks don't match the supported version. details lists them. Reported through the error callback. |
| missingProvisioningEntitlement | Your app is missing the Apple Pay In-App Provisioning entitlement. Reported through the error callback. |
| internalError | Any other failure. |
UNEnvironment
| Case | Meaning |
|---|---|
| production | Unit's production API and Visa's production environment. |
| sandbox | Unit's sandbox API and Visa's sandbox environment. |
Completion and callback types
public typealias UNPushProvisioningCompletion = (Result<Void, UNPushProvisioningError>) -> Void
public typealias UNPushProvisioningStatusCompletion = (Result<VPProvisionStatus, UNPushProvisioningError>) -> Void
public typealias UNPushProvisioningErrorCallback = (UNPushProvisioningError) -> Void
Changelog
5.6.0 (Oct 18, 2026)
- Initial release of the Unit iOS Push Provisioning SDK —
configure,walletStatus,startCardProvisioning, and an error callback, wrapping Visa Digital Enablement SDK 5.6.0.