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.