Bank App Protocol

1. Sale

Following code snippet is used by PaymentGateway in order to open payment application:

       	Intent IntentCard = new Intent();
		IntentCard.setPackage(tag);
		IntentCard.setAction(getResources().getString(R.string.Sale_Action)); //Sale_Action="Sale_Action"
        Bundle bundle_card = new Bundle();
		bundle_card.putInt("Amount",amount);
        bundle_card.putInt("CardReadType",cardReadType);
        bundle_card.putString("CardData",cardData); 
        bundle_card.putString("UUID",uuid); 
		bundle_card.putInt("allowedCardType",allowedCardType);
		bundle_card.putInt("isGIBTerminal",isGIBTerminal);
        IntentCard.setType("text/plain");
        IntentCard.putExtras(bundle_card);
        startActivityForResult(IntentCard, getResources().getInteger(R.integer.Sale_Request_Code)); //Sale_Request_Code=1

Amount : Integer: Ex: 1.25 TL is written 125

CardReadType :

public enum CardReadType {
    NONE(0),
    ICC(1),
    MSR(2),
    ICC2MSR(3),
    KeyIn(4),
    CLCard(5),
    QrPay(6);
    public final int value;
    CardReadType(int value){
        this.value = value;
    }
}

CardData : It will be set for Contactless and MSR. *** Please refer to "11. Auto Card Routing" section***

allowedCardType : 1:Credit, 2:Debit, 3:Both, 4: International.

UUID: Transactions are kept with this value on Payment Gate Way and bank application in case of a power cut. Payment Gate Way sends this value and waits for the return of the transaction result.

isGIBTerminal : 0:Not GIB Terminal, 1: GIB Terminal

Manifest Modifications

To be able to get data from payment gateway, there should be intent filter like below in related class.

        <activity android:name=".SaleActivity">
            <intent-filter>
                <action android:name="Sale_Action" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="text/plain" />
            </intent-filter>
        </activity>

After the payment process, the payment application should broadcast the result.

   void onSaleResponseRetrieved(Integer price, ResponseCode code, Boolean hasSlip, SlipType slipType, String cardNo, String ownerName) {
        Intent resultIntent = new Intent();
        Bundle bundle = new Bundle();
        bundle.putInt("ResponseCode", code.ordinal());
        bundle.putInt("PaymentStatus",0);
        bundle.putInt("Amount",price);
        bundle.putInt("Amount2", price);        
        bundle.putInt("BatchNo",0);
        bundle.putInt("TxnNo",0);
        bundle.putBoolean("IsSlip", hasSlip);
        bundle.putInt("SlipType", slipType.value);
        bundle.putString("RefundInfo", refound_info); 
        bundle.putString("CardNo", cardNo);
        bundle.putString("TID", terminal_id);
        bundle.putString("MID", merchant_id);	    
        bundle.putString("RefNo", ref_no);
        bundle.putString("AuthNo", auth_no);
       
        if (slipType == SlipType.CARDHOLDER_SLIP || slipType == SlipType.BOTH_SLIPS) {
            bundle.putString("customerSlipData", PrintHelper.getFormattedText(getSampleReceipt(cardNo, ownerName), SlipType.CARDHOLDER_SLIP));
        }
        if (slipType == SlipType.MERCHANT_SLIP || slipType == SlipType.BOTH_SLIPS) {
            bundle.putString("merchantSlipData", PrintHelper.getFormattedText(getSampleReceipt(cardNo, ownerName), SlipType.MERCHANT_SLIP));
        }
        resultIntent.putExtras(bundle);
        setResult(Activity.RESULT_OK,resultIntent);
        finish();
    }

responseCode : Result of the payment process

	enum  RESPONSE_CODE{
        SUCCESS,
        ERROR,
        CANCELLED,
        OFFLINE_DECLINE,
        UNABLE_DECLINE,
        ONLINE_DECLINE
        }

paymentStatus : If discount or surcharge is applied, paymentStatus must be set accordingly.

	enum  RESPONSE_CODE{
        NORMAL,
        DISCOUNTED,
        SURCHARGE // Reserved for future use
        }

amount : Integer. Amount that is charged by the payment application. If amount is less than the Broadcasted Amount by Payment Gateway, it means Partial Limit is applied.

amount2 : Integer. If a discount is made by the payment application, this value should be set according to the amount. Ex: Amount from Payment Gateway : 1000 Amount : 900 Discount Amount : 100

batchNo : It is the current Batch No which includes current sale.

txnNo : It is the current Txn No of the sale in current Batch.

CardNo : Masked Card Number, first eight and last four digit is visible others are masked with '*' 12345678****7890

TID : Terminal ID

MID : Merchant ID

IsSlip: Indicates that if a payment slip will be printed or not. (true to print slip)

SlipType: Value that presents which slip types will be printed.

public enum SlipType {

    NO_SLIP(0),
    MERCHANT_SLIP(1),
    CARDHOLDER_SLIP(2),
    BOTH_SLIPS(3);

    public final int value;

    SlipType(int value) {
        this.value = value;
    }
}

customerSlipData: Formatted String for card holder slip.

merchantSlipData: Formatted String for merchant slip.

Sample Code to Generate Formatted Slip String

public static String getFormattedText(SampleReceipt receipt, SlipType slipType) {
        StyledString styledText = new StyledString();

        styledText.setLineSpacing(0.5f);
        styledText.setFontSize(12);
        styledText.setFontFace(PrinterDefinitions.Font_E.SourceSansPro);
        styledText.addTextToLine(receipt.getMerchantName(), Alignment.Center);

        styledText.newLine();
        styledText.setFontFace(PrinterDefinitions.Font_E.Sans_Semi_Bold);
        styledText.addTextToLine("İŞYERİ NO:", Alignment.Left);
        styledText.setFontFace(PrinterDefinitions.Font_E.SourceSansPro);
        styledText.addTextToLine(receipt.getMerchantID(), Alignment.Right);

        styledText.newLine();
        styledText.setFontFace(PrinterDefinitions.Font_E.Sans_Semi_Bold);
        styledText.addTextToLine("TERMİNAL NO:", Alignment.Left);
        styledText.setFontFace(PrinterDefinitions.Font_E.SourceSansPro);
        styledText.addTextToLine(receipt.getPosID(), Alignment.Right);

        styledText.newLine();
        if (slipType == SlipType.CARDHOLDER_SLIP) {
            styledText.addTextToLine("MÜŞTERİ NÜSHASI", Alignment.Center);
            styledText.newLine();
        }
        else if (slipType == SlipType.MERCHANT_SLIP) {
            styledText.addTextToLine("İŞYERİ NÜSHASI", Alignment.Center);
            styledText.newLine();
        }
        styledText.addTextToLine("SATIŞ", Alignment.Center);

        SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yy HH:mm:ss", Locale.getDefault());
        String time = sdf.format(Calendar.getInstance().getTime());

        styledText.newLine();
        styledText.addTextToLine(time + " " + "C ONLINE", Alignment.Center);

        styledText.newLine();
        styledText.addTextToLine(receipt.getCardNo(), Alignment.Center);

        styledText.newLine();
        styledText.addTextToLine(receipt.getFullName(), Alignment.Center);

        styledText.setLineSpacing(1f);
        styledText.setFontSize(14);
        styledText.setFontFace(PrinterDefinitions.Font_E.Sans_Semi_Bold);
        styledText.newLine();
        styledText.addTextToLine("TUTAR:");
        styledText.addTextToLine(receipt.getAmount(), Alignment.Right);

        styledText.setLineSpacing(0.5f);
        styledText.setFontSize(10);
        styledText.newLine();
        if (slipType == SlipType.CARDHOLDER_SLIP) {
            styledText.addTextToLine("KARŞILIĞI MAL/HİZM ALDIM", Alignment.Center);
        }
        else {
            styledText.addTextToLine("İşlem Şifre Girilerek Yapılmıştır", Alignment.Center);
            styledText.newLine();
            styledText.addTextToLine("İMZAYA GEREK YOKTUR", Alignment.Center);
        }

        styledText.setFontFace(PrinterDefinitions.Font_E.Sans_Bold);
        styledText.setFontSize(12);
        styledText.newLine();
        styledText.addTextToLine("SN: " + "0001");
        styledText.addTextToLine("ONAY KODU: " + "235188", Alignment.Right);

        styledText.setFontSize(8);
        styledText.setFontFace(PrinterDefinitions.Font_E.Sans_Semi_Bold);
        styledText.newLine();
        styledText.addTextToLine("GRUP NO:" + receipt.getGroupNo());

        styledText.newLine();
        styledText.addTextToLine("AID: " + receipt.getAid());

        styledText.newLine();
        styledText.addTextToLine("BU İŞLEM YURT İÇİ KARTLA YAPILMIŞTIR", Alignment.Center);
        styledText.newLine();
        styledText.addTextToLine("BU BELGEYİ SAKLAYINIZ", Alignment.Center);
        styledText.newLine();

        styledText.printBitmap("ykb", 20);
        styledText.addSpace(100);

        return styledText.toString();
    }

Slip Contents According to the Device Operation Mode:

You can receive the Z No and the Receipt No as;

getIntent().getExtras().getString("ZNO");
getIntent().getExtras().getString("ReceiptNo");

2. Pos Transactions

Following code snippet is used by PaymentGateway in order to open payment application:

	Intent sendIntentPosTxn = new Intent();
	sendIntentPosTxn.setPackage(tag);
	sendIntentPosTxn.setAction(getResources().getString(R.string.PosTxn_Action));//PosTxn_Action="PosTxn_Action"
	sendIntentPosTxn.setType("text/plain");
	startActivityForResult(sendIntentPosTxn, getResources().getInteger(R.integer.PosTxn_Request_Code)); //PosTxn_Request_Code=13

Manifest Modifications

To be able to get data from payment gateway, there should be intent filter like below in related class.

        <activity android:name=".PosTxnActivity">
            <intent-filter>
                <action android:name="PosTxn_Action" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="text/plain" />
            </intent-filter>
        </activity>

After the pos transaction process, the payment application should send the result.

	Intent resultIntent = new Intent();
	Bundle bundle = new Bundle();
    bundle.putInt("ResponseCode",responseCode);
    resultIntent.putExtras(bundle);
    setResult(Activity.RESULT_OK,resultIntent); //PosTxn_Request_Code=13
    finish();

responseCode : Return of the pos transaction request.

3. Pos Settings

Following code snippet is used by PaymentGateway in order to open payment application:

	Intent sendIntentSettingsTxn = new Intent();
	sendIntentSettingsTxn.setPackage(tag);
	sendIntentSettingsTxn.setAction(getResources().getString(R.string.Settings_Action)); //Settings_Action="Settings_Action"
	sendIntentSettingsTxn.setType("text/plain");
	startActivityForResult(sendIntentSettingsTxn, getResources().getInteger(R.integer.Settings_Request_Code)); //Settings_Request_Code=24

Manifest Modifications

To be able to get data from payment gateway, there should be intent filter like below in related class.

        <activity android:name=".SettingsActivity">
            <intent-filter>
                <action android:name="Settings_Action" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="text/plain" />
            </intent-filter>
        </activity>

After the pos settings process, the payment application should send the result.

	Intent resultIntent = new Intent();
	Bundle bundle = new Bundle();
	bundle.putInt("ResponseCode",responseCode);
	resultIntent.putExtras(bundle);
	setResult(Activity.RESULT_OK,resultIntent); //Settings_Request_Code=24
	finish();

responseCode : Return of the pos settings request.

4. Batch Close

Following code snippet is used by PaymentGateway in order to open payment application:

	Intent sendIntentPosTxn = new Intent();
	sendIntentPosTxn.setPackage(packages.get(i));
	sendIntentPosTxn.setAction(getResources().getString(R.string.BatchClose_Action)); //BatchClose_Action="BatchClose_Action"
	sendIntentPosTxn.setType("text/plain");
	startActivityForResult(sendIntentPosTxn, getResources().getInteger(R.integer.BatchClose_Request_Code)); //BatchClose_Request_Code=25

Manifest Modifications

To be able to get data from payment gateway, there should be intent filter like below in related class.

        <activity android:name=".BatchCloseActivity">
            <intent-filter>
                <action android:name="BatchClose_Action" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="text/plain" />
            </intent-filter>
        </activity>

After the batch close process, the payment application should send the result.

	Intent resultIntent = new Intent();
	Bundle bundle = new Bundle();
	bundle.putInt("ResponseCode",responseCode);
	resultIntent.putExtras(bundle);
	setResult(Activity.RESULT_OK,resultIntent); //BatchClose_Request_Code=25
	finish();

responseCode : Return of the pos settings request.

5. Parameter

Following code snippet is used by PaymentGateway in order to open payment application:

	Intent sendIntentSettingsTxn = new Intent();
	sendIntentSettingsTxn.setPackage(data.getPackage());
	sendIntentSettingsTxn.setAction(getResources().getString(R.string.Parameter_Action)); //Parameter_Action="Parameter_Action"
	sendIntentSettingsTxn.setType("text/plain");
	startActivityForResult(sendIntentSettingsTxn, getResources().getInteger(R.integer.Parameter_Request_Code)); //Parameter_Request_Code=16

Manifest Modifications

To be able to get data from payment gateway, there should be intent filter like below in related class.

        <activity android:name=".ParameterActivity">
            <intent-filter>
                <action android:name="Parameter_Action" />

                <category android:name="android.intent.category.DEFAULT" />

                <data android:mimeType="text/plain" />
            </intent-filter>
        </activity>

After the batch close process, the payment application should send the result.

	Intent resultIntent = new Intent();
    Bundle bundle = new Bundle();
	bundle.putInt("ResponseCode",responseCode);
	resultIntent.putExtras(bundle);
	setResult(Activity.RESULT_OK,resultIntent); //Parameter_Request_Code=16
	finish();

responseCode : Return of the pos settings request.

6. Power Cut Inquiry

If there has been a power cut during a sale transaction, transaction is inquired after device reboot. In order to receive inquiry and return transaction information, a broadcast receiver must be registered in the Android manifest file with action "check_sale" like below:

<receiver android:name=".receivers.CheckSaleReceiver">
    <intent-filter>
        <action android:name="check_sale" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</receiver>

When inquiry broadcast is received, in the broadcast receiver's onReceive() method, if transaction is successful, transaction info must be returned in a bundle like below.

   @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.hasExtra("UUID")) {
            String uuid = intent.getExtras().getString("UUID");
            ...
                //check if a successful transaction with uuid exists
            ...
            Intent resultIntent = new Intent();
            if (transaction != null) {
                Bundle bundle = new Bundle();
                bundle.putInt("ResponseCode", ResponseCode.SUCCESS.ordinal());
                bundle.putInt("PaymentStatus", 0);
                bundle.putInt("Amount", ...);
                bundle.putInt("Amount2", ...);
                bundle.putString("customerSlipData", ...);
                bundle.putString("merchantSlipData", ...);
                bundle.putInt("BatchNo", ...);
                bundle.putInt("TxnNo", ...);
                bundle.putInt("SlipType", SaleSlipType.BOTH_SLIPS.value);
                bundle.putBoolean("IsSlip", true);
                resultIntent.putExtras(bundle);
            }

            resultIntent.setAction("check_sale_result");
            resultIntent.setPackage("com.tokeninc.sardis.paymentgateway");
            context.sendBroadcast(resultIntent);
        }
    }

If you are using SQLite database to store transactions, you should configure your database to insert record instantly when a transaction completed in case of a power cut scenario. https://www.sqlite.org/pragma.html#pragma_synchronous

To do this, in your SQLiteOpenHelper class, override onConfigure() method and add the following code:

    @Override
    public void onConfigure(SQLiteDatabase db) {
        db.execSQL("PRAGMA synchronous = 2");
    }

Following code snippet is used by PaymentGateway in order to check the payment, if there is a power cut PaymentGateway checks for the last sale result then returns UUID to ask for the result of the last sale status.

registerReceiver(receiver, new IntentFilter("check_sale_result"));
Intent intent = new Intent("check_sale");
intent.setPackage(packageName);
intent.putExtra("UUID", uuid);
sendBroadcast(intent);

7. Void / Refund Flow

Void/Refund transaction is started outside of Bank Application. In order for this to work, bank apps must return Refund Info at the end of a successful sale transaction along with other sale data.

bundle.putInt("BatchNo", ...);
bundle.putInt("TxnNo", ...);
bundle.putInt("Amount2", amount);
...
bundle.putString("RefundInfo", ...);
...

RefundInfo is a string which could be in any format that your bank application could use later in case of a refund. Remember, this info will be used only by regarding Bank's application itself.

For your refund activity to be triggered by platform, register your activity with action named "Refund_Action".

<activity android:name=".activity.refund.RefundActivity">
            <intent-filter>
                <action android:name="Refund_Action" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
            </intent-filter>
</activity>

In case your refund activity is triggered, the same RefundInfo string you returned with sale data will be delivered to you. In your activity, you could retrieve it this way:

//In this case, RefundInfo is a JSON value, but you could use any format you want.
String refundInfo = getIntent().getStringExtra("RefundInfo");
try {
     JSONObject json = new JSONObject(refundInfo);
     batchNo = json.getInt("BatchNo");
     txnNo = json.getInt("TxnNo");
}
//Customer shouldn't need to enter any input about transaction except card information.
//All the other transaction data should be retrieved in RefundInfo string.
//Do the void/refund transaction and return the result:

Intent resultIntent = new Intent();
Bundle bundle = new Bundle();
bundle.putInt("ResponseCode", responseCode.ordinal());
resultIntent.putExtras(bundle);
setResult(Activity.RESULT_OK, resultIntent);
finish();

// Always return activity result "RESULT_OK" with "ResponseCode".
// On Back Press, return activity result "RESULT_CANCELED", platform will consider as "5002", "CANCELED".

@Override
public void onBackPressed() {
    setResult(Activity.RESULT_CANCELED);
    super.onBackPressed();
}

8. Remote Activation

To be able to list your bank application in device, you need to support remote activation system as example given below. Let's say you have an activity to run activation process. For that activity or other ui element, you have to support given intent filter below to run activation process.

<activity android:name=".SettingsActivity" android:launchMode="singleTop">
            <intent-filter>
                <action android:name="Activate_Bank" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
            </intent-filter>
   </activity>

Inside intent bundle, you'll see parameters for use that are merchantID and terminalID as string. It's up to you to use this parameters as it totally depends your design. This will start your activation process remotely. When activation on your app is complete

setResult(Activity.RESULT_OK, yourIntent);
finish()

and yourIntent should contain merchantID and terminalID as string if you're not using parameters coming from device.

If some error occured,

setResult(Activity.RESULT_CANCELED, yourIntent);
finish()

and your intent should contain field "message" to understand and log it.

9. Update Parameters on Active Bank App

If your bank application on same fiscal id has changeable merchantID and terminalID, you have to support given intent filter below to run activation process. Let's say you have an activity to run activation process. For that activity or other ui element,

<activity android:name=".SettingsActivity" android:launchMode="singleTop">
            <intent-filter>
                <action android:name="Update_Parameter" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="text/plain" />
            </intent-filter>
   </activity>

Inside intent bundle, you'll see parameters for use that are merchantID and terminalID as string. It's up to you to use this parameters as it totally depends your design. This will start your terminalID and merchantID update process remotely. When update on your app is complete

setResult(Activity.RESULT_OK, yourIntent);
finish()

and yourIntent should contain merchantID and terminalID as string if you're not using parameters coming from device.

If some error occured,

setResult(Activity.RESULT_CANCELED, yourIntent);
finish()

and your intent should contain field "message" to understand and log it.

10. Manual Bank Activation

Let's say some operator needs to install your application manually and doesn't have a chance to send remote activation process. For that kind of situations, please use function setBankParams at

Important Note: If you don't implement this function, your application can't be activated and it can't seen in atms. Therefore you couldn't see your bank applications on POS transactions and sale menu! You can read Pos Settings on the Template Banking app for more information.

DeviceInfo deviceInfo = new DeviceInfo(context);
deviceInfo.setBankParams(new DeviceInfo.DeviceInfoBankParamsSetterHandler() {
            @Override
            public void onReturn(boolean success) {
                	//Handle result, it might not be written for some case.
					//If it's successfully written, you will get result as true
            }
},"yourTerminalId", "yourMerchantId");

11. Auto Card Routing

The bank that will be include the card forwarding system must share the current EMV Contactless Config file, BIN table, allowed transaction types and supported AID list with the Token platform. Relevant information will be shared with the platform in the response of the parameter command initiated in the Trigger time. CL Config files shared by banks will be combined into a single file and used in the card routing infrastructure. The shared BIN ranges will be added to the BIN table created with the relevant bank's ID, and the shared ranges will be updated at the next trigger by deleting the old BIN ranges.

For detailed documentation:

11.1 Sale

11.1.1 Card Route Flow

11.1.2 Card Read Type & Card Data

ICC

In addition to the amount, the card reading type will be sent to the relevant bank in integer value. The relevant bank will initiate its own card reading processes as it currently uses. In addition, the TCardService API, which is started during card reading, will continue by closing the card reading screen.

amount = getIntent().getExtras().getInt("Amount");
cardReadType = bundle.getInt("CardReadType");

obj.put("showAmount", 1);
if(cardReadType == CardReadType.ICC.value) {
    obj.put("showCardScreen", 0); // Card Screen Closed
}

Contactless

In order to perform "Single Tap" CL transactions, card reading will be done by Token Platform and after validation, the card type and card information provided by TCardService will be forwarded to the relevant bank in String format in the same way. The relevant bank will parse and use the shared card data as they currently use it.

cardReadType = bundle.getInt("CardReadType");

cardData = bundle.getString("CardData");

{
   "resultCode":0,
   "mCardReadType":5,
   "mCardNumber":"4797957003463700",
   "mTrack2Data":"201337001101??",
   "mExpireDate":"250731",
   "mTranAmount1":50000,
   "CardSeqNum":"01",
   "AC":"8D402D28A939C4B3",
   "CID":"80",
   "ATC":"016C",
   "TVR":"0000000000",
   "TSI":"0000",
   "AIP":"2000",
   "CVM":"020000",
   "AID2":"A0000000031010",
   "UN":"FDB2E2AA",
   "IAD":"06011103A000000A010000021094A9129767",
   "OnlPINReq":1,
   "PINCtr":3,
   "SID":23,
   "DateTime":"20210413085810",
   "Track1Data":"%B4797957003463700^ \/^2507201100000000000?f",
   "Track2Data":";4797957003463700=2507201337001101??",
    "ALLEmv":"5A0847979570034637005F2403250731950500000000008407A00000000310109F26088D402D28A939C4B39F2701809F3602016C9B020000820220009F34030200009F3704FDB2E2AA9F101206011103A000000A010000021094A91297675F340101DF8F4F020004DF81290830F0F02090F0FF00DF8115060000000000FFDF2A06000000021094990100",
   "CVMAnalysis":2,
   "TransResult":4
}

MSR

In order to perform "Single Swipe" MSR transactions, card reading will be done by Token Platform and after validation, the card type and card information provided by TCardService will be forwarded to the relevant bank in String format in the same way. The relevant bank will parse and use the shared card data as they currently use it.

cardReadType = bundle.getInt("CardReadType");

cardData = bundle.getString("CardData");

{
   "resultCode":0,
   "mCardReadType":2,
   "mCardNumber":"5168881167113299",
   "mTrack2Data":"1201530011?",				//other than pan and exp date
   "mExpireDate":"2711",
   "mTranAmount1":123,
   "mTrack1CustomerName":"REMZI SEPIK",
   "Track1Data":"%B5168881167113299^SEPIK\/REMZI               ^27111201100000000153000000?",
   "Track2Data":";5168881167113299=27111201530011?"
}

11.2 Card Routing Configuration and Requirements by Bank

11.2.1 Parameter_Action Response Data

Relevant information will be shared with the platform at the end of the parameter action process initiated on the Trigger time. If the current application parameter loading is successful, the Activity Result returns as "RESULT_OK". In unsuccessful cases, it returns as "RESULT_CANCELLED". If parameter loading is successful at the end of the parameter action in the new flow, the bundle containing the necessary information should be added to the Activity Result Intent.

public class ComPosKeys {
    public static final String clConfigFile = "clConfigFile";
    public static final String BINS = "BINS";
    public static final String OwnerShip = "OwnerShip";
    public static final String ISSUER = "ISSUER";
    public static final String NONE = "NONE";
    public static final String BRAND = "BRAND";
    public static final String cardRangeStart = "cardRangeStart";
    public static final String cardRangeEnd = "cardRangeEnd";
    public static final String CardType = "CardType";
    public static final String AllowedOperations = "AllowedOperations";
    public static final String QrAllowed = "QrAllowed";
    public static final String KeyInAllowed = "KeyInAllowed";
    public static final String SupportedAIDs = "SupportedAIDs";
}
setResult(Activity.RESULT_OK, resultIntentMain);

EMV CL File

The CL Config file will be added with the tag "clConfigFile" in String format, as it is also used for the setEMVCLConfig API.

BIN Ranges

BIN Ranges will be shared as a JSON Array constructed with the Start value "cardRangeStart", the End value "cardRangeEnd", the Card property "OwnerShip" and the Card type "CardType". BIN range start and end values will be shared as 13 digits.

Note: NOTONUS BIN's were removed as part of the project. Banks do not need to share NOTONUS BIN ranges. Not-ISSUER and non-BRAND BIN's will be considered as NOTONUS.

    Card Type	
    A- Credit Card,  
    B- Debit Card, 
    C- Acquiring BIN,
    D- Prepaid Card
    Ownership	
	ISSUER,
    NONE,
    BRAND

BIN Bundle Example

Bundle[{BINS=[{"cardRangeStart":"1111110000000","cardRangeEnd":"1111119999999","OwnerShip":"ISSUER","CardType":"C"},{"cardRangeStart":"2222220000000","cardRangeEnd":"2222229999999","OwnerShip":"NONE","CardType":"C"},{"cardRangeStart":"3333330000000","cardRangeEnd":"3333339999999","OwnerShip":"BRAND","CardType":"C"}]

Allowed Operations

Allowed Operations will be added with the "AllowedOperations" tag. The allowed transactions will be added as JSON Object, whether the terminal allows payment with QR or not and whether it allows Key In transactions. It will be indicated with “1” if the operation is allowed, “0” if not.

Allowed Operations Bundle Example

AllowedOperations={"QrAllowed":1,"KeyInAllowed":0}

Supported AIDs

Supported AID information will be added to the same bundle with the "SupportedAIDs" tag and shared as a String Array.

Supported AID Bundle Example

SupportedAIDs=[A0000000031010, A0000000041010, A0000000032010, A0000000043060, A0000006723020]

11.3 Device Info

A "CARD_REDIRECTION" field has been added to the currently used Device Info library to determine whether 400TR and 1000TR devices are included in the card routing system. This parameter will be set via ATMS and it will be possible to determine whether there is a card forwarding compatible device from within the application.

Last updated