/** * 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); }
/** * 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; }
/** * 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(); }
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(); }
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()); }
/** * apply_payments_or_refunds * registers a payment or refund made towards a transaction * * @access public * @return void */ public function apply_payments_or_refunds() { $json_response_data = array('return_data' => FALSE); if (isset($this->_req_data['txn_admin_payment']) && isset($this->_req_data['txn_admin_payment']['TXN_ID'])) { //save the new payment $payment = EE_Payment::new_instance(array('TXN_ID' => $this->_req_data['txn_admin_payment']['TXN_ID'], 'STS_ID' => $this->_req_data['txn_admin_payment']['status'], 'PAY_timestamp' => $this->_req_data['txn_admin_payment']['date'], 'PAY_source' => EEM_Payment_Method::scope_admin, 'PMD_ID' => $this->_req_data['txn_admin_payment']['PMD_ID'], 'PAY_amount' => $this->_req_data['txn_admin_payment']['type'] < 0 ? abs($this->_req_data['txn_admin_payment']['amount']) * -1 : abs($this->_req_data['txn_admin_payment']['amount']), 'PAY_gateway_response' => '', 'PAY_txn_id_chq_nmbr' => $this->_req_data['txn_admin_payment']['txn_id_chq_nmbr'], 'PAY_po_number' => $this->_req_data['txn_admin_payment']['po_number'], 'PAY_extra_accntng' => $this->_req_data['txn_admin_payment']['accounting'], 'PAY_details' => $this->_req_data['txn_admin_payment'], 'PAY_ID' => $this->_req_data['txn_admin_payment']['PAY_ID'])); if (!$payment->save()) { $msg = __('An error occurred. The payment has not been processed successfully.', 'event_espresso'); EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); } // get the TXN for this payment $transaction = $payment->transaction(); // verify transaction if ($transaction instanceof EE_Transaction) { /** @type EE_Transaction_Payments $transaction_payments */ $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); //update the transaction with this payment if ($transaction_payments->calculate_total_payments_and_update_status($transaction)) { $msg = __('The payment has been processed successfully.', 'event_espresso'); EE_Error::add_success($msg, __FILE__, __FUNCTION__, __LINE__); } else { $msg = __('The payment was processed successfully but the amount paid for the transaction was not updated.', 'event_espresso'); EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__); } //EEH_Debug_Tools::printr( $payment, '$payment', __FILE__, __LINE__ ); // grab array of IDs for registrations to apply changes to if (isset($this->_req_data['txn_admin_payment']['registrations'])) { $REG_IDs = (array) $this->_req_data['txn_admin_payment']['registrations']; } else { $REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment); } $this->_remove_non_applicable_registration_payments($payment, $REG_IDs); // apply payment to registrations (if applicable) if (!empty($REG_IDs)) { //EEH_Debug_Tools::printr( $REG_IDs, '$REG_IDs', __FILE__, __LINE__ ); $registration_query_where_params = array('REG_ID' => array('IN', $REG_IDs)); $this->_process_updated_registration_payments($transaction, $payment, $registration_query_where_params); // now process status changes for the same registrations if (isset($this->_req_data['txn_reg_status_change'])) { $this->_process_registration_status_change($transaction, array($registration_query_where_params)); } } $this->_process_payment_notification($payment); //prepare to render page $this->_get_payment_status_array(); $json_response_data['return_data']['amount'] = $payment->amount(); $json_response_data['return_data']['total_paid'] = $transaction->paid(); $json_response_data['return_data']['txn_status'] = $transaction->status_ID(); $json_response_data['return_data']['pay_status'] = $payment->STS_ID(); $json_response_data['return_data']['PAY_ID'] = $payment->ID(); $json_response_data['return_data']['STS_ID'] = $payment->STS_ID(); $json_response_data['return_data']['status'] = self::$_pay_status[$payment->STS_ID()]; $json_response_data['return_data']['date'] = $payment->timestamp('Y-m-d', 'h:i a'); $json_response_data['return_data']['method'] = strtoupper($payment->source()); $json_response_data['return_data']['PM_ID'] = $payment->payment_method() ? $payment->payment_method()->ID() : 1; $json_response_data['return_data']['gateway'] = $payment->payment_method() ? $payment->payment_method()->admin_name() : __("Unknown", 'event_espresso'); $json_response_data['return_data']['gateway_response'] = $payment->gateway_response(); $json_response_data['return_data']['txn_id_chq_nmbr'] = $payment->txn_id_chq_nmbr(); $json_response_data['return_data']['po_number'] = $payment->po_number(); $json_response_data['return_data']['extra_accntng'] = $payment->extra_accntng(); $json_response_data['return_data']['registrations'] = array(); //if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows. if (!empty($registration_query_where_params)) { EE_Registry::instance()->load_helper('Template'); $registrations = EEM_Registration::instance()->get_all(array($registration_query_where_params)); foreach ($registrations as $registration) { $json_response_data['return_data']['registrations'][$registration->ID()] = array('owing' => EEH_Template::format_currency($registration->final_price() - $registration->paid()), 'paid' => $registration->pretty_paid()); } } } else { EE_Error::add_error(__('A valid Transaction for this payment could not be retrieved.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__); } } else { $msg = __('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_merge($json_response_data, $notices)); die; }
/** * 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; }
/** * 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); }
/** * 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); }
/** * _create_payment_from_request_data * * @param array $valid_data * @return EE_Payment */ protected function _create_payment_from_request_data($valid_data) { $PAY_ID = $valid_data['PAY_ID']; // get payment amount $amount = $valid_data['amount'] ? abs($valid_data['amount']) : 0; // payments have a type value of 1 and refunds have a type value of -1 // so multiplying amount by type will give a positive value for payments, and negative values for refunds $amount = $valid_data['type'] < 0 ? $amount * -1 : $amount; $payment = EE_Payment::new_instance(array('TXN_ID' => $valid_data['TXN_ID'], 'STS_ID' => $valid_data['status'], 'PAY_timestamp' => $valid_data['date'], 'PAY_source' => EEM_Payment_Method::scope_admin, 'PMD_ID' => $valid_data['PMD_ID'], 'PAY_amount' => $amount, 'PAY_txn_id_chq_nmbr' => $valid_data['txn_id_chq_nmbr'], 'PAY_po_number' => $valid_data['po_number'], 'PAY_extra_accntng' => $valid_data['accounting'], 'PAY_details' => $valid_data, 'PAY_ID' => $PAY_ID), '', array('Y-m-d', 'H:i a')); if (!$payment->save()) { EE_Error::add_error(sprintf(__('Payment %1$d has not been successfully saved to the database.', 'event_espresso'), $payment->ID()), __FILE__, __FUNCTION__, __LINE__); } return $payment; }
function test_sum_related() { $t = EE_Transaction::new_instance(); $t->save(); $p1 = EE_Payment::new_instance(array('PAY_amount' => 1, 'TXN_ID' => $t->ID())); $p1->save(); $p2 = EE_Payment::new_instance(array('PAY_amount' => 2, 'TXN_ID' => $t->ID())); $p2->save(); $p1 = EE_Payment::new_instance(array('PAY_amount' => 1000, 'TXN_ID' => 0)); $p1->save(); $this->assertEquals($t->sum_related('Payment', array(), 'PAY_amount'), 3); $t->_remove_relation_to($p2, 'Payment'); $this->assertEquals($t->sum_related('Payment', array(), 'PAY_amount'), 1); }
/** * test_create_new_payment_or_refund_from_request_data * used for tests that just need an EE_Payment object * * @since 4.8 * @param array $payment_details * @return EE_Payment */ protected function _generate_payment($payment_details) { // make sure refunds have a negative amount $payment_details['PAY_amount'] = $payment_details['type'] < 0 ? $payment_details['PAY_amount'] * -1 : $payment_details['PAY_amount']; // then remove 'type' from the payment details since it's not an EEM_Payment field unset($payment_details['type']); return EE_Payment::new_instance($payment_details, '', array('Y-m-d', 'H:i a')); }
/** * 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); }
/** * 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); }
/** * 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_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; }
/** * 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. * @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' => (int) current_time('timestamp'), 'PAY_gateway' => $txn->selected_gateway(), 'PAY_gateway_response' => $txn->gateway_response_on_transaction())); return $PMT; }