Introduction

The TIM API is the standard application interface for ECR integration using SIX Payment Services terminals.

TIM API provides a comprehensive feature set to support the requirements of several different markets. This guideline is intended to be used by ECR integrators that need to implement the TIM API functionality in their products.

The following document contains an overview structure, description of the TIM API modes synchronous/asynchronous and describes the corresponding functions, notifiers and data elements that can be used with the TIM API. Furthermore implementation examples are provided. Nevertheless always the corresponding description of a function or data element is authoritative, not the examples.

For further information about the architecture of the TIM API can be found in [B1], this document is meant to cover only implementation purposes.


System Requirements

The TIM API is available for multiple platforms. Due to such diversity the support for the TIM API is limited to certain standards. Those are the minimal system requirements:

  • iOS 10
  • Swift 4.1


Setup Configuration

Once a Terminal-instance has been created with a TerminalSettings-instance, the settings can not be changed anymore. Changes to the TerminalSettings-instance will be ignored.

The network and guides configuration are explained in the following chapters. For further information refer toTerminalSettings.

Network Configuration

The TIM API module can communicate with the Terminal over different communication channels. The default communication is over TCP/IP connection.

For TCP/IP connection there are two possible ways to connect to the terminal:

  • Broadcast-Mode:
    • Terminal ID (TID) is known.
    • The TIM API starts broadcasting on the default interface and connects to the connection information sent by the matching terminal.
  • Direct Connect:
    • IP address of the terminal is known.
    • Connection is established directly via IP.

Guides Configuration

There are various Guides covering different use case scenarios. The guide retail is the basic guide and is activated as default. With .guides the guides can be configured. Important: the configuration needs to include all desired guides (including the retail guide).

Code-example for creating a terminal including settings with activated guides retail and hospitality:

// Create settings with Terminal-ID of terminal to connect to
let terminalSettings = try TerminalSettings()
terminalSettings.terminalId = "12345678"

// add wanted guides (with insert)
terminalSettings.guides.insert(CGuides.retail)
terminalSettings.guides.insert(CGuides.hospitality)

// Create terminal
var terminal = try Terminal(settings: terminalSettings)

//...

// Disconnect from terminal and clean up properly
terminal.dispose()

Operation Overview

Follow these basic steps for using the TIM API:

  1. Create TerminalSettings and initialize connection parameters (see Setup Configuration)
  2. Create Terminal instance using the created TerminalSettings
  3. Set some properties if needed:
  4. Connect and Login. This can be done automatically, when the first terminal operation is called or manually using the login method.
  5. Use terminal operation functions.
Operations overview

Automatisms

The TIM API uses two different types of automatisms:

  • Pre-Automatisms: This means that all actions that need to be done before a function can be called. E.g. a transaction can be called in disconnected state without having called connect, login and activate in advance. These are called automatically by the TIM API before the transaction is performed. The Pre-Automatisms are enabled by default.

  • Post-Automatisms: These automatisms can be enabled or disabled using the members autoCommit and fetchBrands. A Post-Automatism is triggered after an action has been performed. E.g. if a connect has been called and fetchBrands is activated, an applicationInformation request is called automatically after the connect. Or if autoCommit is activated a commit is performed automatically after a transaction has been made. autoCommit and fetchBrands are enabled by default.

The following diagrams show the principle of the Pre-Automatisms and Post-Automatisms. Pre-Automatisms are enabled by default and cannot be disabled. If an error occurs the started request from the ECR is returned with an error.

Synchronous flow

Synchronous flow

Asynchronous flow

Asynchronous flow

Terminal methods overview

The basic operation modes of terminal method calls are:

  1. Synchronous
    Method calls are blocking and return after operation is finished successfully or throw a TimException otherwise. Please not that it is highly discouraged to use synchronous method calls on mobile platforms like iOS because the main thread will be blocked by a synchronous call which may not be tolerated by the platform, as they are quite strict regarding blocking calls. This may result in a crash of the mobile App.

  2. Asynchronous
    Method returns immediately after the operation has started or throws a TimException otherwise. A listener-event-method will be called after operation is finished successfully. All listener-event-methods contain a TimEvent. In case of failure a TimException is included. User-implemented listener-handlers can be added to the Terminal-instance with addListener.

If asynchronous functions are used there are two ways to handle the callbacks:

  • Either the protocol TerminalListener can be used directly. Which means that all defined protocol function must be implemented.
  • Or the prepared default protocol implementation DefaultTerminalListener can be used and only the necessary protocol function must be overwritten.

Code example for adding a terminal listener:

//
// Handle asynchronous terminal events.
//
class TerminalHandler: DefaultTerminalListener {

    //
    // The status of the terminal changed. This includes processing status and display content
    //
    override func terminalStatusChanged(terminal: Terminal) {
        // Events usually originate from a different thread than the main thread.
        // Always use DispatchQueue.main.async to be safe
        DispatchQueue.main.async {
            // handle terminal status change
        }
    }

    //
    // A call to Terminal.transactionAsync finished.
    //
    override func transactionCompleted(event: TimEvent, data: TransactionResponse?) {
        // Events usually originate from a different thread than the main thread.
        // Always use DispatchQueue.main.async to be safe
        DispatchQueue.main.async {
            // handle transaction finished using data
        }
    }
}

Main / guide retail terminal functions

Sync method
Async method
Completed event
Description
activate
activateAsync
activateCompleted
Open a user shift.
applicationInformation
applicationInformationAsync
applicationInformationCompleted
Request the list of brands available on the terminal.
balance
balanceAsync
balanceCompleted
Force the EFT Terminal to transmit all transactions to the
host system as well to do the daily closing.
changeSettings
changeSettingsAsync
changeSettingsCompleted
Change configuration parameters of the EFT Terminal.
commit
commitAsync
commitCompleted
Perform Commit-operation after a successful Transaction call.
connect
connectAsync
connectCompleted
Initiates a connection to the EFT Terminal.
counterRequest
counterRequestAsync
counterRequestCompleted
Get counter information`s from the EFT Terminal.
dccRates
dccRatesAsync
dccRatesCompleted
Request DCC rates from the EFT Terminal.
deactivate
deactivateAsync
deactivateCompleted
Close a user shift.
disconnect
disconnectAsync
disconnected
Interrupts the connection to the EFT Terminal.
hardwareInformation
hardwareInformationAsync
hardwareInformationCompleted
Get hardware information from the EFT Terminal.
login
loginAsync
loginCompleted
Activate a communication session between the ECR and
the terminal.
logout
logoutAsync
logoutCompleted
Terminate an active communication session between the ECR
and the terminal.
reboot
rebootAsync
rebootCompleted
Force the EFT Terminal to reboot.
receiptRequest
receiptRequestAsync
receiptRequestCompleted
Receive the latest receipt or a list of silent receipts.
reconciliation
reconciliationAsync
reconciliationCompleted
Force the EFT Terminal to transmit all financial transactions
to the host system.
reconfig
reconfigAsync
reconfigCompleted
Force the EFT Terminal to get the configuration from the service center.
rollback
rollbackAsync
rollbackCompleted
Prevent a transaction from being committed to the transaction
log and generates a technical reversal of the authorization.
softwareUpdate
softwareUpdateAsync
softwareUpdateCompleted
Force the EFT Terminal to start a Software Update.
systemInformation
systemInformationAsync
systemInformationCompleted
Request system information from the EFT Terminal.
transaction
transactionAsync
transactionCompleted
Starts an EFT Terminal Transaction.

Guide Petrol terminal functions

Sync method
Async method
Completed event
Description
cancel Cancel an asynchronous function.
initTransaction
initTransactionAsync
initTransactionCompleted
Retreive card data for the presented card.

Guide Unattended terminal functions

Sync method
Async method
Completed event
Description
openReader
Async
openReaderCompleted
Opens the shutter of the card reader.
closeReader
closeReaderAsync
closeReaderCompleted
Closes the shutter of the card reader.
ejectCard
ejectCardAsync
ejectCardCompleted
Ejects the card from the card reader.
openMaintenanceWindow
openMaintenanceWindowAsync
openMaintenanceWindowCompleted
Opens a maintenance window where the terminal can perform all maintenance processes it was not able to perform before.>
closeMaintenanceWindow
closeMaintenanceWindowAsync
closeMaintenanceWindowCompleted
Prohibits the EFT terminal from performing any triggered maintenance tasks.
holdCommit Increases the commit timeout.
cancel Cancels a running request.
commit
commitAsync
commitCompleted
Commits a transaction after succesful authorization. A lower amount may be commited than the authorized amount.
amtAdjustment
amtAdjustmentAsync
amtAdjustmentCompleted
Send an amount adjustment notification to the terminal during an open transaction. The amount is used as the new amount for the transaction.

Guide dialog terminal functions

Sync method
Async method
Completed event
Description
openDialogMode
openDialogModeAsync
openDialogModeCompleted
Open dialog mode on the terminal.
closeDialogMode
closeDialogModeAsync
closeDialogModeCompleted
Close dialog mode on the terminal.
showDialog
showDialogAsync
showDialogCompleted
Show dialog on the terminal.
showSignatureCapture
showSignatureCaptureAsync
showSignatureCaptureCompleted
Show signature capture on the terminal.

Additional terminal listener-events

Listener-event Description
requestCompleted Operation started by an asynchronous function has finished.
Applications can use both operation specific completion callback
in combination with this generic completion callback.
terminalStatusChanged The terminal status has changed. The new status can be
retrieved from the TerminalStatus property.

Swift Specifics

For Swift, the TIM API is delivered as a "Universal Framework". This means that the framework is build for multiple architectures, for the physical iPhone (ARM) and for the iOS simulator (x86) for development purposes.

To be able to upload your application to the Apple AppStore you must stripe the unused architecture from the framework as Apple does not allow "Universal Frameworks" to be part of an App in the AppStore. This can be done by adding a "Run Script" step to your build steps. Put is after your step to embed frameworks, set it to use "/bin/sh" and enter the following script:

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"

# This script loops through all the frameworks that you have embedded
# in the application and removes all unused architectures.
# This procedure is required to be able to upload your application to the AppStore, that
# uses the TIM API.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
    FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
    FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
    echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"

    EXTRACTED_ARCHS=()

    for ARCH in $ARCHS
    do
        echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
        lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
        EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
    done

    echo "Merging extracted architectures: ${ARCHS}"
    lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
    rm "${EXTRACTED_ARCHS[@]}"

    echo "Replacing original executable with thinned version"
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"

done

The script will look through your built applications "Frameworks" folder and make sure only the architectures you’re building for are present in each Framework.

Function-State-Matrix

Legend:

  • B1-Retail
  • B2-Petrol
  • B3-Unattended
  • B4-Advanced Retail
  • B5-Banking
  • B6-Dialog
  • B8-Gastro
  • B9-Hospitality
  • B10-Value Added Services (VAS)
  • B11-Austrian Use Cases

Function State Book(s)
Disconnected Connected
LoggedOut LoggedIn
Closed Opened Dialog
Activate - - o o - B1
ActivateServiceMenu - - o - - B3
AdjustReservation - - - o - B9
AmtAdjustment - - - o - B3
ApplicationInformation - - o - - B1
AuthorizeCredit - - - o - B5
AuthorizeDeposit - - - o - B5
Balance - - o - - B1
BalanceInquiry - - - o - B4, B5
Cancel - o o o o B1
CancelReservation - - - o - B9
CashAdvance - - - o - B4
ChangeSettings - - o - - B1
CloseDialogMode - - - - o B6
CloseMaintenanceWindow - - o - - B3
CloseReader - - - o - B3
CollectPoints - - - o - B10
Combined - - - o - B5
Commit - - - o - B1
CounterRequest - - o o - B1
Credit - - - o - B1
DccRates - - o - - B1
Deactivate - - o o - B1
EjectCard - - - o - B3
FeatureRequest - o o - - B1
FinalizePurchase - - - o - B2
FinishCeckout - - - o - B10
Giro - - - o - B5
HardwareInformation - - o - - B1
HoldCommit - - - o - B3
InitTransaction - - - o - B2
KeepAlive - - o o o B1
LicenseChanged - - o - - B1
LoadVoucher - - - o - B10
Login - o o - - B1
Logout - o o - - B1
LoyaltyData - - - o - B10
OpenDialogMode - - - o - B6
OpenMaintenanceWindow - - o - - B3
OpenReader - - - o - B3
PreAuthorization - - - o - B2
ProvideLoyaltyBasket - - - o - B10
Purchase - - - o - B1
PurchaseForcedAcceptance - - - o - B4
PurchaseMailOrdered - - - o - B4
PurchasePhoneAuthorized - - - o - B4
PurchasePhoneOrdered - - - o - B4
PurchaseReservation - - - o - B9
PurchaseReservationPhoneAuthorized - - - o - B9
PurchaseWithCashback - - - o - B4
Reboot - - o - - B1
ReceiptRequest - - o o - B1
Reconciliation - - o o - B1
Reconfig - - o - - B1
Reservation - - - o - B9
Reversal - - - o - B1
Rollback - - - o - B1
SendCardCommand - - - - o B6
ShowDialog - - - - o B6
ShowSignatureCapture - - - - o B6
SoftwareUpdate - - o - - B1
StartCheckout - - - o - B10
SystemInformation - - o - - B1
TerminalStatus - o o o o B1
VasInfo - - - o - B10

Reference

Ref. Document Version
[B1] TIM & SIXml Architecture: The SIX ECR Integration System 0.10