/** * Validate the IPN notification *y gon * @param array $update_info like $_REQUEST * @param EE_Payment|EEI_Payment $payment * @return boolean */ public function validate_ipn($update_info, $payment) { //allow us to skip validating IPNs with PayPal (useful for testing) if (apply_filters('FHEE__EEG_Paypal_Standard__validate_ipn__skip', false)) { return true; } //...otherwise, we actually don't care what the $update_info is, we need to look //at the request directly because we can't use $update_info because it has issues with quotes // Reading POSTed data directly from $_POST causes serialization issues with array data in the POST. // Instead, read raw POST data from the input stream. // @see https://gist.github.com/xcommerce-gists/3440401 $raw_post_data = file_get_contents('php://input'); $raw_post_array = explode('&', $raw_post_data); $update_info = array(); foreach ($raw_post_array as $keyval) { $keyval = explode('=', $keyval); if (count($keyval) == 2) { $update_info[$keyval[0]] = urldecode($keyval[1]); } } // read the IPN message sent from PayPal and prepend 'cmd=_notify-validate' $req = 'cmd=_notify-validate'; $get_magic_quotes_exists = function_exists('get_magic_quotes_gpc') ? true : false; foreach ($update_info as $key => $value) { if ($get_magic_quotes_exists && get_magic_quotes_gpc() == 1) { $value = urlencode(stripslashes($value)); } else { $value = urlencode($value); } $req .= "&{$key}={$value}"; } // HTTP POST the complete, unaltered IPN back to PayPal $response = wp_remote_post($this->_gateway_url, array('body' => $req, 'sslverify' => false, 'timeout' => 60, 'user-agent' => 'Event Espresso v' . EVENT_ESPRESSO_VERSION . '; ' . home_url(), 'httpversion' => '1.1')); // then check the response if (!is_wp_error($response) && array_key_exists('body', $response) && strcmp($response['body'], "VERIFIED") == 0) { return true; } else { // huh, something's wack... the IPN didn't validate. We must have replied to the IPN incorrectly, // or their API must have changed: http://www.paypalobjects.com/en_US/ebook/PP_OrderManagement_IntegrationGuide/ipn.html if (is_wp_error($response)) { $error_msg = sprintf(__('WP Error. Code: "%1$s", Message: "%2$s", Data: "%3$s"', 'event_espresso'), $response->get_error_code(), $response->get_error_message(), print_r($response->get_error_data, true)); } elseif (is_array($response) && isset($response['body'])) { $error_msg = $response['body']; } else { $error_msg = print_r($response, true); } $payment->set_gateway_response(sprintf(__("IPN Validation failed! Paypal responded with '%s'", "event_espresso"), $error_msg)); $payment->set_details(array('REQUEST' => $update_info, 'VALIDATION_RESPONSE' => $response)); $payment->set_status(EEM_Payment::status_id_failed); // log the results $this->log(array('url' => $this->_process_response_url(), 'message' => $payment->gateway_response(), 'details' => $payment->details()), $payment); return false; } }