diff --git a/modules/cart/commerce_cart.module b/modules/cart/commerce_cart.module
index c24ffa7..b9b514d 100644
--- a/modules/cart/commerce_cart.module
+++ b/modules/cart/commerce_cart.module
@@ -9,6 +9,7 @@ use Drupal\commerce_order\Entity\OrderInterface;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Field\BaseFieldDefinition;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\commerce_order\Entity\Order;
 
 /**
  * Implements hook_entity_base_field_info().
@@ -47,6 +48,55 @@ function commerce_cart_commerce_order_delete(OrderInterface $order) {
 }
 
 /**
+ * Implements hook_form_alter() for Views commerce cart forms.
+ */
+function commerce_cart_form_alter(array &$form, FormStateInterface $form_state) {
+  // Check for a Views commerce cart forms.
+  if ($form_state->get('step') == 'views_form_views_form') {
+    /** @var \Drupal\views\Entity\View $view */
+    $view = reset($form_state->getBuildInfo()['args'])->storage;
+    if (commerce_cart_is_commerce_cart_form_view($view)) {
+      $view_argument = reset($view->getExecutable()->argument);
+      if (!empty($view_argument->value)) {
+        // Replace the form submit button label.
+        $form['actions']['submit']['#value'] = t('Update cart');
+
+        $order_id = $view_argument->getValue();
+        /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
+        $order = Order::load($order_id);
+        $form_state->set('order_id', $order->id());
+        // Order version must be sent to the client, for later overwrite error checking.
+        $form['version'] = [
+          '#type' => 'hidden',
+          '#default_value' => $order->getVersion(),
+        ];
+        // Add validation.
+        $form['actions']['submit']['#validate'][] = 'commerce_cart_commerce_cart_form_validate';
+        // Also for remove button is available.
+        if (!empty($form['remove_button'])) {
+          foreach (\Drupal\Core\Render\Element::children($form['remove_button']) as $key) {
+            $form['remove_button'][$key]['#validate'][] = 'commerce_cart_commerce_cart_form_validate';
+          }
+        }
+      }
+    }
+  }
+}
+
+/**
+ * Validate handler for Views commerce cart forms.
+ */
+function commerce_cart_commerce_cart_form_validate($form, FormStateInterface $form_state) {
+  // Re-load the order.
+  /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
+  $order = Order::load($form_state->get('order_id'));
+  // A change to the order version must not validate.
+  if ($order->getVersion() > $form_state->getValue('version')) {
+    $form_state->setErrorByName('', t('The order has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.'));
+  }
+}
+
+/**
  * Implements hook_form_BASE_FORM_ID_alter() for 'commerce_order_form'.
  */
 function commerce_cart_form_commerce_order_form_alter(array &$form, FormStateInterface $form_state) {
@@ -57,6 +107,10 @@ function commerce_cart_form_commerce_order_form_alter(array &$form, FormStateInt
       // Move the cart element to the bottom of the meta sidebar container.
       $form['cart']['#group'] = 'meta';
       $form['cart']['#weight'] = 100;
+      // Warning it the order is cart and it was modified in the last hour.
+      if (!empty($order->get('cart')->value) && (REQUEST_TIME - $order->getChangedTime()) < 3600) {
+        drupal_set_message(t('This order has been modified by the customer in the last hour. Modifying it here could cause their future changes to be lost. Proceed with caution.'), 'warning');
+      }
     }
     else {
       // Only draft orders can be carts.
@@ -78,7 +132,7 @@ function commerce_cart_form_commerce_order_type_form_alter(array &$form, FormSta
   $view_storage = \Drupal::entityTypeManager()->getStorage('view');
   $available_views = [];
   foreach ($view_storage->loadMultiple() as $view) {
-    if (strpos($view->get('tag'), 'commerce_cart_form') !== FALSE) {
+    if (commerce_cart_is_commerce_cart_form_view($view)) {
       $available_views[$view->id()] = $view->label();
     }
   }
@@ -146,3 +200,24 @@ function commerce_cart_views_data_alter(array &$data) {
     'id' => 'commerce_line_item_remove_button',
   ];
 }
+
+/**
+ * Helper function to check if a view is a 'commerce_cart_form' view.
+ *
+ *  @param \Drupal\views\Entity\View $view
+ *
+ * @return bool
+ *   True if View has 'commerce_cart_form' like tag, has commerce_order as
+ *   base table and the order_id as the first argument.
+ *   Otherwise return FALSE.
+ */
+function commerce_cart_is_commerce_cart_form_view($view) {
+  // Check for a Views form with 'commerce_cart_form' like tag.
+  if ($view->get('base_table') == 'commerce_order' && strpos($view->get('tag'), 'commerce_cart_form') !== FALSE) {
+    $view_argument = reset($view->getExecutable()->getDisplay()->options['arguments']);
+    if ($view_argument['field'] == 'order_id') {
+      return TRUE;
+    }
+  }
+  return FALSE;
+}
diff --git a/modules/cart/src/Plugin/views/field/EditQuantity.php b/modules/cart/src/Plugin/views/field/EditQuantity.php
index 2f4a68e..5e6d218 100644
--- a/modules/cart/src/Plugin/views/field/EditQuantity.php
+++ b/modules/cart/src/Plugin/views/field/EditQuantity.php
@@ -107,8 +107,6 @@ class EditQuantity extends FieldPluginBase {
         '#step' => 1,
       ];
     }
-    // Replace the form submit button label.
-    $form['actions']['submit']['#value'] = $this->t('Update cart');
   }
 
   /**
diff --git a/modules/order/commerce_order.module b/modules/order/commerce_order.module
index 7686686..3a8e92b 100644
--- a/modules/order/commerce_order.module
+++ b/modules/order/commerce_order.module
@@ -29,6 +29,18 @@ function commerce_order_theme($existing, $type, $theme, $path) {
 }
 
 /**
+ * Implements hook_entity_type_alter().
+ *
+ * @param \Drupal\Core\Entity\EntityTypeInterface[] $entity_types
+ */
+function commerce_order_entity_type_alter(array &$entity_types) {
+  // Unset EntityChanged constraint for Commerce order entities.
+  $order_constraints = $entity_types['commerce_order']->getConstraints();
+  unset($order_constraints['EntityChanged']);
+  $entity_types['commerce_order']->setConstraints($order_constraints);
+}
+
+/**
  * Implements hook_ENTITY_TYPE_presave().
  */
 function commerce_order_commerce_order_presave(OrderInterface $order) {
diff --git a/modules/order/src/Entity/Order.php b/modules/order/src/Entity/Order.php
index fbffdce..57f694f 100644
--- a/modules/order/src/Entity/Order.php
+++ b/modules/order/src/Entity/Order.php
@@ -45,7 +45,7 @@ use Drupal\profile\Entity\ProfileInterface;
  *     "id" = "order_id",
  *     "label" = "order_number",
  *     "uuid" = "uuid",
- *     "bundle" = "type"
+ *     "bundle" = "type",
  *   },
  *   links = {
  *     "canonical" = "/admin/commerce/orders/{commerce_order}",
@@ -55,7 +55,10 @@ use Drupal\profile\Entity\ProfileInterface;
  *     "collection" = "/admin/commerce/orders"
  *   },
  *   bundle_entity_type = "commerce_order_type",
- *   field_ui_base_route = "entity.commerce_order_type.edit_form"
+ *   field_ui_base_route = "entity.commerce_order_type.edit_form",
+ *   constraints = {
+ *     "OrderVersion" = {}
+ *   }
  * )
  */
 class Order extends ContentEntityBase implements OrderInterface {
@@ -82,6 +85,16 @@ class Order extends ContentEntityBase implements OrderInterface {
         $this->setEmail($this->getOwner()->getEmail());
       }
     }
+    else {
+      // Increment order version on each save.
+      $saved_entity = $storage->loadUnchanged($this->id());
+      // A change to the order version must add an exception.
+      if ($saved_entity && $saved_entity->getVersion() > $this->getVersion()) {
+        throw new OrderVersionMismatchException('The order has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.');
+      }
+      $version = $this->getVersion() + 1;
+      $this->setVersion($version);
+    }
 
     // Recalculate the total.
     // @todo Rework this once pricing is finished.
@@ -131,6 +144,21 @@ class Order extends ContentEntityBase implements OrderInterface {
   /**
    * {@inheritdoc}
    */
+  public function getVersion() {
+    return $this->get('version')->value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setVersion($version) {
+    $this->set('version', $version);
+    return $this;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function getOrderNumber() {
     return $this->get('order_number')->value;
   }
@@ -389,6 +417,13 @@ class Order extends ContentEntityBase implements OrderInterface {
   public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
     $fields = self::entityKeysBaseFieldDefinitions($entity_type);
 
+    $fields['version'] = BaseFieldDefinition::create('integer')
+      ->setLabel(t('Version'))
+      ->setDescription(t('The order version number, it gets incremented on each save.'))
+      ->setReadOnly(TRUE)
+      ->setSetting('unsigned', TRUE)
+      ->setDefaultValue(1);
+
     $fields['order_number'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Order number'))
       ->setDescription(t('The order number displayed to the customer.'))
diff --git a/modules/order/src/Entity/OrderInterface.php b/modules/order/src/Entity/OrderInterface.php
index bdbb3c2..ae8f092 100644
--- a/modules/order/src/Entity/OrderInterface.php
+++ b/modules/order/src/Entity/OrderInterface.php
@@ -37,6 +37,24 @@ interface OrderInterface extends EntityStoreInterface, EntityChangedInterface, E
   public function setOrderNumber($order_number);
 
   /**
+   * Gets the order version identifier.
+   *
+   * @return int
+   *   Version identifier of the order.
+   */
+  public function getVersion();
+
+  /**
+   * Sets the order version identifier.
+   *
+   * @param int
+   *   Version identifier of the order.
+   *
+   * @return $this
+   */
+  public function setVersion($version);
+
+  /**
    * Gets the order state.
    *
    * @return \Drupal\state_machine\Plugin\Field\FieldType\StateItemInterface
diff --git a/modules/order/src/Exception/ExceptionInterface.php b/modules/order/src/Exception/ExceptionInterface.php
new file mode 100644
index 0000000..d46f318
--- /dev/null
+++ b/modules/order/src/Exception/ExceptionInterface.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\commerce_order\Exception\ExceptionInterface.
+ */
+
+namespace Drupal\commerce_order\Exception;
+
+/**
+ * Exception interface for all exceptions thrown by the Order module.
+ */
+interface ExceptionInterface { }
diff --git a/modules/order/src/Exception/OrderVersionMismatchException.php b/modules/order/src/Exception/OrderVersionMismatchException.php
new file mode 100644
index 0000000..30b4496
--- /dev/null
+++ b/modules/order/src/Exception/OrderVersionMismatchException.php
@@ -0,0 +1,12 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\commerce_order\Exception\OrderVersionMismatchException.
+ */
+
+namespace Drupal\commerce_order\Exception;
+
+/**
+ * Thrown when attempting to save an order with wrong version.
+ */
+class OrderVersionMismatchException extends \RuntimeException implements ExceptionInterface { }
diff --git a/modules/order/src/Form/OrderForm.php b/modules/order/src/Form/OrderForm.php
index 5075401..44f4ab1 100644
--- a/modules/order/src/Form/OrderForm.php
+++ b/modules/order/src/Form/OrderForm.php
@@ -66,6 +66,11 @@ class OrderForm extends ContentEntityForm {
       '#type' => 'hidden',
       '#default_value' => $order->getChangedTime(),
     ];
+    // Version must be sent to the client, for later overwrite error checking.
+    $form['version'] = [
+      '#type' => 'hidden',
+      '#default_value' => $order->getVersion(),
+    ];
 
     $last_saved = $this->dateFormatter->format($order->getChangedTime(), 'short');
     $form['advanced'] = [
@@ -158,7 +163,8 @@ class OrderForm extends ContentEntityForm {
    * {@inheritdoc}
    */
   public function save(array $form, FormStateInterface $form_state) {
-    $this->entity->save();
+    $order = $this->getEntity();
+    $order->save();
     drupal_set_message($this->t('The order %label has been successfully saved.', ['%label' => $this->entity->label()]));
     $form_state->setRedirect('entity.commerce_order.collection');
   }
diff --git a/modules/order/src/Plugin/Validation/Constraint/OrderVersionConstraint.php b/modules/order/src/Plugin/Validation/Constraint/OrderVersionConstraint.php
new file mode 100644
index 0000000..1f2c4e8
--- /dev/null
+++ b/modules/order/src/Plugin/Validation/Constraint/OrderVersionConstraint.php
@@ -0,0 +1,24 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\commerce_order\Plugin\Validation\Constraint\OrderVersionConstraint.
+ */
+
+namespace Drupal\commerce_order\Plugin\Validation\Constraint;
+
+use Symfony\Component\Validator\Constraint;
+
+/**
+ * Validation constraint for the order version.
+ *
+ * @Constraint(
+ *   id = "OrderVersion",
+ *   label = @Translation("Order version", context = "Validation"),
+ *   type = "entity:commerce_order"
+ * )
+ */
+class OrderVersionConstraint extends Constraint {
+
+  public $message = 'The order has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.';
+}
diff --git a/modules/order/src/Plugin/Validation/Constraint/OrderVersionConstraintValidator.php b/modules/order/src/Plugin/Validation/Constraint/OrderVersionConstraintValidator.php
new file mode 100644
index 0000000..ab3d968
--- /dev/null
+++ b/modules/order/src/Plugin/Validation/Constraint/OrderVersionConstraintValidator.php
@@ -0,0 +1,34 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\commerce_order\Plugin\Validation\Constraint\OrderVersionConstraintValidator.
+ */
+
+namespace Drupal\commerce_order\Plugin\Validation\Constraint;
+
+use Symfony\Component\Validator\Constraint;
+use Symfony\Component\Validator\ConstraintValidator;
+
+/**
+ * Validates the OrderVersion constraint.
+ */
+class OrderVersionConstraintValidator extends ConstraintValidator {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validate($entity, Constraint $constraint) {
+    if (isset($entity)) {
+      /** @var \Drupal\Core\Entity\EntityInterface $entity */
+      if (!$entity->isNew()) {
+        $saved_entity = \Drupal::entityManager()->getStorage($entity->getEntityTypeId())->loadUnchanged($entity->id());
+        // A change to the order version must add a violation.
+        if ($saved_entity && $saved_entity->getVersion() > $entity->getVersion()) {
+          $this->context->addViolation($constraint->message);
+        }
+      }
+    }
+  }
+
+}
diff --git a/modules/order/src/Tests/OrderConstraintsTest.php b/modules/order/src/Tests/OrderConstraintsTest.php
new file mode 100644
index 0000000..1b0fb68
--- /dev/null
+++ b/modules/order/src/Tests/OrderConstraintsTest.php
@@ -0,0 +1,71 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\commerce_order\Tests\OrderConstraintsTest.
+ */
+
+namespace Drupal\commerce_order\Tests;
+
+use Drupal\commerce_order\Tests\OrderTestBase;
+
+/**
+ * Tests order level validation constraints.
+ *
+ * @group commerce
+ */
+class OrderConstraintsTest extends OrderTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+  }
+
+  /**
+   * Tests defining order constraints via order type annotations and hooks.
+   */
+  public function testOrderConstraintDefinition() {
+    // Test reading the annotation. There should be a single constraint,
+    // the OrderRevision defined in the order module.
+    // The core EntityChanged constraint should be unset (not available).
+    $order_type = \Drupal::service('entity_type.manager')->getDefinition('commerce_order');
+    $default_constraints = ['OrderVersion' => []];
+    $this->assertEqual($default_constraints, $order_type->getConstraints());
+  }
+
+  /**
+   * Tests order constraints are validated.
+   */
+  public function testOrderConstraintValidation() {
+    $line_item = $this->createEntity('commerce_line_item', [
+      'type' => 'product_variation',
+    ]);
+    /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
+    $order = $this->createEntity('commerce_order', [
+      'type' => 'default',
+      'mail' => $this->loggedInUser->getEmail(),
+      'line_items' => [$line_item],
+      'store_id' => $this->store->id(),
+    ]);
+
+    // Validate the order created.
+    $violations = $order->validate();
+    $this->assertEqual(count($violations), 0, 'No violations when validating a default order.');
+    if (count($violations) > 0 && !empty($violations[0])) {
+      $this->pass($violations[0]->getMessage() . $violations[0]->getPropertyPath());
+    }
+
+    // Save the order for version increment.
+    $order->save();
+
+    // Set the version to 1 (first version).
+    $order->set('version', 1);
+    $violations = $order->validate();
+    $this->assertEqual(count($violations), 1, 'Violation found when version is less the last version.');
+    $this->assertEqual($violations[0]->getPropertyPath(), '');
+    $this->assertEqual($violations[0]->getMessage(), 'The order has either been modified by another user, or you have already submitted modifications. As a result, your changes cannot be saved.');
+  }
+
+}
