/** * 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; } }
/** * get_payment_row_html * * @access public * @param EE_Payment $payment * @return string */ public function get_payment_row_html($payment = NULL) { $html = ''; if ($payment instanceof EE_Payment) { if ($payment->payment_method() instanceof EE_Payment_Method && $payment->payment_method()->is_off_site() && $payment->status() === EEM_Payment::status_id_failed) { // considering the registrant has made it to the Thank You page, // any failed payments may actually be pending and the IPN is just slow // so let's $payment->set_status(EEM_Payment::status_id_pending); } $payment_declined_msg = $payment->STS_ID() === EEM_Payment::status_id_declined ? '<br /><span class="small-text">' . $payment->gateway_response() . '</span>' : ''; $html .= ' <tr> <td> ' . $payment->timestamp() . ' </td> <td> ' . ($payment->payment_method() instanceof EE_Payment_Method ? $payment->payment_method()->name() : __('Unknown', 'event_espresso')) . ' </td> <td class="jst-rght"> ' . EEH_Template::format_currency($payment->amount()) . ' </td> <td class="jst-rght" style="line-height:1;"> ' . $payment->pretty_status(TRUE) . $payment_declined_msg . ' </td> </tr>'; do_action('AHEE__thank_you_page_payment_details_template__after_each_payment', $payment); } return $html; }
/** * _process_cancelled_payments * just makes sure that the payment status gets updated correctly * so tha tan error isn't generated during payment validation * * @access private * @param EE_Payment $payment * @return EE_Payment | FALSE */ private function _process_cancelled_payments($payment = NULL) { if (isset($_REQUEST['ee_cancel_payment']) && $payment instanceof EE_Payment && $payment->status() == EEM_Payment::status_id_failed) { $payment->set_status(EEM_Payment::status_id_cancelled); } return $payment; }