/**
  * This will just setup the _events property in the expected format.
  * @return void
  */
 protected function _setup_data()
 {
     //now let's loop and set up the _events property.  At the same time we'll set up attendee properties.
     //a variable for tracking totals
     $running_total = 0;
     //get txn
     $this->txn = $this->reg_obj->transaction();
     $this->taxes = $this->txn->tax_total();
     $this->grand_total_price_object = '';
     //possible session stuff?
     $session = $this->txn->session_data();
     $session_data = $session instanceof EE_Session ? $session->get_session_data() : array();
     //other data from the session (if possible)
     $this->user_id = isset($session_data['user_id']) ? $session_data['user_id'] : '';
     $this->ip_address = isset($session_data['ip_address']) ? $session_data['ip_address'] : '';
     $this->user_agent = isset($session_data['user_agent']) ? $session_data['user_agent'] : '';
     $this->init_access = $this->last_access = '';
     $this->payment = $this->txn->get_first_related('Payment');
     $this->payment = empty($this->payment) ? EE_Payment::new_instance(array('STS_ID' => EEM_Payment::status_id_pending, 'PAY_timestamp' => (int) current_time('timestamp'), 'PAY_gateway' => $this->txn->selected_gateway(), 'PAY_gateway_response' => $this->txn->gateway_response_on_transaction())) : $this->payment;
     //if there is no payments associated with the transaction then we just create a default payment object for potential parsing.
     $this->billing = $this->payment->details();
     EE_Registry::instance()->load_helper('Template');
     $this->billing['total_due'] = isset($this->billing['total']) ? EEH_Template::format_currency($this->billing['total']) : '';
     //get reg_objs for txn
     $this->reg_objs = $this->txn->registrations();
     //now we can set things up like we do for other handlers
     $this->_assemble_data();
 }
 protected function _setup_data()
 {
     //basically ALL we're going to get from this is the transaction object and use it to build the majority of our info.
     $session = $this->_data->get_session_data();
     $this->txn = $session['transaction'];
     if (empty($this->txn) || !$this->txn instanceof EE_Transaction) {
         throw new EE_Error(__('Incoming data for the EE_Session data handler must have a valid EE_Transaction object in order to setup the data'));
     }
     $this->reg_info = array();
     $this->incoming_data = $session;
     $this->taxes = $this->txn->tax_total();
     $this->grand_total_price_object = '';
     //other data from the session (if possible)
     $this->user_id = isset($session['user_id']) ? $session['user_id'] : '';
     $this->ip_address = isset($session['ip_address']) ? $session['ip_address'] : '';
     $this->user_agent = isset($session['user_agent']) ? $session['user_agent'] : '';
     $this->init_access = $this->last_access = '';
     $this->payment = $this->txn->get_first_related('Payment');
     $this->payment = empty($this->payment) ? EE_Payment::new_instance(array('STS_ID' => EEM_Payment::status_id_pending, 'PAY_timestamp' => (int) current_time('timestamp'), 'PAY_gateway' => $this->txn->selected_gateway(), 'PAY_gateway_response' => $this->txn->gateway_response_on_transaction())) : $this->payment;
     //if there is no payments associated with the transaction then we just create a default payment object for potential parsing.
     $this->billing = $this->payment->details();
     EE_Registry::instance()->load_helper('Template');
     $this->billing['total_due'] = isset($this->billing['total']) ? EEH_Template::format_currency($this->billing['total']) : '';
     //let's get all the registrations associated with this txn
     $this->reg_objs = $this->txn->registrations();
     $this->_assemble_data();
 }
 /**
  * Updates the transaction in the session to acknowledge the registrant is done
  * the registration process, all that remains is for them ot make the offline
  * payment. Was renamed from 'set_transaction_details' to 'thank_you_page()', because it served the same purpose
  * as it's parent's 'thank_you_page()', which is to update the transaction (but not the payment
  * because in this case no payment has been made)
  * @global type $EE_Session
  * @param EE_Transaction
  * @return void
  */
 public function thank_you_page_logic(EE_Transaction $transaction)
 {
     do_action('AHEE_log', __FILE__, __FUNCTION__, '');
     //check for an existing payment from this gateway
     $payments = $this->_PAY->get_all(array(array('PAY_gateway' => $this->gateway(), 'TXN_ID' => $transaction->ID())));
     //if it already exists, short-circuit updating the transaction
     if (empty($payments)) {
         $this->update_transaction_with_payment($transaction, null);
         $transaction->save();
     }
     //createa hackey payment object, but dont save it
     $payment = EE_Payment::new_instance(array('TXN_ID' => $transaction->ID(), 'STS_ID' => EEM_Payment::status_id_pending, 'PAY_timestamp' => current_time('timestamp'), 'PAY_amount' => $transaction->total(), 'PAY_gateway' => $this->_gateway_name));
     do_action('AHEE_EE_Gateway__update_transaction_with_payment__done', $transaction, $payment);
     parent::thank_you_page_logic($transaction);
 }
 protected function _setup_data()
 {
     $this->reg_info = array();
     $this->txn = $this->_data['txn_obj'];
     $this->payment = $this->_data['pmt_obj'];
     $this->incoming_data = $this->_data;
     $this->taxes = $this->txn->tax_total();
     $this->grand_total_price_object = '';
     //not available and not needed?
     $session_data = $this->txn->session_data();
     //other data from the session (if possible)
     $this->user_id = isset($session_data['user_id']) ? $session_data['user_id'] : '';
     $this->ip_address = isset($session_data['ip_address']) ? $session_data['ip_address'] : '';
     $this->user_agent = isset($session_data['user_agent']) ? $session_data['user_agent'] : '';
     $this->init_access = $this->last_access = '';
     $this->billing = $this->payment->details();
     // check that the gateways didn't blow up
     if (!$this->billing instanceof EE_Error) {
         EE_Registry::instance()->load_helper('Template');
         $this->billing['total_due'] = isset($this->billing['total']) ? EEH_Template::format_currency($this->billing['total']) : '';
     }
     $this->reg_objs = $this->txn->get_many_related('Registration');
     $this->_assemble_data();
 }
 /**
  * test_build_payment_json_response_for_deleted_payment
  * @since    4.8
  * @group    8620
  */
 public function test_build_payment_json_response_for_deleted_payment()
 {
     $this->_admin_page = new Transactions_Admin_Page_Mock();
     $this->_setup_standard_transaction_and_payment(40.0, 4, 15.0);
     // need to make sure relation is set between payment and payment method
     $this->_payment->_add_relation_to($this->_payment_method(), 'Payment_Method');
     $registrations = $this->_get_x_number_of_registrations_from_transaction($this->_transaction, 1);
     $this->_apply_payment_to_registrations($registrations);
     $json_response_data = $this->_admin_page->build_payment_json_response($this->_payment, array(), true);
     $this->assertEquals($this->_payment->ID(), $json_response_data['PAY_ID']);
     $this->assertEquals(15.0, $json_response_data['amount']);
     // total paid is still zero, because we haven't actually updated the TXN with the payment info
     $this->assertEquals(0, $json_response_data['total_paid']);
     $this->assertEquals(EEM_Transaction::incomplete_status_code, $json_response_data['txn_status']);
     $this->assertEquals(EEM_Payment::status_id_approved, $json_response_data['pay_status']);
     $this->assertTrue($json_response_data['delete_txn_reg_status_change']);
     // will validate $json_response_data[ 'registrations' ] in test_registration_payment_data_array()
 }
 /**
  * used by factory to create payment object
  *
  * @since 4.3.0
  *
  * @param array $args Incoming field values to set on the new object
  *
  * @return EE_Payment|false
  */
 public function create_object($args)
 {
     //timezone?
     if (isset($args['timezone'])) {
         $timezone = $args['timezone'];
         unset($args['timezone']);
     } else {
         $timezone = null;
     }
     //date_formats?
     if (isset($args['formats']) && is_array($args['formats'])) {
         $formats = $args['formats'];
         unset($args['formats']);
     } else {
         $formats = array();
     }
     $payment = EE_Payment::new_instance($args, $timezone, $formats);
     $paymentID = $payment->save();
     return $paymentID ? $payment : false;
 }
 protected function _setup_data()
 {
     //basically ALL we're going to get from this is the transaction object and use it to build the majority of our info.
     $session = $this->_data->get_session_data();
     $this->txn = $session['transaction'];
     if (empty($this->txn) || !$this->txn instanceof EE_Transaction) {
         throw new EE_Error(__('Incoming data for the EE_Session data handler must have a valid EE_Transaction object in order to setup the data'));
     }
     $this->reg_info = array();
     $this->incoming_data = $session;
     //other data from the session (if possible)
     $this->user_id = isset($session['user_id']) ? $session['user_id'] : '';
     $this->ip_address = isset($session['ip_address']) ? $session['ip_address'] : '';
     $this->user_agent = isset($session['user_agent']) ? $session['user_agent'] : '';
     $this->init_access = $this->last_access = '';
     $this->payment = $this->txn->get_first_related('Payment');
     $this->payment = empty($this->payment) ? EE_Payment::new_instance(array('STS_ID' => EEM_Payment::status_id_pending, 'PAY_timestamp' => time(), 'PMD_ID' => $this->txn->payment_method_ID(), 'PAY_gateway_response' => $this->txn->gateway_response_on_transaction())) : $this->payment;
     //if there is no payments associated with the transaction then we just create a default payment object for potential parsing.
     //let's get all the registrations associated with this txn
     $this->reg_objs = $this->txn->registrations();
     $this->_assemble_data();
 }
 /**
  * This will just setup the _events property in the expected format.
  * @return void
  */
 protected function _setup_data()
 {
     //now let's loop and set up the _events property.  At the same time we'll set up attendee properties.
     $this->filtered_reg_status = $this->_data['filtered_reg_status'];
     //get txn
     $this->txn = $this->reg_obj->transaction();
     //possible session stuff?
     $session = $this->txn->session_data();
     $session_data = $session instanceof EE_Session ? $session->get_session_data() : array();
     //other data from the session (if possible)
     $this->user_id = isset($session_data['user_id']) ? $session_data['user_id'] : '';
     $this->ip_address = isset($session_data['ip_address']) ? $session_data['ip_address'] : '';
     $this->user_agent = isset($session_data['user_agent']) ? $session_data['user_agent'] : '';
     $this->init_access = $this->last_access = '';
     $this->payment = $this->txn->get_first_related('Payment');
     $this->payment = empty($this->payment) ? EE_Payment::new_instance(array('STS_ID' => EEM_Payment::status_id_pending, 'PAY_timestamp' => time(), 'PMD_ID' => $this->txn->payment_method_ID(), 'PAY_gateway_response' => $this->txn->gateway_response_on_transaction())) : $this->payment;
     //if there is no payments associated with the transaction then we just create a default payment object for potential parsing.
     //get reg_objs for txn
     $this->reg_objs = $this->txn->registrations();
     //now we can set things up like we do for other handlers
     $this->_assemble_data();
 }
 public function test_just_approved()
 {
     $p1 = EE_Payment::new_instance();
     $this->assertFalse($p1->just_approved());
     $p1->set_status(EEM_Payment::status_id_approved);
     $this->assertTrue($p1->just_approved());
     $id = $p1->save();
     $this->assertTrue($p1->just_approved());
     EEM_Payment::reset();
     //now try with a payment that began as approved
     //note that we've reset EEM_payment so this is just like
     //it had been created on a previous request
     $p2 = EEM_Payment::instance()->get_one_by_ID($id);
     $this->assertFalse($p2->just_approved());
     $p2->set_status(EEM_Payment::status_id_pending);
     $p2->save();
     EEM_Payment::reset();
     //again, pretend this next part is a subsequent request
     $p3 = EEM_Payment::instance()->get_one_by_ID($id);
     $this->assertFalse($p3->just_approved());
     $p3->set_status(EEM_Payment::status_id_approved);
     $this->assertTrue($p3->just_approved());
 }
 /**
  * _process_updated_registration_payments
  *
  * this applies the payments to the selected registrations
  * but only if they have not already been paid for
  *
  * @param  EE_Transaction $transaction
  * @param \EE_Payment $payment
  * @param array $registration_query_where_params
  * @return bool
  */
 protected function _process_updated_registration_payments(EE_Transaction $transaction, EE_Payment $payment, $registration_query_where_params = array())
 {
     // we can pass our own custom set of registrations to EE_Payment_Processor::process_registration_payments()
     // so let's do that using our set of REG_IDs from the form, but add in some conditions regarding payment
     // so that we don't apply payments to registrations that are free or have already been paid for
     // but ONLY if the payment is NOT a refund ( ie: the payment amount is not negative )
     if (!$payment->is_a_refund()) {
         $registration_query_where_params = array_merge($registration_query_where_params, array('REG_final_price' => array('!=', 0), 'REG_final_price*' => array('!=', 'REG_paid', true)));
     }
     $registrations = $transaction->registrations(array($registration_query_where_params));
     //EEH_Debug_Tools::printr( $registrations, '$registrations', __FILE__, __LINE__ );
     if (!empty($registrations)) {
         /** @type EE_Payment_Processor $payment_processor */
         $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
         $payment_processor->process_registration_payments($transaction, $payment, $registrations);
     }
 }
 /**
  * Process payments and transaction after payment process completed.
  * ultimately this will send the TXN and payment details off so that notifications can be sent out.
  * if this request happens to be processing an IPN,
  * then we will also set the Payment Options Reg Step to completed,
  * and attempt to completely finalize the TXN if all of the other Reg Steps are completed as well.
  *
  * @param EE_Transaction $transaction
  * @param EE_Payment     $payment
  * @param bool           $IPN
  * @throws \EE_Error
  */
 protected function _post_payment_processing(EE_Transaction $transaction, EE_Payment $payment, $IPN = false)
 {
     /** @type EE_Transaction_Processor $transaction_processor */
     $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
     // is the Payment Options Reg Step completed ?
     $payment_options_step_completed = $transaction_processor->reg_step_completed($transaction, 'payment_options');
     // if the Payment Options Reg Step is completed...
     $revisit = $payment_options_step_completed === true ? true : false;
     // then this is kinda sorta a revisit with regards to payments at least
     $transaction_processor->set_revisit($revisit);
     // if this is an IPN, let's consider the Payment Options Reg Step completed if not already
     if ($IPN && $payment_options_step_completed !== true && ($payment->is_approved() || $payment->is_pending())) {
         $payment_options_step_completed = $transaction_processor->set_reg_step_completed($transaction, 'payment_options');
     }
     /** @type EE_Transaction_Payments $transaction_payments */
     $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
     // maybe update status, but don't save transaction just yet
     $transaction_payments->update_transaction_status_based_on_total_paid($transaction, false);
     // check if 'finalize_registration' step has been completed...
     $finalized = $transaction_processor->reg_step_completed($transaction, 'finalize_registration');
     //  if this is an IPN and the final step has not been initiated
     if ($IPN && $payment_options_step_completed && $finalized === false) {
         // and if it hasn't already been set as being started...
         $finalized = $transaction_processor->set_reg_step_initiated($transaction, 'finalize_registration');
     }
     $transaction->save();
     // because the above will return false if the final step was not fully completed, we need to check again...
     if ($IPN && $finalized !== false) {
         // and if we are all good to go, then send out notifications
         add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
         //ok, now process the transaction according to the payment
         $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment($transaction, $payment);
     }
     // DEBUG LOG
     $payment_method = $payment->payment_method();
     if ($payment_method instanceof EE_Payment_Method) {
         $payment_method_type_obj = $payment_method->type_obj();
         if ($payment_method_type_obj instanceof EE_PMT_Base) {
             $gateway = $payment_method_type_obj->get_gateway();
             if ($gateway instanceof EE_Gateway) {
                 $gateway->log(array('message' => __('Post Payment Transaction Details', 'event_espresso'), 'transaction' => $transaction->model_field_array(), 'finalized' => $finalized, 'IPN' => $IPN, 'deliver_notifications' => has_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications')), $payment);
             }
         }
     }
 }
 /**
  * This sets up an empty EE_Payment object for the purpose of shortcode parsing.  Note that this doesn't actually get saved to the db.
  * @param \EE_Transaction $txn
  * @return \EE_Payment
  */
 private function _get_empty_payment_obj(EE_Transaction $txn)
 {
     $PMT = EE_Payment::new_instance(array('STS_ID' => EEM_Payment::status_id_pending, 'PAY_timestamp' => time(), 'PMD_ID' => $txn->payment_method_ID(), 'PAY_gateway_response' => $txn->gateway_response_on_transaction()));
     return $PMT;
 }
 /**
  * 		generates HTML for the Registration main meta box
  *		@access public
  *		@return void
  */
 public function _reg_details_meta_box()
 {
     $transaction = $this->_registration->transaction() ? $this->_registration->transaction() : EE_Transaction::new_instance();
     $this->_session = $transaction->session_data();
     $this->_template_args['REG_ID'] = $this->_registration->ID();
     $this->_template_args['line_items'] = $transaction->get_many_related('Line_Item', array(array('LIN_type' => 'line-item')));
     $attendee = $this->_registration->attendee();
     // process taxes
     if ($transaction) {
         //get all "tax" line items for this transaction and we'll use them for the tax display.
         $taxes = $transaction->get_many_related('Line_Item', array(array('LIN_type' => EEM_Line_Item::type_tax)));
         $this->_template_args['taxes'] = !empty($taxes) ? $taxes : array();
     } else {
         $this->_template_args['taxes'] = array();
     }
     $this->_template_args['view_transaction_button'] = EE_Registry::instance()->CAP->current_user_can('ee_read_transaction', 'espresso_transactions_view_transaction') ? EEH_Template::get_button_or_link(EE_Admin_Page::add_query_args_and_nonce(array('action' => 'view_transaction', 'TXN_ID' => $transaction->ID()), TXN_ADMIN_URL), __(' View Transaction'), 'button secondary-button right', 'dashicons dashicons-cart') : '';
     $this->_template_args['resend_registration_button'] = $attendee instanceof EE_Attendee && EE_Registry::instance()->CAP->current_user_can('ee_send_message', 'espresso_registrations_resend_registration') ? EEH_Template::get_button_or_link(EE_Admin_Page::add_query_args_and_nonce(array('action' => 'resend_registration', '_REG_ID' => $this->_registration->ID(), 'redirect_to' => 'view_registration'), REG_ADMIN_URL), __(' Resend Registration'), 'button secondary-button right', 'dashicons dashicons-email-alt') : '';
     $this->_template_args['grand_total'] = EEH_Template::format_currency($transaction->total());
     $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
     $payment = $transaction->get_first_related('Payment');
     $payment = !$payment instanceof EE_Payment ? EE_Payment::new_instance() : $payment;
     $payment_method = $payment->get_first_related('Payment_Method');
     $payment_method = !$payment_method instanceof EE_Payment_Method ? EE_Payment_Method::new_instance() : $payment_method;
     $reg_status_class = 'status-' . $this->_registration->status_ID();
     $reg_details = array('payment_method' => $payment_method->name(), 'response_msg' => $payment->gateway_response(), 'registration_id' => $this->_registration->get('REG_code'), 'registration_session' => $this->_registration->session_ID(), 'ip_address' => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '', 'user_agent' => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '');
     if (isset($reg_details['registration_id'])) {
         $this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
         $this->_template_args['reg_details']['registration_id']['label'] = __('Registration ID', 'event_espresso');
         $this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
     }
     if (isset($reg_details['payment_method'])) {
         $this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
         $this->_template_args['reg_details']['payment_method']['label'] = __('Most Recent Payment Method', 'event_espresso');
         $this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
         $this->_template_args['reg_details']['response_msg']['value'] = $reg_details['response_msg'];
         $this->_template_args['reg_details']['response_msg']['label'] = __('Payment method response', 'event_espresso');
         $this->_template_args['reg_details']['response_msg']['class'] = 'regular-text';
     }
     $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
     $this->_template_args['reg_details']['registration_session']['label'] = __('Registration Session', 'event_espresso');
     $this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
     $this->_template_args['reg_details']['ip_address']['value'] = $reg_details['ip_address'];
     $this->_template_args['reg_details']['ip_address']['label'] = __('Registration placed from IP', 'event_espresso');
     $this->_template_args['reg_details']['ip_address']['class'] = 'regular-text';
     $this->_template_args['reg_details']['user_agent']['value'] = $reg_details['user_agent'];
     $this->_template_args['reg_details']['user_agent']['label'] = __('Registrant User Agent', 'event_espresso');
     $this->_template_args['reg_details']['user_agent']['class'] = 'large-text';
     $this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'default', 'event_id' => $this->_registration->event_ID()), REG_ADMIN_URL);
     $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
     echo EEH_Template::display_template($template_path, $this->_template_args, TRUE);
 }
 /**
  * Handles a paypal IPN, verifies we haven't already processed this IPN, creates a payment (regardless of success or not)
  * and updates the provided transaction, and saves to DB
  * @param EE_Transaction or ID $transaction
  * @return boolean
  */
 public function handle_ipn_for_transaction(EE_Transaction $transaction)
 {
     $this->_debug_log("<hr><br>" . get_class($this) . ":start handle_ipn_for_transaction on transaction:" . $transaction instanceof EE_Transaction ? $transaction->ID() : 'unknown');
     //verify there's payment data that's been sent
     if (empty($_POST['payment_status']) || empty($_POST['txn_id'])) {
         return false;
     }
     $this->_debug_log("<hr><br>" . get_class($this) . ": payment_status and txn_id sent properly. payment_status:" . $_POST['payment_status'] . ", txn_id:" . $_POST['txn_id']);
     //ok, then validate the IPN. Even if we've already processed this payment, let paypal know we don't want to hear from them anymore!
     if (!$this->validateIpn()) {
         //huh, something's wack... the IPN didn't validate. We must have replied to the IPN incorrectly,
         //or their API must ahve changed: http://www.paypalobjects.com/en_US/ebook/PP_OrderManagement_IntegrationGuide/ipn.html
         EE_Error::add_error(__("PayPal IPN Validation failed!", "event_espresso"), __FILE__, __FUNCTION__, __LINE__);
         return false;
     }
     //if the transaction's just an ID, swap it for a real EE_Transaction
     $transaction = $this->_TXN->ensure_is_obj($transaction);
     //verify the transaction exists
     if (empty($transaction)) {
         return false;
     }
     //ok, well let's process this payment then!
     if ($_POST['payment_status'] == 'Completed') {
         //the old code considered 'Pending' as completed too..
         $status = EEM_Payment::status_id_approved;
         //approved
         $gateway_response = __('Your payment is approved.', 'event_espresso');
     } elseif ($_POST['payment_status'] == 'Pending') {
         $status = EEM_Payment::status_id_pending;
         //approved
         $gateway_response = __('Your payment is in progress. Another message will be sent when payment is approved.', 'event_espresso');
     } else {
         $status = EEM_Payment::status_id_declined;
         //declined
         $gateway_response = __('Your payment has been declined.', 'event_espresso');
     }
     $this->_debug_log("<hr>Payment is interpreted as {$status}, and the gateway's response set to '{$gateway_response}'");
     //check if we've already processed this payment
     $payment = $this->_PAY->get_payment_by_txn_id_chq_nmbr($_POST['txn_id']);
     if (!empty($payment)) {
         //payment exists. if this has the exact same status and amount, don't bother updating. just return
         if ($payment->STS_ID() == $status && $payment->amount() == $_POST['mc_gross']) {
             //echo "duplicated ipn! dont bother updating transaction foo!";
             $this->_debug_log("<hr>Duplicated IPN! ignore it...");
             return false;
         } else {
             $this->_debug_log("<hr>Existing IPN for this paypal transaction, but it\\'s got some new info. Old status:" . $payment->STS_ID() . ", old amount:" . $payment->amount());
             $payment->set_status($status);
             $payment->set_amount($_POST['mc_gross']);
             $payment->set_gateway_response($gateway_response);
             $payment->set_details($_POST);
         }
     } else {
         $this->_debug_log("<hr>No Previous IPN payment received. Create a new one");
         //no previous payment exists, create one
         $primary_registrant = $transaction->primary_registration();
         $primary_registration_code = !empty($primary_registrant) ? $primary_registrant->reg_code() : '';
         $payment = EE_Payment::new_instance(array('TXN_ID' => $transaction->ID(), 'STS_ID' => $status, 'PAY_timestamp' => current_time('mysql', FALSE), 'PAY_method' => sanitize_text_field($_POST['txn_type']), 'PAY_amount' => floatval($_REQUEST['mc_gross']), 'PAY_gateway' => $this->_gateway_name, 'PAY_gateway_response' => $gateway_response, 'PAY_txn_id_chq_nmbr' => $_POST['txn_id'], 'PAY_po_number' => NULL, 'PAY_extra_accntng' => $primary_registration_code, 'PAY_via_admin' => false, 'PAY_details' => $_POST));
     }
     $payment->save();
     return $this->update_transaction_with_payment($transaction, $payment);
 }
 /**
  * delete_registration_payments_and_update_registrations
  *
  * removes all registration payment records associated with a payment
  * and subtracts their amounts from the corresponding registrations REG_paid field
  *
  * @param EE_Payment $payment
  * @param array $reg_payment_query_params
  * @return bool
  * @throws \EE_Error
  */
 public function delete_registration_payments_and_update_registrations(EE_Payment $payment, $reg_payment_query_params = array())
 {
     $save_payment = false;
     $reg_payment_query_params = !empty($reg_payment_query_params) ? $reg_payment_query_params : array(array('PAY_ID' => $payment->ID()));
     $registration_payments = EEM_Registration_Payment::instance()->get_all($reg_payment_query_params);
     if (!empty($registration_payments)) {
         foreach ($registration_payments as $registration_payment) {
             if ($registration_payment instanceof EE_Registration_Payment) {
                 $amount_paid = $registration_payment->amount();
                 $registration = $registration_payment->registration();
                 if ($registration instanceof EE_Registration) {
                     $registration->set_paid($registration->paid() - $amount_paid);
                     if ($registration->save()) {
                         if ($registration_payment->delete()) {
                             $registration->_remove_relation_to($payment, 'Payment');
                             $payment->_remove_relation_to($registration, 'Registration');
                         }
                         $save_payment = true;
                     }
                 } else {
                     EE_Error::add_error(sprintf(__('An invalid Registration object was associated with Registration Payment ID# %1$d.', 'event_espresso'), $registration_payment->ID()), __FILE__, __FUNCTION__, __LINE__);
                     return false;
                 }
             } else {
                 EE_Error::add_error(sprintf(__('An invalid Registration Payment object was associated with payment ID# %1$d.', 'event_espresso'), $payment->ID()), __FILE__, __FUNCTION__, __LINE__);
                 return false;
             }
         }
     }
     if ($save_payment) {
         $payment->save();
     }
     return true;
 }
 /**
  * _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;
 }
 /**
  * 		generates HTML for the Registration main meta box
  *		@access public
  *		@return void
  */
 public function _reg_details_meta_box()
 {
     EEH_Autoloader::register_line_item_display_autoloaders();
     EEH_Autoloader::register_line_item_filter_autoloaders();
     EE_Registry::instance()->load_Helper('Line_Item');
     $transaction = $this->_registration->transaction() ? $this->_registration->transaction() : EE_Transaction::new_instance();
     $this->_session = $transaction->session_data();
     $filters = new EE_Line_Item_Filter_Collection();
     $filters->add(new EE_Single_Registration_Line_Item_Filter($this->_registration));
     $filters->add(new EE_Non_Zero_Line_Item_Filter());
     $line_item_filter_processor = new EE_Line_Item_Filter_Processor($filters, $transaction->total_line_item());
     $filtered_line_item_tree = $line_item_filter_processor->process();
     $this->_template_args['REG_ID'] = $this->_registration->ID();
     $line_item_display = new EE_Line_Item_Display('reg_admin_table', 'EE_Admin_Table_Registration_Line_Item_Display_Strategy');
     $this->_template_args['line_item_table'] = $line_item_display->display_line_item($filtered_line_item_tree, array('EE_Registration' => $this->_registration));
     $attendee = $this->_registration->attendee();
     $this->_template_args['view_transaction_button'] = EE_Registry::instance()->CAP->current_user_can('ee_read_transaction', 'espresso_transactions_view_transaction') ? EEH_Template::get_button_or_link(EE_Admin_Page::add_query_args_and_nonce(array('action' => 'view_transaction', 'TXN_ID' => $transaction->ID()), TXN_ADMIN_URL), __(' View Transaction'), 'button secondary-button right', 'dashicons dashicons-cart') : '';
     $this->_template_args['resend_registration_button'] = $attendee instanceof EE_Attendee && EE_Registry::instance()->CAP->current_user_can('ee_send_message', 'espresso_registrations_resend_registration') ? EEH_Template::get_button_or_link(EE_Admin_Page::add_query_args_and_nonce(array('action' => 'resend_registration', '_REG_ID' => $this->_registration->ID(), 'redirect_to' => 'view_registration'), REG_ADMIN_URL), __(' Resend Registration'), 'button secondary-button right', 'dashicons dashicons-email-alt') : '';
     $this->_template_args['currency_sign'] = EE_Registry::instance()->CFG->currency->sign;
     $payment = $transaction->get_first_related('Payment');
     $payment = !$payment instanceof EE_Payment ? EE_Payment::new_instance() : $payment;
     $payment_method = $payment->get_first_related('Payment_Method');
     $payment_method = !$payment_method instanceof EE_Payment_Method ? EE_Payment_Method::new_instance() : $payment_method;
     $reg_status_class = 'status-' . $this->_registration->status_ID();
     $reg_details = array('payment_method' => $payment_method->name(), 'response_msg' => $payment->gateway_response(), 'registration_id' => $this->_registration->get('REG_code'), 'registration_session' => $this->_registration->session_ID(), 'ip_address' => isset($this->_session['ip_address']) ? $this->_session['ip_address'] : '', 'user_agent' => isset($this->_session['user_agent']) ? $this->_session['user_agent'] : '');
     if (isset($reg_details['registration_id'])) {
         $this->_template_args['reg_details']['registration_id']['value'] = $reg_details['registration_id'];
         $this->_template_args['reg_details']['registration_id']['label'] = __('Registration ID', 'event_espresso');
         $this->_template_args['reg_details']['registration_id']['class'] = 'regular-text';
     }
     if (isset($reg_details['payment_method'])) {
         $this->_template_args['reg_details']['payment_method']['value'] = $reg_details['payment_method'];
         $this->_template_args['reg_details']['payment_method']['label'] = __('Most Recent Payment Method', 'event_espresso');
         $this->_template_args['reg_details']['payment_method']['class'] = 'regular-text';
         $this->_template_args['reg_details']['response_msg']['value'] = $reg_details['response_msg'];
         $this->_template_args['reg_details']['response_msg']['label'] = __('Payment method response', 'event_espresso');
         $this->_template_args['reg_details']['response_msg']['class'] = 'regular-text';
     }
     $this->_template_args['reg_details']['registration_session']['value'] = $reg_details['registration_session'];
     $this->_template_args['reg_details']['registration_session']['label'] = __('Registration Session', 'event_espresso');
     $this->_template_args['reg_details']['registration_session']['class'] = 'regular-text';
     $this->_template_args['reg_details']['ip_address']['value'] = $reg_details['ip_address'];
     $this->_template_args['reg_details']['ip_address']['label'] = __('Registration placed from IP', 'event_espresso');
     $this->_template_args['reg_details']['ip_address']['class'] = 'regular-text';
     $this->_template_args['reg_details']['user_agent']['value'] = $reg_details['user_agent'];
     $this->_template_args['reg_details']['user_agent']['label'] = __('Registrant User Agent', 'event_espresso');
     $this->_template_args['reg_details']['user_agent']['class'] = 'large-text';
     $this->_template_args['event_link'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'default', 'event_id' => $this->_registration->event_ID()), REG_ADMIN_URL);
     $template_path = REG_TEMPLATE_PATH . 'reg_admin_details_main_meta_box_reg_details.template.php';
     echo EEH_Template::display_template($template_path, $this->_template_args, TRUE);
 }
 /**
  *
  * @param EE_Transaction       $transaction
  * @param float                $amount
  * @param EE_Billing_Info_Form $billing_info
  * @param string               $return_url
  * @param string                 $fail_url
  * @param string               $method
  * @param bool           $by_admin
  * @return EE_Payment
  * @throws EE_Error
  */
 function process_payment(EE_Transaction $transaction, $amount = null, $billing_info = null, $return_url = null, $fail_url = '', $method = 'CART', $by_admin = false)
 {
     // @todo: add surcharge for the payment method, if any
     if ($this->_gateway) {
         //there is a gateway, so we're going to make a payment object
         //but wait! do they already have a payment in progress that we thought was failed?
         $duplicate_properties = array('STS_ID' => EEM_Payment::status_id_failed, 'TXN_ID' => $transaction->ID(), 'PMD_ID' => $this->_pm_instance->ID(), 'PAY_source' => $method, 'PAY_amount' => $amount !== null ? $amount : $transaction->remaining(), 'PAY_gateway_response' => null);
         $payment = EEM_Payment::instance()->get_one(array($duplicate_properties));
         //if we didn't already have a payment in progress for the same thing,
         //then we actually want to make a new payment
         if (!$payment instanceof EE_Payment) {
             $payment = EE_Payment::new_instance(array_merge($duplicate_properties, array('PAY_timestamp' => time(), 'PAY_txn_id_chq_nmbr' => null, 'PAY_po_number' => null, 'PAY_extra_accntng' => null, 'PAY_details' => null)));
         }
         //make sure the payment has been saved to show we started it, and so it has an ID should the gateway try to log it
         $payment->save();
         $billing_values = $this->_get_billing_values_from_form($billing_info);
         //  Offsite Gateway
         if ($this->_gateway instanceof EE_Offsite_Gateway) {
             $payment = $this->_gateway->set_redirection_info($payment, $billing_values, $return_url, EE_Config::instance()->core->txn_page_url(array('e_reg_url_link' => $transaction->primary_registration()->reg_url_link(), 'ee_payment_method' => $this->_pm_instance->slug())), $fail_url);
             $payment->save();
             //  Onsite Gateway
         } elseif ($this->_gateway instanceof EE_Onsite_Gateway) {
             $payment = $this->_gateway->do_direct_payment($payment, $billing_values);
             $payment->save();
         } else {
             throw new EE_Error(sprintf(__('Gateway for payment method type "%s" is "%s", not a subclass of either EE_Offsite_Gateway or EE_Onsite_Gateway, or null (to indicate NO gateway)', 'event_espresso'), get_class($this), gettype($this->_gateway)));
         }
     } else {
         // no gateway provided
         // there is no payment. Must be an offline gateway
         // create a payment object anyways, but dont save it
         $payment = EE_Payment::new_instance(array('STS_ID' => EEM_Payment::status_id_pending, 'TXN_ID' => $transaction->ID(), 'PMD_ID' => $transaction->payment_method_ID(), 'PAY_amount' => 0.0, 'PAY_timestamp' => time()));
     }
     // if there is billing info, clean it and save it now
     if ($billing_info instanceof EE_Billing_Attendee_Info_Form) {
         $this->_save_billing_info_to_attendee($billing_info, $transaction);
     }
     return $payment;
 }
    /**
     * Gets content for displaying about the payment done using this gateway
     * @param EE_Payment $payment
     * @return type
     */
    public function get_payment_overview_content(EE_Payment $payment)
    {
        $registration = $payment->transaction()->primary_registration();
        //$registration = $session_data['registration'][$session_data['primary_attendee']['line_item_id']];
        if (!$this->_payment_settings['show']) {
            return;
        }
        ?>
		<div class="event-display-boxes">
			<?php 
        if (isset($this->_payment_settings['invoice_title'])) {
            ?>

				<?php 
            echo '<h4 id="invoice_title" class="payment_type_title section-heading">' . stripslashes_deep($this->_payment_settings['invoice_title']) . '</h4>';
        }
        ?>
			<p>
				<a href="<?php 
        echo $registration->invoice_url('download');
        ?>
" class="ee-button-lnk inline-button ui-priority-primary ui-state-default ui-state-hover ui-state-focus ui-corner-all" target="_blank">
					<?php 
        _e('Download PDF Invoice', 'event_espresso');
        ?>
 <span class="ee-icon ee-icon-PDF-file-type"></span>
				</a>
			</p>
			<?php 
        if (isset($this->_payment_settings['page_instructions'])) {
            echo '<div class="event-messages ui-state-highlight"><span class="ui-icon ui-icon-alert"></span><p class="instruct">' . stripslashes_deep($this->_payment_settings['page_instructions']) . '</p></div>';
        }
        if (isset($this->_payment_settings['payment_address'])) {
            ?>
				<div class="address-block">
					<?php 
            echo wpautop(stripslashes_deep($this->_payment_settings['payment_address']));
            ?>
				</div>
				<?php 
        }
        ?>
		</div>
		<?php 
    }
 /**
  * For adding any html output above the payment overview.
  * Many gateways won't want ot display anything, so this function just returns an empty string.
  * Other gateways may want to override this, such as offline gateways.
  *
  * @param \EE_Payment $payment
  * @return string
  */
 public function payment_overview_content(EE_Payment $payment)
 {
     return EEH_Template::locate_template('payment_methods' . DS . 'Invoice' . DS . 'templates' . DS . 'invoice_payment_details_content.template.php', array_merge(array('payment_method' => $this->_pm_instance, 'payment' => $payment, 'page_confirmation_text' => '', 'page_extra_info' => '', 'invoice_url' => $payment->transaction()->primary_registration()->invoice_url('html')), $this->_pm_instance->all_extra_meta_array()));
 }
 /**
  * 		registers a payment or refund made towards a transaction
  *		@access public
  *		@return void
  */
 public function apply_payments_or_refunds()
 {
     $return_data = FALSE;
     if (isset($this->_req_data['txn_admin_payment'])) {
         $payment = $this->_req_data['txn_admin_payment'];
         $payment['PAY_ID'] = $payment['PAY_ID'];
         // payments have a type value of 1 and refunds have a type value of -1
         $type = $payment['type'] < 0 ? -1 : 1;
         // if this is a refund
         if ($type == -1) {
             // remove negative sign from amount if it exists
             $payment['amount'] = abs($payment['amount']);
         }
         // so multiplying amount by type will give a positive value for payments, and negative values for refunds
         $amount = $payment['amount'] * $type;
         switch ($payment['method']) {
             case 'PP':
                 $payment['gateway'] = 'PayPal';
                 break;
             case 'CC':
                 $payment['gateway'] = 'Credit_Card';
                 break;
             case 'CHQ':
                 $payment['gateway'] = 'Cheque';
                 break;
             case 'CSH':
                 $payment['gateway'] = 'Cash';
                 $payment['txn_id_chq_nmbr'] = '';
                 break;
             case 'DB':
                 $payment['gateway'] = 'Debit';
                 $payment['gateway_response'] = '';
                 break;
             case 'BK':
                 $payment['gateway'] = 'Bank';
                 break;
             case 'IV':
                 $payment['gateway'] = 'Invoice';
                 break;
             case 'MO':
                 $payment['gateway'] = 'Money_Order';
         }
         $payment['gateway_response'] = '';
         //savea  the new payment
         $payment = EE_Payment::new_instance(array('TXN_ID' => $payment['TXN_ID'], 'STS_ID' => $payment['status'], 'PAY_timestamp' => $payment['date'], 'PAY_method' => $payment['method'], 'PAY_amount' => $amount, 'PAY_gateway' => $payment['gateway'], 'PAY_gateway_response' => $payment['gateway_response'], 'PAY_txn_id_chq_nmbr' => $payment['txn_id_chq_nmbr'], 'PAY_po_number' => $payment['po_number'], 'PAY_extra_accntng' => $payment['accounting'], 'PAY_via_admin' => true, 'PAY_details' => $payment, 'PAY_ID' => $payment['PAY_ID']));
         if (!$payment->save()) {
             $msg = __('An error occurred. The payment has not been processed succesfully.', 'event_espresso');
             EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
         }
         //update the transaction with this payment
         if ($payment->apply_payment_to_transaction()) {
             $msg = __('The payment has been processed succesfully.', 'event_espresso');
             EE_Error::add_success($msg, __FILE__, __FUNCTION__, __LINE__);
         } else {
             $msg = __('An error occurred. The payment was processed succesfully but the amount paid for the transaction was not updated.', 'event_espresso');
             EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
         }
         //prepare to render page
         $transaction = $payment->transaction();
         $this->_get_payment_status_array();
         $return_data['amount'] = $payment->amount();
         $return_data['total_paid'] = $transaction->paid();
         $return_data['txn_status'] = $transaction->status_ID();
         $return_data['pay_status'] = $payment->STS_ID();
         $return_data['PAY_ID'] = $payment->ID();
         $return_data['STS_ID'] = $payment->STS_ID();
         $return_data['status'] = self::$_pay_status[$payment->STS_ID()];
         $return_data['date'] = $payment->timestamp('Y-m-d', 'h:i a');
         $return_data['method'] = strtoupper($payment->method());
         $this->_get_active_gateways();
         $return_data['gateway'] = isset($this->_template_args['active_gateways'][$payment->gateway()]) ? $this->_template_args['active_gateways'][$payment->gateway()] : $payment->gateway();
         $return_data['gateway_response'] = $payment->gateway_response();
         $return_data['txn_id_chq_nmbr'] = $payment->txn_id_chq_nmbr();
         $return_data['po_number'] = $payment->po_number();
         $return_data['extra_accntng'] = $payment->extra_accntng();
         $this->_process_payment_notification($payment);
         if (isset($this->_req_data['txn_reg_status_change'])) {
             $this->_process_registration_status_change($transaction);
         }
     } else {
         $msg = __('An error occurred. The payment form data could not be loaded.', 'event_espresso');
         EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
     }
     $notices = EE_Error::get_notices(FALSE, FALSE, FALSE);
     echo json_encode(array('return_data' => $return_data, 'success' => $notices['success'], 'errors' => $notices['errors']));
     die;
 }
 /**
  * @param EE_Payment $payment to process
  * @param array      $billing_info but should be empty for this gateway
  * @param string     $return_url URL to send the user to after a successful payment on the payment provider's website
  * @param string     $notify_url URL to send the instant payment notification
  * @param string     $cancel_url URL to send the user to after a cancelled payment attempt on teh payment provider's website
  * @throws \EE_Error
  * @return EE_Payment
  */
 public function set_redirection_info($payment, $billing_info = array(), $return_url = NULL, $notify_url = NULL, $cancel_url = NULL)
 {
     /* @var $transaction EE_Transaction */
     $transaction = $payment->transaction();
     //get any of the current registrations,
     $primary_registrant = $transaction->primary_registration();
     $primary_attendee = $primary_registrant->attendee();
     $items = array();
     //if we're are charging for the full amount, show the normal line items
     if ($this->_can_easily_itemize_transaction_for($payment)) {
         $total_line_item = $transaction->total_line_item();
         $tax_total = $total_line_item->get_total_tax();
         foreach ($total_line_item->get_items() as $line_item) {
             $items[] = array('name' => $line_item->name(), 'price' => $this->format_currency($line_item->unit_price()), 'sku' => $line_item->code(), 'quantity' => $line_item->quantity());
         }
     } else {
         //its a partial payment
         $tax_total = 0;
         //partial payment, so just add 1 item
         $items[] = array('name' => sprintf(__("Partial payment for registration %s", 'event_espresso'), $primary_registrant->reg_code()), 'price' => $this->format_currency($payment->amount()), 'sku' => $primary_registrant->reg_code(), 'quantity' => 1);
     }
     $order = array('total' => $this->format_currency($payment->amount()), 'return_url' => $return_url, 'items' => $this->_prepare_for_mijireh($items), 'email' => $primary_attendee->email(), 'first_name' => $primary_attendee->fname(), 'last_name' => $primary_attendee->lname(), 'tax' => $this->format_currency($tax_total), 'partner_id' => 'ee');
     //setup address?
     if ($primary_attendee->address() && $primary_attendee->city() && $primary_attendee->state_ID() && $primary_attendee->country_ID() && $primary_attendee->zip()) {
         $shipping_address = array('first_name' => $primary_attendee->fname(), 'last_name' => $primary_attendee->lname(), 'street' => $primary_attendee->address(), 'city' => $primary_attendee->city(), 'state_province' => $primary_attendee->state_name(), 'zip_code' => $primary_attendee->zip(), 'country' => $primary_attendee->country_ID());
         if ($primary_attendee->address2()) {
             $shipping_address['apt_suite'] = $primary_attendee->address2();
         }
         if ($primary_attendee->phone()) {
             $shipping_address['phone'] = $primary_attendee->phone();
         }
         $order['shipping_address'] = $shipping_address;
     }
     do_action('AHEE_log', __FILE__, __FUNCTION__, serialize(get_object_vars($this)));
     $args = array('headers' => array('Authorization' => 'Basic ' . base64_encode($this->_access_key . ':'), 'Accept' => 'application/json'), 'body' => json_encode($order));
     $response = wp_remote_post('https://secure.mijireh.com/api/1/orders', $args);
     $this->log(array('get checkout url request_args' => $args, 'response' => $response), $payment);
     if (!$response instanceof WP_Error) {
         $response_body = json_decode($response['body']);
         if ($response_body == NULL || !isset($response_body->checkout_url)) {
             if (is_array($response_body) || is_object($response_body)) {
                 $response_body_as_array = (array) $response_body;
                 $problems_string = '';
                 foreach ($response_body_as_array as $problem_parameter => $problems) {
                     $problems_string .= sprintf(__('\\nProblems with %s: %s', 'event_espresso'), $problem_parameter, implode(", ", $problems));
                 }
             } else {
                 $problems_string = $response['body'];
             }
             if ($problems_string == '') {
                 //no message to show? wack
                 if (isset($response['headers']['status'])) {
                     $problems_string = $response['headers']['status'];
                 } else {
                     $problems_string = __('No response from Mijireh', 'event_espresso');
                 }
             }
             throw new EE_Error(sprintf(__('Errors occurred communicating with Mijireh: %s.', 'event_espresso'), $problems_string));
         }
         $payment->set_redirect_url($response_body->checkout_url);
         $payment->set_txn_id_chq_nmbr($response_body->order_number);
         $payment->set_details($response['body']);
     } else {
         $error_message = sprintf(__("Errors communicating with Mijireh: %s", 'event_espresso'), implode(",", $response->get_error_messages()));
         EE_Error::add_error($error_message, __FILE__, __FUNCTION__, __LINE__);
         throw new EE_Error($error_message);
     }
     return $payment;
 }
 /**
  * Message triggers for manual payment applied by admin
  * @param  bool     $success incoming success value
  * @param  EE_Payment $payment EE_payment object
  * @return bool              success/fail
  */
 public function process_admin_payment($success, EE_Payment $payment)
 {
     $success = TRUE;
     //we need to get the transaction object
     $transaction = $payment->transaction();
     $data = array($transaction, $payment);
     $message_type_name = $payment->amount() < 0 ? 'payment_refund' : 'payment';
     $this->_load_controller();
     $success = $this->_EEMSG->send_message($message_type_name, $data);
     if (!$success) {
         EE_Error::add_error(__('Something went wrong and the payment confirmation was NOT resent', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
     }
     return $success;
 }
 /**
  * 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;
     }
 }
 /**
  * Message triggers for manual payment applied by admin
  * @param  bool     $success incoming success value
  * @param  EE_Payment $payment EE_payment object
  * @return bool              success/fail
  */
 public static function process_admin_payment($success = TRUE, EE_Payment $payment)
 {
     //we need to get the transaction object
     $transaction = $payment->transaction();
     if ($transaction instanceof EE_Transaction) {
         $data = array($transaction, $payment);
         $message_type = self::_get_payment_message_type($payment->STS_ID());
         //if payment amount is less than 0 then switch to payment_refund message type.
         $message_type = $payment->amount() < 0 ? 'payment_refund' : $message_type;
         //if payment_refund is selected, but the status is NOT accepted.  Then change message type to false so NO message notification goes out.
         $message_type = $message_type == 'payment_refund' && $payment->STS_ID() != EEM_Payment::status_id_approved ? false : $message_type;
         self::_load_controller();
         //verify this message type is present and active.  If it isn't then no message is sent.
         $active_mts = self::$_EEMSG->get_active_message_types();
         $message_type = in_array($message_type, $active_mts) ? $message_type : false;
         if ($message_type) {
             $success = self::$_EEMSG->send_message($message_type, $data);
             if (!$success) {
                 EE_Error::add_error(__('Something went wrong and the payment confirmation was NOT resent', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
             }
         } else {
             EE_Error::add_error(__('The message type for the status of this payment is not active or does not exist, so no notification was sent.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
         }
     }
     return $success;
 }
 /**
  *    get_payment_details
  *
  * @access    public
  * @param    array $payments
  * @return    string
  */
 public function get_payment_details($payments = array())
 {
     //prepare variables for displaying
     $template_args = array();
     $template_args['transaction'] = $this->_current_txn;
     $template_args['reg_url_link'] = $this->_reg_url_link;
     $template_args['payments'] = array();
     foreach ($payments as $payment) {
         $template_args['payments'][] = $this->get_payment_row_html($payment);
     }
     //create a hacky payment object, but dont save it
     $payment = EE_Payment::new_instance(array('TXN_ID' => $this->_current_txn->ID(), 'STS_ID' => EEM_Payment::status_id_pending, 'PAY_timestamp' => time(), 'PAY_amount' => $this->_current_txn->total(), 'PMD_ID' => $this->_current_txn->payment_method_ID()));
     $payment_method = $this->_current_txn->payment_method();
     if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj() instanceof EE_PMT_Base) {
         $template_args['gateway_content'] = $payment_method->type_obj()->payment_overview_content($payment);
     } else {
         $template_args['gateway_content'] = '';
     }
     // link to SPCO payment_options
     $template_args['show_try_pay_again_link'] = $this->_show_try_pay_again_link;
     $template_args['SPCO_payment_options_url'] = $this->_SPCO_payment_options_url;
     // verify template arguments
     EEH_Template_Validator::verify_instanceof($template_args['transaction'], '$transaction', 'EE_Transaction');
     EEH_Template_Validator::verify_isnt_null($template_args['payments'], '$payments');
     EEH_Template_Validator::verify_isnt_null($template_args['show_try_pay_again_link'], '$show_try_pay_again_link');
     EEH_Template_Validator::verify_isnt_null($template_args['gateway_content'], '$gateway_content');
     EEH_Template_Validator::verify_isnt_null($template_args['SPCO_payment_options_url'], '$SPCO_payment_options_url');
     return EEH_Template::locate_template(THANK_YOU_TEMPLATES_PATH . 'thank-you-page-payment-details.template.php', $template_args, TRUE, TRUE);
 }
 /**
  * Handle IPN for transaction
  */
 public function handle_ipn_for_transaction(EE_Transaction $transaction)
 {
     global $pronamic_payment, $pronamic_url;
     // Transaction ID
     $transaction_id = $transaction->ID();
     // Payment
     $payment = $this->_PAY->get_payment_by_txn_id_chq_nmbr($transaction_id);
     if (empty($payment)) {
         $payment = EE_Payment::new_instance(array('TXN_ID' => $transaction_id, 'STS_ID' => EEM_Payment::status_id_approved, 'PAY_timestamp' => $transaction->datetime(), 'PAY_amount' => $pronamic_payment->amount, 'PAY_gateway' => __('iDEAL', 'pronamic_ideal'), 'PAY_txn_id_chq_nmbr' => $transaction_id));
     } else {
         $payment->set_status(EEM_Payment::status_id_approved);
     }
     // Save
     $payment->save();
     // URL
     $registration = $transaction->primary_registration();
     $pronamic_url = $this->_get_return_url($registration);
     // Return update
     return $this->update_transaction_with_payment($transaction, $payment);
 }
 /**
  * For adding any html output ab ove the payment overview.
  * Many gateways won't want ot display anything, so this function just returns an empty string.
  * Other gateways may want to override this, such as offline gateways.
  * @return string
  */
 public function get_payment_overview_content(EE_Payment $payment)
 {
     if (!$payment->is_approved()) {
         echo "<span class='error payment-problem'>" . $payment->gateway_response() . "</span>";
     } else {
         //stubb
         echo "";
         //just echo out a single space, so the output buffer that's listening doesnt complain its empty
     }
 }
 /**
  * Gets the actual payment status in the database (useful for verifying a payment has actually been updated)
  * @global WPDB $wpdb
  * @param EE_Payment $payment
  * @return string
  */
 protected function _get_payment_status_in_db(EE_Payment $payment)
 {
     global $wpdb;
     $esp_payment = $payment->get_model()->table();
     return $wpdb->get_var($wpdb->prepare("SELECT STS_ID FROM {$esp_payment} WHERE PAY_ID = %d", $payment->ID()));
 }
 /**
  * Process payments and transaction after payment process completed.
  * ultimately this will send the TXN and payment details off so that notifications can be sent out.
  * if this request happens to be processing an IPN,
  * then we will also set the Payment Options Reg Step to completed,
  * and attempt to completely finalize the TXN if all of the other Reg Steps are completed as well.
  *
  * @param EE_Transaction $transaction
  * @param EE_Payment     $payment
  * @param bool           $IPN
  */
 protected function _post_payment_processing(EE_Transaction $transaction, EE_Payment $payment, $IPN = false)
 {
     /** @type EE_Transaction_Processor $transaction_processor */
     $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
     // is the Payment Options Reg Step completed ?
     $payment_options_step_completed = $transaction_processor->reg_step_completed($transaction, 'payment_options');
     // DEBUG LOG
     //$this->log(
     //	__CLASS__, __FUNCTION__, __LINE__,
     //	$transaction,
     //	array(
     //		'IPN'             => $IPN,
     //		'payment_options' => $payment_options_step_completed,
     //	)
     //);
     // if the Payment Options Reg Step is completed...
     $revisit = $payment_options_step_completed === true ? true : false;
     // then this is kinda sorta a revisit with regards to payments at least
     $transaction_processor->set_revisit($revisit);
     // if this is an IPN, let's consider the Payment Options Reg Step completed if not already
     if ($IPN && $payment_options_step_completed !== true && ($payment->is_approved() || $payment->is_pending())) {
         $payment_options_step_completed = $transaction_processor->set_reg_step_completed($transaction, 'payment_options');
     }
     // DEBUG LOG
     //$this->log(
     //	__CLASS__, __FUNCTION__, __LINE__,
     //	$transaction,
     //	array(
     //		'IPN'             => $IPN,
     //		'payment_options' => $payment_options_step_completed,
     //	)
     //);
     /** @type EE_Transaction_Payments $transaction_payments */
     $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
     // maybe update status, but don't save transaction just yet
     $transaction_payments->update_transaction_status_based_on_total_paid($transaction, false);
     // check if 'finalize_registration' step has been completed...
     $finalized = $transaction_processor->reg_step_completed($transaction, 'finalize_registration');
     // DEBUG LOG
     //$this->log(
     //	__CLASS__, __FUNCTION__, __LINE__,
     //	$transaction,
     //	array(
     //		'IPN'       => $IPN,
     //		'finalized' => $finalized,
     //	)
     //);
     //  if this is an IPN and the final step has not been initiated
     if ($IPN && $payment_options_step_completed && $finalized === false) {
         // and if it hasn't already been set as being started...
         $finalized = $transaction_processor->set_reg_step_initiated($transaction, 'finalize_registration');
         // DEBUG LOG
         //$this->log(
         //	__CLASS__, __FUNCTION__, __LINE__,
         //	$transaction,
         //	array(
         //		'IPN'                   => $IPN,
         //		'finalized'             => $finalized,
         //	)
         //);
     }
     $transaction->save();
     // because the above will return false if the final step was not fully completed, we need to check again...
     if ($IPN && $finalized !== false) {
         // and if we are all good to go, then send out notifications
         add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
         // DEBUG LOG
         //$this->log( __CLASS__, __FUNCTION__, __LINE__, $transaction );
         //ok, now process the transaction according to the payment
         $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment($transaction, $payment);
     }
     // DEBUG LOG
     //$this->log(
     //	__CLASS__, __FUNCTION__, __LINE__,
     //	$transaction,
     //	array(
     //		'IPN'  => $IPN,
     //		'finalized' => $finalized,
     //		'payment' => $payment,
     //		'payment_method' => $payment->payment_method() instanceof EE_Payment_Method ? $payment->payment_method
     //()->name() : 'off-line',
     //		'deliver_notifications' => has_filter( 'FHEE__EED_Messages___maybe_registration__deliver_notifications' ),
     //	)
     //);
 }