Skip to main content

Invoice and thermal stencils

There are basically two kinds of invoices used within EVA: certified and non-certified invoices. While the former are pre-built by New Black, ensuring compliancy per country, there is some customization possible. For non-certified invoices we leave it up to you as these are open to heavy customization. This page will talk you through both kinds of invoices and then provide some samples.

Certified invoices

As mentioned, New Black builds and activates the certified invoices (which includes thermal receipts) for you. This means there's little customization possible aside from the optional headers and footers.

For more information and configuration steps on these customizable headers and footers, and how to setup (certified) invoice emails, please see from #5 Certified invoice stencil onwards in our compliance docs.

The remaining customization you can do is to indicate whether you want to display the recommended retail price or not, which you can do with the following setting.

SettingValueDescription
DisplayRecommendedRetailPricetrue or falseWhether to display recommended retail prices on the invoice.

Non-certified

Non-certified invoices

Where the CertifiedInvoice template leads to both an A4 invoice and a thermal receipt based on the destinations PDF and Thermal, the non-certified alternatives both require their own templates: Invoice and ThermalReceipt.

For our non-certified invoice walkthrough will go through these two templates, which can be created several times with differing destinations:

  • Name: Invoice

    • PDF, which is the actual invoice;
    • Mail, which represents a nice message with the PDF as an attachment;
    • HTTP, which will become a document containing raw data (openable using an HTTP viewer).
  • Name: ThermalReceipt

    • Thermal, which can among others be printed by your thermal printer.

Below we provide the template as well as the required helpers, and footer for page numbering (if needed).

PDF template sample
HTML
<html>

<head>

<title>Invoice Tortuga Pirate Supplies</title>
<meta charset="utf-8">
<style>

.container {
padding: 20px;
margin-right: auto;
margin-left: auto;
width: 520px;
height: auto;
border: 2px #e0ddd8;
border-style: none solid none solid;
}

body {
background-color: #F9F7F5;
}

h1,
h2,
h3 {
font-family: 'Hind', sans-serif;
font-weight: 600;
color: #333;
}

h2 {
font-size: 24px;
line-height: 29px;
margin: 0 0 15px 0;
}

h3 {
font-size: 19px;
line-height: 23px;
margin: 4px 0;
}

h3.totaal {
font-size: 19px;
line-height: 23px;
text-align: right;
margin: 0;
}

p {
font-family: 'Hind', sans-serif;
font-size: 12px;
font-weight: 400;
color: #333;
line-height: 16px;
margin: 0 0 10px;
display: block;
}

p.title {
font-size: 13px;
font-weight: bold;
padding-right: 30px;
}

p.desc {
padding-left: 15px;
padding-right: 30px;
}

p.bold {
font-size: 13px;
font-weight: bold;
}

p.italic {
font-style: italic;
}

p.small {
font-size: 10px;
line-height: 12px;
}

.logo {
width: 100%;
height: 70px;
clear: both;
}

.store {
width: 60%;
float: left;
}

.store > .address {
width: 220px;
padding-top: 20px;
float: left;
}

.customer {
width: 40%;
float: left;
}

th {
text-align: left;
}

.table {
width: 100%;
font-family: 'Hind', sans-serif;
font-size: 12px;
}

.table > tr > th,
.table > tr > td {
line-height: 15px;
vertical-align: top;
}

.table > tr > th {
font-size: 13px;
font-weight: bold;
vertical-align: bottom;
}

.headert {
clear: both;
width: 100%;
height: 30px;
border-top: 2px solid #000000;
border-bottom: 2px solid #000000;
}

.product {
margin: 20px 0;
clear: both;
overflow: auto;
position: relative;
}

.bottom {
clear: both;
width: 100%;
}

.left {
width: 350px;
float: left;
border: 2px solid #ddd;
padding: 15px;
}

.right {
width: 400px;
float: right;
text-align: right;
padding-top: 10px;
border-top: 4px solid #000000;
}

.footer {
width: 100%;
border-top: 4px solid #000000;
padding-top: 8px;
text-align: center;
}

.text-right {
text-align: right!important;
}

.remark{
font-family: "Hind", sans-serif;
font-size: 12px;
clear: both;
width: 100%;
}

.hero-image {
text-align: center;
}
.logo {
margin-right: auto;
margin-left: auto;
}
.store-remark {
padding-top: 35px;
}
.table-border-align {
width:515px;
margin:0 auto;
padding-top: 15px;
border-spacing: 10px;
}

.table-align {
width:515px;
margin:0 auto;
}
</style>
<link href="https://fonts.googleapis.com/css2?family=Hind:wght@400;600&display=swap" rel="stylesheet">
</head>

<body>

<div class="container">
<div class="header">
<div class="logo">
<td class="m_3966551746016967307logo" align="center" style="padding-bottom:20px"><a target="_blank"><img src="https://i.ibb.co/938w2xC/Logo-liggend-wit-1.png" width="246" alt="" border="0" style="display:block;margin:0 auto" class="CToWUd"></a></td>
</div>
<div class="hero-image">
<td class="m_3966551746016967307full-width-img"><a target="_blank" ><img src="https://i.ibb.co/kD7JtQQ/Flessenpost.png" width="517" alt="" border="0" style="display:block" class="CToWUd"></a></td>
</div>
</div>
<div class="header-title">
<table>
<tbody>
<tr>
<td><h1 style="padding-top: 15px;">Your Order Receipt</h1></td>
</tr>
</tbody>
</table>
</div>
<div class="body-content">
<table>
<tbody>
<tr>
<td><p>Hi, {{>Customer.FirstName}}</p></td>
</tr>
<tr>
<td><p>Enjoy your Tortuga piece(s), come back soon!</p></td>
</tr>
</tbody>
</table>
</div>
<div class="product-list">
<div class="product-detail">
<table width="515" border="0" cellspacing="0" cellpadding="0" align="center" class="table-border-align">
<tbody>
<tr>
<td><p style="font-size: 17px;">Item</p></td>
<td></td>
<td width="8"></td>
<td width="5"><p style="font-size: 17px;">Quantity</p></td>
<td width="3"></td>
<td width="60"><p style="font-size: 17px;">Price</p></td>
</tr>
<tr>
<td height="5" style="border-top:2px solid #e0ddd8"></td>
<td height="5" style="border-top:2px solid #e0ddd8"></td>
<td width="8"></td>
<td height="5" style="border-top:2px solid #e0ddd8"></td>
<td width="3"></td>
<td height="5" style="border-top:2px solid #e0ddd8"></td>
</tr>
{{for Lines}}
{{if ProductPrimaryImage != null }}
<tr>
<td><img src="{{>~root.AssetsUrl}}/blob/{{>ProductPrimaryImage}}"width="100" /></td>
<td><p>{{>Description}}</p></td>
<td width="8"></td>
<td width="5"><p>{{>TotalQuantityToShip}}</p></td>
<td width="3"></td>
<td width="60"><p>{{:~currency(TotalAmount,~root.CurrencyID, ~root.LanguageID + '-' + ~root.CountryID)}}</p></td>
</tr>
{{else}}
<tr>
<td><p>{{>ProductBackendID}}</p></td>
<td><p>{{>Description}}</p></td>
<td width="8"></td>
<td width="5"><p>{{>TotalQuantityToShip}}</p></td>
<td width="3"></td>
<td width="60"><p>{{:~currency(TotalAmount,~root.CurrencyID, ~root.LanguageID + '-' + ~root.CountryID)}}</p></td>
</tr>
{{/if}}
{{/for}}
</tbody>
</table>
<table width="515" border="0" cellspacing="0" cellpadding="0" align="center" class="table-align">
<tbody>
<tr>
<td height="25" style="border-top:2px solid #e0ddd8"></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="pricing">
<table width="515" border="0" cellspacing="0" cellpadding="0" align="center" class="table-align">
<tbody>
<tr>
<td><p>Subtotal</p></td>
<td style="padding: 0 0 0 390px;"></td>
<td width="65"><p>{{:~currency(InvoiceTotals.SubTotal,~root.CurrencyID, ~root.LanguageID + '-' + ~root.CountryID)}}</p></td>
</tr>
</tbody>
</table>
<table width="515" border="0" cellspacing="0" cellpadding="0" align="center" class="table-align">
<tbody>
<tr>
<td height="25" style="border-top:2px solid #e0ddd8"></td>
</tr>
</tbody>
</table>
{{for InvoiceTotals.Taxes}}
<table width="515" border="0" cellspacing="0" cellpadding="0" align="center" class="table-align">
<tbody>
<tr>
<td width="95"><p>{{:~taxAmount(~root.CountryID, Rate)}}</p></td>
<td style="padding: 0 0 0 375px;"></td>
<td width="85"><p>{{:~currency(Amount,~root.CurrencyID, ~root.LanguageID + '-' + ~root.CountryID)}}</p></td>
</tr>
</tbody>
</table>
{{/for}}
<table width="515" border="0" cellspacing="0" cellpadding="0" align="center" class="table-align">
<tbody>
<tr>
<td height="25" style="border-top:2px solid #e0ddd8"></td>
</tr>
</tbody>
</table>
<table width="515" border="0" cellspacing="0" cellpadding="0" align="center" class="table-align">
<tbody>
<tr>
<td width="95"><p style="font-weight: bold;">Total {{:~totalQty(Lines)}} pcs</p></td>
<td style="padding: 0 0 0 375px;"></td>
<td width="73"><p>{{:~currency(InvoiceTotals.Total,~root.CurrencyID, ~root.LanguageID + '-' + ~root.CountryID)}}</p></td>
</tr>
</tbody>
</table>
<table width="515" border="0" cellspacing="0" cellpadding="0" align="center" style="width:515px;margin:0 auto; padding-top: 15px;">
<tbody>
{{for Payments.Payments}}
<tr>
<td><p>Amount paid via {{>TypeName}}</p></td>
<td style="padding: 0 0 0 280px;"></td>
<td width="64"><p>{{:~currency(Amount,~root.CurrencyID, ~root.LanguageID + '-' + ~root.CountryID)}}</p></td>
</tr>
{{/for}}
</tbody>
</table>
<table width="515" border="0" cellspacing="0" cellpadding="0" align="center" class="table-align">
<tbody>
<tr>
<td height="25" style="border-top:2px solid #e0ddd8"></td>
</tr>
</tbody>
</table>
<table width="515" border="0" cellspacing="0" cellpadding="0" align="center" class="table-align">
<tbody>
<tr>
<td><p style="font-weight: bold;">Remark: </p></td>
</tr>
<tr>
<td>{{>InvoiceData.Remark}}</td>
</tr>
</tbody>
</table>
</div>
<div class="store-info">
{{if ShopAddress.OpeningHours != null && ShopAddress.OpeningHours.length > 0}}
<table width="515" border="0" cellspacing="0" cellpadding="0" align="center" class="table-align">
<tbody>
<tr>
<td><p style="font-weight:bold;">Store Information</p></td>
<td width="136"></td>
<td><p style="font-weight: bold; float: left;">Opening Hours</p></td>
</tr>
<tr height="25"></tr>
{{for ShopAddress}}
<tr>
<td style="vertical-align: top;">
<table width="275">
<tr><td><p style="font-weight: bold;">{{>Name}}</p></td></tr>
<tr><td><p>{{>StreetAndHouseNumber}}</p></td></tr>
<tr><td><p>{{>ZipCodeAndCity}}</p></td></tr>
</table>
</td>
<td width="136">
{{for ShopAddress.OpeningHours}}
<tr>
<td>{{:~dayofweekToString(Day,~root.LanguageID)}}</td>
{{if Closed}}
<td>Closed</td>
{{else}}
<td>{{>Start}} - {{>End}}</td>
{{/if}}
</tr>
{{/for}}
</td>
</tr>
{{/for}}
</tbody>
</table>
{{/if}}
</div>
<div class="invoice-date-barcode" style="padding-top: 35px;">
<table width="515" border="0" cellspacing="0" cellpadding="0" align="center" class="table-align">
<tbody>
<tr>
<td height="25" style="border-top:3px solid #e0ddd8"></td>
</tr>
</tbody>
</table>
<table width="515" border="0" cellspacing="0" cellpadding="0" align="center" style="width:515px;margin:0 auto; padding-bottom: 15px;">
<tbody>
<tr>
<td>
<table width="140" border="0" cellspacing="0" cellpadding="0" align="center" style="width:140px;margin:0 auto;">
<tbody>
<tr>
<td><p>Date & Time</p></td>
</tr>
<tr>
<td><p>{{:~date(InvoiceData.InvoiceDateTime, 'LLL', ~root.LanguageID + '-' + ~root.CountryID, ~root.TimeZone)}}</p></td>
</tr>
</tbody>
</table>
</td>
<td style="padding: 0 0 0 235px;"></td>
</tr>
<tr>
<td></td>
<td></td>
<td style="padding-left: 30px;"><p style="15">Order: {{>InvoiceData.OrderID}}</p></td>
</tr>
</tbody>
</table>
</div>
<div class="social-media" style="background-color: #EBEBEB; height: 35px; width: auto;">
<table border="0" cellspacing="0" cellpadding="3" width="515">
<tbody>
<tr>
<td></td>
<td align="center">
<table>
<tbody>
<tr>
<td style="font-family: 'Hind'; font-size: 13px;">Tortuga Pirate Supplies 2021</td>

</tr>
</tbody>
</table>
</td>
<td></td>
</tr>
</tbody>
</table>
</div>
<div class="footer-info">
<table align="center">
<tr>

</tr>
</table>
</div>
</div>

</body>

</html>
Helpers
JavaScript
function dayofweekToString(nr,languageID) {     
var moment = require('moment');
moment.locale(languageID || 'en')
return capitalizeFirstLetter(moment().day(nr).format('dddd'));
}

function HasDelivery(Lines) {
return Lines.some(x => x.IsDelivery);
} // {{if ~HasDelivery(Lines)}} can then be used to print stuff if there is a line to deliver

function capitalizeFirstLetter(string) {
if (string.length === 0) return "";
return string.charAt(0).toUpperCase() + string.slice(1);
}

function taxrate(rate) {
return (rate*100 - 100);
}

function taxAmount(countryID, rate) {
var prefix = 'VAT';
switch (countryID) {
case 'CA':
case 'US':
prefix = 'TAX';
break;
case 'SE':
case 'NO':
prefix = 'MVA';
break;
case 'NL':
prefix = 'BTW';
break;
case 'DE':
prefix = 'MwST';
break;
case 'FR':
prefix = 'TVA';
break;
case 'PT':
prefix = 'IVA';
break;
}
return prefix + ' ' + ((rate-1)*100).toFixed(2) + '%';
}

function translateResourceType(type) {
if (type) {
switch (type.toLowerCase()) {
case 'serialnumber':
return 'Serienummer';
}
}

return type;
}

function translatePaymentType(description) {
if (description == 'Intersolve') return 'Gift card';
return description;
}

function getHashString(s) {
if(s.length < 31) return '';
return `${s[0]}${s[10]}${s[20]}${s[30]} - Processado por programa\r\ncertificado nº 0/AT`;
}

function trim(value) {
var len = value.length;

if (len < 4) {
return value;
}

return value.substring(0, len - 4) + '****';
}
function getProductProperty(properties, name) {
if (properties === null || properties.length === 0) return null;
for (var i = 0; i < properties.length; ++i) {
if (properties[i].Key == name) return properties[i].Value;
}
return null;
}

function totalQty(total) {
var amount = 0;
i = total.length;
while(i--) {
if(total[i].Description.toUpperCase().indexOf('DISCOUNT')>=0) {
amount = amount;
} else {
amount += total[i].TotalQuantityToShip;
}
}
return amount;
}
Footer (page number)
JavaScript
<p style="margin-left:50px; font-size: 10px; text-align: center;">   
<span class='pageNumber'>
</span>
/
<span class='totalPages'>
</span>
</p>
Invoice e-mail sample
HTML
<head>
<style type="text/css">
h1,
h2,
h3 {
font-family: 'Hind', sans-serif !important;
font-weight: 600;
color: #333;
}

p {
font-family: 'Hind', sans-serif !important;
font-size: 12px;
font-weight: 400;
color: #333;
line-height: 16px;
margin: 0 0 10px;
display: block;
}
</style>

<link href="https://fonts.googleapis.com/css2?family=Hind:wght@400;600&display=swap" rel="stylesheet">
</head>


{#subject} Order #{{>InvoiceData.OrderID}} - Your Digital Invoice {#/subject}
<div style="box-sizing:border-box;margin:0;padding:0;width:100%">



<div class="m_3966551746016967307show" style="font-size:0px;max-height:0px;overflow:hidden;display:none"> Your Digital Invoice<br>
<br>



</div>



<table width="100%" border="0" cellspacing="0" cellpadding="0" align="center" class="m_3966551746016967307wrapper" bgcolor="#f9f7f5">
<tbody><tr>
<td align="center"><table width="600" border="0" cellspacing="0" cellpadding="0" class="m_3966551746016967307full-width" align="center" style="width:600px;margin:0 auto">
<tbody><tr>
<td style="border-left:1px solid #e1e1e1;border-right:1px solid #e1e1e1"><table width="100%" border="0" cellspacing="0" cellpadding="0">
<tbody><tr>
<td align="center"><table width="600" border="0" cellspacing="0" cellpadding="0" class="m_3966551746016967307full-width" align="center" style="width:600px;margin:0 auto">
<tbody><tr>
<td height="20" style="font-size:1px;line-height:1px;height:20px">

<div class="m_3966551746016967307gmailfix" style="white-space:nowrap;font:15px courier;line-height:1px;background:#f9f7f5">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div>

</td>
</tr>
<tr>
<td class="m_3966551746016967307mobile-hide" height="10" style="font-size:1px;line-height:1px;height:10px"></td>
</tr>
<tr>
<td align="center">

<table width="515" border="0" cellspacing="0" cellpadding="0" class="m_3966551746016967307content-wrapper-small" align="center" style="width:515px;margin:0 auto">
<tbody><tr>
<td class="m_3966551746016967307logo" align="center" style="padding-bottom:20px"><a target="_blank"><img src="https://i.ibb.co/938w2xC/Logo-liggend-wit-1.png" width="246" alt="" border="0" style="display:block;margin:0 auto" class="CToWUd"></a></td>
</tr>
</tbody></table>

</td>
</tr>
<tr>
<td height="10" style="font-size:1px;line-height:1px;height:10px"></td>
</tr>
<tr>
<td class="m_3966551746016967307full-width" style="width:600px;max-width:600px;min-width:600px" align="center">

<table width="515" border="0" cellspacing="0" cellpadding="0" class="m_3966551746016967307content-wrapper-small" align="center" style="width:515px;margin:0 auto">
<tbody><tr>
<td class="m_3966551746016967307full-width-img"><a target="_blank" ><img src="https://i.ibb.co/kD7JtQQ/Flessenpost.png" width="515" alt="" border="0" style="display:block" class="CToWUd"></a></td>
</tr>
</tbody></table>
<table width="515" border="0" cellspacing="0" cellpadding="0" class="m_3966551746016967307content-wrapper-small" align="center" style="width:515px;margin:0 auto">
<tbody><tr>
<td height="30"></td>
</tr>
</tbody></table>





<table width="515" border="0" cellspacing="0" cellpadding="0" class="m_3966551746016967307content-wrapper-small" align="center" style="width:515px;margin:0 auto">
<tbody><tr>
<td class="m_3966551746016967307libre" align="left" style="font-family:Hind,sans-serif;font-size:23px;line-height:36px;color:#000001;font-weight:bold">Your Digital Invoice</td>
</tr>
<tr>
<td align="left" style="padding:20px 0 0 0"><table cellpadding="0" cellspacing="0" width="40" border="0" style="width:40px">
<tbody><tr>
<td style="border-top:4px solid #000000;padding-bottom:20px;font-size:1px;line-height:1px">&nbsp;</td>
</tr>
</tbody></table></td>
</tr>
<tr>
<td class="m_3966551746016967307black" align="left" style="font-family:Hind,sans-serif;font-size:14px;line-height:26px;color:#000001;font-weight:500">
Hi {{>Customer.FirstName}}, <br><br>
Thank you for your visit to Tortuga Pirate Supplies. <br>
Enclosed is the digital invoice of your recent purchase<br><br>
We hope to see you again!
</a>
</td> </tr>

</tbody></table>
</td></tr>
</tbody></table>
<table width="515" border="0" cellspacing="0" cellpadding="0" class="m_3966551746016967307content-wrapper-small" align="center" style="width:515px;margin:0 auto">
<tbody><tr>
<td height="35"></td>
</tr>
</tbody></table>


<table width="515" border="0" cellspacing="0" cellpadding="0" class="m_3966551746016967307content-wrapper-small" align="center" style="width:515px;margin:0 auto">
<tbody><tr>
<td height="25" style="border-bottom:2px solid #e0ddd8"></td>
</tr>
<tr>
<td height="35"></td>
</tr>
</tbody></table>




<table align="center" border="0" cellpadding="0" cellspacing="0" class="m_3966551746016967307content-wrapper-small" style="width:515px;margin:0 auto" width="515">

<tbody><tr>
<td height="40">
</td></tr></tbody></table>


<table align="center" border="0" cellpadding="0" cellspacing="0" class="m_3966551746016967307content-wrapper-small" style="width:515px;margin:0 auto" width="515">

<tbody><tr>
<td height="40">
</td></tr></tbody></table>



</td>
</tr>
</tbody></table>

</td>
</tr>
<tr>
<td align="center">
<table border="0" cellpadding="0" cellspacing="0" width="100%">

<tbody><tr>
<td align="center" bgcolor="#eae7e3">
<table align="center" border="0" cellpadding="0" cellspacing="0" class="m_3966551746016967307full-width" style="width:600px;margin:0 auto" width="600">

<tbody><tr>
<td height="20" style="font-size:1px;line-height:1px;height:20px">
<div class="m_3966551746016967307gmailfix" style="white-space:nowrap;font:15px courier;line-height:1px;background:#eae7e3">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div></td></tr><tr>
<td align="center">
<table align="center" border="0" cellpadding="0" cellspacing="0" class="m_3966551746016967307content-wrapper-small" style="width:515px;margin:0 auto" width="515">

<tbody><tr>
<td align="center" style="padding-bottom:20px">
<table align="center" border="0" cellpadding="0" cellspacing="0">

<tbody><tr>
<td>
<p>EVA Tortuga 2021</p>
</td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table>





<table bgcolor="#f9f7f5" border="0" cellpadding="0" cellspacing="0" width="100%">

<tbody><tr>
<td align="center">
<table align="center" border="0" cellpadding="0" cellspacing="0" class="m_3966551746016967307full-width" style="width:600px;margin:0 auto" width="600">

<tbody><tr>
<td align="center">
<table align="center" border="0" cellpadding="0" cellspacing="0" class="m_3966551746016967307content-wrapper-small" style="width:515px;margin:0 auto" width="515">

<tbody><tr>
<td height="20" style="font-size:1px;line-height:1px;height:20px">
<div class="m_3966551746016967307gmailfix" style="white-space:nowrap;font:15px courier;line-height:1px;background:#f9f7f5">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div></td></tr><tr>
<td align="center">
<table align="center" border="0" cellpadding="0" cellspacing="0" class="m_3966551746016967307content-wrapper-small" style="width:290px;margin:0 auto" width="290">

<tbody><tr>
</tr></tbody></table></td></tr></tbody></table></td></tr><tr>
<td height="20" style="font-size:1px;line-height:1px;height:20px">
<div class="m_3966551746016967307gmailfix" style="white-space:nowrap;font:15px courier;line-height:1px;background:#f9f7f5">
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;</div></td></tr></tbody></table></td></tr></tbody></table> </td>
</tr>
</tbody></table></td></tr></tbody></table>
</div>
Invoice HTTP - using middleware

As we stated earlier, the HTTP Destination is mainly used to accommodate scenarios where email invoices are sent out from an external mailing system. In other words, no invoice emails need to be sent from EVA, but rather a push to middleware/external mail system that an email should be sent out to the customer.


This will then overwrite the current standard invoice email sending flow "email receipt" which is promoted during a checkout flow on POS.


Here is an example body of such a message:


JavaScript
{
"Content": {
"TemplateName": "Invoice",
"CurrencyID": "EUR",
"ShippedFrom": {
"Name": "Amsterdam store",
"Description": null,
"BackendID": "am_25",
"EmailAddress": "jippy@newblack.io",
"PhoneNumber": null,
"HouseNumber": "99",
"Address1": "main street",
"Address2": null,
"ZipCodeAndCity": "1010XX Amsterdam",
"BankAccount": null,
"VatNumber": null,
"RegistrationNumber": null,
"BranchNumber": null,
"Website": null,
"BIC": null,
"OpeningHours": [],
"CocNumber": null,
"StreetAndHouseNumber": "main street 99"
},
"ShopAddress": {
"Name": "am_25 Amsterdam main street",
"Description": null,
"BackendID": "am_25",
"EmailAddress": "jippy@newblack.io",
"PhoneNumber": null,
"HouseNumber": "99",
"Address1": "main street",
"Address2": null,
"ZipCodeAndCity": "1010XX Amsterdam",
"BankAccount": null,
"VatNumber": null,
"RegistrationNumber": null,
"BranchNumber": null,
"Website": null,
"BIC": null,
"OpeningHours": [],
"CocNumber": null,
"StreetAndHouseNumber": "Main street 99"
},
"CommercialOrganizationUnit": {
"Name": "New Black OU",
"Description": null,
"BackendID": "NewBlack-NL",
"EmailAddress": null,
"PhoneNumber": null,
"HouseNumber": null,
"Address1": null,
"Address2": null,
"ZipCodeAndCity": null,
"BankAccount": null,
"VatNumber": null,
"RegistrationNumber": null,
"BranchNumber": null,
"Website": null,
"BIC": null,
"OpeningHours": [],
"CocNumber": null,
"StreetAndHouseNumber": null
},
"Company": null,
"DestinationShopAddress": null,
"InvoiceData": {
"OrderID": 46,
"OrderBackendID": null,
"IsCompleted": true,
"InvoiceNumber": "18",
"InvoiceTime": "12 January 2023, 10:56",
"DocumentTime": "23 November 2022, 13:43",
"EmployeeName": "Ruben",
"EmployeeID": 8,
"EmployeeNumber": "",
"OfferExpirationDate": null,
"Remark": null,
"CustomerReference": null,
"CustomerOrderID": null,
"IsOffer": false,
"IsDownPayment": false,
"Signature": null,
"Hash": null,
"InvoiceDateTime": "2023-01-12T10:56:20.99",
"DocumentDateTime": "2022-11-23T13:43:49.75",
"PlacementDateTime": "2022-11-23T13:44:05.143",
"PaymentTermStartDate": null,
"PaymentTermDueDate": null,
"FiscalID": null,
"VatNumber": null,
"ReturnedInvoiceNumber": null,
"ReturnedInvoiceDate": null,
"ReturnedInvoiceReason": null
},
"Customer": {
"ID": 6,
"CompanyName": null,
"FullName": "Jippy Kayay",
"FirstName": "Jippy",
"LastName": "Kayay",
"RegistrationNumber": null,
"VatNumber": null,
"BankAccount": null,
"EmailAddress": "Jippy@newblack.io",
"PhoneNumber": null,
"BackendRelationID": null,
"PaymentTerms": null,
"FiscalID": null,
"LanguageID": "en",
"CountryID": "NL",
"CocNumber": null,
"MobilePhoneNumber": null,
"HomePhoneNumber": null
},
"BillingAddress": {
"FirstName": "Jippy",
"LastName": "Kayay",
"PhoneNumber": null,
"EmailAddress": null,
"HouseNumber": "123",
"Address1": "Soest 1",
"Address2": null,
"ZipCode": "1020XR",
"Subdistrict": null,
"District": null,
"City": "Antwerp",
"State": null,
"ZipCodeAndCity": "1020AA Antwerp",
"CountryID": "NL",
"AddressedTo": "Jippy Kayay",
"StreetAndHouseNumber": "soest 1 123"
},
"ShippingAddress": {
"FirstName": "Jippy",
"LastName": "Kayay",
"PhoneNumber": null,
"EmailAddress": null,
"HouseNumber": "123",
"Address1": "soest 1",
"Address2": null,
"ZipCode": "1020AA",
"Subdistrict": null,
"District": null,
"City": "Antwerp",
"State": null,
"ZipCodeAndCity": "1020AA Antwerp",
"CountryID": "NL",
"AddressedTo": "Jippy Kayay",
"StreetAndHouseNumber": "soest 1 123"
},
"Lines": [
{
"ID": 51,
"ParentID": null,
"Type": "NormalProduct",
"Description": "Mercerized stripe tee",
"TotalQuantityToShip": 1,
"QuantityReturned": 0,
"QuantityShipped": 1,
"OriginalUnitPrice": null,
"OriginalUnitPriceInTax": null,
"UnitPrice": 100,
"UnitPriceInTax": 121,
"TotalAmount": 100,
"TotalAmountInTax": 121,
"SerialNumber": null,
"TaxRateAsPercentage": "21",
"QuantityInvoiced": 1,
"TotalQuantityInvoiced": 1,
"TotalAmountInTaxInvoiced": 121,
"AdditionalDescription": null,
"ProductBackendID": "8719027081962",
"ProductCustomID": "171212_0219-XXL",
"ProductID": 309437,
"SupplierProductBackendID": null,
"ProductTypeID": 1,
"ProductPrimaryImage": null,
"ShowTaxInfo": false,
"CardTransactionStatusID": null,
"ProductVariation": {
"color": "0219",
"color.name": "color",
"size": "XXL",
"size.name": "size"
},
"Barcode": "8719027081962",
"ContractNumber": null,
"RequestedDate": null,
"IsDelivery": true,
"IsReservation": false,
"IsOrdered": false,
"IsShipped": true,
"ReturnedOrderID": null,
"ReturnedOrderBackendID": null,
"ReturnedOrderlineID": null,
"ReturnedOrderCreationTime": null,
"ReturnedOrderPlacementDate": null,
"ShippingMethod": null,
"ProductProperties": {},
"ProductRequirements": [],
"TaxRate": "21",
"BackendID": "8719027081962"
}
],
"InvoiceTotals": {
"SubTotal": 100,
"Total": 121,
"Taxes": [
{
"Rate": 1.21,
"Amount": 21,
"Base": 100,
"Total": 121
}
],
"OpenAmount": 0,
"Discounts": 0,
"ShippingCosts": 0
},
"OrderTotals": {
"SubTotal": 100,
"Total": 121,
"Taxes": [
{
"Rate": 1.21,
"Amount": 21,
"Base": 100,
"Total": 121
}
],
"OpenAmount": 0,
"Discounts": 0,
"ShippingCosts": 0
},
"Totals": {
"SubTotal": 100,
"Total": 121,
"Taxes": [
{
"Rate": 1.21,
"Amount": 21,
"Base": 100,
"Total": 121
}
],
"OpenAmount": 0,
"Discounts": 0,
"ShippingCosts": 0
},
"Payments": {
"Payments": [
{
"Amount": 121,
"TypeName": "EFT",
"BookPaymentMethodInvoice": false,
"Details": null,
"Date": "2022-11-23T13:44:05.067",
"Description": "EFT\n (23-11-2022, 13:44)"
}
],
"OrderPayments": [
{
"Amount": 121,
"TypeName": "EFT",
"BookPaymentMethodInvoice": false,
"Details": null,
"Date": "2022-11-23T13:44:05.067",
"Description": "EFT\n (23-11-2022, 13:44)"
}
],
"Total": 121,
"Change": 0,
"OrderTotal": 121
},
"PinReceipt": [],
"PinReceipts": [],
"IsCopy": true,
"IsInvoice": true,
"IsPurchaseOrder": false,
"TimeZone": null,
"DisplayRecommendedRetailPrice": false,
"AuditingData": {
"LicenseName": null,
"LicenseID": null
},
"Signing": {
"Signature": null
}
},
"MailTo": "jippy@newblack.io",
"Subject": null,
"CcTo": null,
"BccTo": null,
"OrganizationUnitID": 78,
"Context": {
"UserID": 8,
"ApplicationID": 1,
"OrganizationUnitID": 1,
"LanguageID": "en",
"CountryID": "NL",
"CurrencyID": "EUR",
"CreationTime": "2023-01-12T12:23:19.0826229Z",
"ManuallyImpersonated": false,
"MessageQueueErrorID": null,
"RetryCount": null,
"TimeZone": "Etc/UTC",
"CountrySubdivisionID": null
}
}

Non-certified thermal receipts

For non-audited countries, you can also create your own thermal receipts.

This section will guide you through its template and (optional) helper and partials.

Template for thermal receipt

  • For Name, set ThermalReceipt
  • For Destination, tick Thermal
  • Leave all other fields empty

Below you can find a sample.


HTML
<report>
<scope font="FontB">
{{if ReturnedOrderReprint}}

<scope size="1 0" bold="true">
ORDER RETURNED REPRINT
</scope>

<feed amount="32" />

{{/if}}

{#partial ThermalReceipt-Header}

<line width="double" />
<feed amount="4" />
{{if InvoiceNumber}} <bold>INVOICE</bold>{{/if}}
<bold>{{:~date(DocumentTime, 'LLL', LanguageID + '-' + CountryID, TimeZone)}}</bold>
{{if InvoiceNumber}}
Invoice number : {{:InvoiceNumber}}

{{/if}}


{{if CustomerData && CustomerData.length > 0}}
<feed amount="6" />

<scope font="FontB">
{{for CustomerData}}
{{>#data}}
{{/for}}
</scope>
<line />
{{/if}}


<feed amount="24" />

<scope font="FontB">
{{for ShippedLines}}
{#partial ThermalReceipt-ShippedLine}
{{/for}}

{{if NoLinesShipped}}
<bold>NO PRODUCTS SHIPPED</bold>
{{/if}}

{{if AnyUnshippedLines}}

<feed amount="24" />
<line />
<feed amount="24" />

<bold>STILL TO SHIP:</bold>

<feed amount="24" />

{{for UnshippedLines}}

{#partial ThermalReceipt-ShippedLine}

{{/for}}

{{/if}}

<feed amount="24" />

</scope>

<scope font="FontA" align="right">
<grid positions="0, 25">
<row>
<line />
<col><bold>Total</bold>:</col>
<col width="10">{{:~currency(OriginalTotalAmountInTax,~root.CurrencyID, ~root.LanguageID + '-' + ~root.CountryID)}}</col>
</row>
<row>
<col><bold>Subtotal:</bold></col>
<col width="10">{{:~currency(OriginalTotalAmount,~root.CurrencyID, ~root.LanguageID + '-' + ~root.CountryID)}}</col>
</row>
</grid>

<grid positions="0, 25">
{{for Taxes}}
{{if Amount}}
<row>
<col>{{:~taxAmount(~root.CountryID,Rate)}}</col>
<col width="10">{{:~currency(Amount,~root.CurrencyID, ~root.LanguageID + '-' + ~root.CountryID)}}</col>
</row>
{{/if}}
{{/for}}
</grid>

<feed amount="80" />

<grid positions="0,25">
{{for Payments}}
<row>
<col>{{:~translatePaymentType(Description) + ' ' + ~date(PaymentDate, 'DD-MM-YYYY, HH:mm', LanguageID + '-' + CountryID, TimeZone)}}</col>
<col width="10">{{:~currency(Amount,~root.CurrencyID, ~root.LanguageID + '-' + ~root.CountryID)}}</col>
</row>
{{/for}}
</grid>

{{if PaidAmount}}
<grid positions="0,25">
<row>
<col>Paid:</col>
<col width="10">{{:~currency(PaidAmount,~root.CurrencyID, ~root.LanguageID + '-' + ~root.CountryID)}}</col>
</row>
</grid>
{{/if}}

{{if Change}}
<grid positions="0,25">
<row>
<col>Change</col>
<col width="10">{{:~currency(Change,~root.CurrencyID, ~root.LanguageID + '-' + ~root.CountryID)}}</col>
</row>
</grid>
{{/if}}

<feed amount="40" />
<grid positions="0,25">
{{for CardActions}}
<row>
<col>Gift card </col>
<col>{{:~trim(CardNumber)}}</col>
</row>
<row>
<col>Remaining balance </col>
<col>{{:~currency(NewBalance,~root.CurrencyID, ~root.LanguageID + '-' + ~root.CountryID)}}</col>
</row>
<row>
<col> </col>
</row>
{{/for}}
</grid>
</scope>
<scope font="FontB">

<placeholder name="PinReceipt" />
<feed amount="110" />

{{for CardTransactions}}

{{for Lines}}
{{>#data}}
{{/for}}

{{/for}}

<feed amount="15" />

<placeholder name="VoucherActivation" />

{{if Remark}}
<feed amount="32" />
<bold>Remark: {{>Remark}}</bold>
<feed amount="20" />
{{/if}}
<line />

<feed amount="4" />
<scope bold="true" align="center" font="FontB">
{{if OrderCompleted}}
{#partial ThermalReceipt-Footer}
{{/if}}
<scope bold="false" font="FontB">
<feed amount="80" />
<barcode data="{{:OrderBarcode}}" type="Code39" />
<feed amount="24" />
{{:OrderID}}
<feed amount="80" />
</scope>

</scope>
</scope>
</scope>
</report>
Thermal receipt helpers

For the ThermalReceipt template, paste the following code into the Helpers tab:

JavaScript
function taxRate(rate) {
return ((rate-1)*100).toFixed(2) + '%';
}

function taxAmount(countryID, rate) {
var prefix = 'VAT';
switch (countryID) {
case 'US':
prefix = 'TAX';
break;
case 'SE':
case 'NO':
prefix = 'MVA';
break;
case 'NL':
prefix = 'BTW';
break;
case 'DE':
prefix = 'MwST';
break;
case 'FR':
prefix = 'TVA';
break;
case 'PT':
prefix = 'IVA';
break;
}
return prefix + ' ' + rate + '%';
}

function fixed(e) {
e = e || 0;
return e.toFixed(2);
}

function translateResourceType(type) {
if (type) {
switch (type.toLowerCase()) {
case 'serialnumber':
return 'Serienummer';
}
}

return type;
}

function translatePaymentType(description) {
if (description == 'Intersolve') return 'Gift card';
return description;
}

function getHashString(s) {
if(s.length < 31) return '';
return `${s[0]}${s[10]}${s[20]}${s[30]} - Processado por programa\r\ncertificado nº 0/AT`;
}

function trim(value) {
var len = value.length;

if (len < 4) {
return value;
}

return value.substring(0, len - 4) + '****';
}
Thermal receipt partials
  • Select Partial
  • For Name, set ThermalReceipt-Header
  • For Destination, tick the Thermal Printer
  • Leave all other fields empty

Now paste the following code:


HTML
<scope align="center" font="FontB" tabs="21">

<feed amount="32" />

<bold>Tortuga Pirate Supplies {{>ShopName}}</bold>
{{>ShopStreet}}
{{>ShopZipCode}} {{>ShopCity}}
{{>ShopPhoneNumber}}
EVA Tortuga

<feed amount="16" />

</scope>
  • Select Partial
  • For Name, set ThermalReceipt-Footer
  • For Destination, tick the Thermal Printer
  • Leave all other fields empty

Now paste the following code:


HTML
<scope bold="true" align="center" font="FontB">

<bold>Thank you for your purchase at
Tortuga Pirate Supplies!</bold>
You were served by JOHN DOE #123

</scope>

Shipped line

  • Select Partial
  • For Name, set ThermalReceipt-ShippedLine
  • For Destination, tick the Thermal Printer
  • Leave all other fields empty

Now paste the following code:


HTML
<scope align="left">
<grid positions="0, 5, 39, 49">
<row>
{{* Quantity to ship *}}
<col>{{:QuantityToShip}}</col>

{{* Description *}}
<col>{{>PrimaryDescription}}</col>

<col>{{:~taxRate(TaxRate)}}</col>
<col align="right" width="8"><bold>{{:~currency(AmountInTax,~root.CurrencyID, ~root.LanguageID + '-' + ~root.CountryID)}}</bold></col>

</row>
</grid>

{{for Descriptions}}
{{>this}}
{{/for}}

{{if CustomItemNumber || IsInsuranceProduct || CardNumber || SerialNumber}}

<grid positions="0, 4, 20">
<row>
<col>{{:CustomItemNumber}}</col>

{{if CardNumber}}
<col>{{:~trim(CardNumber)}}</col>
{{/if}}
{{if SerialNumber}}
<col>{{:~trim(SerialNumber)}}</col>
{{/if}}
</row>
</grid>

{{/if}}

</scope>
{{if GiftCardActivated}}

{{if Returned}}
Card deactivated
{{else}}
Card activated
{{/if}}

{{/if}}

{{if GiftCardActivationFailed}}
{{if Returned }}
Card not deactivated
{{else}}
Card not activated
{{/if}}
{{/if}}
{{if Returned}}
<bold>RETURNED</bold>
{{/if}}

<feed amount="24" />
<line />