diff --git a/modules/payment/src/Plugin/Commerce/CheckoutPane/PaymentInformation.php b/modules/payment/src/Plugin/Commerce/CheckoutPane/PaymentInformation.php
index 2b2e1b0..2624383 100644
--- a/modules/payment/src/Plugin/Commerce/CheckoutPane/PaymentInformation.php
+++ b/modules/payment/src/Plugin/Commerce/CheckoutPane/PaymentInformation.php
@@ -23,6 +23,68 @@ class PaymentInformation extends CheckoutPaneBase {
   /**
    * {@inheritdoc}
    */
+  public function defaultConfiguration() {
+    return [
+      'free_orders' => []
+    ] + parent::defaultConfiguration(); // TODO: Change the autogenerated stub
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationSummary() {
+    switch ($this->configuration['free_orders']) {
+      case 'collect_billing':
+        $summary = $this->t('Billing information required for free orders: Billing Only');
+        break;
+
+      case 'collect_all':
+        $summary = $this->t('Billing information required for free orders: Billing and Payment');
+        break;
+
+      case 'collect_none':
+      default:
+        $summary = $this->t('Billing information required for free orders: None');
+    }
+
+    return $summary;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
+    $form = parent::buildConfigurationForm($form, $form_state);
+    $form['free_orders'] = [
+      '#type' => 'select',
+      '#title' => $this->t('Billing information required for free orders'),
+      '#description' => $this->t('Determines what information will be collected for free orders.'),
+      '#default_value' => $this->configuration['free_orders'],
+      '#options' => [
+        'collect_none' => $this->t('None'),
+        'collect_all' => $this->t('Payment and Billing'),
+        'collect_billing' => $this->t('Billing Only')
+      ]
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
+    parent::submitConfigurationForm($form, $form_state);
+
+    if (!$form_state->getErrors()) {
+      $values = $form_state->getValue($form['#parents']);
+      $this->configuration['free_orders'] = $values['free_orders'];
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
   public function buildPaneSummary() {
     $summary = [];
     /** @var \Drupal\commerce_payment\Entity\PaymentGatewayInterface $payment_gateway */
@@ -56,6 +118,20 @@ public function buildPaneSummary() {
   }

   /**
+   * @return bool
+   */
+  public function isVisible() {
+    $order = $this->order;
+    /** @var \Drupal\commerce_price\Price $total */
+    $total = $order->getTotalPrice();
+    if (!$total->isZero()) {
+      return TRUE;
+    }
+    $free_order_config = $this->configuration['free_orders'];
+    return $free_order_config != 'collect_none';
+  }
+
+  /**
    * {@inheritdoc}
    */
   public function buildPaneForm(array $pane_form, FormStateInterface $form_state, array &$complete_form) {
diff --git a/modules/payment/src/Plugin/Commerce/CheckoutPane/PaymentProcess.php b/modules/payment/src/Plugin/Commerce/CheckoutPane/PaymentProcess.php
index 5784b57..87df728 100644
--- a/modules/payment/src/Plugin/Commerce/CheckoutPane/PaymentProcess.php
+++ b/modules/payment/src/Plugin/Commerce/CheckoutPane/PaymentProcess.php
@@ -85,7 +85,9 @@ public function submitConfigurationForm(array &$form, FormStateInterface $form_s
   public function isVisible() {
     // This pane can't be used without the PaymentInformation pane.
     $payment_info_pane = $this->checkoutFlow->getPane('payment_information');
-    return $payment_info_pane->isVisible() && $payment_info_pane->getStepId() != '_disabled';
+    // Disable if order total is 0
+    $order_total = $this->order->getTotalPrice();
+    return $payment_info_pane->isVisible() && $payment_info_pane->getStepId() != '_disabled' && !$order_total->isZero();
   }

   /**
