When users use a coupon with a value higher than the order total (are value of eligible products), a part of the coupon's value stay unused and is lost for the user.
I've juste wrote a small module that convert the unused part of the coupon into userpoints, so that the user can spend it later (with ubercart_userpoints)

for the moment there's just the order hook, but some features could be added (to inform the user on the checkout page for exemple)

/**
 * Implementation of hook_order().
 */
function uc_coupon_surplus_to_userpoints_order($op, &$arg1, $arg2) {
  if ($op == 'update') {
    $coupon_used = 0;
    // find the item line where the discount coupon used is stored
    if (count($arg1->line_items)>0) {
      foreach ($arg1->line_items as $line_item) {
        if ($line_item["type"] == "coupon") {
          $coupon_used = $line_item["amount"];
          break;
        }
      }
    }
    //if a discount coupon has been used
    if ($coupon_used < 0) {
      //look if we are validating the order
      $old_status_weight = db_result(db_query("SELECT weight FROM {uc_order_statuses} WHERE order_status_id LIKE '%s'", $arg1->order_status));
      $new_status_weight = db_result(db_query("SELECT weight FROM {uc_order_statuses} WHERE order_status_id LIKE '%s'", $arg2));
      if ($old_status_weight < 10 && $new_status_weight >= 10) {
        //find the origin value of the coupon
        if (isset($arg1->data["coupon"]) && $coupon = uc_coupon_find($arg1->data["coupon"])) {
          //calculate the difference between the origin value and the used value to know if there's a surplus
          $surplus = $coupon->value + $coupon_used;
          if ($surplus > 0) {
            //Add points to the user
            $params = array (
              'uid' => $arg1->uid,
              'points' => $surplus * intval(variable_get(USERPOINTS_UC_DISC, 1)),
            );
            userpoints_userpointsapi($params); 
          }
        }
      }
    }
  }
}
Support from Acquia helps fund testing for Drupal Acquia logo