Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@CodeAngry
Last active December 17, 2020 11:02
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CodeAngry/5957044 to your computer and use it in GitHub Desktop.
Save CodeAngry/5957044 to your computer and use it in GitHub Desktop.
Verify PayPal IPN with PHP & cURL. Works for both Live and Sandbox IPNs.
<?php
/**
* Verifies a PayPal Live/Sandbox IPN.
*
* It returns NULL if freak error occurs (no connection, bad reply, bad IPN).
* It returns BOOL to signal verification success or failure.
*
* @author Claude "CodeAngry" Adrian
*
* @param array/null $IPN
* @return bool/null
*/
function VerifyPaypalIPN(array $IPN = null){
if(empty($IPN)){
$IPN = $_POST;
}
if(empty($IPN['verify_sign'])){
return null;
}
$IPN['cmd'] = '_notify-validate';
$PaypalHost = (empty($IPN['test_ipn']) ? 'www' : 'www.sandbox').'.paypal.com';
$cURL = curl_init();
curl_setopt($cURL, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($cURL, CURLOPT_SSL_VERIFYHOST, true);
curl_setopt($cURL, CURLOPT_URL, "https://{$PaypalHost}/cgi-bin/webscr");
curl_setopt($cURL, CURLOPT_ENCODING, 'gzip');
curl_setopt($cURL, CURLOPT_BINARYTRANSFER, true);
curl_setopt($cURL, CURLOPT_POST, true); // POST back
curl_setopt($cURL, CURLOPT_POSTFIELDS, $IPN); // the $IPN
curl_setopt($cURL, CURLOPT_HEADER, false);
curl_setopt($cURL, CURLOPT_RETURNTRANSFER, true);
curl_setopt($cURL, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
curl_setopt($cURL, CURLOPT_FORBID_REUSE, true);
curl_setopt($cURL, CURLOPT_FRESH_CONNECT, true);
curl_setopt($cURL, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($cURL, CURLOPT_TIMEOUT, 60);
curl_setopt($cURL, CURLINFO_HEADER_OUT, true);
curl_setopt($cURL, CURLOPT_HTTPHEADER, array(
'Connection: close',
'Expect: ',
));
$Response = curl_exec($cURL);
$Status = (int)curl_getinfo($cURL, CURLINFO_HTTP_CODE);
curl_close($cURL);
if(empty($Response) or !preg_match('~^(VERIFIED|INVALID)$~i', $Response = trim($Response)) or !$Status){
return null;
}
if(intval($Status / 100) != 2){
return false;
}
return !strcasecmp($Response, 'VERIFIED');
}
?>
@grooverdan
Copy link

for those looking at this you should VERIFYPEER and VERIFYHOST

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment