Google Ad

CakePHP Paypal IPN Plugin

Date: Sat, Jul 11th 2009, 00:00 Author: nick Views: 53747 Comments share

CakePHP Paypal IPN Plugin

Get it:
  • Download Now
  • git clone git://
I've created a PayPal IPN (Instant Payment Notification) plugin that includes a handy helper that will build your paypal buttons for you (Checkout, Add to Cart, Subscribe, and Donate). The Paypal IPN Plugin logs, and records any transaction made through your application and is completely customizable via its config and on the fly options. The Plugin is also very simple to switch between sandbox/live paypal.

EDIT: This plugin has been updated to 1.3 and 2.x. For 2.x instructions please visit the github source:

The biggest benefit to using the PayPal IPN plugin is that it doesn't require a Website Payment Pro account (monthly charge) to use like the other PayPal implementations in the bakery. The IPN service is free from paypal; you simply have to enable it. Whenever paypal receives a transaction (complete or failure) your app will be notified.

This plugin will process Instant Payment Notifications sent from paypal, log it, and save a record in your database. The plugin provides an afterPaypalNotification callback you can use to apply post transaction logic to your application (set an order to paid, give a user premium access, etc...). This plugin also features a Paypal Helper to create various buttons to use with your paypal IPN service. I hope you find it useful.

Install and Setup

1) Copy plugin into your /app/plugins/paypal_ipn directory
2a) Run the /plugins/paypal_ipn/paypal_ipn.sql in your database.
2b) run
  1. cake schema run create -path plugins/paypal_ipn/config/sql -name ipn
3) Add the following into your /app/config/routes.php file (optional):
  1. /* Optional Routes, but nice */
  2. Router::connect('/paypal_ipn/process', array('plugin' => 'paypal_ipn', 'controller' => 'instant_payment_notifications', 'action' => 'process'));
  3. Router::connect('/paypal_ipn/:action/*', array('admin' => 'true', 'plugin' => 'paypal_ipn', 'controller' => 'instant_payment_notifications', 'action' => 'index'));
  4. /* End Paypal IPN plugin */

Paypal Setup: 1) I suggest you start a sandbox account at 2) Enable IPN in your account.

Administration: (optional) If you want to use the built in admin access to IPNs:
1) Make sure you're logged in as an Administrator via the Auth component.
2) Navigate to

Paypal Button Helper:

(optional) if you plan on using the paypal helper for your PayNow or Subscribe Buttons
1) Update /paypal_ipn/config/paypal_ipn_config.php with your paypal information
2) Add 'PaypalIpn.Paypal' to your helpers list in app_controller.php:
  1. var $helpers = array('Html','Form','PaypalIpn.Paypal');
3) Usage: (view the actual /paypal_ipn/views/helpers/paypal.php for more information)
$paypal->button(String tittle, Options array);
  1. //Pay Now Button
  2. $paypal->button('Pay Now', array('amount' => '12.00', 'item_name' => 'test item'));
  4. //Subscribe Button
  5. $paypal->button('Subscribe', array('type' => 'subscribe', 'amount' => '60.00', 'term' => 'month', 'period' => '2'));
  6. //Unsubscribe Button
  7. $paypal->button('Unsubscribe', array('type' => 'unsubscribe'));
  9. //Donate Button
  10. $paypal->button('Donate', array('type' => 'donate', 'amount' => '60.00'));
  12. //Add To Cart
  13. $paypal->button('Add To Cart', array('type' => 'addtocart', 'amount' => '15.00'));
  15. //Multi Item Cart for Checkout.
  16. $paypal->button('Checkout', array(
  17.   'type' => 'cart',
  18.   'items' => array(
  19.     array('item_name' => 'Item 1', 'amount' => '120', 'quantity' => 2, 'item_number' => '1234'),
  20.     array('item_name' => 'Item 2', 'amount' => '50'),
  21.     array('item_name' => 'Item 3', 'amount' => '80', 'quantity' => 3),
  22.   )
  23. ));

You can seamlessly switch to your testing account by adding 'test' as an option key.
Test Example:
  1. $paypal->button('Pay Now', array('test' => true, 'amount' => '12.00', 'item_name' => 'test item'));

If you'd rather not use the paypal button helper all you'll need to do is make sure you set the 'notify_url' to the plugin's process action.

Paypal Notification Callback:

1) create a function in your /app/app_controller.php like so:
  1. function afterPaypalNotification($txnId){
  2.   //Here is where you can implement code to apply the transaction to your app.
  3.   //for example, you could now mark an order as paid, a subscription, or give the user premium access.
  4.   //retrieve the transaction using the txnId passed and apply whatever logic your site needs.
  5.   $IPN = ClassRegistry::init('PaypalIpn.InstantPaymentNotification');
  6.   $transaction = $IPN->findById($txnId);
  7.     $this->log($transaction['InstantPaymentNotification']['id'], 'paypal');
  9.   //Tip: be sure to check the payment_status is complete because failure
  10.   //     are also saved to your database for review.
  12.   if($transaction['InstantPaymentNotification']['payment_status'] == 'Completed'){
  13.     //Yay!  We have monies!
  14.     $IPN->email(array(
  15.       'id' => $txnId,
  16.       'message' => 'Thank you for your payment'
  17.     ));
  18.   }
  19.   else {
  20.     //Oh no, better look at this transaction to determine what to do; like email a decline letter.
  21.    $IPN->email(array(
  22.       'id' => $txnId,
  23.       'message' => 'Your transaction was declined.'
  24.     ));
  25.   }
  26. }

Basic Email *NEW*

Paypal IPN Plugin comes with a utility email method that is useful for shotting off quick emails tailored to a specific transaction. The email function works off an specific Paypal IPN transaction, pulling the to and from field from its payer_email and business columns. This is useful for sending quick thank you messages or declines.

The usage of this method is pretty basic. Here are some examples of its use:
  1. $IPN = ClassRegistry::init('PaypalIpn.InstantPaymentNotification');
  3. //You can pass in just text and it will send the message
  4. //make sure to set the id first before you attempt the send
  5. //or it won't know where you want to send it.
  6. $IPN->id = '4aeca923-4f4c-49ec-a3af-73d3405bef47';
  7. $IPN->email('Thank you for your transaction!');
  9. //You can pass in multiple options in as an associative array
  10. $IPN->email(array(
  11.   'id' => '4aeca923-4f4c-49ec-a3af-73d3405bef47',
  12.   'subject' => 'Donation Complete!',
  13.   'message' => 'Thank you for your donation!',
  14.   'sendAs' => 'text'
  15. ));

The full list of options is the same options available to the native Email component plus a few extras. Here is the full list of options available to the InstantPaypalNotification::email()

Email Options

  • id: id of instant payment notification to base email off of
  • subject: subject of email (default: Thank you for your paypal transaction)
  • sendAs: html | text (default: html)
  • to: email address to send email to (default: ipn payer_email)
  • from: from email address (default: ipn business)
  • cc: array of email addresses to carbon copy to (default: array())
  • bcc: array of email addresses to blind carbon copy to (default: array())
  • layout: layout of email to send (default: default)
  • template: template of email to send (default: null)
  • log: boolean true | false if you'd like to log the email being sent. (default: true)
  • message: actual body of message to be sent (default: null)

I also suggest you take a look at the API for more:

I hope you find this plugin useful. Please, if you like the plugin, find a bug, or have a feature request, post a comment. =)