Skip to content

Test your integration

Environments and test setup

Integration testing happens on a physical iPhone (XS or later, iOS 18.1 or later) against the Finix Sandbox: Sandbox API credentials, a Sandbox merchant, a Device created against the Sandbox API, and environment: .sandbox in your configuration.

Testing in Sandbox

Sandbox transactions don't move real money. Complete the Apple-side Sandbox setup below before your first tap. Without it, card reads run against Apple's live service.

Set up the iPhone for Sandbox testing

Tap to Pay on iPhone has its own Apple-side test mode, driven by the Apple Account signed in on the test device:

  1. Create a Sandbox Apple Account: in App Store Connect, go to Users and Access ▸ Sandbox ▸ Testers and add a tester. The tester email must be a real address that has never been used as an Apple Account before. Reusing an existing Apple Account email fails silently. See Apple's Sandbox testing guide.
  2. On the test iPhone, sign in with the Sandbox Apple Account as the device's primary Apple Account: sign out of the current account at the top of the Settings app, then sign in with the Sandbox tester.
  3. With the Sandbox account signed in as the primary account, the Terms and Conditions flow and card reads run against Apple's Sandbox, and you can tap Apple Pay Sandbox test cards. Apple publishes test card numbers for Visa, Mastercard, American Express, and Discover that you can add to Wallet on a second (Sandbox-signed-in) device, alongside physical test cards if you have them.
Primary Apple Account, not the App Store Sandbox setting

Settings ▸ App Store ▸ Sandbox Account only affects In-App Purchase testing. It has no effect on Tap to Pay on iPhone or Wallet. The Sandbox tester must be the account the whole device is signed in to. Because signing in replaces the device's iCloud identity (photos, messages, iCloud Drive), use a dedicated test iPhone rather than a personal one.

No iOS betas

Tap to Pay on iPhone does not work on beta releases of iOS. Test on release iOS versions.

Try the demo app

The Finix Tap to Pay on iPhone demo app is a small SwiftUI reference integration. Clone it, add your Sandbox credentials and Device ID in its configuration screen, and run it on a physical iPhone. It demonstrates support checks, linking, reader preparation, and sale, authorization, and refund transactions end to end, which makes it a useful reference before you build the flow into your own app.

Write unit tests

Your app-level logic (receipts, persistence, UI state) can be tested without a device. The result type's memberwise initializer is internal; use the public mock factory to construct results in your test target:

ReceiptRendererTests.swift
import XCTest
import FinixTapToPaySDK
@testable import YourApp

final class ReceiptRendererTests: XCTestCase {
    func testRendersApprovedReceipt() {
        let result = TapToPayTransactionResult.mock(
            amount: 1250,
            currency: "USD",
            cardBrand: "VISA",
            last4: "4242",
            transferId: "TRxxxxxxxxxxxxx",
            transferState: "SUCCEEDED"
        )

        let receipt = ReceiptRenderer().render(result)

        XCTAssertTrue(receipt.contains("$12.50"))
        XCTAssertTrue(receipt.contains("VISA •••• 4242"))
    }
}

mock(amount:currency:...) provides default values for the card fields and nil for the transfer fields. Override the fields your test asserts on.

Manual test checklist

Run through these on a physical iPhone before requesting the distribution entitlement:

  • First link: fresh install, sign-in, linkAccount() presents Apple's Terms and Conditions.
  • Re-link: call linkAccount() again; confirm your app treats .accountAlreadyLinked as success.
  • Cold and warm prepare: first prepareReader() after install (slow) and after foregrounding (fast); your indeterminate progress UI shows during user-visible preparation.
  • Sale, authorization, and refund: one of each; verify each transferId in the Sandbox Finix Dashboard.
  • Cancel mid-read: dismiss the tap sheet and cancel from your UI; both paths surface .transactionCancelled and return to checkout cleanly.
  • Backgrounding: background the app mid-flow; confirm you re-prepare on foreground and no reader call runs from the background.
  • Un-activated Device: point at a Device that was never activated; confirm your recovery path (re-provision) works.
  • Unsupported device: on the simulator or an old iPhone, confirm Tap to Pay on iPhone entry points are hidden by your isSupported() gate.

Next: Privacy and data collection.