/**
  * Handles the payment update (note: mijireh doesn't send an IPN in the usual sense,
  * instead they just redirect the user back to our website and then we need to query them
  * for the payment's status). Also note that the $update_info should be an array with the key
  * 'payment' containing the EEI_Payment to update
  * @param array $update_info unused. We just use the $transaction
  * @param EEI_Transaction $transaction
  * @throws EE_Error
  */
 public function handle_payment_update($update_info, $transaction)
 {
     $payment = $transaction instanceof EEI_Transaction ? $transaction->last_payment() : NULL;
     if ($payment && $payment instanceof EEI_Payment) {
         $url = 'https://secure.mijireh.com/api/1/orders/' . $payment->txn_id_chq_nmbr();
         $request_args = array('headers' => array('Authorization' => 'Basic ' . base64_encode($this->_access_key . ':'), 'Accept' => 'application/json'));
         $response = wp_remote_get($url, $request_args);
         $this->log(array('get payment status request_args' => $request_args, 'response' => $response), $payment);
         if ($response && isset($response['body']) && ($response_body = json_decode($response['body']))) {
             switch ($response_body->status) {
                 case 'paid':
                     $payment->set_status($this->_pay_model->approved_status());
                     break;
                 case 'pending':
                     $payment->set_status($this->_pay_model->pending_status());
                     break;
                 default:
                     $payment->set_status($this->_pay_model->declined_status());
             }
         } else {
             $payment->set_gateway_response(__('Response from Mijireh could not be understood.', 'event_espresso'));
             $payment->set_details($response);
             $payment->set_status($this->_pay_model->failed_status());
         }
         return $payment;
     } else {
         throw new EE_Error(sprintf(__("Could not find Mijireh payment for transaction %s", 'event_espresso'), $transaction->ID()));
     }
 }
 /**
  * Often used for IPNs. But applies the info in $update_info to the payment.
  * What is $update_info? Often the contents of $_REQUEST, but not necessarily. Whatever
  * the payment method passes in.
  * @param array $update_info like $_POST
  * @param EEI_Transaction $transaction
  * @return \EEI_Payment updated
  * @throws \EE_Error
  */
 public function handle_payment_update($update_info, $transaction)
 {
     //verify there's payment data that's been sent
     if (empty($update_info['payment_status']) || empty($update_info['txn_id'])) {
         // waaaait... is this a PDT request? (see https://developer.paypal.com/docs/classic/products/payment-data-transfer/)
         // indicated by the "tx" argument? If so, we don't need it. We'll just use the IPN data when it comes
         if (isset($update_info['tx'])) {
             return $transaction->last_payment();
         } else {
             return null;
         }
     }
     $payment = $this->_pay_model->get_payment_by_txn_id_chq_nmbr($update_info['txn_id']);
     if (!$payment instanceof EEI_Payment) {
         $payment = $transaction->last_payment();
     }
     // 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->validate_ipn($update_info, $payment)) {
         return $payment;
     }
     //ok, well let's process this payment then!
     switch ($update_info['payment_status']) {
         case 'Completed':
             $status = $this->_pay_model->approved_status();
             $gateway_response = __('The payment is approved.', 'event_espresso');
             break;
         case 'Pending':
             $status = $this->_pay_model->pending_status();
             $gateway_response = __('The payment is in progress. Another message will be sent when payment is approved.', 'event_espresso');
             break;
         case 'Denied':
             $status = $this->_pay_model->declined_status();
             $gateway_response = __('The payment has been declined.', 'event_espresso');
             break;
         case 'Expired':
         case 'Failed':
             $status = $this->_pay_model->failed_status();
             $gateway_response = __('The payment failed for technical reasons or expired.', 'event_espresso');
             break;
         case 'Refunded':
         case 'Partially_Refunded':
             // even though it's a refund, we consider the payment as approved, it just has a negative value
             $status = $this->_pay_model->approved_status();
             $gateway_response = __('The payment has been refunded. Please update registrations accordingly.', 'event_espresso');
             break;
         case 'Voided':
         case 'Reversed':
         case 'Canceled_Reversal':
         default:
             $status = $this->_pay_model->cancelled_status();
             $gateway_response = __('The payment was cancelled, reversed, or voided. Please update registrations accordingly.', 'event_espresso');
             break;
     }
     //check if we've already processed this payment
     if ($payment instanceof EEI_Payment) {
         //payment exists. if this has the exact same status and amount, don't bother updating. just return
         if ($payment->status() == $status && $payment->amount() == $update_info['mc_gross']) {
             // DUPLICATED IPN! dont bother updating transaction foo!;
             $message_log = sprintf(__('It appears we have received a duplicate IPN from PayPal for payment %d', 'event_espresso'), $payment->ID());
         } else {
             // new payment yippee !!!
             $payment->set_status($status);
             $payment->set_amount(floatval($update_info['mc_gross']));
             $payment->set_gateway_response($gateway_response);
             $payment->set_details($update_info);
             $payment->set_txn_id_chq_nmbr($update_info['txn_id']);
             $message_log = sprintf(__('Updated payment either from IPN or as part of POST from PayPal', 'event_espresso'));
         }
         $this->log(array('url' => $this->_process_response_url(), 'message' => $message_log, 'payment' => $payment->model_field_array(), 'IPN_data' => $update_info), $payment);
     }
     do_action('FHEE__EEG_Paypal_Standard__handle_payment_update__payment_processed', $payment, $this);
     // kill request here if this is a refund
     if ($update_info['payment_status'] == 'Refunded' || $update_info['payment_status'] == 'Partially_Refunded') {
         if (apply_filters('FHEE__EEG_Paypal_Standard__handle_payment_update__kill_refund_request', true)) {
             status_header(200);
             exit;
         }
     }
     return $payment;
 }
 /**
  * Handles the payment update (note: mijireh doesn't send an IPN in the usual sense,
  * instead they just redirect the user back to our website and then we need to query them
  * for the payment's status). Also note that the $update_info should be an array with the key
  * 'payment' containing the EEI_Payment to update
  *
  * @param array $update_info unused. We just use the $transaction
  * @param EEI_Transaction $transaction
  * @return \EEI_Payment|null
  */
 public function handle_payment_update($update_info, $transaction)
 {
     $payment = $transaction instanceof EEI_Transaction ? $transaction->last_payment() : NULL;
     if (!$payment instanceof EEI_Payment) {
         throw new EE_Error(sprintf(__("Could not find Mijireh payment for transaction %s", 'event_espresso'), $transaction->ID()));
     }
     $request_args = array('headers' => array('Authorization' => 'Basic ' . base64_encode($this->_access_key . ':'), 'Accept' => 'application/json'));
     $response = wp_remote_get($this->_mijireh_api_orders_url . '/' . $payment->txn_id_chq_nmbr(), $request_args);
     $this->log(array('get payment status request_args' => $request_args, 'response' => $response), $payment);
     // validate response
     $response_body = isset($response['body']) ? json_decode($response['body']) : '';
     if ($response && $response_body) {
         switch ($response_body->status) {
             case 'paid':
                 $payment->set_status($this->_pay_model->approved_status());
                 break;
             case 'pending':
                 $payment->set_status($this->_pay_model->pending_status());
                 break;
             default:
                 $payment->set_status($this->_pay_model->declined_status());
         }
     } else {
         $payment->set_gateway_response(__('Response from Mijireh could not be understood.', 'event_espresso'));
         $payment->set_details($response);
         $payment->set_status($this->_pay_model->failed_status());
     }
     // the following is ONLY for testing the Mijireh IPN and should NEVER be uncommented for real usage
     //		$payment->set_status( $this->_pay_model->pending_status() );
     return $payment;
 }