Use the receipt print server

Use the InStore receipt print server to manage point-of-sale (POS) printer operations using a network connection.

The InStore receipt print server has HTTPS support with local certificates, CORS protection, network-wide accessibility, and command-line port configuration. It lets you complete the following tasks over a network connection:

The receipt print server is a demo application for local development and evaluation of how to connect to your printers. Do not use it in your production environments.

Prerequisites

  • The service uses a self-signed certificate for HTTPS.
  • Supported printer types: Epson ("EPSON") and Star Micronics ("STAR").
  • A package manager of your choice. The following examples use npm.

When you first access the receipt print server, your browser will display a security warning.

Install the receipt print server

  1. Clone the receipt-print-server repository from GitHub.
  2. Run the following command:
npm install

Set up HTTPS

You can set up HTTPS using any of the following:

  • A certificate signed by an official Certificate Authority: we recommend this option for production environments.
  • A self-signed certificate: we recommend this option for development environments.
  • A hosted service to create a local tunnel: for development environments when neither a certificate signed by a Certificate Authority or a self-signed certificate is possible. For example, in cases where iOS blocks requests to hosts with self-signed certifications. For information about how to set up a local tunnel for this purpose, see Set up with a local tunnel.

Set up with a self-signed certificate

You can use a utility such as the mkcert tool to create a locally trusted certificate for using the receipt print server in a development environment. To do this, complete the following steps:
  1. Add the local IP address of the computer running the receipt print server to the mkcert creation command, for example:

    mkcert -install
    mkdir certs
    cd certs
    # Generate certificate including your machine's IP address
    mkcert localhost 127.0.0.1 YOUR.IP.ADDRESS.HERE
    # Example: mkcert localhost 127.0.0.1 192.168.68.71
    
  2. mkcert generates the certificate and private key files. Keep these files secure, as you need to add them when configuring the receipt print server.

Set up with a local tunnel

You can use a tunnel utility such as ngrok to expose the local print server via an HTTPS URL. To do this, complete the following steps:
  1. Install the relevant version of ngrok.
  2. Sign up for an account to access the service.
  3. Follow the ngrok instructions to create a static domain.
  4. When running the receipt print server, expose the app via the ngrok tunnel you created.

Configure the receipt print server

To configure the receipt print server, you need to create a .env file and then configure the printer in the InStore colleague app, or via the InStore device CLI.

Create the .env file

Create a .env file at the top level of your directory and then add the following:
PORT=3001  # Default port (can be overridden by command line)
ALLOWED_ORIGINS=https://yourdomain.com,http://localhost:3000
KEY_FILE=localhost-key.pem
CERT_FILE=localhost.pem

Configure the printer in the InStore colleague app

  1. Add or edit an existing printer in the InStore colleague app.
  2. In the Print Server Address field, add the IP address of the computer running the receipt print server, for example https://192.168.0.10:3000. If you are using a local tunnel, add the tunnel URL, for example https://subdomain.ngrok.app.
  3. In the Printer Address field, add the IP address of the printer, for example 192.168.0.250.
  4. Save the new or updated device.

Run the receipt print server

You can run the receipt print server with the default configuration or override settings.

Default configuration

To start the server with the default configuration, run the following at the root directory of the project:

node index.js

Custom port

By default, the receipt print server is accessible from all network interfaces and runs on port 3001, or on the port specified in the .env file. To change this port, run the following command and replace "3000" with your desired port number:
node index.js --port 3000
The port you set using this method takes precedence over the port configured in the .env file.

Expose the app via an ngrok tunnel

If you set up HTTPS with a local tunnel using ngrok, you need to expose the app using the following command:
ngrok http --url=<static-domain-setup-in-ngrok> https://localhost:<your-port-number>

This method does not authenticate requests. While running, the URL is available to requests from the internet.

Access the receipt print server

The receipt print server displays all the available network addresses on start up. For example:

Server running on https://localhost:3001

Available on:
  https://192.168.68.71:3001
  https://OTHER.IP.ADDRESSES:3001

To access the server from other devices on the network, do the following:

  1. Use the required IP address, for example https://192.168.68.71:3001.
  2. Accept the security warning in your browser (for self-signed certificates).

Receipt print server API

Print receipt request body examplebash
POST /api/print
{
  "receipt": "Receipt content",
  "printer": "printer_name",
  "address": "192.168.1.100",
  "width": 42,
  "check": false
}

Generate an SVG receipt

Use this endpoint to generate an SVG representation of a receipt without printing it, for example, to preview the receipt or to send it digitally. The template and data are processed through the builder utility, which converts currency values to Dinero format.

Generate an SVG receipt request body examplebash
POST /api/svg
{
  "template": "Receipt template markup using Handlebars syntax",
  "data": "JSON data object with receipt information",
  "currency": "USD",
  "locale": "en-US",
  "currencyFormat": "Currency format string or object"
}
Generate an SVG receipt response examplebash
POST /api/svg
{
  "markdown": "Compiled receipt markdown",
  "svg": "SVG representation of the receipt",
  "success": true
}
Generate an SVG receipt request with sample data examplebash
{
  "template": "^{{location.location_name}}^\n{{location.address_line_1}}\n-----------------\n{{#each line_items}}\n{{description}} {{quantity}} @ {{price}}\n{{/each}}\n-----------------\nTotal: {{total}}",
  "data": {
    "location": {
      "location_name": "COFFEE SHOP",
      "address_line_1": "123 Main Street"
    },
    "line_items": [
      {
        "description": "Cappuccino",
        "quantity": 1,
        "price": "$4.50"
      },
      {
        "description": "Croissant",
        "quantity": 2,
        "price": "$3.75"
      }
    ],
    "total": "$12.00"
  },
  "currency": "USD",
  "locale": "en-US",
  "currencyFormat": "$0,0.00"
}
Generate an SVG receipt response with sample data examplebash
{
  "markdown": "^COFFEE SHOP^\n123 Main Street\n-----------------\nCappuccino 1 @ $4.50\nCroissant 2 @ $3.75\n-----------------\nTotal: $12.00",
  "svg": "<svg width=\"576px\" height=\"210px\" viewBox=\"0 0 576 210\" preserveAspectRatio=\"xMinYMin meet\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.1\"><style type=\"text/css\"><![CDATA[@import url(\"https://fonts.googleapis.com/css2?family=Courier+Prime&display=swap\");]]></style><defs><filter id=\"receiptlineinvert\" x=\"0\" y=\"0\" width=\"100%\" height=\"100%\"><feFlood flood-color=\"#000\"/><feComposite in=\"SourceGraphic\" operator=\"xor\"/></filter></defs><g font-family=\"'Courier Prime', 'Courier New', 'Courier', monospace\" fill=\"#000\" font-size=\"22\" dominant-baseline=\"text-after-edge\" text-anchor=\"middle\"><g transform=\"translate(0,24)\"><text transform=\"scale(2,1)\"><tspan x=\"84\">C</tspan><tspan x=\"96\">O</tspan><tspan x=\"108\">F</tspan><tspan x=\"120\">F</tspan><tspan x=\"132\">E</tspan><tspan x=\"144\">E</tspan><tspan x=\"156\">&#xa0;</tspan><tspan x=\"168\">S</tspan><tspan x=\"180\">H</tspan><tspan x=\"192\">O</tspan><tspan x=\"204\">P</tspan></text></g><g transform=\"translate(0,54)\"><text><tspan x=\"204\">1</tspan><tspan x=\"216\">2</tspan><tspan x=\"228\">3</tspan><tspan x=\"240\">&#xa0;</tspan><tspan x=\"252\">M</tspan><tspan x=\"264\">a</tspan><tspan x=\"276\">i</tspan><tspan x=\"288\">n</tspan><tspan x=\"300\">&#xa0;</tspan><tspan x=\"312\">S</tspan><tspan x=\"324\">t</tspan><tspan x=\"336\">r</tspan><tspan x=\"348\">e</tspan><tspan x=\"360\">e</tspan><tspan x=\"372\">t</tspan></text></g><!-- SVG truncated for brevity -->",
  "success": true
}
The ^ characters in the template are used for styling (typically bold or larger text) and the template uses Handlebars syntax for dynamic content.

Get printer status

Get printer status request examplebash
POST /api/status
{
  "address": "192.168.1.100",
  "type": "EPSON"
}
Get printer status response examplebash
{
  status: {
    isReady: true,
    drawerOpen: false,
    hasPaper: true,
    coverOpen: false,
    errors: []
    },
    success: true
}

Open cash drawer

Open cash drawer request body examplebash
POST /api/drawer
{
  "address": "192.168.1.100",
  "type": "EPSON"
}
Open cash drawer response examplebash
{
   success: true
}