--- authorizenetwebform.module.orig	2010-10-22 13:21:22.000000000 -0400
+++ authorizenetwebform.module	2010-10-25 17:11:33.000000000 -0400
@@ -1,6 +1,9 @@
 <?php 
 // $Id: authorizenetwebform.module,v 1.1.2.3 2010/03/31 16:09:26 obsidiandesign Exp $
 
+// define('AUTHORIZENETWEBFORM_MODE','test');
+define('AUTHORIZENETWEBFORM_MODE','live');
+
 /**
  * @file
  * Authorize.Net Webform Module File
@@ -27,7 +30,15 @@
     // only deal with this form if it is supposed to go to Authorize.Net
     if ( empty($node->use_authorizenet) ) {
       return ;
-    }
+		} else {
+			// new validation handler
+			$form['#validate'][] = 'authorizenetwebform_validate';
+
+			// add new submit handler. based on webform_php model
+			// adding it as *second* handler (not sure why...)
+			$first = array_shift($form['#submit']);
+			array_unshift($form['#submit'], $first, 'authorizenetwebform_submit');
+		}
   }
   
   // handle editing of webform nodes
@@ -68,9 +79,17 @@
     if ( $form['#parameters'][2]->use_authorizenet == 1 ) {
       module_load_include('inc', 'authorizenetwebform', 'authorizenetwebform_fields');
       foreach (authorizenetwebform_available_fields() as $anwafkey => $anwafvalue) {
-      $anwafkey = strtolower($anwafkey);
-      $anwaf_array[$anwafkey] = $anwafvalue;
+				$anwafkey = strtolower($anwafkey);
+				$anwaf_array[$anwafkey] = $anwafvalue;
       }
+			$variable = 'authorizenetwebform_key_map_' . $form['nid']['#value'];
+			$map = variable_get($variable,array());
+			$form_key = $form['form_key']['#default_value'];
+			if(array_key_exists($form_key,$map)) {
+				$selected = $map[$form_key];
+			} else {
+				$selected = '';
+			}
       $valid_fields = array_merge($anwaf_array, authorizenetwebform_load_custom_fields('webform'));
       $anet_form_key = array(
         '#type' => 'select',
@@ -79,15 +98,29 @@
         '#options' => $valid_fields,
         '#description' => t('Select an Authorize.Net field that this form field will map to.  If you switch the form to an email for this will be used as the machine readable key.'),
         '#weight' => $form['field']['form_key']['#weight'],
-        '#default_value' => empty($form['#parameters'][3]['form_key']) ? '' : $form['#parameters'][3]['form_key'],
+        '#default_value' => $selected,
       ); 
-      $form['advanced']['form_key'] = $anet_form_key;
+			$form['#submit'][] = 'authorizenet_field_key_submit';
+      $form['advanced']['anet_field_key'] = $anet_form_key;
       $form['advanced']['#collapsed'] = FALSE;
     }
   }
  }
 
 /**
+ * submit function for storing the field key mapping
+ */
+function authorizenet_field_key_submit($form,&$form_state) {
+	$variable = 'authorizenetwebform_key_map_' . $form_state['values']['nid'];
+	$map = variable_get($variable,array());
+	$values = $form_state['values'];
+	$form_key = $values['form_key'];
+	$anet_form_key = $values['advanced']['anet_field_key'];
+	$map[$form_key] = $anet_form_key;
+	variable_set($variable,$map);
+}
+
+/**
  * Implementation of hook_nodeapi()
  *
  * Intercept operations on the webform node to assure that the Authorize.net fields are tracked.
@@ -220,6 +253,24 @@
   return $spec;
 }
 
+/**
+ * Return an array of all entries submitted, but with the
+ * key replaced based on the authorizenet mapping
+ * for the web form
+ **/
+function authorizenetwebform_translate_keys($submitted,$map) {
+  $ret = array();
+  reset($submitted);
+  
+  while(list($k,$v) = each($submitted)) {
+    if(array_key_exists($k,$map)) {
+      $k = $map[$k];
+    }
+    $ret[$k] = $v;
+  }
+  return $ret;
+}
+
 /* 
  * Process a webform submission through Authorize.Net
  *
@@ -236,50 +287,63 @@
  *  A form state array
  */
 function authorizenetwebform_process($step, $node, $form, $form_state) {
-  module_load_include('inc', 'authorizenetwebform', '/authorizenetwebform_fields');
-  $form_values = $form_state['values'];
-
   // DO NOT forward to Authorize.net if there are errors in the form validation
   if (form_get_errors()) {
     return $form_state;
   }
-  
-  $wfkeys = array();
-  $wfkeys[0] = "";
+  module_load_include('inc', 'authorizenetwebform', '/authorizenetwebform_fields');
+
+  // store values in our own private variable 
+  $form_values = $form_state['values'];
+
+  // get key mappings for this webform
+  $nid = $form_values['details']['nid'];
+  $variable = 'authorizenetwebform_key_map_' . $nid;
+	$map = variable_get($variable,array());
+
+  // we also want to access keys in the other direction
+  $flipped_map = array_flip($map);
+
+  // remove any non-numeric characters from expiration date
+  // like / or -
+  $exp_date_key = $flipped_map['x_exp_date'];
+  if(array_key_exists($exp_date_key,$form_values['submitted'])) {
+    $form_values['submitted'][$exp_date_key] = preg_replace('/[^0-9]+/','',$form_values['submitted'][$exp_date_key]);
+  }
+
+  // get an array with the webform keys replaced with the authorizenet keys
+  $submitted = authorizenetwebform_translate_keys($form_values['submitted'],$map);
+
   //Not the greatest way to store the transaction id (kind of hackish), but the best we can do until #288199 is fixed.
-  if ($form_values['submitted_tree']['x_trans_id'] == "" && $step == "submit") {
-    $form_values['submitted_tree']['x_trans_id'] = $_SESSION['anwf_trans_id'];
+  if ($submitted['x_trans_id'] == "" && $step == "submit") {
+    $submitted['x_trans_id'] = $_SESSION['anwf_trans_id'];
     unset($_SESSION['anwf_trans_id']);
   }
-  
-  foreach ($form_values['submitted_tree'] as $key => $value) {
-    $wfkeys[] = $key;
-  }
-  
-  //Map the webform fields to the pre-defined Authorize.Net fields
+
+  // Build a submission array that will be sent to authorizenet
   $master_fields = array_merge(authorizenetwebform_available_fields(), authorizenetwebform_load_custom_fields(NULL));
   $submission = array();
   foreach ($master_fields as $mkey => $mvalue) {
-    if (array_key_exists(strtolower($mkey), $form_values['submitted_tree'])) {
-      $submission[$mkey] = $form_values['submitted_tree'][strtolower($mkey)];
+    if (array_key_exists(strtolower($mkey), $submitted)) {
+      $submission[$mkey] = $submitted[strtolower($mkey)];
     }
     else {
-      foreach ($form_values['submitted_tree'] as $fkey => $fvalue) {
+      foreach ($submitted as $fkey => $fvalue) {
         if (is_array($fvalue)) {
           if (array_key_exists(strtolower($mkey), $fvalue)) {
-            $submission[$mkey] = $form_values['submitted_tree'][$fkey][strtolower($mkey)];
+            $submission[$mkey] = $submitted[$fkey][strtolower($mkey)];
           }
           else {
             foreach ($fvalue as $gkey => $gvalue) {
               if (is_array($gvalue)) {
                 if (array_key_exists(strtolower($mkey), $gvalue)) {
-                  $submission[$mkey] = $form_values['submitted_tree'][$fkey][$gkey][strtolower($mkey)];
+                  $submission[$mkey] = $submitted[$fkey][$gkey][strtolower($mkey)];
                 }
                 else {
                  foreach ($gvalue as $hkey => $hvalue) {
                    if (is_array($hvalue)) {
                      if (array_key_exists(strtolower($mkey), $hvalue)) {
-                       $submission[$mkey] = $form_values['submitted_tree'][$fkey][$gkey][$hkey][strtolower($mkey)];
+                       $submission[$mkey] = $submitted[$fkey][$gkey][$hkey][strtolower($mkey)];
                      }
                    }
                  }
@@ -307,6 +371,9 @@
   $post_vars['x_delim_char']    = "|";
   $post_vars['x_relay_response']  = "FALSE";
   $post_vars['x_method'] = "CC";
+  if(AUTHORIZENETWEBFORM_MODE == 'test') {
+    $post_vars['x_test_request '] = "TRUE";
+  }
   
   if ($step == "validate") {
     $post_vars['x_type'] = 'AUTH_ONLY';
@@ -348,47 +415,43 @@
     }
     if ($response_array[6] != "") {
       //We have a transaction ID.  Set it in the webform
-      $form_values['submitted_tree']['x_trans_id'] = $response_array[6];
-      $wfkeynum = webform_get_cid($node, 'x_trans_id', 0);
-      $form_values['submitted'][$wfkeynum] = $form_values['submitted_tree']['x_trans_id'];
+      $form_values['submitted'][$flipped_map['x_trans_id']] = $response_array[6];
+      $wfkeynum = webform_get_cid($node, $flipped_map['x_trans_id'], 0);
+      $form_values['submitted'][$wfkeynum] = $form_values['submitted'][$flipped_map['x_trans_id']];
       //Not the greatest way to store the transaction id (kind of hackish), but the best we can do until #288199 is fixed.
-      $_SESSION['anwf_trans_id'] = $form_values['submitted_tree']['x_trans_id'];
+      $_SESSION['anwf_trans_id'] = $form_values['submitted'][$flipped_map['x_trans_id']];
     }  
   }
   if  ($step == "submit") {
     if ($response_array[2] > 1) {
       watchdog('authorizenetwebform', 'Error response from Authorize.net: %resposne', array("%resposne" => "<pre>". print_r($response_array, TRUE) ."</pre>"));
       //There was some type of error getting an authorization.  Flag it
-      form_set_error('submitted][x_card_num', t('There was an error processing your credit card: %anetresponse.  If the error persists, please try another card.', array("%anetresponse" => $response_array[3])));
+      $cc_key = $flipped_map['x_card_num'];
+      $form_key = "submitted][$cc_key";
+      form_set_error($form_key, t('There was an error processing your credit card: %anetresponse.  If the error persists, please try another card.', array("%anetresponse" => $response_array[3])));
+    }
+    //blank out all but the last 4 CC #'s
+    $wfkeynum = webform_get_cid($node, $flipped_map['x_card_num'], 0);
+    $cc = $form_values['submitted'][$wfkeynum];
+    $cclen = strlen($cc);
+    $end = $cclen - 4;
+    $anon_cc = preg_replace("/^[0-9]{0,$end}/",'xxxxxxxxx',$cc);
+    $form_values['submitted'][$wfkeynum] = $anon_cc;
+    
+    //blank out the expiration date as well
+    $wfkeynum = webform_get_cid($node, $flipped_map['x_exp_date'], 0);
+    $form_values['submitted'][$wfkeynum] = 'xxxxxx';
+    
+    //blank out the security code as well - it's an optional field, so check if it's set first.
+    $wfkeynum = webform_get_cid($node, $flipped_map['x_card_code'], 0);
+    if (isset($form_values['submitted'][$wfkeynum])) {
+      $form_values['submitted'][$wfkeynum] = 'xxx';
     }
-    else {
-      //blank out all but the last 4 CC #'s
-      $ccsize = strlen($form_values['submitted_tree']['x_card_num']);
-      $cclen = $ccsize - 4;
-      for ($i = 0; $i < $cclen; $i++) {
-        $form_values['submitted_tree']['x_card_num'][$i] = 'x';
-      }
-      $wfkeynum = webform_get_cid($node, 'x_card_num', 0);
-      $form_values['submitted'][$wfkeynum] = $form_values['submitted_tree']['x_card_num'];
-      
-      //blank out the expiration date as well
-      $form_values['submitted_tree']['x_exp_date'] = 'xx/xx';
-      $wfkeynum = webform_get_cid($node, 'x_exp_date', 0);
-      $form_values['submitted'][$wfkeynum] = $form_values['submitted_tree']['x_exp_date'];
-      
-      //blank out the security code as well - it's an optional field, so check if it's set first.
-      if (isset($form_values['submitted_tree']['x_card_code'])) {
-        $form_values['submitted_tree']['x_card_code'] = 'xxx';
-        $wfkeynum = webform_get_cid($node, 'x_card_code', 0);
-        $form_values['submitted'][$wfkeynum] = $form_values['submitted_tree']['x_card_code'];
-      }
-      
-      if ($response_array[6] != "") {
-        //We have a transaction ID.  Set it in the webform
-        $form_values['submitted_tree']['x_trans_id'] = $response_array[6];
-        $wfkeynum = webform_get_cid($node, 'x_trans_id', 0);
-        $form_values['submitted'][$wfkeynum] = $form_values['submitted_tree']['x_trans_id'];
-      }
+    
+    if ($response_array[6] != "") {
+      //We have a transaction ID.  Set it in the webform
+      $wfkeynum = webform_get_cid($node, $flipped_map['x_trans_id'], 0);
+      $form_values['submitted'][$wfkeynum] = $response_array[6];
     }
   }
 
@@ -396,4 +459,20 @@
   $form_state['values'] = $form_values;
   
   return $form_state;
-}
\ No newline at end of file
+}
+
+/**
+ * Code to execute when webform is validated 
+ **/
+function authorizenetwebform_validate($form, &$form_state) {
+	$node = node_load($form_state['values']['details']['nid']);
+	$form_state = authorizenetwebform_process("validate", $node, $form_id, $form_state);
+}
+
+/**
+ * Code to execute when webform is submitted
+ **/
+function authorizenetwebform_submit($form, &$form_state) {
+	$node = node_load($form_state['values']['details']['nid']);
+	$form_state = authorizenetwebform_process("submit", $node, $form_id, $form_state);
+}
