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 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.

Before starting with the detailed implementation guide, make sure that you read the Simple Implementation Guide first.


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:

Minimal browser version:
  • Firefox 56
  • Chrome 59
  • Edge 41
  • Safari 11
If run in Node.js environment, minimal version:
  • Node.js 9

Setup Configuration

Before starting using the TIM API, make sure that onTimApiReady() has been called as described in the Simple Implementation Guide in chapter "Library usage".

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

Depending on the platform used, the TIM API module can communicate with the Terminal over different communication channels.

TIM API JavaScript communicates with the terminals using WebSockets. Unlike in other TIM APIs, there's no broadcast mode, since the WebSocket protocol doesn't support this feature. Default port is 80 (for some terminals, e.g. Verifone, it's 8080).

In order to start a connection to a terminal, it's IP address must be known and configured in the TerminalSettings.

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 IP-address and port of terminal to connect to
let settings = new timapi.TerminalSettings();
settings.connectionIPString = "192.168.1.10";
settings.connectionIPPort = 80;

// Add wanted guides
settings.guides.add(timapi.constants.Guides.hospitality);

// Create terminal
let terminal = new timapi.Terminal(settings);

//...

// 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 where required:
  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 diagram shows 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.

Pre-Automatisms flow

Use Cases

This chapter describes various guides and their use cases.

Hint: if no content visible, try to select a guide under "Guide Selection" on the left.

Manual Pan Key Entry

The TIM API offers the possibility to perform a Manual Pan Key Entry (MPKE) on ECR side, e.g. if no physical card is present. This can be done by setting the CardRef field in the TransactionDatacontainer present in the terminal instance.

This CardRef field must have the following format to reference a non-PCI PAN:

Example: "061234567801234567" : "06" is the prefix that defines the content type that follows (non-PCI PAN), "1234568701234567" is then the non-PCI PAN.

Important: The MPKE on the ECR is only allowed for non-PCI brands, otherwise the manual entry must only be performed on the PIN Pad.

Guide Austrian Use Cases

The Austria guide adds two new use cases:

  • Non guaranteed payment (NGV)
  • Delayed payment

Both use cases do not add any new functions. Only the standard TransactionAsync and Transaction functions with TransactionType Purchase are used with additional parameters the can be set in TransactionData before starting the purchase transaction.

Austrian Use Case: NGV

An NGV payment is used in conjunction with a standard purchase transaction. The difference is that the purchase is handled as an own risk transaction for the merchant. Before starting a purchase transaction the NGVMode can be set according to NGVMode to define the NGV behaviour of a transaction.

With the NGVMode it is possible to either forbid NGV usage for the next transaction, to allow it with a fallback to a standard purchase transaction or to set NGV usage to mandatory.

  • If the NGV usage is explicitly forbidden the purchase transaction must be performed as a standard purchase.
  • If the NGV is wished but fallback is allowed it is possible that the current purchase will either be performed as an NGV purchase or automatically as a standard purchase in case it is not possible to make an NGV purchase.
  • If NGV usage is set to mandatory the current purchase transaction must be performed as an NGV purchase. If this is not possible the purchase transaction fails without fallback.

To identify if the current transaction has been performed as an NGV purchase or not a new boolean flag NGVUsedFlag has been introduced in the TransactionResponse. For statistics the NGV transactions can also be identified in the Counters using the same NGVUsedFlag.

Austrian Use Case: Delayed Payment

The delayed payment can only be used in conjunction with an NGV purchase. For delayed payments, the clearing of a transaction is delayed by the clearing house for the defined number of days. The delay is set using the ClearingDelay member in TransactionData.

Terminal methods overview

All terminal methods are in async-mode. Method-calls return 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 ResultCode is included. User-implemented listener-handlers (that extend DefaultTerminalListener) can be added to the Terminal-instance with addListener.

Code example for adding a terminal listener:

/** Asynchronous listener handling terminal events. */

/* Define your own TerminalListener by overwrite all required 
 * methods from the DefaultTerminalListener class
 * which you want to use.
*/
class MyTerminalListener extends timapi.DefaultTerminalListener {

// Overwrite all wanted methods of the DefaultTerminalListener herein

}

/* Then create an instance of your "MyTerminalListener" and add it to
 * your terminal instance.
*/
var myListener = new MyTerminalListener();

terminal.addListener(myListener);


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.
cancel Aborts an open asynchronous Financial Transaction or Non-Financial Transaction request, except for a commit or rollback request, which cannot be cancelled.
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.

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.

Flows

This chapter describes various flows for specific guides.

Hint: if no content visible, try to select a guide under "Guide Selection" on the left.

Guide Austrian Additional Flows

Austrian Flow: NGV Purchase without delay

The following flow describes an NGV purchase without any specific clearing delay set. The NGVMode "AllowedWithFallback" is used which indicates it the card used is not capable of NGV payments the terminal is allowed to make a fallback to a standard purchase. This flow shows a successfully performed NGV payment which can be seen by checking the value NGVUsedFlag, which is set to "true".

ECRECRTimApiTimApiTerminalTerminalAcquirerAcquirerSet NGVMode = "AllowedWithFallback" in TransactionDataTransaction request (TransactionType = Purchase, Amount)FinTransaction:Purchase (Amount, TransactionData)The terminal checks if the cardused is capable of an NGV paymentand performs it if check has beensuccessful.opt[Maybe no authorization can be made]Authorization requestAuthorization responseTransaction response (ResultCode = 0, NGVUsedFlag = true)Transaction response (TransactionResponse[ResultCode, TransactionInformation, ...])Get NGVUsedFlag from TransactionInformation to determine if NGV was successfulAs no ClearingDelay has been setin TransactionData for this transaction,the clearing house will do the clearing as usual,without a specially defined delay.

Austrian Flow: NGV Purchase with delay

In the flow below, additionally to the NGVMode "AllowedWithFallback" also the ClearingDelay is set to define a specific clearing delay in days. This means that the NGV payment clearing will be delayed by the amount of days specified. This flow shows a successful NGV payment including a clearing delay.

ECRECRTimApiTimApiTerminalTerminalAcquirerAcquirerSet NGVMode = "AllowedWithFallback" in TransactionDataSet ClearingDelay in TransactionDataTransaction request (TransactionType = Purchase, Amount)FinTransaction:Purchase (Amount, TransactionData)The terminal checks if the cardused is capable of an NGV paymentand performs it if check has beensuccessful.opt[Maybe no authorization can be made]Authorization requestAuthorization responseTransaction response (ResultCode = 0, NGVUsedFlag = true)Transaction response (TransactionResponse[ResultCode, TransactionInformation, ...])Get NGVUsedFlag from TransactionInformation to determine if NGV was used successfullyThe clearing house will do theclearing of the transactionafter the defined delay.

Austrian Flow: NGV Purchase fallback with Non-NGV card

The following flow describes an NGV payment with NGVMode "AllowedWithFallback" which results in a fallback to a standard purchase due to the fact that the card used is not capable of NGV payments. The NGVUsedFlag is used to determine if the NGV payment was performed as such or if a fallback was used. In this case the NGVUsedFlag value is set to "false" which indicates that the requested NGV payment was not successful and the fallback to a standard purchase has been done.

ECRECRTimApiTimApiTerminalTerminalAcquirerAcquirerSet NGVMode = "AllowedWithFallback" in TransactionDataTransaction request (TransactionType = Purchase, Amount)FinTransaction:Purchase (Amount, TransactionData)The terminal checks if the cardused is capable of an NGV paymentand performs it if check has beensuccessful.In this case the card used does notsupport NGV payments. Therefore the terminalmakes a fallback to a standard purchasetransaction, as NGVMode = "AllowedWithFallback"allows a fallback.Authorization requestAuthorization responseTransaction response (ResultCode = 0, NGVUsedFlag = false)As the NGVMode is set to"AllowedWithFallback" theTerminal made a fallbackto a standard purchase ifthe card used did notsupport NGV.Transaction response (TransactionResponse[ResultCode, TransactionInformation, ...])Get NGVUsedFlag from TransactionInformation to determine if NGV was used successfullyThe clearing house will do theclearing of the transactionas usual, as no special delayhas been defined.

Austrian Flow: NGV Purchase mandatory with error

The following flow describes a mandatory NGV purchase transaction which could not be performed by the terminal. As the used NGVMode is "Mandatory" but the card used is not capable of NGV payments, the transaction results in an error which means a resultCode != '0' and an error payload as transaction response.

ECRECRTimApiTimApiTerminalTerminalAcquirerAcquirerSet NGVMode = "Mandatory" in TransactionDataTransaction request (TransactionType = Purchase, Amount)FinTransaction:Purchase (Amount, TransactionData)As NGVMode = "Mandatory" theTerminal must perform an NGV payment.If this is not possible thetransaction is returned with an error.opt[Maybe no authorization can be made]Authorization requestAuthorization responseTransaction response (ResultCode != 0, NGVUsedFlag = false)As the NGVMode is set to"Mandatory" theTerminal is NOT allowed tomake a fallbackto a standard purchase ifthe card used did notsupport NGV.Transaction response (TimException, Error Payload)

Logging

By default the TIM API JavaScript logs to the webconsole of the corresponding browser used, or to the system shell in case of Node.js. Due to security restrictions in the web context no log-files are created locally. Nevertheless, the TIM API JavaScript offers the possibility that the integrator can overwrite this behaviour by using the onTimApiPublishLogRecord(logRecord) or the onTimApiLog(message) method. If the TIM API JavaScript is used in web context it is recommended that the log message shall be sent to a log server or alike. If used with Node.js the message can be written into a file locally, as there are not such security restrictions in conjunction with Node.js.

The onTimApiPublishLogRecord(logRecord) function can be used if the user wants to filter certain log messages. The log entry is transmitted in a LogRecordobject that includes several information about the log entry. The user then can filter the entry e.g. regarding the logLevel and may then use the Log function to log the message accordingly, if wished so.

/*
* Function to filter certain log records according
* some information given in parameter "record", e.g. LogLevel.
*/
onTimApiPublishLogRecord = function (record) {
  // Do some filtering if wished so.
  if (!record.matchesLevel(timapi.LogRecord.LogLevel.info)) {
    return;
  }

  // timapi.log() will call the onTimApiLog function 
  timapi.log(String(record));
}

The onTimApiLog(message) method is used with a string message as log entry, not with an object. This method should be used to redirect the standard console logging e.g. to a log server or to a local file in case of Node.js.

/**
 * Function will be called, when timapi has a log message
 */
onTimApiLog = function(message) {
 /* Send message to log server or alike
  * or write it into a log file if Node.js
  */ is used.
}
Attention: If this function is used, the default behaviour will not be performed by the TIM API and no console logging is done.

Migration from old TIM API JS to TIM API JS with WebAssembly

The following sections will provide information which changes have to be made to switch from the old TIM API JS solution to the new TIM API JS with WebAssembly. Each section contains an example of the old TIM API JS and one of the new TIM API JS with WebAssembly to directly show the differences.

Ready Initialization

Below is an example how the TIM API must be initialized to be available.

With the old TIM API JS it was essential to check if the TIM API was available before using it. This could be done with the following check:

if(timapi == undefined){
  // TIM API not ready
}else{
  // Start using TIM API
}

In the new TIM API JS with WebAssembly a callback function is called as soon as the TIM API is ready to be used by the application:

function onTimApiReady() {
  // Start using TIM API
}

Class Variable Names

The naming of class variable names changed slightly:

Old TIM API JS used variables names with a '$'-sign like this:

settings.$connectionIPString = "..."

New TIM API JS with WebAssembly uses variables names like this (if " or ' is not important. JS supports both):

settings.connectionIPString = '...'

Listener Declaration

The old TIM API JS used a non-OOP like way to create listeners. A DefaultTerminalListener was created and then the respective methods were "replaced":

var listener = new timapi.DefaultTerminalListener();
listener.terminalStatusChanged = function (_terminal) {
timapi.DefaultTerminalListener.prototype.terminalStatusChanged(_terminal);
  // Do stuff
}

listener.connectCompleted = function (_event) {
timapi.DefaultTerminalListener.prototype.connectCompleted(_event);
  // Do stuff
}

listener.transactionCompleted = function(_event, _data) {
timapi.DefaultTerminalListener.prototype.transactionCompleted(_event, _data);
  // Do stuff
}

The new TIM API JS with WebAssembly uses proper subclassing like this:

class myTerminalListener extends timapi.DefaultTerminalListener {
  terminalStatusChanged(terminal) {
    super.terminalStatusChanged(terminal);
    ...
  }
  requestCompleted(event, data) {
    super.requestCompleted(event, data);
    ...
  }
}

Logging

In the old TIM API JS there was only the possibility to set the logging level but there was no chance to control the logging messages on user application level:

timapi.logging.Log.logLevel = timapi.logging.Level.FINE

This is not existing anymore in WebAssembly. Instead the logger goes to the web console by default but can be intercepted by the user application like this:

onTimApiLog = function(message) {
  ... // message is of type String
}

Which allows to simply output a final predefined log message.

To further filter the logMessages the "onTimApiPublishLogRecord" function can be used.