I’ve never had a customer satisfied with a 3rd party shopping cart application. Most clients want transactions to occur without visual or behavioral seams. Building a custom cart can be a chore, depending on the requirements, but in most ways it’s the same as building any other type of database – the exception being the transaction itself.
Since any kind of financial transaction is sensitive, special attention should be paid to security. Encrypt passwords and transaction types, take care when passing information between pages, and make sure you’re using HTTPS. That said, let’s get into how to perform that one task that separates a cart from any other kind of application – the financial transaction.
There are a number of vendors that provide this service; the largest and most popular by far is Authorize.net. They have varying levels of service, ranging from simple “Buy Now” buttons to SIM (Simple Integration Method – which is a payment form hosted and maintained by them) to AIM (Advanced Integration Method). This last is the one I’ll discuss here, and the method required to have the cart application function within your application, with your webservices in control, your styling, etc.
This technique makes use of cURL – for those of you who’re unfamiliar, cURL performs URL (including HTTP) requests, and returns the response – almost like a form submission within a submission.
The basics of working with cURL can be found here.
We’ll be sending to a webservice provided by authorize.net – https://secure.authorize.net/gateway/transact.dll. We’ll use cURL to accomplish that, and process the response. We need to send some information along with it – credit cart info, the amount of the transaction, our login credentials, etc. The information needs to be sent in standard query string key:value pair format (key1=value1&key2=value2), and can be constructed however you want – loop through an array, string concatenation, whatever. I’ll use the built-in PHP function http_build_query for this example. It’s extremely important this data is processed before sending it, and user-input (direct POST or GET values) should never be used.
$data = // we'll assume all of our transaction information is in this associative array, already processed
$login = '123456789'; // you'll get this value from authorize.net
$tran_key = '90193201323'; // you'll get this value from authorize.net
$delimiter = '|'; // the delimiter we want the response to use
$authnet_values = array(
"x_login" => $login,
"x_version" => "3.1", // or whatever version you're using
"x_delim_char" => $delimiter,
"x_delim_data" => "TRUE",
"x_type" => "AUTH_CAPTURE",
"x_method" => "CC",
"x_tran_key" => $tran_key,
"x_relay_response" => "FALSE",
"x_card_num" => $data['credit_card_number'],
"x_exp_date" => $data['credit_card_expiration'],
"x_description" => $data['transaction_description'],
"x_amount" => $data['transaction_total_cost'],
"x_first_name" => $data['credit_card_user_first_name'],
"x_last_name" => $data['credit_card_user_last_name'],
"x_address" => $data['credit_card_user_street_address'],
"x_city" => $data['credit_card_user_city'],
"x_state" => $data['credit_card_user_state'],
"x_zip" => $data['credit_card_user_zip']
$fields = http_build_query($authnet_values);
$curl_request = curl_init("https://secure.authorize.net/gateway/transact.dll");
curl_setopt($curl_request, CURLOPT_HEADER, 0);
curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_request, CURLOPT_POSTFIELDS, $fields);
$curl_response = curl_exec($curl_request);
$response_values = explode($delimiter, $curl_response);
That’s about it. $response_values is an indexed array that will contain a number of values. The first ($response_values), determines if the transaction is successful – if it is, it’ll have a value of “1” – test for that to determine if the order should be written to your database.
Values (that I’m aware of) include:
0 – success (1) or failure
3 – error message (if applicable)
4 – authorization code
6 – transaction id