# Revolut Tap to Pay SDK

This page contains information about the available methods and parameters of the Revolut Tap to Pay SDK for iOS.

:::info
For detailed instructions on how to install and integrate the SDK, see: [Accept payments via Tap to Pay on iPhone - iOS](/docs/guides/merchant/accept-payments/in-person-payments/tap-to-pay/integration-guide).
:::

## Methods and parameters

### `RevolutTapToPayKit` initialiser

The `RevolutTapToPayKit` initialiser creates the main entry point to all SDK flows. The SDK must be initialised with your client ID, the environment, a token provider that fetches short-lived device tokens from your backend, and an `onLogout` handler.

```swift
public final class RevolutTapToPayKit {
    public init(
        clientId: String,
        environment: RevolutTapToPayKit.Environment,
        tokenProvider: TokenProviderProtocol,
        onLogout: @escaping @Sendable () -> Void
    )
}
```

| Parameter | Description | Format | Required |
|-----------|-------------|--------|----------|
| `clientId` | Your client ID obtained from the [Developer Portal](https://developer.revolut.com/portal). Use the client ID corresponding to the selected environment. | `String` | Yes |
| `environment` | This parameter specifies the environment in which the SDK operates. <br/><br/>_Currently, only the **production environment** is available._ Possible values: <ul><li>`.production`</li></ul> | [`Environment`](#revoluttaptopaykitenvironment-enumeration) | Yes |
| `tokenProvider` | An instance of a type conforming to [`TokenProviderProtocol`](#tokenproviderprotocol-protocol). The SDK calls this to request fresh short-lived device tokens from your backend. | [`TokenProviderProtocol`](#tokenproviderprotocol-protocol) | Yes |
| `onLogout` | A closure called when the SDK receives two unauthorised errors in a row from the `TokenProviderProtocol.fetchAccessToken` method. This means the merchant is no longer authorised — consent was revoked, not granted, or the app permission was removed in the Developer Portal. The SDK cannot continue operating with that merchant account. Stop SDK usage and prompt the merchant to re-authorise via the OAuth consent flow, or fall back to other payment methods. | `Closure` | Yes |

### `RevolutTapToPayKit.performPayment` method

Receives a single payment for a predetermined amount. The SDK handles the entire payment flow - including device pairing, order creation, payment processing, and presenting the payment UI - and returns the result via callbacks.

```swift
func performPayment(
    amount: UInt,
    currency: String,
    description: String?,
    merchantName: String?,
    onDidCharge: @escaping (RevolutTapToPayKit.Receipt?, Result<Void, RevolutTapToPayKit.Error>) -> Void,
    completion: @escaping () -> Void
)
```

| Parameter | Description | Format | Required |
|-----------|-------------|--------|----------|
| `amount` | The payment amount in minor units (e.g., `10_00` for £10.00). Cannot be zero. | `UInt` | Yes |
| `currency` | The payment currency as a 3-letter [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) code (e.g., `"GBP"`). | `String` | Yes |
| `description` | Optional description. This appears in the merchant's Revolut Business transaction history. | `String` | No |
| `merchantName` | Optional merchant name. This is added to the receipt. | `String` | No |
| `onDidCharge` | A closure invoked after the payment is complete, returning the payment result and a [`Receipt`](#revoluttaptopaykitreceipt-struct) if available. When this closure is invoked, the SDK's UI is still presented on screen. <br/><br/> The `Result` is `Result<Void, RevolutTapToPayKit.Error>` - `.success` indicates the payment was completed, `.failure(RevolutTapToPayKit.Error)` indicates the payment failed. See [Errors](#revoluttaptopaykiterror-enumeration). | `Closure` | Yes |
| `completion` | A closure called on the completion of the flow. When this closure is invoked, nothing is presented on screen, and the app may continue with any UI updates. | `Closure` | Yes |

:::note
If the SDK detects that the Tap to Pay payment method cannot accept a payment, it automatically falls back to a QR code payment method. The QR code payment method cannot be invoked directly in `performPayment`.
:::

### `RevolutTapToPayKit.performPayments` method

Receives a series of payments where the merchant enters the amount each time via the SDK's built-in amount entry UI. After the amount is entered, the SDK presents a UI allowing the merchant to choose between Tap to Pay and QR code payment methods.

```swift
func performPayments(
    currency: String,
    merchantName: String?,
    onDidCharge: @escaping (RevolutTapToPayKit.Receipt?, Result<Void, RevolutTapToPayKit.Error>) -> Void,
    completion: @escaping () -> Void
)
```

| Parameter | Description | Format | Required |
|-----------|-------------|--------|----------|
| `currency` | The payment currency as a 3-letter [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) code (e.g., `"GBP"`). This currency is the same for all payments in the series. | `String` | Yes |
| `merchantName` | Optional merchant name. This is added to the receipt. | `String` | No |
| `onDidCharge` | A closure invoked after each payment completes, returning the payment result and a [`Receipt`](#revoluttaptopaykitreceipt-struct) if available. When this closure is invoked, the SDK's UI is still presented on screen. <br/><br/> The `Result` is `Result<Void, RevolutTapToPayKit.Error>` - `.success` indicates the payment was completed, `.failure(RevolutTapToPayKit.Error)` indicates the payment failed. See [Errors](#revoluttaptopaykiterror-enumeration). | `Closure` | Yes |
| `completion` | A closure called on the completion of the flow. When this closure is invoked, nothing is presented on screen, and the app may continue with any UI updates. | `Closure` | Yes |

### `RevolutTapToPayKit.performFirstTimeSetup` method

Optionally guides the merchant through the initial setup. This method:

1. Runs the steps necessary to set up Apple's `ProximityReader` framework for operation, including accepting terms and conditions.
1. Optionally presents an introduction screen giving a short description of Tap to Pay on iPhone capabilities.
1. Gives the merchant an opportunity to run a test payment. The test payment behaves exactly like `performPayment`, with a predefined amount of 1 currency unit (e.g., £0.01).

:::note
Invoking this method is **not required** - `performPayment` and `performPayments` automatically handle any necessary setup on first use. 

However, running it provides a smoother first-time experience for the merchant.
:::

```swift
func performFirstTimeSetup(
    shouldShowIntro: Bool,
    currency: String,
    merchantName: String?,
    completion: @escaping (RevolutTapToPayKit.Receipt?, Result<Void, RevolutTapToPayKit.Error>) -> Void
)
```

| Parameter | Description | Format | Required |
|-----------|-------------|--------|----------|
| `shouldShowIntro` | A flag indicating whether the introduction screen should be shown. The introduction screen is shown only once - subsequent calls with `true` will not show it again. | `Bool` | Yes |
| `currency` | The currency for the test payment, as a 3-letter [ISO 4217](https://en.wikipedia.org/wiki/ISO_4217) code. | `String` | Yes |
| `merchantName` | Optional merchant name. This is added to the receipt. | `String` | No |
| `completion` | A closure called on the completion of the flow. Receives the test payment [`Receipt`](#revoluttaptopaykitreceipt-struct) (if one was made) and the result of the setup or test payment. When this closure is invoked, nothing is presented on screen. <br/><br/> The `Result` is `Result<Void, RevolutTapToPayKit.Error>` - `.success` indicates the setup completed, `.failure(RevolutTapToPayKit.Error)` indicates the setup or test payment failed. See [Errors](#revoluttaptopaykiterror-enumeration). | `Closure` | Yes |

## Helper objects and types

### `TokenProviderProtocol` protocol

The SDK should not receive a static, long-lived credential. Instead, implement a `TokenProviderProtocol` that requests fresh short-lived device tokens from your backend. The SDK calls `fetchAccessToken()` when it needs a token - either on the initial API call or when the current token has expired (received an unauthorised error).

```swift
public protocol TokenProviderProtocol: Sendable {
    func fetchAccessToken() async throws -> SdkTokenApiDto
}
```

| Method | Description |
|--------|-------------|
| `fetchAccessToken()` | Called by the SDK to request a fresh short-lived device token. Your implementation should call your backend endpoint that returns a device token (see [Get started: 3. Get a device token](/docs/guides/merchant/accept-payments/in-person-payments/tap-to-pay/get-started#3-get-a-device-token)). Returns an `SdkTokenApiDto` containing the access token. Throws on error. |

:::info
When the SDK receives two unauthorised errors in a row from `fetchAccessToken`, it calls the `onLogout` handler provided during initialisation. This means the merchant is no longer authorised — consent was revoked, not granted, or the app permission was removed in the Developer Portal. The SDK cannot continue operating with that merchant account.
:::

### `SdkTokenApiDto` struct

This struct wraps the short-lived device token returned by your token provider.

```swift
public struct SdkTokenApiDto: Decodable {
    public let accessToken: String

    public init(accessToken: String) {
        self.accessToken = accessToken
    }
}
```

| Field | Description | Format |
|-------|-------------|--------|
| `accessToken` | The short-lived access token obtained from your backend via the token exchange flow. The SDK uses this as the `Bearer` token for pairing and payment API calls. | `String` |

### `RevolutTapToPayKit.Environment` enumeration

This enum specifies the environment in which the SDK operates. Use the client ID corresponding to the selected environment.

```swift
public enum Environment {
    case production
}
```

| Case | Description |
|------|-------------|
| `.production` | The production environment. Use with the production client ID obtained from the Developer Portal after production approval. |

:::info
Only `.production` is currently available for Tap to Pay. Sandbox is not currently supported.
:::

### `RevolutTapToPayKit.Receipt` struct

This struct represents a payment receipt, returned in the `onDidCharge` closure (for `performPayment` and `performPayments`) and in the `completion` closure (for `performFirstTimeSetup`). The receipt contains a URL that can be shared with the merchant or customer.

```swift
public struct Receipt {
    public let url: URL
}
```

| Field | Description | Format |
|-------|-------------|--------|
| `url` | The URL of the receipt for the completed payment. Use this to present receipt sharing options to the merchant (e.g., via `UIActivityViewController`). | `URL` |

## Errors

### `RevolutTapToPayKit.Error` enumeration

Error types returned by the Revolut Tap to Pay SDK. The `Error` enumeration defines error cases that can occur during the payment or setup process, returned by the `.failure` case of the `onDidCharge` and `completion` closures.

```swift
public enum Error: Swift.Error {
    /// Returned when an internal error occurs.
    case internalError
}
```

| Case | Description |
|------|-------------|
| `.internalError` | An unspecified internal error occurred within the SDK. |

:::info
The SDK currently exposes a single error case. Additional cases may be added in future versions to provide more granular error handling.
:::