Skip to content

Set up a Device

Every iPhone that will be used to accept payments is represented in Finix by a Device, the same way a physical terminal is. The SDK requires the Device's ID at initialization.

Provision before you initialize

Create the Device first, then pass its ID to TapToPayConfiguration. A missing or un-activated Device doesn't fail at initialization. It shows up later as token and transaction failures.

A Tap to Pay on iPhone Device is specific to one merchant and one physical iPhone. The iPhone side of that identity is Apple's reader identifier, which you store as the Device's serial_number.

Run these API calls from your backend

These API calls use your Finix API credentials. The recommended pattern is a single "provision Tap to Pay on iPhone device" endpoint in your API that the app calls with the reader identifier (see Cache and reuse the Device ID). Devices can also be created directly in the Finix Dashboard.

Get the reader identifier

Get the reader identifier

Apple assigns each iPhone a stable reader identifier. Fetch it on the device and send it to your backend.

Check for an existing Device

Check for an existing Device

Before creating a Device, check whether one already exists for this Merchant and reader (for example, after the merchant reinstalls your app).

If the response contains a Device whose serial_number matches the reader identifier and whose enabled is true, reuse its id and skip the rest of this page. Confirm the serial_number matches on your side before reusing a result.

Create the Device

Create the Device

Create the Device under the Merchant that receives the payments.

FieldValue
modelAlways IOS_TAP_TO_PAY.
name, descriptionFree-form labels shown in the Finix Dashboard.
serial_numberThe Apple reader identifier from the previous step.
app_bundle_idYour app's bundle identifier. Must match the app that takes payments.

A successful response returns the new Device. Note the id and that the Device starts disabled:

Response
{
  "id": "DVxxxxxxxxxxxxx",
  "enabled": false,
  "model": "IOS_TAP_TO_PAY",
  "merchant": "MUxxxxxxxxxxxxx",
  "name": "Tap to Pay on iPhone - Front Counter",
  "serial_number": "{reader_identifier}",
  "created_at": "2026-08-04T17:32:11.000Z"
}

Activate the Device

Activate the Device

After creating the Device, activate it before taking payments. A successful response returns the Device with "enabled": true.

Activation is required

A Device must be activated (enabled: true) before it can process transfers. If you skip activation, transactions on that Device fail at processing time.

Cache and reuse the Device ID

Cache and reuse the Device ID

Provisioning only needs to happen once per Merchant and iPhone pair, so don't repeat it on every launch:

  • Persist the Device ID keyed by both the Merchant ID and the reader identifier. A new iPhone (new reader identifier) or a different Merchant needs its own Device.
  • On launch, use the cached ID if present; otherwise run the check-and-create flow above.
  • If a transaction fails with an error indicating the Device is not activated or not enabled, discard the cached ID and re-provision on the next attempt.

Next: Installation and initialization.

import ProximityReader

func fetchReaderIdentifier() async throws -> String {
    try await PaymentCardReader().readerIdentifier
}

func tapToPayDeviceId(merchantId: String, readerIdentifier: String) async throws -> String {
    let cacheKey = "finix_ttp_device_\(merchantId)_\(readerIdentifier)"
    if let cached = UserDefaults.standard.string(forKey: cacheKey) {
        return cached
    }
    // Your backend looks up or creates + activates the Device for
    // (merchantId, readerIdentifier) and returns its ID.
    let deviceId = try await backend.provisionTapToPayDevice(
        merchantId: merchantId,
        readerIdentifier: readerIdentifier
    )
    UserDefaults.standard.set(deviceId, forKey: cacheKey)
    return deviceId
}