Have any of you successfully created a PHP Script that handles PayPal transactions properly? I'd like to set up a subscription system on two of my sites using IPN (Instant Payment Notification), but I don't want it to get messed up on weird transactions. Please let me know!
Yes. I'm not really sure what you mean by "getting messed up on weird transactions", but IPN works fine with PHP. I've been using it for a couple of years without any trouble. A couple of times per year I get a transaction that doesn't come through IPN for a few minutes after the transaction happened, but everything still works fine after the IPN comes through.
I've built an IPN script before and it works, it's just-- I'm not sure I can completely trust it because there's no real way to test all the possible outcomes, you know? I suppose I'm overwhelmed by the IPN doc that lists all the different types of transactions.
When I started I built a log file that would record everything sent. The first thing I would do is to take the entire string the IPN sent and write it out to a log file. That way if something went weird or I encountered a situation I hadn't seen before I could at least go back and read what the IPN sent and then diagnose what happened and why.
I've got a great deal of experience with IPN. It's tough, detailed and hard to troubleshoot. At the same time, it's my favorite processor to code for. Here's a cheat sheet on the different possibilities (weird transactions): In your actual IPN handler, do this: 1. validate the IPN post, maybe use something like this: function validate_ipn($_POST) { $request="cmd=_notify-validate"; while (list($key, $value)=each($_POST)) { $request.="&".$key."=".urlencode(sx($value)); } if (!$fp) { return false; } @fputs($fp, $header.$request); while (!@feof($fp)) { $data=fgets($fp, 1024); if (@strcmp(@$data, "VERIFIED")==0) { @fclose ($fp); return true; } } @fclose ($fp); return false; } PHP: 2. Make sure the $_POST['receiver_email'] matches your paypal ID 3. Check that you were paid in the right currency, maybe use this: 4. Check that the amount paid ($_POST['mc_gross']) matches the amount you expected. 5. Check that the $_POST['txn_id'] isn't already in your database. Many times the posts from paypal are duplicate or come in at unexpected times. If 1-5 passes, your safe to accept the payment! For the actual IPN post, make sure to log the $_POST (addslashes(serialize($_POST))) to somewhere, db or file like tflight mentioned. You can use that data to rebuild the post. This enables you to post directly to your IPN handler just as Paypal would and view the results in your browser, see the example below: <?PHP $data=unserialize(stripslashes('serialized data that you have logged above')); ?> <form action='http://full-url-to-your-ipn-handler.com/ipn-handler.php' method='POST'> <input type='submit' name='Click to Repost the IPN transaction'> <?PHP foreach ($data as $key => $value) { echo '<input type="hidden" name="'.$key.'" value="'.$value.'" />'; echo "\n"; } ?> </form> PHP: Hope that helps! - Andy
Wow, that is outstanding man. That's really helpful. Thank you very much. I do have another question though- what do you do for multiple sites since paypal only allows you to specify one host for IPN?
Do this: 1. Login to your paypal account 2. Click "Profile" 3. Under "Selling Preferences" click "Instant Payment Notification Preferences" 4. Make sure IPN is set to On and leave the "Instant Payment Notification (IPN) URL" blank Now you can pass in the URL to the IPN handler dynamically using the key "notify_url" in your post to paypal. <input type='hidden' name='notify_url' value='http://your-domain.com/ipn-handler.php' />
Websites Payment Pro or Standard? I mean, which one works better for simple subscription handling and the like?