Thomas Posted July 3, 2018 Share Posted July 3, 2018 Hi Larry: I am using your book "Effortless E-commerce with php and mysql 2nd edition" to create a subscription website. When using your example 1 scripts, everything worked fine except that the database was not updating. The log was showing a 400 - Bad request error.The reason I found in one of your forums was a change in paypal's IPN script requirements, however the solution mentioned there is no more valid as paypal has made further changes to the scripts. It is now a completely different script which is very different from the one used in your example. I have tried everything but its not working. Could you please update the ipn script (the ipn_log.php file) in your example so that your example is still usable. Also would it be possible for you to send me a copy of the updated script by e-mail or a link to the updated script. I like all your books and commend you on your presentation style, especially the fact that you make extremely complicated things so simple. Thanks, and waiting for your reply Thomas Link to comment Share on other sites More sharing options...
Larry Posted July 4, 2018 Share Posted July 4, 2018 Thanks for the nice words. Very much appreciated! Can you clarify: are you having problems with the sandbox usage of PayPal or the production usage? Link to comment Share on other sites More sharing options...
Thomas Posted October 29, 2018 Author Share Posted October 29, 2018 Hi Larry, I am still struggling with the paypal IPN script. The problem right now is with the sandbox usage. I have not yet tried the production usage. Link to comment Share on other sites More sharing options...
Larry Posted October 30, 2018 Share Posted October 30, 2018 Sorry to hear you're still having problems. I haven't been able to test anything yet, but I just found a version of an IPN PHP example from PayPal. The key bits are: https://github.com/paypal/ipn-code-samples/blob/master/php/PaypalIPN.php#L63-L139 Some modifications would be required (including changing self::VALID to "VERIFIED" on line 135). Let me know if you need any more details on how to adapt this. Link to comment Share on other sites More sharing options...
Thomas Posted November 5, 2018 Author Share Posted November 5, 2018 Hi Larry, Thank you very much for your time. I have got the ipn script working, but it is not making any changes to the database. I have checked everything but don't seem to find the problem. I am stuck badly. Could you please have a look at the log file and my ipn script. Sorry to bother you, but I have tried everything I could... Here is my script: <?php // This page handles the Instant Payment Notification communications with PayPal. // Most of the code comes from PayPal's documentation. // This script is created in Chapter 6. // This is a modified version of ipn.php that logs all transactions to a text file. // Require the configuration before any PHP code as the configuration controls error reporting: require ('./includes/config.inc.php'); // The config file also starts the session. // Open the text file: // Change this path to make it accurate. // The text file must be writable by PHP! $file = fopen('../ipn.txt', 'a'); // Write the POST data to the file: fwrite($file, "Received:\n"); fwrite($file, print_r($_POST, true)); fwrite($file, "\n"); // Start by creating a request variable: $req = 'cmd=_notify-validate'; // Add each received key=value pair to the request: foreach ($_POST as $key => $value) { $value = urlencode(stripslashes($value)); $req .= "&$key=$value"; } // Open a socket connection to PayPal: $fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30); // Test //$fp = fsockopen ('ssl://www.paypal.com', 443, $errno, $errstr, 30); // Live if (!$fp) { // If we couldn't connect, send an email: trigger_error('Could not connect for the IPN!'); } else { // Send the request to PayPal: $header = "POST /cgi-bin/webscr HTTP/1.1\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . strlen($req) . "\r\n"; $header .= "Connection: Close\r\n"; $header .= "Host: www.sandbox.paypal.com\r\n\r\n"; fputs ($fp, $header . $req); // Write the PayPal request to the text file: fwrite($file, "Sent:\n"); fwrite($file, "$header\n"); fwrite($file, "$req\n"); // Read in the response: while (!feof($fp)) { $res = fgets ($fp, 1024); // Write the PayPal response to the text file: fwrite($file, "Received:\n"); fwrite($file, "$res\n"); if (strcmp ($res, "VERIFIED") == 0) { // Check for the right values: if ( ($_POST['payment_status'] == 'Completed') && ($_POST['receiver_email'] == 'businesstype2@account.com') && ($_POST['mc_gross'] == 2.00) && ($_POST['mc_currency'] == 'USD') && (!empty($_POST['txn_id'])) ) { // Need the database connection now: require(MYSQL); // Check for this transaction in the database: $txn_id = mysqli_real_escape_string($dbc, $_POST['txn_id']); $q = "SELECT id FROM orders WHERE transaction_id='$txn_id'"; $r = mysqli_query ($dbc, $q); if (mysqli_num_rows($r) == 0) { // Add this new transaction: $uid = (int) $_POST['custom']; $status = mysqli_real_escape_string($dbc, $_POST['payment_status']); $amount = (float) $_POST['mc_gross']; $q = "INSERT INTO orders (user_id, transaction_id, payment_status, payment_amount) VALUES ($uid, '$txn_id', '$status', $amount)"; $r = mysqli_query ($dbc, $q); if (mysqli_affected_rows($dbc) == 1) { // Update the users table: $q = "UPDATE users SET date_expires = IF(date_expires > NOW(), ADDDATE(date_expires, INTERVAL 1 YEAR), ADDDATE(NOW(), INTERVAL 1 YEAR)), date_modified=NOW() WHERE id=$uid"; $r = mysqli_query ($dbc, $q); if (mysqli_affected_rows($dbc) != 1) { trigger_error('The user\'s expiration date could not be updated!'); } } else { // Problem inserting the order! trigger_error('The transaction could not be stored in the orders table!'); } } // The order has already been stored! } // The right values don't exist in $_POST! } elseif (strcmp ($res, "INVALID") == 0) { // log for manual investigation } } // End of the WHILE loop. // Close the connection: fclose ($fp); } // End of $fp IF-ELSE. // Inidicate the end of this transaction in the text file: fwrite($file, "--------------\n"); fclose($file); ?> Here is the log file: Received: Array ( [mc_gross] => 2.00 [protection_eligibility] => Eligible [payer_id] => LUR52HDDC9QQJ [payment_date] => 23:28:28 Nov 04, 2018 PST [payment_status] => Completed [charset] => windows-1252 [first_name] => ds [option_selection1] => Option 1 [mc_fee] => 0.36 [notify_version] => 3.9 [subscr_id] => I-KHYJ5W4T4WYA [custom] => 7 [payer_status] => verified [business] => businesstype2@account.com [verify_sign] => AFbtoae17G1snrl8ZQGTOr-6vaYpAOeYDYDiQ1jZwHau1ZceykLAeEqO [payer_email] => personaltype@account.com [option_name1] => payment options [txn_id] => 3MU76381Y5303693J [payment_type] => instant [btn_id] => 3917566 [last_name] => dsa [receiver_email] => businesstype2@account.com [payment_fee] => 0.36 [receiver_id] => JK68KZ5US2C44 [txn_type] => subscr_payment [item_name] => subscribe1 [mc_currency] => USD [item_number] => 1 [residence_country] => US [test_ipn] => 1 [transaction_subject] => subscribe1 [payment_gross] => 2.00 [ipn_track_id] => 2b0519bf904c2 ) Received: Array ( [txn_type] => subscr_signup [subscr_id] => I-KHYJ5W4T4WYA [last_name] => dsa [option_selection1] => Option 1 [residence_country] => US [mc_currency] => USD [item_name] => subscribe1 [business] => businesstype2@account.com [amount3] => 2.00 [recurring] => 1 [verify_sign] => ANc79cx0nOjtjRmd1K0rzvpG.GGCAd5QwZfHVcr7UGVgJ-zLIoUB6vug [payer_status] => verified [test_ipn] => 1 [payer_email] => personaltype@account.com [first_name] => ds [receiver_email] => businesstype2@account.com [payer_id] => LUR52HDDC9QQJ [option_name1] => payment options [reattempt] => 1 [item_number] => 1 [subscr_date] => 23:28:24 Nov 04, 2018 PST [btn_id] => 3917566 [custom] => 7 [charset] => windows-1252 [notify_version] => 3.9 [period3] => 1 W [mc_amount3] => 2.00 [ipn_track_id] => 2b0519bf904c2 ) Sent: POST /cgi-bin/webscr HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 827 Connection: Close Host: www.sandbox.paypal.com cmd=_notify-validate&mc_gross=2.00&protection_eligibility=Eligible&payer_id=LUR52HDDC9QQJ&payment_date=23%3A28%3A28+Nov+04%2C+2018+PST&payment_status=Completed&charset=windows-1252&first_name=ds&option_selection1=Option+1&mc_fee=0.36¬ify_version=3.9&subscr_id=I-KHYJ5W4T4WYA&custom=7&payer_status=verified&business=businesstype2%40account.com&verify_sign=AFbtoae17G1snrl8ZQGTOr-6vaYpAOeYDYDiQ1jZwHau1ZceykLAeEqO&payer_email=personaltype%40account.com&option_name1=payment+options&txn_id=3MU76381Y5303693J&payment_type=instant&btn_id=3917566&last_name=dsa&receiver_email=businesstype2%40account.com&payment_fee=0.36&receiver_id=JK68KZ5US2C44&txn_type=subscr_payment&item_name=subscribe1&mc_currency=USD&item_number=1&residence_country=US&test_ipn=1&transaction_subject=subscribe1&payment_gross=2.00&ipn_track_id=2b0519bf904c2 Sent: POST /cgi-bin/webscr HTTP/1.1 Content-Type: application/x-www-form-urlencoded Content-Length: 668 Connection: Close Host: www.sandbox.paypal.com cmd=_notify-validate&txn_type=subscr_signup&subscr_id=I-KHYJ5W4T4WYA&last_name=dsa&option_selection1=Option+1&residence_country=US&mc_currency=USD&item_name=subscribe1&business=businesstype2%40account.com&amount3=2.00&recurring=1&verify_sign=ANc79cx0nOjtjRmd1K0rzvpG.GGCAd5QwZfHVcr7UGVgJ-zLIoUB6vug&payer_status=verified&test_ipn=1&payer_email=personaltype%40account.com&first_name=ds&receiver_email=businesstype2%40account.com&payer_id=LUR52HDDC9QQJ&option_name1=payment+options&reattempt=1&item_number=1&subscr_date=23%3A28%3A24+Nov+04%2C+2018+PST&btn_id=3917566&custom=7&charset=windows-1252¬ify_version=3.9&period3=1+W&mc_amount3=2.00&ipn_track_id=2b0519bf904c2 Received: HTTP/1.1 200 OK Received: Date: Mon, 05 Nov 2018 07:29:08 GMT Received: Server: Apache Received: X-Frame-Options: SAMEORIGIN Received: Set-Cookie: c9MWDuvPtT9GIMyPc3jwol1VSlO=LO3tJK_vhQ0urAXMiTFbbKU5jsfIrhLsApihIGzPgnV-A7XGCS0ndcdsAZOIBFS9ttES675E7f3itp-vWWm87R8ACF9iwFC3ac8wvO0xtFw038VeOZAARcGEuy48j34EuAx0taCviJPKB91QOfjMxdk5U_NPv3Begcop2P8RSuwC39LpsO1bvpm-4EeqxoJ6KIgCfoB1D7kmhCsOpkgIlJbc26VLB256Z0HxCYPM13RswxXTNT_CHgchEnK3eI6nwKisr_BRgIytBRAoSSY0x8KLTmbTLdMtV649FRz_42-aLYuy7MZNk-kiwawytSquHbUmz8uJS_s1S10LtDCj31kOsvFWYZc5lZA2o692Y96s-4fz5B6FJNr6rWGzy0aA7q9VLXAk75NLVW9tdtA59EiIoVEqQLaOe0g1aPI6BF0rfH1yhA22CXnN0lS; domain=.paypal.com; path=/; Secure; HttpOnly Received: Set-Cookie: cookie_check=yes; expires=Thu, 02-Nov-2028 07:29:08 GMT; domain=.paypal.com; path=/; Secure; HttpOnly Received: Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; Secure; HttpOnly Received: Set-Cookie: navlns=0.0; expires=Wed, 04-Nov-2020 07:29:08 GMT; domain=.paypal.com; path=/; Secure; HttpOnly Received: Set-Cookie: Apache=10.72.108.11.1541402948045743; path=/; expires=Wed, 28-Oct-48 07:29:08 GMT Received: Vary: Accept-Encoding,User-Agent Received: Connection: close Received: HTTP_X_PP_AZ_LOCATOR: sandbox.slc Received: Paypal-Debug-Id: 2964235d617f Received: Set-Cookie: X-PP-SILOVER=name%3DSANDBOX3.WEB.1%26silo_version%3D1880%26app%3Dappdispatcher%26TIME%3D1156702043%26HTTP_X_PP_AZ_LOCATOR%3Dsandbox.slc; Expires=Mon, 05 Nov 2018 07:59:08 GMT; domain=.paypal.com; path=/; Secure; HttpOnly Received: Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT Received: Transfer-Encoding: chunked Received: Content-Type: text/html; charset=UTF-8 Received: Strict-Transport-Security: max-age=63072000 Received: Received: 8 Received: VERIFIED Received: 0 Received: -------------- Received: HTTP/1.1 200 OK Received: Date: Mon, 05 Nov 2018 07:29:08 GMT Received: Server: Apache Received: X-Frame-Options: SAMEORIGIN Received: Set-Cookie: c9MWDuvPtT9GIMyPc3jwol1VSlO=_9eNJYJ52VW6CeqJZ11MjiesH2txcMDfRML1eFI1xDnK5QjmyplQ-2LiFAwG7GgQ_NRyyNmZEi31xRWVCqHdMZLQA2PhW44bRLUQij-lP268JWCW9QIwmSlnhoCWP2xp3G58fjdj1VPIiGN-QWaNoyM_knolxEFhe8RSjfYJc4Tb1PXHy4QOoT1jyHOLJ3iBb804MloM9AohgxK3Ggfhi9ls2sh_ILHLZmW13-eWW_hqkmN0qGJadk84g7gIn6EfzoA0NwxFn5ioAzrtYAJIA9MR7yPnDN_EyqzFAD-ZwpGDwJ_vNNOH4dNHzs_fFocoH6jA14EGq3ZLAsX1Op_NkyQG5zi3OJdXh6vzMHRegbxPiZjcuViwSmzQFwX7cbh2zhJ73JLqTfXEwzKxmM8fatUJ6VtIAa1TyAPGQBiXqyY8_4FVyzZKw6_tdom; domain=.paypal.com; path=/; Secure; HttpOnly Received: Set-Cookie: cookie_check=yes; expires=Thu, 02-Nov-2028 07:29:08 GMT; domain=.paypal.com; path=/; Secure; HttpOnly Received: Set-Cookie: navcmd=_notify-validate; domain=.paypal.com; path=/; Secure; HttpOnly Received: Set-Cookie: navlns=0.0; expires=Wed, 04-Nov-2020 07:29:08 GMT; domain=.paypal.com; path=/; Secure; HttpOnly Received: Set-Cookie: Apache=10.72.108.11.1541402948042463; path=/; expires=Wed, 28-Oct-48 07:29:08 GMT Received: Vary: Accept-Encoding,User-Agent Received: Connection: close Received: HTTP_X_PP_AZ_LOCATOR: sandbox.slc Received: Paypal-Debug-Id: fd4abe3c73e5 Received: Set-Cookie: X-PP-SILOVER=name%3DSANDBOX3.WEB.1%26silo_version%3D1880%26app%3Dappdispatcher%26TIME%3D1156702043%26HTTP_X_PP_AZ_LOCATOR%3Dsandbox.slc; Expires=Mon, 05 Nov 2018 07:59:08 GMT; domain=.paypal.com; path=/; Secure; HttpOnly Received: Set-Cookie: X-PP-SILOVER=; Expires=Thu, 01 Jan 1970 00:00:01 GMT Received: Transfer-Encoding: chunked Received: Content-Type: text/html; charset=UTF-8 Received: Strict-Transport-Security: max-age=63072000 Received: Received: 8 Received: VERIFIED Received: 0 Received: -------------- Link to comment Share on other sites More sharing options...
Larry Posted November 5, 2018 Share Posted November 5, 2018 The log file helps a lot to debug this. It doesn't look like there's anything obviously amiss, which is to say it looks like all checks are passing. I would next debug this by running your MySQL queries by hand with dummy data to make sure they're all syntactically correct. You can also write more debugging info to the log file, things like "Running the SELECT query." and "No records selected." This should help you know what lines get executed and which don't. Link to comment Share on other sites More sharing options...
Thomas Posted November 10, 2018 Author Share Posted November 10, 2018 Hi Larry: Thankyou very much for making the time to look into my log file. I did what you suggested and figured out the problem. If I remove the following 'if' condition, everything works fine. if (strcmp ($res, "VERIFIED") == 0) Any suggestions as to how I can still use this 'if' condition and keep everything working? Could this be because of the new headers now required by paypal: $header = "POST /cgi-bin/webscr HTTP/1.1\r\n"; $header .= "Content-Type: application/x-www-form-urlencoded\r\n"; $header .= "Content-Length: " . strlen($req) . "\r\n"; $header .= "Connection: Close\r\n"; $header .= "Host: www.sandbox.paypal.com\r\n\r\n"; Thankyou once again for your help and support. Link to comment Share on other sites More sharing options...
Larry Posted November 12, 2018 Share Posted November 12, 2018 It looks like PayPal is now using the lowercase "verified" for the payer_status. You could switch to that or use stricmp() instead. Link to comment Share on other sites More sharing options...
Thomas Posted November 14, 2018 Author Share Posted November 14, 2018 Thankyou very much Larry for the reply and guidance. I did try the lowercase and stricmp, but it did not work. I did find a solution though and the reason for the problem. I could not have done it without your help and support! THANKS V. MUCH! Problem: Now Paypal IPN sends back VERIFIED but with numbers before and after Solution: Change the function : if (strcmp ($res, "VERIFIED") == 0) { To if (strpos($res,'VERIFIED') !== false) { Link to comment Share on other sites More sharing options...
Larry Posted November 14, 2018 Share Posted November 14, 2018 Ah, excellent find and fix! Kudos for figuring that out and thanks for sharing the solution! Link to comment Share on other sites More sharing options...
Recommended Posts