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
-
Create the virtual receipt:
-
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.
-
Convert the XML content to a Base64 string.
-
-
Make a POST request to a Terminal API endpoint, specifying:
-
MessageHeader
: The standardSaleToPOIRequest.MessageHeader
object. This includes:Parameter Required Description MessageClass
Device MessageCategory
Display
-
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
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
andErrorCondition
: More information about why the request failed.
For example:
{ "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>