diff --git a/commerce_loyalty_points.install b/commerce_loyalty_points.install
index 90b62b6..1ad96ce 100644
--- a/commerce_loyalty_points.install
+++ b/commerce_loyalty_points.install
@@ -8,6 +8,7 @@
 use Drupal\commerce_product\Entity\ProductVariationType;
 use Drupal\field\Entity\FieldStorageConfig;
 use Drupal\user\Entity\Role;
+use Drupal\Core\Config\FileStorage;
 
 /**
  * Implements hook_install().
@@ -51,3 +52,15 @@ function commerce_loyalty_points_uninstall() {
   // Remove user's data.
   \Drupal::service('user.data')->delete('commerce_loyalty_points');
 }
+
+/**
+ * Update loyalty points admin View.
+ */
+function commerce_loyalty_points_update_8002() {
+  $config_name = 'views.view.loyalty_points_offered';
+  $config_path = drupal_get_path('module', 'commerce_loyalty_points') . '/config/install';
+  $source = new FileStorage($config_path);
+
+  $active_storage = \Drupal::service('config.storage');
+  $active_storage->write($config_name, $source->read($config_name));
+}
diff --git a/commerce_loyalty_points.links.action.yml b/commerce_loyalty_points.links.action.yml
new file mode 100644
index 0000000..b3e76f7
--- /dev/null
+++ b/commerce_loyalty_points.links.action.yml
@@ -0,0 +1,5 @@
+entity.commerce_loyalty_points.add_points:
+  route_name: commerce_loyalty_points.add_form
+  title: 'Add loyalty points'
+  appears_on:
+    - entity.commerce_loyalty_points.collection
diff --git a/commerce_loyalty_points.module b/commerce_loyalty_points.module
index 956fd44..ba2b259 100644
--- a/commerce_loyalty_points.module
+++ b/commerce_loyalty_points.module
@@ -133,3 +133,33 @@ function commerce_loyalty_points_user_profile_form_submit($form, FormStateInterf
     $account->save();
   }
 }
+
+/**
+ * Implements hook_views_data_alter().
+ */
+function commerce_loyalty_points_views_data_alter(array &$data) {
+  $data['commerce_loyalty_points']['aggregate_loyalty_points'] = [
+    'title' => t('Aggregate loyalty points'),
+    'help' => t('Aggregate Loyalty points for a user.'),
+    'field' => [
+      'title' => t('Aggregate loyalty points for a user'),
+      'id' => 'aggregate_loyalty_points',
+    ],
+  ];
+}
+
+/**
+ * Implements hook_form_alter().
+ */
+function commerce_loyalty_points_form_alter(&$form, FormStateInterface $form_state, $form_id) {
+  if (isset($form_state->getStorage('view')['view'])) {
+    $view = $form_state->getStorage('view')['view'];
+    if ($form_id == 'views_exposed_form' && $view->id() == 'loyalty_points_offered' && $view->current_display == 'admin_view') {
+      $form['uid']['#type'] = 'entity_autocomplete';
+      $form['uid']['#target_type'] = 'user';
+      $form['uid']['#selection_settings'] = [
+        'include_anonymous' => FALSE,
+      ];
+    }
+  }
+}
diff --git a/commerce_loyalty_points.routing.yml b/commerce_loyalty_points.routing.yml
new file mode 100644
index 0000000..eb4f23c
--- /dev/null
+++ b/commerce_loyalty_points.routing.yml
@@ -0,0 +1,15 @@
+entity.commerce_loyalty_points.canonical:
+  path: '/loyalty-points/{commerce_loyalty_points}'
+  defaults:
+    _entity_view: 'commerce_loyalty_points'
+    _title: 'Loyalty Points'
+  requirements:
+    _entity_access: 'commerce_loyalty_points.view'
+
+commerce_loyalty_points.add_form:
+  path: '/loyalty-points/add'
+  defaults:
+    _entity_form: commerce_loyalty_points.add
+    _title: 'Add loyalty points'
+  requirements:
+    _permission: 'administer loyalty points entities'
diff --git a/config/install/views.view.loyalty_points_offered.yml b/config/install/views.view.loyalty_points_offered.yml
index 2e6bc15..f5dbd30 100644
--- a/config/install/views.view.loyalty_points_offered.yml
+++ b/config/install/views.view.loyalty_points_offered.yml
@@ -1,3 +1,4 @@
+uuid: 011110e5-aea3-43a6-969f-ddd9430c30f1
 langcode: en
 status: true
 dependencies:
@@ -7,7 +8,7 @@ dependencies:
     - commerce_loyalty_points
     - user
 _core:
-  default_config_hash: 76WSv3f7f7xp6bTdqAbXpD-Pfn7on0XRHbXn5wIHNj4
+  default_config_hash: dUdWeOVNKfDr-3CBtmdXxejvguo_51wDcu5X7oiBM3g
 id: loyalty_points_offered
 label: 'Loyalty points offered'
 module: views
@@ -73,6 +74,10 @@ display:
               field: uid
               rendered: true
               rendered_strip: false
+            -
+              field: aggregate_loyalty_points
+              rendered: true
+              rendered_strip: false
           row_class: ''
           default_row_class: true
           override: true
@@ -82,6 +87,11 @@ display:
           description: ''
           columns:
             uid: uid
+            loyalty_points: loyalty_points
+            created: created
+            reason: reason
+            operations: operations
+            aggregate_loyalty_points: aggregate_loyalty_points
           info:
             uid:
               sortable: false
@@ -89,6 +99,39 @@ display:
               align: ''
               separator: ''
               empty_column: false
+              responsive: priority-low
+            loyalty_points:
+              sortable: false
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+            created:
+              sortable: false
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+            reason:
+              sortable: false
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+            operations:
+              align: ''
+              separator: ''
+              empty_column: false
+              responsive: ''
+            aggregate_loyalty_points:
+              sortable: false
+              default_sort_order: asc
+              align: ''
+              separator: ''
+              empty_column: false
               responsive: ''
           default: '-1'
           empty_table: false
@@ -426,6 +469,9 @@ display:
         filters: false
         filter_groups: false
         access: false
+        fields: false
+        relationships: false
+        title: false
       filters:
         uid:
           id: uid
@@ -443,8 +489,8 @@ display:
           exposed: true
           expose:
             operator_id: uid_op
-            label: 'User ID'
-            description: 'Lookup by user''s unique ID.'
+            label: Username
+            description: 'Start typing a username'
             use_operator: false
             operator: uid_op
             identifier: uid
@@ -455,6 +501,8 @@ display:
               authenticated: authenticated
               anonymous: '0'
               administrator: '0'
+              pos_cashier: '0'
+              loyalty_points_subscriber: '0'
           is_grouped: false
           group_info:
             label: ''
@@ -478,6 +526,375 @@ display:
         type: perm
         options:
           perm: 'administer loyalty points entities'
+      fields:
+        uid:
+          id: uid
+          table: commerce_loyalty_points
+          field: uid
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Username
+          exclude: true
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: target_id
+          type: entity_reference_label
+          settings:
+            link: false
+          group_column: target_id
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: commerce_loyalty_points
+          entity_field: uid
+          plugin_id: field
+        loyalty_points:
+          id: loyalty_points
+          table: commerce_loyalty_points
+          field: loyalty_points
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Loyalty points'
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: number_decimal
+          settings:
+            thousand_separator: ''
+            prefix_suffix: true
+            decimal_separator: .
+            scale: 2
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: commerce_loyalty_points
+          entity_field: loyalty_points
+          plugin_id: field
+        created:
+          id: created
+          table: commerce_loyalty_points
+          field: created
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Created
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: timestamp
+          settings:
+            date_format: short
+            custom_date_format: ''
+            timezone: ''
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: commerce_loyalty_points
+          entity_field: created
+          plugin_id: field
+        reason:
+          id: reason
+          table: commerce_loyalty_points
+          field: reason
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Reason
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          click_sort_column: value
+          type: string
+          settings:
+            link_to_entity: false
+          group_column: value
+          group_columns: {  }
+          group_rows: true
+          delta_limit: 0
+          delta_offset: 0
+          delta_reversed: false
+          delta_first_last: false
+          multi_type: separator
+          separator: ', '
+          field_api_classes: false
+          entity_type: commerce_loyalty_points
+          entity_field: reason
+          plugin_id: field
+        operations:
+          id: operations
+          table: commerce_loyalty_points
+          field: operations
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: Operations
+          exclude: false
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          destination: true
+          entity_type: commerce_loyalty_points
+          plugin_id: entity_operations
+        aggregate_loyalty_points:
+          id: aggregate_loyalty_points
+          table: commerce_loyalty_points
+          field: aggregate_loyalty_points
+          relationship: none
+          group_type: group
+          admin_label: ''
+          label: 'Total points'
+          exclude: true
+          alter:
+            alter_text: false
+            text: ''
+            make_link: false
+            path: ''
+            absolute: false
+            external: false
+            replace_spaces: false
+            path_case: none
+            trim_whitespace: false
+            alt: ''
+            rel: ''
+            link_class: ''
+            prefix: ''
+            suffix: ''
+            target: ''
+            nl2br: false
+            max_length: 0
+            word_boundary: true
+            ellipsis: true
+            more_link: false
+            more_link_text: ''
+            more_link_path: ''
+            strip_tags: false
+            trim: false
+            preserve_tags: ''
+            html: false
+          element_type: ''
+          element_class: ''
+          element_label_type: ''
+          element_label_class: ''
+          element_label_colon: true
+          element_wrapper_type: ''
+          element_wrapper_class: ''
+          element_default_classes: true
+          empty: ''
+          hide_empty: false
+          empty_zero: false
+          hide_alter_empty: true
+          entity_type: commerce_loyalty_points
+          plugin_id: aggregate_loyalty_points
+      relationships: {  }
+      title: 'Administer Loyalty points'
     cache_metadata:
       max-age: 0
       contexts:
diff --git a/src/Entity/LoyaltyPoints.php b/src/Entity/LoyaltyPoints.php
index 118c19a..7528fc8 100644
--- a/src/Entity/LoyaltyPoints.php
+++ b/src/Entity/LoyaltyPoints.php
@@ -12,21 +12,19 @@ use Drupal\Core\Entity\EntityTypeInterface;
  * @ContentEntityType(
  *   id = "commerce_loyalty_points",
  *   label = @Translation("Loyalty points"),
- *   label_singular = @Translation("Loyalty point"),
- *   label_plural = @Translation("Loyalty points"),
- *   label_count = @PluralTranslation(
- *     singular = "@count loyalty point",
- *     plural = "@count loyalty points",
- *   ),
  *   handlers = {
  *     "storage" = "Drupal\commerce_loyalty_points\LoyaltyPointsStorage",
  *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
+ *     "list_builder" = "Drupal\commerce_loyalty_points\LoyaltyPointsListBuilder",
  *     "views_data" = "Drupal\views\EntityViewsData",
  *     "form" = {
- *       "add" = "Drupal\Core\Entity\ContentEntityForm",
- *       "edit" = "Drupal\Core\Entity\ContentEntityForm",
+ *       "add" = "Drupal\commerce_loyalty_points\Form\LoyaltyPointsForm",
+ *       "edit" = "Drupal\commerce_loyalty_points\Form\LoyaltyPointsForm",
  *       "delete" = "Drupal\Core\Entity\ContentEntityDeleteForm"
  *     },
+ *     "route_provider" = {
+ *       "default" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider",
+ *     },
  *   },
  *   base_table = "commerce_loyalty_points",
  *   admin_permission = "administer loyalty points entities",
@@ -35,17 +33,45 @@ use Drupal\Core\Entity\EntityTypeInterface;
  *     "uuid" = "uuid"
  *   },
  *   links = {
- *     "collection" = "/admin/commerce/loyalty-points"
+ *     "canonical" = "/loyalty-points/{commerce_loyalty_points}",
+ *     "add-form" = "/loyalty-points/add",
+ *     "edit-form" = "/loyalty-points/{commerce_loyalty_points}/edit",
+ *     "delete-form" = "/loyalty-points/{commerce_loyalty_points}/delete",
+ *     "collection" = "/admin/commerce/loyalty-points",
  *   },
  * )
  */
-class LoyaltyPoints extends ContentEntityBase {
+class LoyaltyPoints extends ContentEntityBase implements LoyaltyPointsInterface {
 
   /**
    * {@inheritdoc}
    */
   public function getLoyaltyPoints() {
-    return $this->get('id')->value;
+    return $this->get('loyalty_points')->value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getUserId() {
+    return $this->get('uid')->target_id;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getUser() {
+    $uid = $this->get('uid')->target_id;
+    return \Drupal::entityTypeManager()
+      ->getStorage('user')
+      ->load($uid);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getReason() {
+    return $this->get('reason')->value;
   }
 
   /**
@@ -58,16 +84,35 @@ class LoyaltyPoints extends ContentEntityBase {
       ->setDescription(t('The loyalty point identifier.'));
 
     $fields['uid'] = BaseFieldDefinition::create('entity_reference')
-      ->setLabel(t('UID'))
-      ->setDescription(t('User ID referenced from {users}.'))
+      ->setLabel(t('Username'))
       ->setSetting('target_type', 'user')
-      ->setReadOnly(TRUE)
-      ->setDisplayConfigurable('view', TRUE);
+      ->setRequired(TRUE)
+      ->setDisplayConfigurable('form', TRUE)
+      ->setDisplayConfigurable('view', TRUE)
+      ->setDisplayOptions('view', [
+        'label' => 'inline',
+        'type' => 'string',
+        'weight' => 0,
+      ])
+      ->setDisplayOptions('form', [
+        'type' => 'string_textfield',
+        'weight' => 0,
+      ]);
 
     $fields['loyalty_points'] = BaseFieldDefinition::create('decimal')
       ->setLabel(t('Loyalty points'))
-      ->setReadOnly(TRUE)
-      ->setDisplayConfigurable('view', TRUE);
+      ->setRequired(TRUE)
+      ->setDisplayConfigurable('view', TRUE)
+      ->setDisplayOptions('view', [
+        'label' => 'inline',
+        'type' => 'decimal',
+        'weight' => 0,
+      ])
+      ->setDisplayOptions('form', [
+        'type' => 'decimal_textfield',
+        'weight' => 5,
+      ])
+      ->setDescription(t('Positive value to add, negative to deduct'));
 
     $fields['reason'] = BaseFieldDefinition::create('string')
       ->setLabel(t('Reason'))
@@ -80,12 +125,13 @@ class LoyaltyPoints extends ContentEntityBase {
       ->setDisplayOptions('view', [
         'label' => 'inline',
         'type' => 'string',
-        'weight' => -4,
+        'weight' => 0,
       ])
       ->setDisplayOptions('form', [
         'type' => 'string_textfield',
-        'weight' => -4,
+        'weight' => 10,
       ])
+      ->setRequired(TRUE)
       ->setDisplayConfigurable('form', TRUE)
       ->setDisplayConfigurable('view', TRUE);
 
diff --git a/src/Entity/LoyaltyPointsInterface.php b/src/Entity/LoyaltyPointsInterface.php
new file mode 100644
index 0000000..a6b4430
--- /dev/null
+++ b/src/Entity/LoyaltyPointsInterface.php
@@ -0,0 +1,42 @@
+<?php
+
+namespace Drupal\commerce_loyalty_points\Entity;
+
+/**
+ * Interface LoyaltyPointsInterface.
+ */
+interface LoyaltyPointsInterface {
+
+  /**
+   * Loyalty points for an entity.
+   *
+   * @return float
+   *   Loyalty points - positive value to add, negative to deduct.
+   */
+  public function getLoyaltyPoints();
+
+  /**
+   * User ID.
+   *
+   * @return int
+   *   Unique user ID.
+   */
+  public function getUserId();
+
+  /**
+   * User object.
+   *
+   * @return \Drupal\user\Entity\User
+   *   User loaded entity.
+   */
+  public function getUser();
+
+  /**
+   * Reason for adding/deducting loyalty points.
+   *
+   * @return string
+   *   Short description for entity.
+   */
+  public function getReason();
+
+}
diff --git a/src/Form/LoyaltyPointsForm.php b/src/Form/LoyaltyPointsForm.php
new file mode 100644
index 0000000..3584e27
--- /dev/null
+++ b/src/Form/LoyaltyPointsForm.php
@@ -0,0 +1,33 @@
+<?php
+
+namespace Drupal\commerce_loyalty_points\Form;
+
+use Drupal\commerce_loyalty_points\Entity\LoyaltyPoints;
+use Drupal\Core\Entity\ContentEntityForm;
+use Drupal\Core\Form\FormStateInterface;
+
+/**
+ * Form controller for the commerce_loyalty_points entity forms.
+ *
+ * @ingroup commerce_loyalty_points
+ */
+class LoyaltyPointsForm extends ContentEntityForm {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function save(array $form, FormStateInterface $form_state) {
+    /** @var \Drupal\commerce_loyalty_points\Entity\LoyaltyPoints $entity */
+    $entity = $this->getEntity();
+    $entity->save();
+
+    // Redirect to view page.
+    $user = $entity->getUser();
+    $form_state->setRedirect('entity.commerce_loyalty_points.collection', [], [
+      'query' => [
+        'uid' => $user->getUsername() . ' (' . $user->id() . ')',
+      ],
+    ]);
+  }
+
+}
diff --git a/src/LoyaltyPointsListBuilder.php b/src/LoyaltyPointsListBuilder.php
new file mode 100644
index 0000000..72ec52c
--- /dev/null
+++ b/src/LoyaltyPointsListBuilder.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Drupal\commerce_loyalty_points;
+
+use Drupal\Core\Entity\EntityListBuilder;
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * Provides a listing of Loyalty points entities.
+ */
+class LoyaltyPointsListBuilder extends EntityListBuilder {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildHeader() {
+    $header['label'] = $this->t('Loyalty Points');
+//    $header['store'] = $this->t('Store');
+    return $header + parent::buildHeader();
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildRow(EntityInterface $entity) {
+    $row['lpid'] = $entity->label();
+//    $row['reason'] = $entity->getStore()->getName();
+
+    return $row + parent::buildRow($entity);
+  }
+
+}
diff --git a/src/Plugin/views/field/AggregateLoyaltyPoints.php b/src/Plugin/views/field/AggregateLoyaltyPoints.php
new file mode 100644
index 0000000..eb0a6ae
--- /dev/null
+++ b/src/Plugin/views/field/AggregateLoyaltyPoints.php
@@ -0,0 +1,89 @@
+<?php
+
+namespace Drupal\commerce_loyalty_points\Plugin\views\field;
+
+use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\views\Plugin\views\field\FieldPluginBase;
+use Drupal\views\ResultRow;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Aggregates loyalty points for a user.
+ *
+ * @ViewsField("aggregate_loyalty_points")
+ */
+class AggregateLoyaltyPoints extends FieldPluginBase implements ContainerFactoryPluginInterface {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The module handler.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $moduleHandler;
+
+  /**
+   * AggregateLoyaltyPoints constructor.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler service.
+   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
+   *   The entity type manager.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, ModuleHandlerInterface $module_handler, EntityTypeManagerInterface $entity_type_manager) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->moduleHandler = $module_handler;
+    $this->entityTypeManager = $entity_type_manager;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('module_handler'),
+      $container->get('entity_type.manager')
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function query() {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function render(ResultRow $values) {
+    /** @var \Drupal\commerce_loyalty_points\Entity\LoyaltyPointsInterface $entity */
+    $entity = $this->getEntity($values);
+
+    /** @var \Drupal\commerce_loyalty_points\LoyaltyPointsStorageInterface $loyalty_points_storage */
+    $loyalty_points_storage = $this->entityTypeManager->getStorage('commerce_loyalty_points');
+    $uid = $entity->getUserId();
+    $aggregate_loyalty_points = $loyalty_points_storage->loadAndAggregateUserLoyaltyPoints($uid);
+    $key = 'table_aggregate';
+    $this->moduleHandler->alter('loyalty_points_view', $aggregate_loyalty_points, $key);
+
+    return $aggregate_loyalty_points;
+  }
+
+}
