function qpp_ipn_page() { if (isset($_POST['Submit']) && check_admin_referer("save_qpp")) { $options = array('ipn', 'paid', 'title'); foreach ($options as $item) { $ipn[$item] = stripslashes($_POST[$item]); $ipn[$item] = filter_var($ipn[$item], FILTER_SANITIZE_STRING); } update_option('qpp_ipn', $ipn); qpp_admin_notice("The IPN settings have been updated."); } if (isset($_POST['Reset']) && check_admin_referer("save_qpp")) { delete_option('qpp_ipn'); qpp_admin_notice("The IPN settings have been reset."); } $ipn = qpp_get_stored_ipn(); $content = '<div class="qpp-settings"><div class="qpp-options"> <h2>Instant Payment Notifications</h2> <form method="post" action=""> <p>IPN only works if you have a PayPal Business or Premier account and IPN has been set up on that account.</p> <p>See the <a href="https://developer.paypal.com/webapps/developer/docs/classic/ipn/integration-guide/IPNSetup/">PayPal IPN Integration Guide</a> for more information on how to set up IPN.</p> <p>The IPN listener URL you will need is:<pre>' . site_url('/?qpp_ipn') . '</pre></p> <p>To check completed payments click on the <b>Payments</b> link in your dashboard menu or <a href="?page=quick-paypal-payments/quick-paypal-messages.php">click here</a>.</p> <table> <tr> <td><input type="checkbox" style="margin:0; padding: 0; border: none" name="ipn" ' . $ipn['ipn'] . ' value="checked" /></td> <td colspan="2"> Enable IPN.</td> </tr> <tr> <td></td> <td>Payment Report Column header:</td> <td><input type="text" style="width:100%" name="title" value="' . $ipn['title'] . '" /></td> </tr> <tr> <td></td> <td>Payment Complete Label:</td> <td><input type="text" style="width:100%" name="paid" value="' . $ipn['paid'] . '" /></td> </tr> </table> <p><input type="submit" name="Submit" class="button-primary" style="color: #FFF;" value="Save Changes" /> <input type="submit" name="Reset" class="button-primary" style="color: #FFF;" value="Reset" onclick="return window.confirm( \'Are you sure you want to reset the IPN settings?\' );"/></p>'; $content .= wp_nonce_field("save_qpp"); $content .= '</form> </div> <div class="qpp-options" style="float:right;"> <h2>IPN Simulation</h2> <p>IPN can be blocked or resticted by your server settings, theme or other plugins. The good news is you can simulate the notifications to check if all is working.</p> <p>To carry out a simulation:</p> <ol> <li>Enable the PayPal Sandbox on the <a href="?page=quick-paypal-payments/settings.php&tab=setup">plugin setup page</a></li> <li>Fill in and send your payment form (you do not need to make an actual payment)</li> <li>Go to the <a href="?page=quick-paypal-payments/quick-paypal-messages.php">Payments Report</a> and copy the long number in the last column from the payment you have just made</li> <li>Go to the IPN simulation page: <a href="https://developer.paypal.com/developer/ipnSimulator" target="_blank">https://developer.paypal.com/developer/ipnSimulator</a></li> <li>Login and enter the IPN listener URL</li> <li>Select \'Express Checkout\' from the drop down</li> <li>Scroll to the bottom of the page and enter the long number you copied at step 3 into the \'Custom\' field</li> <li>Click \'Send IPN\'. Scroll up the page and you should see an \'IPN Verified\' message.</li> <li>Go back to your Payments Report and refresh, you should now see the payment completed message</li> </ol> </div> </div>'; echo $content; }
function qpp_ipn() { $qpp_setup = qpp_get_stored_setup(); $qpp_ipn = qpp_get_stored_ipn(); if (!isset($_REQUEST['paypal_ipn_result']) && !$qpp_ipn['ipn']) { return; } define("DEBUG", 1); define("LOG_FILE", "./ipn.log"); $raw_post_data = file_get_contents('php://input'); $raw_post_array = explode('&', $raw_post_data); $myPost = array(); foreach ($raw_post_array as $keyval) { $keyval = explode('=', $keyval); if (count($keyval) == 2) { $myPost[$keyval[0]] = urldecode($keyval[1]); } } $req = 'cmd=_notify-validate'; if (function_exists('get_magic_quotes_gpc')) { $get_magic_quotes_exists = true; } foreach ($myPost as $key => $value) { if ($get_magic_quotes_exists == true && get_magic_quotes_gpc() == 1) { $value = urlencode(stripslashes($value)); } else { $value = urlencode($value); } $req .= "&{$key}={$value}"; } if ($qpp_setup['sandbox']) { $paypal_url = 'https://www.sandbox.paypal.com/cgi-bin/webscr'; } else { $paypal_url = "https://www.paypal.com/cgi-bin/webscr"; } $ch = curl_init($paypal_url); if ($ch == FALSE) { return FALSE; } curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $req); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); curl_setopt($ch, CURLOPT_FORBID_REUSE, 1); if (DEBUG == true) { curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLINFO_HEADER_OUT, 1); } curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Connection: Close')); $res = curl_exec($ch); if (curl_errno($ch) != 0) { if (DEBUG == true) { error_log(date('[Y-m-d H:i e] ') . "Can't connect to PayPal to validate IPN message: " . curl_error($ch) . PHP_EOL, 3, LOG_FILE); } curl_close($ch); exit; } else { if (DEBUG == true) { error_log(date('[Y-m-d H:i e] ') . "HTTP request of validation request:" . curl_getinfo($ch, CURLINFO_HEADER_OUT) . " for IPN payload: {$req}" . PHP_EOL, 3, LOG_FILE); error_log(date('[Y-m-d H:i e] ') . "HTTP response of validation request: {$res}" . PHP_EOL, 3, LOG_FILE); } curl_close($ch); } $tokens = explode("\r\n\r\n", trim($res)); $res = trim(end($tokens)); if (strcmp($res, "VERIFIED") == 0) { $custom = $_POST['custom']; $arr = explode(",", $qpp_setup['alternative']); foreach ($arr as $item) { $message = get_option('qpp_messages' . $item); $count = count($message); for ($i = 0; $i <= $count; $i++) { if ($message[$i]['field18'] == $custom) { $message[$i]['field18'] = 'Paid'; $auto = qpp_get_stored_autoresponder($item); if ($auto['enable'] && $message[$i]['field8'] && $auto['whenconfirm'] == 'afterpayment') { $values = array('reference' => $message[$i]['field1'], 'quantity' => $message[$i]['field2'], 'amount' => $message[$i]['field3'], 'stock' => $message[$i]['field4'], 'option1' => $message[$i]['field5'], 'email' => $message[$i]['field8'], 'firstname' => $message[$i]['field9'], 'lastname' => $message[$i]['field10']); qpp_send_confirmation($values, $item, $message[$i]['field3']); } update_option('qpp_messages' . $item, $message); } } } if (DEBUG == true) { error_log(date('[Y-m-d H:i e] ') . "Verified IPN: {$req} " . PHP_EOL, 3, LOG_FILE); } } else { if (strcmp($res, "INVALID") == 0) { if (DEBUG == true) { error_log(date('[Y-m-d H:i e] ') . "Invalid IPN: {$req}" . PHP_EOL, 3, LOG_FILE); } } } }