Receipt Templates for Device Service

The receipt templates are defined as UserControls (.xaml) with no code behind (.xaml.cs). The fields that need to be dynamically parsed are defined in the .json file. The Device Service generates the UserControl and looks through the Json file to see which information is expected and what image/font resources to use. The data is sent through the printing request as JSON with the template name and parameters.

Example request:
POST /DeviceService/PrinterService/PrintReceipt HTTP/1.1
Host: localhost:8526
Content-Type: application/json
Authorization: Basic gfgdfgdfgdfgdfgsgr4etgrfv=
Cache-Control: no-cache
Postman-Token: b315c3b1-4acc-f497-e33a-9fd111996c9d

{
    "template":"donation_globalpay_card",
    "parameters":
    {
        "merchantName":"Bristol",
        "merchantAddress":"Kitten Street 1, S1 2FY sheffield",
        "cardNumber":"XXXX-XXXX-XXXX-4564",
        "transactionId":"dfkgdfklgjdfklgjsdfklg",
        "totalAmount":"4.76",
        "amountPaidFromTerminal":"Amount   £12.45",
        "cardTransactionType":"SALE",
        "cardTransactionNumber":"TXN 0212",
        "CVMResult":"PIN VERIFIED",
        "message":"Auth code 321354564",
        "merchantID":"M:***01111",
        "terminalID":"TID:***61279        S",
        "dateAndTime":"03/10/17 15:01",
        "panSequenceNumber":"PAN SEQ NO. 01",
        "dataSource":"ICC","issuerName":"MASTERCARD",
        "issuerNumber":"123",
        "startDate":"STT 01/01",
        "expiryDate":"EXP 01/02",
        "applicationLabel":"Visa Debit Test ",
        "AID":"AID: A0000000031010",
        "isDeclined":"False",
        "isVoid":"False"
    }
}

Note that the template files (.xaml, .json, images) must be copied over to the C:ProgramDataGW DevicesApplicationsDevice Serviceconfigsmodulesreceipt_templatesfolder in order for them to be picked up when the service is running. Each template may have its own folder inside that receipt_templates folder. The template name in the request must match the ID defined in the template.json.

JSON file structure

The Json file should follow the structure given below.

Field

Content

Example

Content

The fields that make up the data on the receipt. See the TemplateFields table for options to pass in as “Fields” array. The data listed here is sent as the “parameters” when making the printing request.

Content: { “ID”: “main”, “IsRequired”: false, “Fields”: []},

ID

Name of the template. This is used as the “template”when requesting to print the template.

“ID”: “test_template”,

Images

An array of images. Each image should have a “FileName” that matches the image file name, and an “ID” that is then used for the databinding in the xaml template. Note that the file must be placed in the same directory as the xaml and json files.

Images: [{“FileName”: “logo.png”, “ID”: “logo”}],

Fonts

An array of font resources to be used with the template. Note that fonts may not work correctly depending on the host PC so use with caution. Each font should have the “FontName” that matches the resource font name, “FontKey” that matches the resource file name and a relative “FilePath” where the font files are saved.

Fonts: [{ “FontName”: “ITC Avant Garde Std Md”, “FontKey”: “ITCAvantGardeStd-Md”, “FilePath”: “Fonts/ITCAvantGardeStd-Md.otf”}, { “FontName”: “ITC Avant Garde Std Bk”, “FontKey”: “ITCAvantGardeStd-Bk”, “FilePath”: “Fonts/ITCAvantGardeStd-Bk.otf”}],

XAMLFile

Name of the template xaml file.

“XAMLFile”: “TestReceipt.xaml”

TemplateFields

These are the fields available to be used for the template data. When declared in json, this offers some validation through the API, for example the min/max values or if the field is required or not. Note that all the declared fields are set as required, unless if the IsRequired flag is set to false.

Field

Data type

Parameters

Example

Notes

BarcodeField

string (value of barcode)

Scale (int, default 1), Height (int, default 30)

{“__type”: “BarcodeField:#TemplateTool.Models.Fields”, “ID”: “largeBarcode”, “IsRequired”: true, “Height”: 35}

Prints a code-128 barcode as bitmap image of the value passed in. Throws an error if the value cannot be encoded.

BooleanField

string value of boolean

None

{“__type”: “BooleanField:#TemplateTool.Models.Fields”, “ID”: “pickupShowDocumentationCompleted”, “IsRequired”: true}

Throws an error if the value cannot be interpreted as a boolean

CompositeField

Fields (an array[])

{“__type”: “CompositeField:#TemplateTool.Models.Fields”, “ID”: “transactionItem”, “IsRequired”: false, “Fields”: [{ “__type”: “StringField:#TemplateTool.Models.Fields”, “ID”: “label”, “IsRequired”: true, “MaxLength”: null}, {“__type”: “StringField:#TemplateTool.Models.Fields”, “ID”: “value”, “IsRequired”: true, “MaxLength”: null}]}

Used to declare a field that comprises of multiple other fields, for example a label and value pair

DatetimeField

System.DateTime (string)

None

{“__type”: “DatetimeField:#TemplateTool.Models.Fields”, “ID”: “date_time”, “IsRequired”: true}

Throws an error if the value cannot be interpreted as a date time

DecimalField

Decimal

MinimumValue (decimal), MaximumValue (decimal)

{“__type”: “DecimalField:#TemplateTool.Models.Fields”, “ID”: “amount”, “IsRequired”: true, “MaximumValue”: null, “MinimumValue”: null}

Throws an error if value cannot be parsed as decimal. If min or max is not null, also throws an error if the value is below/above the threshold.

IntegerField

Integer

MinimumValue (int), MaximumValue (int)

{“__type”: “IntegerField:#TemplateTool.Models.Fields”, “ID”: “count”, “IsRequired”: true, “MaximumValue”: null, “MinimumValue”: null}

Throws an error if value cannot be parsed as an integer. If min or max is not null, also throws an error if the value is below/above the threshold.

ListField

InnerField

{“__type”: “ListField:#TemplateTool.Models.Fields”, “ID”: “itemisedTransactionDetails”, “IsRequired”: true, “InnerField”: {“__type”: “CompositeField:#TemplateTool.Models.Fields”, “ID”: “transactionItem”, “IsRequired”: false, “Fields”: [{ “__type”: “StringField:#TemplateTool.Models.Fields”, “ID”: “label”, “IsRequired”: true, “MaxLength”: null}, {“__type”: “StringField:#TemplateTool.Models.Fields”, “ID”: “value”, “IsRequired”: true, “MaxLength”: null}]}}

Use to declare a field that accepts and array of the type of field provided as the InnerField parameter. Useful if the receipt contains a dynamic number of the same fields, for example itemisation of purchased items.

QRCodeField

string (value of barcode)

Scale (int, default 1), Height (int, default 30)

{“__type”: “QRCodeField:#TemplateTool.Models.Fields”, “ID”: “uuidQR”, “IsRequired”: true, “Height”: 30, “Scale”: 30}

draws a QR code of the given value. Scale and height can be provided to resize.

StringField

string

MaxLength (int)

{“__type”: “StringField:#TemplateTool.Models.Fields”, “ID”: “transactionId”, “IsRequired”: true, “MaxLength”: null }

If max length is provided, throws an error if that length is exceeded

Note that the validation for the fields only affects the JSON request validation. The xaml template should ensure the fields are shown or hidden as required, and that the values fit into the space provided. The ID is used for the data binding in xaml.

Using the template preview tool

When creating new templates, you can use the TemplatePreviever to test that the template works without the need to request for it to be printed.

Start the tool by running TemplatePreviewer.exe. Click “Browse” and find the folder where the xaml and json files are. Add the data into the “Template Json Data” field. Note that you should only paste in what is in the parameters of the full print receipt request (inluding the {}). So if using the example request above, the data should be:

{
        "merchantName":"Bristol",
        "merchantAddress":"Kitten Street 1, S1 2FY sheffield",
        "cardNumber":"XXXX-XXXX-XXXX-4564",
        "transactionId":"dfkgdfklgjdfklgjsdfklg",
        "totalAmount":"4.76",
        "amountPaidFromTerminal":"Amount   £12.45",
        "cardTransactionType":"SALE",
        "cardTransactionNumber":"TXN 0212",
        "CVMResult":"PIN VERIFIED",
        "message":"Auth code 321354564",
        "merchantID":"M:***01111",
        "terminalID":"TID:***61279        S",
        "dateAndTime":"03/10/17 15:01",
        "panSequenceNumber":"PAN SEQ NO. 01",
        "dataSource":"ICC","issuerName":"MASTERCARD",
        "issuerNumber":"123",
        "startDate":"STT 01/01",
        "expiryDate":"EXP 01/02",
        "applicationLabel":"Visa Debit Test ",
        "AID":"AID: A0000000031010",
        "isDeclined":"False",
        "isVoid":"False"
}

Click preview and you should see the receipt, or an error message.

Tips for designing receipts

Ensure that the receipt width is appropriate for the printer used, as if it is too wide the edges may be cut off. Leave enough empty space on the sides of the receipt, as the paper may not always be fully centered and things too close to the edges may be cut off. The length of the receipt should be long enough to accommodate the expected data. However the taller the receipt is, the longer the printing will take as the receipt is drawn as a bitmap, so if you’re not expecting very long receipts, you should reduce the height to speed up printing.