diff --git a/commerce_pos.libraries.yml b/commerce_pos.libraries.yml
index 64d7f4e..d4e4c28 100644
--- a/commerce_pos.libraries.yml
+++ b/commerce_pos.libraries.yml
@@ -4,4 +4,4 @@ form:
     layout:
       css/commerce_pos_style.css: {}
   js:
-    js/commerce_pos.js: {}
\ No newline at end of file
+    js/commerce_pos.js: {}
diff --git a/commerce_pos.routing.yml b/commerce_pos.routing.yml
index 8ea2023..f1a582d 100644
--- a/commerce_pos.routing.yml
+++ b/commerce_pos.routing.yml
@@ -38,3 +38,12 @@ commerce_pos.main:
     _title: 'Point of Sale'
   requirements:
     _permission: 'access commerce pos pages'
+
+commerce_pos.pos_order_item_widget_autocomplete:
+  path: '/commerce_pos/orderItemAutoCompleteHandler/{entity_type}/{view_mode}/{count}'
+  defaults:
+    _controller: '\Drupal\commerce_pos\Controller\PosOrderItemAutoComplete::orderItemAutoCompleteHandler'
+    _format: json
+    _title: 'Pos Order Item Autocomplete'
+  requirements:
+    _permission: 'access content'
diff --git a/config/install/core.entity_form_display.commerce_order.pos.default.yml b/config/install/core.entity_form_display.commerce_order.pos.default.yml
index 982c0a7..853ea08 100644
--- a/config/install/core.entity_form_display.commerce_order.pos.default.yml
+++ b/config/install/core.entity_form_display.commerce_order.pos.default.yml
@@ -2,33 +2,27 @@ langcode: en
 status: true
 dependencies:
   config:
-    - commerce_order.commerce_order_type.default
-    - field.field.commerce_order.pos.field_order_items
+    - commerce_order.commerce_order_type.pos
+    - field.field.commerce_order.pos.field_cashier
+    - field.field.commerce_order.pos.field_register
+    - field.field.commerce_order.pos.order_items
   module:
     - commerce_order
     - commerce_pos
+    - inline_entity_form
+_core:
+  default_config_hash: HhZKA_IA19mJACTv88yTh3eJ7gPY3sMapJ1qYbed0zs
 id: commerce_order.pos.default
 targetEntityType: commerce_order
 bundle: pos
 mode: default
 content:
-  order_items:
-    type: inline_entity_form_complex
-    weight: 0
-    settings:
-      override_labels: true
-      label_singular: 'order item'
-      label_plural: 'order items'
-      allow_new: true
-      match_operator: CONTAINS
-      allow_existing: false
-      form_mode: default
-    third_party_settings: {  }
   adjustments:
     type: commerce_adjustment_default
     weight: 1
     settings: {  }
     third_party_settings: {  }
+    region: content
   mail:
     type: email_default
     weight: 2
@@ -37,6 +31,16 @@ content:
       size: 60
       placeholder: ''
     third_party_settings: {  }
+  order_items:
+    type: pos_order_item_widget
+    weight: 0
+    settings:
+      size: 60
+      placeholder: ''
+      num_results: 10
+      purchasable_entity_view_mode: commerce_pos_product_select
+    third_party_settings: {  }
+    region: content
   uid:
     type: inline_entity_form_complex
     weight: 0
@@ -53,6 +57,8 @@ content:
 hidden:
   billing_profile: true
   created: true
+  field_cashier: true
+  field_register: true
   ip_address: true
   order_number: true
   state: true
diff --git a/config/install/core.entity_view_display.commerce_order_item.default.commerce_pos_order_item.yml b/config/install/core.entity_view_display.commerce_order_item.default.commerce_pos_order_item.yml
new file mode 100644
index 0000000..27dfbf3
--- /dev/null
+++ b/config/install/core.entity_view_display.commerce_order_item.default.commerce_pos_order_item.yml
@@ -0,0 +1,51 @@
+uuid: 95eceb82-b5e8-4f1e-9010-02fab6f8c08f
+langcode: en
+status: true
+dependencies:
+  config:
+    - commerce_order.commerce_order_item_type.default
+    - core.entity_view_mode.commerce_order_item.commerce_pos_order_item
+  enforced:
+    module:
+      - commerce_product
+  module:
+    - commerce_price
+_core:
+  default_config_hash: YvPk7-s7bZEOuxWBbu1G5wo4qc-OOnZpmCwPUdhp40o
+id: commerce_order_item.default.commerce_pos_order_item
+targetEntityType: commerce_order_item
+bundle: default
+mode: commerce_pos_order_item
+content:
+  purchased_entity:
+    type: entity_reference_entity_view
+    weight: 0
+    settings:
+      view_mode: commerce_pos_product_select
+      link: false
+    third_party_settings: {  }
+    label: hidden
+    region: content
+  quantity:
+    type: number_decimal
+    weight: 1
+    settings:
+      thousand_separator: ''
+      decimal_separator: .
+      scale: 2
+      prefix_suffix: true
+    third_party_settings: {  }
+    label: inline
+    region: content
+  total_price:
+    type: commerce_price_default
+    weight: 2
+    settings:
+      strip_trailing_zeroes: false
+      display_currency_code: false
+    third_party_settings: {  }
+    label: inline
+    region: content
+hidden:
+  adjustments: true
+  unit_price: true
diff --git a/config/install/core.entity_view_display.commerce_product_variation.default.commerce_pos_product_select.yml b/config/install/core.entity_view_display.commerce_product_variation.default.commerce_pos_product_select.yml
new file mode 100644
index 0000000..028bd98
--- /dev/null
+++ b/config/install/core.entity_view_display.commerce_product_variation.default.commerce_pos_product_select.yml
@@ -0,0 +1,43 @@
+uuid: 99fc632a-7961-49a5-8265-1ba38655c484
+langcode: en
+status: true
+dependencies:
+  config:
+    - commerce_product.commerce_product_variation_type.default
+    - core.entity_view_mode.commerce_product_variation.commerce_pos_product_select
+    - field.field.commerce_product_variation.pos.field_upc
+  module:
+    - commerce_price
+id: commerce_product_variation.default.commerce_pos_product_select
+targetEntityType: commerce_product_variation
+bundle: default
+mode: commerce_pos_product_select
+content:
+  price:
+    label: inline
+    type: commerce_price_default
+    weight: 1
+    region: content
+    settings:
+      strip_trailing_zeroes: false
+      display_currency_code: false
+    third_party_settings: {  }
+  sku:
+    type: string
+    weight: 2
+    region: content
+    label: inline
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
+  title:
+    type: string
+    weight: 0
+    region: content
+    label: hidden
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
+hidden:
+  field_upc: true
+  product_id: true
diff --git a/config/install/core.entity_view_mode.commerce_order_item.commerce_pos_order_item.yml b/config/install/core.entity_view_mode.commerce_order_item.commerce_pos_order_item.yml
new file mode 100644
index 0000000..430b9b0
--- /dev/null
+++ b/config/install/core.entity_view_mode.commerce_order_item.commerce_pos_order_item.yml
@@ -0,0 +1,9 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - commerce_order
+id: commerce_order_item.commerce_pos_order_item
+label: 'Commerce POS order item'
+targetEntityType: commerce_order_item
+cache: true
diff --git a/config/install/core.entity_view_mode.commerce_product_variation.commerce_pos_product_select.yml b/config/install/core.entity_view_mode.commerce_product_variation.commerce_pos_product_select.yml
new file mode 100644
index 0000000..961084b
--- /dev/null
+++ b/config/install/core.entity_view_mode.commerce_product_variation.commerce_pos_product_select.yml
@@ -0,0 +1,9 @@
+langcode: en
+status: true
+dependencies:
+  module:
+    - commerce_product
+id: commerce_product_variation.commerce_pos_product_select
+label: 'Commerce POS product select'
+targetEntityType: commerce_product_variation
+cache: true
diff --git a/config/install/field.field.commerce_order.pos.field_order_items.yml b/config/install/field.field.commerce_order.pos.order_items.yml
similarity index 100%
rename from config/install/field.field.commerce_order.pos.field_order_items.yml
rename to config/install/field.field.commerce_order.pos.order_items.yml
diff --git a/src/Controller/PosOrderItemAutoComplete.php b/src/Controller/PosOrderItemAutoComplete.php
new file mode 100644
index 0000000..58744c4
--- /dev/null
+++ b/src/Controller/PosOrderItemAutoComplete.php
@@ -0,0 +1,127 @@
+<?php
+
+namespace Drupal\commerce_pos\Controller;
+
+use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Render\RendererInterface;
+use Drupal\user\PrivateTempStoreFactory;
+use Symfony\Component\HttpFoundation\JsonResponse;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\commerce_product\Entity\ProductVariation;
+
+/**
+ * Class PosOrderItemAutoComplete.
+ *
+ * @package Drupal\commerce_pos\Controller
+ */
+class PosOrderItemAutoComplete extends ControllerBase {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface
+   */
+  protected $entityDisplayRepository;
+
+  /**
+   * The tempstore object.
+   *
+   * @var \Drupal\user\SharedTempStore
+   */
+  protected $tempStore;
+
+  /**
+   * The renderer.
+   *
+   * @var \Drupal\Core\Render\RendererInterface
+   */
+  protected $renderer;
+
+  /**
+   * Constructs a new POS object.
+   */
+  public function __construct(EntityTypeManagerInterface $entity_type_manager, PrivateTempStoreFactory $temp_store_factory, RendererInterface $renderer) {
+    $this->entityTypeManager = $entity_type_manager;
+    $this->tempStore = $temp_store_factory->get('commerce_pos');
+    $this->renderer = $renderer;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static(
+      $container->get('entity_type.manager'),
+      $container->get('user.private_tempstore'),
+      $container->get('renderer')
+    );
+  }
+
+  /**
+   * Order item auto complete handler.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request $request
+   *   The request object.
+   * @param $entity_type
+   * @param $view_mode
+   * @param $count
+   *
+   * @return object
+   *   The Json object for auto complete suggestions.
+   */
+  public function orderItemAutoCompleteHandler(Request $request, $entity_type, $view_mode, $count) {
+
+    $results = [];
+    if ($input = $request->query->get('q')) {
+      $suggestions = $this->searchQueryString($input);
+      $view_builder = $this->entityTypeManager->getViewBuilder($entity_type);
+      foreach ($suggestions as $key) {
+        $product_variation = ProductVariation::load($key->variation_id);
+        $results[] = [
+          'value' => $product_variation->id(),
+          'label' => $this->renderer->renderPlain($view_builder->view($product_variation, $view_mode, $product_variation->language()->getId())),
+        ];
+      }
+    }
+
+    return new JsonResponse($results);
+  }
+
+  /**
+   * Helper function for searching the product.
+   *
+   * @param string $string
+   *   The Query string.
+   *
+   * @return mixed
+   *   The query search result.
+   */
+  public function searchQueryString($string) {
+    // Getting the Store ID.
+    $register = $this->tempStore->get('register');
+    if (!empty($register)) {
+      $register = \Drupal::entityTypeManager()->getStorage('commerce_pos_register')->load($register);
+      $store_id = $register->getStoreId();
+    }
+    else {
+      $store_storage = \Drupal::entityTypeManager()->getStorage('commerce_store');
+      $store_id = $store_storage->loadDefault()->id();
+    }
+
+    // @todo convert to entity query? This might be tricky... need to load all
+    // the products for a store and then all their variations?
+    $connection = \Drupal::service('database');
+    $query = $connection->select('commerce_product_variation_field_data', 'cpvd')
+      ->fields('cpvd', ['variation_id', 'product_id', 'title'])
+      ->range(0, 10);
+    $query->join('commerce_product__stores', 'cps', 'cps.entity_id = cpvd.product_id AND cps.stores_target_id = :store_id
+    AND cpvd.title LIKE :string', [':store_id' => $store_id, ':string' => '%' . $string . '%']);
+
+    $result = $query->execute()->fetchAll();
+
+    return $result;
+  }
+
+}
diff --git a/src/Form/POSForm.php b/src/Form/POSForm.php
index 6fc5ff7..ebd2cfe 100644
--- a/src/Form/POSForm.php
+++ b/src/Form/POSForm.php
@@ -3,8 +3,13 @@
 namespace Drupal\commerce_pos\Form;
 
 use Drupal\commerce_price\Price;
+use Drupal\Component\Datetime\TimeInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Entity\ContentEntityForm;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Url;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Drupal\commerce_price\Entity\Currency;
 use Drupal\commerce_order\Entity\Order;
@@ -14,6 +19,24 @@ use Drupal\commerce_order\Entity\Order;
  */
 class POSForm extends ContentEntityForm {
 
+  /**
+   * Constructs a ContentEntityForm object.
+   *
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager.
+   * @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entity_type_bundle_info
+   *   The entity type bundle service.
+   * @param \Drupal\Component\Datetime\TimeInterface $time
+   *   The time service.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory service.
+   */
+  public function __construct(EntityManagerInterface $entity_manager, EntityTypeBundleInfoInterface $entity_type_bundle_info = NULL, TimeInterface $time = NULL, ConfigFactoryInterface $config_factory) {
+    parent::__construct($entity_manager, $entity_type_bundle_info, $time);
+
+    $this->setConfigFactory($config_factory);
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -22,7 +45,7 @@ class POSForm extends ContentEntityForm {
       $container->get('entity.manager'),
       $container->get('entity_type.bundle.info'),
       $container->get('datetime.time'),
-      $container->get('current_user')
+      $container->get('config.factory')
     );
   }
 
@@ -40,11 +63,6 @@ class POSForm extends ContentEntityForm {
     $form['#tree'] = TRUE;
     $form['#theme'] = 'commerce_pos_form';
     $form['#attached']['library'][] = 'commerce_pos/form';
-    // @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';
-    }
 
     $step = $form_state->get('step');
     $step = $step ?: 'order';
@@ -89,6 +107,14 @@ class POSForm extends ContentEntityForm {
     ];
 
     $form['actions']['submit']['#value'] = t('Add Payment');
+    // Ensure the user is redirected back to this page after deleting an order.
+    if (isset($form['actions']['delete']['#url']) && $form['actions']['delete']['#url'] instanceof Url) {
+      $form['actions']['delete']['#url']->mergeOptions([
+        'query' => [
+          'destination' => Url::fromRoute('commerce_pos.main')->toString()
+        ]
+      ]);
+    }
 
     return $form;
   }
@@ -97,6 +123,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';
diff --git a/src/Plugin/Field/FieldWidget/PosOrderItemWidget.php b/src/Plugin/Field/FieldWidget/PosOrderItemWidget.php
new file mode 100644
index 0000000..6169a57
--- /dev/null
+++ b/src/Plugin/Field/FieldWidget/PosOrderItemWidget.php
@@ -0,0 +1,331 @@
+<?php
+
+namespace Drupal\commerce_pos\Plugin\Field\FieldWidget;
+
+use Drupal\commerce_order\Entity\Order;
+use Drupal\commerce_order\Entity\OrderItem;
+use Drupal\commerce_product\Entity\ProductVariation;
+use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\ReplaceCommand;
+use Drupal\Core\Entity\EntityDisplayRepositoryInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Field\FieldDefinitionInterface;
+use Drupal\Core\Field\FieldItemListInterface;
+use Drupal\Core\Field\WidgetBase;
+use Drupal\Core\Field\WidgetInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\Validator\ConstraintViolationInterface;
+
+/**
+ * Plugin implementation of the 'pos_order_item_widget' widget.
+ *
+ * @FieldWidget(
+ *   id = "pos_order_item_widget",
+ *   label = @Translation("Pos order item widget"),
+ *   field_types = {
+ *     "entity_reference"
+ *   },
+ *   multiple_values = true
+ * )
+ */
+class PosOrderItemWidget extends WidgetBase implements WidgetInterface, ContainerFactoryPluginInterface  {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface
+   */
+  protected $entityDisplayRepository;
+
+  /**
+   * Constructs a EntityReferenceEntityFormatter instance.
+   *
+   * @param string $plugin_id
+   *   The plugin_id for the formatter.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
+   *   The definition of the field to which the formatter is associated.
+   * @param array $settings
+   *   The formatter settings.
+   * @param array $third_party_settings
+   *   Any third party settings settings.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   * @param \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository
+   *   The entity display repository.
+   */
+  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings,  EntityTypeManagerInterface $entity_type_manager, EntityDisplayRepositoryInterface $entity_display_repository) {
+    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings);
+
+    $this->entityTypeManager = $entity_type_manager;
+    $this->entityDisplayRepository = $entity_display_repository;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $plugin_id,
+      $plugin_definition,
+      $configuration['field_definition'],
+      $configuration['settings'],
+      $configuration['third_party_settings'],
+      $container->get('entity_type.manager'),
+      $container->get('entity_display.repository')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function defaultSettings() {
+    return [
+      'size' => 60,
+      'placeholder' => 'Enter a product name',
+      'num_results' => 10,
+      'purchasable_entity_view_mode' => 'commerce_pos_product_select',
+      'order_item_view_mode' => 'commerce_pos_order_item',
+    ] + parent::defaultSettings();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state) {
+    $elements = [];
+
+    $elements['size'] = [
+      '#type' => 'number',
+      '#title' => t('Size of textfield'),
+      '#default_value' => $this->getSetting('size'),
+      '#required' => TRUE,
+      '#min' => 1,
+    ];
+    $elements['placeholder'] = [
+      '#type' => 'textfield',
+      '#title' => t('Placeholder'),
+      '#default_value' => $this->getSetting('placeholder'),
+      '#description' => t('Text that will be shown inside the field until a value is entered. This hint is usually a sample value or a brief description of the expected format.'),
+    ];
+    $elements['num_results'] = [
+      '#type' => 'number',
+      '#title' => t('Number of search results'),
+      '#default_value' => $this->getSetting('num_results'),
+      '#required' => TRUE,
+      '#min' => 1,
+      '#max' => 50,
+    ];
+    $elements['purchasable_entity_view_mode'] = [
+      '#type' => 'select',
+      '#title' => t('Purchasable entity view mode'),
+      '#default_value' => $this->getSetting('purchasable_entity_view_mode'),
+      '#required' => TRUE,
+      // @todo use the "Purchasable entity type" from the order type.
+      '#options' => $this->entityDisplayRepository->getViewModeOptions('commerce_product_variation'),
+      '#description' => 'This view mode is used for the list of product variations to select from.'
+    ];
+    $elements['order_item_view_mode'] = [
+      '#type' => 'select',
+      '#title' => t('Order item view mode'),
+      '#default_value' => $this->getSetting('order_item_view_mode'),
+      '#required' => TRUE,
+      // @todo use the .
+      '#options' => $this->entityDisplayRepository->getViewModeOptions('commerce_order_item'),
+      '#description' => 'This view mode is used list the order items on the form.'
+    ];
+
+    return $elements;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $summary = [];
+
+    $summary[] = t('Textfield size: @size', ['@size' => $this->getSetting('size')]);
+    if (!empty($this->getSetting('placeholder'))) {
+      $summary[] = t('Placeholder: @placeholder', ['@placeholder' => $this->getSetting('placeholder')]);
+    }
+
+    $summary[] = t('Number of results: @num_results', ['@num_results' => $this->getSetting('num_results')]);
+    $summary[] = t('Purchasable entity view mode: @view_mode', ['@view_mode' => $this->getSetting('purchasable_entity_view_mode')]);
+    $summary[] = t('Order item view mode: @view_mode', ['@view_mode' => $this->getSetting('order_item_view_mode')]);
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(FieldItemListInterface $items, array &$form, FormStateInterface $form_state, $get_delta = NULL) {
+    $new_form = parent::form($items, $form, $form_state, $get_delta);
+
+    return $new_form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function extractFormValues(FieldItemListInterface $items, array $form, FormStateInterface $form_state) {
+    // There's nothing to do here the order already has the references. They
+    // have been added by static::addOrderItem().
+    return;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
+    $element = [
+      '#type' => 'fieldset',
+      '#tree' => TRUE,
+      '#description' => $this->fieldDefinition->getDescription(),
+      '#field_title' => $this->fieldDefinition->getLabel(),
+    ] + $element;
+
+    $element['product_selector'] = [
+      '#type' => 'textfield',
+      '#size' => $this->getSetting('size'),
+      '#placeholder' => $this->getSetting('placeholder'),
+      '#maxlength' => $this->getFieldSetting('max_length'),
+      '#default_value' => NULL,
+      '#autocomplete_route_name' => 'commerce_pos.pos_order_item_widget_autocomplete',
+      '#autocomplete_route_parameters' => [
+        // @todo use the "Purchasable entity type" from the order type.
+        'entity_type' => 'commerce_product_variation',
+        'view_mode' => $this->getSetting('purchasable_entity_view_mode'),
+        'count' => $this->getSetting('num_results'),
+      ],
+      '#ajax' => [
+        'event' => 'autocompleteclose',
+        'callback' => [$this, 'addOrderItem'],
+      ]
+    ];
+
+    // Render a list of products that have been added to the order.
+    $referenced_entities = $items->referencedEntities();
+    $element['products'] = [];
+    /** @var \Drupal\commerce_order\Entity\OrderItem $entity */
+    foreach($referenced_entities as $entity) {
+      $product = $entity->getPurchasedEntity();
+      $view_builder = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId());
+      $element['products'][]['product'] = [
+        $view_builder->view($entity, $this->getSetting('order_item_view_mode'), $entity->language()->getId()),
+        [
+          '#type' => 'button',
+          '#value' => '+',
+          '#ajax' => [
+            'callback' => [$this, 'adjustOrder'],
+          ],
+          '#product_id' => $product->id(),
+          '#order_item_id' => $entity->id(),
+          '#quantity' => 1,
+        ],
+        [
+          '#type' => 'button',
+          '#value' => '-',
+          '#ajax' => [
+            'callback' => [$this, 'adjustOrder'],
+          ],
+          '#product_id' => $product->id(),
+          '#order_item_id' => $entity->id(),
+          '#quantity' => -1,
+        ],
+
+      ];
+    }
+
+    $element['#default_value'] = $items->referencedEntities();
+    return ['target_id' => $element];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function errorElement(array $element, ConstraintViolationInterface $error, array $form, FormStateInterface $form_state) {
+    return isset($element['target_id']) ? $element['target_id'] : FALSE;
+  }
+
+  public static function adjustOrder($form, FormStateInterface &$form_state) {
+    $trigger_element = $form_state->getTriggeringElement();
+    $order_item = OrderItem::load($trigger_element['#order_item_id']);
+    $new_quantity = $order_item->getQuantity() + $trigger_element['#quantity'];
+    /** @var \Drupal\commerce_order\Entity\Order $order */
+    $order = $order_item->getOrder();
+    if ($new_quantity > 0) {
+      $order_item->setQuantity($order_item->getQuantity() + $trigger_element['#quantity']);
+      $order_item->save();
+    }
+    else {
+      $order->removeItem($order_item);
+      $order_item->delete();
+    }
+    $order->recalculateTotalPrice()->save();
+    return static::updateOrderForm($order, $form, $form_state);
+  }
+
+  public static function addOrderItem($form, FormStateInterface &$form_state) {
+    // Loading the product variation object.
+    $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.
+      return $form;
+    }
+
+    // Remove the user input as we no longer need it.
+    $user_input = $form_state->getUserInput();
+    unset($user_input['order_items']['target_id']['product_selector']);
+    $form_state->setUserInput($user_input);
+
+    // If there is already an order item for this variation add to the quantity.
+    $create_new_order_item = TRUE;
+    // For some reason this doesn't work :(
+//    $order = $form_state->getFormObject()->getEntity();
+//    $order = Order::load($order->id());
+    $order = \Drupal::getContainer()->get('commerce_pos.current_order')->get();
+    /** @var \Drupal\commerce_order\Entity\OrderItem $order_item */
+    foreach ($order->getItems() as $order_item) {
+      if ($order_item->getPurchasedEntity()->id() === $product_variation->id()) {
+        $create_new_order_item = FALSE;
+        $order_item
+          ->setQuantity($order_item->getQuantity() + 1)
+          ->save();
+        $order->recalculateTotalPrice();
+        $order->save();
+        break;
+      }
+    }
+    if ($create_new_order_item) {
+      // Create new order Item for adding into existing order.
+      $order_item = OrderItem::create([
+        'type' => 'default',
+        'purchased_entity' => $product_variation,
+        'quantity' => 1,
+        'unit_price' => $product_variation->getPrice(),
+      ]);
+      $order_item->save();
+
+      // Adding the item into the Order.
+      $order->addItem($order_item)->recalculateTotalPrice()->save();
+    }
+
+    return static::updateOrderForm($order, $form, $form_state);
+  }
+
+  protected static function updateOrderForm(Order $order, $form, FormStateInterface $form_state) {
+    $form_object = $form_state->getFormObject();
+    $form_object->setEntity($order);
+    // Rebuild the entire form.
+    $form = \Drupal::formBuilder()->rebuildForm($form_object->getFormId(), $form_state, $form);
+    $response = new AjaxResponse();
+    $response->addCommand(new ReplaceCommand('form.commerce-pos', $form));
+    return $response;
+  }
+
+}
diff --git a/tests/fixtures/setup_test_pos.php b/tests/fixtures/setup_test_pos.php
new file mode 100644
index 0000000..91c83f4
--- /dev/null
+++ b/tests/fixtures/setup_test_pos.php
@@ -0,0 +1,61 @@
+<?php
+
+/**
+ * Script to set up configure a test POS set up to make testing and development
+ * simple.
+ */
+
+include_once \Drupal::root() . '/core/tests/Drupal/Tests/RandomGeneratorTrait.php';
+# Create a store.
+class storeCreator {
+  /** @todo  */
+  use \Drupal\Tests\RandomGeneratorTrait;
+  use \Drupal\commerce_store\StoreCreationTrait { createStore as public; }
+
+  public function createProductionVariation(array $values = []) {
+    $variation = \Drupal\commerce_product\Entity\ProductVariation::create($values + [
+      'type' => 'default',
+      'sku' => strtolower($this->randomMachineName()),
+      'title' => $this->randomMachineName(),
+      'status' => 1,
+      'price' => new \Drupal\commerce_price\Price(mt_rand(10,100), 'USD'),
+    ]);
+    $variation->save();
+    return $variation;
+  }
+
+  public function createProduct(array $values = []) {
+    $product = \Drupal\commerce_product\Entity\Product::create($values + [
+      'type' => 'default',
+      'title' => $this->randomMachineName(),
+    ]);
+    $product->save();
+    return $product;
+  }
+}
+
+$storeCreator = new storeCreator();
+$test_store = $storeCreator->createStore('POS test store', 'pos_test_store@example.com', 'physical');
+
+$register = \Drupal\commerce_pos\Entity\Register::create([
+  'store_id' => $test_store->id(),
+  'name' => 'Test register',
+  'cash' => new \Drupal\commerce_price\Price('1000.00', 'USD'),
+]);
+$register->save();
+
+$variations = [
+  $storeCreator->createProductionVariation(['title' => 'T-shirt XL']),
+  $storeCreator->createProductionVariation(['title' => 'T-shirt L']),
+  $storeCreator->createProductionVariation(['title' => 'T-shirt M']),
+];
+
+$storeCreator->createProduct(['variations' => $variations, 'title' => 'T-shirt', 'stores' => [$test_store]]);
+
+$variations = [
+  $storeCreator->createProductionVariation(['title' => 'Jumper XL']),
+  $storeCreator->createProductionVariation(['title' => 'Jumper L']),
+  $storeCreator->createProductionVariation(['title' => 'Jumper M']),
+];
+
+$storeCreator->createProduct(['variations' => $variations, 'title' => 'Jumper', 'stores' => [$test_store]]);
