Acceptance Devices | Tap to Pay on iPhone Solution Integration Guide

This section describes how to use this guide and where to find further information.
Audience and Purpose
This guide is written for application developers who want to integrate the Acceptance Devices | Tap to Pay on iPhone software development kit (SDK) into their apps and to process contactless transactions on mobile devices.
Integrating this SDK requires software development skills and the understanding of contactless payments on near-field communication (NFC)-enabled, commercial, off-the-shelf (COTS) mobile devices. You must write code that uses the SDK to integrate the Acceptance Devices | Tap to Pay on iPhone Solution into your existing payment system.
Conventions
These statements appear in this document:
IMPORTANT
An
Important
statement contains information essential to successfully completing a task or learning a concept.
WARNING
A
Warning
contains information or instructions, which, if not heeded, can result in a security risk, irreversible loss of data, or significant cost in time or revenue or both.
Related Documentation
Visit the
Cybersource
documentation hub
to find additional technical documentation.
Customer Support
For support information about any service, visit the Support Center:

Recent Revisions to This Document

26.02.01

This revision contains only editorial changes and no technical updates.

26.01.01

Added new Device Enrollment section: Show Merchant Education Screens.

25.10.02

Added new SDK release. See SDK Version 3.3.0 Release Notes.

25.10.01

Replaced code example in step 2 of Sale with On-Reader Tipping.
Added new SDK release. See SDK Version 3.2.0 Release Notes.

25.08.01

Added a new method for checking the status of a transaction in Check Transaction Status.
Added new SDK release. See SDK Version 3.1.0 Release Notes.

25.07.02

Updated the code example in step 1 of Sale with On-Reader Tipping.

25.07.01

Initial release
Includes Tap to Phone on iPhone SDK, version 3.0.0.

VISA Platform Connect: Specifications and Conditions for Resellers/Partners

The following are specifications and conditions that apply to a Reseller/Partner enabling its merchants through
Cybersource for
Visa Platform Connect
(“VPC”) processing
. Failure to meet any of the specifications and conditions below is subject to the liability provisions and indemnification obligations under Reseller/Partner’s contract with Visa/Cybersource.
  1. Before boarding merchants for payment processing on a VPC acquirer’s connection, Reseller/Partner and the VPC acquirer must have a contract or other legal agreement that permits Reseller/Partner to enable its merchants to process payments with the acquirer through the dedicated VPC connection and/or traditional connection with such VPC acquirer.
  2. Reseller/Partner is responsible for boarding and enabling its merchants in accordance with the terms of the contract or other legal agreement with the relevant VPC acquirer.
  3. Reseller/Partner acknowledges and agrees that all considerations and fees associated with chargebacks, interchange downgrades, settlement issues, funding delays, and other processing related activities are strictly between Reseller and the relevant VPC acquirer.
  4. Reseller/Partner acknowledges and agrees that the relevant VPC acquirer is responsible for payment processing issues, including but not limited to, transaction declines by network/issuer, decline rates, and interchange qualification, as may be agreed to or outlined in the contract or other legal agreement between Reseller/Partner and such VPC acquirer.
DISCLAIMER: NEITHER VISA NOR CYBERSOURCE WILL BE RESPONSIBLE OR LIABLE FOR ANY ERRORS OR OMISSIONS BY THE
Visa Platform Connect
ACQUIRER IN PROCESSING TRANSACTIONS. NEITHER VISA NOR CYBERSOURCE WILL BE RESPONSIBLE OR LIABLE FOR RESELLER/PARTNER BOARDING MERCHANTS OR ENABLING MERCHANT PROCESSING IN VIOLATION OF THE TERMS AND CONDITIONS IMPOSED BY THE RELEVANT
Visa Platform Connect
ACQUIRER.

Introduction to Acceptance Devices | Tap to Pay on iPhone Solution

The Acceptance Devices | Tap to Pay on iPhone Solution enables you to use any compatible iPhone as a payment acceptance device. You can integrate the Tap to Pay on iPhone software development kit (SDK) into your iOS POS app to easily manage the payment flow.

Compatibility Requirements for iPhones

To accept contactless payments, your iPhone must be compatible with the Tap to Pay on iPhone Solution. These are the requirements for a compatible iPhone:
  • iPhone model XS or later
  • iOS version that is less than 1 year old (recommendation is to use the latest iOS version available)
  • Debugger is not connected

Transaction Workflow for the Tap to Pay on iPhone Solution

This diagram shows the transaction workflow for the Tap to Pay on iPhone Solution.

Figure:

Tap to Pay on iPhone Solution Transaction Workflow
Tap to Pay on iPhone Solution transaction workflow diagram showing the sequence
                    of events used to process a transaction
  1. The iOS point-of-sale (POS) app integrates to the Tap to Pay on iPhone SDK.
  2. The merchant's iOS POS app sends a request to the Tap to Pay on iPhone SDK to process a payment.
  3. The Tap to Pay on iPhone SDK user interface (UI) opens on the iPhone screen and guides the customer through the payment flow.
  4. The Tap to Pay on iPhone SDK sends a response with the transaction result and details to the iOS POS app.

Getting Started with the Tap to Pay on iPhone Solution

Use this information to get started with integrating the Tap to Pay on iPhone Solution. After completing the integration, you can start accepting payments. For more information, see Tap to Pay on iPhone Payment Services.

Configuring the Tap to Pay on iPhone SDK

Use this information to configure the Tap to Pay on iPhone SDK.

Add the Tap to Pay on iPhone SDK to Your Xcode Project

To complete this task, the ThinClient framework must be available to be copied. To obtain the framework, contact your implementation manager.
Follow these steps to add the Tap to Pay on iPhone SDK to your Xcode project.
IMPORTANT
Stay current with the latest SDK. The SDK repository is continuously updated to make available the six latest versions. When a new version is released, the oldest is removed and can no longer be used for new application builds. Establish a regular process for updating to the newest available SDK version to avoid potential build failures and to ensure that your application runs with the latest features, performance enhancements, and security updates.
  1. In the Xcode app, click
    File
    .
  2. Click
    Add Package Dependencies
    .
  3. In the search bar, enter this GitHub link: acceptance-devices-ios-sdk.
  4. Set the Dependency Rule to
    Up to Next Major Version
    .
  5. Open the
    Add to Target
    drop-down menu, then choose your app.
  6. Click
    Add Package
    .

Request the Tap to Pay on iPhone Entitlement

You must have an Apple Developer account to complete this task. Use this link to create an account or to sign in to your existing account.
To use the Tap to Pay on iPhone solution, you must request the Tap to Pay on iPhone entitlement from Apple and configure your application to use it.
  1. Configure your application to use the Tap to Pay on iPhone entitlement. For more information, see Setting up Tap to Pay on iPhone in the Apple Developer documentation.

Create a Sandbox Apple Account to Test Your Integration

Before you can test your Tap to Pay on iPhone integration in a sandbox environment, you must create a Sandbox Apple account.
Follow these steps to create a Sandbox Apple Account.
  1. See the Apple Developer documentation: Create a Sandbox Apple Account.
  2. Sign in to your Sandbox Apple account from the device on which you will test transactions.

Generating a Secret Key for an Existing Merchant ID

Use this information to generate a secret key for an existing merchant ID (MID) in the
Business Center
or by using a REST API request. The secret key and MID are required values that you must enter in the
mposUi
 instance that you create. For more information, see Creating an mposUI Instance.

Generate a Secret Key for an Existing Merchant ID in the Business Center

You can generate a secret key for an existing merchant ID (MID) in the
Business Center
. You must enter this value in the
mposUi
 instance that you create. For more information, see Creating an mposUI Instance.
Follow these steps to generate a secret key for an existing MID in the
Business Center
.
  1. In the
    Business Center
    , go to the left navigation panel and choose
    Payment Configuration > Key Management
    . The Key Management page appears.
  2. From the Merchant drop-down list, choose a merchant ID.
  3. Click
    Generate Key
    .
  4. In the Recommended Key Types list, scroll down and choose
    Acceptance Devices Secret Key
    .
  5. Click
    Generate Key
    . The Key Generation page appears.
  6. Click
    Generate Key
    . Your MID and secret key appear on the page.
  7. Click the
    Copy
    or
    Download
    icon to obtain the MID and secret key.

    ADDITIONAL INFORMATION

    IMPORTANT
    If you choose to copy the secret key instead of downloading it, save the information locally because you cannot return to the
    Business Center
    Key Generation page to obtain the same secret key. You must restart the process to obtain a new secret key.

Generate a Secret Key for an Existing Merchant ID Using a REST API Request

You can use a REST API request to generate a secret key for an existing merchant ID (MID). You must enter this value in the
mposUi
 instance you create. For more information, see Creating an mposUI Instance.
You must authenticate each request that you send to a
Cybersource
API. To authenticate an API request, you can use a REST shared secret key or a REST certificate. For more information about authentication requirements, see the .

Endpoints:

Test:
POST
https://apitest.cybersource.com
/kms/v2/keys-sym-pos
Production:
POST
https://api.cybersource.com
/kms/v2/keys-sym-pos

Required Fields to Generate a Secret Key for an Existing Merchant ID Using a REST API Request

This field is required to generate a secret key for an existing merchant ID when using a REST API request:
keyInformation.organizationId

REST Example: Generate a Secret Key for an Existing Merchant ID Using a REST API Request

Request
{ "keyInformation": [ { "organizationId": "transacting_MID" } ] }
Response to a Successful Request
{ "submitTimeUtc": "2023-08-07T13:07:17Z", "status": "ACCEPTED", "keyInformation": [ { "organizationId": "transacting_MID", "externalOrganizationId": "MerchantId", "key": "SecretKey", "keyId": "af922a42-6d2c-41fd-92f7-09d908647de4", "status": "ACTIVE", "expirationDate": "2033-08-07T13:07:17Z" } ] }

Creating an mposUI Instance

Use this information to create and configure an
mposUI
 instance. Before creating an
mposUI
instance, you must create the
Credentials
and
Configuration
objects.

Create an
mposUI
Credentials Object

Before starting this task, obtain a merchant ID and secret key. For more information, see Generating a Secret Key for an Existing Merchant ID.
The
mposUI Credentials
 object is required in order to access the functionality of the Tap to Pay on iPhone SDK. You must create this object before you can create an
mposUI
instance.
Follow these steps to create the
mposUI Credentials
object.
  1. Import
    MposUI
    .
  2. Create a
    Credentials
    object.
  3. Set the
    merchant
    field value to the merchant ID that you obtained.
  4. Set the
    secret
    field value to the secret key that you obtained.
  5. Set the
    environment
    field value to
    test
    or to
    live
    .
    • Use the
      test
      setting to test your integration without charging a real payment card. Use the merchant ID and secret key that you obtained from the test environment.
    • Use the
      live
      setting to process live transactions. Use the merchant ID and secret key that you obtained from the production environment.
    import MposUI let credentials = Credentials(merchant: "MerchantId", secret: "SecretKey", environment: .live)

Create an
mposUI
Configuration Object

To create and use the
mposUI
instance with the Tap to Pay on iPhone SDK, you must create the
mposUI Configuration
 object.
Use the
Configuration
 object to configure these parameters for the
mposUI
 instance:
  • Configure these Summary screen features:
    • Refund a transaction (
      .refundTransaction
      ).
    • Send a receipt by email (
      .sendReceiptViaEmail
      ).
    • Capture a transaction (
      .captureTransaction
      ).
    • Increment a transaction (
      .incrementTransaction
      ).
    • Re-try a failed transaction (
      .retryTransaction
      ).
  • Configure the Summary screen so that it can be skipped (
    .skipSummaryScreen
    ). The default setting is to show the Summary screen (
    .displayIndefinitely
    ).
  • Configure the signature capture so that it prints on the paper receipt (
    .onReceipt
    ) or is skipped (
    .none
    ). The default setting is on-screen signature capture.
Follow this step to create the
mposUI Configuration
object.
  1. Create the
    Configuration
    object.
    let configuration = Configuration(summaryFeatures: [.sendReceiptViaEmail, .refundTransaction, .captureTransaction, .incrementTransaction, .retryTransaction], resultConfiguration: .displayIndefinitely, signatureCapture: .onScreen)

Create an
mposUI
Instance

Before you can create the
mposUI
instance, create and configure the
Credentials
and
Configuration
 objects.
Follow this step to create the
mposUI
instance.
  1. Create the
    mposUI
    instance.
    let mposUi = await mposUiBuilder(credentials: credentials, configuration: configuration)

Enabling Device Enrollment

Use this information to enable device enrollment and view the device enrollment result in the Tap to Pay on iPhone SDK. The enrollment workflow guides you through the device enrollment activity.

Enroll a Device

Use the
enroll
function to enroll a device. This function shows options in a merchant-facing UI for enrolling a new device or enrolling a previously enrolled device by entering the serial number.
switch await mposUi.enroll() { case .success(let deviceId): print("Enrollment successful with device id: %@", deviceId) case .cancelledByUser: print("Enrollment cancelled.") case .error(let developerInfo): print("Enrollment failed. Info: %@", developerInfo) }

View the Device Enrollment Result

Before you can view the device enrollment result, you must enroll a device.
Use the
enrollmentStatus
function to view the device enrollment result.
switch await mposUi.enrollmentStatus() { case .enrolled: print("Device enrolled.") case .enrolling: print("Enrollment in progress. Please do not start a new one.") case .notEnrolled: print("Device not enrolled. Please enroll device.") }

Show Merchant Education Screens

When a device enrollment is completed successfully, the Merchant Education screens must show on the device. The Merchant Education screens also must be accessible in your app's Settings or Help section.
Use Apple's
ProximityReaderDiscovery
object to show the Merchant Education screens. This object provides the UI with information about how to use Tap to Pay on iPhone. For more information about the object, see the Apple Developer documentation: ProximityReaderDiscovery.

Tap to Pay on iPhone Payment Services

Use this information to process the payment services featured in the Tap to Pay on iPhone Solution.

Sale

Use this information to process a sale transaction. This type of transaction combines an authorization and a capture into a single transaction.
Follow these steps to process a sale.
  1. Create a
    ChargeParameters
    object and provide the required information for the payment.
  2. Use the
    startChargeTransaction
    method to initiate the transaction flow.
    let chargeParameters = ChargeParameters(amount: Decimal(1.00), currency: .USD, customIdentifier: "yourReferenceForTheTransaction") let charge = await mposUi.startChargeTransaction(with: chargeParameters)
  3. When the transaction is complete, you can view the result of the transaction.
    switch charge { case .success(let transaction): print("Transaction with id: %@ completed with state: %@", transaction.identifier, transaction.status) case .failure(let error): print("Transaction failed with error: %@", error.localizedDescription) }
  4. To get complete transaction details, access the
    transaction
    object.

Refund

Use this information to process a refund using a reference to the original transaction for a full or partial transaction amount. Stand-alone credits are also supported in this Acceptance Devices solution. For more information, see Stand-Alone Credit.
Follow these steps to process a refund.
  1. Use the
    refundTransaction
    method to start the transaction flow.
    let linkedRefund = await mposUi.refundTransaction(withID: "transactionIdentifier", //Specify amount and currency for partial refunds partiallyWithAmount: (Decimal(1.00), .USD))
  2. When the transaction is complete, you can view the result of the transaction.
    switch linkedRefund { case .success(let transaction): print("Transaction with id: %@ completed with state: %@", transaction.identifier, transaction.status) case .cancelledByUser: print("Transaction canceled.") case .error(let developerInfo): print("Transaction failed. Info: %@", developerInfo) }
  3. To get complete transaction details, access the
    transaction
    object.

Stand-Alone Credit

Use this information to process a stand-alone credit. This transaction is used to process a credit without reference to the original transaction. The customer is required to present their payment card for this type of transaction.
WARNING
When processing a stand-alone credit, there is no limit on the credit amount because there is no reference to the original transaction amount. The recommendation is to use a refund transaction whenever possible. For more information, see Refund.
Follow these steps to process a stand-alone credit.
  1. Create a
    RefundParameters
    object and provide the required information for the payment.
  2. Use the
    startStandaloneRefundTransaction
    method to initiate the transaction flow.
    let refundParameters = RefundParameters(amount: Decimal(1.00), currency: .USD, customIdentifier: "yourReferenceForTheTransaction") let refund = await mposUi.startStandaloneRefundTransaction(with: refundParameters)
  3. After the transaction is completed, get the results of the transaction.
    switch refund { case .success(let transaction): print("Transaction with id: %@ completed with state: %@", transaction.identifier, transaction.status) case .failure(let error): print("Transaction failed with error: %@", error.localizedDescription) }
  4. To get complete transaction details, access the
    transaction
    object.

Check Transaction Status

Use this information to check the status of a transaction.

Check Transaction Status Using the
showSummary
Method

To submit a check transaction status request, you must have the
transactionIdentifier
value for the transaction that you want to check.
Use the check transaction status request to obtain response data for a transaction that was lost or timed out. When you send the request using the
showSummary
method, the transaction details are shown on the Summary screen.
Follow these steps to request a check transaction status.
  1. Use the
    showSummary
    method to open the Summary screen.
    let summary = await mposUi.showSummary(forID: "transactionIdentifier")
  2. After the activity is complete, you can view the results of the activity.
    switch summary { case .success(let transaction): print("Summary screen was shown for transaction with id %@", transaction.identifier) case .failure(let error): print("Error checking transaction status or displaying summary screen: %@", error.localizedDescription) }
  3. To view the full transaction details, access the
    transaction
    object.

Check Transaction Status Using the
lookupTransaction
Method

To submit a check transaction status request, you must have the
transactionIdentifier
value for the transaction that you want to check.
Use the check transaction status request to obtain response data for a transaction that was lost or timed out. When you send the request using the
lookupTransaction
method, the transaction details are shown in the
transaction
object.
Follow these steps to request a check transaction status.
  1. Use the
    lookupTransaction
    method to find the transaction details.
    let result = await mposUI.lookupTransaction(forID: "transactionIdentifier")
  2. After the activity is complete, you can view the results of the activity.
    switch result { case .success(let transaction): print("Lookup successful for id %@", transaction.identifier) case .notFound: print("Transaction not found.") case .networkError(let developerInfo): print("Lookup failed. Info: %@", developerInfo) case .unexepcted(let developerInfo): print("Lookup failed. Info: %@", developerInfo) }
  3. To view the full transaction details, access the
    transaction
    object.

Sale with On-Reader Tipping

Use this information to process a sale with on-reader tipping. At the start of each transaction, the device prompts the customer to add a tip by showing suggested tip amounts and a no-tip option. The customer chooses or enters an amount before presenting their payment card.
Follow these steps to process a sale with on-reader tipping.
  1. Create a
    ChargeParameters
    object and provide the required information for the payment.
  2. Use the
    startChargeTransaction
    method to initiate the transaction flow.
    // Use to display three tipping percentage choices let tipConfig = Tipping.percentageChoice([5, 10, 15]) // Use to ask for tip amount // let tipConfig = Tipping.input(.tipAmount()) // Use to ask for total transaction amount including tip // let tipConfig = Tipping.input(.totalAmount()) let chargeParameters = ChargeParameters(amount: Decimal(1.00), currency: .USD, customIdentifier: "yourReferenceForTheTransaction", tip: tipConfig) let charge = await mposUi.startChargeTransaction(with: chargeParameters)
  3. After the transaction is completed, get the results of the transaction.
    switch charge { case .success(let transaction): print("Transaction with id: %@ completed with state: %@", transaction.identifier, transaction.status) case .failure(let error): print("Transaction failed with error: %@", error.localizedDescription) }
  4. To get complete transaction details, access the
    transaction
    object.

Pre-Authorization

Use this information to process a pre-authorization for an initial amount. This transaction places a temporary hold on the customer's payment card. The transaction amount can be captured at a later time.
Most authorizations expire in 5 to 7 days. The issuing bank sets this period of time. When an authorization expires with the issuing bank, your bank or processor might require you to re-submit an authorization request and include a request for capture in the same message. For more information, see Capture.
Follow these steps to process a pre-authorization.
  1. Create a
    ChargeParameters
    object and provide the required information for the payment.
  2. Use the
    startChargeTransaction
    method to initiate the transaction flow.
    let chargeParameters = ChargeParameters(amount: Decimal(1.00), currency: .USD, customIdentifier: "yourReferenceForTheTransaction", autocapture: false) let charge = await mposUi.startChargeTransaction(with: chargeParameters)
  3. After the transaction is completed, get the results of the transaction.
    switch charge { case .success(let transaction): print("Transaction with id: %@ completed with state: %@", transaction.identifier, transaction.status) case .failure(let error): print("Transaction failed with error: %@", error.localizedDescription) }
  4. To get complete transaction details, access the
    transaction
    object.

Incremental Authorization

Use this information to process an incremental authorization. This transaction can be applied to a pre-authorization request to increase the authorized amount before it is captured.
Follow these steps to process an incremental authorization.
  1. Use the
    incrementTransaction
    method to initiate the transaction flow.
    let increment = await mposUi.incrementTransaction(withID: "transactionIdentifier", withAmount: (Decimal(1.00), .USD))
  2. After the transaction is completed, get the results of the transaction.
    switch increment { case .success(let transaction): print("Transaction with id: %@ completed with state: %@", transaction.identifier, transaction.status) case .cancelledByUser: print("Transaction canceled.") case .error(let developerInfo): print("Transaction failed. Info: %@", developerInfo) }
  3. To get complete transaction details, access the
    transaction
    object.

Capture

Use this information to capture a pre-authorized transaction. The capture request references the approved pre-authorization request.
Follow these steps to process a capture.
  1. Use the
    captureTransaction
    method to start the transaction flow.
    let capture = await mposUi.captureTransaction(withID: "transactionIdentifier", //Specify amount and currency for partial captures partiallyWithAmount: (Decimal(1.00), .USD))
  2. After the transaction is completed, get the results of the transaction.
    switch capture { case .success(let transaction): print("Transaction with id: %@ completed with state: %@", transaction.identifier, transaction.status) case .cancelledByUser: print("Transaction canceled.") case .error(let developerInfo): print("Transaction failed. Info: %@", developerInfo)
  3. To get complete transaction details, access the
    transaction
    object.

Email a Customer Receipt

Use this information to email the receipt for a previous transaction to a customer.
Follow these steps to email a customer receipt.
  1. Use the
    sendEmailReceipt
    method to start the flow for emailing a receipt.
    let email = await mposUi.sendEmailReceipt(forID: "transactionIdentifier")
  2. After the emailing activity is completed, get the results of the activity.
    switch email { case .success: print("Operation completed.") case .cancelByUser: print("Operation canceled.") case .error(let developerInfo): print("Operation failed. Info: %@", developerInfo) }

Release Notes for Tap to Pay on iPhone Solution

These release notes are organized by release name and version, from newest to oldest.
Each release note includes these details:
  • Name of release
  • Type of release: app or SDK
  • Version number
  • Operating system: Android or iOS
  • Release date: MM-DD-YYYY format
These are the types of release notes published:
  • General information
  • Improvements
  • New features
  • Fixed issues
  • Updated requirements
  • Security updates
  • Hot fixes

SDK Version 3.3.0 Release Notes

These release notes are for the Tap to Pay on iPhone SDK, version 3.3.0 for iOS. The release date is 10-31-2025.

Improvements

  • Improved the error messages that can appear during transaction processing.
  • Applied general improvements to UI.

Fixed Issues

  • Fixed the issue that occasionally caused the Signature screen to be shown twice.
  • Fixed the issue that caused the Increment button to be shown on the Summary screen after the transaction is fully refunded.

SDK Version 3.2.0 Release Notes

These release notes are for the Tap to Pay on iPhone SDK, version 3.2.0 for iOS. The release date is 10-06-2025.

New Features

Added tip amount and total amount as tipping options.

SDK Version 3.1.0 Release Notes

These release notes are for the Tap to Pay on iPhone SDK, version 3.1.0 for iOS. The release date is 08-18-2025.

New Features

Added the ability to look up transaction details without showing the Summary screen.

Fixed Issues

Applied general fixes to UI.