diff --git payment/uc_authorizenet/uc_authorizenet.module payment/uc_authorizenet/uc_authorizenet.module
index a2e1161..434df79 100644
--- payment/uc_authorizenet/uc_authorizenet.module
+++ payment/uc_authorizenet/uc_authorizenet.module
@@ -656,6 +656,154 @@ function uc_authorizenet_recurring_fee_ops($context, $fee) {
 }
 
 /**
+ * Callback function for setting up a recurring fee
+ */
+function uc_recurring_authorizenet_fee($order, &$fee) {
+  // Don't process the fee if ARB is disabled in the gateway settings.
+  if (variable_get('uc_authnet_arb_mode', 'disabled') == 'disabled') {
+    return FALSE;
+  }
+
+  $server = variable_get('uc_authnet_arb_mode', 'disabled');
+
+  // Setup variables for the payment schedule.
+  list($length, $unit) = explode(' ', $fee->regular_interval);
+  list($trial_length, $trial_unit) = explode(' ', $fee->initial_charge);
+
+  // Convert weeks and years to days.
+  if ($unit == 'weeks') {
+    $length *= 7;
+    $unit = 'days';
+  }
+  elseif ($unit == 'years') {
+    $length *= 365;
+    $unit = 'days';
+  }
+
+  // Get a default SKU if none was supplied.
+  if (empty($fee->model)) {
+    $fee->model = db_result(db_query("SELECT model FROM {uc_products} WHERE nid = %d", $fee->nid));
+  }
+
+  // Make sure we have valid values for Authorize.Net.
+  if ($length <= 0 || $unit == 'days' && $length > 365 || $unit == 'months' && $length > 12) {
+    watchdog('uc_authorizenet', 'Product @sku has invalid interval settings for Authorize.Net - @length @unit', array('@sku' => $fee->model, '@length' => $length, '@unit' => $unit), WATCHDOG_ERROR);
+    return FALSE;
+  }
+
+  // Get the country data for the billing and shipping information.
+  $billing_country = uc_get_country_data(array('country_id' => $order->billing_country));
+  $delivery_country = uc_get_country_data(array('country_id' => $order->delivery_country));
+
+  // Build the data array for the request.
+  $data = array(
+    'refId' => substr($order->order_id .'-'. time(), 0, 20),
+    'subscription' => array(
+      'name' => substr(t('Order @order_id', array('@order_id' => $order->order_id)), 0, 50),
+      'paymentSchedule' => array(
+        'interval' => array(
+          'length' => $length,
+          'unit' => $unit,
+        ),
+        'startDate' => date('Y-m-d', strtotime('+ '. $fee->initial_charge)),
+        'totalOccurrences' => $fee->number_intervals,
+        'trialOccurrences' => '0',
+      ),
+      'amount' => round($fee->fee_amount, 2),
+      'trialAmount' => 0,
+      'payment' => array(), // Data inserted below based on payment method.
+      'order' => array(
+        'invoiceNumber' => substr($order->order_id, 0, 20),
+        'description' => substr(t('Order @order_id - @sku', array('@order_id' => $order->order_id, '@sku' => $fee->model)), 0, 255),
+      ),
+      'customer' => array(
+        'id' => substr($order->uid, 0, 20),
+        'email' => substr($order->primary_email, 0, 255),
+        'phoneNumber' => substr($order->billing_phone, 0, 25),
+        // 'faxNumber' => '',
+      ),
+      'billTo' => array(
+        'firstName' => substr($order->billing_first_name, 0, 50),
+        'lastName' => substr($order->billing_last_name, 0, 50),
+        'company' => substr($order->billing_company, 0, 50),
+        'address' => substr($order->billing_street1, 0, 60),
+        'city' => substr($order->billing_city, 0, 40),
+        'state' => substr(uc_get_zone_code($order->billing_zone), 0, 2),
+        'zip' => substr($order->billing_postal_code, 0, 20),
+        'country' => !$billing_country ? '' : $billing_country[0]['country_iso_code_2'],
+      ),
+      'shipTo' => array(
+        'firstName' => substr($order->delivery_first_name, 0, 50),
+        'lastName' => substr($order->delivery_last_name, 0, 50),
+        'company' => substr($order->delivery_company, 0, 50),
+        'address' => substr($order->delivery_street1, 0, 60),
+        'city' => substr($order->delivery_city, 0, 40),
+        'state' => substr(uc_get_zone_code($order->delivery_zone), 0, 2),
+        'zip' => substr($order->delivery_postal_code, 0, 20),
+        'country' => !$delivery_country ? '' : $delivery_country[0]['country_iso_code_2'],
+      ),
+    ),
+  );
+
+  // Strip out the shipping info if it isn't necessary.
+  if (empty($data['subscription']['shipTo']['firstName'])) {
+    unset($data['subscription']['shipTo']);
+  }
+
+  // Add the payment information to the data array based on the payment method.
+  if ($order->payment_method == 'credit') {
+    if ($order->payment_details['cc_exp_month'] < 10) {
+      $order->payment_details['cc_exp_month'] = '0'. $order->payment_details['cc_exp_month'];
+    }
+
+    $data['subscription']['payment'] = array(
+      'creditCard' => array(
+        'cardNumber' => $order->payment_details['cc_number'],
+        'expirationDate' => $order->payment_details['cc_exp_year'] .'-'. $order->payment_details['cc_exp_month'],
+      ),
+    );
+  }
+
+  // Build the XML string.
+  $xml = _uc_authorizenet_xml_api_wrapper('ARBCreateSubscriptionRequest', _uc_authorizenet_array_to_xml($data));
+
+  // Send the request off to the server and get the response.
+  $response = uc_authorizenet_xml_api($server, $xml);
+
+  // Fail if the response is empty or FALSE.
+  if (!$response) {
+    return FALSE;
+  }
+
+  // Parse the response into a data array.
+  $data = _uc_authorizenet_arb_parse_response($response);
+
+  if ($data['resultCode'] == 'Error') {
+    uc_order_comment_save($order->order_id, 0, t('Authorize.Net: Recurring fee for @model failed.<br />@error - @text', array('@model' => $fee->model, '@error' => $data['code'], '@text' => $data['text'])), 'admin');
+    return FALSE;
+  }
+
+  $fee->fee_handler = 'authorizenet_arb';
+  $fee->data => array('subscriptionId' => $data['subscriptionId']);
+
+  return TRUE;
+}
+
+/**
+ * Callback to process a recurring renewal
+ */
+function uc_recurring_authorizenet_arb_renew($order, $fee) {
+  return TRUE; // renewals handled by autorisenet, so we don't need to so anything here
+}
+
+/**
+ * Callback for uc_recurring_fee_ops().
+ */
+function uc_recurring_authorizenet_arb_fee_ops($context, $fee) {
+  uc_authorizenet_recurring_fee_ops($context, $fee); // just use the old function
+}
+
+/**
  * Sends an XML API Request to Authorize.Net.
  *
  * @param $server
diff --git payment/uc_authorizenet/uc_authorizenet.pages.inc payment/uc_authorizenet/uc_authorizenet.pages.inc
index f8e5941..038150b 100644
--- payment/uc_authorizenet/uc_authorizenet.pages.inc
+++ payment/uc_authorizenet/uc_authorizenet.pages.inc
@@ -30,19 +30,10 @@ function uc_authorizenet_silent_post() {
     }
     else {
       // Otherwise, update the recurring fee information in our database.
-      $fee = db_fetch_array(db_query("SELECT * FROM {uc_recurring_users} WHERE fee_handler = 'uc_authorizenet' AND data = '%s'", $_POST['x_subscription_id']));
+      $fee = uc_recurring_find_fee($fee_handler, $_POST['x_subscription_id']);
 
-      // Only process if the fee actually exists!
-      if (!empty($fee)) {
-        // Update the interval counters.
-        $fee['remaining_intervals'] -= 1;
-        $fee['charged_intervals'] += 1;
-
-        // Set the next expected charge time.
-        $fee['next_charge'] = strtotime('+'. $fee['regular_interval'], $fee['next_charge']);
-
-        // Save the new values.
-        uc_recurring_fee_save('user', $fee);
+      if ($fee) {
+        uc_recurring_renew($fee);
 
         // Log the ARB payment if enabled.
         if (variable_get('uc_authnet_report_arb_post', FALSE)) {
