3 use PayPal\Core\PPHttpConfig;
4 use PayPal\Exception\PPConfigurationException;
5 use PayPal\Core\PPConfigManager;
6 use PayPal\Core\PPConstants;
7 use PayPal\Core\PPConnectionManager;
14 const IPN_CMD = 'cmd=_notify-validate';
20 private $isIpnVerified;
31 private $ipnData = array();
35 * @param string $postData OPTIONAL post data. If null,
36 * the class automatically reads incoming POST data
37 * from the input stream
39 public function __construct($postData='', $config = null) {
42 $conf = PPConfigManager::getInstance();
43 $this->config = $conf->config;
47 $this->config = $config;
50 // reading posted data from directly from $_POST may causes serialization issues with array data in POST
51 // reading raw POST data from input stream instead.
52 $postData = file_get_contents('php://input');
55 $rawPostArray = explode('&', $postData);
56 foreach ($rawPostArray as $keyValue) {
57 $keyValue = explode ('=', $keyValue);
58 if (count($keyValue) == 2)
59 $this->ipnData[$keyValue[0]] = urldecode($keyValue[1]);
61 //var_dump($this->ipnData);
65 * Returns a hashmap of raw IPN data
69 public function getRawData() {
70 return $this->ipnData;
74 * Validates a IPN message
78 public function validate() {
79 if(isset($this->isIpnVerified))
81 return $this->isIpnVerified;
85 $request = self::IPN_CMD;
86 if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() == 1) {
87 $get_magic_quotes_exists = true;
89 $get_magic_quotes_exists = false;
91 foreach ($this->ipnData as $key => $value) {
92 if($get_magic_quotes_exists) {
93 $value = urlencode(stripslashes($value));
95 $value = urlencode($value);
97 $request .= "&$key=$value";
100 $httpConfig = new PPHttpConfig($this->setEndpoint());
101 $httpConfig->addCurlOption(CURLOPT_FORBID_REUSE, 1);
102 $httpConfig->addCurlOption(CURLOPT_HTTPHEADER, array('Connection: Close'));
104 $connection = PPConnectionManager::getInstance()->getConnection($httpConfig, $this->config);
105 $response = $connection->execute($request);
106 if($response == 'VERIFIED') {
107 $this->isIpnVerified = true;
110 $this->isIpnVerified = false;
111 return false; // value is 'INVALID'
116 * Returns the transaction id for which
117 * this IPN was generated, if one is available
121 public function getTransactionId() {
122 if(isset($this->ipnData['txn_id'])) {
123 return $this->ipnData['txn_id'];
124 } else if(isset($this->ipnData['transaction[0].id'])) {
127 $transId[] = $this->ipnData["transaction[$idx].id"];
129 } while(isset($this->ipnData["transaction[$idx].id"]));
135 * Returns the transaction type for which
136 * this IPN was generated
140 public function getTransactionType() {
141 return $this->ipnData['transaction_type'];
144 private function setEndpoint()
146 if(isset($this->config['service.EndPoint.IPN']))
148 $url = $this->config['service.EndPoint.IPN'];
150 else if(isset($this->config['mode']))
152 if(strtoupper($this->config['mode']) == 'SANDBOX')
154 $url = PPConstants::IPN_SANDBOX_ENDPOINT;
156 else if (strtoupper($this->config['mode']) == 'LIVE')
158 $url = PPConstants::IPN_LIVE_ENDPOINT;
162 throw new PPConfigurationException('mode should be LIVE or SANDBOX');
167 throw new PPConfigurationException('No COnfig file found');