go to Simple Implementation Guide
Detailed Implementation Guide

 Introduction

The TIM API is the standard application interface for ECR integration using Worldline 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.


 Setup Configuration

The configuration of the terminal can be done by creating and configuring a terminal_settings-instance. The terminal_settings-instance must then be passed to the terminal_createfunction.

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

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

 Network Configuration

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

The default communication is over TCP/IP connection. Default port used is 7784.

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 retailis the basic guide and is activated as default. With set_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:

ta_object_t terminal = ta_object_invalid;
ta_object_t settings = ta_object_invalid;

// create terminal settings instance
ta_terminal_settings_create(&settings);

// add wanted guides (with bitwise or)
ta_terminal_settings_set_guides(settings, ta_c_guide_retail | ta_c_guide_dialog);

// create terminal
ta_terminal_create(&terminal, settings);

// release terminal settings
ta_object_release(settings);

//...

// in the end release terminal as well
ta_oject_release(terminal);

 Operation Overview

Follow these basic steps for using the TIM API:

  1. Create terminal_settings and initialize connection parameters (see Setup Configuration)
  2. Create terminal instance using the created terminal_settings
  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.

A basic flow to show a dialog is:

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 auto_commit and fetch_brands. A Post-Automatism is triggered after an action has been performed. E.g. if a connect has been called and fetch_brands is activated, an application_information request is called automatically after the connect. Or if auto_commit is activated a commit is performed automatically after a transaction has been made. auto_commit and fetch_brands are enabled by default.

The following diagramsshow 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

 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 card_ref field in the transaction_datacontainer present in the terminal instance.

This card_ref 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 Petrol Use Cases

Petrol functionality adds a number of additional methods and notifiers, transaction types, containers (additional_info_list, basket) , container content (processing_disposition) and flows tailored to the needs at petrol stations.

Petrol has the following basic use cases:

 Petrol Basket Handling

An essential part of the petrol use cases is the usage of the basket container. This container is used to exchange information regarding purchased goods and fuel at a petrol station. It is important to know that the correctness of the content of the basket container lies within the responsibility of the ECR and/or the acquiring host, not of the TIM API or the terminal.

The basket is sent from the ECR to the terminal, then from the terminal to the host. The host may adjust the content of the basket depending on the card used for the transaction, therefore the basket sent from ECR to terminal may differ from the basket returned from terminal to ECR.

A basket may be used with the following transaction_types:

  • Purchase
  • FinalizePurchase

To send a basket within a request, the transaction_request must be created by the integrator and the basket and its basket_items must then be set in the transaction_request. The transaction_request is then used as parameter of the transaction/ transaction_async function.

 Indoor - Online Card

Online cards are processed like a standard credit or debit payment card through an online system, no mather if it is a standard credit card or an oil company card. In the latter case however, depending on the exact brand rules, additional data must be supplied by the ECR system (usually the type of goods being purchased, see basket) and may be collected form the cardholder (e.g. ID number) and sent on to the online system.

The data is also provided back to the ECR via the basket and additional_info_list containers.

An online system may decline parts of the purchase basket.

The transaction flow differs from the standard scenario in an additional way. To distinguish between online cards (this scenario) and offline cards (that scenario ) it is necessary to first initiate a card detection through an ta_terminal_init_transaction call.

This is an indoor scenario, i.e. takes place in an attended environment, usually a shop that is part of the petrol station. See this flow for reference.

 Outdoor - Online Card

Outdoor - Online Card is esentially the same scenario as above. The difference is that it takes place on an unattended terminal generally located at or near the petrol pump.

This scenario requires that exchange of goods for money is slightly altered. The new sequence of events is: check if sufficient funds are available, hand out goods, finalize the funds transfer after the final amount is known. This is supported through the transaction types pre_authorization and finalize_purchase.

This is an outdoor scenario, i.e. takes place in an unattended environment, usually at the petrol pump. See this flow for reference.

 Indoor - Offline Card

Offline cards are cards that are processed entirely by the ECR system. The EFT operates only as a card reader, display and keyboard for the ECR. The ECR recognises offline cards based on the processing_disposition returned from ta_terminal_init_transaction.

After the completion of ta_terminal_init_transaction the ECR is responsible for all further interaction. For cardholder interaction a number of dialogs (part of the "Dialog" guide) can be used.

This is an indoor scenario, i.e. takes place in an attended environment, usually a shop that is part of the petrol station. See this flow for reference.

 Outdoor - Offline Card

Outdoor offline processing of cards does not differ from indoor online processing.

This is an outdoor scenario, i.e. takes place in an unattended environment usually at the petrol pump. See this flow for reference.

 Guide Unattended Use Cases

Unattended functionality is aimed at the needs of vending machines an similar devices. It adds additional methods, transaction types and flows.

Unattended has the following basic use cases:

 Use Case Partial Commit

This use case deals with vending machines that dispense multiple products. It uses the standard retail "Purchase" transaction function with a subsequent "Commit". Products are dispensed after the successful transaction and before "Commit" is invoked. If only a part of the products can by dispensed (e.g. out of paper state on a ticketing machine) the cardholder should only be debited for the products actually received. To facilitate this commits can be "partial" meaning only an amount lower than the previously authorised amount is booked. To this end the commit-function has an amount parameter. See this flow for reference.

 Use Case Hold Commit

Products are usually dispensed between the successful transaction return and before "Commit" is invoked. Should product dispensing take more time than the commit timeout the timneout can be prolonged by HoldCommit. See this flow for reference.

 Use Case Amount Adjustment

Some machines allow the cardholder to buy multiple products, each product operation changing the final amount to pay. These machines may also choose to allow the cardholder to finalize the purchase by just inserting the credit card instead of pressing an additional button. For contactless support the terminal needs to always be ready for a transaction, therefore the transaction amount needs to be continualy updated. This can be achived with "Amount Adjustment". See this flow for reference.

 Use Case Retain Card

A vending machine has the option to prevent the automatic ejection of the card right after the transaction and instead opt to handle the exact ejection time itself. This is achived with the "Retain Card"-flag See this flow for reference.

 Use Case Silent Abort

Machines that take multiple forms of payment (e.g. cash and cards) will often open all payment channels. If the customer chooses a payment means not handled by the terminal the terminal transaction needs to be aborted. Usually this shows "Abort" on the screen of the terminal which can be confusing the the customer. Therefore it is possible to do a "silent abort" that prevents that text from appearing. See this flow for reference.

 Guide Banking Use Cases

Banking functionality adds an additional methods and notifiers, banking transaction types, and flows tailored to the needs of banking use cases.

Banking guide offers the following use cases:

 Balance Inquiry

To have an overview about the balance of the account, TIM offers a function to check the current account balance of the card used. This function is called ta_terminal_balance_inquiry and requires a present card. To be sure that only the right cardholder is able to check his/her account balance a PIN check will be performed.

See this flow for reference.

 Client Identification

For certain banking actions it is required to identify the cardholder by performing a PIN check. TIM offers this functionality using the "Dialog Mode" which requires the "Dialog" guide as well, besides the "Banking" guide. The corresponding value for resource_id used to show a PIN check dialog is pin_check.

See this flow for reference.

 Signature Capture

Besides checking the PIN of a customer it may be required that a customer has to sign to perform a certain action. TIM offers a signature capture functionality. This function requires the "Dialog" guide to be active, besides the "Banking" guide, if used in banking environment. The corresponding function ta_terminal_show_signature_capture is shown more detailed in the "Dialog" guide.

See this flow for reference.

 Card Identification

As there might be some special cards used in the banking environment and therefore special functions used, TIM allows to make a card identification which delivers card_data to determine which action should be done next, depending on the card data returned. This function requires the "Dialog" guide to be active, besides the "Banking" guide. The corresponding values for resource_id used to identify the card used, are either swiss _post _card_identification for Swiss Post or banking _card_identification for other Banking purposes.

See this flow for reference.

 Account Transfer: Swiss Post only

A common use case at a bank is to transfer money from one account to another. To be able to use this feature the "Dialog" guide is required besides the "Banking" guide. TIM offers a function that allows to set the source account, the destination account and the amount to transfer. The function ta_terminal_show_dialog_async with the corresponding resource_id and the placeholder_items must be used. The correct resource_id is inter_account_transfer and the following placeholder_items are required to be set in the show_dialog_request:

  • 0: Source Account
  • 1: Source Account Type
  • 2: Currency Source Account
  • 3: Source Account - Description
  • 4: Destination Account
  • 5: Destination Account Type
  • 6: Currency Destination Account
  • 7: Destination Account - Description
  • 8: Currency
  • 9: Amount

See this flow for reference.

 Account Deposit: Swiss Post only

Another use case is that the customer wants to deposit an amount on his/her account. To be able to use this feature the transaction_type "AuthorizeDeposit" is introduced in the "Banking" guide. This is done with the function ta_terminal_transaction_async and the corresponding transaction_type.

See this flow for reference.

 Account Payout: Swiss Post only

A similar use case as above is that the customer wants to withdraw an amount from his/her account. To be able to use this feature the "Dialog" guide is required besides the "Banking" guide. This is also done with the function ta_terminal_show_dialog_async and the corresponding resource_id and placeholder_items. The correct resource_id is disbursement_from_account and the following placeholder_items are required to be set in the show_dialog_request:

  • 0: Debit Account
  • 1: Debit Currency
  • 2: Amount

See this flow for reference.

 Parcel Acknowledgement: Swiss Post only

This next use case is that a customer wants to pick up a parcel and must sign on the device to acknowledge that he/she actually picked up the parcel. As this requires the signature input of the customer it is offered as dialog function ta_terminal_show_dialog_async and the corresponding resource_id. This requires an activeted "Dialog" guide. The correct resource_id is packet_acknowledgement, There are no placeholder_items required.

See this flow for reference.

 Load PrePaid Phone: Swiss Post only

Another use case is to load a pre paid phone. This is also done with the function ta_terminal_show_dialog_async and the corresponding resource_id and placeholder_items. The correct resource_id is show_phone_number_with_amount and the following placeholder_items are required to be set in the show_dialog_request:

  • 0: Phone number
  • 1: Currency
  • 2: Amount to load

See this flow for reference.

 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 ta_terminal_transaction_async and ta_terminal_transaction functions with transaction_type _purchase are used with additional parameters the can be set in transaction_data 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 ngv_mode can be set according to ngv_mode to define the NGV behaviour of a transaction.

With the ngv_mode 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 ngv_used_flag has been introduced in the transaction_response. For statistics the NGV transactions can also be identified in the counters using the same ngv_used_flag.

 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 clearing_delay member in transaction_data.

 Terminal methods overview

The basic operation modes of terminal function calls are:

  1. Synchronous
    Function calls are blocking and return after the operation has finished. Error code is provided and indicates if request was successful or not.

  2. Asynchronous
    Function call returns immediately after the operation has started successfully. A user-implemented callback function will then be called, after the operation has finished. All callback functions receive an event. The event contains a result_code indicating if there were errors or not. The user-implemented callback function has to be registered with add_listener.

Functions called on terminal perform synchronous by default. The asynchronous method has the same name with _aync appended to its name.

Code example for adding a terminal listener:

/*
 * Example for adding a terminal status listener
 *
 * \param[in] terminal Terminal instance
 */
void add_status_listener(ta_object_t terminal) {
    ta_object_t listener = ta_object_invalid;
    ta_s_terminal_listener_t listener_config;

    // clear listener-config
    memset(&listener_config, 0, sizeof(listener_config));

    // add user-implemented callback to listener-config
    listener_config.terminal_status_changed = mylistener_terminal_status_changed;

    // optional: add user content to listener,
    // pointer will be handed over to all callbacks:
    //listener_config.user_pointer = &custom_struct;

    // create listener-object
    ta_terminal_listener_create(&listener, &listener_config);

    // add listener-object to terminal
    ta_terminal_add_listener(terminal, listener);

    // release listener-object
    ta_object_release(listener);
}

/*
 * Callback for terminal status changes
 *
 * Will be called when status of terminal changes.
 * \param[in] terminal Terminal instance
 * \param[in] user_pointe User-pointer which can be set in the terminal listener
 */
void mylistener_terminal_status_changed(ta_object_t terminal,	void *user_pointer) {

	// implement your code to process status change here...
	//printf(" > listener_terminal_status_changed\n");
}

 Main / guide Retail terminal functions

Sync method
Async method
Completed event
Description
ta_terminal_activate
ta_terminal_activate_async
activate_completed
Open a user shift.
ta_terminal_application_information
ta_terminal_ application_information_async
application_information_completed
Request the list of brands available on the terminal.
ta_terminal_balance
ta_terminal_balance_async
balance_completed
Force the EFT Terminal to transmit all transactions to the
host system as well to do the daily closing.
ta_terminal_cancel Aborts an open asynchronous Financial Transaction or Non-Financial Transaction request, except for a commit or rollback request, which cannot be cancelled.
ta_terminal_change_settings
ta_terminal_change_settings_async
change_settings_completed
Change configuration parameters of the EFT Terminal.
ta_terminal_commit
ta_terminal_commit_async
commit_completed
Perform Commit-operation after a successful Transaction call.
ta_terminal_connect
ta_terminal_connect_async
connect_completed
Initiates a connection to the EFT Terminal.
ta_terminal_counter_request
ta_terminal_counter_request_async
counter_request_completed
Get counter information`s from the EFT Terminal.
ta_terminal_dcc_rates
ta_terminal_dcc_rates_async
dcc_rates_completed
Request DCC rates from the EFT Terminal.
ta_terminal_deactivate
ta_terminal_deactivate_async
deactivate_completed
Close a user shift.
ta_terminal_disconnect
ta_terminal_disconnect_async
disconnected
Interrupts the connection to the EFT Terminal.
ta_terminal_hardware_information
ta_terminal_hardware_information_async
hardware_information_completed
Get hardware information from the EFT Terminal.
ta_terminal_login
ta_terminal_login_async
login_completed
Activate a communication session between the ECR and
the terminal.
ta_terminal_logout
ta_terminal_logout_async
logout_completed
Terminate an active communication session between the ECR
and the terminal.
ta_terminal_reboot
ta_terminal_reboot_async
reboot_completed
Force the EFT Terminal to reboot.
ta_terminal_receipt_request
ta_terminal_receipt_request_async
receipt_request_completed
Receive the latest receipt or a list of silent receipts.
ta_terminal_reconciliation
ta_terminal_reconciliation_async
reconciliation_completed
Force the EFT Terminal to transmit all financial transactions
to the host system.
ta_terminal_reconfig
ta_terminal_reconfig_async
reconfig_completed
Force the EFT Terminal to get the configuration from the service center.
ta_terminal_rollback
ta_terminal_rollback_async
rollback_completed
Prevent a transaction from being committed to the transaction
log and generates a technical reversal of the authorization.
ta_terminal_software_update
ta_terminal_software_update_async
software_update_completed
Force the EFT Terminal to start a Software Update.
ta_terminal_system_information
ta_terminal_system_information_async
system_information_completed
Request system information from the EFT Terminal.
ta_terminal_transaction
ta_terminal_transaction_async
transaction_completed
Starts an EFT Terminal Transaction.

 Guide Petrol terminal functions

Sync method
Async method
Completed event
Description
ta_terminal_init_transaction
ta_terminal_init_transaction_async
init_transaction_completed
Retrieve card data for the presented card.

 Guide Unattended terminal functions

Sync method
Async method
Completed event
Description
ta_terminal_open_reader
ta_terminal_open_reader_async
open_reader_completed
Opens the shutter of the card reader.
ta_terminal_amt_adjustment Send an amount adjustment notification to the terminal during an open transaction. The amount is used as the new amount for the transaction.
ta_terminal_close_maintenance_window
ta_terminal_close_maintenance_window_async
close_maintenance_window_completed
Prohibits the EFT terminal from performing any triggered maintenance tasks.
ta_terminal_close_reader
ta_terminal_close_reader_async
close_reader_completed
Closes the shutter of the card reader.
ta_terminal_commit
ta_terminal_commit_async
commit_completed
Commits a transaction after succesful authorization. A lower amount may be commited than the authorized amount.
ta_terminal_eject_card
ta_terminal_eject_card_async
eject_card_completed
Ejects the card from the card reader.
ta_terminal_hold_commit Increases the commit timeout.
ta_terminal_open_maintenance_window
ta_terminal_open_maintenance_window_async
open_maintenance_window_completed
Opens a maintenance window where the terminal can perform all maintenance processes it was not able to perform before.>

 Banking terminal functions

Sync method
Async method
Completed event
Description
ta_terminal_balance_inquiry
ta_terminal_balance_inquiry_async
balance_inquiry_completed
Perform a balance check of a card/account on the terminal.

 Guide Dialog terminal functions

 Additional terminal listener-events

Listener-event Description
request_completed Operation started by an asynchronous function has finished.
Applications can use both operation specific completion callback
in combination with this generic completion callback.
terminal_status_changed 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.

 Petrol Additional Flows

 Petrol Flow: Indoor - Online Card

ECRECREFTEFTClientClientHostHostTransactionState: IdleInit Transaction Request (Amount)TransactionState: WaitForCardInsert CardStart reading cardTransactionState: ReadingCardTransactionState: ApplicationSelectionHave read all card dataTransactionState: WaitForProceedInit Transaction Response ([CardData], [ProcessingDisposition=OnEFT])Purchase Request ([Basket], Amount)opt[MOC Petrol: AdditionalInformation already required in AuthRequest]loop[0..n]Request additional informationEntry additional informationAuthorization Request (Amount, [AddInfo], [SetOfRestrictions])Authorization Response (Amount, [AddInfo], [SetOfRestrictions])opt[MOC Online: AdditionalInformation only required in submission]loop[0..n]Request additional informationEntry additional informationopt[Amount may have changed: Cardholder confirmation]Confirm new amountPurchase Response (Amount, [AdditionalInfo], [Basket], [PrintData], TransactionInformation)Commit RequestCommit Response

 Petrol Flow: Outdoor - Online Card

ECRECREFTEFTClientClientHostHostInit Transaction RequestTransactionState: WaitForCardInsert CardStart reading cardTransactionState: ReadingCardTransactionState: ApplicationSelectionHave read all card dataTransactionState: WaitForProceedInit Transaction Response ([CardData], [ProcessingDisposition=OnEFT])PreAuth Request (Amount)opt[MOC Petrol: AdditionalInformation already required in AuthRequest]loop[0..n]Request additional informationEntry additional informationAuthorization Request (Amount, [AddInfo], [SetOfRestriction])Authorization Response ([AddInfo], [SetOfRestrictions])opt[MOC Online: AdditionalInformation only required in submission]loop[0..n]Request additional informationEntry additional informationPreAuth Response ([AdditionalInfo], [Basket], Amount)opt[At ECR Discretion]OpenDialogMode RequestOpenDialogMode Responseloop[0..n]Dialog mainly used for pump selection and the like.Dialog RequestRequest additional informationEntry additional informationDialog ResponseCloseDialogMode RequestCloseDialogMode ResponsePump selectedRemove cardPump petrolFinalizePurchase Request ([AdditionalInfo], [Amount], [TransactionData], [Basket])loop[1..3]Online Advice Request (Amount, [AddInfo], [SetOfRestrictions])Online Advice Response (Amount, [AddInfo], [SetOfRestrictions])FinalizePurchase Response (Amount, [Basket], [PrintData], TransactionInformation)Commit RequestCommit Response

 Petrol Flow: Indoor - Offline Card

ECRECREFTEFTClientClientHostHostInit Transaction Request (Amount)TransactionState: WaitForCardInsert CardStart reading cardTransactionState: ReadingCardTransactionState: ApplicationSelectionHave read all card dataTransactionState: IdleInit Transaction Response ([CardData], [ProcessingDisposition=OnECR])OpenDialogMode RequestOpenDialogMode Responseloop[0..n]Dialog RequestRequest additional information- Collection of FleetID, Mileage, UserID.- PIN check- Pump selectionEntry additional informationDialog ResponseDialog Request ([RemoveCard])Show "Please Remove card"Takes cardDialog ResponseCloseDialogMode RequestCloseDialogMode Response

 Petrol Flow: Outdoor - Offline Card

ECRECREFTEFTClientClientHostHostInit Transaction RequestTransactionState: WaitForCardInsert CardStart reading cardTransactionState: ReadingCardTransactionState: ApplicationSelectionHave read all card dataTransactionState: IdleInit Transaction Response ([CardData], [ProcessingDisposition=OnECR])OpenDialogMode RequestOpenDialogMode Responseloop[0..n]Dialog RequestRequest additional information- Collection of FleetID, Mileage, UserID.- PIN check- Pump selectionEntry additional informationDialog ResponseDialog Request ([RemoveCard])Show "Please Remove card"Takes cardDialog ResponseCloseDialogMode RequestCloseDialogMode Response

 Guide Unattended Additional Flows

  Flow: Partial Commit

ECRECREFTEFTClientClientHostHostTerminalTerminalPurchase(Amount, TransactionData)InsertCard / TapCardPinEntryCardRemoval (for Contact)return Purchase(ResultCode = 0)TransactionState: WaitForCommitalt["Partial Commit" if Vending Machine failed to deliver all goods]Commit(Amount)["Commit" no discount]Commit()return Commit()

  Flow: Hold commit

ECRECREFTEFTClientClientHostHostTerminalTerminalPurchase(Amount, TransactionData)InsertCard / TapCardPinEntryCardRemoval (for Contact)return Purchase(ResultCode = 0)opt["Vending Machine busy"]loop["SendingHoldCommitnotifications as long as Vending Machine is not ready to continue."]HoldCommit()Commit()return Commit()

  Flow: Amount adjustment

ECRECREFTEFTClientClientHostHostTerminalTerminalPurchase(Amount, TransactionData)loopSelect ItemAmtAdjustment(Amount)TerminalStatusNotification(FinalAmount)InsertCard / TapCardPinEntryCardRemoval (for Contact)return Purchase(ResultCode = 0)Commit()return Commit()

  Flow: PreAuthorization

ECRECREFTEFTClientClientHostHostTerminalTerminalPreAuthorization(Amount, TransactionData)InsertCard / TapCardPinEntryCardRemoval (for Contact)return PreAuthorization(ResultCode = 0)Vending Machine dispensing goods.FinalizePurchase()return FinalizePurchase()alt[If AutoCommit diabled]Commit()return Commit()

  Flow: Retain card

ECRECREFTEFTClientClientHostHostTerminalTerminalPurchase()Terminal display:EUR 23.50Card pleaseInsertCard / TapCardalt[CardRetainFlag = true]Cancel(CardRetainFlag = true)CardRetainFlag is used so thecard is retained insidethe card reader after the abort.Terminal display:Abort[CardRetainFlag = false]Cancel(CardRetainFlag = false)CardRetainFlag is NOT used so thecard is not retained insidethe card reader after the abort.Terminal display:Abortreturn Purchase(ResultCode = 50, ErrorMessage)Card is ejectedTerminal display:Remove card pleaseCard removal

  Flow: Silent abort

ECRECREFTEFTClientClientHostHostTerminalTerminalPurchase()Terminal display:EUR 23.50Card pleaseInsertCard / TapCardalt[Silent Abort]Cancel(SilentFlag = true)SilentFlag is used sothe terminal won't show"Abort" on its display.[No Silent Abort]Cancel(SilentFlag = false)SilentFlag is NOT used sothe terminal will show"Abort" on its display.Terminal display:Abortreturn Purchase(ResultCode = 50, ErrorMessage)Card will be ejected.

 Banking Additional Flows

 Banking Flow: BalanceInquiry

ECRECREFTEFTClientClientalt[Card before transaction]Card insertionBalanceInquiryAsync() requestalt[Card after transaction]Card insertionPIN entryalt[PIN wrong]loop[if PIN entered wrong and not last PIN try]PIN wrongTry againPIN & OKPIN entryalt[PIN wrong and last PIN try]PIN wrongLast tryPIN & OKPIN entryalt[Last PIN try wrong]BalanceInquiryCompleted() ResultCode != 0[PIN correct]PIN OKBalanceCHF 2000.00BalanceInquiryCompleted() ResultCode = 0

 Banking Flow: Client Identification

ECRECREFTEFTClientClientalt[Card before transaction]Card insertionalt[Swiss Post]ShowDialogAsync(ResourceId=PIN_ENTRY) request[Banking]ShowDialogAsync(ResourceId=BANKING_PIN_CHECK) requestalt[Card after transaction]Please insert cardCard insertionPIN & OK_ _ _ _ _ _PIN entryalt[PIN wrong]loop[if PIN entered wrong and not last PIN try]PIN wrongTry againPIN & OKPIN entryalt[PIN wrong and last PIN try]PIN wrongLast tryPIN & OKPIN entryalt[Last PIN try wrong]ShowDialogCompleted() Reason=PIN_NOK[PIN correct]PIN OKShowDialogCompleted() Reason=PIN_OK

 Banking Flow: Card Identification

ECRECREFTEFTClientClientalt[Swiss Post]ShowDialogAsync(ResourceId=WELCOME_CARD) request[Banking]ShowDialogAsync(ResourceId=BANKING_INSERT_CARD) requestWelcome, card pleaseCard insertionReading cardShowDialogCompleted() CardData, Reason=CardReader

 Banking Flow: Account Transfer

ECRECREFTEFTClientClientShowDialogAsync(ResourceId = INTER_ACCOUNT_TRANSFER, PlaceholderItems) requestFrom 01-234567-8 Sparkonto CHFMax, Mustermannto 09-876543-2 Privatkonto CHFMax, MustermannCHF 10.00alt[STOP by cardholder]Cardholder input: STOPShowDialogCompleted() Reason=STOP[OK]Cardholder input: OKShowDialogCompleted() Reason=OKShowDialogAsync(ResourceId = INTER_ACCOUNT_TRANSFER_CONFIRMATION, PlaceholderItems) request01-234567-8 Sparkonto CHFCHF 1234.5609-876543-2 Privatkonto CHFCHF 4321.56alt[STOP by cardholder]Cardholder input: STOPShowDialogCompleted() Reason=STOP[OK]Cardholder input: OKShowDialogCompleted() Reason=OK

 Banking Flow: Account Deposit

ECRECREFTEFTClientClientCard insertionTransactionAsync(TransactionType = AuthorizeDeposit, Amount) requestalt[Card after transaction]Please insert cardCard insertionDeposit own accountauthorizationCHF 10.00 OK?alt[STOP by cardholder]STOP pressedTransactionCompleted() ResultCode != 0[OK by cardholder]OK pressedTransactionCompleted() ResultCode = 0

 Banking Flow: Account Payout

ECRECREFTEFTClientClientShowDialogAsync(ResourceId = DISBURSEMENT_FROM_ACCOUNT, PlaceholderItems) requestDisbursement from account01-2345-6CHF 10.00 OK?alt[STOP by cardholder]Cardholder input: STOPShowDialogCompleted() Reason=STOP[OK]Cardholder input: OKShowDialogCompleted() Reason=OK

 Banking Flow: Parcel Acknowledgement

ECRECREFTEFTClientClientShowSignatureCaptureAsync(ResourceId = PACKET_ACKNOWLEDGEMENT) requestI acknowledge havingreceived the parceland its listed contents:Signature please:_ _ _ _ _ _ _ _ _ _alt[Client signs on terminal]Input signatureCardholder input: OKShowSignatureCaptureCompleted() Reason=OK[Client STOP]Cardholder input: STOPShowSignatureCaptureCompleted() Reason=STOP

 Banking Flow: Load PrePaid Phone

ECRECREFTEFTClientClientShowDialogAsync(ResourceId = ENTER_PHONE_OR_PREPAID_NUMBER) requestEnter phone numberor Prepaid card:_ _ _ _ _ _ _ _ _ _alt[Client presses STOP]STOP pressedShowDialogCompleted() Reason=STOP[Client enters phone number and presses OK]Input phone numberCardholder input: OKShowDialogCompleted() Reason=OK[Cardholder inserts card]Card insertionShowDialogCompleted() Reason=CardReaderalt[In case of OK or card insertion]ShowDialogAsync(ResourceId = SHOW_PHONE_NUMBER, PlaceholderItems) requestYour phone number012 345 67 89alt[Cardholder STOP]STOP pressedShowDialogCompleted() Reason=STOP[Cardholder OK]OK pressedShowDialogCompleted() Reason=OKShowDialogAsync(ResourceId = SHOW_PHONE_NUMBER_WITH_AMOUNT, PlaceholderItems) request012 345 67 89CHF 50.00alt[Cardholder STOP]STOP pressedShowDialogCompleted() Reason=STOP[Cardholder OK]OK pressedShowDialogCompleted() Reason=OKShowDialogAsync(ResourceId = PROCESSING_OK) requestShowDialogCompleted() Reason=OK

 Guide Austrian Additional Flows

 Austrian Flow: NGV Purchase without delay

The following flow describes an NGV purchase without any specific clearing delay set. The ngv_mode "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 ngv_used_flag, 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 ngv_mode "AllowedWithFallback" also the clearing_delay 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 ngv_mode "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 ngv_used_flag is used to determine if the NGV payment was performed as such or if a fallback was used. In this case the ngv_used_flag 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 ngv_mode is "Mandatory" but the card used is not capable of NGV payments, the transaction results in an error which means a result_code != '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

The TIM API is able to log an extensive set of events and actions within the TIM API. It's key that logs are created and stored properly. Logging enables support and makes bug-tracking much easier.

The TIM API C fires log events for every log_record. It's the application's responsibility to manage and store these.

In order to get notified about log-events, implement the callback function ta_cb_publish_log_record and register it with ta_logger_set_global_logger .

Note: The TIM SDK contains example code for how to manage and store log-records. You can find the files "timapi_loghelper.c" and "timapi_loghelper.h" under "C/Utils/" in the TIM SDK.

 Log Level

The following logging levels exist:

  • ta_c_ll_finest
  • ta_c_ll_fine
  • ta_c_ll_info
  • ta_c_ll_warning
  • ta_c_ll_severe
  • ta_c_ll_off

 Log Configuration

Note: ta_terminal_settings contains deprecated options regarding logging. Do not use these:

  • set_log_dir
  • get_log_dir
  • set_log_file_count_per_archive
  • get_log_file_count_per_archive
  • set_log_retain_archive_count
  • get_log_retain_archive_count
  • set_log_retain_file_count
  • get_log_retain_file_count
See chapter Logging for how to get logs in TIM API C.

 C Language Specifics

 Objects in TIM API C

The TIM API C is based on an object-type concept. Most TIM API functions will either take or return parameters in shape of the "opaque type" ta_object_t. For example: ta_terminal_create will create a new terminal-instance, which returns a ta_object_t. On the other hand terminal-function calls like ta_terminal_get_terminal_id require the terminal-instance as parameter of type ta_object_t.

Note: This concept introduces a behaviour similar to certain aspects of object-oriented programming to the environment of C. Similarities are as follows:

  • For each object-type there are functions similar to getters and setters, in order to access the object-properties.
  • For each object-type there are functions similar to methods, performing object-specific tasks.
  • For certain object-types create-functions exist, which are similar to constructors.

 Memory Management in TIM API C

The memory needed for each object will be allocated and freed by the TIM API itself. However, the user is responsible to release retained objects, when no longer needed. Retained objects are:

(see header-documentation or this doxygen-dok to determine, if objects are retained / not retained. Most IDE support doxygen of header-documentation and will show these information while coding).

Following an example of memory management. Shown by using a list:
/* --- Create list -------------------------------------------------- */
ta_object_t myList = ta_object_invalid;
ta_list_create(&myList);

/* --- Add an integer ----------------------------------------------- */
// Create an object of type integer, since list can only contain
// ta_object_t-instances
ta_object_t myInteger = ta_object_invalid;
ta_integer_create(&myInteger, 1234);
ta_list_add(myList, myInteger);

// Important: User must release the integer-object. Either now or later.
ta_object_release(myInteger);

/* --- Get size of list --------------------------------------------- */
size_t myListSize;
ta_list_get_count(myList, &myListSize);

/* --- Receive first element of list -------------------------------- */
ta_object_t myListElement = ta_object_invalid;
ta_list_get_at(myList, 0, &myListElement);

// do something with element...
// - user is responsible to know how to read /
//   process retreived objects from list
// - in our case here it`s an integer-object
int64_t myIntValue = 0;
ta_integer_get_value(myListElement, &myIntValue);
printf("MyIntValue: %Id\n", myIntValue);

// Important:
// - The list returns list elements as not retained!
// - List element must not be released!

/* --- Release list ------------------------------------------------- */
ta_object_release(myList);

// - At this point, myListElement is no longer (reliably) accessible.
//   Since list has been released, all its elements have been released
//   as well, if no one else is retaining the list elements.

// - If user still wants to use myListElement, he needs to call
//   ta_object_retain(myListElement) right after receiving it from
//   the list. In this case, he later needs to release the list
//   element with ta_object_release(myListElement).

 Data Types in TIM API C

C doesn't provide data types / collections like string, boolean, list, timedate etc. Therefore the TIM API uses and provides a set of basic data types. In various places the TIM API requires or returns these data types.

Data Type Description
boolean A Boolean type (true/false)
integer An Integer type (64-bit)
list A list collection. Supports create, add, get, index of, remove and more.
map A map collection. Supports create, set, get, has, remove and more.
object The base object (see [Objects in TIM API`C`]).
string A String type. Null-terminated character sequence.
timedate Time-Date type.