Starting a Tap to Pay Transaction
Currently Tap to Pay is in Beta Release. If you would like to participate, please reach out to your Account Manager.
Call the startTransaction() to initiate a transaction. This can be used to start a Sale, Refund or Account Verification transaction. The request accepts various parameters, including amount, transaction type, unique reference, whether to enable/disable gratuity and currency.
When the startTransaction() method is successful, asynchronous updates are provided in the following callbacks; transactionUpdate, userNotification, applicationSelection, signatureVerification, and transactionFinished.
For additional information, you can refer to the SDK README.
Using Tap To Pay on iPhone
Use Tap to Pay on iPhone to accept contactless payments directly on supported iPhone devices without any additional hardware.
Requirements
- iPhone XS or later
- iOS 17.4+
- Stax account with Tap to Pay enabled
- CloudCommerce.xcframework
Passcode requiredYour iPhone must use a passcode. This is a security requirement for Tap to Pay to work. An error message will appear similar to a connection error if no passcode is active.
How it works
Tap to Pay uses the same TransactionRequest model as a mobile reader for payments, but uses the iPhone's built-in NFC reader to accept contactless cards and digital wallets.
Connect to Tap to Pay
Before taking a Tap to Pay transaction, you must first connect to the Tap to Pay reader on the iPhone using connectToTap. Once the connection is successful, you can proceed to take a payment.
if #available(iOS 17.4, *) {
omni.connectToTap(completion: {
print("Connected to Tap to Pay!")
// Now take a payment
let amount = Amount(cents: 1050) // $10.50
let request = TransactionRequest(amount: amount)
omni.takeTapTransaction(with: request) { transaction in
print("Tap payment successful!")
print("Transaction ID: \(transaction.id)")
print("Amount: \(transaction.total)")
} error: { error in
print("Tap payment failed: \(error)")
}
}, error: { error in
print("Failed to connect to Tap to Pay: \(String(describing: error))")
})
} else {
print("Tap to Pay requires iOS 17.4 or later")
}Taking a Tap to Pay Transaction
// Create an Amount
let amount = Amount(cents: 1050) // $10.50
// Create the TransactionRequest
let request = TransactionRequest(amount: amount)
// Take a Tap to Pay transaction
if #available(iOS 17.4, *) {
omni.takeTapTransaction(with: request) { transaction in
print("Tap payment successful!")
print("Transaction ID: \(transaction.id)")
print("Amount: \(transaction.total)")
// Handle successful payment
// Update your UI, print receipt, etc.
} error: { error in
print("Tap payment failed: \(error)")
// Handle error
// Show error message to user
}
} else {
print("Tap to Pay requires iOS 17.4 or later")
}Complete Example
import Fattmerchant
class PaymentViewController: UIViewController {
var omni: Omni?
@IBAction func processTapPayment(_ sender: UIButton) {
guard #available(iOS 17.4, *) else {
showAlert(title: "Not Supported", message: "Tap to Pay requires iOS 17.4 or later")
return
}
// Create amount for $25.00
let amount = Amount(cents: 2500)
// Create transaction request
let request = TransactionRequest(amount: amount)
// Optional: Add metadata
request.meta = ["order_id": "12345", "customer_name": "John Doe"]
// Show processing UI
showProcessingUI()
// Process the payment
omni?.takeTapTransaction(with: request, completion: { [weak self] transaction in
guard let self = self else { return }
self.hideProcessingUI()
// Payment succeeded
self.showSuccessUI(transaction: transaction)
print("✅ Payment successful!")
print("Transaction ID: \(transaction.id)")
print("Amount: \(transaction.total)")
print("Last 4: \(transaction.lastFour ?? "N/A")")
}, error: { [weak self] error in
guard let self = self else { return }
self.hideProcessingUI()
// Payment failed
self.showErrorUI(error: error)
print("❌ Payment failed: \(error.localizedDescription)")
})
}
private func showProcessingUI() {
// Show loading indicator and "Hold card near iPhone" message
}
private func hideProcessingUI() {
// Hide loading indicator
}
private func showSuccessUI(transaction: StaxTransaction) {
// Show success checkmark, amount, etc.
}
private func showErrorUI(error: OmniException) {
// Show error message
}
private func showAlert(title: String, message: String) {
let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .default))
present(alert, animated: true)
}
}Refund a Payment
You can use the [Stax API]({{ site.api_ref_url }}#reference/0/transactions){:target="_blank" rel="noreferrer"} to refund a payment. Once you receive the transaction, call the refundMobileReaderTransaction method to attempt the refund.
// Attain a transaction
var transaction = Transaction()
// Perform refund
omni.refundMobileReaderTransaction(transaction: transaction, completion: { (refundedTransaction) in
// Refund successful!
}, error: { error in
// Error
})Updated about 2 months ago
