---
title: Transactions
slug: transactions
docTags: 
createdAt: 2025-05-12T11:33:15.288Z
---

## States

These are the possible states when processing a [purchase](docId\:Mkssy1oNFV6v3FUYRRT3m) or [refund](docId\:gtBWF4C5P-1EYUv-2BusW) :

```swift
public enum TransactionState {
    /// Transaction is idle and ready to start
    case ready
    
    /// Attempting connection to the ToroClient.selectedDevice
    case connectingToDevice
    
    /// Awaiting confirmation of gratuity amount from the customer.
    /// Only applicable if ToroConfig.gratuityEnabled is true
    case awaitingGratuity
    
    /// Awaiting customer to present card on any interface (contact, contactless, magswipe)
    case awaitingCard
    
    /// Awaiting customer signature (in app or on device).
    /// - SeeAlso: ToroConfig.signatureMode
    case awaitingSignature
    
    /// Awaiting cardholder to enter PIN on the PED.
    case awaitingPinEntry
    
    /// Awaiting cardholder to confirm application to use for transaction.
    case awaitingApplicationSelection
    
    /// Contacting the gateway to authorise the transaction
    case authorising
    
    /// Transaction was completed successfully and an outcome was received (approved/declined)
    case completed
    
    /// Transaction was cancelled by the user or operator
    case cancelled
    
    /// Transaction failed due to an error
    case failed
}
```

### Transaction State Listener

To receive transaction state updates, you can implement the `TransactionStateListener` and register it with the `ToroClient` instance:

```swift
class MyTransactionStateListener: TransactionStateListener {
    var currentTransactionState: TransactionState = .ready
    
    func onTransactionStateChanged(_ state: ToroSDK.TransactionState) {
        currentTransactionState = state
    }
}
```

Alternatively, you can use the `transactionState` property on the `ToroClient` instance to check the current state of the transaction:

```swift
let transactionState = toro.transactionState
```

## Metadata

The `TransactionMetadata` class allows you to include additional information with [purchases](docId\:Mkssy1oNFV6v3FUYRRT3m) or [refunds](docId\:gtBWF4C5P-1EYUv-2BusW).

```swift
public struct TransactionMetadata {
    /**
     * Custom ID for the transaction. This id will be returned in the `TransactionReceipt`.
     * Max length is 35 characters.
     */
    let saleReferenceId: String?
    
    /**
     * The gratuity amount for the transaction.
     * The gratuity amount is added to the transaction amount specified in startTransaction().
     * This is useful if you are wanting to use a custom gratuity flow outside of the SDK.
     * Setting this will result in an error if gratuity is enabled in ToroConfig.
     */
    let gratuityAmount: Int?
    
    /**
     * Any other additional data you want returned in the `TransactionReceipt`
     * This data will be sent in the `AcceptorAuthorisationRequest` - AccptrAuthstnReq/AuthstnReq/Tx/TxDtls/AddtlInf
     */
    let additionalInformation: [String: Any?]?
    
    /**
    * Details of the original transaction that is being refunded.
    * Not applicable for purchases.
    */
    let originalTransactionDetails: OriginalTransactionDetails?
  }
```

## Cancelling an in-progress transaction

To cancel an in-progress [purchase](docId\:xfTYvCsCNePqsmJfZ6o4a) or [refund](docId\:ezdh0uhDPD1bvbGCddqiO), you can call the `cancelTransaction` method on the `ToroClient` instance:

```swift
toro.cancelTransaction()
```

This will also close the Bluetooth session with the Miura device if it is open.

## Signatures

The SDK provides two different methods for collecting cardholder signatures. The method used depends on the `signatureMode` set in the `ToroConfig`. See [configuration](docId\:H18_V1clRy140IMRfldm-) for more information.

**`SignatureMode.DEVICE`**

The signature will be captured on the Miura device. This is only applicable to devices which have a touch screen (e.g., M021).

**`SignatureMode.APP`**

The signature will be captured in the app through the SDKs built-in `SignatureView`.

In both cases, signatures are requesed automatically by the SDK when the `TransactionState` is `.awaitingSignature`. No additional configuration is required in your app for it to work.

## Receipt

```swift
public struct TransactionReceipt {

    /**
     *  Unique reference number to identify the transaction.
     *  Can be set in TransactionMetadata.
     */
    public let saleReferenceId: String?

    /**
     * The total amount of the transaction represented in the smallest
     * unit of the currency, e.g. cents for USD, pence for GBP.
     */
    public let amount: Int

    /**
     * The amount of the transaction that was authorised by the acquirer.
     * In most cases the same as amount, but can differ e.g. partial approvals.
     */
    public let authorisedAmount: Int?

    /**
     * The type of transaction. Purchase, refund.
     */
    public let type: TransactionType
    /**
     * Gratuity amount confirmed by the customer.
     * This can be set either through TransactionMetadata or
     * when ToroConfig.gratuityEnabled is set to true and the built in
     * gratuity flow is used.
     */
    public let gratuityAmount: Int

    /**
     * The currency of the transaction.
     */
    public let currency: CurrencyCode

    /**
     * The authorisation code set by the acquirer.
     */
    public let authCode: String?

    /**
     * The result of the authorisation (acquirer decision).
     * Typically APPROVED or DECLINED.
     */
    public let responseCode: ResponseCode

    /**
     * The reason for the responseCode.
     */
    public let responseReason: String?

    /**
     * Cardholder Verification Method
     */
    public let authenticationMethod: AuthenticationMethod8?

    /**
     * Additional response information (from gateway or acquirer).
     */
    public let additionalResponseInformation: String?

    /**
     * Also known as the authorisation response code.
     * EMV tag 8A set by the acquirer.
     */
    public let actionCode: String?

    /**
     * Application identifier of the card that was presented
     */
    public let aid: String?

    /**
     * Application label of the card that was presented
     */
    public let applicationLabel: String?

    /**
     * The payment interface used to process the transaction.
     * E.g. Contactless.
     */
    public let paymentInterface: PaymentInterface

    /**
     * The first 6 or 8 digits of the Primary Account Number (PAN).
     * AKA Bank Identification Number (BIN).
     */
    public let panStart: String?

    /**
     * The last 4 digits of the Primary Account Number (PAN).
     */
    public let panLastFour: String?

    /**
     * Identifier set by the recipient (acquirer) to reference the transaction.
     * This can be the same as the initiatorTransactionId depending on the acquirer.
     */
    public let recipientTransactionId: String?

    /**
     * Identifier set by the initiator (merchant) to reference the transaction.
     * The Toro SDK handles this internally and cannot be overridden by the host application.
     */
    public let initiatorTransactionId: String?

    /**
     * Unique identification of the transaction assigned by the POI (Point Of Interaction)
     */
    public let transactionReference: String?

    /**
     * The date and time the transaction occurred in ISO 8601 format.
     */
    public let dateTime: String?

    /**
     * The serial number of the terminal the transaction was processed on.
     */
    public let terminalSerialNumber: String

    /**
     * Cardholder signature base64 encoded if applicable.
     */
    public let signatureBase64: String?

    /**
     * Indicates whether the signature verification failed, either due to
     * merchant rejection or customer cancellation during signature entry.
     */
    public let signatureVerificationFailed: Bool

    /**
     * Whether the transaction was captured by the acquirer.
     */
    public let captured: Bool

    /**
     * The latitude of the device at the point of transaction.
     */
    public let longitude: String?

    /**
     * The longitude of the device at the point of transaction.
     */
    public let latitude: String?

    /**
     * The custom data set in TransactionMetadata
     */
    public let additionalInformation: [String: Any?]?
  }
```

