protected function _get_data_for_context($context, EE_Registration $registration, $id)
 {
     //use the registration to get the transaction.
     $transaction = $registration->transaction();
     //bail early if no transaction
     if (!$transaction instanceof EE_Transaction) {
         throw new EE_Error(__('The given registration does not have an associated transaction. Something is wrong.', 'event_espresso'));
     }
     $payment = !empty($id) ? EEM_Payment::instance()->get_one(array(array('PAY_ID' => $id, 'TXN_ID' => $transaction->ID()))) : 0;
     return array($transaction, $payment);
 }
 /**
  * @since 4.6.0
  */
 public function test_get_payments_between_dates()
 {
     $timezone = new DateTimeZone('America/Toronto');
     //set $now in the timezone being tested.
     $now = new DateTime('now', $timezone);
     $this->_setup_payments($now, $timezone);
     //test defaults
     $this->assertEquals(2, count(EEM_Payment::instance()->get_payments_made_between_dates()));
     //test including a date from past date for start date.
     $this->assertEquals(4, count(EEM_Payment::instance()->get_payments_made_between_dates($now->sub(new DateInterval('P2D'))->format('d/m/Y'), '', 'd/m/Y', 'America/Toronto')));
     //test including a date from past date for end date.
     $this->assertEquals(4, count(EEM_Payment::instance()->get_payments_made_between_dates('', $now->format('d/m/Y'), 'd/m/Y', 'America/Toronto')));
     //test including a date from upcoming date for start date
     $this->assertEquals(3, count(EEM_Payment::instance()->get_payments_made_between_dates($now->add(new DateInterval('P4D'))->format('d/m/Y'), '', 'd/m/Y', 'America/Toronto')));
     //test including a date from upcoming date for end date
     $this->assertEquals(3, count(EEM_Payment::instance()->get_payments_made_between_dates('', $now->format('d/m/Y'), 'd/m/Y', 'America/Toronto')));
     //test exception
     $this->setExpectedException('EE_Error');
     EEM_Payment::instance()->get_payments_made_between_dates('trigger_exception');
 }
 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());
 }
 /**
  *
  * @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;
 }
 /**
  * Process the IPN. Firstly, we'll hope we put the standard args into the IPN URL so
  * we can easily find what registration the IPN is for and what payment method.
  * However, if not, we'll give all payment methods a chance to claim it and process it.
  * If a payment is found for the IPN info, it is saved.
  *
  * @param array             $_req_data eg $_REQUEST
  * @param EE_Transaction|int $transaction          optional (or a transactions id)
  * @param EE_Payment_Method $payment_method       (or a slug or id of one)
  * @param boolean           $update_txn           whether or not to call
  *                                                EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment()
  * @param bool              $separate_IPN_request whether the IPN uses a separate request ( true like PayPal )
  *                                                or is processed manually ( false like Mijireh )
  * @throws EE_Error
  * @throws Exception
  * @return EE_Payment
  */
 public function process_ipn($_req_data, $transaction = null, $payment_method = null, $update_txn = true, $separate_IPN_request = true)
 {
     EE_Registry::instance()->load_model('Change_Log');
     $_req_data = $this->_remove_unusable_characters_from_array((array) $_req_data);
     EE_Processor_Base::set_IPN($separate_IPN_request);
     $obj_for_log = null;
     if ($transaction instanceof EE_Transaction) {
         $obj_for_log = $transaction;
         if ($payment_method instanceof EE_Payment_Method) {
             $obj_for_log = EEM_Payment::instance()->get_one(array(array('TXN_ID' => $transaction->ID(), 'PMD_ID' => $payment_method->ID()), 'order_by' => array('PAY_timestamp' => 'desc')));
         }
     } else {
         if ($payment_method instanceof EE_Payment) {
             $obj_for_log = $payment_method;
         }
     }
     $log = EEM_Change_Log::instance()->log(EEM_Change_Log::type_gateway, array('IPN data received' => $_req_data), $obj_for_log);
     try {
         /**
          * @var EE_Payment $payment
          */
         $payment = NULL;
         if ($transaction && $payment_method) {
             /** @type EE_Transaction $transaction */
             $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction);
             /** @type EE_Payment_Method $payment_method */
             $payment_method = EEM_Payment_Method::instance()->ensure_is_obj($payment_method);
             if ($payment_method->type_obj() instanceof EE_PMT_Base) {
                 $payment = $payment_method->type_obj()->handle_ipn($_req_data, $transaction);
                 $log->set_object($payment);
             } else {
                 // not a payment
                 EE_Error::add_error(sprintf(__('A valid payment method could not be determined due to a technical issue.%sPlease refresh your browser and try again or contact %s for assistance.', 'event_espresso'), '<br/>', EE_Registry::instance()->CFG->organization->get_pretty('email')), __FILE__, __FUNCTION__, __LINE__);
             }
         } else {
             //that's actually pretty ok. The IPN just wasn't able
             //to identify which transaction or payment method this was for
             // give all active payment methods a chance to claim it
             $active_payment_methods = EEM_Payment_Method::instance()->get_all_active();
             foreach ($active_payment_methods as $active_payment_method) {
                 try {
                     $payment = $active_payment_method->type_obj()->handle_unclaimed_ipn($_req_data);
                     $payment_method = $active_payment_method;
                     EEM_Change_Log::instance()->log(EEM_Change_Log::type_gateway, array('IPN data' => $_req_data), $payment);
                     break;
                 } catch (EE_Error $e) {
                     //that's fine- it apparently couldn't handle the IPN
                 }
             }
         }
         // 			EEM_Payment_Log::instance()->log("got to 7",$transaction,$payment_method);
         if ($payment instanceof EE_Payment) {
             $payment->save();
             //  update the TXN
             $this->update_txn_based_on_payment($transaction, $payment, $update_txn, $separate_IPN_request);
         } else {
             //we couldn't find the payment for this IPN... let's try and log at least SOMETHING
             if ($payment_method) {
                 EEM_Change_Log::instance()->log(EEM_Change_Log::type_gateway, array('IPN data' => $_req_data), $payment_method);
             } elseif ($transaction) {
                 EEM_Change_Log::instance()->log(EEM_Change_Log::type_gateway, array('IPN data' => $_req_data), $transaction);
             }
         }
         return $payment;
     } catch (EE_Error $e) {
         do_action('AHEE__log', __FILE__, __FUNCTION__, sprintf(__('Error occurred while receiving IPN. Transaction: %1$s, req data: %2$s. The error was "%3$s"', 'event_espresso'), print_r($transaction, TRUE), print_r($_req_data, TRUE), $e->getMessage()));
         throw $e;
     }
 }
 /**
  * delete_payment
  * 	delete a payment or refund made towards a transaction
  *
  * @access public
  *	@return void
  */
 public function delete_payment()
 {
     $json_response_data = array('return_data' => FALSE);
     $PAY_ID = isset($this->_req_data['delete_txn_admin_payment'], $this->_req_data['delete_txn_admin_payment']['PAY_ID']) ? absint($this->_req_data['delete_txn_admin_payment']['PAY_ID']) : 0;
     if ($PAY_ID) {
         $delete_txn_reg_status_change = isset($this->_req_data['delete_txn_reg_status_change']) ? $this->_req_data['delete_txn_reg_status_change'] : false;
         $payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
         if ($payment instanceof EE_Payment) {
             $REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
             /** @type EE_Transaction_Payments $transaction_payments */
             $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
             if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
                 EE_Error::add_success(__('The Payment was successfully deleted.', 'event_espresso'));
                 $json_response_data['return_data'] = array('PAY_ID' => $PAY_ID, 'amount' => $payment->amount(), 'total_paid' => $payment->transaction()->paid(), 'txn_status' => $payment->transaction()->status_ID(), 'pay_status' => $payment->STS_ID(), 'delete_txn_reg_status_change' => $delete_txn_reg_status_change);
                 //if non empty reg_ids lets get an array of registrations and update the values for the apply_payment/refund rows.
                 if (!empty($REG_IDs)) {
                     EE_Registry::instance()->load_helper('Template');
                     $registrations = EEM_Registration::instance()->get_all(array(array('REG_ID' => array('IN', $REG_IDs))));
                     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());
                     }
                 }
                 if ($delete_txn_reg_status_change) {
                     $this->_req_data['txn_reg_status_change'] = $delete_txn_reg_status_change;
                     //MAKE sure we also add the delete_txn_req_status_change to the
                     //$_REQUEST global because that's how messages will be looking
                     //for it.
                     $_REQUEST['txn_reg_status_change'] = $delete_txn_reg_status_change;
                     $this->_process_registration_status_change($payment->transaction());
                 }
             }
         } else {
             EE_Error::add_error(__('Valid Payment data could not be retrieved from the database.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
         }
     } else {
         $msg = __('A valid Payment ID was not received, therefore 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;
 }
 /**
  * Data that has been stored in persistent storage that was prepped by _convert_data_for_persistent_storage
  * can be sent into this method and converted back into the format used for instantiating with this data handler.
  *
  * @param array  $data
  *
  * @return array
  */
 public static function convert_data_from_persistent_storage($data)
 {
     $prepped_data = array(0 => isset($data['Transaction']) ? EEM_Transaction::instance()->get_one_by_ID($data['Transaction']) : null, 1 => isset($data['Payment']) ? EEM_Payment::instance()->get_one_by_ID($data['Payment']) : null, 2 => isset($data['filter']) ? $data['filter'] : null);
     return $prepped_data;
 }
 /**
  * recalculate_total_payments_for_transaction
  *
  * @access public
  * @param EE_Transaction $transaction
  * @param string         $payment_status One of EEM_Payment's statuses, like 'PAP' (Approved).
  *                                       By default, searches for approved payments
  * @return float|false   float on success, false on fail
  * @throws \EE_Error
  */
 public function recalculate_total_payments_for_transaction(EE_Transaction $transaction, $payment_status = EEM_Payment::status_id_approved)
 {
     // verify transaction
     if (!$transaction instanceof EE_Transaction) {
         EE_Error::add_error(__('Please provide a valid EE_Transaction object.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
         return false;
     }
     // ensure Payment model is loaded
     EE_Registry::instance()->load_model('Payment');
     // calls EEM_Base::sum()
     return EEM_Payment::instance()->sum(array(array('TXN_ID' => $transaction->ID(), 'STS_ID' => $payment_status)), 'PAY_amount');
 }
 /**
  * @group 7151
  */
 function test_fresh_entity_map_with()
 {
     $p = $this->new_model_obj_with_dependencies('Payment', array('PAY_amount' => 25));
     $p->save();
     $this->assertEquals($p, EEM_Payment::instance()->get_from_entity_map($p->ID()));
     //now purposefully make a naughty payment which isn't in the entity map
     $p2 = clone $p;
     $this->assertFalse($p2->in_entity_map());
     //make the two EE_Payments diverge
     $p2->set('PAY_amount', 99);
     $t = EE_Transaction::new_instance();
     $p2->cache('Transaction', $t);
     $this->assertEquals(25, $p->get('PAY_amount'));
     $this->assertEquals(99, $p2->get('PAY_amount'));
     $this->assertNotEquals($p->get_all_from_cache('Transaction'), $p2->get_all_from_cache('Transaction'));
     //now update the payment in the entity map with the other
     EEM_Payment::instance()->refresh_entity_map_with($p->ID(), $p2);
     $this->assertEquals(99, $p->get('PAY_amount'));
     //make sure p hasn't changed into p2. that's not what we wanted to do...
     $this->assertFalse($p2 === $p);
     //We wanted to just UPDATE p with p2's values
     $this->assertEquals($p, EEM_Payment::instance()->get_from_entity_map($p->ID()));
     //and make sure p's cache was updated to be the same as p2's
     $this->assertEquals($p2->get_all_from_cache('Transaction'), $p->get_all_from_cache('Transaction'));
 }
 /**
  * test_build_payment_json_response_for_payment
  * @since    4.8
  * @group    8620
  */
 public function test_build_payment_json_response_for_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);
     $pay_status = EEM_Payment::instance()->status_array(true);
     $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->assertEquals(EEM_Payment::status_id_approved, $json_response_data['STS_ID']);
     $this->assertEquals($pay_status[EEM_Payment::status_id_approved], $json_response_data['status']);
     $this->assertEquals($this->_payment->ID(), $json_response_data['PAY_ID']);
     $this->assertEquals($this->_payment->timestamp('Y-m-d', 'h:i a'), $json_response_data['date']);
     $this->assertEquals(strtoupper($this->_payment->source()), $json_response_data['method']);
     $this->assertEquals($this->_payment_method()->ID(), $json_response_data['PM_ID']);
     $this->assertEquals($this->_payment_method()->admin_name(), $json_response_data['gateway']);
     $this->assertEquals($this->_payment->gateway_response(), $json_response_data['gateway_response']);
     $this->assertEquals($this->_payment->txn_id_chq_nmbr(), $json_response_data['txn_id_chq_nmbr']);
     $this->assertEquals($this->_payment->po_number(), $json_response_data['po_number']);
     $this->assertEquals($this->_payment->extra_accntng(), $json_response_data['extra_accntng']);
     $this->assertEquals($this->_payment->extra_accntng(), $json_response_data['extra_accntng']);
     // will validate $json_response_data[ 'registrations' ] in test_registration_payment_data_array()
 }
 /**
  * 		delete a payment or refund made towards a transaction
  *		@access public
  *		@return void
  */
 public function delete_payment()
 {
     $return_data = array();
     if (isset($this->_req_data['delete_txn_admin_payment'])) {
         $pymt = $this->_req_data['delete_txn_admin_payment'];
         if ($payment = EEM_Payment::instance()->get_one_by_ID($pymt['PAY_ID'])) {
             if ($transaction = EEM_Payment::instance()->delete_by_ID($payment->ID())) {
                 $return_data = array('amount' => $payment->amount(), 'total_paid' => $transaction->paid(), 'txn_status' => $transaction->status_ID(), 'pay_status' => $payment->STS_ID(), 'PAY_ID' => $pymt['PAY_ID'], 'delete_txn_reg_status_change' => $this->_req_data['delete_txn_reg_status_change']);
             }
         }
         if (isset($this->_req_data['delete_txn_reg_status_change'])) {
             $this->_req_data['txn_reg_status_change'] = $this->_req_data['delete_txn_reg_status_change'];
             $_REQUEST['txn_reg_status_change'] = $this->_req_data['delete_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__);
         $return_data = FALSE;
     }
     $notices = EE_Error::get_notices(FALSE, FALSE, FALSE);
     echo json_encode(array('return_data' => $return_data, 'success' => $notices['success'], 'errors' => $notices['errors']));
     die;
 }
Ejemplo n.º 12
0
 protected function __construct(EEM_Gateways &$model)
 {
     do_action('AHEE_log', __FILE__, __FUNCTION__, '');
     //echo '<h4>$this->_gateway_name : ' . $this->_gateway_name . '  <br /><span style="font-size:10px;font-weight:normal;">' . __FILE__ . '<br />line no: ' . __LINE__ . '</span></h4>';
     if (!defined('GATEWAYS_ADMIN_URL')) {
         define('GATEWAYS_ADMIN_URL', admin_url('admin.php?page=espresso_payment_settings'));
     }
     $this->_EEM_Gateways = $model;
     require_once EE_MODELS . 'EEM_Transaction.model.php';
     require_once EE_CLASSES . 'EE_Transaction.class.php';
     $this->_TXN = EEM_Transaction::instance();
     require_once EE_MODELS . 'EEM_Payment.model.php';
     require_once EE_CLASSES . 'EE_Payment.class.php';
     $this->_PAY = EEM_Payment::instance();
     require_once EE_MODELS . 'EEM_Registration.model.php';
     require_once EE_CLASSES . 'EE_Registration.class.php';
     $this->_REG = EEM_Registration::instance();
     if (!$this->_btn_img) {
         $this->_btn_img = EE_GATEWAYS_URL . $this->_gateway_name . DS . 'lib' . DS . $this->_button_base;
     }
     $this->_set_default_properties();
     $this->_handle_payment_settings();
     if (is_admin() && !empty($_GET['page']) && $_GET['page'] == 'espresso_payment_settings') {
         $this->_gateways_admin();
     } else {
         $this->_gateways_frontend();
     }
     //load formatter helper and form fields helper
     EE_Registry::instance()->load_helper('Formatter');
     EE_Registry::instance()->load_helper('Form_Fields');
 }
 /**
  * update_transaction_with_payment
  *
  * loops through the self::$_abandoned_transactions array
  * and attempts to finalize any TXNs that have not been completed
  * but have had their sessions expired, most likely due to a user not
  * returning from an off-site payment gateway
  * 
  * @throws \EE_Error
  */
 public static function update_transaction_with_payment()
 {
     do_action('AHEE_log', __CLASS__, __FUNCTION__);
     // are there any TXNs that need cleaning up ?
     if (!empty(self::$_update_transactions_with_payment)) {
         /** @type EE_Payment_Processor $payment_processor */
         $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
         // set revisit flag for payment processor
         $payment_processor->set_revisit(false);
         // load EEM_Transaction
         EE_Registry::instance()->load_model('Transaction');
         foreach (self::$_update_transactions_with_payment as $TXN_ID => $PAY_ID) {
             // reschedule the cron if we can't hit the db right now
             if (!EE_Maintenance_Mode::instance()->models_can_query()) {
                 // reset cron job for updating the TXN
                 EE_Cron_Tasks::schedule_update_transaction_with_payment(time() + EE_Cron_Tasks::reschedule_timeout, $TXN_ID, $PAY_ID);
                 continue;
             }
             $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
             $payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
             // verify transaction
             if ($transaction instanceof EE_Transaction && $payment instanceof EE_Payment) {
                 // now try to update the TXN with any payments
                 $payment_processor->update_txn_based_on_payment($transaction, $payment, true, true);
             }
             unset(self::$_update_transactions_with_payment[$TXN_ID]);
         }
     }
 }
 /**
  * delete_payment
  * 	delete a payment or refund made towards a transaction
  *
  * @access public
  *	@return void
  */
 public function delete_payment()
 {
     $json_response_data = array('return_data' => FALSE);
     $PAY_ID = isset($this->_req_data['delete_txn_admin_payment'], $this->_req_data['delete_txn_admin_payment']['PAY_ID']) ? absint($this->_req_data['delete_txn_admin_payment']['PAY_ID']) : 0;
     if ($PAY_ID) {
         $delete_txn_reg_status_change = isset($this->_req_data['delete_txn_reg_status_change']) ? $this->_req_data['delete_txn_reg_status_change'] : false;
         $payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
         if ($payment instanceof EE_Payment) {
             /** @type EE_Transaction_Payments $transaction_payments */
             $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
             if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
                 EE_Error::add_success(__('The Payment was successfully deleted.', 'event_espresso'));
                 $json_response_data['return_data'] = array('PAY_ID' => $PAY_ID, 'amount' => $payment->amount(), 'total_paid' => $payment->transaction()->paid(), 'txn_status' => $payment->transaction()->status_ID(), 'pay_status' => $payment->STS_ID(), 'delete_txn_reg_status_change' => $delete_txn_reg_status_change);
                 if ($delete_txn_reg_status_change) {
                     $this->_req_data['txn_reg_status_change'] = $delete_txn_reg_status_change;
                     //MAKE sure we also add the delete_txn_req_status_change to the
                     //$_REQUEST global because that's how messages will be looking
                     //for it.
                     $_REQUEST['txn_reg_status_change'] = $delete_txn_reg_status_change;
                     $this->_process_registration_status_change($payment->transaction());
                 }
             }
         } else {
             EE_Error::add_error(__('Valid Payment data could not be retrieved from the database.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
         }
     } else {
         $msg = __('A valid Payment ID was not received, therefore 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;
 }
 /**
  * return the payment object for a given payment ID
  *
  * @since 4.3.0
  *
  * @param int $PMT_ID the payment id for the payment to attempt to retrieve
  *
  * @return mixed null|EE_Payment
  */
 public function get_object_by_id($PMT_ID)
 {
     return EEM_Payment::instance()->get_one_by_ID($PMT_ID);
 }
 public function test_process_payment__offsite__declined_then_approved()
 {
     /** @type EE_Payment_Method $pm */
     $pm = $this->new_model_obj_with_dependencies('Payment_Method', array('PMD_type' => 'Mock_Offsite'));
     $transaction = $this->_new_typical_transaction();
     global $wp_actions;
     EE_Registry::instance()->load_helper('Array');
     $successful_payment_actions = EEH_Array::is_set($wp_actions, 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful', 0);
     /** @type EE_Payment_Processor $payment_processor */
     $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
     $payment = $payment_processor->process_payment($pm, $transaction, NULL, NULL, 'success', 'CART', TRUE, TRUE);
     $this->assertInstanceOf('EE_Payment', $payment);
     //verify it's already been saved
     $this->assertNotEquals(0, $payment->ID());
     //assert that the payment still has its default status
     $this->assertEquals(EEM_Payment::instance()->field_settings_for('STS_ID')->get_default_value(), $payment->status());
     $this->assertEquals(EEM_Payment::instance()->field_settings_for('STS_ID')->get_default_value(), $this->_get_payment_status_in_db($payment));
     //assert that the we haven't notified of successful payment JUST yet...
     $this->assertEquals($successful_payment_actions, EEH_Array::is_set($wp_actions, 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful', 0));
     //PENDING IPN
     $payment = $payment_processor->process_ipn(array('status' => EEM_Payment::status_id_pending, 'gateway_txn_id' => $payment->txn_id_chq_nmbr()), $transaction, $pm);
     $this->assertEquals(EEM_Payment::status_id_pending, $payment->status());
     $this->assertEquals(EEM_Payment::status_id_pending, $this->_get_payment_status_in_db($payment));
     //and the payment-approved action should have NOT been triggered
     $this->assertEquals($successful_payment_actions, EEH_Array::is_set($wp_actions, 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful', 0));
     //APPROVED IPN
     $payment = $payment_processor->process_ipn(array('status' => EEM_Payment::status_id_approved, 'gateway_txn_id' => $payment->txn_id_chq_nmbr()), $transaction, $pm);
     //payment should be what the gateway set it to be, which was approved
     $this->assertEquals(EEM_Payment::status_id_approved, $payment->status());
     $this->assertEquals(EEM_Payment::status_id_approved, $this->_get_payment_status_in_db($payment));
     //and the payment-approved action should have been triggered
     $this->assertEquals($successful_payment_actions + 1, EEH_Array::is_set($wp_actions, 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful', 0));
     //DUPLICATE SUCCESS IPN
     //for this, we need to reset payment model so we fetch a NEW payment object, instead of reusing the old
     //and because the payment method caches a payment method type which caches a gateway which caches the payment model,
     //we also need to reset the payment method
     EEM_Payment::reset();
     $pm = EEM_Payment_Method::reset()->get_one_by_ID($pm->ID());
     $payment = $payment_processor->process_ipn(array('status' => EEM_Payment::status_id_approved, 'gateway_txn_id' => $payment->txn_id_chq_nmbr()), $transaction, $pm);
     //payment should be what the gateway set it to be, which was failed
     $this->assertEquals(EEM_Payment::status_id_approved, $payment->status());
     //and the payment-approved action should have NOT been triggered this time because it's a duplicate
     $this->assertEquals($successful_payment_actions + 1, EEH_Array::is_set($wp_actions, 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful', 0));
 }
Ejemplo n.º 17
0
 /**
  * Export a custom CSV of registration info including: A bunch of the reg fields, the time of the event, the price name,
  * and the questions associated with the registrations
  * @param int $event_id
  */
 function report_registrations_for_event($event_id = NULL)
 {
     $reg_fields_to_include = array('TXN_ID', 'ATT_ID', 'REG_ID', 'REG_date', 'REG_code', 'REG_count', 'REG_final_price');
     $att_fields_to_include = array('ATT_fname', 'ATT_lname', 'ATT_email', 'ATT_address', 'ATT_address2', 'ATT_city', 'STA_ID', 'CNT_ISO', 'ATT_zip', 'ATT_phone');
     $registrations_csv_ready_array = array();
     $reg_model = EE_Registry::instance()->load_model('Registration');
     $query_params = apply_filters('FHEE__EE_Export__report_registration_for_event', array(array('OR' => array('Transaction.STS_ID' => array('NOT IN', array(EEM_Transaction::failed_status_code, EEM_Transaction::abandoned_status_code)), 'STS_ID' => EEM_Registration::status_id_approved), 'Ticket.TKT_deleted' => array('IN', array(true, false))), 'order_by' => array('Transaction.TXN_ID' => 'asc', 'REG_count' => 'asc'), 'force_join' => array('Transaction', 'Ticket', 'Attendee'), 'caps' => EEM_Base::caps_read_admin), $event_id);
     if ($event_id) {
         $query_params[0]['EVT_ID'] = $event_id;
     } else {
         $query_params['force_join'][] = 'Event';
     }
     $registration_rows = $reg_model->get_all_wpdb_results($query_params);
     //get all questions which relate to someone in this group
     $registration_ids = array();
     foreach ($registration_rows as $reg_row) {
         $registration_ids[] = intval($reg_row['Registration.REG_ID']);
     }
     //		EEM_Question::instance()->show_next_x_db_queries();
     $questions_for_these_regs_rows = EEM_Question::instance()->get_all_wpdb_results(array(array('Answer.REG_ID' => array('IN', $registration_ids))));
     foreach ($registration_rows as $reg_row) {
         if (is_array($reg_row)) {
             $reg_csv_array = array();
             if (!$event_id) {
                 //get the event's name and Id
                 $reg_csv_array[__('Event', 'event_espresso')] = sprintf(__('%1$s (%2$s)', 'event_espresso'), $this->_prepare_value_from_db_for_display(EEM_Event::instance(), 'EVT_name', $reg_row['Event_CPT.post_title']), $reg_row['Event_CPT.ID']);
             }
             $is_primary_reg = $reg_row['Registration.REG_count'] == '1' ? true : false;
             /*@var $reg_row EE_Registration */
             foreach ($reg_fields_to_include as $field_name) {
                 $field = $reg_model->field_settings_for($field_name);
                 if ($field_name == 'REG_final_price') {
                     $value = $this->_prepare_value_from_db_for_display($reg_model, $field_name, $reg_row['Registration.REG_final_price'], 'localized_float');
                 } elseif ($field_name == 'REG_count') {
                     $value = sprintf(__('%s of %s', 'event_espresso'), $this->_prepare_value_from_db_for_display($reg_model, 'REG_count', $reg_row['Registration.REG_count']), $this->_prepare_value_from_db_for_display($reg_model, 'REG_group_size', $reg_row['Registration.REG_group_size']));
                 } elseif ($field_name == 'REG_date') {
                     $value = $this->_prepare_value_from_db_for_display($reg_model, $field_name, $reg_row['Registration.REG_date'], 'no_html');
                 } else {
                     $value = $this->_prepare_value_from_db_for_display($reg_model, $field_name, $reg_row[$field->get_qualified_column()]);
                 }
                 $reg_csv_array[$this->_get_column_name_for_field($field)] = $value;
                 if ($field_name == 'REG_final_price') {
                     //add a column named Currency after the final price
                     $reg_csv_array[__("Currency", "event_espresso")] = EE_Config::instance()->currency->code;
                 }
             }
             //get pretty status
             $stati = EEM_Status::instance()->localized_status(array($reg_row['Registration.STS_ID'] => __('unknown', 'event_espresso'), $reg_row['TransactionTable.STS_ID'] => __('unknown', 'event_espresso')), FALSE, 'sentence');
             $reg_csv_array[__("Registration Status", 'event_espresso')] = $stati[$reg_row['Registration.STS_ID']];
             //get pretty trnasaction status
             $reg_csv_array[__("Transaction Status", 'event_espresso')] = $stati[$reg_row['TransactionTable.STS_ID']];
             $reg_csv_array[__('Transaction Amount Due', 'event_espresso')] = $is_primary_reg ? $this->_prepare_value_from_db_for_display(EEM_Transaction::instance(), 'TXN_total', $reg_row['TransactionTable.TXN_total'], 'localized_float') : '0.00';
             $reg_csv_array[__('Amount Paid', 'event_espresso')] = $is_primary_reg ? $this->_prepare_value_from_db_for_display(EEM_Transaction::instance(), 'TXN_paid', $reg_row['TransactionTable.TXN_paid'], 'localized_float') : '0.00';
             $payment_methods = array();
             $gateway_txn_ids_etc = array();
             $payment_times = array();
             if ($is_primary_reg && $reg_row['TransactionTable.TXN_ID']) {
                 $payments_info = EEM_Payment::instance()->get_all_wpdb_results(array(array('TXN_ID' => $reg_row['TransactionTable.TXN_ID'], 'STS_ID' => EEM_Payment::status_id_approved), 'force_join' => array('Payment_Method')), ARRAY_A, 'Payment_Method.PMD_admin_name as name, Payment.PAY_txn_id_chq_nmbr as gateway_txn_id, Payment.PAY_timestamp as payment_time');
                 foreach ($payments_info as $payment_method_and_gateway_txn_id) {
                     $payment_methods[] = isset($payment_method_and_gateway_txn_id['name']) ? $payment_method_and_gateway_txn_id['name'] : __('Unknown', 'event_espresso');
                     $gateway_txn_ids_etc[] = isset($payment_method_and_gateway_txn_id['gateway_txn_id']) ? $payment_method_and_gateway_txn_id['gateway_txn_id'] : '';
                     $payment_times[] = isset($payment_method_and_gateway_txn_id['payment_time']) ? $payment_method_and_gateway_txn_id['payment_time'] : '';
                 }
             }
             $reg_csv_array[__('Payment Date(s)', 'event_espresso')] = implode(',', $payment_times);
             $reg_csv_array[__('Payment Method(s)', 'event_espresso')] = implode(",", $payment_methods);
             $reg_csv_array[__('Gateway Transaction ID(s)', 'event_espresso')] = implode(',', $gateway_txn_ids_etc);
             //get whether or not the user has checked in
             $reg_csv_array[__("Check-Ins", "event_espresso")] = $reg_model->count_related($reg_row['Registration.REG_ID'], 'Checkin');
             //get ticket of registration and its price
             $ticket_model = EE_Registry::instance()->load_model('Ticket');
             if ($reg_row['Ticket.TKT_ID']) {
                 $ticket_name = $this->_prepare_value_from_db_for_display($ticket_model, 'TKT_name', $reg_row['Ticket.TKT_name']);
                 $datetimes_strings = array();
                 foreach (EEM_Datetime::instance()->get_all_wpdb_results(array(array('Ticket.TKT_ID' => $reg_row['Ticket.TKT_ID']), 'order_by' => array('DTT_EVT_start' => 'ASC'), 'default_where_conditions' => 'none')) as $datetime) {
                     $datetimes_strings[] = $this->_prepare_value_from_db_for_display(EEM_Datetime::instance(), 'DTT_EVT_start', $datetime['Datetime.DTT_EVT_start']);
                 }
             } else {
                 $ticket_name = __('Unknown', 'event_espresso');
                 $datetimes_strings = array(__('Unknown', 'event_espresso'));
             }
             $reg_csv_array[$ticket_model->field_settings_for('TKT_name')->get_nicename()] = $ticket_name;
             $reg_csv_array[__("Datetimes of Ticket", "event_espresso")] = implode(", ", $datetimes_strings);
             //get datetime(s) of registration
             //add attendee columns
             foreach ($att_fields_to_include as $att_field_name) {
                 $field_obj = EEM_Attendee::instance()->field_settings_for($att_field_name);
                 if ($reg_row['Attendee_CPT.ID']) {
                     if ($att_field_name == 'STA_ID') {
                         $value = EEM_State::instance()->get_var(array(array('STA_ID' => $reg_row['Attendee_Meta.STA_ID'])), 'STA_name');
                     } elseif ($att_field_name == 'CNT_ISO') {
                         $value = EEM_Country::instance()->get_var(array(array('CNT_ISO' => $reg_row['Attendee_Meta.CNT_ISO'])), 'CNT_name');
                     } else {
                         $value = $this->_prepare_value_from_db_for_display(EEM_Attendee::instance(), $att_field_name, $reg_row[$field_obj->get_qualified_column()]);
                     }
                 } else {
                     $value = '';
                 }
                 $reg_csv_array[$this->_get_column_name_for_field($field_obj)] = $value;
             }
             //make sure each registration has the same questions in the same order
             foreach ($questions_for_these_regs_rows as $question_row) {
                 if (!isset($reg_csv_array[$question_row['Question.QST_admin_label']])) {
                     $reg_csv_array[$question_row['Question.QST_admin_label']] = null;
                 }
             }
             //now fill out the questions THEY answered
             foreach (EEM_Answer::instance()->get_all_wpdb_results(array(array('REG_ID' => $reg_row['Registration.REG_ID']), 'force_join' => array('Question'))) as $answer_row) {
                 /* @var $answer EE_Answer */
                 if ($answer_row['Question.QST_ID']) {
                     $question_label = $this->_prepare_value_from_db_for_display(EEM_Question::instance(), 'QST_admin_label', $answer_row['Question.QST_admin_label']);
                 } else {
                     $question_label = sprintf(__('Question $s', 'event_espresso'), $answer_row['Answer.QST_ID']);
                 }
                 if (isset($answer_row['Question.QST_type']) && $answer_row['Question.QST_type'] == EEM_Question::QST_type_state) {
                     $reg_csv_array[$question_label] = EEM_State::instance()->get_state_name_by_ID($answer_row['Answer.ANS_value']);
                 } else {
                     $reg_csv_array[$question_label] = $this->_prepare_value_from_db_for_display(EEM_Answer::instance(), 'ANS_value', $answer_row['Answer.ANS_value']);
                 }
             }
             $registrations_csv_ready_array[] = apply_filters('FHEE__EE_Export__report_registrations__reg_csv_array', $reg_csv_array, $reg_row);
         }
     }
     //if we couldn't export anything, we want to at least show the column headers
     if (empty($registrations_csv_ready_array)) {
         $reg_csv_array = array();
         $model_and_fields_to_include = array('Registration' => $reg_fields_to_include, 'Attendee' => $att_fields_to_include);
         foreach ($model_and_fields_to_include as $model_name => $field_list) {
             $model = EE_Registry::instance()->load_model($model_name);
             foreach ($field_list as $field_name) {
                 $field = $model->field_settings_for($field_name);
                 $reg_csv_array[$this->_get_column_name_for_field($field)] = null;
                 //$registration->get($field->get_name());
             }
         }
         $registrations_csv_ready_array[] = $reg_csv_array;
     }
     if ($event_id) {
         $event_slug = EEM_Event::instance()->get_var(array(array('EVT_ID' => $event_id)), 'EVT_slug');
         if (!$event_slug) {
             $event_slug = __('unknown', 'event_espresso');
         }
     } else {
         $event_slug = __('all', 'event_espresso');
     }
     $filename = sprintf("registrations-for-%s", $event_slug);
     $handle = $this->EE_CSV->begin_sending_csv($filename);
     $this->EE_CSV->write_data_array_to_csv($handle, $registrations_csv_ready_array);
     $this->EE_CSV->end_sending_csv($handle);
 }
 /**
  * delete_payment
  * 	delete a payment or refund made towards a transaction
  *
  * @access public
  *	@return void
  */
 public function delete_payment()
 {
     $json_response_data = array('return_data' => FALSE);
     $PAY_ID = isset($this->_req_data['delete_txn_admin_payment'], $this->_req_data['delete_txn_admin_payment']['PAY_ID']) ? absint($this->_req_data['delete_txn_admin_payment']['PAY_ID']) : 0;
     if ($PAY_ID) {
         $delete_txn_reg_status_change = isset($this->_req_data['delete_txn_reg_status_change']) ? $this->_req_data['delete_txn_reg_status_change'] : false;
         $payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
         if ($payment instanceof EE_Payment) {
             $REG_IDs = $this->_get_existing_reg_payment_REG_IDs($payment);
             /** @type EE_Transaction_Payments $transaction_payments */
             $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
             if ($transaction_payments->delete_payment_and_update_transaction($payment)) {
                 $json_response_data['return_data'] = $this->_build_payment_json_response($payment, $REG_IDs, $delete_txn_reg_status_change);
                 if ($delete_txn_reg_status_change) {
                     $this->_req_data['txn_reg_status_change'] = $delete_txn_reg_status_change;
                     //MAKE sure we also add the delete_txn_req_status_change to the
                     //$_REQUEST global because that's how messages will be looking for it.
                     $_REQUEST['txn_reg_status_change'] = $delete_txn_reg_status_change;
                     $this->_maybe_send_notifications();
                     $this->_process_registration_status_change($payment->transaction(), $REG_IDs);
                 }
             }
         } else {
             EE_Error::add_error(__('Valid Payment data could not be retrieved from the database.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
         }
     } else {
         EE_Error::add_error(__('A valid Payment ID was not received, therefore payment form data could not be loaded.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
     }
     $notices = EE_Error::get_notices(false, false, false);
     $this->_template_args = array('data' => $json_response_data, 'success' => $notices['success'], 'error' => $notices['errors'], 'attention' => $notices['attention']);
     $this->_return_json();
 }