diff --git a/README.md b/README.md
index f2accb2..eed59da 100644
--- a/README.md
+++ b/README.md
@@ -3,21 +3,31 @@ Commerce Canada Post
 
 Provides Canada Post shipping rates and tracking functionality for Drupal Commerce.
 
-## Development Setup
-
+## Module Setup
 
 1. Use [Composer](https://getcomposer.org/) to get Commerce Canada Post with all dependencies: `composer require drupal/commerce_canadapost`
 
 2. Enable module.
 
+## Configuration
+
 3. Go to /admin/commerce/config/shipping-methods/add:
   - Select 'Canada Post' as the Plugin
   - Select a default package type
   - Select all the shipping services that should be enabled
   - Click on the Canada Post API settings link under 'API Authentication'
     - Enter the customer number, username, password and other optional config and save configuration.
+  - Go to /admin/commerce/config/order-types/{COMMERCE_ORDER_TYPE}/edit
+    - Select 'Canada Post' for the Shipment type and save
+
+## Fetching Rates
+
+1. Add a product to cart and checkout
+2. Enter your shipping address and click on 'Calculate Shipping'
+3. The estimated rates retrieved from Canada Post will now show up for the order
 
 ## Updating Tracking Information
+
 Tracking summary for each shipment on an order can be seen in the order view page.
 
 To add the tracking code received from Canada Post to a shipment:
@@ -28,5 +38,5 @@ To add the tracking code received from Canada Post to a shipment:
 
 3. Enter the tracking code received from Canada Post in the 'Tracking code' field and save.
 
-Once a shipment is updated with a tracking code, tracking summary is automatically updated via cron.
-It can also be done via the drush command: `drush cc-uptracking`.
+Once a tracking code is added to a shipment, tracking summary is automatically updated when the shipment form is saved and also via cron.
+It can also be done manually via the drush command: `drush cc-uptracking`.
diff --git a/commerce_canadapost.install b/commerce_canadapost.install
index a205e9e..f711535 100644
--- a/commerce_canadapost.install
+++ b/commerce_canadapost.install
@@ -5,6 +5,10 @@
  * Install file for Commerce Canada Post module.
  */
 
+use Drupal\field\Entity\FieldConfig;
+use Drupal\field\Entity\FieldStorageConfig;
+use Symfony\Component\Yaml\Yaml;
+
 /**
  * Add Commerce Canada Post as a dependency to config files.
  */
@@ -31,3 +35,97 @@ function commerce_canadapost_update_8001() {
     $config->save();
   }
 }
+
+/**
+ * Update Commerce Canada Post shipment type field names.
+ */
+function commerce_canadapost_update_8002() {
+  $new_fields = [
+    'field_actual_delivery' => 'canadapost_actual_delivery',
+    'field_attempted_delivery' => 'canadapost_attempted_delivery',
+    'field_current_location' => 'canadapost_current_location',
+    'field_expected_delivery' => 'canadapost_expected_delivery',
+    'field_mailed_on' => 'canadapost_mailed_on',
+  ];
+
+  // Create the new fields in the database.
+  foreach ($new_fields as $old_field => $new_field) {
+    $module_path = drupal_get_path('module', 'commerce_canadapost');
+
+    // Create the field storage.
+    $yml = Yaml::parse(file_get_contents($module_path . '/config/install/field.storage.commerce_shipment.' . $new_field . '.yml'));
+    if (!FieldStorageConfig::loadByName($yml['entity_type'], $yml['field_name'])) {
+      FieldStorageConfig::create($yml)->save();
+    }
+    // Create the field.
+    $yml = Yaml::parse(file_get_contents($module_path . '/config/install/field.field.commerce_shipment.canadapost.' . $new_field . '.yml'));
+    if (!FieldConfig::loadByName($yml['entity_type'], $yml['bundle'], $yml['field_name'])) {
+      FieldConfig::create($yml)->save();
+    }
+  }
+
+  // Re-import our default configs.
+  \Drupal::service('config.installer')->installDefaultConfig('module', 'commerce_canadapost');
+
+  // Copy over the data from the old fields to the new fields.
+  _commerce_canadapost_copy_field_data($new_fields);
+
+  // Finally, let's delete the old fields.
+  foreach ($new_fields as $old_field => $new_field) {
+    // Delete the field storage.
+    $field = FieldStorageConfig::loadByName('commerce_shipment', $old_field);
+    if ($field) {
+      $field->delete();
+    }
+    // Delete the field.
+    $field = FieldConfig::loadByName('commerce_shipment', 'canadapost', $old_field);
+    if ($field) {
+      $field->delete();
+    }
+  }
+}
+
+/**
+ * Copy over the old field data to the new renamed fields.
+ *
+ * @param array $new_fields
+ *   The old and new field names.
+ */
+function _commerce_canadapost_copy_field_data(array $new_fields) {
+  /** @var \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager */
+  $entity_type_manager = \Drupal::entityTypeManager();
+  /** @var \Drupal\Core\Entity\EntityStorageInterface $shipment_storage */
+  $shipment_storage = $entity_type_manager->getStorage('commerce_shipment');
+
+  if (!isset($sandbox['max'])) {
+    $sandbox['current'] = 0;
+    $sandbox['count'] = 0;
+    $sandbox['max'] = $shipment_storage->getQuery()
+      ->accessCheck(FALSE)
+      ->condition('type', 'canadapost')
+      ->count()->execute();
+  }
+  $shipment_ids = $shipment_storage->getQuery()
+    ->accessCheck(FALSE)
+    ->range(0, 50)
+    ->condition('type', 'canadapost')
+    ->condition('shipment_id', $sandbox['current'], '>')
+    ->sort('shipment_id', 'ASC')
+    ->execute();
+  $shipments = $shipment_storage->loadMultiple($shipment_ids);
+
+  /** @var \Drupal\node\NodeInterface $node */
+  foreach ($shipments as $shipment) {
+    foreach ($new_fields as $old_field => $new_field) {
+      if ($shipment->hasField($old_field)) {
+        $field_value = $shipment->get($old_field)->getValue();
+        $shipment->set($new_field, $field_value);
+      }
+    }
+
+    $shipment->save();
+    $sandbox['current'] = $shipment->id();
+    $sandbox['count']++;
+  }
+  $sandbox['#finished'] = empty($sandbox['max']) ? 1 : $sandbox['current'] / $sandbox['max'];
+}
diff --git a/commerce_canadapost.module b/commerce_canadapost.module
index c0f404c..ce08e3c 100644
--- a/commerce_canadapost.module
+++ b/commerce_canadapost.module
@@ -39,18 +39,21 @@ function commerce_canadapost_help($route_name, RouteMatchInterface $route_match)
       $output .= '<dt>' . t('2. Select \'Canada Post\' as the Plugin') . '</dt>';
       $output .= '<dt>' . t('3. Enter the Canada Post API details') . '</dt>';
       $output .= '<dt>' . t('4. Select a default package type') . '</dt>';
-      $output .= '<dt>' . t('5. Select all the shipping services that should be disabled') . '</dt>';
-      $output .= '<dt>' . t('6. Click on the Canada Post API settings link under \'API Authentication\' and add your customer number, username, password and other optional config and save configuration') . '</dt>';
-      $output .= '<dt>' . t('7. Add a product to cart and checkout') . '</dt>';
-      $output .= '<dt>' . t('8. Enter your shipping address and click on \'Calculate Shipping\'') . '</dt>';
-      $output .= '<dt>' . t('9. The estimated rates retrieved from Canada Post will now show up for the order') . '</dt>';
+      $output .= '<dt>' . t('5. Select all the shipping services that should be enabled') . '</dt>';
+      $output .= '<dt>' . t('6. Click on the Canada Post API settings link under \'API Authentication\' and add your customer number, username, password and other optional config and save configuration.') . '</dt>';
+      $output .= '<dt>' . t('7. Go to /admin/commerce/config/order-types/{COMMERCE_ORDER_TYPE}/edit and select \'Canada Post\' for the Shipment type and save.') . '</dt>';
+      $output .= '<h3>' . t('Fetching Rates') . '</h3>';
+      $output .= '<dt>' . t('1. Add a product to cart and checkout') . '</dt>';
+      $output .= '<dt>' . t('2. Enter your shipping address and click on \'Calculate Shipping\'') . '</dt>';
+      $output .= '<dt>' . t('3. The estimated rates retrieved from Canada Post will now show up for the order.') . '</dt>';
       $output .= '<h3>' . t('Updating Tracking Information') . '</h3>';
       $output .= '<p>' . t('Tracking summary for each shipment on an order can be seen in the order view page.') . '</p>';
       $output .= '<p>' . t('To add the tracking code received from Canada Post to a shipment:') . '</p>';
       $output .= '<dt>' . t('1. Go to /admin/commerce/orders/{COMMERCE_ORDER_ID}/shipments') . '</dt>';
       $output .= '<dt>' . t('2. Click on the \'Edit\' button under the appropriate shipment') . '</dt>';
       $output .= '<dt>' . t('3. Enter the tracking code received from Canada Post in the \'Tracking code\' field and save') . '</dt>';
-      $output .= '<p>' . t('Once a shipment is updated with a tracking code, tracking summary is automatically updated via cron. It can also be done via the drush command: `drush cc-uptracking`.') . '</p>';
+      $output .= '<p>' . t('Once a tracking code is added to a shipment, tracking summary is automatically updated when the shipment form is saved and also via cron.
+       <br>It can also be done manually via the drush command: <code>drush cc-uptracking</code>.') . '</p>';
 
       return $output;
   }
@@ -71,19 +74,20 @@ function commerce_canadapost_form_commerce_checkout_flow_multistep_default_alter
     return;
   }
 
-  foreach ($form['shipping_information']['shipments'] as &$shipment) {
-    $fields = [
-      'field_actual_delivery',
-      'field_attempted_delivery',
-      'field_expected_delivery',
-      'field_mailed_on',
-    ];
-    foreach ($fields as $field) {
-      if (isset($shipment[$field])) {
-        $shipment[$field]['#access'] = FALSE;
-      }
-    }
+  $utilities_service = \Drupal::service('commerce_canadapost.utilities_service');
+  $utilities_service->hideTrackingFields($form);
+}
+
+/**
+ * Implements hook_form_BASE_FORM_ID_alter().
+ */
+function commerce_canadapost_form_commerce_checkout_flow_alter(&$form, FormStateInterface $form_state, $form_id) {
+  if (!isset($form['shipping_information']['shipments'])) {
+    return;
   }
+
+  $utilities_service = \Drupal::service('commerce_canadapost.utilities_service');
+  $utilities_service->hideTrackingFields($form);
 }
 
 /**
@@ -120,6 +124,16 @@ function commerce_canadapost_form_commerce_store_form_alter(&$form, FormStateInt
   $form['actions']['submit']['#submit'][] = 'commerce_canadapost_form_commerce_store_form_submit';
 }
 
+/**
+ * Implements hook_cron().
+ */
+function commerce_canadapost_cron() {
+  // Update tracking data for all incomplete canadapost shipments with a
+  // tracking code.
+  $utilities_service = \Drupal::service('commerce_canadapost.utilities_service');
+  $utilities_service->updateTracking();
+}
+
 /**
  * Functions.
  */
@@ -144,21 +158,26 @@ function commerce_canadapost_commerce_shipment_form_submit($form, FormStateInter
   $tracking_service = \Drupal::service('commerce_canadapost.tracking_api');
   $tracking_summary = $tracking_service->fetchTrackingSummary($submitted_tracking_pin, $shipment);
 
+  // Update the tracking fields with the summary.
   $values = [];
-  if (!empty($tracking_summary['actual-delivery-date'])) {
-    $values['field_actual_delivery'][0]['value'] = new DrupalDateTime($tracking_summary['actual-delivery-date']);
+  if ($tracking_summary['actual-delivery-date'] != '') {
+    $values['canadapost_actual_delivery'][0]['value'] = new DrupalDateTime($tracking_summary['actual-delivery-date']);
+  }
+
+  if ($tracking_summary['attempted-date'] != '') {
+    $values['canadapost_attempted_delivery'][0]['value'] = new DrupalDateTime($tracking_summary['attempted-date']);
   }
 
-  if (!empty($tracking_summary['attempted-date'])) {
-    $values['field_attempted_delivery'][0]['value'] = new DrupalDateTime($tracking_summary['attempted-date']);
+  if ($tracking_summary['expected-delivery-date'] != '') {
+    $values['canadapost_expected_delivery'][0]['value'] = new DrupalDateTime($tracking_summary['expected-delivery-date']);
   }
 
-  if (!empty($tracking_summary['expected-delivery-date'])) {
-    $values['field_expected_delivery'][0]['value'] = new DrupalDateTime($tracking_summary['expected-delivery-date']);
+  if ($tracking_summary['mailed-on-date'] != '') {
+    $values['canadapost_mailed_on'][0]['value'] = new DrupalDateTime($tracking_summary['mailed-on-date']);
   }
 
-  if (!empty($tracking_summary['mailed-on-date'])) {
-    $values['field_mailed_on'][0]['value'] = new DrupalDateTime($tracking_summary['mailed-on-date']);
+  if ($tracking_summary['event-location'] != '') {
+    $values['canadapost_current_location'][0]['value'] = $tracking_summary['event-location'];
   }
 
   $form_state->setValues($values);
diff --git a/commerce_canadapost.services.yml b/commerce_canadapost.services.yml
index 34c0a72..58002df 100755
--- a/commerce_canadapost.services.yml
+++ b/commerce_canadapost.services.yml
@@ -1,12 +1,13 @@
 services:
   commerce_canadapost.rating_api:
     class: Drupal\commerce_canadapost\Api\RatingService
-    arguments: ['@commerce_canadapost.utilities_service', '@logger.factory']
 
   commerce_canadapost.tracking_api:
     class: Drupal\commerce_canadapost\Api\TrackingService
-    arguments: ['@commerce_canadapost.utilities_service', '@logger.factory']
 
   commerce_canadapost.utilities_service:
     class: Drupal\commerce_canadapost\UtilitiesService
-    arguments: ['@config.factory']
+    arguments:
+      - '@config.factory'
+      - '@commerce_canadapost.tracking_api'
+      - '@entity_type.manager'
diff --git a/config/install/core.entity_form_display.commerce_shipment.canadapost.default.yml b/config/install/core.entity_form_display.commerce_shipment.canadapost.default.yml
index 0aafef6..dba4d14 100644
--- a/config/install/core.entity_form_display.commerce_shipment.canadapost.default.yml
+++ b/config/install/core.entity_form_display.commerce_shipment.canadapost.default.yml
@@ -3,10 +3,11 @@ status: true
 dependencies:
   config:
     - commerce_shipping.commerce_shipment_type.canadapost
-    - field.field.commerce_shipment.canadapost.field_actual_delivery
-    - field.field.commerce_shipment.canadapost.field_attempted_delivery
-    - field.field.commerce_shipment.canadapost.field_expected_delivery
-    - field.field.commerce_shipment.canadapost.field_mailed_on
+    - field.field.commerce_shipment.canadapost.canadapost_actual_delivery
+    - field.field.commerce_shipment.canadapost.canadapost_attempted_delivery
+    - field.field.commerce_shipment.canadapost.canadapost_current_location
+    - field.field.commerce_shipment.canadapost.canadapost_expected_delivery
+    - field.field.commerce_shipment.canadapost.canadapost_mailed_on
   module:
     - commerce_shipping
     - datetime
@@ -15,25 +16,33 @@ targetEntityType: commerce_shipment
 bundle: canadapost
 mode: default
 content:
-  field_actual_delivery:
+  canadapost_actual_delivery:
     weight: 23
     settings: {  }
     third_party_settings: {  }
     type: datetime_default
     region: content
-  field_attempted_delivery:
+  canadapost_attempted_delivery:
     weight: 24
     settings: {  }
     third_party_settings: {  }
     type: datetime_default
     region: content
-  field_expected_delivery:
+  canadapost_current_location:
+    weight: 25
+    settings:
+      size: 60
+      placeholder: ''
+    third_party_settings: {  }
+    type: string_textfield
+    region: content
+  canadapost_expected_delivery:
     weight: 22
     settings: {  }
     third_party_settings: {  }
     type: datetime_default
     region: content
-  field_mailed_on:
+  canadapost_mailed_on:
     weight: 21
     settings: {  }
     third_party_settings: {  }
diff --git a/config/install/core.entity_view_display.commerce_shipment.canadapost.default.yml b/config/install/core.entity_view_display.commerce_shipment.canadapost.default.yml
index 6590b46..1c48852 100644
--- a/config/install/core.entity_view_display.commerce_shipment.canadapost.default.yml
+++ b/config/install/core.entity_view_display.commerce_shipment.canadapost.default.yml
@@ -3,10 +3,11 @@ status: true
 dependencies:
   config:
     - commerce_shipping.commerce_shipment_type.canadapost
-    - field.field.commerce_shipment.canadapost.field_actual_delivery
-    - field.field.commerce_shipment.canadapost.field_attempted_delivery
-    - field.field.commerce_shipment.canadapost.field_expected_delivery
-    - field.field.commerce_shipment.canadapost.field_mailed_on
+    - field.field.commerce_shipment.canadapost.canadapost_actual_delivery
+    - field.field.commerce_shipment.canadapost.canadapost_attempted_delivery
+    - field.field.commerce_shipment.canadapost.canadapost_current_location
+    - field.field.commerce_shipment.canadapost.canadapost_expected_delivery
+    - field.field.commerce_shipment.canadapost.canadapost_mailed_on
   module:
     - commerce_shipping
     - datetime
@@ -16,7 +17,7 @@ targetEntityType: commerce_shipment
 bundle: canadapost
 mode: default
 content:
-  field_actual_delivery:
+  canadapost_actual_delivery:
     weight: 13
     label: above
     settings:
@@ -25,7 +26,7 @@ content:
     third_party_settings: {  }
     type: datetime_default
     region: content
-  field_attempted_delivery:
+  canadapost_attempted_delivery:
     weight: 14
     label: above
     settings:
@@ -34,7 +35,15 @@ content:
     third_party_settings: {  }
     type: datetime_default
     region: content
-  field_expected_delivery:
+  canadapost_current_location:
+    weight: 15
+    label: above
+    settings:
+      link_to_entity: false
+    third_party_settings: {  }
+    type: string
+    region: content
+  canadapost_expected_delivery:
     weight: 12
     label: above
     settings:
@@ -43,7 +52,7 @@ content:
     third_party_settings: {  }
     type: datetime_default
     region: content
-  field_mailed_on:
+  canadapost_mailed_on:
     weight: 11
     label: above
     settings:
diff --git a/config/install/field.field.commerce_shipment.canadapost.field_actual_delivery.yml b/config/install/field.field.commerce_shipment.canadapost.canadapost_actual_delivery.yml
similarity index 62%
rename from config/install/field.field.commerce_shipment.canadapost.field_actual_delivery.yml
rename to config/install/field.field.commerce_shipment.canadapost.canadapost_actual_delivery.yml
index 2e9deab..f8a71a8 100644
--- a/config/install/field.field.commerce_shipment.canadapost.field_actual_delivery.yml
+++ b/config/install/field.field.commerce_shipment.canadapost.canadapost_actual_delivery.yml
@@ -3,14 +3,14 @@ status: true
 dependencies:
   config:
     - commerce_shipping.commerce_shipment_type.canadapost
-    - field.storage.commerce_shipment.field_actual_delivery
+    - field.storage.commerce_shipment.canadapost_actual_delivery
   module:
     - datetime
-id: commerce_shipment.canadapost.field_actual_delivery
-field_name: field_actual_delivery
+id: commerce_shipment.canadapost.canadapost_actual_delivery
+field_name: canadapost_actual_delivery
 entity_type: commerce_shipment
 bundle: canadapost
-label: 'Actual Delivery'
+label: 'Actual delivery'
 description: ''
 required: false
 translatable: false
diff --git a/config/install/field.field.commerce_shipment.canadapost.field_expected_delivery.yml b/config/install/field.field.commerce_shipment.canadapost.canadapost_attempted_delivery.yml
similarity index 61%
rename from config/install/field.field.commerce_shipment.canadapost.field_expected_delivery.yml
rename to config/install/field.field.commerce_shipment.canadapost.canadapost_attempted_delivery.yml
index 2a46d8b..a3b5893 100644
--- a/config/install/field.field.commerce_shipment.canadapost.field_expected_delivery.yml
+++ b/config/install/field.field.commerce_shipment.canadapost.canadapost_attempted_delivery.yml
@@ -3,14 +3,14 @@ status: true
 dependencies:
   config:
     - commerce_shipping.commerce_shipment_type.canadapost
-    - field.storage.commerce_shipment.field_expected_delivery
+    - field.storage.commerce_shipment.canadapost_attempted_delivery
   module:
     - datetime
-id: commerce_shipment.canadapost.field_expected_delivery
-field_name: field_expected_delivery
+id: commerce_shipment.canadapost.canadapost_attempted_delivery
+field_name: canadapost_attempted_delivery
 entity_type: commerce_shipment
 bundle: canadapost
-label: 'Expected Delivery'
+label: 'Attempted delivery'
 description: ''
 required: false
 translatable: false
diff --git a/config/install/field.field.commerce_shipment.canadapost.canadapost_current_location.yml b/config/install/field.field.commerce_shipment.canadapost.canadapost_current_location.yml
new file mode 100644
index 0000000..d78f0e3
--- /dev/null
+++ b/config/install/field.field.commerce_shipment.canadapost.canadapost_current_location.yml
@@ -0,0 +1,20 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - commerce_shipping.commerce_shipment_type.canadapost
+    - field.storage.commerce_shipment.canadapost_current_location
+  module:
+    - address
+id: commerce_shipment.canadapost.canadapost_current_location
+field_name: canadapost_current_location
+entity_type: commerce_shipment
+bundle: canadapost
+label: 'Current location'
+description: ''
+required: false
+translatable: false
+default_value: {  }
+default_value_callback: ''
+settings: {  }
+field_type: string
diff --git a/config/install/field.field.commerce_shipment.canadapost.field_attempted_delivery.yml b/config/install/field.field.commerce_shipment.canadapost.canadapost_expected_delivery.yml
similarity index 61%
rename from config/install/field.field.commerce_shipment.canadapost.field_attempted_delivery.yml
rename to config/install/field.field.commerce_shipment.canadapost.canadapost_expected_delivery.yml
index 5b30813..bfc7042 100644
--- a/config/install/field.field.commerce_shipment.canadapost.field_attempted_delivery.yml
+++ b/config/install/field.field.commerce_shipment.canadapost.canadapost_expected_delivery.yml
@@ -3,14 +3,14 @@ status: true
 dependencies:
   config:
     - commerce_shipping.commerce_shipment_type.canadapost
-    - field.storage.commerce_shipment.field_attempted_delivery
+    - field.storage.commerce_shipment.canadapost_expected_delivery
   module:
     - datetime
-id: commerce_shipment.canadapost.field_attempted_delivery
-field_name: field_attempted_delivery
+id: commerce_shipment.canadapost.canadapost_expected_delivery
+field_name: canadapost_expected_delivery
 entity_type: commerce_shipment
 bundle: canadapost
-label: 'Attempted Delivery'
+label: 'Expected delivery'
 description: ''
 required: false
 translatable: false
diff --git a/config/install/field.field.commerce_shipment.canadapost.field_mailed_on.yml b/config/install/field.field.commerce_shipment.canadapost.canadapost_mailed_on.yml
similarity index 65%
rename from config/install/field.field.commerce_shipment.canadapost.field_mailed_on.yml
rename to config/install/field.field.commerce_shipment.canadapost.canadapost_mailed_on.yml
index c7296a7..039c7e2 100644
--- a/config/install/field.field.commerce_shipment.canadapost.field_mailed_on.yml
+++ b/config/install/field.field.commerce_shipment.canadapost.canadapost_mailed_on.yml
@@ -3,14 +3,14 @@ status: true
 dependencies:
   config:
     - commerce_shipping.commerce_shipment_type.canadapost
-    - field.storage.commerce_shipment.field_mailed_on
+    - field.storage.commerce_shipment.canadapost_mailed_on
   module:
     - datetime
-id: commerce_shipment.canadapost.field_mailed_on
-field_name: field_mailed_on
+id: commerce_shipment.canadapost.canadapost_mailed_on
+field_name: canadapost_mailed_on
 entity_type: commerce_shipment
 bundle: canadapost
-label: 'Mailed On'
+label: 'Mailed on'
 description: ''
 required: false
 translatable: false
diff --git a/config/install/field.storage.commerce_shipment.field_expected_delivery.yml b/config/install/field.storage.commerce_shipment.canadapost_actual_delivery.yml
similarity index 80%
rename from config/install/field.storage.commerce_shipment.field_expected_delivery.yml
rename to config/install/field.storage.commerce_shipment.canadapost_actual_delivery.yml
index fc155d0..e991a23 100644
--- a/config/install/field.storage.commerce_shipment.field_expected_delivery.yml
+++ b/config/install/field.storage.commerce_shipment.canadapost_actual_delivery.yml
@@ -6,8 +6,8 @@ dependencies:
   module:
     - commerce_shipping
     - datetime
-id: commerce_shipment.field_expected_delivery
-field_name: field_expected_delivery
+id: commerce_shipment.canadapost_actual_delivery
+field_name: canadapost_actual_delivery
 entity_type: commerce_shipment
 type: datetime
 settings:
diff --git a/config/install/field.storage.commerce_shipment.field_attempted_delivery.yml b/config/install/field.storage.commerce_shipment.canadapost_attempted_delivery.yml
similarity index 79%
rename from config/install/field.storage.commerce_shipment.field_attempted_delivery.yml
rename to config/install/field.storage.commerce_shipment.canadapost_attempted_delivery.yml
index 475eafa..99142d3 100644
--- a/config/install/field.storage.commerce_shipment.field_attempted_delivery.yml
+++ b/config/install/field.storage.commerce_shipment.canadapost_attempted_delivery.yml
@@ -6,8 +6,8 @@ dependencies:
   module:
     - commerce_shipping
     - datetime
-id: commerce_shipment.field_attempted_delivery
-field_name: field_attempted_delivery
+id: commerce_shipment.canadapost_attempted_delivery
+field_name: canadapost_attempted_delivery
 entity_type: commerce_shipment
 type: datetime
 settings:
diff --git a/config/install/field.storage.commerce_shipment.canadapost_current_location.yml b/config/install/field.storage.commerce_shipment.canadapost_current_location.yml
new file mode 100644
index 0000000..1c370e6
--- /dev/null
+++ b/config/install/field.storage.commerce_shipment.canadapost_current_location.yml
@@ -0,0 +1,23 @@
+langcode: en
+status: true
+dependencies:
+  config:
+    - commerce_shipping.commerce_shipment_type.canadapost
+  module:
+    - address
+    - commerce_shipping
+id: commerce_shipment.canadapost_current_location
+field_name: canadapost_current_location
+entity_type: commerce_shipment
+type: string
+settings:
+  max_length: 255
+  is_ascii: false
+  case_sensitive: false
+module: core
+locked: false
+cardinality: 1
+translatable: true
+indexes: {  }
+persist_with_no_fields: false
+custom_storage: false
diff --git a/config/install/field.storage.commerce_shipment.field_actual_delivery.yml b/config/install/field.storage.commerce_shipment.canadapost_expected_delivery.yml
similarity index 79%
rename from config/install/field.storage.commerce_shipment.field_actual_delivery.yml
rename to config/install/field.storage.commerce_shipment.canadapost_expected_delivery.yml
index 47e5950..d5336f4 100644
--- a/config/install/field.storage.commerce_shipment.field_actual_delivery.yml
+++ b/config/install/field.storage.commerce_shipment.canadapost_expected_delivery.yml
@@ -6,8 +6,8 @@ dependencies:
   module:
     - commerce_shipping
     - datetime
-id: commerce_shipment.field_actual_delivery
-field_name: field_actual_delivery
+id: commerce_shipment.canadapost_expected_delivery
+field_name: canadapost_expected_delivery
 entity_type: commerce_shipment
 type: datetime
 settings:
diff --git a/config/install/field.storage.commerce_shipment.field_mailed_on.yml b/config/install/field.storage.commerce_shipment.canadapost_mailed_on.yml
similarity index 82%
rename from config/install/field.storage.commerce_shipment.field_mailed_on.yml
rename to config/install/field.storage.commerce_shipment.canadapost_mailed_on.yml
index 908ec2d..5f9a755 100644
--- a/config/install/field.storage.commerce_shipment.field_mailed_on.yml
+++ b/config/install/field.storage.commerce_shipment.canadapost_mailed_on.yml
@@ -6,8 +6,8 @@ dependencies:
   module:
     - commerce_shipping
     - datetime
-id: commerce_shipment.field_mailed_on
-field_name: field_mailed_on
+id: commerce_shipment.canadapost_mailed_on
+field_name: canadapost_mailed_on
 entity_type: commerce_shipment
 type: datetime
 settings:
diff --git a/drush.services.yml b/drush.services.yml
index e5a3f7a..f81b346 100644
--- a/drush.services.yml
+++ b/drush.services.yml
@@ -1,6 +1,7 @@
 services:
   commerce_canadapost.commands:
     class: \Drupal\commerce_canadapost\Commands\Commands
-    arguments: ['@commerce_canadapost.rating_api', '@commerce_canadapost.tracking_api']
+    arguments:
+      - '@commerce_canadapost.utilities_service'
     tags:
       - { name: drush.command }
diff --git a/src/Api/RatingService.php b/src/Api/RatingService.php
index f3eb6ae..ed97887 100644
--- a/src/Api/RatingService.php
+++ b/src/Api/RatingService.php
@@ -2,67 +2,33 @@
 
 namespace Drupal\commerce_canadapost\Api;
 
-use CanadaPost\Exception\ClientException;
-use Drupal\commerce_canadapost\UtilitiesService;
 use Drupal\commerce_price\Price;
 use Drupal\commerce_shipping\Entity\ShipmentInterface;
 use Drupal\commerce_shipping\Plugin\Commerce\ShippingMethod\ShippingMethodInterface;
 use Drupal\commerce_shipping\ShippingRate;
 use Drupal\commerce_shipping\ShippingService;
-use Drupal\Core\Logger\LoggerChannelFactoryInterface;
+
+use CanadaPost\Exception\ClientException;
 use CanadaPost\Rating;
 
 /**
  * Provides the default Rating API integration services.
  */
-class RatingService implements RatingServiceInterface {
-
-  /**
-   * The Canada Post utilities service object.
-   *
-   * @var \Drupal\commerce_canadapost\UtilitiesService
-   */
-  protected $service;
-
-  /**
-   * The logger channel factory.
-   *
-   * @var \Drupal\Core\Logger\LoggerChannelInterface
-   */
-  protected $logger;
-
-  /**
-   * The Canada Post API settings.
-   *
-   * @var array
-   */
-  protected $apiSettings;
-
-  /**
-   * Constructs a new TrackingService object.
-   *
-   * @param \Drupal\commerce_canadapost\UtilitiesService $service
-   *   The Canada Post utilities service object.
-   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
-   *   The logger channel factory.
-   */
-  public function __construct(
-    UtilitiesService $service,
-    LoggerChannelFactoryInterface $logger_factory
-  ) {
-    $this->service = $service;
-    $this->logger = $logger_factory->get(COMMERCE_CANADAPOST_LOGGER_CHANNEL);
-  }
+class RatingService extends Request implements RatingServiceInterface {
 
   /**
    * {@inheritdoc}
    */
-  public function getRates(ShippingMethodInterface $shipping_method, ShipmentInterface $shipment, array $options) {
+  public function getRates(
+    ShippingMethodInterface $shipping_method,
+    ShipmentInterface $shipment,
+    array $options
+  ) {
     $order = $shipment->getOrder();
     $store = $order->getStore();
 
-    // Fetch the Canada Post API settings first.
-    $this->apiSettings = $this->service->getApiSettings($store);
+    // Set the Canada Post API settings first.
+    $this->setApiSettings($store);
 
     $origin_postal_code = !empty($shipping_method->getConfiguration()['shipping_information']['origin_postal_code'])
       ? $shipping_method->getConfiguration()['shipping_information']['origin_postal_code']
@@ -82,8 +48,8 @@ public function getRates(ShippingMethodInterface $shipping_method, ShipmentInter
         ob_start();
       }
 
-      $request = $this->getRequest();
-      $response = $request->getRates($origin_postal_code, $postal_code, $weight, $options);
+      $rating = $this->getRequest();
+      $response = $rating->getRates($origin_postal_code, $postal_code, $weight, $options);
 
       if ($this->apiSettings['log']['request']) {
         $response_output = var_export($response, TRUE);
@@ -123,30 +89,17 @@ public function getRates(ShippingMethodInterface $shipping_method, ShipmentInter
   }
 
   /**
-   * Returns a Canada Post request service api.
+   * Returns an initialized Canada Post Rating service.
    *
    * @return \CanadaPost\Rating
-   *   The Canada Post request service object.
+   *   The rating service class.
    */
   protected function getRequest() {
-    $config = [
-      'username' => $this->apiSettings['username'],
-      'password' => $this->apiSettings['password'],
-      'customer_number' => $this->apiSettings['customer_number'],
-      'contract_id' => $this->apiSettings['contract_id'],
-      'env' => $this->getEnvironmentMode(),
-    ];
+    $config = $this->getRequestConfig($this->apiSettings);
 
     return new Rating($config);
   }
 
-  /**
-   * Convert the environment mode to the correct format for the SDK.
-   */
-  private function getEnvironmentMode() {
-    return $this->apiSettings['mode'] === 'live' ? 'prod' : 'dev';
-  }
-
   /**
    * Parse results from Canada Post API into ShippingRates.
    *
diff --git a/src/Api/Request.php b/src/Api/Request.php
new file mode 100644
index 0000000..9001ec0
--- /dev/null
+++ b/src/Api/Request.php
@@ -0,0 +1,130 @@
+<?php
+
+namespace Drupal\commerce_canadapost\Api;
+
+use Drupal\commerce_store\Entity\StoreInterface;
+
+use Exception;
+
+/**
+ * CanadaPost API Service.
+ *
+ * @package Drupal\commerce_canadapost
+ */
+class Request implements RequestInterface {
+
+  /**
+   * The Canada Post API settings.
+   *
+   * @var array
+   */
+  protected $apiSettings;
+
+  /**
+   * The config factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactoryInterface
+   */
+  protected $configFactory;
+
+  /**
+   * The logger channel factory.
+   *
+   * @var \Drupal\Core\Logger\LoggerChannelInterface
+   */
+  protected $logger;
+
+  /**
+   * Request class constructor.
+   */
+  public function __construct() {
+    $this->configFactory = \Drupal::service('config.factory');
+    $this->logger = \Drupal::service('logger.factory')->get(COMMERCE_CANADAPOST_LOGGER_CHANNEL);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function setApiSettings(StoreInterface $store = NULL) {
+    $api_settings = [];
+
+    // If we have store specific settings, return that.
+    if ($store && !empty($store->get('canadapost_api_settings')->getValue()[0]['value'])) {
+      $api_settings = $this->parseSettings(
+        $store->get('canadapost_api_settings')->getValue()[0]['value']
+      );
+    }
+    // Else, we fetch it from the sitewide settings.
+    else {
+      $config = $this->configFactory->get('commerce_canadapost.settings');
+
+      foreach ($this->getApiKeys() as $key) {
+        $api_settings[$key] = $config->get("api.$key");
+      }
+    }
+
+    $this->apiSettings = $api_settings;
+
+    return $this->apiSettings;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getRequestConfig() {
+    // Verify necessary configuration is available.
+    if (empty($this->apiSettings['username'])
+      || empty($this->apiSettings['password'])
+      || empty($this->apiSettings['customer_number'])) {
+      throw new Exception('Configuration is required.');
+    }
+
+    $config = [
+      'username' => $this->apiSettings['username'],
+      'password' => $this->apiSettings['password'],
+      'customer_number' => $this->apiSettings['customer_number'],
+      'contract_id' => $this->apiSettings['contract_id'],
+      'env' => $this->getEnvironmentMode(),
+    ];
+
+    return $config;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getApiKeys() {
+    return [
+      'customer_number',
+      'username',
+      'password',
+      'contract_id',
+      'mode',
+      'log',
+    ];
+  }
+
+  /**
+   * Convert the environment mode to the correct format for the SDK.
+   *
+   * @return string
+   *   The environment mode (prod/dev).
+   */
+  protected function getEnvironmentMode() {
+    return $this->apiSettings['mode'] === 'live' ? 'prod' : 'dev';
+  }
+
+  /**
+   * Parse the Canada Post API settings stored as json in the store entity.
+   *
+   * @param object $api_settings
+   *   The json encoded Canada Post api settings.
+   *
+   * @return array
+   *   An array of values extracted from the json object.
+   */
+  protected function parseSettings($api_settings) {
+    return json_decode($api_settings, TRUE);
+  }
+
+}
diff --git a/src/Api/RequestInterface.php b/src/Api/RequestInterface.php
new file mode 100644
index 0000000..853c753
--- /dev/null
+++ b/src/Api/RequestInterface.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Drupal\commerce_canadapost\Api;
+
+use Drupal\commerce_store\Entity\StoreInterface;
+
+/**
+ * Interface for the Canada Post API Service.
+ *
+ * @package Drupal\commerce_canadapost
+ */
+interface RequestInterface {
+
+  /**
+   * Fetch the Canada Post API settings, first from the store then the site.
+   *
+   * @param \Drupal\commerce_store\Entity\StoreInterface $store
+   *   A store entity, if the api settings are for a store.
+   *
+   * @return array
+   *   Returns the api settings.
+   */
+  public function setApiSettings(StoreInterface $store = NULL);
+
+  /**
+   * Returns a Canada Post config to pass to the request service api.
+   *
+   * @return \CanadaPost\Rating
+   *   The Canada Post request service object.
+   */
+  public function getRequestConfig();
+
+  /**
+   * Return the Canada Post API keys.
+   *
+   * @return array
+   *   An array of API setting keys.
+   */
+  public function getApiKeys();
+
+}
diff --git a/src/Api/TrackingService.php b/src/Api/TrackingService.php
index 7aaa777..8d41f33 100644
--- a/src/Api/TrackingService.php
+++ b/src/Api/TrackingService.php
@@ -2,53 +2,15 @@
 
 namespace Drupal\commerce_canadapost\Api;
 
-use CanadaPost\Exception\ClientException;
-use Drupal\commerce_canadapost\UtilitiesService;
 use Drupal\commerce_shipping\Entity\ShipmentInterface;
-use Drupal\Core\Logger\LoggerChannelFactoryInterface;
+
+use CanadaPost\Exception\ClientException;
 use CanadaPost\Tracking;
 
 /**
  * Provides the default Tracking API integration services.
  */
-class TrackingService implements TrackingServiceInterface {
-
-  /**
-   * The Canada Post utilities service object.
-   *
-   * @var \Drupal\commerce_canadapost\UtilitiesService
-   */
-  protected $service;
-
-  /**
-   * The logger channel factory.
-   *
-   * @var \Drupal\Core\Logger\LoggerChannelInterface
-   */
-  protected $logger;
-
-  /**
-   * The Canada Post API settings.
-   *
-   * @var array
-   */
-  protected $apiSettings;
-
-  /**
-   * Constructs a new TrackingService object.
-   *
-   * @param \Drupal\commerce_canadapost\UtilitiesService $service
-   *   The Canada Post utilities service object.
-   * @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_factory
-   *   The logger channel factory.
-   */
-  public function __construct(
-    UtilitiesService $service,
-    LoggerChannelFactoryInterface $logger_factory
-  ) {
-    $this->service = $service;
-    $this->logger = $logger_factory->get(COMMERCE_CANADAPOST_LOGGER_CHANNEL);
-  }
+class TrackingService extends Request implements TrackingServiceInterface {
 
   /**
    * {@inheritdoc}
@@ -56,7 +18,7 @@ public function __construct(
   public function fetchTrackingSummary($tracking_pin, ShipmentInterface $shipment) {
     // Fetch the Canada Post API settings first.
     $store = $shipment->getOrder()->getStore();
-    $this->apiSettings = $this->service->getApiSettings($store);
+    $this->setApiSettings($store);
 
     try {
       // Turn on output buffering if we are in test mode.
@@ -107,19 +69,15 @@ public function fetchTrackingSummary($tracking_pin, ShipmentInterface $shipment)
   }
 
   /**
-   * Returns a Canada Post request service api.
+   * Returns an initialized Canada Post Tracking service.
    *
    * @return \CanadaPost\Tracking
-   *   The Canada Post tracking request service object.
+   *   The tracking service class.
    */
   protected function getRequest() {
-    $config = [
-      'username' => $this->apiSettings['username'],
-      'password' => $this->apiSettings['password'],
-      'customer_number' => $this->apiSettings['customer_number'],
-    ];
+    $config = $this->getRequestConfig($this->apiSettings);
 
-    return $tracking = new Tracking($config);
+    return new Tracking($config);
   }
 
   /**
@@ -128,8 +86,8 @@ protected function getRequest() {
    * @param array $response
    *   The response from the Canada Post API Rating service.
    *
-   * @return \Drupal\commerce_shipping\ShippingRate[]
-   *   The Canada Post shipping rates.
+   * @return array
+   *   The tracking summary from Canada Post.
    */
   private function parseResponse(array $response) {
     if (!empty($response['tracking-summary']['pin-summary'])) {
diff --git a/src/Commands/Commands.php b/src/Commands/Commands.php
index ae1510e..aef98d4 100644
--- a/src/Commands/Commands.php
+++ b/src/Commands/Commands.php
@@ -2,8 +2,7 @@
 
 namespace Drupal\commerce_canadapost\Commands;
 
-use Drupal\commerce_canadapost\Api\RatingServiceInterface;
-use Drupal\commerce_canadapost\Api\TrackingServiceInterface;
+use Drupal\commerce_canadapost\UtilitiesService;
 use Drush\Commands\DrushCommands;
 
 /**
@@ -12,30 +11,47 @@
 class Commands extends DrushCommands {
 
   /**
-   * The Tracking API service.
+   * The Canada Post utilities service object.
    *
-   * @var \Drupal\commerce_canadapost\Api\TrackingServiceInterface
+   * @var \Drupal\commerce_canadapost\UtilitiesService
    */
-  protected $trackingApi;
+  protected $service;
 
   /**
-   * The Rating API service.
+   * Constructs a new Commands object.
    *
-   * @var \Drupal\commerce_canadapost\Api\RatingServiceInterface
+   * @param \Drupal\commerce_canadapost\UtilitiesService $service
+   *   The Canada Post utilities service object.
    */
-  protected $ratingApi;
+  public function __construct(UtilitiesService $service) {
+    $this->service = $service;
+  }
 
   /**
-   * Constructs a new Commands object.
+   * Fetching tracking summary for shipments and update the tracking data.
    *
-   * @param \Drupal\commerce_canadapost\Api\RatingServiceInterface $service_api
-   *   The Rating API service.
-   * @param \Drupal\commerce_canadapost\Api\TrackingServiceInterface $tracking_api
-   *   The Tracking API service.
+   * @command commerce_canadapost:update_tracking
+   * @aliases cc-uptracking
+   * @option order_ids A comma-separated list of order IDs to update.
+   * @usage commerce_canadapost:update_tracking
+   *   Update tracking for all incomplete orders.
+   * @usage commerce_canadapost:update_tracking --order_ids='1,2,3'
+   *   Update tracking for order IDs 1,2,3.
    */
-  public function __construct(RatingServiceInterface $service_api, TrackingServiceInterface $tracking_api) {
-    $this->trackingApi = $tracking_api;
-    $this->ratingApi = $service_api;
+  public function updateTracking($options = ['order_ids' => NULL]) {
+    $order_ids = NULL;
+    if (!empty($options['order_ids'])) {
+      $order_ids = explode(',', $options['order_ids']);
+    }
+
+    // Update the tracking.
+    $updated_order_ids = $this->service->updateTracking($order_ids);
+
+    $this->logger()->success(dt(
+      'Updated tracking for the following orders: @order_ids.', [
+        '@order_ids' => implode(', ', $updated_order_ids),
+      ]
+    ));
   }
 
 }
diff --git a/src/Plugin/Commerce/ShippingMethod/CanadaPost.php b/src/Plugin/Commerce/ShippingMethod/CanadaPost.php
index 0b9625c..1f89f8a 100755
--- a/src/Plugin/Commerce/ShippingMethod/CanadaPost.php
+++ b/src/Plugin/Commerce/ShippingMethod/CanadaPost.php
@@ -6,11 +6,13 @@
 use Drupal\commerce_shipping\Entity\ShipmentInterface;
 use Drupal\commerce_shipping\PackageTypeManagerInterface;
 use Drupal\commerce_shipping\Plugin\Commerce\ShippingMethod\ShippingMethodBase;
+
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Link;
-use Symfony\Component\DependencyInjection\ContainerInterface;
+
 use CanadaPost\Rating;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Provides the Canada Post shipping method.
@@ -147,7 +149,7 @@ public function buildConfigurationForm(array $form, FormStateInterface $form_sta
     $form['api']['info'] = [
       '#type' => 'markup',
       '#markup' => $this->t(
-        'Canada Post API settings can be added per store or can be configured to be used sitewide. Please @action your @link here.',
+        'Canada Post API settings can be configured to be used sitewide or can be configured per store as well. Please @action your @link here.',
         [
           '@action' => $this->apiIsConfigured() ? 'review' : 'enter',
           '@link' => Link::createFromRoute(
diff --git a/src/UtilitiesService.php b/src/UtilitiesService.php
index 624147e..8c79954 100644
--- a/src/UtilitiesService.php
+++ b/src/UtilitiesService.php
@@ -2,13 +2,16 @@
 
 namespace Drupal\commerce_canadapost;
 
+use Drupal\commerce_canadapost\Api\Request;
+use Drupal\commerce_canadapost\Api\TrackingServiceInterface;
+use Drupal\commerce_shipping\Entity\ShipmentInterface;
 use Drupal\commerce_store\Entity\StoreInterface;
+
 use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\Link;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Core\Url;
-use function json_encode;
-use function json_decode;
 
 /**
  * Class UtilitiesService.
@@ -29,41 +32,45 @@ class UtilitiesService {
   protected $configFactory;
 
   /**
-   * Constructs a UtilitiesService class.
+   * The Tracking API service.
    *
-   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
-   *   The config factory.
+   * @var \Drupal\commerce_canadapost\Api\TrackingServiceInterface
    */
-  public function __construct(ConfigFactoryInterface $config_factory) {
-    $this->configFactory = $config_factory;
-  }
+  protected $trackingApi;
 
   /**
-   * Fetch the Canada Post API settings, first from the store then the site.
+   * The Canada Post Request API service.
    *
-   * @param \Drupal\commerce_store\Entity\StoreInterface $store
-   *   A store entity, if the api settings are for a store.
-   *
-   * @return array
-   *   An array of api settings.
+   * @var \Drupal\commerce_canadapost\Api\RequestInterface
    */
-  public function getApiSettings(StoreInterface $store = NULL) {
-    // If we have store specific settings, return that.
-    if ($store && !empty($store->get('canadapost_api_settings')->getValue()[0]['value'])) {
-      $api_settings = $this->parseSettings(
-        $store->get('canadapost_api_settings')->getValue()[0]['value']
-      );
-    }
-    // Else, we fetch it from the sitewide settings.
-    else {
-      $config = $this->configFactory->get('commerce_canadapost.settings');
+  protected $requestApi;
 
-      foreach ($this->getApiKeys() as $key) {
-        $api_settings[$key] = $config->get("api.$key");
-      }
-    }
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
 
-    return $api_settings;
+  /**
+   * Constructs a UtilitiesService class.
+   *
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
+   *   The config factory.
+   * @param \Drupal\commerce_canadapost\Api\TrackingServiceInterface $tracking_api
+   *   The Tracking API service.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   */
+  public function __construct(
+    ConfigFactoryInterface $config_factory,
+    TrackingServiceInterface $tracking_api,
+    EntityTypeManagerInterface $entity_type_manager
+  ) {
+    $this->configFactory = $config_factory;
+    $this->trackingApi = $tracking_api;
+    $this->requestApi = new Request();
+    $this->entityTypeManager = $entity_type_manager;
   }
 
   /**
@@ -76,7 +83,9 @@ public function getApiSettings(StoreInterface $store = NULL) {
    *   The encoded json object.
    */
   public function encodeSettings(array $values) {
-    foreach ($this->getApiKeys() as $key) {
+    $api_settings_values = [];
+
+    foreach ($this->requestApi->getApiKeys() as $key) {
       $api_settings_values[$key] = $values[$key];
     }
 
@@ -126,7 +135,7 @@ public function buildApiForm(StoreInterface $store = NULL) {
     }
 
     // Fetch the Canada Post API settings.
-    $api_settings = $this->getApiSettings($store);
+    $api_settings = $this->requestApi->setApiSettings($store);
 
     $form['api']['customer_number'] = [
       '#type' => 'textfield',
@@ -192,6 +201,128 @@ public function buildApiForm(StoreInterface $store = NULL) {
     return $form;
   }
 
+  /**
+   * Update tracking data for all incomplete canadapost shipments.
+   *
+   * @param array $order_ids
+   *   An array of order IDs to update the tracking data for. Leave empty to
+   *   update all orders with incomplete shipments.
+   *
+   * @return array
+   *   An array of order IDs for which the shipments were updated for.
+   */
+  public function updateTracking(array $order_ids = NULL) {
+    $updated_order_ids = [];
+
+    // Fetch shipments for tracking.
+    $shipments = $this->fetchShipmentsForTracking($order_ids);
+
+    foreach ($shipments as $shipment) {
+      /** @var \Drupal\commerce_shipping\Entity\ShipmentInterface $shipment */
+      // Fetch tracking summary.
+      $tracking_summary = $this->trackingApi->fetchTrackingSummary($shipment->getTrackingCode(), $shipment);
+
+      // Update the shipment fields with the tracking data.
+      $updated_order_ids[] = $this->updateTrackingFields($shipment, $tracking_summary);
+    }
+
+    return $updated_order_ids;
+  }
+
+  /**
+   * Hide the Canada Post tracking fields from the checkout form.
+   *
+   * @param array $form
+   *   The form array.
+   */
+  public function hideTrackingFields(array &$form) {
+    foreach ($form['shipping_information']['shipments'] as &$shipment) {
+      $fields = [
+        'canadapost_actual_delivery',
+        'canadapost_attempted_delivery',
+        'canadapost_expected_delivery',
+        'canadapost_mailed_on',
+        'canadapost_current_location',
+      ];
+      foreach ($fields as $field) {
+        if (isset($shipment[$field])) {
+          $shipment[$field]['#access'] = FALSE;
+        }
+      }
+    }
+  }
+
+  /**
+   * Fetch all incomplete canadapost shipments that have a tracking pin.
+   *
+   * @param array $order_ids
+   *   Only fetch shipments of specific order IDs.
+   *
+   * @return array
+   *   An array of shipment entities.
+   */
+  protected function fetchShipmentsForTracking(array $order_ids = NULL) {
+    // Query the db for the incomplete shipments.
+    $shipment_query = $this->entityTypeManager
+      ->getStorage('commerce_shipment')
+      ->getQuery();
+    $shipment_query
+      ->condition('type', 'canadapost')
+      ->condition('state', 'completed', '!=')
+      ->condition('tracking_code', NULL, 'IS NOT NULL');
+    // If specific order IDs have been passed.
+    if (!empty($order_ids)) {
+      $shipment_query->condition('order_id', $order_ids, 'IN');
+    }
+    // Fetch the results.
+    $shipment_ids = $shipment_query->execute();
+
+    // Return the loaded shipment entities.
+    return $this->entityTypeManager
+      ->getStorage('commerce_shipment')
+      ->loadMultiple($shipment_ids);
+  }
+
+  /**
+   * Update the shipment fields with the tracking summary.
+   *
+   * @param \Drupal\commerce_shipping\Entity\ShipmentInterface $shipment
+   *   The commerce shipment.
+   * @param array $tracking_summary
+   *   The tracking summary from Canada Post.
+   *
+   * @return int
+   *   The order ID for which the shipment was updated for.
+   */
+  protected function updateTrackingFields(ShipmentInterface $shipment, array $tracking_summary) {
+    // Update the fields.
+    if ($tracking_summary['actual-delivery-date'] != '') {
+      $shipment->set('canadapost_actual_delivery', $tracking_summary['actual-delivery-date']);
+    }
+
+    if ($tracking_summary['attempted-date'] != '') {
+      $shipment->set('canadapost_attempted_delivery', $tracking_summary['attempted-date']);
+    }
+
+    if ($tracking_summary['expected-delivery-date'] != '') {
+      $shipment->set('canadapost_expected_delivery', $tracking_summary['expected-delivery-date']);
+    }
+
+    if ($tracking_summary['mailed-on-date'] != '') {
+      $shipment->set('canadapost_mailed_on', $tracking_summary['mailed-on-date']);
+    }
+
+    if ($tracking_summary['event-location'] != '') {
+      $shipment->set('canadapost_current_location', $tracking_summary['event-location']);
+    }
+
+    // Now, save the shipment.
+    $shipment->save();
+
+    // Return the order ID for this updated shipment.
+    return $shipment->getOrderId();
+  }
+
   /**
    * Alter the Canada Post API settings form fields if we're in the store form.
    *
@@ -213,7 +344,7 @@ protected function alterApiFormFields(array &$form) {
         ],
       ],
     ];
-    foreach ($this->getApiKeys() as $key) {
+    foreach ($this->requestApi->getApiKeys() as $key) {
       $form['api'][$key]['#states'] = $states;
       $form['api'][$key]['#required'] = FALSE;
     }
@@ -224,34 +355,4 @@ protected function alterApiFormFields(array &$form) {
     unset($form['api']['log']['#states']['required']);
   }
 
-  /**
-   * Return the Canada Post API keys.
-   *
-   * @return array
-   *   An array of API setting keys.
-   */
-  protected function getApiKeys() {
-    return [
-      'customer_number',
-      'username',
-      'password',
-      'contract_id',
-      'mode',
-      'log',
-    ];
-  }
-
-  /**
-   * Parse the Canada Post API settings stored as json in the store entity.
-   *
-   * @param object $api_settings
-   *   The json encoded Canada Post api settings.
-   *
-   * @return array
-   *   An array of values extracted from the json object.
-   */
-  protected function parseSettings($api_settings) {
-    return json_decode($api_settings, TRUE);
-  }
-
 }
diff --git a/tests/src/Unit/CanadaPostApiSettingsTest.php b/tests/src/Unit/CanadaPostApiSettingsTest.php
new file mode 100644
index 0000000..a3f58e4
--- /dev/null
+++ b/tests/src/Unit/CanadaPostApiSettingsTest.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Drupal\Tests\commerce_canadapost\Unit;
+
+use Drupal\commerce_canadapost\Api\Request;
+
+/**
+ * Class CanadaPostApiSettingsTest.
+ *
+ * @coversDefaultClass \Drupal\commerce_canadapost\Api\Request
+ * @group commerce_canadapost
+ */
+class CanadaPostApiSettingsTest extends CanadaPostUnitTestBase {
+
+  /**
+   * ::covers getRequestConfig.
+   */
+  public function testSiteWideApiSettingsReturned() {
+    // Set the API settings w/o passing a store entity.
+    $request = new Request();
+    $request->setApiSettings();
+
+    // Now, test that we are returned back the sitewide API settings.
+    $config = $request->getRequestConfig();
+
+    $this->assertEquals('sitewide_mock_cn', $config['customer_number']);
+    $this->assertEquals('sitewide_mock_name', $config['username']);
+    $this->assertEquals('sitewide_mock_pwd', $config['password']);
+    $this->assertEquals('dev', $config['env']);
+  }
+
+  /**
+   * ::covers getRequestConfig.
+   */
+  public function testStoreApiSettingsReturned() {
+    // Set the API settings passing a store entity.
+    $request = new Request();
+    $request->setApiSettings($this->shipment->getOrder()->getStore());
+
+    // Now, test that we are returned back the store API settings.
+    $config = $request->getRequestConfig();
+
+    $this->assertEquals('store_mock_cn', $config['customer_number']);
+    $this->assertEquals('store_mock_name', $config['username']);
+    $this->assertEquals('store_mock_pwd', $config['password']);
+    $this->assertEquals('prod', $config['env']);
+  }
+
+}
diff --git a/tests/src/Unit/CanadaPostRateRequestTest.php b/tests/src/Unit/CanadaPostRateRequestTest.php
index 58ff106..524b289 100644
--- a/tests/src/Unit/CanadaPostRateRequestTest.php
+++ b/tests/src/Unit/CanadaPostRateRequestTest.php
@@ -4,7 +4,6 @@
 
 use CanadaPost\Exception\ClientException;
 use CanadaPost\Rating;
-use Drupal\commerce_canadapost\UtilitiesService;
 use Psr\Http\Message\RequestInterface;
 
 /**
@@ -23,7 +22,6 @@ public function testGetRatesWithPriceQuotes() {
     // we need to mock the getRequest() function and this is the only way to do
     // so.
     $rating_service = $this->getMockBuilder('Drupal\commerce_canadapost\Api\RatingService')
-      ->setConstructorArgs([$this->service, $this->loggerFactory])
       ->setMethods(['getRequest'])
       ->getMock();
 
@@ -55,7 +53,6 @@ public function testGetRatesWithoutPriceQuotes() {
     // we need to mock the getRequest() function and this is the only way to do
     // so.
     $rating_service = $this->getMockBuilder('Drupal\commerce_canadapost\Api\RatingService')
-      ->setConstructorArgs([$this->service, $this->loggerFactory])
       ->setMethods(['getRequest'])
       ->getMock();
 
@@ -77,7 +74,6 @@ public function testGetRatesWithException() {
     // we need to mock the getRequest() function and this is the only way to do
     // so.
     $rating_service = $this->getMockBuilder('Drupal\commerce_canadapost\Api\RatingService')
-      ->setConstructorArgs([$this->service, $this->loggerFactory])
       ->setMethods(['getRequest'])
       ->getMock();
 
diff --git a/tests/src/Unit/CanadaPostTrackingtTest.php b/tests/src/Unit/CanadaPostTrackingtTest.php
index 167b0e4..0cd195f 100644
--- a/tests/src/Unit/CanadaPostTrackingtTest.php
+++ b/tests/src/Unit/CanadaPostTrackingtTest.php
@@ -22,7 +22,6 @@ public function testFetchTrackingSummaryWithTrackingPin() {
     // we need to mock the getRequest() function and this is the only way to do
     // so.
     $tracking_service = $this->getMockBuilder('Drupal\commerce_canadapost\Api\TrackingService')
-      ->setConstructorArgs([$this->service, $this->loggerFactory])
       ->setMethods(['getRequest'])
       ->getMock();
 
@@ -52,7 +51,6 @@ public function testFetchTrackingSummaryWithoutTrackingPin() {
     // we need to mock the getRequest() function and this is the only way to do
     // so.
     $tracking_service = $this->getMockBuilder('Drupal\commerce_canadapost\Api\TrackingService')
-      ->setConstructorArgs([$this->service, $this->loggerFactory])
       ->setMethods(['getRequest'])
       ->getMock();
 
@@ -74,7 +72,6 @@ public function testFetchTrackingSummaryWithException() {
     // we need to mock the getRequest() function and this is the only way to do
     // so.
     $tracking_service = $this->getMockBuilder('Drupal\commerce_canadapost\Api\TrackingService')
-      ->setConstructorArgs([$this->service, $this->loggerFactory])
       ->setMethods(['getRequest'])
       ->getMock();
 
diff --git a/tests/src/Unit/CanadaPostUnitTestBase.php b/tests/src/Unit/CanadaPostUnitTestBase.php
index 0269484..c97b24b 100644
--- a/tests/src/Unit/CanadaPostUnitTestBase.php
+++ b/tests/src/Unit/CanadaPostUnitTestBase.php
@@ -3,8 +3,10 @@
 namespace Drupal\Tests\commerce_canadapost\Unit;
 
 use CommerceGuys\Addressing\AddressInterface;
-use Drupal\commerce_canadapost\UtilitiesService;
 use Drupal\commerce_shipping\Plugin\Commerce\ShippingMethod\ShippingMethodInterface;
+use Drupal\Core\Config\ConfigFactoryInterface;
+use Drupal\Core\Config\ImmutableConfig;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\Logger\LoggerChannelFactoryInterface;
 use Drupal\Core\Logger\LoggerChannelInterface;
 use Drupal\Tests\UnitTestCase;
@@ -17,6 +19,7 @@
 use Drupal\commerce_shipping\Entity\ShipmentInterface;
 use Drupal\commerce_shipping\Plugin\Commerce\PackageType\PackageTypeInterface;
 use Drupal\commerce_store\Entity\StoreInterface;
+use Drupal\text\Plugin\Field\FieldType\TextLongItem;
 
 define('COMMERCE_CANADAPOST_LOGGER_CHANNEL', 'commerce_canadapost');
 
@@ -27,13 +30,6 @@
  */
 abstract class CanadaPostUnitTestBase extends UnitTestCase {
 
-  /**
-   * The logger channel factory.
-   *
-   * @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
-   */
-  protected $loggerFactory;
-
   /**
    * The shipping method interface.
    *
@@ -48,13 +44,6 @@
    */
   protected $shipment;
 
-  /**
-   * The Canada Post Utilities service object.
-   *
-   * @var \Drupal\commerce_canadapost\UtilitiesService
-   */
-  protected $service;
-
   /**
    * Set up requirements for test.
    */
@@ -68,26 +57,21 @@ public function setUp() {
     $logger = $this->prophesize(LoggerChannelInterface::class);
     $logger_factory->get(COMMERCE_CANADAPOST_LOGGER_CHANNEL)
       ->willReturn($logger->reveal());
-
-    $this->loggerFactory = $logger_factory->reveal();
-
-    $store = $this->shipment->getOrder()->getStore();
-
-    $utilities_service = $this->prophesize(UtilitiesService::class);
-    $utilities_service->getApiSettings($store)->willReturn([
-      'customer_number' => 'mock_cn',
-      'username' => 'mock_name',
-      'password' => 'mock_pwd',
-      'contract_id' => '',
-      'rate.origin_postal_code' => '',
-      'mode' => 'test',
-      'log' => [
-        'request' => FALSE,
-        'response' => FALSE,
-      ],
-    ]);
-
-    $this->service = $utilities_service->reveal();
+    $logger_factory = $logger_factory->reveal();
+
+    $config_factory = $this->prophesize(ConfigFactoryInterface::class);
+    $config = $this->prophesize(ImmutableConfig::class);
+    $sitewide_settings = $this->getSiteWideApiSettings();
+    foreach ($sitewide_settings as $key => $value) {
+      $config->get("api.$key")->willReturn($value);
+    }
+    $config_factory->get('commerce_canadapost.settings')->willReturn($config);
+    $config_factory = $config_factory->reveal();
+
+    $container = new ContainerBuilder();
+    $container->set('logger.factory', $logger_factory);
+    $container->set('config.factory', $config_factory);
+    \Drupal::setContainer($container);
   }
 
   /**
@@ -101,6 +85,16 @@ public function mockShipment() {
     $order = $this->prophesize(OrderInterface::class);
     $store = $this->prophesize(StoreInterface::class);
 
+    // Mock the store API settings.
+    $api_settings = $this->prophesize(TextLongItem::class);
+    $encoded_api_settings = json_encode($this->getStoreApiSettings());
+    $api_settings->getValue()->willReturn([
+      0 => [
+        'value' => $encoded_api_settings,
+      ],
+    ]);
+    $store->get('canadapost_api_settings')->willReturn($api_settings);
+
     // Mock the getAddress method to return a Canadian address.
     $store->getAddress()
       ->willReturn(new Address('CA', 'YK', 'Whitehorse', '', 'Y1A4P9', '', '9031 Quartz Road'));
@@ -150,4 +144,46 @@ public function mockShippingMethod() {
     return $shipping_method->reveal();
   }
 
+  /**
+   * Returns an array of mock Canada Post API settings.
+   *
+   * @return array
+   *   The API settings.
+   */
+  protected function getSiteWideApiSettings() {
+    return [
+      'customer_number' => 'sitewide_mock_cn',
+      'username' => 'sitewide_mock_name',
+      'password' => 'sitewide_mock_pwd',
+      'contract_id' => '',
+      'rate.origin_postal_code' => '',
+      'mode' => 'test',
+      'log' => [
+        'request' => FALSE,
+        'response' => FALSE,
+      ],
+    ];
+  }
+
+  /**
+   * Returns an array of mock Canada Post API settings.
+   *
+   * @return array
+   *   The API settings.
+   */
+  protected function getStoreApiSettings() {
+    return [
+      'customer_number' => 'store_mock_cn',
+      'username' => 'store_mock_name',
+      'password' => 'store_mock_pwd',
+      'contract_id' => '',
+      'rate.origin_postal_code' => '',
+      'mode' => 'live',
+      'log' => [
+        'request' => FALSE,
+        'response' => FALSE,
+      ],
+    ];
+  }
+
 }
