Amadis

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Current »

It might be required in some cases (when using an external Entry Point for example) to call Agnos only after SELECT PPSE and FINAL SELECT have been performed. Agnos is capable of handling such a scenario. Below the steps to perform (once the application selection was made).

image-20241008-202026.png

Transaction Execution

 The following Steps shall be executed for each Transaction.

The codes samples below are written in C but can be transposed to Java using the Ola, OlaContactless classes.

Step 1

Each transaction must begin with a call to ola_contactless_flush_aid_supported().

Step 2

Transaction Related Data (TRD) must be passed to OLA using ola_emv_set_tag() for each TRD data elements (i.e., Transaction Type '9C', Transaction Date '9A', Transaction Time '9F21', Authorized Amount '9F02', Other Amount '9F03',...).

Ex:

ola_emv_set_tag(0x9C, “\x00”, 1);
ola_emv_set_tag(0x9A, “\x23\x05\x18”, 3);
… 

Step 3

Pass the FCI returned by the FINAL SELECT ‘6F’ using ola_emv_set_tag()

Ex:

uint8_t fci[] = {
        0x6F,0x3F,0x84,0x08,0xA0,0x00,0x00,0x00,0x25,0x01,
        0x04,0x03,0xA5,0x33,0x50,0x10,0x50,0x65,0x72,0x73,
        0x6F,0x6E,0x61,0x6C,0x20,0x41,0x63,0x63,0x6F,0x75,
        0x6E,0x74,0x5F,0x2D,0x04,0x45,0x4E,0x46,0x52,0x9F,
        0x38,0x14,0x9F,0x6E,0x04,0x9F,0x35,0x01,0x9F,0x37,
        0x04,0x95,0x05,0x9F,0x34,0x03,0x9F,0x02,0x06,0x9F,
        0x03,0x06,0x87,0x01,0x01
};

ola_emv_set_tag(0x6F, fci, sizeof(fci));

Step 4

Pass the Kernel ID of the Kernel to activate with Tag ‘9F2A’ using ola_emv_set_tag().

Ex:

ola_emv_set_tag(0x9F2A, 0x04, 1); 

Step 5

Set Configuration Data of Selected Candidate (Reader Combination) for the transaction using ola_contactless_add_aid_supported().

Only the configuration data for the Selected AID/Kernel ID is required.

Sample Configurations for each Kernels are listed below.

Ex:

ola_contactless_add_aid_supported(aid, sizeof(aid), partial_selection_indicator, kernel_id, cfg_data, sizeof(cfg_data));

Step 6

Execution the Transaction using ola_contacless_do_transaction().

Step 7

Get Outcome Parameters, UI Request Messages and retrieval of Authorization Data Elements

The outcome parameters can be fetched using ola_contactless_get_outcome().

Ex:

tOlaOutcomeParameter outcome;
ola_contactless_get_outcome(&outcome);

The format of tOlaOutcomeParameter can be found in ola_contactless.h along values for each parameter. If the Outcome Parameters indicate the presence of a UI Request Message on Outcome, this latter can be fetched using ola_contactless_get_UI_request_upon_outcome().

Ex:

tOlaUIRequest uireq;

if (outcome.UIReqOnOutcomePresent) {

        ola_contactless_get_UI_request_upon_outcome(&uireq);
}

The format of tOlaUIRequest can be found in ola_contactless.h along values for each parameter.

If the Outcome Parameters indicate the presence of a UI Request Message on Restart, this latter can be fetched using ola_contactless_get_UI_request_restart().

Ex:

tOlaUIRequest uireq;

if (outcome.UIReqOnRestartPresent) {

        ola_contactless_get_UI_request_restart(&uireq);
}

Data Elements required by Issuers for building Authorization Message can be retrieved using ola_emv_get_tag() for each Data Element.

Ex:

uint8_t un[4];
uint8_t pan[10];
uint16_t len;

ola_emv_get_tag(0x9F37, un, &len);
ola_emv_get_tag(0x5A, pan, &len);
…

Step 8

It is important calling the function ola_contacless_clean() once the Transaction is completed.

Exemple

Below an exemple of how to perform a transaction with an external EntryPoint :

private fun performTransaction() {

    //Mock data of the SelectPPSE and FinalSelect from the external EP
    val selectPPSE = byteArrayOf(0x00, 0xA4.toByte(), 0x04, 0x00, 0x0e, 0x32, 0x50, 0x41, 0x59, 0x2e, 0x53, 0x59, 0x53, 0x2e, 0x44, 0x44, 0x46, 0x30, 0x31, 0x00)
    val selectFinal = byteArrayOf(0x00, 0xA4.toByte(), 0x04, 0x00, 0x07, 0xA0.toByte(), 0x00, 0x00, 0x00, 0x03, 0x10, 0x10, 0x00)

    // Beginning of transaction (card detection, SELECT PPSE, SELECT FINAL)
    if (detectCard(60) != 2) {

        Log.e("MainActivity", "performTransaction - error while detecting card")
        return
    }

    if (sendApdu(selectPPSE) == null) {

        Log.e("MainActivity", "performTransaction - error while sending SELECT PPSE")
        return
    }

    val fci = sendApdu(selectFinal)
    if (fci == null ){

        Log.e("MainActivity", "performTransaction - error while sending SELECT FINAL")
        return
    }

    // Step 1 - Clean SDK context
    //agnos.olaContactlessPreprocess()
    agnos.olaContactlessFlushAIDSupported()

    // Step 2 - Set Transaction Related Data
    val now = LocalDateTime.now()
    agnos.olaEmvSetTag(OlaTag.TRANSACTION_DATE, Utils.bcdDate(now))
    agnos.olaEmvSetTag(OlaTag.TRANSACTION_TIME, Utils.bcdTime(now))

    val ccy = Currency.getInstance(Locale.getDefault())
    agnos.olaEmvSetTag(OlaTag.AMOUNT_AUTHORISED, Utils.bcdAmount(100)) // 1.00$
    agnos.olaEmvSetTag(OlaTag.TRANSACTION_CURRENCY_CODE, Utils.ccyCode(ccy))
    agnos.olaEmvSetTag(OlaTag.TRANSACTION_CURRENCY_EXPONENT, Utils.ccyExponent(ccy))

    agnos.olaEmvSetTag(OlaTag.TRANSACTION_TYPE, byteArrayOf(0x00))
    agnos.olaEmvSetTag(OlaTag.TRANSACTION_CATEGORY_CODE, byteArrayOf(0x11))

    // Step 3 - Pass FCI to SDK context
    agnos.olaEmvSetTag(fci[0].toInt(), fci.copyOfRange(2, fci.size - 2))

    // Step 4 - Set kernel ID (only using Visa with this example)
    agnos.olaEmvSetTag(0x9F2A, byteArrayOf(0x03))

    // Step 5 - Set AID data
    agnos.olaContactlessAddAIDSupported(ConfigData.products[4].AID(),
        ConfigData.products[4].partial,
        ConfigData.products[4].kernel.kernelId,
        ConfigData.products[4].kernel.config())

    var tcc = Holders.SingleObjectHolder<ByteArray>()
    val err = agnos.olaEmvGetTag(OlaTag.TRANSACTION_CURRENCY_CODE, tcc)

    // Step 6 - Perform reste of transaction
    agnos.olaContactlessDoTransaction()

    var tcc2 = Holders.SingleObjectHolder<ByteArray>()
    val err2 = agnos.olaEmvGetTag(OlaTag.TRANSACTION_CURRENCY_CODE, tcc2)

    // Step 7 - Get results
    var outcome = Holders.SingleObjectHolder<OlaOutcomeParameter>()
    agnos.olaContactlessGetOutcome(outcome)

    var tcc3 = Holders.SingleObjectHolder<ByteArray>()
    val err3 = agnos.olaEmvGetTag(OlaTag.TRANSACTION_CURRENCY_CODE, tcc3)
    Log.v("MainActivity", "performTransaction - result for getTag(): $err3 => " +
            Utils.bytesToHex(tcc3.get()))

    Log.v("MainActivity", "performTransaction - transaction complete")
}

  • No labels