# Integration Guide

Integrate the Finix Tap to Pay on iPhone SDK into your own iOS app.

Tap to Pay entitlement required
Do not continue until Apple has granted your [Tap to Pay on iPhone entitlement](/ios/tap-to-pay/getting-started#request-the-tap-to-pay-entitlement). Your integration will not work without it.

**Before you start**, complete the [Getting Started](/ios/tap-to-pay/getting-started) guide. You'll need:

- Apple's Tap to Pay on iPhone entitlement granted to your developer account.
- A sandbox Apple Account to sign in on the test iPhone.
- Your Finix merchant credentials and IDs from the Finix Dashboard.


The [Demo App Walkthrough](/ios/tap-to-pay/demo-app-walkthrough) is optional but recommended as a working reference before you build your own integration.

Completed the demo app walkthrough?
You still need to create a new Finix Device for your own app.

## 1. Review Apple's App Review Requirements

Build to Apple's App Review requirements from day one
Apple reviews Tap to Pay on iPhone apps against specific user-experience requirements before granting the distribution entitlement. Build these requirements into your app from the start; retrofitting them after review feedback delays your launch. Review the [App Review requirements](/ios/tap-to-pay/app-review) before designing your checkout UI.

## 2. Configure Xcode and verify entitlement support

Once Apple has granted your Tap to Pay on iPhone entitlement, wire it into your project:

1. In your [Apple Developer account](https://developer.apple.com/account/), add the **Tap to Pay on iPhone** capability to your App ID, then regenerate and download your provisioning profiles.
2. Add the entitlement to your app's `.entitlements` file:


```xml YourApp.entitlements
<key>com.apple.developer.proximity-reader.payment.acceptance</key>
<true/>
```

1. Add an NFC usage description to your app's `Info.plist`. iOS shows this string the first time the reader is used:


```xml Info.plist
<key>NFCReaderUsageDescription</key>
<string>This app uses NFC to securely accept contactless payments via Tap to Pay on iPhone.</string>
```

1. Build to a physical iPhone and gate every Tap to Pay on iPhone entry point in your UI on `isSupported()`:


```swift
import FinixTapToPaySDK

if FinixTapToPay.isSupported() {
    // Show your Tap to Pay on iPhone entry points.
} else {
    // Hide Tap to Pay on iPhone and offer another payment method.
}
```

`isSupported()` returns `false` on unsupported hardware and on the simulator. If it returns `true` but reader preparation later fails immediately, re-check that the entitlement is present in the built app's signature and that your provisioning profile includes the capability. See [Troubleshooting and support](/ios/tap-to-pay/support).

iPad is not supported
Apple's Tap to Pay on iPhone is iPhone-only. `isSupported()` returns `false` on iPad regardless of iPadOS version.

## 3. Collect your SDK values

Collect these values before you initialize the SDK:

| Value | Format | Where to find it |
|  --- | --- | --- |
| API username | `USxxxxxxxxxxxxx` | [From the Finix Dashboard](/ios/tap-to-pay/getting-started#creating-api-keys). |
| API password | Issued with the username. | Shown once in the Dashboard when the key is created. Treat as a secret. |
| Merchant ID | `MUxxxxxxxxxxxxx` | [From the Finix Dashboard](/ios/tap-to-pay/getting-started#locating-the-merchant-id). |
| Merchant display name | Shown to the Buyer on Apple's tap screen. | From the Merchant details page. |
| Device ID | `DVxxxxxxxxxxxxx` | Created in [Set up a Device](/ios/tap-to-pay/device-setup). |


A configuration's credentials, merchant, and Device must all belong to the same environment (`.sandbox` or `.production`). Mixing environments is a common cause of authentication and token errors.

Keep credentials off the client
API credentials embedded in an app binary can be extracted. Instead of compiling them in, have your backend deliver the credential pair, merchant details, and Device ID to the app at session start, scoped to the signed-in merchant.

## 4. Confirm Your App's Bundle ID

You need your app's Bundle Identifier to create the Finix Device.

1. Open your project in Xcode.
2. Select your app target and go to **Signing & Capabilities**.
3. Copy the **Bundle Identifier**; you'll use it in the next step.


## 5. Create a Finix Device

Create a Device resource in Finix for the iPhone and your app's bundle ID. Do this once per merchant-iPhone pair; cache and reuse the Device ID on subsequent launches rather than creating duplicates.

Run these calls from your backend
Your Finix API credentials should not be embedded in the app binary. See [Collect your SDK values](#3-collect-your-sdk-values) above for the recommended pattern.

`{reader_identifier}` below is Apple's per-device identifier, obtained at runtime from `PaymentCardReader().readerIdentifier` (the `ProximityReader` framework). See [Device → Get the reader identifier](/ios/tap-to-pay/device-setup) in the SDK Reference for the Swift pattern to pass it to your backend.

**Using the API:**

```bash
curl -i -X POST \
  -u {your_api_key}:{your_api_secret} \
  https://finix.sandbox-payments-api.com/merchants/{merchant_id}/devices \
  -H 'Content-Type: application/json' \
  -H 'Finix-Version: 2022-02-01' \
  -d '{
    "app_bundle_id": "{your_app_bundle_id}",
    "description": "iOS Tap to Pay device",
    "model": "IOS_TAP_TO_PAY",
    "name": "iPhone Tap to Pay - {merchant name}",
    "serial_number": "{reader_identifier}"
  }'
```

Example response:

```json
{
  "id": "DVxxxxxxxxxxxxx",
  "enabled": false,
  "model": "IOS_TAP_TO_PAY",
  "merchant": "MUxxxxxxxxxxxxx",
  "name": "iPhone Tap to Pay - Front Counter",
  "serial_number": "{reader_identifier}",
  "created_at": "2026-10-06T22:03:38.297337Z"
}
```

Copy the `id`; you need it to activate the Device and to pass into `TapToPayConfiguration`.

## 6. Activate the Device

The Device starts disabled. Activate it before initializing the SDK.

```bash
curl -i -X PUT \
  -u {your_api_key}:{your_api_secret} \
  https://finix.sandbox-payments-api.com/devices/{device_id} \
  -H 'Content-Type: application/json' \
  -H 'Finix-Version: 2022-02-01' \
  -d '{ "action": "ACTIVATE" }'
```

A successful response returns the Device with `"enabled": true`.

## 7. Install and Initialize the SDK

The SDK is distributed as a binary XCFramework via Swift Package Manager.

1. In Xcode, choose **File → Add Package Dependencies…**
2. Enter the package URL: `https://github.com/finix-payments/finix-taptopay-ios-sdk`
3. Select **Up to Next Major Version** starting at `1.0.0`.


Build a `TapToPayConfiguration` with the values you collected in [Step 3](#3-collect-your-sdk-values) and the `Device` ID from [Step 5](#5-create-a-finix-device):

```swift
import FinixTapToPaySDK

let configuration = TapToPayConfiguration(
    credentials: TapToPayConfiguration.APICredentials(
        username: "USxxxxxxxxxxxxx",
        password: "{your_api_secret}"
    ),
    merchant: TapToPayConfiguration.MerchantInfo(
        merchantId: "MUxxxxxxxxxxxxx",
        merchantName: "Your Merchant Display Name"
    ),
    environment: .sandbox,
    deviceId: "DVxxxxxxxxxxxxx"
)

let tapToPay = FinixTapToPay(configuration: configuration)
```

Environment naming collision in SwiftUI
`TapToPayConfiguration.Environment` collides with `SwiftUI.Environment` in files that import both. If you need to reference the type by name (not just a case like `.sandbox`), add a typealias:

```swift
typealias TapToPayEnvironment = TapToPayConfiguration.Environment
```

Initialization makes no network calls; authentication happens on the first `linkAccount()`, `prepareReader()`, or `startTransaction()`.

See the [Installation and initialization](/ios/tap-to-pay/installation) reference for the full `TapToPayConfiguration`, `MerchantInfo`, and `TransactionOptions` field tables, and for the runtime methods (`refreshConfiguration()`, `clearAllCaches()`).

## 8. Sign In to Your iPhone with the Sandbox Account

Sign your test iPhone in to the [Sandbox Apple Account](/ios/tap-to-pay/getting-started#create-an-apple-sandbox-account):

1. Open the **Settings** app on the iPhone.
2. Tap your name at the top and sign out of the current Apple Account.
3. Sign in with the Sandbox Apple Account you created.


Use a dedicated test iPhone
Signing in replaces the device's iCloud identity (photos, messages, iCloud Drive). Use a dedicated test iPhone rather than a personal device.

## 9. Link the Merchant Account

Follow the [Account linking](/ios/tap-to-pay/account-linking) reference to call `linkAccount()` and present Apple's Terms and Conditions flow.

**Key points for your UI:**

- Gate all Tap to Pay entry points on `FinixTapToPay.isSupported()`; this returns `false` on unsupported hardware and the simulator.
- Handle `.accountAlreadyLinked` as success (not an error); the merchant has already accepted Apple's Terms.


## 10. Prepare the Reader

Follow the [Transactions: Prepare the reader](/ios/tap-to-pay/transactions#prepare-the-reader) reference to call `prepareReader()`.

**Key points:**

- Prepare the reader at app launch and on foreground, not just before a payment. This avoids visible latency at checkout.
- Enable `autoPrepareOnForeground` so an existing session is re-prepared automatically.


## 11. Process Transactions

Follow the [Transactions](/ios/tap-to-pay/transactions) reference to start a sale, authorization, or refund. The SDK presents Apple's card-reading sheet, processes the payment through Finix, and returns a `TapToPayTransactionResult`.

**Key points:**

- Subscribe to transaction events before calling `startTransaction()`; Apple expects your processing UI to appear within about one second of the merchant initiating a payment.
- Show your processing screen immediately on the first event, not after the tap.


## 12. Test Your Integration

Run through the [manual test checklist](/ios/tap-to-pay/testing#manual-test-checklist) on a physical iPhone, then [verify each transaction in the Sandbox Dashboard](/ios/tap-to-pay/testing#verify-contactless-transactions-in-the-dashboard) before requesting the distribution entitlement.

## 13. Review Privacy Disclosures

Review [Privacy and data collection](/ios/tap-to-pay/privacy) and ensure your app's privacy disclosures accurately reflect the data the SDK collects.

## 14. Request the Distribution Entitlement

Verify App Review requirements before requesting
Walk through the [App Review requirements](/ios/tap-to-pay/app-review) one more time against your built app before you request the distribution entitlement. Each requirement that isn't met adds another round of Apple feedback and delays your launch.

Once your integration is complete and your app meets Apple's App Review requirements, request the distribution entitlement to enable TestFlight and App Store distribution.

At the time Apple granted your Tap to Pay on iPhone entitlement, a follow-up email was sent describing the steps needed to publish your app:

1. Reply to the original Apple email thread requesting the distribution entitlement.
2. Upload any materials Apple requests (videos demonstrating your UX, etc.) using the link in the email.
3. Ensure your app meets all items in the [App Review requirements](/ios/tap-to-pay/app-review).


The distribution entitlement typically takes 1-2 weeks with one or two rounds of Apple feedback.

TestFlight requires the distribution entitlement
The distribution entitlement is required even for TestFlight; plan for the review lead time before any beta launch.

## 15. Go Live

Once the distribution entitlement is granted, switch your integration to Production:

1. Create a new Finix Device against the Production API (`https://finix.live-payments-api.com`) using your Production credentials and Production merchant.
2. Activate the new Device.
3. Update your `TapToPayConfiguration` with Production credentials, the Production merchant ID, the Production Device ID, and `environment: .production`.
4. Sign the merchant's iPhone in with their regular Apple Account (not the Sandbox Apple Account).


The rest of your integration stays the same.