Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<h2>Code</h2> <p>I've used the c# equivalent of this many times (and the PHP version looks quite similar).</p> <p><a href="https://www.x.com/developers/PayPal/documentation-tools/code-sample/216623" rel="nofollow">https://www.x.com/developers/PayPal/documentation-tools/code-sample/216623</a></p> <pre><code>&lt;?php //reading raw POST data from input stream. reading pot data from $_POST may cause serialization issues since POST data may contain arrays $raw_post_data = file_get_contents('php://input'); $raw_post_array = explode('&amp;', $raw_post_data); $myPost = array(); foreach ($raw_post_array as $keyval) { $keyval = explode ('=', $keyval); if (count($keyval) == 2) $myPost[$keyval[0]] = urldecode($keyval[1]); } // read the post from PayPal system and add 'cmd' $req = 'cmd=_notify-validate'; if(function_exists('get_magic_quotes_gpc')) { $get_magic_quotes_exits = true; } foreach ($myPost as $key =&gt; $value) { if($get_magic_quotes_exits == true &amp;&amp; get_magic_quotes_gpc() == 1) { $value = urlencode(stripslashes($value)); } else { $value = urlencode($value); } $req .= "&amp;$key=$value"; } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://www.paypal.com/cgi-bin/webscr'); 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_HTTPHEADER, array('Host: www.paypal.com')); // In wamp like environment where the root authority certificate doesn't comes in the bundle, you need // to download 'cacert.pem' from "http://curl.haxx.se/docs/caextract.html" and set the directory path // of the certificate as shown below. // curl_setopt($ch, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem'); $res = curl_exec($ch); curl_close($ch); // assign posted variables to local variables $item_name = $_POST['item_name']; $item_number = $_POST['item_number']; $payment_status = $_POST['payment_status']; $payment_amount = $_POST['mc_gross']; $payment_currency = $_POST['mc_currency']; $txn_id = $_POST['txn_id']; $receiver_email = $_POST['receiver_email']; $payer_email = $_POST['payer_email']; if (strcmp ($res, "VERIFIED") == 0) { // 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 } else if (strcmp ($res, "INVALID") == 0) { // log for manual investigation } ?&gt; </code></pre> <h2>Overview</h2> <p>Basically, PayPal contacts you and you respond; this allows you to validate that it was PayPal invoking your IPN handler and not a malicious party. After that validation step, you can proceed with processing the results. As I'm sure you know, an IPN call is made after a payment occurs (and also can be configured for other events in the payment lifecycle). You can use IPN to update a system status (e.g. unlocking a purchased product).</p> <h2>Other Stuff</h2> <ul> <li>The last development URL I used for PayPal was <a href="https://www.sandbox.paypal.com/cgi-bin/webscr" rel="nofollow">https://www.sandbox.paypal.com/cgi-bin/webscr</a> (probably still valid)</li> <li>The IPN page/handler needs to be publicly available for PayPal to invoke.</li> <li>You'll need to configure IPN notifications in the PayPal developer UI (which mainly involves giving them the URL to your IPN page)</li> <li>You can send custom information to PayPal with the original transaction that PayPal will send back to the IPN handler. I believe it is passed in a field called "custom".</li> </ul>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload