Ingenico (RBA) Payloads

The Parser can process payloads from Ingenico RBA devices that produce P2PE payloads. RBA devices include the: iPP 320, iPP 350, iSC 250, iSC Touch 250, and iSC Touch 480. These devices support manual 1) card data entry, 2) magnetic card swipes and 3) contactless card data entry.

Typically, Ingenico terminals are connected to a host computer that runs a Point of Sale (POS) application. The terminal vendor supply software development kits for wide variety of operating systems and development languages on their developers portal. They make it easy for the POS application to obtains data from the payment terminal.

In this guide we include sample code that use Ingenico's Android SDK to extract a P2PE secured payload from an RBA terminal. Ingenico provide similar SDKs in pure Java, Objective-C, and a number of other languages. While the programming languages are different, the software use a similar pattern when extracting data from the terminal. i.e. the SDK/POS sends async commands to the terminal. The commands are sent via an instance of RBA_API class. Other code listens for responses to act upon.

The first step is to identify the device's serial number by sending a Health Check (08) command to the terminal.

//Send the command via the RBA_API object.
ERROR_ID result = RBA_API.ProcessMessage( MESSAGE_ID.M08_HEALTH_STAT );

//check to see if the result of the command was a success or not.
if ( result == ERROR_ID.RESULT_SUCCESS ) {
    logData("Successfully Sent 87 command");
}
else {
    logData("Failed to Send 87 command: Error = " + result);
}

In the listener code we extract the serial number from the response and store it in the serialNumber variable for later use.

final String serialNumber = RBA_API.GetParam(PARAMETER_ID.P08_RES_SERIAL_NUMBER)

Next, send a command to terminal to initialise a card data capture and encryption, an 87 command. The following snippet of Android code updates the terminal text and sends the 87 command to the terminal:

//set the text to appear on the terminal screen.
RBA_API.SetParam( PARAMETER_ID.P87_REQ_PROMPT_INDEX, "Please swipe card." );

//Send the command via the RBA_API object.
ERROR_ID result = RBA_API.ProcessMessage( MESSAGE_ID.M87_E2EE_CARD_READ );

//check to see if the result of the command was a success or not. 
if ( result == ERROR_ID.RESULT_SUCCESS ) {
    logData("Successfully Sent 87 command");
}
else {
    logData("Failed to Send 87 command: Error = " + result);
}

The following code processes the response and extract the payload.

String exitType = RBA_API.GetParam( PARAMETER_ID.P87_RES_EXIT_TYPE );
switch ( Integer.parseInt( exitType ) ) {
    case 0: {
        //Successful read and P2PE encryption
        String source   = RBA_API.GetParam( PARAMETER_ID.P87_RES_CARD_SOURCE );
        String cardData = RBA_API.GetParam( PARAMETER_ID.P87_RES_CARD_DATA   );
        logData( "Card Source = " + source   );
        logData( "Card Data   = " + cardData );
        break;
    }
    case 1:     logData( "Bad Read" );              break;
    case 2:     logData( "Cancelled" );             break;
    case 3:     logData( "Button Pressed" );        break;
    case 7:     logData( "Encryption Failed" );     break;
    case 9:     logData( "Declined" );              break;
    default:    logData( "ERROR" );                 break;
}

The cardData variable contains the payload data that we want to use in our API call.

54152444441612212101912TEST/BLUEFIN1B0B0229000000000000020114334787735642891651=726961371397062832AF86BB9DB92C98416AAB5BCA769D565A96C1E5C07F1D49A912C9919DBD3EA0661DF20CAC633BC330ECF753994278F50F56F7A2CE0C7212BAACFDED1632B98BE3EC8

To use this payload with the Parser, post it with your Bluefin credentials and the device's serial number to our parser endpoint.

curl 'https://cert-parser.decryptx.com/api/v1/decrypt/parser' \
    -X POST \
    --header 'Content-Type: application/json' \
    --header 'Accept: application/json' \
    -d '{
            "partnerId"     : "WATERFORD",
            "partnerKey"    : "ef1ad938150fb15a1384b883a104ce70",
            "reference"     : "723f57e1-e9c8-48cb-81d9-547ad2b76435",
            "deviceType"    : "ingenico-rba",
            "deviceSerial"  : "80612860",
            "devicePayload" : "54152444441612212101912TEST/BLUEFIN1B0B0229000000000000020114334787735642891651=726961371397062832AF86BB9DB92C98416AAB5BCA769D565A96C1E5C07F1D49A912C9919DBD3EA0661DF20CAC633BC330ECF753994278F50F56F7A2CE0C7212BAACFDED1632B98BE3EC8"
        }'

If the API call is successful a JSON response object similar to the following is returned.

{
  "success"   : true,
  "messageId" : "1201703221545061032173045",
  "reference" : "723f57e1-e9c8-48cb-81d9-547ad2b76435",
  "meta": {
    "device" : "INGENICO",
    "serial" : "80612860",
    "mode"   : "swiped"
  },
  "track2": {
    "decrypted" : "34313532343434343434343434343432323132313031313233343536373839",
    "encoding"  : "hex",
    "length"    : 33,
    "ascii"     : ";5415244444444444=2212101123456789?",
    "masked"    : ";541524******4444=2212************?"
  },
  "extracted": {
    "PAN"       : "5415244444444444",
    "FirstName" : "BLUEFIN",
    "Surname"   : "TEST",
    "EXPY"      : "1222",
    "ServiceCode"   : "101",
    "Discretionary" : "123456789"
  }
}


RBA Test Application

It is possible to extract payload data from an Ingenico device by using the vendor's RBA Test Application. To capture a payload with the test app execute an 87 command. The output from the terminal be displayed on the Test Application. Instead of the one byte characters for a) start of transmission, b) end of transmission, c) field separator and d) LRC check sum, the response will contain the following text elements [STX], [ETX], [FC] and [LRC]. For example:

[STX]87.0[FS]41249399901612212101912TEST/BLUEFIN1BFFFF99999900F660000B0114331089645004140780=52138380040406783299B50C91A3B8A8302DB5B68F36AAE851960E91C78B1AA699A986957236BB6FAD69F7047F06FF046FF61B1A020BD2016814A2E402305C089BABA1214883E15FB1698[ETX][LRC]

While the encrypted payload is only a subset of this response string, you can use the whole string with the Parser. The Parser will identify the relevant data and extract it from the full string.