Verify PayPal IPN with PHP & cURL. Works for both Live and Sandbox IPNs.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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'); | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
for those looking at this you should VERIFYPEER and VERIFYHOST