/**
     * 	get_payment_row_html
     *
     *  @access 	public
     *  @param 	EE_Payment	$payment
     *  @return 	string
     */
    public function get_payment_row_html($payment = NULL)
    {
        $html = '';
        if ($payment instanceof EE_Payment) {
            if ($payment->payment_method() instanceof EE_Payment_Method && $payment->payment_method()->is_off_site() && $payment->status() === EEM_Payment::status_id_failed) {
                // considering the registrant has made it to the Thank You page,
                // any failed payments may actually be pending and the IPN is just slow
                // so let's
                $payment->set_status(EEM_Payment::status_id_pending);
            }
            $payment_declined_msg = $payment->STS_ID() === EEM_Payment::status_id_declined ? '<br /><span class="small-text">' . $payment->gateway_response() . '</span>' : '';
            $html .= '
				<tr>
					<td>
						' . $payment->timestamp() . '
					</td>
					<td>
						' . ($payment->payment_method() instanceof EE_Payment_Method ? $payment->payment_method()->name() : __('Unknown', 'event_espresso')) . '
					</td>
					<td class="jst-rght">
						' . EEH_Template::format_currency($payment->amount()) . '
					</td>
					<td class="jst-rght" style="line-height:1;">
						' . $payment->pretty_status(TRUE) . $payment_declined_msg . '
					</td>
				</tr>';
            do_action('AHEE__thank_you_page_payment_details_template__after_each_payment', $payment);
        }
        return $html;
    }
 /**
  * This should be called each time there may have been an update to a
  * payment on a transaction (ie, we asked for a payment to process a
  * payment for a transaction, or we told a payment method about an IPN, or
  * we told a payment method to
  * "finalize_payment_for" (a transaction), or we told a payment method to
  * process a refund. This should handle firing the correct hooks to
  * indicate
  * what exactly happened and updating the transaction appropriately). This
  * could be integrated directly into EE_Transaction upon save, but we want
  * this logic to be separate from 'normal' plain-jane saving and updating
  * of transactions and payments, and to be tied to payment processing.
  * Note: this method DOES NOT save the payment passed into it. It is the responsibility
  * of previous code to decide whether or not to save (because the payment passed into
  * this method might be a temporary, never-to-be-saved payment from an offline gateway,
  * in which case we only want that payment object for some temporary usage during this request,
  * but we don't want it to be saved).
  *
  * @param EE_Transaction|int $transaction
  * @param EE_Payment     $payment
  * @param boolean        $update_txn
  *                        whether or not to call
  *                        EE_Transaction_Processor::
  *                        update_transaction_and_registrations_after_checkout_or_payment()
  *                        (you can save 1 DB query if you know you're going
  *                        to save it later instead)
  * @param bool           $IPN
  *                        if processing IPNs or other similar payment
  *                        related activities that occur in alternate
  *                        requests than the main one that is processing the
  *                        TXN, then set this to true to check whether the
  *                        TXN is locked before updating
  * @throws \EE_Error
  */
 public function update_txn_based_on_payment($transaction, $payment, $update_txn = true, $IPN = false)
 {
     $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__not_successful';
     /** @type EE_Transaction $transaction */
     $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction);
     // can we freely update the TXN at this moment?
     if ($IPN && $transaction->is_locked()) {
         // don't update the transaction at this exact moment
         // because the TXN is active in another request
         EE_Cron_Tasks::schedule_update_transaction_with_payment(time(), $transaction->ID(), $payment->ID());
     } else {
         // verify payment and that it has been saved
         if ($payment instanceof EE_Payment && $payment->ID()) {
             if ($payment->payment_method() instanceof EE_Payment_Method && $payment->payment_method()->type_obj() instanceof EE_PMT_Base) {
                 $payment->payment_method()->type_obj()->update_txn_based_on_payment($payment);
                 // update TXN registrations with payment info
                 $this->process_registration_payments($transaction, $payment);
             }
             $do_action = $payment->just_approved() ? 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful' : $do_action;
         } else {
             // send out notifications
             add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true');
             $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__no_payment_made';
         }
         // if this is an IPN, then we want to know the initial TXN status prior to updating the TXN
         // so that we know whether the status has changed and notifications should be triggered
         if ($IPN) {
             /** @type EE_Transaction_Processor $transaction_processor */
             $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
             $transaction_processor->set_old_txn_status($transaction->status_ID());
         }
         if ($payment->status() !== EEM_Payment::status_id_failed) {
             /** @type EE_Transaction_Payments $transaction_payments */
             $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments');
             // set new value for total paid
             $transaction_payments->calculate_total_payments_and_update_status($transaction);
             // call EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() ???
             if ($update_txn) {
                 $this->_post_payment_processing($transaction, $payment, $IPN);
             }
         }
         // granular hook for others to use.
         do_action($do_action, $transaction, $payment);
         do_action('AHEE_log', __CLASS__, __FUNCTION__, $do_action, '$do_action');
         //global hook for others to use.
         do_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', $transaction, $payment);
     }
 }
 /**
  * _build_payment_json_response
  *
  * @access public
  * @param \EE_Payment $payment
  * @param array       $REG_IDs
  * @param bool | null        $delete_txn_reg_status_change
  * @return array
  */
 protected function _build_payment_json_response(EE_Payment $payment, $REG_IDs = array(), $delete_txn_reg_status_change = null)
 {
     // was the payment deleted ?
     if (is_bool($delete_txn_reg_status_change)) {
         return array('PAY_ID' => $payment->ID(), 'amount' => $payment->amount(), 'total_paid' => $payment->transaction()->paid(), 'txn_status' => $payment->transaction()->status_ID(), 'pay_status' => $payment->STS_ID(), 'registrations' => $this->_registration_payment_data_array($REG_IDs), 'delete_txn_reg_status_change' => $delete_txn_reg_status_change);
     } else {
         $this->_get_payment_status_array();
         return array('amount' => $payment->amount(), 'total_paid' => $payment->transaction()->paid(), 'txn_status' => $payment->transaction()->status_ID(), 'pay_status' => $payment->STS_ID(), 'PAY_ID' => $payment->ID(), 'STS_ID' => $payment->STS_ID(), 'status' => self::$_pay_status[$payment->STS_ID()], 'date' => $payment->timestamp('Y-m-d', 'h:i a'), 'method' => strtoupper($payment->source()), 'PM_ID' => $payment->payment_method() ? $payment->payment_method()->ID() : 1, 'gateway' => $payment->payment_method() ? $payment->payment_method()->admin_name() : __("Unknown", 'event_espresso'), 'gateway_response' => $payment->gateway_response(), 'txn_id_chq_nmbr' => $payment->txn_id_chq_nmbr(), 'po_number' => $payment->po_number(), 'extra_accntng' => $payment->extra_accntng(), 'registrations' => $this->_registration_payment_data_array($REG_IDs));
     }
 }