My issue with this method is that because it is handling the error after the form is processed it wipes all fields when it redirects back to the form. I figured out a way to fix this and in the process I believe I solved both of the other issues.
I discovered
here that you can invalidate a field in the on form process so basically once we get the response from authorize.net I check the error and then invalidate whatever field is associated with the error. If there is no error I then obfuscate the CC Number (as it has been processed but not saved to the DB).
The awesome part of invalidating a field is two fold, 1) You can actually highlight whatever field caused the error and 2) It doesn't call a redirect or refresh the page so all of the fields are still filled out.
I deleted both the On Form Display and the After Form Has Been Processed code. All you need is the On Form Process which I have added below.
Unfortunately you are causing an invalid form error and not a credit card error. I found a workaround where I basically hijack the built in error form and replace it with the credit card string. Here are the steps to do it:
1) Click on Properties/Form Info and click "Edit the Error Message". Switch to HTML view and add an ID tag = "FormError". Then after the error message add in a call to a javascript function: changeError(), here is the code:
(You have to set TinyMCE to allow the <script> tag for this to work)
<p id="FormError" class="formRed">Please complete all required fields!</p>
<script type="text/javascript">// <![CDATA[
changeError();
// ]]></script>
2) Click on Properties/CSS and Javascript and add this code to the Javascript section:
<script type="text/javascript">
var errorMsg = "Missing Required Field!";
function changeError() {
document.getElementById("FormError").innerHTML = errorMsg;
}
</script>
3) Click on Properties/PHP Scripts and add this code to the On Form Process:
if(!empty($_POST['form']['cc_number']) && !empty($_POST['form']['exp_month']) && !empty($_POST['form']['exp_year']) && !empty($_POST['form']['cc_amount']) && !empty($_POST['form']['cc_first']) && !empty($_POST['form']['cc_last'])){
/* $post_url = "https://secure.authorize.net/gateway/transact.dll"; */
$post_url = "https://test.authorize.net/gateway/transact.dll";
$post_values = array(
// the API Login ID and Transaction Key must be replaced with
//valid values
"x_login" => "xxxxxxxx",
"x_tran_key" => "xxxxxxxxxx",
"x_version" => "3.1",
"x_delim_data" => "TRUE",
"x_delim_char" => "|",
"x_relay_response" => "FALSE",
"x_type" => "AUTH_CAPTURE",
"x_method" => "CC",
"x_card_num" => $_POST['form']['cc_number'],
"x_exp_date" => substr($_POST['form']['exp_month'][0], 0, 2).substr($_POST['form']['exp_year'][0], 2, 2),
"x_amount" => str_replace( array('$',',') ,
'' , $_POST['form']['cc_amount']),
"x_description" => "USA Application Deposit",
"x_first_name" => $_POST['form']['cc_first'],
"x_last_name" => $_POST['form']['cc_last']
);
$post_string = "";
foreach( $post_values as $key => $value )
{ $post_string .= "$key=" . urlencode( $value ) . "&"; }
$post_string = rtrim( $post_string, "& " );
$request = curl_init($post_url); // initiate curl object curl_setopt($request, CURLOPT_HEADER, 0); /
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($request, CURLOPT_POSTFIELDS, $post_string);
curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE);
$post_response = curl_exec($request);
curl_close ($request); // close curl object
$response_array = explode($post_values["x_delim_char"],$post_response);
/*
Response Codes from Authorize.net Key - $response_array[0]
1 - Approved
2 - Declined
3 - There has been an error processing this transaction
4 - Transaction being held for review
Response Codes and Reason text - Code: $response_array[2] - Text: $response_array[3]
1 - This transaction has been approved
2 - This transaction has been declined
3 - This transaction has been declined
4 - This transaction has been declined
5 - A valid amount is required
6 - The credit card number is invalid
7 - credit card expiration date is invalid
8 - The credit card has expired
*/
$_POST['form']['cc_number']="***********".substr($_POST['form']['cc_number'],12,4);
/* If card is declined or there is an error*/
if($response_array[0] == 2 || $response_array[0] == 3){
/* If the error message is related to the Credit Card Number then invalidate the number and change error message*/
if($response_array[2] == 2 || $response_array[2] == 3 || $response_array[2] == 4 || $response_array[2] == 6){
$invalid[] = RSFormProHelper::getComponentId("cc_number");
echo'<script type="text/javascript">errorMsg = "'.$response_array[3].'";</script>';
}
/* If the error message is related to the Expiration Dates*/
if($response_array[2] == 7 || $response_array[2] == 8){
$invalid[] = RSFormProHelper::getComponentId("exp_month");
$invalid[] = RSFormProHelper::getComponentId("exp_year");
echo'<script type="text/javascript">errorMsg = "'.$response_array[3].'";</script>';
}
}
}
This will replace the standard Error message with the Credit Card error and it will highlight whatever field you invalidate. In my form I have a set amount that is readonly so I know I will never get error number 5 but you could write additional parameters to deal with whatever you want (or invalidate whatever you want based on the error).
Kyle