# Test and go live

Test your integration in test mode on a real iPhone. Then use the checklist to go live.

## Test mode[​](#test-mode "Direct link to Test mode")

* A test mode API key gives a sandbox token. Payments with a sandbox token are test payments.
* A live API key gives a live token.
* Do not use test and live tokens on the same device.

Tap to Pay on iPhone does not run in the iOS Simulator. Test on a supported iPhone: an iPhone XS or newer with iOS 18.5 or later. For the test and live API keys, see [Testing](https://docs.monei.com/testing.md).

Test these cases before you go live:

* An approved payment and a declined payment, each with its signed webhook.
* A payment that the user cancels on Apple's screen.
* An expired token: renew it and call `prepare` again.
* Location access denied, and location access allowed again in Settings.
* Your pending state for [`outcomeUnknown`](https://docs.monei.com/monei-pay/in-app-tap-to-pay/errors.md#outcome-unknown), and how your team finds the payment by `orderId`.

## Example app[​](#example-app "Direct link to Example app")

The package repository has an example app: `Example/TapToPayExample.xcodeproj`. It is a SwiftUI app with a token field, an amount, an order ID, a pay button, education and a result view.

1. Open `Example/TapToPayExample.xcodeproj` in Xcode.
2. Set your team and bundle ID. Your team must have the Tap to Pay on iPhone entitlement.
3. Run the app on a supported iPhone.
4. Paste a token from your server, or from a `curl` call with your test mode API key. See [Request a token](https://docs.monei.com/monei-pay/in-app-tap-to-pay/backend.md#request-a-token).

## Versions and compatibility[​](#versions "Direct link to Versions and compatibility")

The SDK uses semantic versioning (`MAJOR.MINOR.PATCH`):

* **Patch:** bug fixes. No change to the public API or to error semantics.
* **Minor:** an update inside the SDK, or new API that does not break your code.
* **Major:** a change in error semantics, or a change that breaks your code.
* **0.x versions:** until 1.0.0, a minor version (for example 0.2.0) can change the public API. Read the release notes before you update.
* **Prereleases** (`-beta.N`) are for testing only. Do not ship them to production.

| SDK version    | iOS minimum | Built with               | Notes                                                                                                                                                                                                                             |
| -------------- | ----------- | ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `0.2.0`        | 18.5        | Xcode 26.6 (Swift 6.3.3) | `PaymentResult` has new fields: `amount`, `currency`, `statusCode`, `statusMessage`, `authorizationCode`, `cardType` and `cardCountry`. A declined result shows the reason without a call to MONEI. No change to existing fields. |
| `0.1.1`        | 18.5        | Xcode 26.6 (Swift 6.3.3) | Installs without a GitHub token: public download URLs. Same SDK code as `0.1.0`.                                                                                                                                                  |
| `0.1.0`        | 18.5        | Xcode 26.6 (Swift 6.3.3) | First release. Signed binary. Same code as `0.1.0-beta.5`.                                                                                                                                                                        |
| `0.1.0-beta.5` | 18.5        | Xcode 26.6 (Swift 6.3.3) | Prerelease. Signed binary.                                                                                                                                                                                                        |
| `0.1.0-beta.4` | 18.5        | Xcode 26.6 (Swift 6.3.3) | Prerelease. Signed binary.                                                                                                                                                                                                        |
| `0.1.0-beta.3` | 18.5        | Xcode 27.0 (Swift 6.4)   | Prerelease. Not signed.                                                                                                                                                                                                           |

Use the same Xcode version as "Built with", or a newer one. From `0.1.0-beta.4`, MONEI signs the `MoneiTapToPay` binary (team `72J3PXJJ4K`).

For 0.x versions, use an exact version in Swift Package Manager. From 1.0.0, use `from:`. See [Add the package](https://docs.monei.com/monei-pay/in-app-tap-to-pay/get-started.md#add-package).

## Go-live checklist[​](#go-live-checklist "Direct link to Go-live checklist")

* Apple gave your team the **publishing** Tap to Pay on iPhone entitlement.
* MONEI has your Apple Team ID and the bundle ID of each app that takes payments.
* Your app uses a release version of the SDK, for example `0.2.0`, and not a prerelease (`-beta.N`).
* Your server uses your live API key, and the app gets live tokens only.
* Your server renews each token before it expires, and the app calls `prepare` with the new token.
* Each payment has a new `orderId` and a `callbackUrl`.
* Your server verifies the signature of each webhook, and fulfils orders from the webhook only.
* Your app shows a pending state for `outcomeUnknown` and never retries the payment.
* Your UI uses the name "Tap to Pay on iPhone", and hides it when `TapToPay.isSupported` is `false`.
* You declared the [App Store privacy details](https://docs.monei.com/monei-pay/in-app-tap-to-pay/get-started.md#privacy).

## Common questions[​](#common-questions "Direct link to Common questions")

### Can I test in the iOS Simulator?[​](#simulator "Direct link to Can I test in the iOS Simulator?")

No. Tap to Pay on iPhone does not run in the iOS Simulator. Test on a supported iPhone.

### Can I ship a prerelease to the App Store?[​](#ship-prerelease "Direct link to Can I ship a prerelease to the App Store?")

No. Prereleases (`-beta.N`) are for testing only. Ship a release version, for example `0.2.0`.

### Which Xcode version do I need?[​](#xcode-version "Direct link to Which Xcode version do I need?")

The Xcode version in the "Built with" column for your SDK version, or a newer one. For `0.2.0`, use Xcode 26.6 or newer.
