diff -u b/modules/receipt/commerce_pos_receipt.libraries.yml b/modules/receipt/commerce_pos_receipt.libraries.yml
--- b/modules/receipt/commerce_pos_receipt.libraries.yml
+++ b/modules/receipt/commerce_pos_receipt.libraries.yml
@@ -3,6 +3,13 @@
   css:
     theme:
       css/commerce_pos_receipt.css: {}
+  js:
+    js/commerce_pos_receipt.js: {}
+  dependencies:
+    - core/jquery
+    - core/drupal
+    - core/drupalSettings
+    - core/drupal.ajax
 jQuery.print:
   remote: https://github.com/DoersGuild/jQuery.print
   version: 1.5.1
@@ -14 +21 @@
-    /libraries/jQuery.print/jQuery.print.js: {}
+    /libraries/jquery.print/jQuery.print.js: {}
diff -u b/modules/receipt/commerce_pos_receipt.module b/modules/receipt/commerce_pos_receipt.module
--- b/modules/receipt/commerce_pos_receipt.module
+++ b/modules/receipt/commerce_pos_receipt.module
@@ -25,11 +25,25 @@
 }
 
 /**
+ * Implements hook_theme().
+ */
+function commerce_pos_receipt_theme() {
+  $theme['commerce_pos_receipt'] = [
+    'variables' => [
+      'receipt' => NULL,
+    ],
+    'template' => 'commerce-pos-receipt'
+  ];
+
+  return $theme;
+}
+
+/**
  * Implements hook_operations.
  *
  * @param EntityInterface $entity The order entity.
  *
- * @return array.
+ * @return array
  */
 function commerce_pos_receipt_entity_operation(EntityInterface $entity) {
   $operations = [];
@@ -53,6 +67,16 @@
     '#type' => 'container',
   ];
 
+  $form['#attached']['library'][] = 'commerce_pos_receipt/receipt';
+  $form['#attached']['library'][] = 'commerce_pos_receipt/jQuery.print';
+
+  $module_handler = \Drupal::service('module_handler');
+  $module_path = $module_handler->getModule('commerce_pos_receipt')->getPath();
+
+  $form['#attached']['drupalSettings']['commercePosReceipt'] = [
+    'cssUrl' => Url::fromUri('base:' . $module_path . '/css/commerce_pos_receipt_print.css', ['absolute' => TRUE])->toString()
+  ];
+
   $form['receipt']['contents'] = [
     '#markup' => '<div id="commerce-pos-receipt"></div>',
   ];
diff -u b/modules/receipt/config/install/commerce_pos_receipt.settings.yml b/modules/receipt/config/install/commerce_pos_receipt.settings.yml
--- b/modules/receipt/config/install/commerce_pos_receipt.settings.yml
+++ b/modules/receipt/config/install/commerce_pos_receipt.settings.yml
@@ -1,3 +1,7 @@
+dependencies:
+  module:
+    - commerce_pos_receipt
+    - commerce_pos
 header: "(logo??)<br />Company Name/Store#<br />Address line 1<br />Address line 2<br />Phone #"
 footer: "Thanks for shopping at CompanyName!<br />Return Policy --<br />Exchange Policy --<br />Company Motto<br />Website --<br /><br />(optional)<br />Visit our website for a chance to --"
 header_format: "html"
diff -u b/modules/receipt/css/commerce_pos_receipt.css b/modules/receipt/css/commerce_pos_receipt.css
--- b/modules/receipt/css/commerce_pos_receipt.css
+++ b/modules/receipt/css/commerce_pos_receipt.css
@@ -1,86 +1,3 @@
-@page {
-  margin: 5mm;
-  size: 72mm 200mm;
-}
-.pos-receipt {
-  color: #000;
-  font-family: Arial, sans-serif;
-  font-size: 16px;
-  font-weight: bold;
-  text-transform: uppercase;
-}
-
-.pos-receipt .pos-order-info {
-  margin-bottom: 1em;
-  padding-bottom: 1em;
-  border-bottom: 1px dashed #000;
-}
-
-/* BASIC TABLE STYLES */
-.pos-receipt table {
-  width: 100%;
-  padding-bottom: 1em;
-  margin-bottom: 1em;
-  border-bottom: 1px dashed #000;
-}
-
-.pos-receipt td,
-.pos-receipt th {
-  text-align: left;
-  font-size: 16px;
-  font-weight: bold;
-  text-transform: uppercase;
-}
-
-.pos-receipt .payment-no-total td .payment-name,
-.pos-receipt .payment-no-total td.component-total {
-  text-decoration: line-through;
-}
-
-.pos-receipt .payment-no-total td span.commerce-pos-receipt-void-message {
-  text-decoration: none;
-}
-
-.pos-receipt .payment-status-void td span.commerce-pos-receipt-void-message {
-  text-decoration: none;
-}
-
-.pos-receipt td.component-total {
-  text-align: right;
-}
-
-.pos-receipt .receipt-hide {
-  display: none;
-}
-
-.pos-receipt .receipt-header,
-.pos-receipt .receipt-footer {
-  text-align: center;
-}
-
-.pos-receipt .receipt-header {
-  margin-bottom: 1em;
-  padding-bottom: 1em;
-  border-bottom: 1px dashed black;
-}
-
-.pos-receipt .receipt-footer {
-  margin-top: 1em;
-  padding-top: 1em;
-  margin-bottom: 1em;
-}
-
-.pos-receipt tr.line-item td,
-.pos-receipt tr.line-item-details td {
-  border-bottom: 1px solid #000;
-}
-
-.pos-receipt tr.line-item.has-details td {
-  border-bottom: 0;
-}
-
-.pos-receipt tr.last td {
-  border-bottom: 0;
-}
+#commerce-pos-receipt{display:none}
 
 /*# sourceMappingURL=commerce_pos_receipt.css.map */
diff -u b/modules/receipt/css/commerce_pos_receipt.css.map b/modules/receipt/css/commerce_pos_receipt.css.map
--- b/modules/receipt/css/commerce_pos_receipt.css.map
+++ b/modules/receipt/css/commerce_pos_receipt.css.map
@@ -1,7 +1 @@
-{
-"version": 3,
-"mappings": "AAAA,KAGC;EAFC,MAAM,EAAE,GAAG;EACX,IAAI,EAAE,UAAU;AAElB,YAAa;EACX,KAAK,EAAE,IAAI;EACX,WAAW,EAAE,iBAAiB;EAC9B,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,IAAI;EACjB,cAAc,EAAE,SAAS;;AAE3B,4BAA6B;EAC3B,aAAa,EAAE,GAAG;EAClB,cAAc,EAAE,GAAG;EACnB,aAAa,EAAE,eAAe;;AAIhC,wBAAwB;AACxB,kBAAmB;EACjB,KAAK,EAAE,IAAI;EACX,cAAc,EAAE,GAAG;EACnB,aAAa,EAAE,GAAG;EAClB,aAAa,EAAE,eAAe;;AAEhC;eACgB;EACd,UAAU,EAAE,IAAI;EAChB,SAAS,EAAE,IAAI;EACf,WAAW,EAAE,IAAI;EACjB,cAAc,EAAE,SAAS;;AAE3B;iDACkD;EAChD,eAAe,EAAE,YAAY;;AAE/B,wEAAyE;EACvE,eAAe,EAAE,IAAI;;AAEvB,2EAA4E;EAC1E,eAAe,EAAE,IAAI;;AAEvB,+BAAgC;EAC9B,UAAU,EAAE,KAAK;;AAEnB,0BAA2B;EACzB,OAAO,EAAE,IAAI;;AAEf;4BAC6B;EAC3B,UAAU,EAAE,MAAM;;AAEpB,4BAA6B;EAC3B,aAAa,EAAE,GAAG;EAClB,cAAc,EAAE,GAAG;EACnB,aAAa,EAAE,gBAAgB;;AAEjC,4BAA6B;EAC3B,UAAU,EAAE,GAAG;EACf,WAAW,EAAE,GAAG;EAChB,aAAa,EAAE,GAAG;;AAEpB,qCAAsC;EACpC,kBAAkB;;AAEpB;oCACqC;EACnC,aAAa,EAAE,cAAc;;AAE/B,wCAAyC;EACvC,aAAa,EAAE,CAAC;;AAElB,uBAAwB;EACtB,aAAa,EAAE,CAAC",
-"sources": ["../sass/commerce_pos_receipt.scss"],
-"names": [],
-"file": "commerce_pos_receipt.css"
-}
+{"version":3,"file":"commerce_pos_receipt.css","sources":["commerce_pos_receipt.scss"],"sourcesContent":["#commerce-pos-receipt {\n  display: none;\n}\n"],"mappings":"AAAA,AAAA,qBAAqB,AAAC,CACpB,OAAO,CAAE,IAAK,CACf","names":[]}
\ No newline at end of file
diff -u b/modules/receipt/sass/commerce_pos_receipt.scss b/modules/receipt/sass/commerce_pos_receipt.scss
--- b/modules/receipt/sass/commerce_pos_receipt.scss
+++ b/modules/receipt/sass/commerce_pos_receipt.scss
@@ -1,75 +1,3 @@
-@page {
-  margin: 5mm;
-  size: 72mm 200mm;
-}
-.pos-receipt {
-  color: #000;
-  font-family: Arial, sans-serif;
-  font-size: 16px;
-  font-weight: bold;
-  text-transform: uppercase;
-}
-.pos-receipt .pos-order-info {
-  margin-bottom: 1em;
-  padding-bottom: 1em;
-  border-bottom: 1px dashed #000;
-}
-.pos-receipt .pos-order-info .transaction-type {
-}
-/* BASIC TABLE STYLES */
-.pos-receipt table {
-  width: 100%;
-  padding-bottom: 1em;
-  margin-bottom: 1em;
-  border-bottom: 1px dashed #000;
-}
-.pos-receipt td,
-.pos-receipt th {
-  text-align: left;
-  font-size: 16px;
-  font-weight: bold;
-  text-transform: uppercase;
-}
-.pos-receipt .payment-no-total td .payment-name,
-.pos-receipt .payment-no-total td.component-total {
-  text-decoration: line-through;
-}
-.pos-receipt .payment-no-total td span.commerce-pos-receipt-void-message {
-  text-decoration: none;
-}
-.pos-receipt .payment-status-void td span.commerce-pos-receipt-void-message {
-  text-decoration: none;
-}
-.pos-receipt td.component-total {
-  text-align: right;
-}
-.pos-receipt .receipt-hide {
+#commerce-pos-receipt {
   display: none;
 }
-.pos-receipt .receipt-header,
-.pos-receipt .receipt-footer {
-  text-align: center;
-}
-.pos-receipt .receipt-header {
-  margin-bottom: 1em;
-  padding-bottom: 1em;
-  border-bottom: 1px dashed black;
-}
-.pos-receipt .receipt-footer {
-  margin-top: 1em;
-  padding-top: 1em;
-  margin-bottom: 1em;
-}
-.pos-receipt table.commerce-pos-order {
-  /*margin: 1em 0;*/
-}
-.pos-receipt tr.line-item td,
-.pos-receipt tr.line-item-details td {
-  border-bottom: 1px solid #000;
-}
-.pos-receipt tr.line-item.has-details td {
-  border-bottom: 0;
-}
-.pos-receipt tr.last td {
-  border-bottom: 0;
-}
diff -u b/modules/receipt/src/Controller/PrintController.php b/modules/receipt/src/Controller/PrintController.php
--- b/modules/receipt/src/Controller/PrintController.php
+++ b/modules/receipt/src/Controller/PrintController.php
@@ -3,8 +3,11 @@
 namespace Drupal\commerce_pos_receipt\Controller;
 
 use Drupal\commerce_order\Entity\OrderInterface;
+use Drupal\commerce_pos_receipt\Ajax\PrintReceiptCommand;
 use Drupal\commerce_price\Entity\Currency;
 use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\HtmlCommand;
+use Drupal\Core\Ajax\InsertCommand;
 use Drupal\Core\Ajax\ReplaceCommand;
 use Drupal\Core\Controller\ControllerBase;
 
@@ -22,7 +25,10 @@
     $build = $this->showReceipt($commerce_order);
 
     $response = new AjaxResponse();
-    $response->addCommand(new ReplaceCommand('#commerce-pos-receipt', $renderer->render($build)));
+
+    // TODO: could this be turned into 1 command, and if so, is that better?
+    $response->addCommand(new HtmlCommand('#commerce-pos-receipt', $renderer->render($build)));
+    $response->addCommand(new PrintReceiptCommand('#commerce-pos-receipt'));
 
     return $response;
   }
@@ -41,12 +47,15 @@
 
     $items = $commerce_order->getItems();
     foreach ($items as $item) {
-      $totals[] = [$item->getTitle(), $item->getAdjustedTotalPrice()];
+      $totals[] = [
+        $item->getTitle(),
+        $number_formatter->formatCurrency($item->getAdjustedTotalPrice()->getNumber(), $currency)
+      ];
     }
 
     $totals[] = ['Subtotal', $formatted_amount];
 
-    // Commerce appears to have a bug where if not adjustments exist, it will
+    // Commerce appears to have a bug where if no adjustments exist, it will
     // return a 0 => null array, which will still trigger a foreach loop.
     foreach ($commerce_order->collectAdjustments() as $key => $adjustment) {
       if (!empty($adjustment)) {
@@ -73,7 +82,8 @@
     }
 
     $config = \Drupal::config('commerce_pos_receipt.settings');
-    $build['receipt'] = [
+    $build = ['#theme' => 'commerce_pos_receipt'];
+    $build['#receipt'] = [
       'header' => [
         '#markup' => check_markup($config->get('header'), $config->get('header_format')),
       ],
only in patch2:
unchanged:
--- a/gulpfile.js
+++ b/gulpfile.js
@@ -12,6 +12,7 @@ var gutil = require('gulp-util');
 var config = {
   'sassDirectories': [
     { src: './modules/keypad/sass/**/*.scss', dest: './modules/keypad/css'},
+    { src: './modules/receipt/sass/**/*.scss', dest: './modules/receipt/css'},
     { src: './sass/**/*.scss', dest: './css' }
   ]
 };
only in patch2:
unchanged:
--- a/modules/keypad/js/commerce_pos_keypad.js
+++ b/modules/keypad/js/commerce_pos_keypad.js
@@ -1,4 +1,4 @@
-(function ($) {
+(function ($, Drupal, drupalSettings) {
   var inputBox = null;
 
   Drupal.behaviors.commercePosKeypadKeypad = {
@@ -258,4 +258,4 @@
     });
   };
 
-}(jQuery));
+}(jQuery, Drupal, drupalSettings));
only in patch2:
unchanged:
--- /dev/null
+++ b/modules/receipt/css/commerce_pos_receipt_print.css
@@ -0,0 +1,3 @@
+@page{margin:5mm;size:72mm 200mm}.pos-receipt{color:#000;font-family:Arial, sans-serif;font-size:16px;font-weight:bold;text-transform:uppercase}.pos-receipt .pos-order-info{margin-bottom:1em;padding-bottom:1em;border-bottom:1px dashed #000}.pos-receipt table{width:100%;padding-bottom:1em;margin-bottom:1em;border-bottom:1px dashed #000}.pos-receipt td,.pos-receipt th{text-align:left;font-size:16px;font-weight:bold;text-transform:uppercase}.pos-receipt .payment-no-total td .payment-name,.pos-receipt .payment-no-total td.component-total{text-decoration:line-through}.pos-receipt .payment-no-total td span.commerce-pos-receipt-void-message{text-decoration:none}.pos-receipt .payment-status-void td span.commerce-pos-receipt-void-message{text-decoration:none}.pos-receipt td.component-total{text-align:right}.pos-receipt .receipt-hide{display:none}.pos-receipt .receipt-header,.pos-receipt .receipt-footer{text-align:center}.pos-receipt .receipt-header{margin-bottom:1em;padding-bottom:1em;border-bottom:1px dashed black}.pos-receipt .receipt-footer{margin-top:1em;padding-top:1em;margin-bottom:1em}.pos-receipt tr.line-item td,.pos-receipt tr.line-item-details td{border-bottom:1px solid #000}.pos-receipt tr.line-item.has-details td{border-bottom:0}.pos-receipt tr.last td{border-bottom:0}
+
+/*# sourceMappingURL=commerce_pos_receipt_print.css.map */
only in patch2:
unchanged:
--- /dev/null
+++ b/modules/receipt/css/commerce_pos_receipt_print.css.map
@@ -0,0 +1 @@
+{"version":3,"file":"commerce_pos_receipt_print.css","sources":["commerce_pos_receipt_print.scss"],"sourcesContent":["@page {\n  margin: 5mm;\n  size: 72mm 200mm;\n}\n\n.pos-receipt {\n  color: #000;\n  font-family: Arial, sans-serif;\n  font-size: 16px;\n  font-weight: bold;\n  text-transform: uppercase;\n}\n\n.pos-receipt .pos-order-info {\n  margin-bottom: 1em;\n  padding-bottom: 1em;\n  border-bottom: 1px dashed #000;\n}\n\n.pos-receipt .pos-order-info .transaction-type {\n}\n\n/* BASIC TABLE STYLES */\n.pos-receipt table {\n  width: 100%;\n  padding-bottom: 1em;\n  margin-bottom: 1em;\n  border-bottom: 1px dashed #000;\n}\n\n.pos-receipt td,\n\n.pos-receipt th {\n  text-align: left;\n  font-size: 16px;\n  font-weight: bold;\n  text-transform: uppercase;\n}\n\n.pos-receipt .payment-no-total td .payment-name,\n\n.pos-receipt .payment-no-total td.component-total {\n  text-decoration: line-through;\n}\n\n.pos-receipt .payment-no-total td span.commerce-pos-receipt-void-message {\n  text-decoration: none;\n}\n.pos-receipt .payment-status-void td span.commerce-pos-receipt-void-message {\n  text-decoration: none;\n}\n.pos-receipt td.component-total {\n  text-align: right;\n}\n.pos-receipt .receipt-hide {\n  display: none;\n}\n.pos-receipt .receipt-header,\n.pos-receipt .receipt-footer {\n  text-align: center;\n}\n.pos-receipt .receipt-header {\n  margin-bottom: 1em;\n  padding-bottom: 1em;\n  border-bottom: 1px dashed black;\n}\n.pos-receipt .receipt-footer {\n  margin-top: 1em;\n  padding-top: 1em;\n  margin-bottom: 1em;\n}\n.pos-receipt table.commerce-pos-order {\n  /*margin: 1em 0;*/\n}\n.pos-receipt tr.line-item td,\n.pos-receipt tr.line-item-details td {\n  border-bottom: 1px solid #000;\n}\n.pos-receipt tr.line-item.has-details td {\n  border-bottom: 0;\n}\n.pos-receipt tr.last td {\n  border-bottom: 0;\n}\n"],"mappings":"AAAA,KAAK,CACH,MAAM,CAAE,GAAI,CACZ,IAAI,CAAE,UAAW,CAGnB,AAAA,YAAY,AAAC,CACX,KAAK,CAAE,IAAK,CACZ,WAAW,CAAE,iBAAkB,CAC/B,SAAS,CAAE,IAAK,CAChB,WAAW,CAAE,IAAK,CAClB,cAAc,CAAE,SAAU,CAC3B,AAED,AAAa,YAAD,CAAC,eAAe,AAAC,CAC3B,aAAa,CAAE,GAAI,CACnB,cAAc,CAAE,GAAI,CACpB,aAAa,CAAE,eAAgB,CAChC,AAMD,AAAa,YAAD,CAAC,KAAK,AAAC,CACjB,KAAK,CAAE,IAAK,CACZ,cAAc,CAAE,GAAI,CACpB,aAAa,CAAE,GAAI,CACnB,aAAa,CAAE,eAAgB,CAChC,AAED,AAAa,YAAD,CAAC,EAAE,CAEf,AAAa,YAAD,CAAC,EAAE,AAAC,CACd,UAAU,CAAE,IAAK,CACjB,SAAS,CAAE,IAAK,CAChB,WAAW,CAAE,IAAK,CAClB,cAAc,CAAE,SAAU,CAC3B,AAED,AAAkC,YAAtB,CAAC,iBAAiB,CAAC,EAAE,CAAC,aAAa,CAE/C,AAAiC,YAArB,CAAC,iBAAiB,CAAC,EAAE,AAAA,gBAAgB,AAAC,CAChD,eAAe,CAAE,YAAa,CAC/B,AAED,AAAsC,YAA1B,CAAC,iBAAiB,CAAC,EAAE,CAAC,IAAI,AAAA,kCAAkC,AAAC,CACvE,eAAe,CAAE,IAAK,CACvB,AACD,AAAyC,YAA7B,CAAC,oBAAoB,CAAC,EAAE,CAAC,IAAI,AAAA,kCAAkC,AAAC,CAC1E,eAAe,CAAE,IAAK,CACvB,AACD,AAAe,YAAH,CAAC,EAAE,AAAA,gBAAgB,AAAC,CAC9B,UAAU,CAAE,KAAM,CACnB,AACD,AAAa,YAAD,CAAC,aAAa,AAAC,CACzB,OAAO,CAAE,IAAK,CACf,AACD,AAAa,YAAD,CAAC,eAAe,CAC5B,AAAa,YAAD,CAAC,eAAe,AAAC,CAC3B,UAAU,CAAE,MAAO,CACpB,AACD,AAAa,YAAD,CAAC,eAAe,AAAC,CAC3B,aAAa,CAAE,GAAI,CACnB,cAAc,CAAE,GAAI,CACpB,aAAa,CAAE,gBAAiB,CACjC,AACD,AAAa,YAAD,CAAC,eAAe,AAAC,CAC3B,UAAU,CAAE,GAAI,CAChB,WAAW,CAAE,GAAI,CACjB,aAAa,CAAE,GAAI,CACpB,AAID,AAA0B,YAAd,CAAC,EAAE,AAAA,UAAU,CAAC,EAAE,CAC5B,AAAkC,YAAtB,CAAC,EAAE,AAAA,kBAAkB,CAAC,EAAE,AAAC,CACnC,aAAa,CAAE,cAAe,CAC/B,AACD,AAAsC,YAA1B,CAAC,EAAE,AAAA,UAAU,AAAA,YAAY,CAAC,EAAE,AAAC,CACvC,aAAa,CAAE,CAAE,CAClB,AACD,AAAqB,YAAT,CAAC,EAAE,AAAA,KAAK,CAAC,EAAE,AAAC,CACtB,aAAa,CAAE,CAAE,CAClB","names":[]}
\ No newline at end of file
only in patch2:
unchanged:
--- /dev/null
+++ b/modules/receipt/js/commerce_pos_receipt.js
@@ -0,0 +1,20 @@
+(function ($, Drupal, drupalSettings) {
+
+  /**
+   * Ajax command to set the toolbar subtrees.
+   *
+   * @param {Drupal.Ajax} ajax
+   *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
+   * @param {object} response
+   *   JSON response from the Ajax request.
+   * @param {number} [status]
+   *   XMLHttpRequest status.
+   */
+  Drupal.AjaxCommands.prototype.printReceipt = function (ajax, response, status) {
+    $(response.content).print({
+      globalStyles: false,
+      stylesheet: drupalSettings.commercePosReceipt.cssUrl
+    });
+  };
+
+}(jQuery, Drupal, drupalSettings));
only in patch2:
unchanged:
--- /dev/null
+++ b/modules/receipt/sass/commerce_pos_receipt_print.scss
@@ -0,0 +1,84 @@
+@page {
+  margin: 5mm;
+  size: 72mm 200mm;
+}
+
+.pos-receipt {
+  color: #000;
+  font-family: Arial, sans-serif;
+  font-size: 16px;
+  font-weight: bold;
+  text-transform: uppercase;
+}
+
+.pos-receipt .pos-order-info {
+  margin-bottom: 1em;
+  padding-bottom: 1em;
+  border-bottom: 1px dashed #000;
+}
+
+.pos-receipt .pos-order-info .transaction-type {
+}
+
+/* BASIC TABLE STYLES */
+.pos-receipt table {
+  width: 100%;
+  padding-bottom: 1em;
+  margin-bottom: 1em;
+  border-bottom: 1px dashed #000;
+}
+
+.pos-receipt td,
+
+.pos-receipt th {
+  text-align: left;
+  font-size: 16px;
+  font-weight: bold;
+  text-transform: uppercase;
+}
+
+.pos-receipt .payment-no-total td .payment-name,
+
+.pos-receipt .payment-no-total td.component-total {
+  text-decoration: line-through;
+}
+
+.pos-receipt .payment-no-total td span.commerce-pos-receipt-void-message {
+  text-decoration: none;
+}
+.pos-receipt .payment-status-void td span.commerce-pos-receipt-void-message {
+  text-decoration: none;
+}
+.pos-receipt td.component-total {
+  text-align: right;
+}
+.pos-receipt .receipt-hide {
+  display: none;
+}
+.pos-receipt .receipt-header,
+.pos-receipt .receipt-footer {
+  text-align: center;
+}
+.pos-receipt .receipt-header {
+  margin-bottom: 1em;
+  padding-bottom: 1em;
+  border-bottom: 1px dashed black;
+}
+.pos-receipt .receipt-footer {
+  margin-top: 1em;
+  padding-top: 1em;
+  margin-bottom: 1em;
+}
+.pos-receipt table.commerce-pos-order {
+  /*margin: 1em 0;*/
+}
+.pos-receipt tr.line-item td,
+.pos-receipt tr.line-item-details td {
+  border-bottom: 1px solid #000;
+}
+.pos-receipt tr.line-item.has-details td {
+  border-bottom: 0;
+}
+.pos-receipt tr.last td {
+  border-bottom: 0;
+}
only in patch2:
unchanged:
--- /dev/null
+++ b/modules/receipt/src/Ajax/PrintReceiptCommand.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace Drupal\commerce_pos_receipt\Ajax;
+
+use Drupal\Core\Ajax\CommandInterface;
+
+/**
+ * AJAX command for retrieving data and printing a receipt.
+ */
+class PrintReceiptCommand implements CommandInterface {
+
+  protected $receipt;
+
+  public function __construct($receipt) {
+    $this->receipt = $receipt;
+  }
+
+  /**
+   * Return an array to be run through json_encode and sent to the client.
+   */
+  public function render() {
+    return [
+      'command' => 'printReceipt',
+      'content' => $this->receipt,
+    ];
+  }
+
+}
