Paypal IPN (Instant Payment Notification) plugin complete with PaypalHelper

by webtechnick
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.
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.


Paypal IPN plugin. (Paypal Instant Payment Notification)
Version 1.4
Author: Nick Baker (nick@webtechnick.com)

Website: http://www.webtechnick.com

Browse, Download, or Checkout the Plugin.
Browse: http://projects.webtechnick.com/paypal_ipn
Download: http://projects.webtechnick.com/paypal_ipn.tar.gz
SVN: https://svn2.xp-dev.com/svn/nurvzy-paypal-ipn

I suggest reading the README.txt file included within the plugin. Installation is very straight forward.

Install:
1) Copy plugin into your /app/plugins/paypal_ipn directory
2) Run the /plugins/paypal_ipn/paypal_ipn.sql in your database.
3) Add the following into your /app/config/routes.php file (optional):

Controller Class:

<?php 
  
/* Paypal IPN plugin */
  
Router::connect('/paypal_ipn/process', array('plugin' => 'paypal_ipn''controller' => 'instant_payment_notifications''action' => 'process'));
  
  
/* Optional Routes, but nice for administration */
  
Router::connect('/paypal_ipn/edit/:id', array('admin' => true'plugin' => 'paypal_ipn''controller' => 'instant_payment_notifications''action' => 'edit'), array('id' => '[a-zA-Z0-9\-]+''pass' => array('id')));
  
Router::connect('/paypal_ipn/view/:id', array('admin' => true'plugin' => 'paypal_ipn''controller' => 'instant_payment_notifications''action' => 'view'), array('id' => '[a-zA-Z0-9\-]+''pass' => array('id')));
  
Router::connect('/paypal_ipn/delete/:id', array('admin' => true'plugin' => 'paypal_ipn''controller' => 'instant_payment_notifications''action' => 'delete'), array('id' => '[a-zA-Z0-9\-]+''pass' => array('id')));
  
Router::connect('/paypal_ipn/add', array('admin' => true'plugin' => 'paypal_ipn''controller' => 'instant_payment_notifications''action' => 'edit'));
  
Router::connect('/paypal_ipn', array('admin' => true'plugin' => 'paypal_ipn''controller' => 'instant_payment_notifications''action' => 'index'));/*
  /* End Paypal IPN plugin */
?>

Paypal Setup:
1) I suggest you start a sandbox account at https://developer.paypal.com
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 http://www.yoursite.com/paypal_ipn


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:

Controller Class:

<?php 
       
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);
Examples:

View Template:


<?php
//Pay Now Button
echo $paypal->button('Pay Now', array('amount' => '12.00''item_name' => 'test item'));
//Pay Now Button with Image
echo $paypal->button('pay_now.jpg', array('amount' => '12.00''item_name' => 'test item'));

//Subscribe Button
echo $paypal->button('Subscribe', array('type' => 'subscribe''amount' => '60.00''term' => 'month''period' => '2'));

//Donate Button
echo $paypal->button('Donate', array('type' => 'donate''amount' => '60.00'));

//Add To Cart
echo $paypal->button('Add To Cart', array('type' => 'addtocart''amount' => '15.00'));
?>

You can seamlessly switch to your testing account by adding 'test' as an option key.
Test Example:

View Template:

<?php echo $paypal->button('Pay Now', array('test' => true'amount' => '12.00''item_name' => 'test item')); ?> You can also add any other valid PayPal element into the button options.
Example:

View Template:

<?php echo $paypal->button('Pay Now', array('amount' => '12.00''item_name' => 'Stuff''return' => 'http://www.yoursite.com/thankyou')); ?> Refer to PayPal.com for a complete list of button name-value pair elements you can use in your buttons.


Paypal Button:
1) Use the PaypalHelper to generate your buttons for you. See Paypal Button Helper (above) for more.
- or -
2) Make sure to use notify_url set to http://www.yoursite.com/paypal_ipn/process in your paypal button.
Example:

View Template:


<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
  ...
  ...  
  <input type="hidden" name="notify_url" value="http://www.yoursite.com/paypal_ipn/process" />
  ...
</form>


After Paypal Notification Callback:
After a notification is sent to your app, it is saved to your database and an afterPaypalNotification is called (if it exists). Here is where you can add logic to your app to do something with that specific payment.

1) Create a function in your /app/app_controller.php like so:

Controller Class:

<?php 
  
function afterPaypalNotification($txnId){
    
//Here is where you can implement code to apply the transaction to your app.
    //for example, you could now mark an order as paid, a subscription, or give the user premium access.
    //retrieve the transaction using the txnId passed and apply whatever logic your site needs.
    
    
$transaction ClassRegistry::init('PaypalIpn.InstantPaymentNotification')->findById($txnId);
    
$this->log($transaction['InstantPaymentNotification']['id'], 'paypal');

    
//Tip: be sure to check the payment_status is complete because failure transactions 
    //     are also saved to your database for review.

    
if($transaction['InstantPaymentNotification']['payment_status'] == 'Completed'){
      
//Yay!  We have monies!
    
}
    else {
      
//Oh no, better look at this transaction to determine what to do; like email a decline letter.
    
}
  }
?>

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

Report

More on Plugins

Advertising

Comments

  • Stinkbug posted on 01/29/11 11:02:03 AM
    I had to make a change before it seemed to work for me. I didn't verify it, but mine didn't work until I made this change and passed the $newData variable back to paypal for verification.

    $newData['cmd'] = '_notify-validate';
    foreach ($data AS $key => $val) {
    $newData[$key] = $val;
    }

    I don't think the _notify-validate was getting added to the beginning of the paramaters. I didn't verify that, but it didn't work until I made this change.
  • lutskovp posted on 12/31/10 10:46:51 PM
    First, thank you for a very well-developed contribution. The last time I tried implementing IPN into a CakePHP app (about two years ago), things were nowhere near the quality of your code. I'm not sure if dev environment situation is unique, but it's presenting me some challenges in implementing your plugin. I wonder if I could ask for your thoughts on the following issues I'm trying to resolve.

    I have 3 separate environments (local, qa, production) where my application lives. My local environment serves the app through IIS (7.5 on Win7) whereas the QA and production versions are run off a pure LAMP stack. Naturally, QA and local environments use a debug level of 2 while production is set to the production default of 0. The plugin routing works great in my local and QA environment but fails with a 404 error in production. The only difference between QA and production is the debug level. Local has the added IIS-specific bonus of using App.baseUrl instead of default routing with mod_rewrite help.

    Despite using the recommended routes from the latest README file, my production site continues to issue 404 errors when accessing paypal_ipn urls. Even the default CakePHP plugin urls fail (/plugin/controller/method). If you have any thoughts on debugging this issue (I've tried a few things, dug into Router a bit, tried to do custom error handling, etc), I would very much appreciate it.

    Again, thank you for your contribution. I'll keep working on this issue and if I find a solution before I hear back, I'll update this thread.

    - Paul
  • WhyNotSmile posted on 12/24/10 11:49:56 AM
    This plugin is great, but how do I get it to redirect to my site after processing?

    Currently, it will accept the payment, and the payment gets processed ok, but nothing goes in the database, and then it just shows the standard PayPal 'Thank You' screen - there's no button to go back to my site, and it doesn't do it automatically.

    What I'd like to happen is for it to accept the payment, and then return to my site to say 'thank you' there; meanwhile, I want to set the order to 'complete', and trigger a few emails.

    I've set

    'notify_url' => 'http://www.mysite.co.uk/paypal_ipn/process',

    in the config file, and enabled IPN in my paypal account. As I say, it's not even saving anything to the database. What else do I need to do?

    When I use the test IPN tool on PayPal, it says it has worked.

    For changing the order to 'complete' and so on, do I do that in 'afterPaypalNotification' in app_controller? I know how to do it, just not sure where.

    Thanks!
  • WhyNotSmile posted on 12/24/10 10:54:21 AM
    Thank you for this plugin - it's really excellent. I'm using Cake 1.3, and it just slotted in and basically worked! Only issue I had is that in one of the controllers, it had $name="InstantPayPalNotifications" - with an s on the end. That gave some weird errors, but was resolved by making it singular.

    Thanks again.
  • bendo01 posted on 05/08/10 05:07:47 PM
    is it compatible with cake 1.3 stable version ?
  • lakum4cakephp posted on 04/08/10 03:26:59 AM
    I have written this code in my ctp file.

    echo $paypal->button('Pay Now', array('test'=>true, 'amount' => '20.00', 'item_name' => 'User Upgrade'));

    And also given notify_url in paypal_ipn/config/paypal_ipn_config.php , but when I complete the payment using my paypal sandbox account, it shows the "Test, thank you for your payment" page but don't getting payment data in database. The code is as it is you have given here.
    • bubuzzz posted on 12/08/10 04:29:59 PM
      [quote] I have written this code in my ctp file.

      echo $paypal->button('Pay Now', array('test'=>true, 'amount' => '20.00', 'item_name' => 'User Upgrade'));

      And also given notify_url in paypal_ipn/config/paypal_ipn_config.php , but when I complete the payment using my paypal sandbox account, it shows the "Test, thank you for your payment" page but don't getting payment data in database. The code is as it is you have given here.
      [end quote]


      I cannot either. Has anyone solved this ?
  • joebob posted on 01/09/10 09:01:29 PM
    Your paypal plugin is greatly appreciated! I've only been toying with it in the sandbox for about an hour, but it's been working smoothly so far.

    Thanks again!
  • saschaappel posted on 01/03/10 01:09:21 PM
    Hi

    How do you validate a user befor and after the transaction?
    More details:
    If a user press the "Bay now" button do you add some id, or how do you now if you get the call back from paypal that this user has executed the transaction?


  • webtechnick posted on 11/06/09 01:09:27 AM
    I've made more improvements to paypal_ipn with the uploading of cart inspiration.

    Multiple Items
    -------------------
    By doing an update to the latest version you'll now need to migrate your databased to the newest release via this command:

    cake schema run create -path plugins/paypal_ipn/config/sql -name items
    With this, you'll now have access to all the items, tax, shipping, etc details for each paypal item a customer purchases via the paypal cart.

    This is useful for making paypal your full featured cart/merchant service.

    -------
    Single items, Subscriptions, and Donations work just as they did before.
  • webtechnick posted on 11/05/09 04:12:39 AM
    I've gone ahead and implemented a multi item cart feature to the paypal helper with the help of the guide I found in my previous comment.

    You can download the latest version from my website: http://projects.webtechnick.com/paypal_ipn.tar.gz

    Or you can checkout/update via my svn
    svn co http://svn2.xp-dev.com/svn/nurvzy-paypal-ipn paypal_ipn
    Example usage:

    PHP Snippet:

    <?php 
    echo $paypal->button('Checkout', array(
      
    'type' => 'cart',
      
    'items' => array(
        array(
    'item_name' => 'Item 1''amount' => '120''quantity' => 2'item_number' => '1234'),
        array(
    'item_name' => 'Item 2''amount' => '50'),
        array(
    'item_name' => 'Item 3''amount' => '80''quantity' => 3),
      )
    ));
    ?>

    You can review my API at: http://projects.webtechnick.com/docs/paypal_ipn

    Read more about the changes in v3.5 here: http://www.webtechnick.com/blogs/view/225/Paypal_IPN_Plugin_v3_5_Email_and_Multi_Items

    Thanks for the inspiration,
    Nick
    • creambun posted on 08/03/10 03:02:34 PM
      Hello, I'd like to create "Subscription" cart.
      Does it possible ??

      I tried like below, but it does not work.

      please help me.

      PHP Snippet:

      <?php 
      echo $paypal->button('Checkout', array( 
        
      'type' => 'cart'
        
      'items' => array( 
          array(
      'type' => 'subscribe''amount' => '500.00''term' => 'month''period' => '3'), 
          array(
      'type' => 'subscribe''amount' => '600.00''term' => 'month''period' => '2'), 
          array(
      'type' => 'subscribe''amount' => '700.00''term' => 'month''period' => '1'), 
        ) 
      ));
      ?>
  • webtechnick posted on 11/05/09 03:39:01 AM
    You'll need to refer to paypal in order to do what you're looking for.

    I've done the digging for you: https://cms.paypal.com/us/cgi-bin/?&cmd=_render-content&content_ID=developer/e_howto_html_cart_upload
    Currently the paypal helper including with my plugin doesn't handle cart uploads but it looks pretty simple to implement in a future release. I'll add that to the 'wish list'.

    For now, you'll need to do what you want by hand. The link above is a pretty good tutorial on how to upload an existing cart into a paypal cart for purchasing. As I said before, just make sure to set the 'notify_url' name in the form somewhere and you should be all set.

    Hope that helps,
    Nick
  • webtechnick posted on 11/04/09 11:05:00 PM
    I'm not sure what you mean by multi item. The helper will build a complete form pointing to paypal live or sandbox with the options you pass into it along with all the defaults you specify in config/paypal_ipn_config.php.

    The paypal helper is completely optional, the plugin will process the IPNs for you if you choose to use the helper, do it all by hand, or build your buttons via the paypal web developer's toolkit.

    If you're not going to use the helper, just make sure you have 'notify_url' set in your html form somewhere like so:
    <input type="hidden" name="notify_url" value="http://www.yoursite.com/paypal_ipn/process" />
    You can even tell your paypal account to always send IPN data to a specific URL no matter where the payment came from. By doing that you can skip all the notify_url steps.

    As long as you somewhere tell paypal to send back IPN data to the process action in the plugin, the plugin will receive, parse, log, and execute any logic in your afterPaypalNotification callback function for you.

    The helper is just a convenience, use whatever you're comfortable with.

    Hope that helps,
    Nick
    • koceng posted on 11/04/09 11:32:39 PM
      I'm sorry if I waste your time :P

      how I use the "$paypal->button();" if the item more than one?

      there an invoice to confirm so I send all data item at that invoice and the paypal can count the all price. so not one button for one item.

      if I use html form, the target site not to paypal transaction site like an always.

      Thanks,
      johan
  • koceng posted on 11/04/09 10:32:38 PM
    hello nick,

    I have a problem if I send multi item to paypal.

    I use $paypal->button(); to send the data.

    if I use Html form there are problem when the data send.

    will the plugin knowing if I use html form??



    johan
  • koceng posted on 11/04/09 12:22:44 AM
    thanks nick

    I hope this gonna work to my code.. :P



    johan
  • webtechnick posted on 11/03/09 10:04:54 PM
  • koceng posted on 11/03/09 08:39:30 PM
    I don't have the plugin...where I can get the plugin?

    please help me...

    thanks

    johan
  • webtechnick posted on 10/02/09 10:39:15 AM
    I think I understand your question, let me know if I'm way off base.

    The configuration is completely optional and is only for the paypal helper included with this plugin. This plugin will handle IPN data for you automatically -- as long as you point paypal to use 'notify_url' to your process action. I've included the helper to go along with the plugin so that all your paypal buttons will direct to your paypal process action, but you don't have to use the paypal helper if you don't want to. If you don't use the helper, you'll need to follow the paypal IPN manual from your paypal account and direct any ipn data postback from paypal to the plugin's process action which will take the data, verify it, and then save it to your database.

    Configuration Location:
    /paypal_ipn/config/paypal_ipn_config.php

    In the config file there are two arrays -- settings, and test_settings. You'll need to update these options so you don't have to pass them into the helper each time.


    /************
        * Each settings key coresponds to the Paypal API.  Review www.paypal.com for more. 
        */
    var $settings = array(
        'business' => 'live_email@paypal.com', //Your Paypal email account
        'server' => 'https://www.paypal.com', //Main paypal server.
        'notify_url' => 'http://www.yoursite.com/paypal_ipn/process', //Set this to the process path of your paypal_ipn::instant_payment_notification::process action
        'currency_code' => 'USD', //Currency
        'lc' => 'US', //Locality
        'item_name' => 'Paypal_IPN', //Default item name.
        'amount' => '15.00' //Default item amount.
      );

    You'll need to update/configure each setting key=>value pair to your own liking. I suggest in the very least updating 'business' with your paypal email and 'notify_url' with the full URL to your paypal_ipn::process action (as specified in the article). That way you wont have to specify those options in the options array whenever you call $paypal->button();

    You can even add more key value pairs as specified by the paypal API, review paypal.com for more.

    I hope that helps,
    Nick
  • vanduongsuper posted on 10/01/09 11:36:32 PM
    Hello Nick Baker,

    I just see config for admin area, not for IPN data. When paypal return a data, which is file configured for save data into mysql?
  • webtechnick posted on 09/30/09 09:58:06 PM
    You can't use the https repository link I have in the article, you must use:

    svn co http://svn2.xp-dev.com/svn/nurvzy-paypal-ipn/
    It's public, I was able to do an anon checkout just now.

    If you're still having problems let me know.
    • rynop posted on 09/30/09 10:04:24 PM
      You can't use the https repository link I have in the article, you must use:

      svn co http://svn2.xp-dev.com/svn/nurvzy-paypal-ipn/
      It's public, I was able to do an anon checkout just now.

      If you're still having problems let me know.

      My bad dude - I read your previous posts wrong. It works. sorry to waste ur time.
  • rynop posted on 09/30/09 09:27:16 PM
    Nick - I am unable to do an SVN checkout as its prompting me for username/password. Do you have an anon user?
  • webtechnick posted on 09/23/09 05:14:40 AM
    xp-dev.com no longer offers SSL for their free users. The SVN repo can only be accessed via http.

    NEW SVN: http://svn2.xp-dev.com/svn/nurvzy-paypal-ipn
    If you've currently checked out this plugin you can use svn switch to change the repo to get the latest updates.

    svn switch --relocate https://svn2.xp-dev.com/svn/nurvzy-paypal-ipn  http://svn2.xp-dev.com/svn/nurvzy-paypal-ipn 
    If you have any problems, let me know.
  • webtechnick posted on 09/15/09 10:29:54 PM
    The setup should look like:

    $ cd app/plugins/paypal_ipn
    $ ls
    config/
    controllers/
    models/
    paypal_ipn_app_controller.php
    paypal_ipn_app_model.php
    paypal_ipn.sql
    README.txt
    views/


    Make sure you have the database setup the way I've described above.

    If you installed the app via svn, I recommend doing an svn update to get the latest version which I've just released that includes a schema that will create the required table for you via a cake schema run command.

    cake schema run create -path plugins/paypal_ipn/config/sql -name ipn
    That will drop and create the required database.

    I hope that helps,
    Nick
  • WidePixels posted on 09/15/09 10:03:10 PM
    I followed your instructions but get
    Error: The requested address '/admin/paypal_ipn' was not found on this server. or if i go directly to site.com/paypal_ipn i get:
    Fatal error: Call to undefined function loadmodel() in /cake/libs/model/db_acl.php on line 114
    Set up as:
    plugins/
    /paypal_ipn
    /config
    /controllers
    /models
    /views
    paypal..controller.php
    paypal..model.php

    Copied your routes...tried a few variations but keep gettingthe same error. Ideas where I may have gone wrong?
  • webtechnick posted on 08/26/09 03:19:39 PM
    As was discussed in the IRC I'd be happy to be of any assistance.
  • ProLoser posted on 08/21/09 03:49:07 AM
    Trying to get several people to contribute to a new official unofficial shopping cart plugin. I have spent a long time discussing with people the best way to standardize shopping cart features and one major resolution we came up with is putting all payment gateways into datasources and making standardized access to them via 1 payment_gateway behavior that attaches to whatever product model(s) of their choosing.

    It looked like your code would benefit from being packaged in that way. Think you'd be interested in discussing a good standard that more developers can start to work with? We have a small and slowly growing channel: #cakephp-cupcakes if you want to stop by and help us develop some of the pieces to the plugin.

    I'm gonna try merging your code myself, it looks very clean and straightforwards, however if you wish to help out you'd probably know how to refactor it faster.
  • webtechnick posted on 08/13/09 05:59:33 PM
    Very slick! Learn something new everyday. I still prefer long descriptive names and just using routes, but that's very neat. Thanks for the tip. =)

  • utoxin posted on 08/13/09 12:37:31 PM
    However, renaming the controller to PaypalIpnController may not give you what you think without a custom route; you would have navigate to /paypal_ipn/paypal_ipn/:action/:id (once for plugin, once for controller) which just reads odd.

    Actually, as long as you don't have a controller in your app called 'PaypalIpn', you don't have to double up the URL like that. If Cake doesn't find a controller named PaypalIpn, and it sees a plugin called that, it will automatically load the plugin controller with the same name.
  • mhuggins posted on 08/11/09 05:37:13 PM
    Cool, I'm definitely going to have to check this out. One immediate thought from glancing over it though, why not just name the controller "PaypalIpnController" (paypal_ipn_controller.php)? That way you can avoid all the nasty custom routes.
    • webtechnick posted on 08/11/09 05:55:37 PM
      Cool, I'm definitely going to have to check this out. One immediate thought from glancing over it though, why not just name the controller "PaypalIpnController" (paypal_ipn_controller.php)? That way you can avoid all the nasty custom routes.
      Hi, well those routes are optional. I put them in the article because I know most people would find it useful. However I named that way because I have a poor memory and personally like long descriptive names.

      However, renaming the controller to PaypalIpnController may not give you what you think without a custom route; you would have navigate to /paypal_ipn/paypal_ipn/:action/:id (once for plugin, once for controller) which just reads odd.

      Arguably one might rename the plugin 'paypal' and the controller 'IpnController' so the url would be /paypal/ipn/:action/:id which looks clean but as I said earlier, long descriptive names are my personal flavor. However, I also realize most people don't like long names. Thus, I added an example of custom routes for users to use if they so desire.

      Another easier way you might like is:
      Router::connect('/paypal_ipn/:action/*', array('admin' => 'true', 'plugin' => 'paypal_ipn', 'controller' => 'instant_payment_notifications', 'action' => 'index'));
      Which would combine all the "nasty routes" into one aliased route.

      Routes are cool. =)
  • ADmad posted on 08/05/09 02:14:09 PM
    1) Apologies, i didn't realize the 'test_ipn' was in the data posted by paypal

    2) Currently support for datasources in plugins isn't good enough so i see your point.

    We discussed things on IRC but just wanted to put short comments here for easy reference.
  • webtechnick posted on 08/04/09 11:36:40 AM
    Hi, Thanks again for your feedback. However I have to disagree this time.

    1) The $data['test_ipn'] is sent from the paypal call back, not from the user. Paypal automatically sends a key ['test_ipn'] => 1 if the transaction occured on its sandbox server. It has nothing to do with the user setting an option in the data that is passed to isValid. In my plugin you'll find the data passed to the datasource is purely $_POST, nothing more -- and it will work with both the test and live automatically.

    2) Datasources in Plugins are poorly implemented. I tried implementing it the normal way (like the link provided) but that wouldn't work. To get a datasource to work in a plugin I had to take inspiration from matt curry:
    http://www.pseudocoder.com/archives/2009/02/10/yahoo-search-boss-as-a-cakephp-plugin/
    Matt had to import the file directly. But again, Matt Curry needed a config passed into the datasource, I do not, as all the data needed to validate is given to me by paypal. I don't need credentials, I don't need the user to specify if its test or not, Paypal does all that work for me. All I needed is to import the file manually, because CM doesn't handle plugin datasources, instantiate it, and call the isValid method with the $_POST paypal gave me. Which is what I've done in the cleanest way I know how.

    If there's a cleaner way to do it I'm all ears but the link you provided me is great for normal datasources, but doesn't seem to apply to Plugin-Datasources. I'll be hanging around the IRC.

    Once again, thank you for all your time and feedback.
  • ADmad posted on 08/04/09 10:08:19 AM
    Your implementation of datasource and its usage still needs some work. The selection of sandbox or live url should be done using config array not passed as key in param to the isValid function. Also how you use the ds in your model is incorrect. Please see this as an example of proper datasource implementation and usage. http://github.com/felixge/debuggable-scraps/blob/3fbfca1bd3205e78aac80414bb8e8556a40496ae/cakephp/datasources/akismet/readme.textile

    Please contact me or another experienced user on irc if you need more help.
  • ADmad posted on 08/02/09 04:56:22 PM
    I am sorry if my earlier comment was a bit ambigious. I didn't mean that you don't need the controller at all. I am aware that paypal IPN is a service where paypal POSTs data to a url of your choice, so you do need a controller and action for that. Now in order to verify that data you have to POST it back to paypal and check the response returned. That part should be handled by the M layer not C. I see that you have now moved that part to a model but in cakephp the most appropriate class for implementing a webservices interface is datasource and hence i suggest making a datasource for it and have a model on top of it. Also your code will look cleaner if you use cake's HttpSocket core lib.
    • webtechnick posted on 08/03/09 01:00:34 AM
      I am sorry if my earlier comment was a bit ambigious. I didn't mean that you don't need the controller at all. I am aware that paypal IPN is a service where paypal POSTs data to a url of your choice, so you do need a controller and action for that. Now in order to verify that data you have to POST it back to paypal and check the response returned. That part should be handled by the M layer not C. I see that you have now moved that part to a model but in cakephp the most appropriate class for implementing a webservices interface is datasource and hence i suggest making a datasource for it and have a model on top of it. Also your code will look cleaner if you use cake's HttpSocket core lib.
      Hi, Thanks again for your feedback.

      Ahh, yes, thank you for explaining. I agree. I've followed all your suggestions. I've created a datasource for the verification post-back and now utilize the HttpSocket core lib -- which does indeed make the code MUCH cleaner. Thank you again for your feedback.

      I hope these updates are to your satisfaction.

      Thanks,
      Nick
  • ADmad posted on 07/18/09 01:39:49 PM
    Thank you for your contribution but web services should be ideally accessed using a datasource. So the part where you post transaction data to paypal and get response should be in a datasource not a controller action. The bakery already has a datasource for paypal nvp api so please look at that and others for inspiration.
    • webtechnick posted on 07/22/09 05:50:45 PM
      Thank you for your contribution but web services should be ideally accessed using a datasource. So the part where you post transaction data to paypal and get response should be in a datasource not a controller action. The bakery already has a datasource for paypal nvp api so please look at that and others for inspiration.
      Thank you for your feedback. You may or may not be familiar with the Instant Payment Notification service paypal offers. It's not an api in which I can use to gain information, rather its a url callback that paypal will send POST data to upon a successful transaction. That callback needs to access your cakePHP app from an outside source. A controller action is exactly where it belongs.

      The paypal nvp api service is completely different than the paypal IPN service. The paypal NVP api allows a user to directly access and make payments to a paypal account withough actually going to the paypal site. The NVP api is NOT free. A user is required to use SSL and pay a monthly fee to use this service live in paypal.

      However, the IPN is a free service offered by paypal for users who don't mind the flow of payment jumping from their site to paypals. After completion paypal notifies your app of the payment. This plugin handles that notification the best way possible.

      IRC discussion: http://irc.cakephp.org/logs/link/908711#message908721

      Update: I've updated the plugin to be of fat-model-skinny-controller paradigm.
login to post a comment.