? .svn
? uc_recurring-authorize-580938-20.patch
? uc_recurring-authorize-580938-23.patch
? uc_recurring_hosted
Index: uc_recurring.uc_authorizenet.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/uc_recurring/modules/Attic/uc_recurring.uc_authorizenet.inc,v
retrieving revision 1.1.2.6
diff -u -p -r1.1.2.6 uc_recurring.uc_authorizenet.inc
--- uc_recurring.uc_authorizenet.inc	17 Sep 2009 01:08:46 -0000	1.1.2.6
+++ uc_recurring.uc_authorizenet.inc	8 Oct 2009 18:47:57 -0000
@@ -35,22 +35,10 @@ function uc_recurring_uc_authorizenet_re
       'cancel' => UC_RECURRING_MENU_DEFAULT,
     ), // Use the default user operation defined in uc_recurring.
   );
-  $items['authorizenet_arb'] = array(
-    'name' => t('Authorize.net (ARB)'),
-    'payment method' => 'credit',
-    'module' => 'uc_recurring',
-    'fee handler' => 'authorizenet_arb',
-    'process' => 'uc_recurring_authorizenet_arb_process',
-    'own handler' => TRUE,
-  );
 
   if (variable_get('uc_authnet_cim_mode', 'disabled') != 'disabled') {
     $items['authorizenet'] = $items['authorizenet_cim'];
   }
-  elseif (variable_get('uc_authnet_arb_mode', 'disabled') != 'disabled') {
-    // ARB not currently supported, uncomment to test
-    // $items['authorizenet'] = $items['authorizenet_arb'];
-  }
   return $items;
 }
 
@@ -219,136 +207,3 @@ function uc_recurring_authorizenet_cim_p
 
   return $form;
 }
-
-/**
- * Set up the recurring fee using the ARB api.
- *
- * @param $order
- *   The order object.
- * @param $fee
- *   The fee object.
- * @return
- *   TRUE if recurring fee setup
- */
-function uc_recurring_authorizenet_arb_process($order, &$fee) {
-  $fee->fee_handler = 'authorizenet_arb';
-  // We can't just call the existing arb function in ubercart as that would try
-  // and setup thing that uc_recurring does now for all recurring fees.
-  // return uc_authorizenet_arb_create($order, $fee);
-  $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';
-  }
-
-  // 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->title, '@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;
-  }
-
-  return TRUE;
-}
-
Index: uc_recurring_hosted.info
===================================================================
RCS file: uc_recurring_hosted.info
diff -N uc_recurring_hosted.info
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_recurring_hosted.info	8 Oct 2009 18:47:57 -0000
@@ -0,0 +1,5 @@
+name = Recurring Fees - Hosted
+description = Recurring Fees handlers for hosted gateways - i.e. Authorize.net ARB and Paypal WPS
+dependencies[] = uc_recurring
+package = Ubercart - payment
+core = 6.x
Index: uc_recurring_hosted.install
===================================================================
RCS file: uc_recurring_hosted.install
diff -N uc_recurring_hosted.install
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_recurring_hosted.install	8 Oct 2009 18:47:57 -0000
@@ -0,0 +1,46 @@
+<?php
+//$Id$
+
+/**
+ * @file
+ * Installs the Recurring Fee Hosted module.
+ */
+
+/**
+ * Implementation of hook_schema().
+ */
+function uc_recurring_hosted_schema() {
+  $schema = array();
+
+  $schema['uc_recurring_hosted'] = array(
+    'description' => t('Stores recurring fee ids for hosted payment gateways.'),
+    'fields' => array(
+      'rfid' => array(
+        'description' => t('The id of the recurring fee.'),
+        'type' => 'int',
+        'unsigned' => TRUE,
+        'not null' => TRUE,
+      ),
+      'subscription_id' => array(
+        'description' => t('The corresponding subscription id from the hosted gateway.'),
+        'type' => 'varchar',
+        'length' => 50,
+        'not null' => TRUE,
+        'default' => '',
+      ),
+    ),
+    'primary key' => array('rfid'),
+  );
+  return $schema;
+}
+
+/**
+ * Implementation of hook_install().
+ */
+function uc_recurring_hosted_install() {
+  drupal_install_schema('uc_recurring_hosted');
+}
+
+function uc_recurring_hosted_uninstall() {
+  drupal_uninstall_schema('uc_recurring_hosted');
+}
Index: uc_recurring_hosted.module
===================================================================
RCS file: uc_recurring_hosted.module
diff -N uc_recurring_hosted.module
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ uc_recurring_hosted.module	8 Oct 2009 18:47:57 -0000
@@ -0,0 +1,300 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Provides hosted gateway specific code for recurring payments, specifically
+ * Authorize.net ARB and Paypal WPS
+ */
+
+/**
+ * Implementation of hook_recurring_info().
+ */
+function uc_recurring_hosted_uc_authorizenet_recurring_info() {
+  $items['authorizenet_arb'] = array(
+    'name' => t('Authorize.net (ARB)'),
+    'payment method' => 'credit',
+    'module' => 'uc_recurring',
+    'fee handler' => 'authorizenet_arb',
+    'process callback' => 'uc_recurring_hosted_authorizenet_arb_process',
+    'cancel callback' => 'uc_recurring_hosted_authorizenet_arb_cancel',
+    'menu' => array(
+      'update' => array(
+        'title' => 'Update Account Details',
+        'page arguments' => array('uc_recurring_hosted_authorizenet_arb_update_form'),
+      ),
+      'cancel' => UC_RECURRING_MENU_DEFAULT,
+    ),
+    'own handler' => TRUE,
+  );
+
+  if (variable_get('uc_authnet_arb_mode', 'disabled') != 'disabled') {
+    $items['authorizenet'] = $items['authorizenet_arb'];
+  }
+  return $items;
+}
+
+/**
+ * Implementation of hook_uc_auth_arb_payment().
+ * Called during an ARB silent post 
+ */
+function uc_recurring_hosted_uc_auth_arb_payment($post) {
+  $fee = db_fetch_object(db_query("SELECT rfid FROM {uc_recurring_hosted} WHERE subscription_id = '%s'", $post['x_subscription_id']));
+
+  if (!empty($fee)) {
+    $fee = uc_recurring_fee_user_load($fee->rfid);
+    uc_recurring_renew($fee);
+
+    // Log the ARB payment if enabled.
+    if (variable_get('uc_authnet_report_arb_post', FALSE)) {
+      watchdog('uc_authorizenet', 'ARB payment reported for order @order_id: <pre>@post</pre>', array('@order_id' => $fee->order_id, '@post' => print_r($post, TRUE)));
+    }
+  }
+}
+
+/**
+ * Set up the recurring fee using the ARB api.
+ *
+ * @param $order
+ *   The order object.
+ * @param $fee
+ *   The fee object.
+ * @return
+ *   TRUE if recurring fee setup
+ */
+function uc_recurring_hosted_authorizenet_arb_process($order, &$fee) {
+  $fee->fee_handler = 'authorizenet_arb';
+  // We can't just call the existing arb function in ubercart as that would try
+  // and setup thing that uc_recurring does now for all recurring fees.
+  // return uc_authorizenet_arb_create($order, $fee);
+  $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';
+  }
+
+  // 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->title, '@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', $fee->next_charge),
+        'totalOccurrences' => $fee->remaining_intervals == -1 ? 9999 : $fee->remaining_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;
+  }
+  uc_order_comment_save($order->order_id, 0, t('Authorize.Net: ARB subscription created - @id', array('@id' => $data['subscriptionId'])));
+  
+  // Save the new credit reference to the db.
+  $record = array(
+    'rfid' => $fee->rfid, 
+    'subscription_id' => $data['subscriptionId'],
+  );
+  drupal_write_record('uc_recurring_hosted', $record);
+  $order->data = uc_credit_log_reference($order->order_id, $data['subscriptionId'], $order->payment_details['cc_number']);
+
+  return TRUE;
+}
+
+/**
+ * Cancel the recurring fee using the ARB api.
+ *
+ * @param $order
+ *   The order object.
+ * @param $fee
+ *   The fee object.
+ * @return
+ *   TRUE if recurring fee was cancelled
+ */
+function uc_recurring_hosted_authorizenet_arb_cancel($order, &$fee) {
+  $server = variable_get('uc_authnet_arb_mode', 'disabled');
+  
+  $order = uc_order_load($order->order_id);
+  $subscription_id = end(array_keys($order->data['cc_txns']['references']));
+
+  // Build the data array for the request.
+  $data = array(
+    'refId' => substr($order->order_id .'-'. time(), 0, 20),
+    'subscriptionId' => $subscription_id,
+  );
+
+  // Build the XML string.
+  $xml = _uc_authorizenet_xml_api_wrapper('ARBCancelSubscriptionRequest', _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') {
+    if (!empty($order_id)) {
+      uc_order_comment_save($order_id, 0, t('Authorize.Net: Subscription @subscription_id cancellation failed.<br />@error - @text', array('@subscription_id' => $subscription_id, '@error' => $data['code'], '@text' => $data['text'])), 'admin');
+    }
+    return FALSE;
+  }
+
+  uc_order_comment_save($order_id, 0, t('Authorize.Net: Subscription @subscription_id cancelled.', array('@subscription_id' => $subscription_id)), 'admin');
+
+  return TRUE;
+}
+
+/**
+ * Create form for updating credit card details for recurring fee.
+ */
+function uc_recurring_hosted_authorizenet_arb_update_form($form_state, $rfid) {
+  $form['rfid'] = array(
+    '#type' => 'value',
+    '#value' => $rfid,
+  );
+  $form['cc_data'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Credit card details'),
+    '#theme' => 'uc_payment_method_credit_form',
+    '#tree' => TRUE,
+  );
+  $form['cc_data'] += uc_payment_method_credit_form(array(), $order);
+  unset($form['cc_data']['cc_policy']);
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Update'),
+    '#suffix' => l(t('Cancel'), 'user/'. $user->uid),
+  );
+
+  return $form;
+}
+
+/**
+ * Implements update form submit for the authorizenet ARB gateway.
+ */
+function uc_recurring_hosted_authorizenet_arb_update_form_submit(&$form, &$form_state) {
+  $fee = uc_recurring_fee_user_load($form_state['values']['rfid']);
+  $order = uc_order_load($fee->order_id);
+  $order->payment_details = $form_state['values']['cc_data'];
+  $subscription_id = end(array_keys($order->data['cc_txns']['references']));
+    
+  if ($order->payment_details['cc_exp_month'] < 10) {
+    $order->payment_details['cc_exp_month'] = '0'. $order->payment_details['cc_exp_month'];
+  }
+
+  // Build the data array for the request.
+  $updates = array(
+    'payment' => array(
+      'creditCard' => array(
+        'cardNumber' => $order->payment_details['cc_number'],
+        'expirationDate' => $order->payment_details['cc_exp_year'] .'-'. $order->payment_details['cc_exp_month'],
+      ),
+    ),
+  );
+  
+  if (uc_authorizenet_arb_update($subscription_id, $updates, $order->order_id)) {
+    drupal_set_message('Account updated.');
+    $form_state['redirect'] = 'user/'. $form_state['values']['uid'];
+  }
+  else {
+    drupal_set_message('Account update failed.', 'error');
+  }
+}
