Mutley Posted December 16, 2007 Share Posted December 16, 2007 When a user wishes to purchase a "Premium" account on my website I wish them to get special access/privileges over other users. So when they hit the Paypal button and complete the purchase, how do I make sure it updates the database for that user? I've seen on Paypal their is a "Return Page" you can do but this can easily be seen in the source, so any user can bypass the payment I don't know how I can check they've paid or not? Any ideas? Thanks. Quote Link to comment Share on other sites More sharing options...
marcus Posted December 16, 2007 Share Posted December 16, 2007 Use IPN Quote Link to comment Share on other sites More sharing options...
Mutley Posted December 16, 2007 Author Share Posted December 16, 2007 Thanks, I've tried looking into it but doesn't seem too well explained. So I turned IPN on and set the URL to the file which contains: <?php // Read the post from PayPal system and add 'cmd' $req = 'cmd=_notify-validate'; foreach ($_POST as $key => $value) { $value = urlencode(stripslashes($value)); $req .= "&$key=$value"; } // Post back to PayPal system to validate $header = "POST /cgi-bin/webscr HTTP/1.0\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . strlen($req) . "\r\n\r\n"; $fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30); // Assign posted variables to local variables $item_name = $_POST['item_name']; $business = $_POST['business']; $item_number = $_POST['item_number']; $payment_status = $_POST['payment_status']; $mc_gross = $_POST['mc_gross']; $payment_currency = $_POST['mc_currency']; $txn_id = $_POST['txn_id']; $receiver_email = $_POST['receiver_email']; $receiver_id = $_POST['receiver_id']; $quantity = $_POST['quantity']; $num_cart_items = $_POST['num_cart_items']; $payment_date = $_POST['payment_date']; $first_name = $_POST['first_name']; $last_name = $_POST['last_name']; $payment_type = $_POST['payment_type']; $payment_status = $_POST['payment_status']; $payment_gross = $_POST['payment_gross']; $payment_fee = $_POST['payment_fee']; $settle_amount = $_POST['settle_amount']; $memo = $_POST['memo']; $payer_email = $_POST['payer_email']; $txn_type = $_POST['txn_type']; $payer_status = $_POST['payer_status']; $address_street = $_POST['address_street']; $address_city = $_POST['address_city']; $address_state = $_POST['address_state']; $address_zip = $_POST['address_zip']; $address_country = $_POST['address_country']; $address_status = $_POST['address_status']; $item_number = $_POST['item_number']; $tax = $_POST['tax']; $option_name1 = $_POST['option_name1']; $option_selection1 = $_POST['option_selection1']; $option_name2 = $_POST['option_name2']; $option_selection2 = $_POST['option_selection2']; $for_auction = $_POST['for_auction']; $invoice = $_POST['invoice']; $custom = $_POST['custom']; $notify_version = $_POST['notify_version']; $verify_sign = $_POST['verify_sign']; $payer_business_name = $_POST['payer_business_name']; $payer_id =$_POST['payer_id']; $mc_currency = $_POST['mc_currency']; $mc_fee = $_POST['mc_fee']; $exchange_rate = $_POST['exchange_rate']; $settle_currency = $_POST['settle_currency']; $parent_txn_id = $_POST['parent_txn_id']; $pending_reason = $_POST['pending_reason']; $reason_code = $_POST['reason_code']; // Subscription specific vars /* $subscr_id = $_POST['subscr_id']; $subscr_date = $_POST['subscr_date']; $subscr_effective = $_POST['subscr_effective']; $period1 = $_POST['period1']; $period2 = $_POST['period2']; $period3 = $_POST['period3']; $amount1 = $_POST['amount1']; $amount2 = $_POST['amount2']; $amount3 = $_POST['amount3']; $mc_amount1 = $_POST['mc_amount1']; $mc_amount2 = $_POST['mc_amount2']; $mc_amount3 = $_POST['mcamount3']; $recurring = $_POST['recurring']; $reattempt = $_POST['reattempt']; $retry_at = $_POST['retry_at']; $recur_times = $_POST['recur_times']; $username = $_POST['username']; $password = $_POST['password']; // Auction specific vars $for_auction = $_POST['for_auction']; $auction_closing_date = $_POST['auction_closing_date']; $auction_multi_item = $_POST['auction_multi_item']; $auction_buyer_id = $_POST['auction_buyer_id']; */ // DB connect creds and email - I HAVE DONE THIS REMOVED FOR SECURITY... $notify_email = ""; //email address to which debug emails are sent to $DB_Server = "localhost"; //your MySQL Server $DB_Username = ""; //your MySQL User Name $DB_Password = ""; //your MySQL Password $DB_DBName = ""; //your MySQL Database Name if (!$fp) { // HTTP ERROR } else { fputs ($fp, $header . $req); while (!feof($fp)) { $res = fgets ($fp, 1024); if (strcmp ($res, "VERIFIED") == 0) { // Create MySQL connection $Connect = @mysql_connect($DB_Server, $DB_Username, $DB_Password) or die("Couldn't connect to MySQL:<br>" . mysql_error() . "<br>" . mysql_errno()); // Select database $Db = @mysql_select_db($DB_DBName, $Connect) or die("Couldn't select database:<br>" . mysql_error(). "<br>" . mysql_errno()); if($item_number == '1') { $sql = "UPDATE users SET premium = '1' WHERE user_id = '".$custom."' LIMIT 1"; mysql_query($sql); } elseif (strcmp ($res, "INVALID") == 0) { // Log for manual investigation mail($notify_email, "INVALID IPN", "$res\n $req"); } fclose ($fp); } } } ?> Unfortunately I have little idea if the code works as I can't test it without doing a Paypal transaction, any ideas? All I want to do is execute this query if someone has paid: $sql = "UPDATE users SET premium = '1' WHERE user_id = '".$custom."' LIMIT 1"; mysql_query($sql); The $custom is a hidden field in the Paypal form button. Quote Link to comment Share on other sites More sharing options...
phpcode Posted December 17, 2007 Share Posted December 17, 2007 Use this code: http://www.micahcarrick.com/04-19-2005/php-paypal-ipn-integration-class.html Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted December 17, 2007 Share Posted December 17, 2007 I'll explain the IPN to you Person make a purchase and pays for it they go to a thank you page. Paypal verifies the payment and when it clears (or not) they send a request to your ipn script (The script posted below) Your script opens a socket to paypal and verifies a checksum From that you get all the purchase details (Payment price, Buyer, Date, Cleared, etc.) After you verify the amounts add up and all sorts you query your mysql saying update status of that user set it to premium or what ever The only tricky part is you need to pass a hidden custom variable to payapal with the primary key of the purchaser so that you know who to approve on the IPN page. Does this clear it up for you? Quote Link to comment Share on other sites More sharing options...
datafan Posted December 17, 2007 Share Posted December 17, 2007 You can test it all at paypal developer central, it's like a mirror of paypal for testing. https://developer.paypal.com/ Paypal also has a script for the php "return" page you can start with. I have set it up several times and it works great. I think the script is in the ipn docs. Quote Link to comment Share on other sites More sharing options...
Mutley Posted December 17, 2007 Author Share Posted December 17, 2007 Thanks guys although I still don't understand how to implement it. I know what IPN does, just not how to use it. Use this code: http://www.micahcarrick.com/04-19-2005/php-paypal-ipn-integration-class.html Thanks, I guess I have to make the button redirect to this script too? It seems a lot of verifying data, all I want to do is run a 1 line query. Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted December 17, 2007 Share Posted December 17, 2007 the verification is mandated by paypal so you dont complain that you got had by a dropped payment. Follow paypal's pre made IPN script, and just put it on your server sign up for IPN in paypal and tell it that is your script, run paypal in your sandbox and your all set to test Quote Link to comment Share on other sites More sharing options...
Mutley Posted December 17, 2007 Author Share Posted December 17, 2007 Does the Paypal Buy button need editing in someway? Does it need to redirect to the script? I'm testing it and it's not working, from the several sample scripts I have. Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted December 17, 2007 Share Posted December 17, 2007 The button it self does not, but it needs a QUERYSTRING hidden variable or CUSTOM (I forget which one paypal uses) that you pass to it so in your paypal form add <input type="hidden" name="CUSTOM" value="".$primaryKey." /> or some form of that Quote Link to comment Share on other sites More sharing options...
Mutley Posted December 17, 2007 Author Share Posted December 17, 2007 What's the primary key? Is that something I have to define? Quote Link to comment Share on other sites More sharing options...
cooldude832 Posted December 17, 2007 Share Posted December 17, 2007 Look up on paypal your allowed to pass up to 64 characters on a custom string as a hidden variable Quote Link to comment Share on other sites More sharing options...
datafan Posted December 17, 2007 Share Posted December 17, 2007 This is the pay pal return script. You just need to add you're $auth_token from the sandbox.paypal or regular paypal site depending on if you testing or real, then change the $fp accordingly as well. You have to create your paypal button from the sandbox or real site as well, so when you go "real" you need to use buttons from the real site. Once this works you can do whatever you want at the end of it. <?php // read the post from PayPal system and add 'cmd' $req = 'cmd=_notify-synch'; $tx_token = $_GET['tx']; $auth_token = "GX_sTf5bW3wxRfFEbgofs88nQxvMQ7nsI8m21rzNESnl_79ccFTWj2aPgQ0"; //change to your sandbox or real paypal code $req .= "&tx=$tx_token&at=$auth_token"; // post back to PayPal system to validate $header .= "POST /cgi-bin/webscr HTTP/1.0\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . strlen($req) . "\r\n\r\n"; $fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30); //change to www.sandbox.paypal.com or back for real paypal // If possible, securely post back to paypal using HTTPS // Your PHP server will need to be SSL enabled // $fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30); if (!$fp) { // HTTP ERROR } else { fputs ($fp, $header . $req); // read the body data $res = ''; $headerdone = false; while (!feof($fp)) { $line = fgets ($fp, 1024); if (strcmp($line, "\r\n") == 0) { // read the header $headerdone = true; } else if ($headerdone) { // header has been read. now read the contents $res .= $line; } } // parse the data $lines = explode("\n", $res); $keyarray = array(); if (strcmp ($lines[0], "SUCCESS") == 0) { for ($i=1; $i<count($lines);$i++){ list($key,$val) = explode("=", $lines[$i]); $keyarray[urldecode($key)] = urldecode($val); } // check the payment_status is Completed // check that txn_id has not been previously processed // check that receiver_email is your Primary PayPal email // check that payment_amount/payment_currency are correct // process payment $firstname = $keyarray['first_name']; $lastname = $keyarray['last_name']; $itemname = $keyarray['item_name']; $amount = $keyarray['payment_gross']; echo ("<p><h3>Thank you for your purchase!</h3></p>"); echo ("<b>Payment Details</b><br>\n"); echo ("<li>Name: $firstname $lastname</li>\n"); echo ("<li>Item: $itemname</li>\n"); echo ("<li>Amount: $amount</li>\n"); echo (""); } else if (strcmp ($lines[0], "FAIL") == 0) { // log for manual investigation } } fclose ($fp); ?> Your transaction has been completed, and a receipt for your purchase has been emailed to you.<br> You may log into your account at <a href='https://www.paypal.com'>www.paypal.com</a> to view details of this transaction.<br> Quote Link to comment Share on other sites More sharing options...
Mutley Posted December 17, 2007 Author Share Posted December 17, 2007 The part I don't understand is, currently they pay and it stays on the Paypal page saying it's confirmed. To redirect to this script (I assume I have to for it to work, not just have the IPN turned on with link) do I have to add a line to the button form at all? And where do I find the auth code for my Paypal? Thanks a lot. Quote Link to comment Share on other sites More sharing options...
datafan Posted December 18, 2007 Share Posted December 18, 2007 In a nutshell: 1. Create an account at develper.paypal.com 2. Create 2 test accounts, one for the merchant and one to use as the buyer 3. Sign in as the merchant and add website payment standard 4. Click on "profile" then "Instant Payment Notification Preferences". Enter the path to the "return.php" file on you site. (the script from my post above) 5. Go back and click on "Website Payment Preferences". Turn on auto return, enter return url (the script from my post above) , turn on payment data transfer and get your identity token. 6. Save it, then go right back in the same link and find "button factory". Create encrypted buttons with the tool and copy past the code to you're page. 7. update the script from my post above with your identity token and change it to sandbox.paypal.com. 8. stay signed on to developer.paypal.com while you test, then use the 2nd buyer id to "pay" for the transaction and test. When you get it working the way you want. You need to go to the real paypal site and do the above, create new buttons, and change return.php file with the real identity token and www.paypal.com Quote Link to comment Share on other sites More sharing options...
Mutley Posted December 18, 2007 Author Share Posted December 18, 2007 Thanks datafan! Got it working. Now I'm trying to transfer the user_id of the user to the script, I inserted a hidden field called "custom" then did a "$custom = $keyarray['custom'];" in the script, but it doesn't seem to work, in the URL I get a "&cm=" so I guess that's the custom field just not transferring the data? Quote Link to comment Share on other sites More sharing options...
datafan Posted December 18, 2007 Share Posted December 18, 2007 Not sure what you are trying to do. If you want to keep track of that specific user when they are done paying by a unique user id on your site, set a session or cookie when they initially sign on. Then check for the session or cookie right on top of your return.php page. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.