diff --git a/commerce_sos.module b/commerce_sos.module
index 9281279..d4d6a53 100644
--- a/commerce_sos.module
+++ b/commerce_sos.module
@@ -5,6 +5,9 @@
  * Contains code for commerce_sos.module.
  */
 
+define('COMMERCE_SOS_LINE_ITEM_DISCOUNT_NAME', 'sos_line_item_discount');
+define('COMMERCE_SOS_ORDER_DISCOUNT_NAME', 'sos_order_discount');
+
 /**
  * Implements hook_menu().
  */
@@ -645,3 +648,57 @@ function theme_commerce_sos_products_table(array $variables) {
 
   return $output;
 }
+
+/**
+ * Implements hook_commerce_line_item_rebase_unit_price().
+ */
+function commerce_sos_commerce_line_item_rebase_unit_price(&$price, $old_components, $line_item) {
+  // Check if any discounts have been applied to a line item and recalculate
+  // them as needed.
+  foreach ($old_components as $component) {
+    if (isset($component['price']['data']['sos_discount_type'])) {
+      $discount_type = $component['price']['data']['sos_discount_type'];
+      $line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
+
+      switch ($discount_type) {
+        case 'percent':
+          $discount_amount = $component['price']['data']['sos_discount_rate'];
+          break;
+
+        case 'fixed':
+          $discount_amount = $component['price']['amount'] * -1;
+          break;
+      }
+
+      commerce_sos_apply_discount($line_item_wrapper, $discount_type, $discount_amount);
+
+      if ($component = commerce_sos_get_discount_component($line_item_wrapper->commerce_unit_price, $component['price']['data']['discount_name'])) {
+        $component_name = 'discount|' . COMMERCE_SOS_LINE_ITEM_DISCOUNT_NAME;
+        $price['data'] = commerce_price_component_add($price, $component_name, $component['price'], TRUE);
+        $price['amount'] += $component['price']['amount'];
+      }
+    }
+  }
+}
+
+/**
+ * Implements hook_commerce_price_formatted_components_alter().
+ */
+function commerce_sos_commerce_price_formatted_components_alter(&$components, $price, $entity) {
+  if (isset($price['data']['components'])) {
+    // Loop into price components and alter the component title if the discount
+    // component label is found.
+    foreach ($price['data']['components'] as $component) {
+      if (!isset($component['price']['data']['sos_discount_component_title'])) {
+        continue;
+      }
+
+      $components[$component['name']]['title'] = $component['price']['data']['sos_discount_component_title'];
+
+      if (empty($price['#commerce_sos_print']) && strpos($component['name'], 'sos_order_discount') !== FALSE) {
+        // Add action button for removing order discount.
+        $components[$component['name']]['action'] = '<a href="#" class="commerce-sos-remove-order-discount button-link small">' . t('remove') . '</a>';
+      }
+    }
+  }
+}
diff --git a/includes/commerce_sos.discount.inc b/includes/commerce_sos.discount.inc
index e69de29..89069ae 100644
--- a/includes/commerce_sos.discount.inc
+++ b/includes/commerce_sos.discount.inc
@@ -0,0 +1,556 @@
+<?php
+
+/**
+ * @file
+ * Contains discount related code for the commerce_sos module.
+ */
+
+/**
+ * Retrieves the existing amount for a discount on a line item, if one exists.
+ */
+function commerce_sos_get_existing_line_item_discount_amount($line_item_id, $discount_name = COMMERCE_SOS_LINE_ITEM_DISCOUNT_NAME) {
+  if ($line_item = commerce_line_item_load($line_item_id)) {
+    $line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
+    return commerce_sos_get_line_item_discount_data($line_item_wrapper, $discount_name);
+  }
+
+  return FALSE;
+}
+
+/**
+ * Fetches the existing amount for a discount on a line item.
+ */
+function commerce_sos_get_line_item_discount_data($line_item_wrapper, $discount_name) {
+  $data = [
+    'type' => '',
+    'amount' => 0,
+  ];
+
+  if ($component = commerce_sos_get_discount_component($line_item_wrapper->commerce_unit_price, $discount_name)) {
+    $data['type'] = $component['price']['data']['sos_discount_type'];
+    $data['currency_code'] = $component['price']['currency_code'];
+
+    // Found our discount, return its amount.
+    if ($component['price']['data']['sos_discount_type'] == 'percent') {
+      $data['amount'] = $component['price']['data']['sos_discount_rate'] * 100;
+    }
+    else {
+      $data['amount'] = number_format(abs($component['price']['amount'] / 100), 2);
+    }
+  }
+
+  return $data;
+}
+
+/**
+ * Retrieves the price component relating to SOS discount from a price field.
+ *
+ * @param EntityMetadataWrapper $price_wrapper
+ *   A metadata wrapper around a commerce price field.
+ *
+ * @return array|bool
+ *   The price component, or FALSE if none was found.
+ */
+function commerce_sos_get_discount_component(EntityMetadataWrapper $price_wrapper, $discount_name) {
+  $data = (array) $price_wrapper->data->value() + ['components' => []];
+
+  // Look for our discount in each of the price components.
+  foreach ($data['components'] as $key => $component) {
+    if (!empty($component['price']['data']['discount_name'])) {
+      if ($component['price']['data']['discount_name'] == $discount_name) {
+        return $component;
+      }
+    }
+  }
+
+  return FALSE;
+}
+
+/**
+ * Adds a discount to a specific line item in the order.
+ */
+function commerce_sos_add_line_item_discount($type, $line_item_id, $amount) {
+  if ($line_item = commerce_line_item_load($line_item_id)) {
+    $wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
+
+    // Remove any existing discount components on the line item.
+    commerce_sos_remove_discount_components($wrapper->commerce_unit_price, COMMERCE_SOS_LINE_ITEM_DISCOUNT_NAME);
+    $pre_discount_amount = $wrapper->commerce_unit_price->amount->raw();
+
+    commerce_sos_apply_discount($wrapper, $type, $amount);
+
+    $wrapper->commerce_unit_price->amount->set($pre_discount_amount);
+    $wrapper_value = $wrapper->value();
+    commerce_line_item_rebase_unit_price($wrapper_value);
+
+    $wrapper->save();
+  }
+}
+
+/**
+ * Remove discount components from a given price and recalculate the total.
+ *
+ * @param object $price_wrapper
+ *   Wrapped commerce price.
+ */
+function commerce_sos_remove_discount_components($price_wrapper, $discount_name_to_remove) {
+  $discount_amounts = 0;
+
+  $data = (array) $price_wrapper->data->value() + ['components' => []];
+  $component_removed = FALSE;
+  // Remove price components belonging to order discounts.
+  foreach ($data['components'] as $key => $component) {
+    $remove = FALSE;
+
+    // Remove all discount components.
+    if (!empty($component['price']['data']['discount_name'])) {
+      $discount_name = $component['price']['data']['discount_name'];
+
+      if ($discount_name_to_remove == $discount_name) {
+        $remove = TRUE;
+      }
+    }
+
+    if ($remove) {
+      $discount_amounts += $component['price']['amount'];
+
+      unset($data['components'][$key]);
+      $component_removed = TRUE;
+    }
+  }
+  // Don't alter the price components if no components were removed.
+  if (!$component_removed) {
+    return;
+  }
+
+  // Re-save the price without the discounts (if existed).
+  $price_wrapper->data->set($data);
+
+  // Re-set the total price.
+  $new_total = $price_wrapper->amount->raw() - $discount_amounts;
+  $price_wrapper->amount->set($new_total);
+}
+
+/**
+ * Apply a specific type of discount.
+ *
+ * This simply services as a centralized function to control which discount
+ * method(s) to call, rather than each individual piece of coding having to
+ * determine where to call applyPercentDiscount or applyFixedDiscount.
+ */
+function commerce_sos_apply_discount($wrapper, $type, $rate) {
+  switch ($type) {
+    case 'percent':
+      commerce_sos_apply_percent_discount($wrapper, $rate);
+
+      break;
+
+    case 'fixed':
+      commerce_sos_apply_fixed_discount($wrapper, $rate);
+
+      break;
+  }
+}
+
+/**
+ * A modified version of commerce_discount_percentage().
+ */
+function commerce_sos_apply_percent_discount($wrapper, $rate) {
+  if ($rate > 1) {
+    $rate = $rate / 100;
+  }
+
+  $component_data = [
+    'sos_discount_type' => 'percent',
+    'sos_discount_rate' => $rate,
+  ];
+
+  switch ($wrapper->type()) {
+    case 'commerce_order':
+
+      $discount_name = COMMERCE_SOS_ORDER_DISCOUNT_NAME;
+
+      $calculated_discount = 0;
+      // Loop the line items of the order and calculate the total discount.
+      foreach ($wrapper->commerce_line_items as $line_item_wrapper) {
+        $line_item_total = commerce_price_wrapper_value($line_item_wrapper, 'commerce_total', TRUE);
+        $calculated_discount += $line_item_total['amount'] * $rate;
+      }
+
+      if ($calculated_discount) {
+        $discount_amount = [
+          'amount' => $calculated_discount * -1,
+          'currency_code' => $wrapper->commerce_order_total->currency_code->value(),
+        ];
+
+        // Modify the existing discount line item or add a new line item
+        // if that fails.
+        if (!commerce_sos_set_existing_line_item_price($wrapper, $discount_name, $discount_amount, $component_data)) {
+          commerce_sos_discount_add_line_item($wrapper, $discount_name, $discount_amount, $component_data);
+        }
+      }
+      else {
+        commerce_sos_remove_order_discount_line_items($wrapper);
+      }
+
+      break;
+
+    case 'commerce_line_item':
+
+      $discount_name = COMMERCE_SOS_LINE_ITEM_DISCOUNT_NAME;
+
+      $unit_price = commerce_price_wrapper_value($wrapper, 'commerce_unit_price', TRUE);
+      $calculated_discount = $unit_price['amount'] * $rate * -1;
+
+      if ($calculated_discount) {
+        $discount_amount = [
+          'amount' => $calculated_discount,
+          'currency_code' => $unit_price['currency_code'],
+        ];
+
+        commerce_sos_add_price_component($wrapper, $discount_name, $discount_amount, $component_data);
+      }
+      break;
+  }
+}
+
+/**
+ * A modified version of commerce_discount_fixed_amount().
+ */
+function commerce_sos_apply_fixed_discount(EntityMetadataWrapper $wrapper, $discount_amount) {
+  $discount_price['amount'] = -$discount_amount;
+
+  $component_data = [
+    'sos_discount_type' => 'fixed',
+  ];
+
+  switch ($wrapper->type()) {
+    case 'commerce_order':
+
+      $discount_name = COMMERCE_SOS_ORDER_DISCOUNT_NAME;
+
+      if ($discount_amount) {
+        $discount_price['currency_code'] = $wrapper->commerce_order_total->currency_code->value();
+
+        // If the discount will bring the order to less than zero, set the
+        // discount amount so that it stops at zero.
+        // Loop the line items of the order and calculate the total discount.
+        $order_amount = 0;
+
+        foreach ($wrapper->commerce_line_items as $line_item_wrapper) {
+          $line_item_total = commerce_price_wrapper_value($line_item_wrapper, 'commerce_total', TRUE);
+          $order_amount += $line_item_total['amount'];
+        }
+
+        if (-$discount_price['amount'] > $order_amount) {
+          $discount_price['amount'] = -$order_amount;
+        }
+
+        // Modify the existing discount line item or add a new one if that
+        // fails.
+        if (!commerce_sos_set_existing_line_item_price($wrapper, $discount_name, $discount_price, $component_data)) {
+          commerce_sos_discount_add_line_item($wrapper, $discount_name, $discount_price, $component_data);
+        }
+      }
+      else {
+        commerce_sos_remove_order_discount_line_items($wrapper);
+      }
+
+      break;
+
+    case 'commerce_line_item':
+
+      $discount_name = COMMERCE_SOS_LINE_ITEM_DISCOUNT_NAME;
+
+      if ($discount_amount) {
+
+        // Do not allow negative line item totals.
+        $line_item_amount = $wrapper->commerce_unit_price->amount->value();
+        if (-$discount_price['amount'] > $line_item_amount) {
+          $discount_price['amount'] = -$line_item_amount;
+        }
+
+        $discount_price['currency_code'] = $wrapper->commerce_unit_price->currency_code->value();
+
+        commerce_sos_add_price_component($wrapper, $discount_name, $discount_price, $component_data);
+      }
+      break;
+  }
+}
+
+/**
+ * Updates the unit price of an existing discount line item.
+ *
+ * Non-discount line items are ignored.
+ *
+ * @param EntityDrupalWrapper $order_wrapper
+ *   The wrapped order entity.
+ * @param string $discount_name
+ *   The name of the discount being applied.
+ * @param array $discount_price
+ *   The discount amount price array (amount, currency_code).
+ * @param array $component_data
+ *   Any price data to merge into the component.
+ *
+ * @return bool
+ *   TRUE if an existing line item was successfully modified, FALSE otherwise.
+ */
+function commerce_sos_set_existing_line_item_price(EntityDrupalWrapper $order_wrapper, $discount_name, array $discount_price, array $component_data = []) {
+  $modified_existing = FALSE;
+  foreach ($order_wrapper->commerce_line_items as $line_item_wrapper) {
+    if ($line_item_wrapper->getBundle() == 'commerce_sos_discount') {
+      // Add the discount component price if the line item was originally
+      // added by discount module.
+      $line_item = $line_item_wrapper->value();
+      if (isset($line_item->data['discount_name']) && $line_item->data['discount_name'] == $discount_name) {
+        commerce_sos_set_price_component($line_item_wrapper, $discount_name, $discount_price, $component_data);
+        $modified_existing = TRUE;
+        $line_item_wrapper->save();
+      }
+    }
+  }
+
+  return $modified_existing;
+}
+
+/**
+ * Sets a discount price component to the provided line item.
+ *
+ * @param EntityDrupalWrapper $line_item_wrapper
+ *   The wrapped line item entity.
+ * @param string $discount_name
+ *   The name of the discount being applied.
+ * @param array $discount_amount
+ *   The discount amount price array (amount, currency_code).
+ * @param array $component_data
+ *   Any price data to merge into the component.
+ */
+function commerce_sos_set_price_component(EntityDrupalWrapper $line_item_wrapper, $discount_name, array $discount_amount, array $component_data = []) {
+  $unit_price = commerce_price_wrapper_value($line_item_wrapper, 'commerce_unit_price', TRUE);
+  // Currencies don't match, abort.
+  if ($discount_amount['currency_code'] != $unit_price['currency_code']) {
+    return;
+  }
+
+  $discount_amount['data'] = [
+    'discount_name' => $discount_name,
+    'sos_discount_component_title' => commerce_sos_get_discount_component_title($discount_name),
+  ];
+
+  $discount_amount['data'] += $component_data;
+
+  // Set the new unit price.
+  $line_item_wrapper->commerce_unit_price->amount = $discount_amount['amount'];
+  $line_item_wrapper->commerce_unit_price->data = commerce_price_component_delete($line_item_wrapper->commerce_unit_price->value(), 'discount|sos_order_discount');
+
+  // Add the discount amount as a price component.
+  $price = $line_item_wrapper->commerce_unit_price->value();
+  $type = check_plain('discount|' . $discount_name);
+  $line_item_wrapper->commerce_unit_price->data = commerce_price_component_add($price, $type, $discount_amount, TRUE, TRUE);
+
+  commerce_sos_calculate_taxes($line_item_wrapper);
+
+  // Update the line item total.
+  commerce_sos_update_line_item_total($line_item_wrapper);
+}
+
+/**
+ * Creates a discount line item on the provided order.
+ *
+ * @param EntityDrupalWrapper $order_wrapper
+ *   The wrapped order entity.
+ * @param string $discount_name
+ *   The name of the discount being applied.
+ * @param array $discount_amount
+ *   The discount amount price array (amount, currency_code).
+ * @param array $data
+ *   Any additional data to be added to the price component.
+ */
+function commerce_sos_discount_add_line_item(EntityDrupalWrapper $order_wrapper, $discount_name, array $discount_amount, array $data) {
+  // Create a new line item.
+  $values = [
+    'type' => 'commerce_sos_discount',
+    'order_id' => $order_wrapper->order_id->value(),
+    'quantity' => 1,
+    // Flag the line item.
+    'data' => ['discount_name' => $discount_name],
+  ];
+  $discount_line_item = entity_create('commerce_line_item', $values);
+  $discount_line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $discount_line_item);
+
+  // Initialize the line item unit price.
+  $discount_line_item_wrapper->commerce_unit_price->amount = 0;
+  $discount_line_item_wrapper->commerce_unit_price->currency_code = $discount_amount['currency_code'];
+
+  // Reset the data array of the line item total field to only include a
+  // base price component, set the currency code from the order.
+  $base_price = [
+    'amount' => 0,
+    'currency_code' => $discount_amount['currency_code'],
+    'data' => [],
+  ];
+
+  $discount_line_item_wrapper->commerce_unit_price->data = commerce_price_component_add($base_price, 'base_price', $base_price, TRUE);
+
+  // Add the discount price component.
+  commerce_sos_add_price_component($discount_line_item_wrapper, $discount_name, $discount_amount, $data);
+
+  commerce_sos_calculate_taxes($discount_line_item_wrapper);
+
+  // Save the line item and add it to the order.
+  $discount_line_item_wrapper->save();
+  $order_wrapper->commerce_line_items[] = $discount_line_item_wrapper;
+}
+
+/**
+ * Adds a discount price component to the provided line item.
+ *
+ * @param EntityDrupalWrapper $line_item_wrapper
+ *   The wrapped line item entity.
+ * @param string $discount_name
+ *   The name of the discount being applied.
+ * @param array $discount_amount
+ *   The discount amount price array (amount, currency_code).
+ * @param array $data
+ *   Any additional data to be merged into the new price component's data
+ *   array.
+ */
+function commerce_sos_add_price_component(EntityDrupalWrapper $line_item_wrapper, $discount_name, array $discount_amount, array $data) {
+  $unit_price = commerce_price_wrapper_value($line_item_wrapper, 'commerce_unit_price', TRUE);
+  $current_amount = $unit_price['amount'];
+  // Currencies don't match, abort.
+  if ($discount_amount['currency_code'] != $unit_price['currency_code']) {
+    return;
+  }
+
+  // Calculate the updated amount and create a price array representing the
+  // difference between it and the current amount.
+  $updated_amount = commerce_round(COMMERCE_ROUND_HALF_UP, $current_amount + $discount_amount['amount']);
+
+  $difference = [
+    'amount' => commerce_round(COMMERCE_ROUND_HALF_UP, $discount_amount['amount']),
+    'currency_code' => $discount_amount['currency_code'],
+    'data' => [
+      'discount_name' => $discount_name,
+      'sos_discount_component_title' => commerce_sos_get_discount_component_title($discount_name),
+    ],
+  ];
+
+  $difference['data'] += $data;
+
+  // Set the new unit price.
+  $line_item_wrapper->commerce_unit_price->amount = $updated_amount;
+
+  // Add the discount amount as a price component.
+  $price = $line_item_wrapper->commerce_unit_price->value();
+  $type = check_plain('discount|' . $discount_name);
+  $line_item_wrapper->commerce_unit_price->data = commerce_price_component_add($price, $type, $difference, TRUE, TRUE);
+
+  // Update the line item total.
+  commerce_sos_update_line_item_total($line_item_wrapper);
+}
+
+/**
+ * Retrieves a display name for a specific discount type.
+ */
+function commerce_sos_get_discount_component_title($discount_name) {
+  switch ($discount_name) {
+    case COMMERCE_SOS_LINE_ITEM_DISCOUNT_NAME:
+      return t('Product Discount');
+
+    case COMMERCE_SOS_ORDER_DISCOUNT_NAME:
+      return t('Order Discount');
+
+    default:
+      return FALSE;
+  }
+}
+
+/**
+ * Update commerce_total without saving line item.
+ *
+ * To have the order total refreshed without saving the line item.
+ * Taken from CommerceLineItemEntityController::save().
+ */
+function commerce_sos_update_line_item_total($line_item_wrapper) {
+  $quantity = $line_item_wrapper->quantity->value();
+
+  // Update the total of the line item based on the quantity and unit price.
+  $unit_price = commerce_price_wrapper_value($line_item_wrapper, 'commerce_unit_price', TRUE);
+
+  $line_item_wrapper->commerce_total->amount = $quantity * $unit_price['amount'];
+  $line_item_wrapper->commerce_total->currency_code = $unit_price['currency_code'];
+
+  // Add the components multiplied by the quantity to the data array.
+  if (empty($unit_price['data']['components'])) {
+    $unit_price['data']['components'] = [];
+  }
+  else {
+    foreach ($unit_price['data']['components'] as $key => &$component) {
+      $component['price']['amount'] *= $quantity;
+    }
+  }
+
+  // Set the updated data array to the total price.
+  $line_item_wrapper->commerce_total->data = $unit_price['data'];
+  // Reset the cache because we aren't saving it.
+  entity_get_controller('commerce_line_item')->resetCache([$line_item_wrapper->getIdentifier()]);
+}
+
+/**
+ * Calculate the taxes on a given line item.
+ *
+ * @param EntityMetadataWrapper $line_item_wrapper
+ *   A metadata wrapper representing the line item.
+ */
+function commerce_sos_calculate_taxes(EntityMetadataWrapper $line_item_wrapper) {
+  if (module_exists('commerce_tax')) {
+    module_load_include('inc', 'commerce_tax', 'commerce_tax.rules');
+
+    // First remove all existing tax components from the line item if any
+    // exist.
+    commerce_tax_remove_taxes($line_item_wrapper, FALSE, array_keys(commerce_tax_rates()));
+
+    foreach (commerce_tax_types() as $name => $type) {
+      commerce_tax_calculate_by_type($line_item_wrapper->value(), $name);
+    }
+  }
+}
+
+/**
+ * Removes all SOS discount line items from an order.
+ *
+ * @param EntityMetadataWrapper $order_wrapper
+ *   The order entity.
+ */
+function commerce_sos_remove_order_discount_line_items(EntityMetadataWrapper $order_wrapper) {
+  $line_items_to_delete = [];
+
+  foreach ($order_wrapper->commerce_line_items as $delta => $line_item_wrapper) {
+    if ($line_item_wrapper->type->value() == 'commerce_sos_discount') {
+      $order_wrapper->commerce_line_items->offsetUnset($delta);
+      $line_items_to_delete[] = $line_item_wrapper->line_item_id;
+    }
+  }
+
+  if ($line_items_to_delete) {
+    commerce_line_item_delete_multiple($line_items_to_delete);
+  }
+}
+
+/**
+ * Adds a discount to the order.
+ *
+ * @param object $order
+ *   The order entity.
+ * @param string $type
+ *   The discount type.
+ * @param int $amount
+ *   The discount amount.
+ */
+function commerce_sos_add_order_discount($order, $type, $amount) {
+  if ($wrapper = entity_metadata_wrapper('commerce_order', $order->id)) {
+    commerce_sos_apply_discount($wrapper, $type, $amount);
+    $wrapper->save();
+  }
+}
diff --git a/includes/commerce_sos.form.inc b/includes/commerce_sos.form.inc
index 3a7a60f..48bb3fd 100644
--- a/includes/commerce_sos.form.inc
+++ b/includes/commerce_sos.form.inc
@@ -778,6 +778,54 @@ function _commerce_sos_ajax_check(&$form, &$form_state) {
           _commerce_sos_update_line_item_product_options($order, $form, $form_state);
 
           break;
+
+        case 'add-percent-discount':
+        case 'add-fixed-discount':
+          $discount_amount = $form_state['values']['products'][$form_state['triggering_element']['#line_item_id']]['discounts']['add_discount']['amount'];
+
+          if ($form_state['triggering_element']['#element_key'] == 'add-percent-discount') {
+            $discount_type = 'percent';
+            // Convert percent 100% style to 1.0 style.
+            $discount_amount /= 100;
+          }
+          else {
+            $discount_type = 'fixed';
+            // Convert the amount into cents, as we expected it to be provided
+            // in dollars.
+            $discount_amount *= 100;
+          }
+
+          commerce_sos_add_line_item_discount($discount_type, $form_state['triggering_element']['#line_item_id'], $discount_amount);
+
+          break;
+
+        case 'remove-discount':
+          $discount_amount = 0;
+          $discount_type = 'fixed';
+
+          commerce_sos_add_line_item_discount($discount_type, $form_state['triggering_element']['#line_item_id'], $discount_amount);
+
+          break;
+
+        case 'add-order-percent-discount':
+        case 'add-order-fixed-discount':
+          $discount_amount = $form_state['values']['transaction_options']['actions']['add_order_discount']['amount'];
+
+          if ($form_state['triggering_element']['#element_key'] == 'add-order-percent-discount') {
+            $discount_type = 'percent';
+            // Convert percent 100% style to 1.0 style.
+            $discount_amount /= 100;
+          }
+          else {
+            $discount_type = 'fixed';
+            // Convert the amount into cents, as we expected it to be provided
+            // in dollars.
+            $discount_amount *= 100;
+          }
+
+          commerce_sos_add_order_discount($form_state['commerce_order'], $discount_type, $discount_amount);
+
+          break;
       }
     }
     else {
@@ -891,6 +939,9 @@ function _commerce_sos_add_products_table_fields(array $form, array &$form_state
         '#ajax' => $wrapper_ajax,
       ];
 
+      // Add our discount fields here.
+      commerce_sos_add_discount_fields($form, $form_state, $product_info, $line_item);
+
       $form['products'][$line_item_id]['total'] = [
         '#markup' => '<strong>' . commerce_currency_format($line_item_total['amount'], $line_item_total['currency_code']) . '</strong>',
       ];
@@ -927,7 +978,8 @@ function _commerce_sos_add_products_table_fields(array $form, array &$form_state
       if (isset($form_state['triggering_element']) && isset($form_state['triggering_element']['#element_key'])
         && $form_state['triggering_element']['#line_item_id'] == $line_item_id
         && ($form_state['triggering_element']['#element_key'] == 'line-item-change-product-attribute'
-        || $form_state['triggering_element']['#element_key'] == 'line-item-change-product-option')) {
+          || $form_state['triggering_element']['#element_key'] == 'line-item-change-product-option')
+      ) {
         $form['products'][$line_item_id]['edit']['#options']['attributes']['class'][] = 'edit-clicked';
       }
 
@@ -1475,7 +1527,6 @@ function commerce_sos_add_product_options(&$form, &$form_state, $product_info, $
                 }
               }
 
-
               // Set the default value.
               if (!empty($options) && isset($options['product_options'][$default_product->product_id][$field_name][$delta]->{$key}[$lang_code][0]['value'])) {
                 $form['products'][$line_item_id]['options'][$field_name][$delta][$key]['#default_value'] = $options['product_options'][$default_product->product_id][$field_name][$delta]->{$key}[$lang_code][0]['value'];
@@ -1542,8 +1593,8 @@ function _commerce_sos_fetch_default_product(&$form, &$form_state, $line_item) {
     $products = commerce_product_load_multiple($product_ids, ['status' => 1]);
     $form_state['added_products'][$line_item_id]['products_in_referenced_node'] = $products;
 
-    // If the products are all of the same type and there are qualifying fields on
-    // that product type, display their options for customer selection.
+    // If the products are all of the same type and there are qualifying fields
+    // on that product type, display their options for customer selection.
     $form['added_products'][$line_item_id]['type'] = '';
 
     // Find the default product so we know how to set default options on the
@@ -1677,7 +1728,8 @@ function _commerce_sos_update_line_item_product($order, &$form, &$form_state) {
   // Update the line item with the new matching default product.
   $product_info = commerce_sos_get_product_details($default_product->sku);
 
-  // Now update the line item and order, reset the pricing attribute data as well.
+  // Now update the line item and order, reset the pricing attribute data as
+  // well.
   $line_item = commerce_sos_remove_commerce_option_attributes($line_item);
   commerce_product_line_item_populate($line_item, $default_product);
   commerce_line_item_save($line_item);
@@ -1757,3 +1809,149 @@ function _commerce_sos_update_line_item_product_options($order, &$form, &$form_s
 
   $form_state['added_products'][$line_item_id]['line_item'] = $line_item;
 }
+
+/**
+ * Add the discount fields to each line item.
+ */
+function commerce_sos_add_discount_fields(&$form, &$form_state, $product_info, $line_item) {
+  $line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
+  $line_item_id = $line_item_wrapper->line_item_id->value();
+  $current_product = $product_info['product'];
+  $wrapper_ajax = [
+    'callback' => 'commerce_sos_add_products_ajax_callback',
+    'wrapper' => 'sos-products-table',
+  ];
+
+  $form['products'][$line_item_id]['discounts'] = [
+    '#type' => 'container',
+    '#id' => 'commerce-sos-discount-wrapper-' . $line_item_id,
+    '#attributes' => [
+      'class' => [
+        'commerce-sos-discount-wrapper',
+      ],
+    ],
+  ];
+
+  $form['products'][$line_item_id]['discounts']['toggle_discount'] = [
+    '#type' => 'button',
+    '#value' => t('Discount'),
+    '#line_item_id' => $line_item_id,
+    '#element_key' => 'toggle-discount',
+    '#name' => 'commerce-sos-discount-toggle-discount-' . $line_item_id,
+    '#ajax' => [
+      'wrapper' => 'commerce-sos-discount-wrapper-' . $line_item_id,
+      'callback' => 'commerce_sos_discount_add_discount_ajax_callback',
+    ],
+  ];
+
+  $discount_data = commerce_sos_get_existing_line_item_discount_amount($line_item_id);
+  if (!empty($form_state['triggering_element']['#element_key']) && $form_state['triggering_element']['#element_key'] == 'toggle-discount' &&
+    $form_state['triggering_element']['#line_item_id'] == $line_item_id) {
+    $form['products'][$line_item_id]['discounts']['toggle_discount']['#element_key'] = 'toggle-discount-hide';
+
+    $form['products'][$line_item_id]['discounts']['add_discount'] = [
+      '#type' => 'container',
+      '#size' => 2,
+    ];
+
+    $form['products'][$line_item_id]['discounts']['add_discount']['#attached']['js'][] = [
+      'type' => 'setting',
+      'data' => [
+        'commerceSOSDiscount' => [
+          'focusInput' => TRUE,
+          'lineItemId' => $line_item_id,
+        ],
+      ],
+    ];
+
+    $discount_default_value = NULL;
+    if ($discount_data && !empty($discount_data['amount'])) {
+      $discount_default_value = $discount_data['amount'];
+    }
+
+    $form['products'][$line_item_id]['discounts']['add_discount']['amount'] = [
+      '#type' => 'textfield',
+      '#title' => NULL,
+      '#size' => 2,
+      '#default_value' => $discount_default_value,
+    ];
+
+    $form['products'][$line_item_id]['discounts']['add_discount']['percent'] = [
+      '#type' => 'button',
+      '#value' => '%',
+      '#element_key' => 'add-percent-discount',
+      '#line_item_id' => $line_item_id,
+      '#name' => 'commerce-sos-discount-percent-discount-' . $line_item_id,
+      '#ajax' => $wrapper_ajax,
+      '#attributes' => [
+        'class' => ['sos-blue'],
+      ],
+    ];
+
+    $form['products'][$line_item_id]['discounts']['add_discount']['fixed'] = [
+      '#type' => 'button',
+      '#value' => '$',
+      '#element_key' => 'add-fixed-discount',
+      '#line_item_id' => $line_item_id,
+      '#name' => 'commerce-sos-discount-fixed-discount-' . $line_item_id,
+      '#ajax' => $wrapper_ajax,
+      '#attributes' => [
+        'class' => ['sos-blue'],
+      ],
+    ];
+
+    if ($discount_data) {
+      $form['products'][$line_item_id]['discounts']['add_discount'][$discount_data['type']]['#attributes']['class'][] = 'sos-active';
+    }
+  }
+  else {
+    if (!empty($discount_data) && isset($discount_data['amount']) & !empty($discount_data['amount'])) {
+      $discount_price = '';
+      if (isset($discount_data['type']) && $discount_data['type'] == 'percent') {
+        $discount_price = $discount_data['amount'] . '%';
+      }
+      else {
+        $discount_price = commerce_currency_format(($discount_data['amount'] * 100), $discount_data['currency_code']);
+      }
+
+      $form['products'][$line_item_id]['discounts']['discount_description'] = [
+        '#markup' => $discount_price,
+        '#prefix' => '<span class="discount-description">',
+        '#suffix' => '</span>',
+        '#line_item_id' => $line_item_id,
+        '#element_key' => 'discount-description',
+      ];
+
+      $form['products'][$line_item_id]['discounts']['remove_discount'] = [
+        '#type' => 'button',
+        '#value' => 'remove',
+        '#prefix' => ' - ',
+        '#element_key' => 'remove-discount',
+        '#line_item_id' => $line_item_id,
+        '#name' => 'commerce-sos-discount-remove-discount-' . $line_item_id,
+        '#ajax' => $wrapper_ajax,
+        '#attributes' => [
+          'class' => ['sos-remove-discount-link', 'sos-small'],
+        ],
+      ];
+    }
+    else {
+      $form['products'][$line_item_id]['discounts']['#attributes']['class'][] = 'sos-no-background';
+    }
+  }
+}
+
+/**
+ * AJAX callback for the "Add Discount" buttons.
+ */
+function commerce_sos_discount_add_discount_ajax_callback($form, &$form_state) {
+  $commands = array();
+
+  // Replace all the discount elements attached to all line items so we have
+  // only the clicked discount element showing.
+  foreach (element_children($form['products']) as $line_item_id) {
+    $commands[] = ajax_command_replace('#commerce-sos-discount-wrapper-' . $line_item_id, drupal_render($form['products'][$line_item_id]['discounts']));
+  }
+
+  return ['#type' => 'ajax', '#commands' => $commands];
+}
