Commit 99479087 authored by dandaman's avatar dandaman Committed by Obsidian Design

Issue #897090 by reybryand: Updates Authorize.net Payment Webform module to be...

Issue #897090 by reybryand: Updates Authorize.net Payment Webform module to be compatible with Webform 3.x.  Thanks to dandaman for authoring the patch.
parent db86f05e
<?php
// define('AUTHORIZENETWEBFORM_MODE','test');
define('AUTHORIZENETWEBFORM_MODE','live');
/**
* @file
* Authorize.Net Webform Module File
......@@ -26,7 +29,15 @@ function authorizenetwebform_form_alter(&$form, &$form_state, $form_id) {
// 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
......@@ -45,13 +56,13 @@ function authorizenetwebform_form_alter(&$form, &$form_state, $form_id) {
);
$authorizenet_form['authorizenetsettings']['use_authorizenet'] = array(
'#type' => 'radios',
'#title' => t('Allow Payment via Authorize.Net'),
'#options' => array(
1 => t('Yes'), 0 => t('No')
),
'#description' => t('If yes, the form\'s results will be processed via Authorize.Net. The credit card enetered will be validated & authorized before the form is formally submitted.'),
'#default_value' => ($form['#node']->use_authorizenet) ? $form['#node']->use_authorizenet : 0,
'#type' => 'radios',
'#title' => t('Allow Payment via Authorize.Net'),
'#options' => array(
1 => t('Yes'), 0 => t('No')
),
'#description' => t('If yes, the form\'s results will be processed via Authorize.Net. The credit card enetered will be validated & authorized before the form is formally submitted.'),
'#default_value' => ($form['#node']->use_authorizenet) ? $form['#node']->use_authorizenet : 0,
);
/* End Authorize.Net settings form */
......@@ -67,9 +78,17 @@ function authorizenetwebform_form_alter(&$form, &$form_state, $form_id) {
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',
......@@ -78,14 +97,28 @@ function authorizenetwebform_form_alter(&$form, &$form_state, $form_id) {
'#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()
*
......@@ -228,6 +261,32 @@ function authorizenet_create_custom_field_spec($custom_fields) {
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 (is_array($v)) {
foreach ($v as $key => $value) {
if (array_key_exists($key, $map)) {
$ret[$map[$key]] = $value;
}
}
} else {
if(array_key_exists($k,$map)) {
$k = $map[$k];
}
$ret[$k] = $v;
}
}
return $ret;
}
/*
* Process a webform submission through Authorize.Net
*
......@@ -244,67 +303,61 @@ function authorizenet_create_custom_field_spec($custom_fields) {
* 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;
}
module_load_include('inc', 'authorizenetwebform', '/authorizenetwebform_fields');
$wfkeys = array();
$wfkeys[0] = "";
//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'];
unset($_SESSION['anwf_trans_id']);
// store values in our own private variable
$form_values = $form_state['values'];
// Flatten the user-submitted data (in case the data is nested within fieldsets).
$submitted_data = _array_flatten($form_state['values']['submitted'], true);
// 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'])) {
$submitted_data[$exp_date_key] = preg_replace('/[^0-9]+/', '', $submitted_data[$exp_date_key]);
}
foreach ($form_values['submitted_tree'] as $key => $value) {
$wfkeys[] = $key;
// get an array with the webform keys replaced with the authorizenet keys
$submitted = authorizenetwebform_translate_keys($submitted_data, $map);
// Not the greatest way to store the transaction id (kind of hackish), but the best we can do until #288199 is fixed.
if ($submitted['x_trans_id'] == "" && $step == "submit") {
$submitted['x_trans_id'] = $_SESSION['anwf_trans_id'];
unset($_SESSION['anwf_trans_id']);
}
//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)];
}
else {
foreach ($form_values['submitted_tree'] as $fkey => $fvalue) {
if (is_array($fvalue)) {
if (array_key_exists(strtolower($mkey), $fvalue)) {
$submission[$mkey] = $form_values['submitted_tree'][$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)];
}
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)];
}
}
}
}
}
}
}
}
}
if (array_key_exists(strtolower($mkey), $submitted)) {
$submission[$mkey] = $submitted[strtolower($mkey)];
}
}
if (isset($submission['anwf_quantity']) && is_numeric($submission['anwf_quantity'])) {
$submission['x_amount'] = ((double) $submission['x_amount']) * ((double) $submission['anwf_quantity']);
}
$post_vars = array();
foreach ($submission as $key => $value) {
if (strcmp(substr($key, 0, 2), "x_") == 0 && $value != "") {
$post_vars[$key] = $value;
}
}
// Authorize.Net required field information
$posturl = variable_get('authorizenetwebform_url', NULL);
$post_url = ($posturl == "main") ? "https://secure.authorize.net/gateway/transact.dll" : "https://test.authorize.net/gateway/transact.dll";
......@@ -315,28 +368,25 @@ function authorizenetwebform_process($step, $node, $form, $form_state) {
$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';
}
if ($step == "submit") {
if (!array_key_exists('x_trans_id', $post_vars)) {
//There was a problem getting the Auth previously, so we need to auth & capture in one step.
$post_vars['x_type'] = 'AUTH_CAPTURE';
}
else {
$post_vars['x_type'] = 'PRIOR_AUTH_CAPTURE';
}
// If there was a problem getting the Auth previously, we need to auth & capture in one step.
$post_vars['x_type'] = !array_key_exists('x_trans_id', $post_vars) ? 'AUTH_CAPTURE' : 'PRIOR_AUTH_CAPTURE';
}
// This section takes the input fields and converts them to the proper format
// for an http post. For example: "x_login=username&x_tran_key=a1B2c3D4"
$post_string = "";
foreach ( $post_vars as $key => $value ) {
$post_string .= "$key=". urlencode( $value ) ."&";
$post_string .= "$key=" . urlencode($value) . "&";
}
$post_string = rtrim( $post_string, "& " );
$post_string = rtrim($post_string, "& ");
$request = curl_init($post_url); // initiate curl object
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1); // Returns response data instead of TRUE(1)
......@@ -355,53 +405,107 @@ function authorizenetwebform_process($step, $node, $form, $form_state) {
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])));
}
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'];
// Setting items in the original form_values to replace.
$replacements = array(
$flipped_map['x_trans_id'] => $response_array[6],
);
//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'] = $response_array[6];
}
}
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])));
}
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'];
}
$replacements = array();
$cids = flatten_array_by_cids($node);
//blank out all but the last 4 CC #'s
$cc = $submitted[$cids[$flipped_map['x_card_num']]];
$cclen = strlen($cc);
$end = $cclen - 4;
$anon_cc = preg_replace("/^[0-9]{0,$end}/",'xxxxxxxxx',$cc);
$replacements[$cids[$flipped_map['x_card_num']]] = $anon_cc;
//blank out the expiration date as well
$replacements[$cids[$flipped_map['x_exp_date']]] = 'xxxxxx';
//blank out the security code as well
$replacements[$cids[$flipped_map['x_card_code']]] = 'xxx';
if ($response_array[6] != "") {
//We have a transaction ID. Set it in the webform
$replacements[$cids[$flipped_map['x_trans_id']]] = $response_array[6];
}
}
// Replace the old values with the new ones.
array_walk_recursive($form_values['submitted'], '_replace_value_in_recursive', $replacements);
//Return our temporary values to the $form_state array
$form_state['values'] = $form_values;
return $form_state;
}
/**
* 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);
}
/**
* Utility function to flatten a multidimensional array.
*/
function _array_flatten($array, $preserve_keys = false) {
if (!$preserve_keys) {
// ensure keys are numeric values to avoid overwritting when array_merge gets called
$array = array_values($array);
}
$flattened_array = array();
foreach ($array as $k => $v) {
if (is_array($v)) {
$flattened_array = array_merge($flattened_array, call_user_func(__FUNCTION__, $v, $preserve_keys));
} elseif ($preserve_keys) {
$flattened_array[$k] = $v;
} else {
$flattened_array[] = $v;
}
}
return $flattened_array;
}
/**
* Utility function for replacing the transaction ID in the original
* (unflattened) array.
*/
function _replace_value_in_recursive(&$item, $key, $replacements) {
if (array_key_exists($key, $replacements)) {
$item = $replacements[$key];
}
}
function flatten_array_by_cids($node) {
$cids = array();
foreach ($node->webform['components'] as $component) {
if ($component['type'] != 'fieldset') {
$cids[$component['form_key']] = $component['cid'];
}
}
return $cids;
}
\ No newline at end of file
......@@ -21,6 +21,7 @@ function authorizenetwebform_available_fields() {
// Transaction Info
'x_amount' => 'Amount',
'anwf_quantity' => 'Quantity - Multiplies this number by Amount - 1 if not set',
'x_card_num' => 'Card Number',
'x_card_code' => 'Card Security Code',
'x_description' => 'Transaction Description',
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment