Purely as an example, we’ll dispatch a choice of card applications to the sale terminal to choose from.
After the usual login request, the Sale terminal issue a payment request to the POI terminal
<?xml version="1.0"?> <SaleToPOIRequest> <MessageHeader MessageClass="Service" MessageCategory="Payment" MessageType="Request" ServiceID="2" SaleID="ArkosSales" POIID="PreCertificationAmadis1" /> <PaymentRequest> <SaleData SaleReferenceID="ArkosSale42"> <SaleTransactionID TransactionID="1" TimeStamp="2019-08-21T14:48:05+05:00" /> </SaleData> <PaymentTransaction> <AmountsReq Currency="EUR" RequestedAmount="50.00" /> </PaymentTransaction> <PaymentData PaymentType="Normal" /> </PaymentRequest> </SaleToPOIRequest>
The snippet below demonstrate forwarding card applications to the Sale terminal. Sending a multi-choice request to the Sale terminal is as simple as
SendMenuEntryInputRequest( "Please select a card application:", new String[]{"VISA", "MasterCard", "AMEX"} );
In the sample below, rather than using constant strings, the prompt and choices are fetched from resources and ArkosLib respectively:
@Override public int cardholderChooseApplication(DisplayParams displayParams, byte[] bytes) { String prompt = LangHelper.localize(R.string.ch_display_chooseApplication, displayParams.selectedLanguage); Log.d(LOG_TAG, prompt); List<String> application = new ArrayList<>(); Collections.addAll(application, displayParams.itemList); /* AKHD-1003: Add input request multi-choice support. Solely for demonstration purposes, this is not a real-world use-case, we DO NOT recommend such usage in a production context. If the polled event is a payment, then we send a choice-based input request to the retail terminal else we simply use the application fragment. The displayParams.itemList parameters lists the possible 'applications' we received from the payment card, the choice is passed on to the retail terminal through a multi-choice input request. */ NexoEvent event = PaymentSystem.getRetailHandler().getEvent(); if (event instanceof PaymentRequest) { int menuEntryNumber = PaymentSystem.getRetailHandler().SendMenuEntryInputRequest( prompt, displayParams.itemList); if(menuEntryNumber<displayParams.itemList.length) { return menuEntryNumber; } else { throw new InvalidValueException( "Was expecting a value between 0-"+ displayParams.itemList.length); } } return selectApplication(prompt, application); }
Typically you simply need to add a SendMenuEntryInputRequest()
method similar to the one below in the RetailHandler
class which can be found in the \Arkos\workspaces\android-demo-fixed\app\src\main\java\ca\amadis\arkospay\RetailHandler.java file:
public synchronized int SendMenuEntryInputRequest(String prompt, String[] choices) { if (bConnected) { Log.d(LOG_TAG, "POI menu entry input request: " + prompt + "choices: "+ choices); InputResponse resp = retailModule.requestInput(OutgoingInputRequest.MenuEntryConfirmation(prompt, choices, 60)); if(resp.getResult() == InputResult.Success){ // The -1 is for transposing the NEXO 1-N specification about MenuEntryNumber // found in the InputResponse return resp.wrap().getMenuEntryNumber()-1; } } return 0; }
The getMenuEntryNumber()
function checks if result is a success, meaning that a response was received.
The requestInput()
function used in the SendMenuEntryInputRequest()
method (above) has been added in ASL and version 2.8.10 and the OutgoingInputRequest.MenuEntryConfirmation
helper function was added in ASL version 2.8.13.
Following the NEXO standard, the getMenuEntryNumber()
function returns an integer between 1 and N (where N in the number in menu items in the orignal input request). The zero and minus one values have special meanings regarding menu navigation. Those are currently not supported by ASL. A reponse with theMenuEntryNumber
value set to zero or minus one will throw a InvalidMenuEntryNumberValueException
type exception.
In this sample SendMenuEntryInputRequest
function we simply transpose to a 0 to N-1 by subtracting 1 to getMenuEntryNumber()
returned value.
Below is an example request and response, both of which are from the NEXO Sale to POI Protocol Specifications v3.0 document. First a sample MenuEntry input request:
<?xml version="1.0" encoding="UTF-8"?> <SaleToPOIRequest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <MessageHeader MessageClass="Device" MessageCategory="Input" MessageType="Request" ServiceID="675" DeviceID="4" SaleID="ArkosSales" POIID="AFDB0001" /> <InputRequest> <DisplayOutput Device="CustomerDisplay" InfoQualify="Display"> <OutputContent OutputFormat="Text"> <OutputText>Choose the report:</OutputText> </OutputContent> <MenuEntry OutputFormat="Text"> <OutputText>1: Daily Payment Report</OutputText> </MenuEntry> <MenuEntry OutputFormat="Text" MenuEntryTag="NonSelectable"> <OutputText>2: Daily Loyalty Report</OutputText> </MenuEntry> <MenuEntry OutputFormat="Text" MenuEntryTag="SubMenu"> <OutputText>3: Other Reports</OutputText> </MenuEntry> </DisplayOutput> <InputData Device="CustomerInput" InfoQualify="Input" InputCommand="GetMenuEntry" /> </InputRequest> </SaleToPOIRequest>
A sample MenuEntry response:
Note that the value of two below, really means 2nd item.
<?xml version="1.0"?> <SaleToPOIResponse> <MessageHeader MessageClass="Device" MessageCategory="Input" MessageType="Response" DeviceID="1374" SaleID="ArkosSales" POIID="AFDB0001"/> <InputResponse> <InputResult Device="CashierInput" InfoQualify="Input"> <Response Result="Success"/> <Input InputCommand="GetMenuEntry"> <MenuEntryNumber>2</MenuEntryNumber> </Input> </InputResult> </InputResponse> </SaleToPOIResponse>