diff --git a/commerce_pos.libraries.yml b/commerce_pos.libraries.yml
index 9f8898e..68aa876 100644
--- a/commerce_pos.libraries.yml
+++ b/commerce_pos.libraries.yml
@@ -14,4 +14,8 @@ jQuery.print:
     url: https://github.com/DoersGuild/jQuery.print/blob/master/LICENSE
     gpl-compatible: no
   js:
+<<<<<<< HEAD
     /libraries/jQuery.print/jQuery.print.js: {}
+=======
+    js/commerce_pos.js: {}
+>>>>>>> saurabh commit
diff --git a/commerce_pos.links.menu.yml b/commerce_pos.links.menu.yml
index d958b53..5375811 100755
--- a/commerce_pos.links.menu.yml
+++ b/commerce_pos.links.menu.yml
@@ -29,4 +29,4 @@ commerce_pos.main:
   title: 'Point of Sale'
   route_name: 'commerce_pos.main'
   parent: 'commerce_pos.base'
-  description: 'Point of Sale Interface'
\ No newline at end of file
+  description: 'Point of Sale Interface'
diff --git a/commerce_pos.permissions.yml b/commerce_pos.permissions.yml
index ef877b2..9aaf12a 100755
--- a/commerce_pos.permissions.yml
+++ b/commerce_pos.permissions.yml
@@ -1,4 +1,4 @@
 'access commerce pos administration pages':
   title: 'Use the commerce point of sale administration pages'
 'access commerce pos pages':
-  title: 'Use the commerce point of sale standard functionality'
\ No newline at end of file
+  title: 'Use the commerce point of sale standard functionality'
diff --git a/modules/keypad/js/commerce_pos_keypad.js b/modules/keypad/js/commerce_pos_keypad.js
index 5012c20..50f2677 100644
--- a/modules/keypad/js/commerce_pos_keypad.js
+++ b/modules/keypad/js/commerce_pos_keypad.js
@@ -120,4 +120,155 @@
     this.valueElement.val(this.output);
   };
 
+  Drupal.behaviors.commercePosKeypadCashInput = {
+    attach: function (context, settings) {
+      if (drupalSettings.commerce_pos_keypad.commerce_pos_keypad.commercePosKeypadCashInput && drupalSettings.commerce_pos_keypad.commerce_pos_keypad.commercePosKeypadCashInput.inputBox) {
+        $('body').once('commerce-pos-keypad-cash-input').each(function () {
+          inputBox = new CashInputBox();
+        });
+      }
+
+      $('.commerce-pos-keypad-cash-input', context).each(function() {
+        var _this = $(this);
+        _this.once('commerce-pos-keypad-cash-input-processed').each(function () {
+          _this.after('<div class="commerce-pos-keypad-cash-input-icon"></div>');
+
+          _this.siblings('.commerce-pos-keypad-cash-input-icon').click(function () {
+            inputBox.setTextInput(_this);
+            inputBox.show();
+          });
+        });
+      });
+    }
+  };
+
+  var CashInputBox = function() {
+    this.currencyCode = '';
+    this.inputValues = {};
+    this.construct();
+  };
+
+  CashInputBox.prototype.setTextInput = function(textInput) {
+    this.textInput = textInput;
+  };
+
+  CashInputBox.prototype.show = function() {
+    var inputValues = this.textInput.data('inputValues');
+
+    this.inputBox.find('.amount-input').each(function() {
+      var amountInput = $(this);
+      var value = 0;
+      var cashType = amountInput.attr('data-cash-type');
+
+      if (inputValues && typeof inputValues[cashType] !== 'undefined') {
+        value = inputValues[cashType];
+      }
+
+      amountInput.val(value).trigger('keyup');
+    });
+
+    this.inputBox.show();
+  };
+
+  CashInputBox.prototype.hide = function() {
+    this.inputBox.hide();
+    this.textInput.data('inputValues', JSON.parse(JSON.stringify(this.inputValues)));
+  };
+
+  CashInputBox.prototype.formatAmount = function(amount, currencyCode) {
+    var formattedAmount = amount;
+
+    if (Drupal.CommercePosReport && Drupal.CommercePosReport.currencyFormat) {
+      formattedAmount = Drupal.CommercePosReport.currencyFormat(formattedAmount, currencyCode);
+    }
+
+    return formattedAmount;
+  };
+
+  CashInputBox.prototype.calculateTotal = function(currencyCode) {
+    var total = 0;
+
+    this.inputBox.find('.amount-output').each(function() {
+      var cents = $(this).data('cents');
+
+      if (!isNaN(cents)) {
+        total += cents;
+      }
+    });
+
+    var formattedTotal = this.formatAmount(total, currencyCode);
+    this.totalInput.data('total', total);
+    this.totalInput.html(formattedTotal);
+  };
+
+  CashInputBox.prototype.addTotal = function() {
+    if (this.textInput && !this.textInput.is(':disabled')) {
+      var total = this.totalInput.data('total');
+
+      if (Drupal.CommercePosReport && Drupal.CommercePosReport.currencyRound) {
+        total = Drupal.CommercePosReport.currencyRound(total, this.currencyCode, true);
+      }
+      else {
+        total = total / 100;
+      }
+
+      this.textInput.val(total);
+    }
+    this.hide();
+  };
+
+  CashInputBox.prototype.construct = function() {
+    $('body').prepend(drupalSettings.commerce_pos_keypad.commerce_pos_keypad.commercePosKeypadCashInput.inputBox);
+
+    this.inputBox = $('#commerce-pos-keypad-cash-input-box');
+    this.totalInput = this.inputBox.find('.input-total');
+
+    var self = this;
+
+    this.inputBox.find('.amount-input').each(function() {
+      var _this = $(this);
+      var outputBox = self.inputBox.find('.amount-output[data-cash-type="' + _this.attr('data-cash-type') + '"]');
+      _this.data('outputBox', outputBox);
+
+      if (self.currencyCode == '') {
+        self.currencyCode = _this.attr('data-currency-code');
+      }
+
+      _this.keyup(function() {
+        var _this = $(this);
+        var amount = _this.attr('data-amount');
+        var value = _this.val();
+
+        if (!isNaN(value)) {
+          var inputVal = _this.val();
+          var cents = amount * inputVal;
+          var outputBox = _this.data('outputBox');
+          var currencyCode = _this.attr('data-currency-code');
+          var formattedAmount = self.formatAmount(cents, currencyCode);
+
+          outputBox
+            .val(formattedAmount)
+            .data('cents', cents);
+
+          self.calculateTotal(currencyCode);
+          self.inputValues[_this.attr('data-cash-type')] = inputVal;
+        }
+      });
+    });
+
+    this.inputBox.once('bindEvents').each(function () {
+      $(this).find('.add-total').click(function(e) {
+        self.addTotal();
+        e.preventDefault();
+        return false;
+      });
+
+      $(this).find('.cancel-total').click(function(e) {
+        self.hide();
+        e.preventDefault();
+        return false;
+      });
+    });
+  };
+
 }(jQuery, Drupal, drupalSettings));
diff --git a/src/Form/POSForm.php b/src/Form/POSForm.php
index a1af2a5..3c26685 100644
--- a/src/Form/POSForm.php
+++ b/src/Form/POSForm.php
@@ -2,9 +2,13 @@
 
 namespace Drupal\commerce_pos\Form;
 
+use Drupal\commerce_pos_receipt\Ajax\PrintReceiptCommand;
+use Drupal\commerce_pos_receipt\Controller\PrintController;
 use Drupal\commerce_price\Price;
 use Drupal\commerce_store\CurrentStore;
 use Drupal\Component\Datetime\TimeInterface;
+use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\HtmlCommand;
 use Drupal\Core\Entity\ContentEntityForm;
 use Drupal\Core\Entity\EntityManagerInterface;
 use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
@@ -91,6 +95,10 @@ class POSForm extends ContentEntityForm {
    * Build the POS Order Form.
    */
   protected function buildOrderForm(array $form, FormStateInterface $form_state) {
+    /* @var \Drupal\commerce_order\Entity\Order $order */
+    $order = $this->entity;
+    $form_state->set('commerce_pos_order_id', $order->id());
+
     $form = parent::buildForm($form, $form_state);
 
     $form['customer'] = [
@@ -121,6 +129,11 @@ class POSForm extends ContentEntityForm {
    * Build the payment form, this is the second and final step of a POS order.
    */
   public function buildPaymentForm(array $form, FormStateinterface $form_state) {
+    // @todo not really the right way to do this. I think the
+    // commerce_pos_keypad should override the template to add the library in.
+    if ($this->moduleHandler->moduleExists('commerce_pos_keypad')) {
+      $form['#attached']['library'][] = 'commerce_pos_keypad/keypad';
+    }
     /* @var \Drupal\commerce_order\Entity\Order $order */
     $order = $this->entity;
     $wrapper_id = 'commerce-pos-pay-form-wrapper';
@@ -162,6 +175,7 @@ class POSForm extends ContentEntityForm {
       '#type' => 'container',
       '#id' => 'commerce-pos-sale-keypad-wrapper',
       '#tree' => TRUE,
+      '#theme' => 'commerce_pos_keypad',
     ];
 
     // If no triggering element is set, grab the default payment method.
@@ -181,14 +195,12 @@ class POSForm extends ContentEntityForm {
       // Fetching fraction digit to set as step.
       $fractionDigits = $this->currentStore->getStore()->getDefaultCurrency()->getFractionDigits();
       $form['keypad']['amount'] = [
-        '#type' => 'number',
+        '#type' => 'textfield',
         '#title' => t('Enter @title Amount', [
           '@title' => $payment_gateways[$option_id]->label(),
         ]),
-        '#step' => pow(0.1, $fractionDigits),
         '#required' => TRUE,
         '#default_value' => $keypad_amount,
-        '#commerce_pos_keypad' => TRUE,
         '#attributes' => [
           'autofocus' => 'autofocus',
           'autocomplete' => 'off',
@@ -229,6 +241,13 @@ class POSForm extends ContentEntityForm {
       '#disabled' => !$balance_paid,
       '#name' => 'commerce-pos-finish',
       '#submit' => ['::submitForm'],
+      '#attributes' => [
+        'class' => ['use-ajax-submit'],
+      ],
+      '#ajax' => [
+        'callback' => [get_class($this), 'ajaxReceipt'],
+        'wrapper' => 'commerce-pos-receipt',
+      ],
       '#element_key' => 'finish-order',
     ];
 
@@ -367,6 +386,15 @@ class POSForm extends ContentEntityForm {
     $number_formatter_factory = \Drupal::service('commerce_price.number_formatter_factory');
     $number_formatter = $number_formatter_factory->createInstance();
 
+    foreach ($this->getOrderPayments() as $payment) {
+      $amount = $payment->getAmount();
+      $voided = $payment->getState()->value == 'voided' ? ' (Void)' : '';
+      $totals[] = [
+        $payment->getPaymentGateway()->label() . $voided,
+        $number_formatter->formatCurrency($amount->getNumber(), Currency::load($amount->getCurrencyCode())),
+      ];
+    }
+
     $sub_total_price = $order->getSubtotalPrice();
     if (!empty($sub_total_price)) {
       $currency = Currency::load($sub_total_price->getCurrencyCode());
@@ -376,7 +404,7 @@ class POSForm extends ContentEntityForm {
       $formatted_amount = $number_formatter->formatCurrency(0, $default_currency);
     }
 
-    $totals[] = [$this->t('Subtotal'), $formatted_amount];
+    $totals[] = ['Subtotal', $formatted_amount];
 
     // Commerce appears to have a bug where if not adjustments exist, it will return a
     // 0 => null array, which will still trigger a foreach loop.
@@ -403,7 +431,14 @@ class POSForm extends ContentEntityForm {
       $formatted_amount = $number_formatter->formatCurrency(0, $default_currency);
     }
 
-    $totals[] = [$this->t('Total'), $formatted_amount];
+    $totals[] = ['Total', $formatted_amount];
+
+    // Collect the remaining balance.
+    $remaining_balance = $this->getOrderBalance();
+    $currency = Currency::load($remaining_balance->getCurrencyCode());
+    $formatted_amount = $number_formatter->formatCurrency($remaining_balance->getNumber(), $currency);
+
+    $totals[] = ['Remaining Balance', $formatted_amount];
 
     $form['totals']['totals'] = [
       '#type' => 'table',
@@ -516,4 +551,24 @@ class POSForm extends ContentEntityForm {
 
   }
 
+  /**
+   * AJAX callback for the finish button.
+   */
+  public function ajaxReceipt($form, $form_state) {
+    $renderer = \Drupal::service('renderer');
+    $callbackObject = $form_state->getBuildInfo()['callback_object'];
+    $commerce_order = $callbackObject->entity;
+
+    $printController = new PrintController();
+    $build = $printController->showReceipt($commerce_order);
+    unset($build['#receipt']['print']);
+    $response = new AjaxResponse();
+
+    // 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;
+  }
+
 }
diff --git a/src/Plugin/Field/FieldWidget/PosOrderItemWidget.php b/src/Plugin/Field/FieldWidget/PosOrderItemWidget.php
index f9f2052..d991088 100644
--- a/src/Plugin/Field/FieldWidget/PosOrderItemWidget.php
+++ b/src/Plugin/Field/FieldWidget/PosOrderItemWidget.php
@@ -432,7 +432,9 @@ class PosOrderItemWidget extends WidgetBase implements WidgetInterface, Containe
    */
   protected function addOrderItem(FieldItemListInterface $items, array &$form, FormStateInterface &$form_state) {
     // Loading the product variation object.
-    $product_variation = ProductVariation::load($form_state->getValue(['order_items', 'target_id', 'product_selector']));
+    $product_variation = ProductVariation::load($form_state->getValue([
+      'order_items', 'target_id', 'product_selector',
+    ]));
     // If we've not loaded a product variation then exit doing nothing.
     if (!$product_variation) {
       // There's nothing to do.
diff --git a/tests/src/FunctionalJavascript/PosFormTest.php b/tests/src/FunctionalJavascript/PosFormTest.php
index ff8315a..2915a55 100644
--- a/tests/src/FunctionalJavascript/PosFormTest.php
+++ b/tests/src/FunctionalJavascript/PosFormTest.php
@@ -23,6 +23,8 @@ class PosFormTest extends JavascriptTestBase {
    */
   public static $modules = [
     'commerce_pos',
+    // @todo commerce_pos has a circular dependency on commerce_pos_keypad
+    'commerce_pos_keypad',
   ];
 
   /**
@@ -42,20 +44,34 @@ class PosFormTest extends JavascriptTestBase {
     $register->save();
 
     $variations = [
-      $this->createProductionVariation(['title' => 'T-shirt XL', 'price' => new Price("23.20", 'USD')]),
+      $this->createProductionVariation([
+        'title' => 'T-shirt XL',
+        'price' => new Price("23.20", 'USD'),
+      ]),
       $this->createProductionVariation(['title' => 'T-shirt L']),
       $this->createProductionVariation(['title' => 'T-shirt M']),
     ];
 
-    $this->createProduct(['variations' => $variations, 'title' => 'T-shirt', 'stores' => [$test_store]]);
+    $this->createProduct([
+      'variations' => $variations,
+      'title' => 'T-shirt',
+      'stores' => [$test_store],
+    ]);
 
     $variations = [
-      $this->createProductionVariation(['title' => 'Jumper XL', 'price' => new Price("50", 'USD')]),
+      $this->createProductionVariation([
+        'title' => 'Jumper XL',
+        'price' => new Price("50", 'USD'),
+      ]),
       $this->createProductionVariation(['title' => 'Jumper L']),
       $this->createProductionVariation(['title' => 'Jumper M']),
     ];
 
-    $this->createProduct(['variations' => $variations, 'title' => 'Jumper', 'stores' => [$test_store]]);
+    $this->createProduct([
+      'variations' => $variations,
+      'title' => 'Jumper',
+      'stores' => [$test_store],
+    ]);
 
     // @todo work out the expected permissions to view products etc...
     $this->drupalLogin($this->rootUser);
diff --git a/tests/src/Kernel/UPCTest.php b/tests/src/Kernel/UPCTest.php
index 6d5d4e9..c58e47f 100644
--- a/tests/src/Kernel/UPCTest.php
+++ b/tests/src/Kernel/UPCTest.php
@@ -70,7 +70,8 @@ class UPCTest extends CommerceKernelTestBase {
       $this->assertEquals($variation->get('field_upc')->getValue()[0]['value'], '12345');
     }
 
-    // Check that if we try and load a upc that doesn't exist we don't get anything.
+    // Check that if we try and load a upc that doesn't exist
+    // we don't get anything.
     $variations = $upc->lookup('77777');
     $this->assertEmpty($variations);
   }
