diff --git payment/uc_credit/test_gateway.module payment/uc_credit/test_gateway.module
index 7854691..934148c 100644
--- payment/uc_credit/test_gateway.module
+++ payment/uc_credit/test_gateway.module
@@ -18,6 +18,7 @@ function test_gateway_payment_gateway() {
     'title' => t('Test Gateway'),
     'description' => t('Process credit card payments through the Test Gateway.'),
     'credit' => 'test_gateway_charge',
+    'recurring_fee' => 'test_gateway_recurring_fee',
   );
 
   return $gateways;
@@ -63,3 +64,141 @@ function test_gateway_charge($order_id, $amount, $data) {
 
   return $result;
 }
+
+/**
+ * Implements hook_recurring_renew()
+ * 
+ * 
+ */
+function test_gateway_recurring_renew($order, $fee) {
+  if ($key = uc_credit_encryption_key()) {
+    $crypt = new uc_encryption_class;
+    $fee['data']['payment_details']['cc_number'] = $crypt->decrypt($key, $fee['data']['payment_details']['cc_number']);
+    if (variable_get('uc_credit_debug', FALSE)) {
+      $fee['data']['payment_details']['cc_cvv'] = $crypt->decrypt($key, $fee['data']['payment_details']['cc_cvv']);
+    }
+    $fee['data']['payment_details']['cc_exp_month'] = $crypt->decrypt($key, $fee['data']['payment_details']['cc_exp_month']);
+    $fee['data']['payment_details']['cc_exp_year'] = $crypt->decrypt($key, $fee['data']['payment_details']['cc_exp_year']);
+    uc_store_encryption_errors($crypt, 'uc_recurring');
+  }
+  if (test_gateway_charge_renewal($fee)) {
+    return TRUE;
+  }
+  return FALSE;
+}
+
+// Processes credit cards for the default handler.
+function test_gateway_charge_renewal($fee) {
+  static $show = TRUE;
+
+  // Get the charge function for the default credit card gateway.
+  $gateways = _payment_gateway_list('credit', TRUE);
+  if (count($gateways) == 1) {
+    $keys = array_keys($gateways);
+    $func = $gateways[$keys[0]]['credit'];
+  }
+  elseif (count($gateways) > 1) {
+    foreach ($gateways as $gateway) {
+      if ($gateway['id'] == variable_get('uc_payment_credit_gateway', '')) {
+        $func = $gateway['credit'];
+      }
+    }
+  }
+
+  // Whoa... bad function? ABORT! ABORT!
+  if (!function_exists($func)) {
+    if ($show) {
+      watchdog('uc_recurring', 'Recurring payments failed to process due to invalid credit card gateway.', array(), WATCHDOG_ERROR);
+      $show = FALSE;
+    }
+    return FALSE;
+  }
+
+  // Cache the CC details stored by the handler.
+  uc_credit_cache('save', $fee['data']['payment_details'], FALSE);
+
+  // Run the charge.
+  $result = $func($fee['order_id'], $fee['fee_amount'], NULL);
+
+  // Handle the result.
+  if ($result['success'] === TRUE) {
+    uc_payment_enter($fee['order_id'], 'credit', $fee['fee_amount'], 0, $result['data'], t('Recurring fee payment.') .'<br />'. $result['comment']);
+    uc_order_comment_save($fee['order_id'], 0, t('!amount recurring fee collected for @model. (ID: <a href="!url">!fee</a>)', array('!url' => url('admin/store/orders/recurring/view/fee/'. $fee['rfid']), '!fee' => $fee['rfid'], '!amount' => uc_currency_format($fee['fee_amount']), '@model' => $fee['data']['model'])));
+
+    // Modules can hook into the charge process using hook_recurring_api().
+    module_invoke_all('recurring_api', 'charge', $fee);
+
+    // Needs to be updated for Conditional Actions. -RS
+    // workflow_ng_invoke_event('fee_charge_successful', uc_order_load($fee['order_id']));
+    // if ($fee['remaining_intervals'] == 1) {
+    //   workflow_ng_invoke_event('fee_expires', uc_order_load($fee['order_id']));
+    // }
+  }
+  else {
+    uc_order_comment_save($fee['order_id'], 0, t('Error: Recurring fee <a href="!url">!fee</a> for product @model failed.', array('!url' => url('admin/store/orders/recurring/view/fee/'. $fee['rfid']), '!fee' => $fee['rfid'], '@model' => $fee['data']['model'])));
+    watchdog('uc_recurring', 'Failed to capture recurring fee of !amount for product @model on order !order_id.', array('!amount' => $fee['fee_amount'], '@model' => $fee['data']['model'], '!order_id' => $fee['order_id']), WATCHDOG_ERROR, l(t('order !order_id', array('!order_id' => $fee['order_id'])), 'admin/store/orders/'. $fee['order_id']));
+
+    // Modules can hook into the charge process using hook_recurring_api().
+    module_invoke_all('recurring_api', 'fail', $fee);
+
+    // Provide a Workflow event for folks to hook into.
+    // workflow_ng_invoke_event('fee_charge_fails', uc_order_load($fee['order_id']));
+  }
+
+  return $result['success'];
+}
+
+/**
+ * Implementation of hook_recurring_fee()
+ */
+function test_gateway_recurring_fee($order, $fee) {
+  if ($order->payment_method !== 'credit') {
+    watchdog('uc_recurring', 'You can only use the credit card payment method with the uc_recurring handler.', array(), WATCHDOG_ERROR);
+    return FALSE;
+  }
+
+  $data = array(
+    'billing_first_name' => $order->billing_first_name,
+    'billing_last_name' => $order->billing_last_name,
+    'billing_phone' => $order->billing_phone,
+    'billing_company' => $order->billing_company,
+    'billing_street1' => $order->billing_street1,
+    'billing_street2' => $order->billing_street2,
+    'billing_city' => $order->billing_city,
+    'billing_zone' => $order->billing_zone,
+    'billing_postal_code' => $order->billing_postal_code,
+    'billing_country' => $order->billing_country,
+    'payment_details' => $order->payment_details,
+    'model' => $fee->model,
+  );
+
+  if ($key = uc_credit_encryption_key()) {
+    $crypt = new uc_encryption_class;
+    $data['payment_details']['cc_number'] = $crypt->encrypt($key, $data['payment_details']['cc_number'], 32);
+    if (variable_get('uc_credit_debug', FALSE)) {
+      $data['payment_details']['cc_cvv'] = $crypt->encrypt($key, $data['payment_details']['cc_cvv'], 32);
+    }
+    $data['payment_details']['cc_exp_month'] = $crypt->encrypt($key, $data['payment_details']['cc_exp_month'], 32);
+    $data['payment_details']['cc_exp_year'] = $crypt->encrypt($key, $data['payment_details']['cc_exp_year'], 32);
+    uc_store_encryption_errors($crypt, 'uc_recurring');
+  }
+
+  $fee = array(
+    'rfid' => 0,
+    'uid' => $order->uid,
+    'fee_handler' => 'test_gateway',
+    'next_charge' => strtotime('+'. $fee->initial_charge),
+    'fee_amount' => $fee->fee_amount,
+    'regular_interval' => $fee->regular_interval,
+    'remaining_intervals' => $fee->number_intervals,
+    'charged_intervals' => 0,
+    'order_id' => $order->order_id,
+    'data' => serialize($data),
+  );
+
+  $fee['rfid'] = uc_recurring_fee_save('user', $fee);
+
+  uc_order_comment_save($order->order_id, 0, t('Recurring fee <a href="!url">!fee</a> added to order.', array('!url' => url('admin/store/orders/recurring/view/fee/'. $fee['rfid']), '!fee' => $fee['rfid'])));
+
+  return TRUE;
+}
diff --git payment/uc_recurring/uc_recurring.module payment/uc_recurring/uc_recurring.module
index 48aee29..f3b0055 100644
--- payment/uc_recurring/uc_recurring.module
+++ payment/uc_recurring/uc_recurring.module
@@ -250,45 +250,75 @@ function uc_recurring_order_view_update_form_submit($form, &$form_state) {
  * Implementation of hook_cron().
  */
 function uc_recurring_cron() {
-  if (variable_get('uc_recurring_handler', 'uc_recurring') == 'uc_recurring') {
-    $successes = 0;
-    $fails = 0;
-
-    $result = db_query("SELECT * FROM {uc_recurring_users} WHERE fee_handler = 'uc_recurring' AND remaining_intervals > 0 AND next_charge <= %d", time());
-    while ($fee = db_fetch_array($result)) {
-      $fee['data'] = unserialize($fee['data']);
-
-      if ($key = uc_credit_encryption_key()) {
-        $crypt = new uc_encryption_class;
-        $fee['data']['payment_details']['cc_number'] = $crypt->decrypt($key, $fee['data']['payment_details']['cc_number']);
-        if (variable_get('uc_credit_debug', FALSE)) {
-          $fee['data']['payment_details']['cc_cvv'] = $crypt->decrypt($key, $fee['data']['payment_details']['cc_cvv']);
-        }
-        $fee['data']['payment_details']['cc_exp_month'] = $crypt->decrypt($key, $fee['data']['payment_details']['cc_exp_month']);
-        $fee['data']['payment_details']['cc_exp_year'] = $crypt->decrypt($key, $fee['data']['payment_details']['cc_exp_year']);
-        uc_store_encryption_errors($crypt, 'uc_recurring');
+  $successes = 0;
+  $fails = 0;
+
+  $result = db_query("SELECT * FROM {uc_recurring_users} WHERE remaining_intervals > 0 AND next_charge <= %d", time());
+  while ($fee = db_fetch_array($result)) {
+    $fee['data'] = unserialize($fee['data']);
+
+    // attempt to a call <payment_gateway>_recurring_renew() function if it exits
+    $renew_func = $fee['fee_handler'] .'_recurring_renew'; 
+    if (function_exists($renew_func)) {
+      // Load the order.
+      $order = uc_order_load($fee['order_id']);
+
+      // create a new order by cloning the curring order and replacing order id's
+      $new_order = uc_order_new($order->uid, $state = 'in_checkout');
+      $new_id = $new_order->order_id;
+      $new_order = $order;
+      $new_order->order_id = $new_id;
+      $new_order->order_status = 'pending';
+      // needs a new set of product id's
+      foreach ($new_order->products as $index => $product) {
+        $new_order->products[$index]->order_id = $new_id;
+        unset($new_order->products[$index]->order_product_id);
       }
+      $fee['order_id'] = $new_id;
 
-      // Attempt to process the charge.
-      if (uc_recurring_charge($fee)) {
+      if ($renew_func($order, $fee)) {
+        // payment was successful save the new order
+        uc_order_save($new_order);
         // Update the fee in the database.
         if ($fee['remaining_intervals'] == 1) {
           $next_charge = time();
         }
         else {
           $next_charge = strtotime('+'. $fee['regular_interval']);
+          $user_fee = array(
+            'rfid' => 0,
+            'uid' => $order->uid,
+            'fee_handler' => $fee['fee_handler'],
+            'next_charge' => $next_charge,
+            'fee_amount' => $fee['fee_amount'],
+            'regular_interval' => $fee['regular_interval'],
+            'remaining_intervals' => $fee['remaining_intervals']-1,
+            'charged_intervals' => $fee['charged_intervals']+1,
+            'order_id' => $new_id,
+            'data' => serialize($fee['data']),
+          );
+          uc_recurring_fee_save('user', $user_fee);
         }
-        db_query("UPDATE {uc_recurring_users} SET next_charge = %d, remaining_intervals = remaining_intervals - 1, charged_intervals = charged_intervals + 1 WHERE rfid = %d", $next_charge, $fee['rfid']);
+
+        // stop the old recurring payment
+        db_query("UPDATE {uc_recurring_users} SET next_charge = %d, remaining_intervals = 0, charged_intervals = charged_intervals + 1 WHERE rfid = %d", time(), $fee['rfid']);
+        // update the status which will invoke any hooks that respond to completed status
+        uc_order_update_status($new_id, 'completed');
         $successes++;
       }
       else {
+        // payment attempted but failed
         $fails++;
+        // TODO: add code to handle failures
+        // ie: 
+        //    notify user/admin
+        //    extend current order for set time to give user a chance to fix problem
       }
     }
+  }
 
-    if ($successes > 0 || $fails > 0) {
-      watchdog('uc_recurring', '!successes recurring fees processed successfully; !fails failed.', array('!successes' => $successes, '!fails' => $fails));
-    }
+  if ($successes > 0 || $fails > 0) {
+    watchdog('uc_recurring', '!successes recurring fees processed successfully; !fails failed.', array('!successes' => $successes, '!fails' => $fails));
   }
 }
 
@@ -384,61 +414,6 @@ function uc_recurring_product_feature() {
 }
 
 /**
- * Implementation of hook_recurring_fee(); default recurring fee handler.
- */
-function uc_recurring_recurring_fee($order, $fee) {
-  if ($order->payment_method !== 'credit') {
-    watchdog('uc_recurring', 'You can only use the credit card payment method with the uc_recurring handler.', array(), WATCHDOG_ERROR);
-    return FALSE;
-  }
-
-  $data = array(
-    'billing_first_name' => $order->billing_first_name,
-    'billing_last_name' => $order->billing_last_name,
-    'billing_phone' => $order->billing_phone,
-    'billing_company' => $order->billing_company,
-    'billing_street1' => $order->billing_street1,
-    'billing_street2' => $order->billing_street2,
-    'billing_city' => $order->billing_city,
-    'billing_zone' => $order->billing_zone,
-    'billing_postal_code' => $order->billing_postal_code,
-    'billing_country' => $order->billing_country,
-    'payment_details' => $order->payment_details,
-    'model' => $fee->model,
-  );
-
-  if ($key = uc_credit_encryption_key()) {
-    $crypt = new uc_encryption_class;
-    $data['payment_details']['cc_number'] = $crypt->encrypt($key, $data['payment_details']['cc_number'], 32);
-    if (variable_get('uc_credit_debug', FALSE)) {
-      $data['payment_details']['cc_cvv'] = $crypt->encrypt($key, $data['payment_details']['cc_cvv'], 32);
-    }
-    $data['payment_details']['cc_exp_month'] = $crypt->encrypt($key, $data['payment_details']['cc_exp_month'], 32);
-    $data['payment_details']['cc_exp_year'] = $crypt->encrypt($key, $data['payment_details']['cc_exp_year'], 32);
-    uc_store_encryption_errors($crypt, 'uc_recurring');
-  }
-
-  $fee = array(
-    'rfid' => 0,
-    'uid' => $order->uid,
-    'fee_handler' => 'uc_recurring',
-    'next_charge' => strtotime('+'. $fee->initial_charge),
-    'fee_amount' => $fee->fee_amount,
-    'regular_interval' => $fee->regular_interval,
-    'remaining_intervals' => $fee->number_intervals,
-    'charged_intervals' => 0,
-    'order_id' => $order->order_id,
-    'data' => serialize($data),
-  );
-
-  $fee['rfid'] = uc_recurring_fee_save('user', $fee);
-
-  uc_order_comment_save($order->order_id, 0, t('Recurring fee <a href="!url">!fee</a> added to order.', array('!url' => url('admin/store/orders/recurring/view/fee/'. $fee['rfid']), '!fee' => $fee['rfid'])));
-
-  return TRUE;
-}
-
-/**
  * Implementation of hook_recurring_fee_ops().
  */
 function uc_recurring_recurring_fee_ops($context, $fee) {
@@ -633,13 +608,6 @@ function uc_recurring_feature_form_submit($form, &$form_state) {
 
 // Adds the settings for the recurring module on the feature settings form.
 function uc_recurring_settings_form() {
-  $form['uc_recurring_handler'] = array(
-    '#type' => 'select',
-    '#title' => t('Recurring fee handler'),
-    '#description' => t('Select a module to process recurring fees on your site.'),
-    '#options' => drupal_map_assoc(module_implements('recurring_fee', TRUE)),
-    '#default_value' => variable_get('uc_recurring_handler', 'uc_recurring'),
-  );
   foreach (_payment_method_list() as $method) {
     $options[$method['id']] = $method['name'];
   }
@@ -883,9 +851,15 @@ function uc_recurring_find_fees($order) {
  *   TRUE or FALSE indicating whether or not the processing was successful.
  */
 function uc_recurring_process($order, $fee) {
-  $handler = variable_get('uc_recurring_handler', 'uc_recurring') .'_recurring_fee';
+  $gateways = _payment_gateway_list($order->payment_method, TRUE);
+  foreach ($gateways as $gateway) {
+    if ($gateway['recurring_fee']) {
+      $handler = $gateway['recurring_fee'];
+      break;
+    }
+  }
   if (!function_exists($handler)) {
-    drupal_set_message(t('The handler for processing recurring fees cannot be found.'), 'error');
+    drupal_set_message(t('A handler for processing recurring fees cannot be found.'), 'error');
     return FALSE;
   }
 
@@ -896,63 +870,4 @@ function uc_recurring_process($order, $fee) {
   return FALSE;
 }
 
-// Processes credit cards for the default handler.
-function uc_recurring_charge($fee) {
-  static $show = TRUE;
 
-  // Get the charge function for the default credit card gateway.
-  $gateways = _payment_gateway_list('credit', TRUE);
-  if (count($gateways) == 1) {
-    $keys = array_keys($gateways);
-    $func = $gateways[$keys[0]]['credit'];
-  }
-  elseif (count($gateways) > 1) {
-    foreach ($gateways as $gateway) {
-      if ($gateway['id'] == variable_get('uc_payment_credit_gateway', '')) {
-        $func = $gateway['credit'];
-      }
-    }
-  }
-
-  // Whoa... bad function? ABORT! ABORT!
-  if (!function_exists($func)) {
-    if ($show) {
-      watchdog('uc_recurring', 'Recurring payments failed to process due to invalid credit card gateway.', array(), WATCHDOG_ERROR);
-      $show = FALSE;
-    }
-    return FALSE;
-  }
-
-  // Cache the CC details stored by the handler.
-  uc_credit_cache('save', $fee['data']['payment_details'], FALSE);
-
-  // Run the charge.
-  $result = $func($fee['order_id'], $fee['fee_amount'], NULL);
-
-  // Handle the result.
-  if ($result['success'] === TRUE) {
-    uc_payment_enter($fee['order_id'], 'credit', $fee['fee_amount'], 0, $result['data'], t('Recurring fee payment.') .'<br />'. $result['comment']);
-    uc_order_comment_save($fee['order_id'], 0, t('!amount recurring fee collected for @model. (ID: <a href="!url">!fee</a>)', array('!url' => url('admin/store/orders/recurring/view/fee/'. $fee['rfid']), '!fee' => $fee['rfid'], '!amount' => uc_currency_format($fee['fee_amount']), '@model' => $fee['data']['model'])));
-
-    // Modules can hook into the charge process using hook_recurring_api().
-    module_invoke_all('recurring_api', 'charge', $fee);
-
-    // Needs to be updated for Conditional Actions. -RS
-    // workflow_ng_invoke_event('fee_charge_successful', uc_order_load($fee['order_id']));
-    // if ($fee['remaining_intervals'] == 1) {
-    //   workflow_ng_invoke_event('fee_expires', uc_order_load($fee['order_id']));
-    // }
-  }
-  else {
-    uc_order_comment_save($fee['order_id'], 0, t('Error: Recurring fee <a href="!url">!fee</a> for product @model failed.', array('!url' => url('admin/store/orders/recurring/view/fee/'. $fee['rfid']), '!fee' => $fee['rfid'], '@model' => $fee['data']['model'])));
-    watchdog('uc_recurring', 'Failed to capture recurring fee of !amount for product @model on order !order_id.', array('!amount' => $fee['fee_amount'], '@model' => $fee['data']['model'], '!order_id' => $fee['order_id']), WATCHDOG_ERROR, l(t('order !order_id', array('!order_id' => $fee['order_id'])), 'admin/store/orders/'. $fee['order_id']));
-
-    // Modules can hook into the charge process using hook_recurring_api().
-    module_invoke_all('recurring_api', 'fail', $fee);
-
-    // Provide a Workflow event for folks to hook into.
-    // workflow_ng_invoke_event('fee_charge_fails', uc_order_load($fee['order_id']));
-  }
-
-  return $result['success'];
-}
