diff --git a/commerce_reports.plugin_type.yml b/commerce_reports.plugin_type.yml
new file mode 100644
index 0000000..bf06209
--- /dev/null
+++ b/commerce_reports.plugin_type.yml
@@ -0,0 +1,5 @@
+commerce_reports.commerce_report_type:
+  label: Order report type
+  provider: commerce_reports
+  plugin_manager_service_id: plugin.manager.commerce_report_type
+  plugin_definition_decorator_class: Drupal\plugin\PluginDefinition\ArrayPluginDefinitionDecorator
diff --git a/commerce_reports.services.yml b/commerce_reports.services.yml
index a8c02ce..247586c 100644
--- a/commerce_reports.services.yml
+++ b/commerce_reports.services.yml
@@ -1,6 +1,10 @@
 services:
   commerce_reports.order_placed_subscriber:
     class: Drupal\commerce_reports\EventSubscriber\OrderPlacedEventSubscriber
-    arguments: ['@entity_type.manager', '@state']
+    arguments: ['@entity_type.manager', '@state', '@plugin.manager.commerce_report_type']
     tags:
       - { name: event_subscriber }
+
+  plugin.manager.commerce_report_type:
+      class: Drupal\commerce_reports\ReportTypeManager
+      parent: default_plugin_manager
diff --git a/src/Annotation/CommerceReportType.php b/src/Annotation/CommerceReportType.php
new file mode 100644
index 0000000..7a9494c
--- /dev/null
+++ b/src/Annotation/CommerceReportType.php
@@ -0,0 +1,43 @@
+<?php
+
+namespace Drupal\commerce_reports\Annotation;
+
+use Drupal\Component\Annotation\Plugin;
+
+/**
+ * Defines the commerce report type plugin annotation object.
+ *
+ * Plugin namespace: Plugin\Commerce\ReportType.
+ *
+ * @see plugin_api
+ *
+ * @Annotation
+ */
+class CommerceReportType extends Plugin {
+
+  /**
+   * The plugin ID.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The commerce report type label.
+   *
+   * @ingroup plugin_translatable
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   */
+  public $label;
+
+  /**
+   * The commerce report type create label.
+   *
+   * @ingroup plugin_translatable
+   *
+   * @var \Drupal\Core\Annotation\Translation
+   */
+  public $create_label;
+
+}
diff --git a/src/Entity/OrderReport.php b/src/Entity/OrderReport.php
index a79fa39..3e4810a 100644
--- a/src/Entity/OrderReport.php
+++ b/src/Entity/OrderReport.php
@@ -2,6 +2,9 @@

 namespace Drupal\commerce_reports\Entity;

+use Drupal\Core\Annotation\PluralTranslation;
+use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Entity\Annotation\ContentEntityType;
 use Drupal\Core\Entity\ContentEntityBase;
 use Drupal\Core\Entity\EntityTypeInterface;
 use Drupal\Core\Field\BaseFieldDefinition;
@@ -18,10 +21,12 @@
  *     singular = "@count order report",
  *     plural = "@count order reports",
  *   ),
+ *   bundle_label = @Translation("Order report type"),
+ *   bundle_plugin_type = "commerce_report_type",
  *   handlers = {
  *     "access" = "Drupal\commerce\EntityAccessControlHandler",
  *     "permission_provider" = "Drupal\commerce\EntityPermissionProvider",
- *     "list_builder" = "Drupal\commerce_reports\OrderReportsListBuilder",
+ *     "list_builder" = "Drupal\commerce_reports\ReportsListBuilder",
  *     "storage" = "Drupal\Core\Entity\Sql\SqlContentEntityStorage",
  *     "views_data" = "Drupal\views\EntityViewsData",
  *     "route_provider" = {
@@ -33,6 +38,7 @@
  *   fieldable = TRUE,
  *   entity_keys = {
  *     "id" = "report_id",
+ *     "bundle" = "type",
  *     "uuid" = "uuid",
  *   },
  *   links = {
@@ -77,33 +83,6 @@ public function getCreatedTime() {
   /**
    * {@inheritdoc}
    */
-  public function getAmount() {
-    if (!$this->get('amount')->isEmpty()) {
-      return $this->get('amount')->first()->toPrice();
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTaxAmount() {
-    if (!$this->get('tax_amount')->isEmpty()) {
-      return $this->get('tax_amount')->first()->toPrice();
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getShippingAmount() {
-    if (!$this->get('shipping_amount')->isEmpty()) {
-      return $this->get('shipping_amount')->first()->toPrice();
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
   public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
     $fields = parent::baseFieldDefinitions($entity_type);

@@ -112,21 +91,6 @@ public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
       ->setDescription(t('The parent order.'))
       ->setSetting('target_type', 'commerce_order')
       ->setReadOnly(TRUE);
-    $fields['amount'] = BaseFieldDefinition::create('commerce_price')
-      ->setLabel(t('Amount'))
-      ->setDescription(t('The order total amount.'))
-      ->setRequired(TRUE)
-      ->setDisplayConfigurable('view', TRUE);
-    $fields['tax_amount'] = BaseFieldDefinition::create('commerce_price')
-      ->setLabel(t('Tax amount'))
-      ->setDescription(t('The tax amount.'))
-      ->setRequired(TRUE)
-      ->setDisplayConfigurable('view', TRUE);
-    $fields['shipping_amount'] = BaseFieldDefinition::create('commerce_price')
-      ->setLabel(t('Shipping amount'))
-      ->setDescription(t('The shipping amount.'))
-      ->setRequired(TRUE)
-      ->setDisplayConfigurable('view', TRUE);
     $fields['created'] = BaseFieldDefinition::create('created')
       ->setLabel(t('Created'))
       ->setDescription(t('The time when the order report was created.'))
diff --git a/src/Entity/OrderReportInterface.php b/src/Entity/OrderReportInterface.php
index 71d4bdf..d5931e0 100644
--- a/src/Entity/OrderReportInterface.php
+++ b/src/Entity/OrderReportInterface.php
@@ -26,30 +26,6 @@ public function getOrderId();
   public function getOrder();

   /**
-   * Gets the order total amount.
-   *
-   * @return \Drupal\commerce_price\Price|null
-   *   The order total amount, or NULL.
-   */
-  public function getAmount();
-
-  /**
-   * Gets the order total tax amount.
-   *
-   * @return \Drupal\commerce_price\Price|null
-   *   The order total tax amount, or NULL.
-   */
-  public function getTaxAmount();
-
-  /**
-   * Gets the order total shipping amount.
-   *
-   * @return \Drupal\commerce_price\Price|null
-   *   The order total shipping amount, or NULL.
-   */
-  public function getShippingAmount();
-
-  /**
    * Gets the order report creation timestamp.
    *
    * This is when the order transitions from a draft to a non-draft state,
diff --git a/src/EventSubscriber/OrderPlacedEventSubscriber.php b/src/EventSubscriber/OrderPlacedEventSubscriber.php
index 9a38717..f4ef55a 100644
--- a/src/EventSubscriber/OrderPlacedEventSubscriber.php
+++ b/src/EventSubscriber/OrderPlacedEventSubscriber.php
@@ -2,6 +2,8 @@

 namespace Drupal\commerce_reports\EventSubscriber;

+use Drupal\commerce_reports\Plugin\Commerce\ReportType\OrderReportTypeInterface;
+use Drupal\commerce_reports\ReportTypeManager;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
 use Drupal\Core\State\StateInterface;
 use Drupal\state_machine\Event\WorkflowTransitionEvent;
@@ -15,13 +17,6 @@
 class OrderPlacedEventSubscriber implements EventSubscriberInterface {

   /**
-   * The order report storage.
-   *
-   * @var \Drupal\Core\Entity\EntityStorageInterface
-   */
-  protected $orderReportStorage;
-
-  /**
    * The order storage.
    *
    * @var \Drupal\Core\Entity\EntityStorageInterface
@@ -36,17 +31,24 @@ class OrderPlacedEventSubscriber implements EventSubscriberInterface {
   protected $state;

   /**
+   * @var \Drupal\commerce_payment\OrderReportTypeManager
+   */
+  protected $orderReportTypeManager;
+
+  /**
    * Constructs a new OrderPlacedEventSubscriber object.
    *
    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
    *   The entity type manager.
    * @param \Drupal\Core\State\StateInterface $state
    *   The state key/value store.
+   * @param \Drupal\commerce_payment\OrderReportTypeManager
+   *   The order report type manager.
    */
-  public function __construct(EntityTypeManagerInterface $entity_type_manager, StateInterface $state) {
-    $this->orderReportStorage = $entity_type_manager->getStorage('commerce_order_report');
+  public function __construct(EntityTypeManagerInterface $entity_type_manager, StateInterface $state, ReportTypeManager $orderReportTypeManager) {
     $this->orderStorage = $entity_type_manager->getStorage('commerce_order');
     $this->state = $state;
+    $this->orderReportTypeManager = $orderReportTypeManager;
   }

   /**
@@ -57,7 +59,6 @@ public function __construct(EntityTypeManagerInterface $entity_type_manager, Sta
    */
   public function flagOrder(WorkflowTransitionEvent $event) {
     $order = $event->getEntity();
-
     $existing = $this->state->get('commerce_order_reports', []);
     $existing[] = $order->id();
     $this->state->set('commerce_order_reports', $existing);
@@ -72,16 +73,14 @@ public function flagOrder(WorkflowTransitionEvent $event) {
   public function generateReports(PostResponseEvent $event) {
     $order_ids = $this->state->get('commerce_order_reports', []);
     $orders = $this->orderStorage->loadMultiple($order_ids);
-
+    /** @var OrderReportTypeInterface[] $plugin_types */
+    $plugin_types = $this->orderReportTypeManager->getDefinitions();
     /** @var \Drupal\commerce_order\Entity\OrderInterface $order */
     foreach ($orders as $order) {
-      $order_report = $this->orderReportStorage->create([
-        'order_id' => $order->id(),
-        'amount' => $order->getTotalPrice(),
-        'created' => $order->getPlacedTime(),
-      ]);
-      // @todo decide on how to allow others to add additional field data.
-      $order_report->save();
+      foreach ($plugin_types as $plugin_type) {
+        $instance = $this->orderReportTypeManager->createInstance($plugin_type['id'], []);
+        $instance->generateReport($order);
+      }
     }

     $this->state->set('commerce_order_reports', []);
diff --git a/src/Plugin/Commerce/ReportType/OrderReport.php b/src/Plugin/Commerce/ReportType/OrderReport.php
new file mode 100644
index 0000000..e575bc4
--- /dev/null
+++ b/src/Plugin/Commerce/ReportType/OrderReport.php
@@ -0,0 +1,53 @@
+<?php
+
+namespace Drupal\commerce_reports\Plugin\Commerce\ReportType;
+
+use Drupal\commerce\BundleFieldDefinition;
+use Drupal\commerce_order\Entity\OrderInterface;
+use Drupal\commerce_reports\Annotation\CommerceReportType;
+use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Entity\EntityStorageInterface;
+
+/**
+ * Provides the basic Order Report
+ *
+ * @CommerceReportType(
+ *   id = "order_report",
+ *   label = @Translation("Order Report"),
+ *   description = @Translation("Basic order report with order id, total, and created date")
+ * )
+ */
+class OrderReport extends ReportTypeBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildFieldDefinitions() {
+    $fields = [];
+    $fields['amount'] = BundleFieldDefinition::create('commerce_price')
+      ->setLabel(t('Total Amount'))
+      ->setDescription(t('The total amount of the order'))
+      ->setCardinality(1)
+      ->setRequired(TRUE)
+      ->setDisplayConfigurable('view', TRUE);
+
+    return $fields;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function generateReport(OrderInterface $order) {
+    /** @var EntityStorageInterface $orderReportStorage */
+    $orderReportStorage = \Drupal::service('entity_type.manager')
+      ->getStorage('commerce_order_report');
+    $order_report = $orderReportStorage->create([
+      'type' => 'order_report',
+      'order_id' => $order->id(),
+      'amount' => $order->getTotalPrice(),
+      'created' => $order->getPlacedTime(),
+    ]);
+    // @todo decide on how to allow others to add additional field data.
+    $order_report->save();
+  }
+}
diff --git a/src/Plugin/Commerce/ReportType/ReportTypeBase.php b/src/Plugin/Commerce/ReportType/ReportTypeBase.php
new file mode 100644
index 0000000..b986ace
--- /dev/null
+++ b/src/Plugin/Commerce/ReportType/ReportTypeBase.php
@@ -0,0 +1,26 @@
+<?php
+
+namespace Drupal\commerce_reports\Plugin\Commerce\ReportType;
+
+use Drupal\Component\Plugin\PluginBase;
+
+/**
+ * Provides the base order report type class.
+ */
+abstract class ReportTypeBase extends PluginBase implements ReportTypeInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getLabel() {
+    return $this->pluginDefinition['label'];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getDescription() {
+    return $this->pluginDefinition['description'];
+  }
+
+}
diff --git a/src/Plugin/Commerce/ReportType/ReportTypeInterface.php b/src/Plugin/Commerce/ReportType/ReportTypeInterface.php
new file mode 100644
index 0000000..a9af207
--- /dev/null
+++ b/src/Plugin/Commerce/ReportType/ReportTypeInterface.php
@@ -0,0 +1,38 @@
+<?php
+
+namespace Drupal\commerce_reports\Plugin\Commerce\ReportType;
+
+use Drupal\commerce\BundlePluginInterface;
+use Drupal\commerce_order\Entity\OrderInterface;
+
+/**
+ * Defines the interface for order report types.
+ */
+interface ReportTypeInterface extends BundlePluginInterface {
+
+  /**
+   * Gets the order report type label.
+   *
+   * @return string
+   *   The order report type label.
+   */
+  public function getLabel();
+
+  /**
+   * Gets the order report type description
+   *
+   * @return string
+   *   The order report type description.
+   */
+  public function getDescription();
+
+
+  /**
+   * Creates an order report
+   *
+   * @param OrderInterface $order
+   *   The order.
+   */
+  public function generateReport(OrderInterface $order);
+
+}
diff --git a/src/ReportTypeManager.php b/src/ReportTypeManager.php
new file mode 100644
index 0000000..f7b44aa
--- /dev/null
+++ b/src/ReportTypeManager.php
@@ -0,0 +1,49 @@
+<?php
+
+namespace Drupal\commerce_reports;
+
+use Drupal\Component\Plugin\Exception\PluginException;
+use Drupal\Core\Cache\CacheBackendInterface;
+use Drupal\Core\Extension\ModuleHandlerInterface;
+use Drupal\Core\Plugin\DefaultPluginManager;
+
+/**
+ * Manages discovery and instantiation of payment method type plugins.
+ *
+ * @see \Drupal\commerce_reports\Annotation\ReportType
+ * @see plugin_api
+ */
+class ReportTypeManager extends DefaultPluginManager {
+
+  /**
+   * Constructs a new OrderReportTypeManager object.
+   *
+   * @param \Traversable $namespaces
+   *   An object that implements \Traversable which contains the root paths
+   *   keyed by the corresponding namespace to look for plugin implementations.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cache_backend
+   *   The cache backend.
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   */
+  public function __construct(\Traversable $namespaces, CacheBackendInterface $cache_backend, ModuleHandlerInterface $module_handler) {
+    parent::__construct('Plugin/Commerce/ReportType', $namespaces, $module_handler, 'Drupal\commerce_reports\Plugin\Commerce\ReportType\ReportTypeInterface', 'Drupal\commerce_reports\Annotation\CommerceReportType');
+
+    $this->alterInfo('commerce_report_type_info');
+    $this->setCacheBackend($cache_backend, 'commerce_report_type_plugins');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function processDefinition(&$definition, $plugin_id) {
+    parent::processDefinition($definition, $plugin_id);
+
+    foreach (['id', 'label'] as $required_property) {
+      if (empty($definition[$required_property])) {
+        throw new PluginException(sprintf('The report type %s must define the %s property.', $plugin_id, $required_property));
+      }
+    }
+  }
+
+}
diff --git a/src/OrderReportsListBuilder.php b/src/ReportsListBuilder.php
similarity index 96%
rename from src/OrderReportsListBuilder.php
rename to src/ReportsListBuilder.php
index 8829f08..32384b7 100644
--- a/src/OrderReportsListBuilder.php
+++ b/src/ReportsListBuilder.php
@@ -8,7 +8,7 @@
 /**
  * Builds a listing of the order report entities.
  */
-class OrderReportsListBuilder extends EntityListBuilder {
+class ReportsListBuilder extends EntityListBuilder {

   /**
    * {@inheritdoc}
