diff --git a/payment/uc_credit/uc_credit.module b/payment/uc_credit/uc_credit.module
index ee765e3..88bafc8 100644
--- a/payment/uc_credit/uc_credit.module
+++ b/payment/uc_credit/uc_credit.module
@@ -5,6 +5,7 @@
  * Defines the credit card payment method and hooks in payment gateways.
  */
 
+use Drupal\uc_order\UcOrderInterface;
 use Drupal\uc_store\Encryption;
 
 /** Just authorize an amount on a credit card account. */
@@ -200,14 +201,6 @@ function uc_credit_uc_store_status() {
  * Implements hook_uc_order().
  */
 function uc_credit_uc_order($op, $order, $arg2) {
-  // Set up the encryption key and object for saving and loading.
-  if ($order->getPaymentMethodId() == 'credit' && ($op == 'save' || $op == 'load')) {
-    // Log an error if encryption isn't configured properly.
-    if (!uc_credit_encryption_key()) {
-      watchdog('uc_credit', 'Credit card encryption must be set up to process credit cards.');
-    }
-  }
-
   switch ($op) {
     case 'submit':
       if ($order->getPaymentMethodId() == 'credit') {
@@ -232,24 +225,32 @@ function uc_credit_uc_order($op, $order, $arg2) {
         }
       }
       break;
+  }
+}
 
-    case 'save':
-      if ($order->getPaymentMethodId() == 'credit' && !empty($order->payment_details)) {
-        _uc_credit_save_cc_data_to_order($order->payment_details, $order->id());
+/**
+ * Implements hook_uc_order_load().
+ */
+function uc_credit_uc_order_load($orders) {
+  foreach ($order as $order) {
+    if ($order->getPaymentMethodId() == 'credit') {
+      // Load the CC details from the credit cache if available.
+      $order->payment_details = uc_credit_cache('load');
+
+      // Otherwise load any details that might be stored in the data array.
+      if (empty($order->payment_details) && isset($order->data['cc_data'])) {
+        $order->payment_details = uc_credit_cache('save', $order->data['cc_data']);
       }
-      break;
-
-    case 'load':
-      if ($order->getPaymentMethodId() == 'credit') {
-        // Load the CC details from the credit cache if available.
-        $order->payment_details = uc_credit_cache('load');
+    }
+  }
+}
 
-        // Otherwise load any details that might be stored in the data array.
-        if (empty($order->payment_details) && isset($order->data['cc_data'])) {
-          $order->payment_details = uc_credit_cache('save', $order->data['cc_data']);
-        }
-      }
-      break;
+/**
+ * Implements hook_uc_order_update().
+ */
+function uc_credit_uc_order_update(UcOrderInterface $order) {
+  if ($order->getPaymentMethodId() == 'credit' && !empty($order->payment_details)) {
+    _uc_credit_save_cc_data_to_order($order->payment_details, $order->id());
   }
 }
 
diff --git a/payment/uc_payment/uc_payment.api.php b/payment/uc_payment/uc_payment.api.php
index af7684e..35f5778 100644
--- a/payment/uc_payment/uc_payment.api.php
+++ b/payment/uc_payment/uc_payment.api.php
@@ -166,11 +166,11 @@ function hook_uc_payment_method() {
  *   should clean up any extra data they stored related to the order.
  * - "order-details": Called when an order is being edited by an administrator.
  *   Return a string or a form array to be displayed to the administator.
- * - "order-load": Called from hook_uc_order('load') when this payment method
+ * - "order-load": Called from hook_uc_order_load() when this payment method
  *   is selected for the order.
  * - "order-process": Called when an order has been edited by an administrator.
  *   Process any form elements returned by the "order-details" op.
- * - "order-save": Called from hook_uc_order('save') when this payment method
+ * - "order-save": Called from hook_uc_order_update() when this payment method
  *   is selected for the order.
  * - "order-submit": Called from hook_uc_order('submit') when this payment
  *   method is selected for the order.
diff --git a/payment/uc_payment/uc_payment.module b/payment/uc_payment/uc_payment.module
index 783498d..9a57b9b 100644
--- a/payment/uc_payment/uc_payment.module
+++ b/payment/uc_payment/uc_payment.module
@@ -125,35 +125,11 @@ function uc_payment_uc_order($op, $order) {
     case 'submit':
       return Drupal::service('plugin.manager.uc_payment.method')->createFromOrder($order)->orderSubmit($order);
 
-    case 'load':
-      if ($order->getPaymentMethodId()) {
-        Drupal::service('plugin.manager.uc_payment.method')->createFromOrder($order)->orderLoad($order);
-      }
-      break;
-
-    case 'save':
-      if ($order->getPaymentMethodId()) {
-        Drupal::service('plugin.manager.uc_payment.method')->createFromOrder($order)->orderSave($order);
-      }
-      break;
-
     case 'can_delete':
       if (uc_payment_load_payments($order->id()) !== FALSE) {
         return FALSE;
       }
       break;
-
-    case 'delete':
-      db_delete('uc_payment_receipts')
-        ->condition('order_id', $order->id())
-        ->execute();
-
-      // Call each payment method to delete method-specific data from the
-      // database.
-      foreach (uc_payment_method_list() as $id => $method) {
-        Drupal::service('plugin.manager.uc_payment.method')->createInstance($id)->orderDelete($order);
-      }
-      break;
   }
 }
 
@@ -394,19 +370,46 @@ function uc_payment_uc_payment_entered(UcOrderInterface $order) {
 }
 
 /**
+ * Implements hook_uc_order_load().
+ */
+function uc_payment_uc_order_load($orders) {
+  foreach ($orders as $order) {
+    if ($order->getPaymentMethodId()) {
+      Drupal::service('plugin.manager.uc_payment.method')->createFromOrder($order)->orderLoad($order);
+    }
+  }
+}
+
+/**
  * Implements hook_uc_order_update().
- *
- * Move non-shippable orders from "payment received" to "completed".
- *
- * @todo Remove when Rules is available.
  */
 function uc_payment_uc_order_update(UcOrderInterface $order) {
+  if ($order->getPaymentMethodId()) {
+    Drupal::service('plugin.manager.uc_payment.method')->createFromOrder($order)->orderSave($order);
+  }
+
+  // Move non-shippable orders from "payment received" to "completed".
+  // @todo Remove when Rules is available.
   if ($order->getStatusId() == 'payment_received' && !$order->isShippable()) {
     $order->setStatusId('completed')->save();
   }
 }
 
 /**
+ * Implements hook_uc_order_delete().
+ */
+function uc_payment_uc_order_delete(UcOrderInterface $order) {
+  db_delete('uc_payment_receipts')
+    ->condition('order_id', $order->id())
+    ->execute();
+
+  // Call each payment method to delete method-specific data from the database.
+  foreach (uc_payment_method_list() as $id => $method) {
+    Drupal::service('plugin.manager.uc_payment.method')->createInstance($id)->orderDelete($order);
+  }
+}
+
+/**
  * Deletes a payment from the database.
  */
 function uc_payment_delete($receipt_id) {
diff --git a/shipping/uc_quote/uc_quote.module b/shipping/uc_quote/uc_quote.module
index 42d53e4..5b2b9dd 100644
--- a/shipping/uc_quote/uc_quote.module
+++ b/shipping/uc_quote/uc_quote.module
@@ -12,6 +12,7 @@
 use Drupal\Core\Ajax\AjaxResponse;
 use Drupal\Core\Ajax\PrependCommand;
 use Drupal\Core\Ajax\ReplaceCommand;
+use Drupal\uc_order\UcOrderInterface;
 use Drupal\uc_store\Address;
 
 /**
@@ -284,38 +285,42 @@ function uc_quote_uc_order_pane() {
 }
 
 /**
- * Implements hook_uc_order().
+ * Implements hook_uc_order_load().
  */
-function uc_quote_uc_order($op, $order, $arg2) {
-  switch ($op) {
-    case 'save':
-      if (isset($order->quote['method'])) {
-        db_merge('uc_order_quotes')
-          ->key(array('order_id' => $order->id()))
-          ->fields(array(
-            'method' => $order->quote['method'],
-            'accessorials' => $order->quote['accessorials'],
-            'rate' => $order->quote['rate'],
-          ))
-          ->execute();
-      }
-      break;
-
-    case 'load':
-      $quote = db_query("SELECT method, accessorials, rate FROM {uc_order_quotes} WHERE order_id = :id", array(':id' => $order->id()))->fetchAssoc();
-      $order->quote = $quote;
-      $order->quote['accessorials'] = strval($quote['accessorials']);
-      break;
+function uc_quote_uc_order_load($orders) {
+  foreach ($orders as $order) {
+    $quote = db_query("SELECT method, accessorials, rate FROM {uc_order_quotes} WHERE order_id = :id", array(':id' => $order->id()))->fetchAssoc();
+    $order->quote = $quote;
+    $order->quote['accessorials'] = strval($quote['accessorials']);
+  }
+}
 
-    case 'delete':
-      db_delete('uc_order_quotes')
-        ->condition('order_id', $order->id())
-        ->execute();
-      break;
+/**
+ * Implements hook_uc_order_update().
+ */
+function uc_quote_uc_order_update(UcOrderInterface $order) {
+  if (isset($order->quote['method'])) {
+    db_merge('uc_order_quotes')
+      ->key(array('order_id' => $order->id()))
+      ->fields(array(
+        'method' => $order->quote['method'],
+        'accessorials' => $order->quote['accessorials'],
+        'rate' => $order->quote['rate'],
+      ))
+      ->execute();
   }
 }
 
 /**
+ * Implements hook_uc_order_delete().
+ */
+function uc_quote_uc_order_delete(UcOrderInterface $order) {
+  db_delete('uc_order_quotes')
+    ->condition('order_id', $order->id())
+    ->execute();
+}
+
+/**
  * Implements hook_uc_line_item().
  */
 function uc_quote_uc_line_item() {
@@ -764,7 +769,7 @@ function uc_quote_apply_quote_to_order($form, &$form_state) {
       }
 
       // Save selected shipping
-      uc_quote_uc_order('save', $order, '');
+      uc_quote_uc_order_update($order);
 
       // Update line items.
       $order->line_items = uc_order_load_line_items($order);
diff --git a/uc_order/lib/Drupal/uc_order/Entity/UcOrder.php b/uc_order/lib/Drupal/uc_order/Entity/UcOrder.php
index 536c4c8..5b7b9ea 100644
--- a/uc_order/lib/Drupal/uc_order/Entity/UcOrder.php
+++ b/uc_order/lib/Drupal/uc_order/Entity/UcOrder.php
@@ -108,8 +108,6 @@ class UcOrder extends ContentEntityBase implements UcOrderInterface {
 
       $order->products = entity_load_multiple_by_properties('uc_order_product', array('order_id' => $id));
 
-      uc_order_module_invoke('load', $order, NULL);
-
       // Load line items... has to be last after everything has been loaded.
       $order->line_items = uc_order_load_line_items($order);
     }
@@ -129,8 +127,6 @@ class UcOrder extends ContentEntityBase implements UcOrderInterface {
     }
     $this->host->value = \Drupal::request()->getClientIp();
     $this->modified->value = REQUEST_TIME;
-
-    uc_order_module_invoke('presave', $this, NULL);
   }
 
   /**
@@ -142,8 +138,6 @@ class UcOrder extends ContentEntityBase implements UcOrderInterface {
       uc_order_product_save($this->id(), $product);
     }
 
-    uc_order_module_invoke('save', $this, NULL);
-
     // Record a log entry if the order status has changed.
     if ($update && $this->getStatusId() != $this->original->getStatusId()) {
       $this->logChanges(array(t('Order status') => array(
@@ -158,15 +152,6 @@ class UcOrder extends ContentEntityBase implements UcOrderInterface {
   /**
    * {@inheritdoc}
    */
-  public static function preDelete(EntityStorageControllerInterface $storage_controller, array $orders) {
-    foreach ($orders as $order) {
-      uc_order_module_invoke('delete', $order, NULL);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public static function postDelete(EntityStorageControllerInterface $storage_controller, array $orders) {
     // Delete data from the appropriate Ubercart order tables.
     $ids = array_keys($orders);
diff --git a/uc_order/uc_order.api.php b/uc_order/uc_order.api.php
index b09400f..6dfeff5 100644
--- a/uc_order/uc_order.api.php
+++ b/uc_order/uc_order.api.php
@@ -126,18 +126,6 @@ function hook_uc_line_item_data_alter(&$items) {
  *   This is the order object.
  * @param $arg2
  *   This is variable and is based on the value of $op:
- *   - new: Called when an order is created. $order is a reference to the new
- *     order object, so modules may add to or modify the order at creation.
- *   - presave: Before an order object is saved, the hook gets invoked with this
- *     op to let other modules alter order data before it is written to the
- *     database. $order is a reference to the order object.
- *   - save: When an order object is being saved, the hook gets invoked with
- *     this op to let other modules do any necessary saving. $order is a
- *     reference to the order object.
- *   - load: Called when an order is loaded after the order and product data has
- *     been loaded from the database. Passes $order as the reference to the
- *     order object, so modules may add to or modify the order object when it's
- *     loaded.
  *   - submit: When a sale is being completed and the customer has clicked the
  *     Submit order button from the checkout screen, the hook is invoked with
  *     this op. This gives modules a chance to determine whether or not the
@@ -156,9 +144,6 @@ function hook_uc_line_item_data_alter(&$items) {
  *     may be deleted. Returning FALSE will prevent a delete from happening.
  *     (For example, the payment module returns FALSE by default when an order
  *     has already received payments.)
- *   - delete: Called when an order is deleted and before the rest of the order
- *     information is removed from the database. Passes $order as the order
- *     object to let your module clean up it's tables.
  */
 function hook_uc_order($op, $order, $arg2) {
   switch ($op) {
diff --git a/uc_order/uc_order.module b/uc_order/uc_order.module
index 9f7ac1c..f756a39 100644
--- a/uc_order/uc_order.module
+++ b/uc_order/uc_order.module
@@ -547,8 +547,6 @@ function uc_order_new($uid = 0, $state = 'in_checkout') {
 
   $order->save();
 
-  uc_order_module_invoke('new', $order, NULL);
-
   return $order;
 }
 
@@ -774,22 +772,6 @@ function uc_order_load_line_items_display($order) {
 }
 
 /**
- * Invokes hook_uc_order() in every module.
- *
- * We cannot use module_invoke() for this, because the arguments need to
- * be passed by reference.
- */
-function uc_order_module_invoke($op, &$order, $edit) {
-  $module_handler = \Drupal::moduleHandler();
-  foreach ($module_handler->getImplementations('uc_order') as $module) {
-    $function = $module . '_uc_order';
-    if (function_exists($function)) {
-      $function($op, $order, $edit);
-    }
-  }
-}
-
-/**
  * Determines whether a product is shippable or not.
  */
 function uc_order_product_is_shippable($product) {
diff --git a/uc_taxes/uc_taxes.module b/uc_taxes/uc_taxes.module
index 30a23a4..1b0a3f0 100644
--- a/uc_taxes/uc_taxes.module
+++ b/uc_taxes/uc_taxes.module
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\entity\Entity\EntityViewDisplay;
+use Drupal\uc_order\UcOrderInterface;
 
 /**
  * Implements hook_permission().
@@ -42,7 +43,7 @@ function uc_taxes_menu() {
  * calculations are made.
  */
 function uc_taxes_module_implements_alter(&$implementations, $hook) {
-  if (in_array($hook, array('uc_order', 'entity_view_alter'))) {
+  if (in_array($hook, array('uc_order_insert', 'uc_order_update', 'entity_view_alter'))) {
     $group = $implementations['uc_taxes'];
     unset($implementations['uc_taxes']);
     $implementations['uc_taxes'] = $group;
@@ -146,60 +147,63 @@ function uc_taxes_uc_line_item() {
 }
 
 /**
- * Implements hook_uc_order().
+ * Implements hook_uc_order_insert().
+ */
+function uc_taxes_uc_order_insert(UcOrderInterface $order) {
+  uc_taxes_uc_order_update($order);
+}
+
+/**
+ * Implements hook_uc_order_update().
  *
  * Updates and saves tax line items to the order.
  */
-function uc_taxes_uc_order($op, $order, $arg2) {
-  switch ($op) {
-    case 'save':
-      $changes = array();
-      $line_items = uc_taxes_calculate($order);
-      foreach ($line_items as $id => $tax) {
-        $line_items[$id] = _uc_taxes_to_line_item($tax);
-      }
-
-      // Loop through existing line items and update or delete as necessary.
-      if (is_array($order->line_items)) {
-        foreach ($order->line_items as $i => $line) {
-          if ($line['type'] == 'tax') {
-            $delete = TRUE;
-            foreach ($line_items as $id => $new_line) {
-              if ($new_line['data']['tax_id'] == $line['data']['tax_id']) {
-                if ($new_line['amount'] != $line['amount']) {
-                  uc_order_update_line_item($line['line_item_id'], $new_line['title'], $new_line['amount'], $new_line['data']);
-                  $order->line_items[$i]['amount'] = $new_line['amount'];
-                  $order->line_items[$i]['data'] = $new_line['data'];
-                  $changes[] = t('Changed %title to %amount.', array('%amount' => uc_currency_format($new_line['amount']), '%title' => $new_line['title']));
-                }
-                unset($line_items[$id]);
-                $delete = FALSE;
-                break;
-              }
-            }
-            if ($delete) {
-              uc_order_delete_line_item($line['line_item_id']);
-              unset($order->line_items[$i]);
-              $changes[] = t('Removed %title.', array('%title' => $line['title']));
+function uc_taxes_uc_order_update(UcOrderInterface $order) {
+  $changes = array();
+  $line_items = uc_taxes_calculate($order);
+  foreach ($line_items as $id => $tax) {
+    $line_items[$id] = _uc_taxes_to_line_item($tax);
+  }
+
+  // Loop through existing line items and update or delete as necessary.
+  if (is_array($order->line_items)) {
+    foreach ($order->line_items as $i => $line) {
+      if ($line['type'] == 'tax') {
+        $delete = TRUE;
+        foreach ($line_items as $id => $new_line) {
+          if ($new_line['data']['tax_id'] == $line['data']['tax_id']) {
+            if ($new_line['amount'] != $line['amount']) {
+              uc_order_update_line_item($line['line_item_id'], $new_line['title'], $new_line['amount'], $new_line['data']);
+              $order->line_items[$i]['amount'] = $new_line['amount'];
+              $order->line_items[$i]['data'] = $new_line['data'];
+              $changes[] = t('Changed %title to %amount.', array('%amount' => uc_currency_format($new_line['amount']), '%title' => $new_line['title']));
             }
+            unset($line_items[$id]);
+            $delete = FALSE;
+            break;
           }
         }
-      }
-
-      // Now add line items for any remaining new taxes.
-      if (is_array($line_items)) {
-        foreach ($line_items as $line) {
-          $order->line_items[] = uc_order_line_item_add($order->id(), 'tax', $line['title'], $line['amount'], $line['weight'], $line['data']);
-          $changes[] = t('Added %amount for %title.', array('%amount' => uc_currency_format($line['amount']), '%title' => $line['title']));
+        if ($delete) {
+          uc_order_delete_line_item($line['line_item_id']);
+          unset($order->line_items[$i]);
+          $changes[] = t('Removed %title.', array('%title' => $line['title']));
         }
       }
+    }
+  }
 
-      // And log the changes to the order.
-      if (count($changes)) {
-        $order->logChanges($changes);
-        usort($order->line_items, 'Drupal\Component\Utility\SortArray::sortByWeightElement');
-      }
-    break;
+  // Now add line items for any remaining new taxes.
+  if (is_array($line_items)) {
+    foreach ($line_items as $line) {
+      $order->line_items[] = uc_order_line_item_add($order->id(), 'tax', $line['title'], $line['amount'], $line['weight'], $line['data']);
+      $changes[] = t('Added %amount for %title.', array('%amount' => uc_currency_format($line['amount']), '%title' => $line['title']));
+    }
+  }
+
+  // And log the changes to the order.
+  if (count($changes)) {
+    $order->logChanges($changes);
+    usort($order->line_items, 'Drupal\Component\Utility\SortArray::sortByWeightElement');
   }
 }
 
