Search

Are you looking for test card numbers?

Would you like to contact support?

Point-of-sale icon

Show a virtual receipt on the terminal

Show a virtual receipt on the display of the payment terminal.

Before the payment transaction starts, you can use the payment terminal to show the shopper an overview of their purchase. This functionality is available for the following terminal models:

  • M400
  • P400 Plus
  • V400c Plus
  • V400m

The next examples show what such virtual receipts look like on landscape (wide) and portrait (narrow) terminal displays. The receipt lines are scrollable. On a terminal with a landscape display, you can include a QR code next to the receipt lines.

 

 

 

To show a virtual receipt on the terminal display, you need to gather all content in an XML file, convert this file to a Base64 string, and pass that string in a display request. The XML file can contain:

  • <screen name>: The XSLT to use. There's one version for portrait terminals (P400 Plus, V400c Plus, and V400m) that shows a receipt without QR code. And there are three versions for landscape terminals (M400) that show a receipt with or without QR code. The display request will fail if you use a <screen name> that's incompatible with the terminal model.
  • <qrcodeblock>: QR code with a header and footer. When used with a <screen name> that doesn't show a QR code, the <qrcodeblock> is ignored.
  • <list-header>: The header line of the virtual receipt.
  • <lines>: Contains line items that represent the goods that the shopper is purchasing. Each line item can have a count, description, and amount.
  • <tax>: The amount and type of tax.
  • <total>: Subtotal and total amount due.

For the full structure, see the example receipt XML file below.

Make a display request for a virtual receipt

  1. Create the virtual receipt:

    1. Based on our example XML file, populate an XML file with line items and total amounts from your cash register. Make sure you use the correct screen name:

      • <screen name="virtual-receipt.xslt">: Shows a receipt without QR code where the receipt has a 'sticky' header which remains visible when scrolling down the receipt lines. For use on portrait terminals: P400 Plus, V400c Plus, and V400m.
      • <screen name="virtual-receipt-with-qr-code.xslt">: Shows a receipt with a QR code. For use on the M400.
      • <screen name="virtual_receipt01.xslt">: Shows a receipt without QR code. For use on the M400.
      • <screen name="virtual_receipt02.xslt">: Shows a receipt without QR code but with a 'sticky' header. For use on the M400.

    2. Convert the XML content to a Base64 string.

  2. Make a POST request to a Terminal API endpoint, specifying:

    • DisplayRequest.DisplayOutput : An array containing a single array item with:

      Parameter Description
      Device CustomerDisplay
      InfoQualify Display
      OutputContent.OutputFormat XHTML
      OutputContent.OutputXHTML The Base64 string containing the XML content.
    {
       "SaleToPOIRequest":{
          "DisplayRequest":{
             "DisplayOutput":[
                {
                   "Device":"CustomerDisplay",
                   "InfoQualify":"Display",
                   "OutputContent":{
                      "OutputFormat":"XHTML",
                      "OutputXHTML": "...paste Base64 encoded XML here..."
                   }
                }
             ]
          },
          "MessageHeader":{
             "ServiceID":"1116172359",
             "ProtocolVersion":"3.0",
             "MessageClass":"Device",
             "POIID":"M400-284251175",
             "MessageType":"Request",
             "SaleID":"POSSystemID12345",
             "MessageCategory":"Display"
          }
       }
    }
    String serviceID = "YOUR_UNIQUE_ATTEMPT_ID";
    String POIID = "YOUR_TERMINAL_ID";
    String saleID = "YOUR_CASH_REGISTER_ID";
    
    SaleToPOIRequest saleToPOIRequest = new SaleToPOIRequest();
    DisplayRequest displayRequest = new DisplayRequest();
    DisplayOutput displayOutput = new DisplayOutput();
    displayOutput.setDevice( DeviceType.CUSTOMER_DISPLAY );
    displayOutput.setInfoQualify( InfoQualifyType.DISPLAY );
    OutputContent outputContent = new OutputContent();
    outputContent.setOutputFormat( OutputFormatType.XHTML );
    outputContent.setOutputXHTML("...paste base64 encoded XML here...");
    displayOutput.setOutputContent(outputContent);
    displayRequest.setDisplayOutput(displayOutput);
    saleToPOIRequest.setDisplayRequest(displayRequest);
    
    MessageHeader messageHeader = new MessageHeader();
    messageHeader.setServiceID(serviceID);
    messageHeader.setProtocolVersion("3.0");
    messageHeader.setMessageClass( MessageClassType.DEVICE );
    messageHeader.setPOIID(POIID);
    messageHeader.setMessageType( MessageType.REQUEST );
    messageHeader.setSaleID(saleID);
    messageHeader.setMessageCategory( MessageCategoryType.DISPLAY );
    saleToPOIRequest.setMessageHeader(messageHeader);
    terminalAPIRequest.setSaleToPOIRequest(saleToPOIRequest);

    If the request is successful, you receive a display response with:

    • OutputResult.Response.Result: Success
    Display response
    {
       "SaleToPOIResponse":{
          "DisplayResponse":{
             "OutputResult":[
                {
                   "InfoQualify":"Display",
                   "Device":"CustomerDisplay",
                   "Response":{
                      "Result":"Success"
                   }
                }
             ]
          },
          "MessageHeader":{...}
       }
    }

    If the request is not successful, for example if you sent the DisplayRequest to an incompatible terminal, you receive a display response with:

    • OutputResult.Response.Result: Failure.
    • AdditionalResponse and ErrorCondition: More information about why the request failed.

    For example:

    Response for a failed display request
    {
       "SaleToPOIResponse":{
          "DisplayResponse":{
             "OutputResult":[
                {
                   "Device":"CustomerDisplay",
                   "InfoQualify":"Display",
                   "Response":{
                      "Result":"Failure",
                      "AdditionalResponse":"message=DisplayRequest%20API%20cannot%20be%20used%20for%20this%20terminal%20model.",
                      "ErrorCondition":"NotAllowed"
                   }
                }
             ]
          },
          "MessageHeader":{...}
       }
    }

Receipt XML file

Use the following example XML file to populate an XML input file with line items and total amounts from your cash register, making sure you specify a <screen name> that's compatible with the terminal and the result you want to achieve:

  • P400 Plus, V400c Plus, and V400m: Use <screen name="virtual-receipt.xslt">. The <qrcodeblock> in the XML will be ignored.
  • M400: Use one of the following:
    • <screen name="virtual-receipt-with-qr-code.xslt">: For a receipt with a QR code.
    • <screen name="virtual_receipt01.xslt">: For a receipt without QR code. The <qrcodeblock> in the XML will be ignored.
    • <screen name="virtual_receipt02.xslt">: For a receipt without QR code but with a 'sticky' header. The <qrcodeblock> in the XML will be ignored.
<?xml version="1.0" encoding="UTF-8"?>
<screen name="virtual-receipt-with-qr-code.xslt">
<!-- screen names are: virtual-receipt-with-qr-code.xslt, virtual_receipt01.xslt and virtual_receipt02.xslt for M400; or virtual-receipt.xslt for other terminals -->
    <receipt>
       <qrcodeblock>
          <qrheader>
            <description>Scan to access member card</description>
          </qrheader>
          <call-to-action>Scan</call-to-action>
          <qrcodedata>https%3A%2F%2Fwww%2Eadyen%2Ecom%2Fsignup%2F%3Flocation%3Damsterdam%26store%3DStore42%26POSID%3DREG0042%26hash%3DAAhbcdfjkbckjwbnadsjkn4%3D</qrcodedata>
          <qrfooter>
            <description>Don't have the app? Scan to download</description>
          </qrfooter>
        </qrcodeblock>
        <list-header>Your items</list-header>
        <!-- a receipt can have 0 or 1 lines element -->
        <lines>
            <!-- the lines element can have 0 or more lineitems -->
            <lineitem>
                <description>** SALES **</description>
            </lineitem>
            <lineitem>
                <!-- all elements (count, description, and amount) are optional -->
                <count>1</count>
                <description>Running shoes</description>
                <amount>
                    <!-- an amount must have a currency symbol or code, and a value -->
                    <currency>$</currency>
                    <value>79.99</value>
                </amount>
            </lineitem>
            <lineitem>
                <count>2</count>
                <description>Green T-shirt @ 9.89</description>
                <amount>
                    <currency>$</currency>
                    <value>19.78</value>
                </amount>
            </lineitem>
            <lineitem>
                    <description>** DISCOUNTS **</description>
            </lineitem>
            <lineitem>
                <description>Loyalty discount</description>
                <amount>
                    <currency>$</currency>
                    <value>-4.48</value>
                </amount>
            </lineitem>
            <lineitem>
                <description></description><!-- a lineitem containing only an empty description returns a blank line -->
            </lineitem>
            <lineitem>
                <description>** RETURNS **</description>
            </lineitem>
            <lineitem>
                <count>1</count>
                <description>Grey t-shirt @ 12.99</description>
                <amount>
                    <currency>$</currency>
                    <value>-12.99</value>
                </amount>
            </lineitem>
            <lineitem>
                <description>____________________</description>
            </lineitem>
            <!-- an empty lineitem returns a blank line (taking up vertical space) -->
            <lineitem></lineitem>
        </lines>
        <!-- a receipt can have 0 or 1 tax element -->
        <tax>
            <!-- a tax element can have 0 or 1 taxtotal element -->
            <taxtotal>
                <!-- description and amount are both optional -->
                <description>Total tax:</description>
                <amount>
                    <currency>$</currency>
                    <value>22.14</value>
                </amount>
            </taxtotal>
            <!-- the tax element can have 0 or more taxitems -->
            <taxitem>
                <!-- description and amount are both optional -->
                <description>VAT:</description>
                <amount>
                    <currency>$</currency>
                    <value>21.34</value>
                </amount>
            </taxitem>
            <taxitem>
                <description>Seasonal tax:</description>
                <amount>
                    <currency>$</currency>
                    <value>0.80</value>
                </amount>
            </taxitem>
        </tax>
        <!-- a receipt can have 0 or 1 subtotal element -->
        <subtotal>
            <!-- description and amount are both optional -->
            <description>subtotal</description>
            <amount>
                <currency>$</currency>
                <value>82.30</value>
            </amount>
        </subtotal>
        <!-- a receipt can have 0 or 1 total element -->
        <total>
            <!-- description and amount are both optional -->
            <description>Total amount:</description>
            <amount>
                <currency>$</currency>
                <value>104.44</value>
            </amount>
        </total>
    </receipt>
</screen>

See also