Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Table of Contents

Introduction

OLA stands for Open L2 API. It is a programmable interface normalizing card processing (L2) services required by a payment application (L3).

Important: this interface has been designed from a Nexo Fast perspective. OLA is a global initiative aiming to cover a missing key element in the payment ecosystem: the EMV L2 API. However, OLA is generic enough to support any kind of payment dynamic beyond Nexo implementations.

Principles

Interacting with a L2 stack is based a simple principles:

  1. Set pre-conditions

  2. Initiate transaction

  3. Eventually, complete transaction

  4. Get post-conditions

Setting pre-conditions consists in pushing EMV parameters fecthed from a TMS to the L2 stacks. This step depends on the payment application implementation and the selection process that occurs during stage of the transaction.

Initiating and completing a transaction is about delegating the card processing to the L2 stack. It triggers a behavior that has been L2 certified and granted with a LoA. It is based on the configuration parameters previously pushed.

Getting post-conditions consists in gathering a series of information to be able to provide a final outcome for the transaction.

Hypothesis: a payment application (L3) controls the polling of the technologies, implements a specific region EMV application .selection mechanism (if needed), and owns the configuration (fetched from its TMS). Card processing (L2) is global, and only depends on an ICS that is aligned on merchant’s requirements. Consequently:

  • A payment application detects whether a contact or contactless application will be triggerred

  • A payment application implements the logic to select a final application based on OLA services

  • A payment application configures the EMV parameters based on the final selection

Architecture

OLA aims:

  • To break dependencies between different integration levels and L2 implementations

  • To fill the gap between different objectives of testability (usually dependent on the context of integration)

  • To normalize L2 API beyond certificatibility objectives

Image Removed

Interfaces

...

Interface

...

Description

...

ola.h

...

This interface presents different administrative services

...

ola_emv.h

...

This interface presents common services required to support contact and contactless card processing

...

ola_publickey.h

...

This interface allows a payment application to intialize a L2 stack with a set of public keys required to execute an EMV transaction flow (contact and contactless)

...

ola_contact.h

...

This interface is meant to support contact transaction flow

...

ola_contactless.h

...

This interface is meant to support contactless transaction flow

...

ola_tags_dictionary.h

...

This header lists all the tags that are specific to Nexo Fast and consequently subject to a translation for further indexation in the L2 stack

...

ola_terminal.h

...

Deprecated from OLA 2.x versions

API

ola_implem.h

Code Block
breakoutModefull-width
languagec
// NAME.......  ola_implem.h
// PURPOSE....  Level 2 Abstraction Layer for contactless to be used by the external world (Level 3 application)
// PROJECT....  Arkos Payment Solution
// REFERENCES.	--
//
//
// Copyright 2005-2020 - 9164-4187 QUEBEC INC (AMADIS), All Rights Reserved
//

#ifndef OLA_IMPLEM_H_
#define OLA_IMPLEM_H_

#include "ola.h"

//---------------------------------------------------------
//			OLA related Services
//---------------------------------------------------------

typedef struct {
	void (*flush_aid_supported)(void);
	tOLAError (*answer_to_reset)(const char* reader);
	tOLAError (*add_aid_supported)(const uint8_t *aid, uint8_t aidLength, int partial);
	tOLAError (*build_candidate_list)(uint8_t *nb_candidates, int *pse);
	tOLAError (*get_tag_from_candidate)(uint8_t candidate, uint32_t tag, uint8_t *value, uint16_t *length);
	tOLAError (*final_select_candidate)(uint8_t candidate);
	tOLAError (*initiate_transaction)(tOlaModeContactTransaction mode);
	tOLAError (*complete_transaction)(const uint8_t *authorResponseCode, const uint8_t *issuerAuthenticationData, uint8_t issuerAuthenticationData_length);
	void  (*clean)(void);
} ola_contact_implem_t;

typedef struct {
	void (*flush_aid_supported)(void);
	tOLAError (*add_aid_supported)(const uint8_t *aid, uint8_t aidLength, int partial, uint8_t kernelId, const uint8_t *tlv, uint16_t tlvLength);
	uint16_t (*add_drl_supported)(const uint8_t *programId, uint8_t programIdLength, const uint8_t *transactionLimit, const uint8_t *floorLimit, const uint8_t *CVMLimit, int statusCheck, int isZeroAllowed, uint8_t kernelId);
	void (*commit_supported_aids)(void);
	uint16_t (*build_candidate_list)(uint8_t *nb_candidates);
	uint16_t (*get_tag_from_candidate)(uint8_t candidate, uint32_t tag, uint8_t *value, uint16_t *length);
	tOLAError (*final_select_candidate)(uint8_t candidate, uint8_t *kernelId);
	tOLAError (*get_card_preferred_language)(char *language);
	tOLAError (*preprocess)(void);
	tOLAError (*do_transaction)(void);
	void (*clean)(void);
	tOLAError (*get_outcome)(tOlaOutcomeParameter *outcome);
	tOLAError (*get_UI_request_upon_outcome)(tOlaUIRequest *uiRequest);
	tOLAError (*get_UI_request_restart)(tOlaUIRequest *uiRequest);
} ola_contactless_implem_t;

typedef struct {
	tOLAError (*set_tag)(uint32_t tag, uint8_t *value, uint16_t length);
	tOLAError (*get_tag)(uint32_t tag, uint8_t *value, uint16_t *length);
	tOLAError (*get_cvm_results)(tOlaEMVCoCVM *cvm);
} ola_emv_implem_t;

typedef struct {
	void (*flush)(void);
	tOLAError (*add)(const tOlaPubKey *key, const uint8_t *checksum);
	tOLAError (*find)(tOlaPubKey *key, uint8_t *checksum);
	tOLAError (*get_next_id)(uint8_t *idx, uint8_t *rid, int start);
	tOLAError (*commit)(void);
} ola_publickey_implem_t;

typedef struct {
	ola_contact_implem_t contact;
	ola_contactless_implem_t contactless;
	ola_emv_implem_t emv;
	ola_publickey_implem_t publickey;
} ola_implem_t;


#endif /* OLA_IMPLEM_H_ */

ola.h

Code Block
breakoutModefull-width
languagec
// NAME.......  ola.h
// PURPOSE....  OLA Interface main header. Level 2 Abstraction Layer for Public Keys to be used by the external world (Level 3 application)
// PROJECT....  Arkos Payment Solution
// REFERENCES.	--
//
//
// Copyright 2005-2020 - 9164-4187 QUEBEC INC (AMADIS), All Rights Reserved
//

#ifndef _OLA_H_
#define _OLA_H_

#ifdef __cplusplus
extern "C" {
#endif

//---------------------------------------------------------
//			Includes
//---------------------------------------------------------

#include "ola_tags_dictionary.h" /// Generic Public Key configuration API
#include "ola_emv.h" /// Generic EMV API
#include "ola_publickey.h" /// Generic Public Key configuration API
#include "ola_contactless.h" /// Generic Contacless Processing API
#include "ola_contact.h" /// Generic Contact Processing API

//---------------------------------------------------------
//			Definitions
//---------------------------------------------------------

typedef void (*logf_function)(char* str);

//---------------------------------------------------------
//			Primitives
//---------------------------------------------------------

/// Version of the OLA API
/// No compatibility between 1.x and 2.x versions
#define OLA_API_VERSION "2.1.5"

/**
 * @brief Get the current version of the OLA Api
 * @return Pointer to a string representation of the API version
 */
const char *ola_get_api_version(void);

/**
 * @brief Get the current version of the OLA Implementation
 * @return Pointer to a string representation of the API implementation
 */
const char *ola_get_implementation_version(void);

/**
 * @brief Initialize OLA implementation
 * @param[in] tag: tag objects containing specific tags for a specific L2 stack
 * @param[in] value: data objects length
 * @return value in:
 * 		- OLA_EMV_OK
 * 		- OLA_PARAM_ERROR: invalid input parameters
 */
tOLAError ola_initialize_at_start_up(const uint8_t *tlv, uint16_t tlvLength);

/**
 * @brief Initialize trace function
 * @return void
 */
void ola_set_trace_function(logf_function fct);

#ifdef __cplusplus
}
#endif

#endif

ola_emv.h

Code Block
breakoutModefull-width
languagec
// NAME.......  ola_emv.h
// PURPOSE....  Level 2 Abstraction Layer for EMV primitives to be used by the external world (Level 3 application)
// PROJECT....  Arkos Payment Solution
// REFERENCES.	--
//
//
// Copyright 2005-2020 - 9164-4187 QUEBEC INC (AMADIS), All Rights Reserved
//

#ifndef OLA_EMV_H
#define OLA_EMV_H

//---------------------------------------------------------
//			Includes
//---------------------------------------------------------

#include <stdint.h>

//---------------------------------------------------------
//			Definitions
//---------------------------------------------------------

typedef enum
{
	OLA_OK,
	OLA_CARD_MUTE,
	OLA_CARD_BLOCKED,
	OLA_MAX_REACHED,
	OLA_NO_CANDIDATE,
	OLA_CONTACT_NEW_SELECTION,
	OLA_CONTACT_SELECTION_ERROR,
	OLA_CONDITIONS_NOT_SATISFIED,
	OLA_ACCEPTED,
	OLA_NOT_ACCEPTED,
	OLA_OFFLINE_ACCEPTED,
	OLA_OFFLINE_DECLINED,
	OLA_GO_ONLINE,
	OLA_DECLINED,
	OLA_MISSING_DATA,
	OLA_PINPAD_ERROR,
	OLA_PARAM_ERROR,
	OLA_NOT_IMPLEMENTED,
	OLA_ERROR,
	OLA_CARD_ERROR,
	OLA_CANCEL,
	OLA_PUBLIC_KEY_OK,
	OLA_PUBLIC_KEY_MISSING,
	OLA_PUBLIC_KEY_MAX_REACHED,
	OLA_PUBLIC_KEY_END,
	OLA_PUBLIC_KEY_ERROR,
	OLA_CARD_REMOVED
} tOLAError;

typedef enum
{
    cvmNone,
    cvmNoCvm,
    cvmSignature,
    cvmOnlinePin,
    cvmOnlinePin_Signature,
    cvmOfflinePinPlaintext,
    cvmOfflinePinPlaintext_Signature,
    cvmOfflinePinCiphered,
    cvmOfflinePinCiphered_Signature
} tOlaEMVCoCVM;

//---------------------------------------------------------
//			Primitives
//---------------------------------------------------------

/**
 * @brief Set a tag in L2 stack
 * @param[in] tag: tag to set
 * @param[in] value: tag's value
 * @param[in] length: tag's length
 * @return value in:
 * 		- OLA_EMV_OK
 * 		- OLA_OLA_ERROR: invalid processing path execution
 * 		- OLA_EMV_PARAM_ERROR: invalid input parameters
 */
tOLAError ola_emv_set_tag(
	uint32_t tag,
    uint8_t *value,
    uint16_t length
);

/**
 * @brief Get a tag from L2 stack
 * @param[in] tag: tag to set
 * @param[out] value: tag's value
 * @param[out] length: tag's length
 * @return value in:
 * 		- OLA_EMV_OK
 * 		- OLA_EMV_MISSING_DATA: tag not present
 * 		- OLA_NOT_IMPLEMENTED: tag read not supported
 * 		- OLA_EMV_PARAM_ERROR: invalid input parameters
 */
tOLAError ola_emv_get_tag(
	uint32_t tag,
    uint8_t *value,
    uint16_t *length
);

/**
 * @brief Get CVM result from tag 9F34's byte 1 interpretation
 * @param[out] cvm: cvm result
 * @return value in:
 * 		- OLA_EMV_OK
 * 		- OLA_ERROR: invalid processing path execution
 * 		- OLA_PARAM_ERROR: invalid input parameters
 */
tOLAError ola_emv_get_cvm_results(
	tOlaEMVCoCVM *cvm
);


#endif /* OLA_EMV_H */

ola_contact.h

Code Block
breakoutModefull-width
languagec
// NAME.......  ola_contact.h
// PURPOSE....  Level 2 Abstraction Layer for EMV contact
//              to be used by the external world (Level 3 application)
// PROJECT....  Arkos Payment Solution
// REFERENCES.	--
//
//
// Copyright 2005-2020 - 9164-4187 QUEBEC INC (AMADIS), All Rights Reserved
//

#ifndef OLA_CONTACT_H
#define OLA_CONTACT_H

//---------------------------------------------------------
//			Includes
//---------------------------------------------------------

#include "ola_emv.h"
#include <stdint.h>

//---------------------------------------------------------
//			Definitions
//---------------------------------------------------------

typedef enum
{
    metUndef = 0,
    metFull,
    metExtractPAN,
    metUnknown
} tOlaModeContactTransaction;

//---------------------------------------------------------
//			Primitives
//---------------------------------------------------------

/**
 * @brief Erase all AID supported from configuration
 * @return void
 */
void ola_contact_flush_aid_supported(void);

/**
 * @brief Add one AID supported to configuration. Must be called before ola_emv_build_candidate_list()
 * @param[in] reader: reader's name
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_CARD_MUTE
 * 		- OLA_PARAM_ERROR: invalid input parameters
 */
tOLAError ola_contact_answer_to_reset(const char* reader);

/**
 * @brief Add one AID supported to configuration. Must be called before ola_emv_build_candidate_list()
 * @param[in] aid: AID, max 16 bytes
 * @param[in] aidLength: length of the AID
 * @param[in] partial: allow partial selection with this AID when building candidate list; 0 is false, else is true
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_MAX_REACHED
 * 		- OLA_PARAM_ERROR
 */
tOLAError  ola_contact_add_aid_supported(
		const uint8_t *aid,
	    uint8_t aidLength,
		int partial
);

/**
 * @brief Build the mutual list of common AID between the card and the terminal's configuration
 * @param[out] nb_candidates: number of candidates in the mutual list
 * @param[out] pse: tell whether pse has been used; 0 is false, 1 is true
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_NO_CANDIDATE
 * 		- OLA_CARD_BLOCKED
 * 		- OLA_PARAM_ERROR
 */
tOLAError ola_contact_build_candidate_list(
		uint8_t *nb_candidates,
	    int *pse
);

/**
 * @brief Get a tag from a candidate in the candidate list. Must be called after ola_emv_build_candidate_list()
 * @param[in] candidate: an application in candidate list, value must be from 1 to nb_candidates
 * @param[in] tag: tag to fetch, located in FCI
 * @param[out] value: tag's value
 * @param[out] length: tag's length
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_MISSING_DATA
 * 		- OLA_ERROR
 * 		- OLA_PARAM_ERROR
 */
tOLAError ola_contact_get_tag_from_candidate(
		uint8_t candidate,
	    uint32_t tag,
		uint8_t *value,
	    uint16_t *length
);

/**
 * @brief Send the final select to the card for a candidate in the candidate list
 * @param[in] candidate: an application in candidate list, value must be from 1 to nb_candidates
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_ERROR
 * 		- OLA_PARAM_ERROR
 */
tOLAError ola_contact_final_select_candidate(
		uint8_t candidate
);

/**
 * @brief Initiate an EMV transaction after the AID is selected and configured (first step is building the PDOL and sending the GPO command)
 * @param[in] mode: when value is metExtractPAN, it will stop after READ RECORDS step and will end card dialog in sending GENAC with AAC
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_MSSING_DATA
 * 		- OLA_GO_ONLINE
 * 		- OLA_OFFLINE_ACCEPTED
 * 		- OLA_OFFLINE_DECLINED
 * 		- OLA_NOT_ACCEPTED
 * 		- OLA_CONTACT_NEW_SELECTION
 * 		- OLA_CONTACT_SELECTION_ERROR
 * 		- OLA_CANCEL
 * 		- OLA_ERROR
 * 		- OLA_PARAM_ERROR
 */
tOLAError ola_contact_initiate_transaction(
		tOlaModeContactTransaction mode
);

/**
 * @brief Complete an EMV transaction after going online (or trying and being unable)
 * If there is any EMV script from the issuer, ola_emv_set_tag() with tag 71 or 72 must be used before calling this function
 * @param[in] authorResponseCode: two ASCII bytes (as tag 8A) (NULL pointer when unable to go online)
 * @param[in] issuerAuthenticationData: buffer with the value received (as tag 91) (NULL pointer if there is no value received)
 * @param[in] issuerAuthenticationData_length: from 8 to 16 (0 if there is no value received)
 * @return value in:
 * 		- OLA_ACCEPTED
 * 		- OLA_DECLINED
 * 		- OLA_NOT_ACCEPTED
 * 		- OLA_ERROR
 * 		- OLA_PARAM_ERROR
 */
tOLAError ola_contact_complete_transaction(
		const uint8_t *authorResponseCode,
	    const uint8_t *issuerAuthenticationData,
	    uint8_t issuerAuthenticationData_length
);

/**
 * @brief Release all internal states
 * @return void
 */
void  ola_contact_clean(void);

#endif /* OLA_CONTACT_H */

ola_ contactless.h

Code Block
breakoutModefull-width
languagec
// NAME.......  ola_contactless.h
// PURPOSE....  Level 2 Abstraction Layer for contactless to be used by the external world (Level 3 application)
// PROJECT....  Arkos Payment Solution
// REFERENCES.	--
//
//
// Copyright 2005-2020 - 9164-4187 QUEBEC INC (AMADIS), All Rights Reserved
//

#ifndef OLA_CONTACTLESS_H
#define OLA_CONTACTLESS_H

//---------------------------------------------------------
//			Includes
//---------------------------------------------------------

#include "ola_emv.h"
#include <stdint.h>

//---------------------------------------------------------
//			Definitions
//---------------------------------------------------------

#define OLA_KERNEL_ID_MASTERCARD                    2
#define OLA_KERNEL_ID_VISA                          3
#define OLA_KERNEL_ID_AMEX                          4
#define OLA_KERNEL_ID_JCB                           5
#define OLA_KERNEL_ID_DISCOVER                      6
#define OLA_KERNEL_ID_CUP                           7

#define OLA_MSD_ID_APPROVED                         0x03
#define OLA_MSD_ID_NOT_AUTHORISED                   0x07
#define OLA_MSD_ID_PLEASE_INSERT_OR_SWIPE_CARD      0x18
#define OLA_MSD_ID_AUTHORISING_PLEASE_WAIT          0x1B
#define OLA_MSD_ID_INSERT_SWIPE_OR_TRY_ANOTHER_CARD 0x1C
#define OLA_MSD_ID_SEE_PHONE_FOR_INSTRUCTIONS       0x20

typedef enum
{
	ctsNone,
	ctsPreprocess,
	ctsBuildCandidate,
	ctsFinalSelect,
	ctsActivate
} tOlaContactlessTransactionStep;

// Outcome definition based on EMV Co Books A and B
typedef enum
{
	outcNone,
	outcSelectNext,
	outcTryAgain,
	outcApproved,
	outcDeclined,
	outcOnlineRequest,
	outcTryAnotherInterface,
	outcEndApplication
} tOlaOutcome;

typedef enum
{
	spNoStart,
	spStartA,
	spStartB,
	spStartC,
	spStartD,
} tOlaStartPoint;

typedef enum
{
	ordNone,
	ordEmv,
	ordAny
} tOlaOnlineResponseData;

typedef enum
{
	aipNone,
	aipContactChip,
	aipMagneticStripe
} tOlaAlternateInterfacePreference;

typedef enum
{
	cvmclNone,
	cvmclNoCvm,
	cvmclSignature,
	cvmclOnlinePin,
	cvmclConfirmationCodeVerified
} tOlaCVMethodContactless;

typedef enum
{
	staNone,
	staNotReady,
	staIdle,
	staReadyToRead,
	staProcessing,
	staCardReadSuccessfully,
	staProcessingError
} tOlaStatus;

typedef enum
{
	vqNone,
	vqAmount,
	vqBalance
} tOlaValueQualifier;

typedef struct
{
	tOlaOutcome outCome;
	tOlaStartPoint startingPoint;
	tOlaOnlineResponseData onlineResponseData;
	tOlaCVMethodContactless cvm;
	int UIReqOnOutcomePresent;
	int UIReqOnRestartPresent;
	int receipt;
	int dataRecordPresent;
	int discretionaryDataPresent;
	tOlaAlternateInterfacePreference alternateInterfacePreference;
	uint32_t fieldOffReq;
	uint32_t removalTimeout;
} tOlaOutcomeParameter;

// User Interface Request definition based on EMV Co Books A and B
typedef struct
{
	uint8_t messageIdentifier;
	tOlaStatus status;
	uint32_t holdTime;
	uint8_t languagePreference[8];  // List of languages, ISO 639-1 representation
	tOlaValueQualifier valueQualifier;
	uint8_t value[6];               // BCD
	uint8_t currencyCode[2];        // Numeric ISO 4217
} tOlaUIRequest;

//---------------------------------------------------------
//			Primitives
//---------------------------------------------------------

/**
 * @brief Erase all AID supported from configuration
 * @return void
 */
void ola_contactless_flush_aid_supported(void);

/**
 * @brief Add one AID supported to configuration. Must be called before ola_contactless_preprocess()
 * @param[in] aid: AID, max 16 bytes
 * @param[in] aidLength: length of the AID
 * @param[in] partial: allow partial selection with this AID when building candidate list; 0 is false, else is true
 * @param[in] kernelId: on one byte, identifies the kernel to be used when selected later
 * @param[in] tlv: combination
 * @param[in] tlvLength: combination's length
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_MAX_REACHED: max aid reached
 * 		- OLA_MISSING_DATA:
 * 		- OLA_PARAM_ERROR: invalid input parameters
 */
tOLAError ola_contactless_add_aid_supported(
        const uint8_t *aid,
        uint8_t aidLength,
        int partial,
        uint8_t kernelId,
        const uint8_t *tlv,
        uint16_t tlvLength
);

/**
 * @brief Add one DRL (Dynamic Reader Limit) supported to configuration
 * @param[in] programId: Program ID, max 16 bytes (one byte for XPressPay)
 * @param[in] programIdLength: Program ID's length
 * @param[in] transactionLimit: contactless transaction limit, 6 bytes BCD (NULL pointer if there is no value)
 * @param[in] floorLimit: contactless floor limit, 6 bytes BCD (NULL pointer if there is no value)
 * @param[in] CVMLimit: contactless CVM limit, 6 bytes BCD (NULL pointer if there is no value)
 * @param[in] statusCheck: for PayWave only: allow status check; 0 is false, else is true
 * @param[in] isZeroAllowed: for PayWave only: allow zero amount;  0 is false, else is true
 * @param[in] kernelId: on one byte, identifies the kernel using the DRL; it can be 3 (PayWave) or 4 (XPressPay)
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_MAX_REACHED:
 * 		- OLA_MISSING_DATA:
 * 		- OLA_PARAM_ERROR: invalid input parameters
 * 		- OLA_NOT_IMPLEMENTED: service not implemented
 */
uint16_t ola_contactless_add_drl_supported(
        const uint8_t *programId,
        uint8_t programIdLength,
        const uint8_t *transactionLimit,
        const uint8_t *floorLimit,
        const uint8_t *CVMLimit,
        int statusCheck,
        int isZeroAllowed,
        uint8_t kernelId
);

/**
 * @brief Commit AID, combinations and DRL supported in configuration
 * @return value in:
 * 		- OLA__OK
 * 		- OLA_NOT_IMPLEMENTED: service not implemented
 */
void ola_contactless_commit_supported_aids(void);

/**
 * @brief Build the candidate list of common AID between the card and the configuration in order of priority
 * @param[out] nb_candidates: number of candidates in the list
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_NO_CANDIDATE:
 * 		- OLA_CARD_ERROR:
 * 		- OLA_NOT_IMPLEMENTED: service not implemented
 */
uint16_t ola_contactless_build_candidate_list(
        uint8_t *nb_candidates
);

/**
 * @brief Get a tag from a candidate in the candidate list. Must be called after ola_contactless_build_candidate_list()
 * @param[in] candidate: occurrence in candidates list, value must between 1 and nb_candidates
 * @param[in] tag:
 * @param[out] value: tag's value
 * @param[out] length: value's length
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_MISSING_DATA:
 * 		- OLA_CARD_ERROR:
 * 		- OLA_PARAM_ERROR:
 */
uint16_t ola_contactless_get_tag_from_candidate(
        uint8_t candidate,
        uint32_t tag,
        uint8_t *value,
        uint16_t *length
);

/**
 * @brief Send the final select to the card for a candidate in the candidate list
 * @param[in] candidate: an occurrence in candidate list, value must be from 1 to nb_candidates
 * @param[out] kernelId: the kernel Id that will be activated for this candidate
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_CARD_BLOCKED
 * 		- OLA_CARD_ERROR
 * 		- OLA_PARAM_ERROR
 */
tOLAError ola_contactless_final_select_candidate(
        uint8_t candidate,
        uint8_t *kernelId
);

/**
 * @brief Get the preference language for the card holder. It's the first match between the
 * card preferred languages list and terminal languages supported, or, when this match does
 * not occur, the first occurrence of terminal languages supported
 * @param[out] language: preference language in ISO 639-1 format (two ASCII character)
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_NOT_IMPLEMENTED
 */
tOLAError ola_contactless_get_card_preferred_language(
        char *language
);

/**
 * @brief Perform preprocessing
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_USE_CONTACT
 * 		- OLA_NOT_IMPLEMENTED
 */
tOLAError ola_contactless_preprocess(void);

/**
 * @brief Perform transaction
 * @return value in:
 * 		- OLA_GO_ONLINE
 * 		- OLA_OFFLINE_ACCEPTED
 * 		- OLA_OFFLINE_DECLINED
 * 		- OLA_SEE_PHONE
 * 		- OLA_USE_CONTACT
 * 		- OLA_USE_OTHER_CARD
 * 		- OLA_CONDITIONS_NOT_SATISFIED
 * 		- OLA_NO_RESPONSE
 * 		- OLA_CARD_ERROR
 */
tOLAError ola_contactless_do_transaction(void);

/**
 * @brief Release all internal states
 * @return void
 */
void  ola_contactless_clean(void);

/**
 * @brief Get the outcome from the transaction context. Values based on EMV Co Book A Annex B (standards outcomes),
 * or as specified elsewhere in Book B (for entry point outcome), or in Books C (specifics for different schemes)
 * @param[out] outcome: outcome parameter structure
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_PARAM_ERROR: invalid input parameters
 */
tOLAError ola_contactless_get_outcome(
        tOlaOutcomeParameter *outcome
);

/**
 * @brief Get the UI request on outcome from the contactless transaction context
 * @param[out] uiRequest: UI request parameter structure
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_PARAM_ERROR: invalid input parameters
 */
tOLAError ola_contactless_get_UI_request_upon_outcome(
        tOlaUIRequest *uiRequest
);

/**
 * @brief Get the UI request on restart from the contactless transaction context
 * @param[out] uiRequest: UI request parameter structure
 * @return value in:
 * 		- OLA_OK
 * 		- OLA_PARAM_ERROR: invalid input parameters
 */
tOLAError ola_contactless_get_UI_request_restart(
        tOlaUIRequest *uiRequest
);

#endif /* OLA_CONTACTLESS_H */

ola_ publickey.h

...

breakoutModefull-width
languagec

...

Table of Contents

Introduction

Open L2 API (OLA) is a programmable interface normalizing card processing (L2) services required by a payment application (L3).

Important: this interface has been designed from a Nexo Fast perspective. OLA is a global initiative aiming to cover a missing key element in the payment ecosystem: the EMV L2 API. However, OLA is generic enough to support any kind of payment dynamic beyond Nexo implementations.

Principles

Interacting with a L2 stack is based a simple principles:

  1. Set pre-conditions

  2. Initiate transaction

  3. Eventually, complete transaction

  4. Get post-conditions

Setting pre-conditionsconsists in pushing EMV parameters fecthed from a TMS to the L2 stacks. This step depends on the payment application implementation and the selection process that occurs during stage of the transaction.

Initiating and completing a transaction is about delegating the card processing to the L2 stack. It triggers a behavior that has been L2 certified and granted with a LoA. It is based on the configuration parameters previously pushed.

Getting post-conditionsconsists in gathering a series of information to be able to provide a final outcome for the transaction.

Hypothesis: a payment application (L3) controls the polling of the technologies, implements a specific region EMV application .selection mechanism (if needed), and owns the configuration (fetched from its TMS). Card processing (L2) is global, and only depends on an ICS that is aligned on merchant’s requirements. Consequently:

  • A payment application detects whether a contact or contactless application will be triggerred

  • A payment application implements the logic to select a final application based on OLA services

  • A payment application configures the EMV parameters based on the final selection

Architecture

OLA aims:

  • To break dependencies between different integration levels and L2 implementations

  • To fill the gap between different objectives of testability (usually dependent on the context of integration)

  • To normalize L2 API beyond certificatibility objectives

Image Added

API

See Developer's Guide for more details on OLA API.

Interface

Description

ola_implem.h

This interface presents callback structures to integrate OLA with a minimum zero dependency from platform

ola.h

This interface presents different administrative services

ola_emv.h

This interface presents common services required to support contact and contactless card processing

ola_publickey.h

This interface allows a payment application to intialize a L2 stack with a set of public keys required to execute an EMV transaction flow (contact and contactless)

ola_contact.h

This interface is meant to support contact transaction flow

ola_contactless.h

This interface is meant to support contactless transaction flow

ola_tags_dictionary.h

This header lists all the tags that are specific to Nexo Fast and consequently subject to a translation for further indexation in the L2 stack

ola_terminal.h

Deprecated from OLA 2.x versions