# Adapter scenarios
# Printing Custom Receipt
Business Need : Based on the market and acquirer’s needs, we want to print additional data on the receipt.
To achieve this goal, processorOptions object is used. It is a map of key-value strings and used for various processor specific data including the custom fields to be printed on the receipt.
Poynt terminal application looks for certain keys received in the response message and prints the key and corresponding value on the receipt.
In the following Response Handler Java Script code, the procOpt (an internal variable) is filled with following custom data. Acquirers may decide their own custom data printed on the receipt.
- Promotional messages
- Number of installments
- Cardholder name
And finally TRANSACTION data object is set with the the values with the ones within the procOpt.
POS Terminal application checks certain keywords (“isPrintPromotionalMessage”, “noOfInstallments“, “Cardholder Name“) and then prints them on the receipt.
function responseHandler() {
//Processor Options bag of Key/Value pairs to return.
//Most of these are for receipt printing
var procOpt = $TRANSACTION.getProcessorOptions();
if (procOpt === null) {
procOpt = new java.util.HashMap();
}
var promoMessageStr = $SELF.getField('hostMessage');
if (promoMessageStr !== null) {
procOpt.put("isPrintPromotionalMessage", "true");
procOpt.put("promotionalMessage", promoMessageStr);
procOpt.put("isPromotionalMessageDisplayed", "true");
}
var installmentData = $SELF.getField('originalData');
if (installmentData != null && installmentData.length>=3) {
var noOfInstallmemnts = installmentData.substring(1,3);
procOpt.put("noOfInstallments",noOfInstallmemnts);
}
if ($TRANSACTION.getFundingSource().getCard() !== null &&
$TRANSACTION.getFundingSource().getCard().getCardHolderFullName() !== null) {
procOpt.put("Cardholder Name", $TRANSACTION.getFundingSource().getCard().getCardHolderFullName());
}
$TRANSACTION.setProcessorOptions(procOpt);
};
# Adding SCA Logic (EU)
Business Need : In Europe, SCA is mandated by regulation. Acquirers send certain SCA soft decline codes to the terminal (INSERT_CARD, ENTER_PIN) and POS terminal prompts user to insert the card or enter the PIN based on these response codes.
To achieve this, Response Handler Java Script code performs following operations :
If ReplyCode indicates 1111 (a specific value for ENTER PIN soft decline)
- Set internal variable (scaResult) to $SCA_ENTER_PIN
If ReplyCode indicates 2222 (a specific value for INSERT CAR soft decline)
If the transaction is done with a mobile wallet (checkedTag and checkedByte variables)
- Set internal variable (scaResult) to
$SCA_CDCVM
- Set internal variable (scaResult) to
else
- Set internal variable (scaResult) to
$SCA_INSERT_CARD
- Set internal variable (scaResult) to
And finally set scaResult in the $PROCESSOR_RESPONSE
.
POS terminal gets the $PROCESSOR_RESPONSE
, checks the scaResult and perform the defined actions based on this data.
# Setting EMV Data(Auth Message)
Business Need : Brands) have different EMV tags and new tags comes in certain periods. We need to be able to define any EMV tags in the authorization message.
emvData field has following attributes:
To achieve this goal, there is a WHITELIST function where EMV tags are defined. New tags can easily be added in this list.
The Java script code performs following operations :
var eMode = $TRANSACTION.getFundingSource().getEntryDetails().getEntryMode().name();
console.info ('>>>>>>>>eMode' + eMode)
if (eMode == 'INTEGRATED_CIRCUIT_CARD' || eMode == 'CONTACTLESS_INTEGRATED_CIRCUIT_CARD') {
var emvData = $TRANSACTION.getFundingSource().getEmvData();
if (emvData !== null) {
var WHITELIST = ['0x9F6E', '0x82', '0x95', '0x9A', '0x9C', '0x5F2A', '0x9F02', '0x9F03', '0x9F09', '0x9F1A',
'0x9F1E', '0x9F26', '0x9F27', '0x9F33', '0x9F34', '0x9F35', '0x9F36', '0x9F37', '0x9F39',
'0x9F41', "0x9F53", '0x84', '0x9F10', '0x5F34', '0x9F1E', '0x9F06', '0x9F07'];
var tlv = $TLV.make(emvData, WHITELIST);
return tlv;
}
}
# Setting EMV Data(Auth Response)
Business Need : EMV data received from the acquirer should be sent to the terminal.
EMV response data includes significant data(Authorization response cryptogram, issuer response code, etc) to successfully complete an EMV transaction.
To achieve this, Response Handler Java Script code performs following operations :
If entryMode indicates that it is an EMV transaction
- Set the $PROCESSOR_RESPONSE data object with the EMV response tags.
POS terminal reaches out the EMV response data within the $PROCESSOR_RESPONSE and performs EMV defined operations to complete the transaction.
//process EMV response
var entryMode = $TRANSACTION.getFundingSource().getEntryDetails().getEntryMode().name();
if (entryMode === 'INTEGRATED_CIRCUIT_CARD' ||
entryMode === 'CONTACTLESS_INTEGRATED_CIRCUIT_CARD') {
var emvDataResp = $BINARY.toHexString($SELF.getBinaryField('emvData'));
var emvData = $TLV.parse(emvDataResp);
$PROCESSOR_RESPONSE.setEmvTags(emvData);
}
# Setting Processing Code
Business need : We need to set Processing Code field-(3-4) to a certain value in the following 2 cases.
EMV card with US common debit AID
MSR card with PIN entry
Processing field has following attributes :
To achieve this, Java Script code performs following operations :
if the entry mode is EMV or contactless
If value of EMV Tag 84 (AID) is an U.S Common Debit AID
- Set the Processing Code field (3-4) to the
$INT_DEB_CRD_PIN
- Set the Processing Code field (3-4) to the
if the entry mode is NOT EMV or contactless
If the trnsaction includes PIN data
- Set the Processing Code field (3-4) to the
$INT_DEB_CRD_PIN
- Set the Processing Code field (3-4) to the
function() {
var txnType = $PC_GOODS_SERVICE;
if ($TRANSACTION.getAmounts().getCashbackAmount() != null && $TRANSACTION.getAmounts().getCashbackAmount() > 0) {
txnType = $PC_GOODS_SERVICE_CASHBACK;
}
var fromAccount = $PC_FROM_CREDIT;
if ($TRANSACTION.getFundingSource().isDebit() != null && $TRANSACTION.getFundingSource().isDebit()) {
fromAccount = $PC_FROM_US_DEBIT;
}
if ($TRANSACTION.getFundingSource().getAccountType() != null && $TRANSACTION.getFundingSource().getAccountType().name() === "EBT") {
fromAccount = $PC_FROM_EBT;
}
console.log(txnType + fromAccount + $PC_TO_DEFAULT);
return txnType + fromAccount + $PC_TO_DEFAULT;
}
# Setting Track2Data
Business Need : Converting Track2 data to fixed length alphanumeric format and add Fs at the end.
Track2 data comes in the TRANSACTION data object in the BINARY format as defined in the attributes below.
To achieve this, Java Script code performs following operations :
If the EntryMode is not KEYED
Get the Track2Data from the TRANSACTION object (the path is
$TRANSACTION.getFundingSource().getCard().getTrack2data()
)If the total length of the track2Data is odd
- Pad “F” character at the end
Convert it to String format
function evaluate() {
//Z-Attribute Format Rules:
//replace seperatar/delimiter with 'D' if it is '='
//If total length is still odd, right pad with F
//HEX encode the whole thing
if ($TRANSACTION.getFundingSource().getEntryDetails().getEntryMode().name() !== 'KEYED') {
var track2 = $TRANSACTION.getFundingSource().getCard().getTrack2data();
track2 = track2.replace(/=/g,'D'); //Replace '=' with 'D'
var track2Len = track2.length;
if(track2.length % 2 != 0){ // Check if total length of track II is odd
track2 = track2 + 'F'; // Right pad with 'F'
}
var newTrack2 = track2Len.toString() + track2;
return newTrack2;
}
return null;
}
# Error Message on Terminal Screen
Business Need : We need to show specific error messages on the terminal screen for certain response codes.
To achieve this, Response Handler Java Script code performs following operations :
Define error messages for selected response codes (51 and 55 in this example)
If the response code is different than 00
Set the
$PROCESSOR_RESPONSE.setStatusMessage
to the defined error messagevar errorMessageEn = { '51': 'PIN Try limit exceeded', '55': 'Incorrect PIN' } if ($SELF.getField('responseCode') === '00') { $PROCESSOR_RESPONSE.setStatus($SUCCESSFUL); $PROCESSOR_RESPONSE.setStatusCode('00'); $PROCESSOR_RESPONSE.setStatusMessage($SELF.getField('authIdResponse')); } else { if ($SELF.getField('responseCode') && errorMessageEn[$SELF.getField('responseCode')]) { $PROCESSOR_RESPONSE.setStatusMessage(errorMessageEn[$SELF.getField('responseCode')]); } $PROCESSOR_RESPONSE.setStatus($FAILURE); $PROCESSOR_RESPONSE.setStatusCode($SELF.getField('responseCode')); }
Poynt terminal displays the message received in the $PROCESSOR_RESPONSE.StatusMessage
# Entry Mode in the Auth Message
Business Need : Field 22 consists of the 2 sub-fields : First 2 bytes is Entry Mode and last byte is PIN entry capability. The field is defined has following attributes : Field type is Fixed length numeric, Length is 3 and Val Encoding is BCD. The field goes in the position 22 in the authorization message.
At the bottom of the field definition screen, a Java script is seen. This Java script gets the Entry Mode in the TRANSACTION data object, performs certain controls and then sets the EntryMode in an authorization message.
The Java script code performs following operations :
Gets the entry mode from the TRANSACTION data object
Sets the entryMode based on the data in the TRANSACTION data object (First 2 digits)
Sets the entryMode to ENTRY_MODE_ICC_FALLBACK_MSR if it is a fallback transaction
If the transaction includes encrypted PIN data, then sets the 3th digit of the entryMode to 1 (PIN entered)
Returns entryMode
The Adapter Java Script Code :
function() {
console.log('ENTRY MODE:' + $TRANSACTION.getFundingSource().getEntryDetails().getEntryMode());
var entryMode = $ENTRY_MODE_ICC;
var canAcceptPin = '1'; //PIN entry capability
switch ($TRANSACTION.getFundingSource().getEntryDetails().getEntryMode().name()) {
case 'KEYED':
entryMode = $ENTRY_MODE_MANUAL;
break;
case 'TRACK_DATA_FROM_MAGSTRIPE':
entryMode = $ENTRY_MODE_MSR;
break;
case 'CONTACTLESS_MAGSTRIPE':
entryMode = $ENTRY_MODE_MSR_CL;
break;
case 'INTEGRATED_CIRCUIT_CARD':
entryMode = $ENTRY_MODE_ICC;
break;
case 'CONTACTLESS_INTEGRATED_CIRCUIT_CARD':
entryMode = $ENTRY_MODE_ICC_CL;
break;
default:
entryMode = $ENTRY_MODE_ICC;
}
if ($TRANSACTION.getFundingSource().getEntryDetails().isIccFallback() != null &&
$TRANSACTION.getFundingSource().getEntryDetails().isIccFallback()) {
entryMode = $ENTRY_MODE_ICC_FALLBACK_MSR;
}
return entryMode + canAcceptPin;
}
# Defining Custom Encoder
Sometimes, acquirers may have custom fields in the payload. In the following example, the payload has 2 bytes of the length (length of the payload) information at the beginning of the message. The following Custom Encoder Java Script adds this 2 byte of the length at the beginning of the message and Custom Decoder removes this length bytes.
Custom Encoder
function encode(data) {
console.log("Data Length >>>>> " + data.length);
var edata = new ArrayBuffer(2 + data.length);
edata[0] = (data.length & 0x0000ff00) >> 8;
edata[1] = (data.length & 0x000000ff);
for (var i = 0; i < data.length; i++) {
edata[i + 2] = data[i];
}
return Java.to(edata, 'byte[]');
}
Custom Decoder
function decode(data) {
console.log("Data Length >>>>> " + data.length);
var ddata = new ArrayBuffer(data.length + 2);
for (var i = 2; i < data.length; i++) {
ddata[i - 2] = data[i];
}
return Java.to(ddata, 'byte[]');
}
← Going Live FAQs →