Advertisement
Guest User

Untitled

a guest
Feb 11th, 2013
381
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.73 KB | None | 0 0
  1. <?php
  2. /**
  3. * PayPal IPN Listener
  4. *
  5. * A class to listen for and handle Instant Payment Notifications (IPN) from
  6. * the PayPal server.
  7. *
  8. * https://github.com/Quixotix/PHP-PayPal-IPN
  9. *
  10. * @package PHP-PayPal-IPN
  11. * @author Micah Carrick
  12. * @copyright (c) 2011 - Micah Carrick
  13. * @version 2.0.5
  14. * @license http://opensource.org/licenses/gpl-3.0.html
  15. */
  16. class IpnListener {
  17.  
  18. /**
  19. * If true, the recommended cURL PHP library is used to send the post back
  20. * to PayPal. If flase then fsockopen() is used. Default true.
  21. *
  22. * @var boolean
  23. */
  24. public $use_curl = true;
  25.  
  26. /**
  27. * If true, explicitly sets cURL to use SSL version 3. Use this if cURL
  28. * is compiled with GnuTLS SSL.
  29. *
  30. * @var boolean
  31. */
  32.  
  33. public $force_ssl_v3 = true;
  34.  
  35. /**
  36. * If true, cURL will use the CURLOPT_FOLLOWLOCATION to follow any
  37. * "Location: ..." headers in the response.
  38. *
  39. * @var boolean
  40. */
  41. public $follow_location = false;
  42.  
  43. /**
  44. * If true, an SSL secure connection (port 443) is used for the post back
  45. * as recommended by PayPal. If false, a standard HTTP (port 80) connection
  46. * is used. Default true.
  47. *
  48. * @var boolean
  49. */
  50. public $use_ssl = true;
  51.  
  52. /**
  53. * If true, the paypal sandbox URI www.sandbox.paypal.com is used for the
  54. * post back. If false, the live URI www.paypal.com is used. Default false.
  55. *
  56. * @var boolean
  57. */
  58. public $use_sandbox = false;
  59.  
  60. /**
  61. * The amount of time, in seconds, to wait for the PayPal server to respond
  62. * before timing out. Default 30 seconds.
  63. *
  64. * @var int
  65. */
  66. public $timeout = 30;
  67.  
  68. private $post_data = array();
  69. private $post_uri = '';
  70. private $response_status = '';
  71. private $response = '';
  72.  
  73. const PAYPAL_HOST = 'www.paypal.com';
  74. const SANDBOX_HOST = 'www.sandbox.paypal.com';
  75.  
  76. /**
  77. * Post Back Using cURL
  78. *
  79. * Sends the post back to PayPal using the cURL library. Called by
  80. * the processIpn() method if the use_curl property is true. Throws an
  81. * exception if the post fails. Populates the response, response_status,
  82. * and post_uri properties on success.
  83. *
  84. * @param string The post data as a URL encoded string
  85. */
  86. protected function curlPost($encoded_data) {
  87.  
  88. if ($this->use_ssl) {
  89. $uri = 'https://'.$this->getPaypalHost().'/cgi-bin/webscr';
  90. $this->post_uri = $uri;
  91. } else {
  92. $uri = 'http://'.$this->getPaypalHost().'/cgi-bin/webscr';
  93. $this->post_uri = $uri;
  94. }
  95.  
  96. $ch = curl_init();
  97.  
  98. curl_setopt($ch, CURLOPT_URL, $uri);
  99. curl_setopt($ch, CURLOPT_POST, true);
  100. curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded_data);
  101. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, $this->follow_location);
  102. curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
  103. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  104. curl_setopt($ch, CURLOPT_HEADER, true);
  105.  
  106. if ($this->force_ssl_v3) {
  107. curl_setopt($ch, CURLOPT_SSLVERSION, 3);
  108. }
  109.  
  110. $this->response = curl_exec($ch);
  111. $this->response_status = strval(curl_getinfo($ch, CURLINFO_HTTP_CODE));
  112.  
  113. if ($this->response === false || $this->response_status == '0') {
  114. $errno = curl_errno($ch);
  115. $errstr = curl_error($ch);
  116. throw new Exception("cURL error: [$errno] $errstr");
  117. }
  118. }
  119.  
  120. /**
  121. * Post Back Using fsockopen()
  122. *
  123. * Sends the post back to PayPal using the fsockopen() function. Called by
  124. * the processIpn() method if the use_curl property is false. Throws an
  125. * exception if the post fails. Populates the response, response_status,
  126. * and post_uri properties on success.
  127. *
  128. * @param string The post data as a URL encoded string
  129. */
  130. protected function fsockPost($encoded_data) {
  131.  
  132. if ($this->use_ssl) {
  133. $uri = 'ssl://'.$this->getPaypalHost();
  134. $port = '443';
  135. $this->post_uri = $uri.'/cgi-bin/webscr';
  136. } else {
  137. $uri = $this->getPaypalHost(); // no "http://" in call to fsockopen()
  138. $port = '80';
  139. $this->post_uri = 'http://'.$uri.'/cgi-bin/webscr';
  140. }
  141.  
  142. $fp = fsockopen($uri, $port, $errno, $errstr, $this->timeout);
  143.  
  144. if (!$fp) {
  145. // fsockopen error
  146. throw new Exception("fsockopen error: [$errno] $errstr");
  147. }
  148.  
  149. $header = "POST /cgi-bin/webscr HTTP/1.0rn";
  150. $header .= "Host: ".$this->getPaypalHost()."rn";
  151. $header .= "Content-Type: application/x-www-form-urlencodedrn";
  152. $header .= "Content-Length: ".strlen($encoded_data)."rn";
  153. $header .= "Connection: Closernrn";
  154.  
  155. fputs($fp, $header.$encoded_data."rnrn");
  156.  
  157. while(!feof($fp)) {
  158. if (empty($this->response)) {
  159. // extract HTTP status from first line
  160. $this->response .= $status = fgets($fp, 1024);
  161. $this->response_status = trim(substr($status, 9, 4));
  162. } else {
  163. $this->response .= fgets($fp, 1024);
  164. }
  165. }
  166.  
  167. fclose($fp);
  168. }
  169.  
  170. private function getPaypalHost() {
  171. if ($this->use_sandbox) return IpnListener::SANDBOX_HOST;
  172. else return IpnListener::PAYPAL_HOST;
  173. }
  174.  
  175. /**
  176. * Get POST URI
  177. *
  178. * Returns the URI that was used to send the post back to PayPal. This can
  179. * be useful for troubleshooting connection problems. The default URI
  180. * would be "ssl://www.sandbox.paypal.com:443/cgi-bin/webscr"
  181. *
  182. * @return string
  183. */
  184. public function getPostUri() {
  185. return $this->post_uri;
  186. }
  187.  
  188. /**
  189. * Get Response
  190. *
  191. * Returns the entire response from PayPal as a string including all the
  192. * HTTP headers.
  193. *
  194. * @return string
  195. */
  196. public function getResponse() {
  197. return $this->response;
  198. }
  199.  
  200. /**
  201. * Get Response Status
  202. *
  203. * Returns the HTTP response status code from PayPal. This should be "200"
  204. * if the post back was successful.
  205. *
  206. * @return string
  207. */
  208. public function getResponseStatus() {
  209. return $this->response_status;
  210. }
  211.  
  212. /**
  213. * Get Text Report
  214. *
  215. * Returns a report of the IPN transaction in plain text format. This is
  216. * useful in emails to order processors and system administrators. Override
  217. * this method in your own class to customize the report.
  218. *
  219. * @return string
  220. */
  221. public function getTextReport() {
  222.  
  223. $r = '';
  224.  
  225. // date and POST url
  226. for ($i=0; $i<80; $i++) { $r .= '-'; }
  227. $r .= "n[".date('m/d/Y g:i A').'] - '.$this->getPostUri();
  228. if ($this->use_curl) $r .= " (curl)n";
  229. else $r .= " (fsockopen)n";
  230.  
  231. // HTTP Response
  232. for ($i=0; $i<80; $i++) { $r .= '-'; }
  233. $r .= "n{$this->getResponse()}n";
  234.  
  235. // POST vars
  236. for ($i=0; $i<80; $i++) { $r .= '-'; }
  237. $r .= "n";
  238.  
  239. foreach ($this->post_data as $key => $value) {
  240. $r .= str_pad($key, 25)."$valuen";
  241. }
  242. $r .= "nn";
  243.  
  244. return $r;
  245. }
  246.  
  247. /**
  248. * Process IPN
  249. *
  250. * Handles the IPN post back to PayPal and parsing the response. Call this
  251. * method from your IPN listener script. Returns true if the response came
  252. * back as "VERIFIED", false if the response came back "INVALID", and
  253. * throws an exception if there is an error.
  254. *
  255. * @param array
  256. *
  257. * @return boolean
  258. */
  259. public function processIpn($post_data=null) {
  260.  
  261. $encoded_data = 'cmd=_notify-validate';
  262.  
  263. if ($post_data === null) {
  264. // use raw POST data
  265. if (!empty($_POST)) {
  266. $this->post_data = $_POST;
  267. $encoded_data .= '&'.file_get_contents('php://input');
  268. } else {
  269. throw new Exception("No POST data found.");
  270. }
  271. } else {
  272. // use provided data array
  273. $this->post_data = $post_data;
  274.  
  275. foreach ($this->post_data as $key => $value) {
  276. $encoded_data .= "&$key=".urlencode($value);
  277. }
  278. }
  279.  
  280. if ($this->use_curl) $this->curlPost($encoded_data);
  281. else $this->fsockPost($encoded_data);
  282.  
  283. if (strpos($this->response_status, '200') === false) {
  284. throw new Exception("Invalid response status: ".$this->response_status);
  285. }
  286.  
  287. if (strpos($this->response, "VERIFIED") !== false) {
  288. return true;
  289. } elseif (strpos($this->response, "INVALID") !== false) {
  290. return false;
  291. } else {
  292. throw new Exception("Unexpected response from PayPal.");
  293. }
  294. }
  295.  
  296. /**
  297. * Require Post Method
  298. *
  299. * Throws an exception and sets a HTTP 405 response header if the request
  300. * method was not POST.
  301. */
  302. public function requirePostMethod() {
  303. // require POST requests
  304. if ($_SERVER['REQUEST_METHOD'] && $_SERVER['REQUEST_METHOD'] != 'POST') {
  305. header('Allow: POST', true, 405);
  306. throw new Exception("Invalid HTTP request method.");
  307. }
  308. }
  309. }
  310. ?>
  311.  
  312. <?php
  313. /*
  314. ipn.php - example code used for the tutorial:
  315.  
  316. PayPal IPN with PHP
  317. How To Implement an Instant Payment Notification listener script in PHP
  318. http://www.micahcarrick.com/paypal-ipn-with-php.html
  319.  
  320. (c) 2011 - Micah Carrick
  321. */
  322.  
  323. // tell PHP to log errors to ipn_errors.log in this directory
  324. ini_set('log_errors', true);
  325. ini_set('error_log', dirname(__FILE__).'/ipn_errors.log');
  326.  
  327. // intantiate the IPN listener
  328. include('ipnlistener.php');
  329. $listener = new IpnListener();
  330.  
  331. // tell the IPN listener to use the PayPal test sandbox
  332. $listener->use_sandbox = true;
  333.  
  334. // try to process the IPN POST
  335. try {
  336. $listener->requirePostMethod();
  337. $verified = $listener->processIpn();
  338. } catch (Exception $e) {
  339. error_log($e->getMessage());
  340. exit(0);
  341. }
  342.  
  343. if ($verified) {
  344.  
  345. $errmsg = ''; // stores errors from fraud checks
  346.  
  347. // 1. Make sure the payment status is "Completed"
  348. if ($_POST['payment_status'] != 'Completed') {
  349. // simply ignore any IPN that is not completed
  350. exit(0);
  351. }
  352.  
  353. // 2. Make sure seller email matches your primary account email.
  354. if ($_POST['receiver_email'] != 'mail@example.com') {
  355. $errmsg .= "'receiver_email' does not match: ";
  356. $errmsg .= $_POST['receiver_email']."n";
  357. }
  358.  
  359. // 3. Make sure the amount(s) paid match
  360. //if ($_POST['mc_gross'] != '9.99') {
  361. //$errmsg .= "'mc_gross' does not match: ";
  362. //$errmsg .= $_POST['mc_gross']."n";
  363. //}
  364.  
  365. // 4. Make sure the currency code matches
  366. if ($_POST['mc_currency'] != 'USD') {
  367. $errmsg .= "'mc_currency' does not match: ";
  368. $errmsg .= $_POST['mc_currency']."n";
  369. }
  370.  
  371. // 5. Ensure the transaction is not a duplicate.
  372. mysql_connect('dfdesignzstudiocom.ipagemysql.com','root2121','******') or exit(0);
  373. mysql_select_db('paypal') or exit(0);
  374.  
  375.  
  376. if (!empty($errmsg)) {
  377.  
  378. // manually investigate errors from the fraud checking
  379. $body = "IPN failed fraud checks: n$errmsgnn";
  380. $body .= $listener->getTextReport();
  381. mail('myemail@example.com', 'IPN Fraud Warning', $body);
  382.  
  383. } else {
  384. // add this order to a table of completed orders
  385. $payer_email = mysql_real_escape_string($_POST['payer_email']);
  386. $first_name = mysql_real_escape_string($_POST['first_name']);
  387. $last_name = mysql_real_escape_string($_POST['last_name']);
  388. $contact_phone = mysql_real_escape_string($_POST['contact_phone']);
  389. $item_name = mysql_real_escape_string($_POST['item_name']);
  390. $quantity = mysql_real_escape_string($_POST['quantity']);
  391. $mc_fee = mysql_real_escape_string($_POST['mc_fee']);
  392. $sql = "INSERT INTO orders (payer_email, first_name, last_name, contact_phone, item_name, quantity, mc_fee) VALUES
  393. ('$payer_email', '$first_name', '$last_name', '$contact_phone', '$item_name', '$quantity', '$mc_fee')";
  394.  
  395. if (!mysql_query($sql)) {
  396. error_log(mysql_error());
  397. exit(0);
  398. }
  399. // send seller an email with buyer information
  400. $to = filter_var('myemail@example.com', FILTER_SANITIZE_EMAIL);
  401. $subject = "New Class Registration";
  402. $message = "Registration Information: n$first_name $last_namen$payer_emailnItem Name: $item_name nQuantity: $quantitynTotal paid: $mc_fee";
  403. mail($to, $subject, $message);
  404.  
  405.  
  406.  
  407. $command="mysqldump --xml --host=dfdesignzstudiocom.ipagemysql.com --user=root2121 --password=****** paypal > database.xml";
  408. system($command);
  409.  
  410. }
  411. } else {
  412. // manually investigate the invalid IPN
  413. mail('myemail@example.com', 'Invalid IPN', $listener->getTextReport());
  414. }
  415. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement