We build custom web applications
to grow your business.

cakePHP authorize.net plugin for a custom shopping cart: Installed in 5 minutes

Authorize.net is one of the most respected payment systems on the web and if you feel for an upgrade from paypal, it is one of the best alternative. So here is a quick way to create an authorize.net plugin for your cakePHP website.

1. Create a mysql table for authorize.net POST variables
2. Create your plugin using cakePHP bake option
3. Edit the AuthorizenetAppController.php file in your plugin to process information sent to your site from authroize.net
4. Create a checkout page with authorize.net form data
5. Create a thank you page
6. Edit authorize.net account information

First, create a database table called "authorizenets" to store authorize.net POST variables. Also add a user_id column to it so that we can reference payment received to the user who has made the payment.

CREATE TABLE IF NOT EXISTS `authorizenets` ( 
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `user_id int(10) unsigned NOT NULL,
  `x_response_code` char(2) NOT NULL,
  `x_response_reason_code` char(2) NOT NULL,
  `x_response_reason_text` varchar(150) NOT NULL,
  `x_avs_code` char(5) NOT NULL,
  `x_auth_code` varchar(150) NOT NULL,
  `x_trans_id` int(10) unsigned NOT NULL,
  `x_method` char(10) NOT NULL,
  `x_card_type` char(15) NOT NULL,
  `x_first_name` varchar(30) NOT NULL,
  `x_last_name` varchar(30) NOT NULL,
  `x_company` varchar(100) NOT NULL,
  `x_address` varchar(60) NOT NULL,
  `x_city` varchar(25) NOT NULL,
  `x_state` varchar(15) NOT NULL,
  `x_zip` varchar(5) NOT NULL,
  `x_country` varchar(150) NOT NULL,
  `x_phone` varchar(18) NOT NULL,
  `x_fax` varchar(18) NOT NULL,
  `x_email` varchar(60) NOT NULL,
  `x_invoice_num` char(15) NOT NULL,
  `x_description` varchar(150) NOT NULL,
  `x_type` varchar(25) NOT NULL,
  `x_cust_id` int(10) unsigned NOT NULL,
  `x_ship_to_first_name` varchar(30) NOT NULL,
  `x_ship_to_last_name` varchar(30) NOT NULL,
  `x_ship_to_company` varchar(100) NOT NULL,
  `x_ship_to_address` varchar(60) NOT NULL,
  `x_ship_to_city` varchar(15) NOT NULL,
  `x_ship_to_state` varchar(15) NOT NULL,
  `al x_ship_to_zip` varchar(5) NOT NULL,
  `x_ship_to_country` varchar(150) NOT NULL,
  `x_amount` decimal(8,2) NOT NULL,
  `x_tax` decimal(6,2) NOT NULL,
  `x_duty` decimal(6,2) NOT NULL,
  `x_freight` decimal(6,2) NOT NULL,
  `x_tax_exempt` varchar(25) NOT NULL,
  `x_po_num` varchar(150) NOT NULL,
  `x_MD5_Hash` varchar(50) NOT NULL,
  `x_cvv2_resp_code` varchar(50) NOT NULL,
  `x_cavv_response` varchar(50) NOT NULL,
  `x_test_request` char(20) NOT NULL,
  `x_method_available` char(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

Now create a plugin using cakePHP bake option.

Log into shell and then locate your app folder
Type in

# cake bake plugin authorizenet.

This should create the authorizenet plugin with the directory structure below.

/app
    /Plugin
        /ContactManager
            /Controller
                /Component
                /AuthorizenetAppController.php
                /AuthorizenetController.php
            /Model
                /Behavior
            /View
                /Helper
                /Layouts

Open your bootstrap.php file located in your app/config folder. Ensure that the Authorizenet plugin is enabled.

CakePlugin::load('Authorizenet', array('bootstrap' => false, 'routes' => false));

In your mysql users table add a column and name it "is_paid" with data type int() and default of 0. When a transaction occurs is_paid will have a value of 1.

Then add this to your AuthorizenetController.php file

<?php
class AuthorizenetController extends AuthorizenetAppController {   
    public $helpers = array('Html', 'Form');

 * beforeFilter makes sure the process is allowed by auth
 *  since authorize.net will need direct access to it.
 */   
    public function beforeFilter(){
        parent::beforeFilter();
        if (isset($this->Auth)) {
            $this->Auth->allow('process');
        }
        
        if (isset($this->Security) && $this->action == 'process') {
          $this->Security->validatePost = false;
          $this->Security->csrfCheck = false;
        }        
    }

    // process the $_POST
    public function process() {    
        $this->autoRender = false;
        $this->log('Process accessed', 'authnet');
        if ($this->request->is('post')) {            
            
            // add to table authorizenets
            $this->loadModel('Authorizenet');
            $_POST['user_id'] = $_POST['x_cust_id'];
            $this->request->data['Authorizenet'] = $_POST;           

            // write to error log or a log file of your choice
            CakeLog::write('error',  print_r($_POST, true));   
            $this->Authorizenet->save($this->request->data);             

            // edit user and record that user has paid
            $this->loadModel('User');
            $this->request->data['User']['id'] = $_POST['x_cust_id'];            
            $this->request->data['User']['is_paid'] = 1;
            $this->User->save($this->request->data);
            
            // Send a text message to yourself to test your script
            //$ms = wordwrap('user with id '.$this->request->data['User']['id'], 40);           
            //mail('YOURPHONENUMBER@vtext.com', '', $ms );       
        } else {
            $this->log('POST Not Validated', 'authnet');
        }
        //return $this->redirect('/');       
    }
}
?>

In your PagesController.php add the following.

<?php
if ($this->params['action'] === 'register') {
            $this->Auth->allow('checkout');
}        

if ($this->params['action'] === 'thankyou') {
      $this->Auth->allow('thankyou');
}
?>

This will ensure that if Auth component is set in you AppController.php file that your checkout and thankyou pages will be viewable by all

We have not yet created the the checkout and thankyou pages. Create them in your View folder and call them checkout.ctp and thankyou.ctp

In you checkout.ctp file add the following code. Change the loginID and transactionKey to those provided to you by authorize.net

<?php
// the parameters for the payment can be configured here
// add your API login and transaction key
$loginID = "YOURLOGINID";
$transactionKey = "YOURTRANSACTIONKEY";

$amount = "99.95";
$description = "Product XYZ";
$testMode = "false";

// user TEST or SECURE url
//$url =  "https://secure.authorize.net/gateway/transact.dll";
$url = "https://test.authorize.net/gateway/transact.dll";<

// an invoice is generated using the date and time
$invoice = date('YmdHis');
// a sequence number is randomly generated
$sequence = rand(1, 1000);
// a timestamp is generated
$timeStamp = time();>

// The following lines generate the SIM fingerprint. PHP versions 5.1.2 and
// newer have the necessary hmac function built in. For older versions, it
// will try to use the mhash library.
if( phpversion() >= '5.1.2' )
{ $fingerprint = hash_hmac("md5", $loginID . "^" . $sequence . "^" . $timeStamp . "^" . $amount . "^", $transactionKey); }
else
{ $fingerprint = bin2hex(mhash(MHASH_MD5, $loginID . "^" . $sequence . "^" . $timeStamp . "^" . $amount . "^", $transactionKey)); }
?>

Add the form elements to your checkout.ctp page as well.

<!-- Create the HTML form containing necessary SIM post values -->
<form method='post' action='<?php echo $url; ?>' >
<!-- Additional fields can be added here as outlined in the SIM integration
guide at: http://developer.authorize.net -->
<input type="hidden" name="x_logo_url" VALUE="YOUR LOGO URL">
<input type="hidden" name="x_cust_id" VALUE="<?php echo $this->Session->read('Auth.User.id'); ?>">
<input type="hidden" name="x_first_name" VALUE="<?php echo $this->Session->read('Auth.User.first_name'); ?>">
<input type="hidden" name="x_last_name" VALUE="<?php echo $this->Session->read('Auth.User.last_name'); ?>">
<input type="hidden" name="x_company" VALUE="<?php echo $this->Session->read('Auth.User.country'); ?>">
<input type="hidden" name="x_address" VALUE="<?php echo $this->Session->read('Auth.User.address'); ?>">
<input type="hidden" name="x_city" VALUE="<?php echo $this->Session->read('Auth.User.city'); ?>">
<input type="hidden" name="x_state" VALUE="<?php echo $this->Session->read('Auth.User.state'); ?>">
<input type="hidden" name="x_zip" VALUE="<?php echo $this->Session->read('Auth.User.zip'); ?>">
<input type="hidden" name="x_phone" VALUE="<?php echo $this->Session->read('Auth.User.phone'); ?>">

<input type='hidden' name='x_login' value='<?php echo $loginID; ?>' />
<input type='hidden' name='x_amount' value='<?php echo $amount; ?>' />
<input type='hidden' name='x_description' value='<?php echo $description; ?>' />
<input type='hidden' name='x_invoice_num' value='<?php echo $invoice; ?>' />
<input type='hidden' name='x_fp_sequence' value='<?php echo $sequence; ?>' />
<input type='hidden' name='x_fp_timestamp' value='<?php echo $timeStamp; ?>' />
<input type='hidden' name='x_fp_hash' value='<?php echo $fingerprint; ?>' />
<input type='hidden' name='x_test_request' value='<?php echo $testMode; ?>' /><

<<input type="hidden" name="x_receipt_link_method" value="LINK" >
<input type='hidden' name='x_receipt_link_url' value='http://YOURWWEBSITE/thankyou' />

<<input type='hidden' name='x_email' value='<?php echo $this->Session->read('Auth.User.email'); ?>' />
<input type='hidden' name='x_email_customer' value='true' />

<input type='hidden' name='x_show_form' value='PAYMENT_FORM' />

<button type="submit" class="btn btn-primary btn-lg"> $<?php echo $amount; ?> PAY NOW</button>
</form>

 Log into your Authorize.net account. If you do not have an account as yet, you can create a sandbox or test account to test your plugin. Once you have logged in, click on setting.

Then click on secret url and enter this url: . Authorize.net will POST the transaction variables to your site usings your secret url which should be  http://www.yoursite.com/authorizenet/authorizenet/process.

Then click on settings, then receipt. Enter your thank you page url. After the transaction is completed authorize.net will direct the users to your thank you page.