Completed
Branch BUG-9951-10331-8793-pue-fixes (40e696)
by
unknown
27:52 queued 13:57
created

EEG_Mijireh::handle_payment_update()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 9
nc 9
nop 2
dl 0
loc 14
rs 8.8571
c 0
b 0
f 0
1
<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) { exit('No direct script access allowed'); }
2
/**
3
 *
4
 * EEG_Mijireh
5
 *
6
 * @package			Event Espresso
7
 * @subpackage
8
 * @author				Mike Nelson
9
 *
10
 */
11
class EEG_Mijireh extends EE_Offsite_Gateway{
12
13
	protected $_access_key;
14
15
	protected $_currencies_supported = EE_Gateway::all_currencies_supported;
16
17
	protected $_mijireh_api_orders_url = 'https://secure.mijireh.com/api/1/orders';
18
19
20
21
	/**
22
	 * @param EE_Payment $payment to process
23
	 * @param array      $billing_info but should be empty for this gateway
24
	 * @param string     $return_url URL to send the user to after a successful payment on the payment provider's website
25
	 * @param string     $notify_url URL to send the instant payment notification
26
	 * @param string     $cancel_url URL to send the user to after a cancelled payment attempt on teh payment provider's website
27
	 * @throws \EE_Error
28
	 * @return EE_Payment
29
	 */
30
	public function set_redirection_info($payment, $billing_info = array(), $return_url = NULL, $notify_url = NULL, $cancel_url = NULL) {
31
		/* @var $transaction EE_Transaction */
32
		$transaction = $payment->transaction();
33
34
		//get any of the current registrations,
35
		$primary_registrant = $transaction->primary_registration();
36
37
		$primary_attendee = $primary_registrant->attendee();
38
		$items = array();
39
		//if we're are charging for the full amount, show the normal line items
40
		if( $this->_can_easily_itemize_transaction_for( $payment )){
41
			$total_line_item = $transaction->total_line_item();
42
			$tax_total = $total_line_item->get_total_tax();
43
			foreach($total_line_item->get_items() as $line_item){
44
				$items[] = array(
45
					'name'=>apply_filters(
46
						'FHEE__EEG_Mijireh__set_redirection_info__full_amount_line_item_name',
47
						$this->_format_line_item_name( $line_item, $payment ),
0 ignored issues
show
Deprecated Code introduced by
The method EE_Gateway::_format_line_item_name() has been deprecated with message: since 4.9.31 instead use $this->_get_gateway_formatter()->formatLineItemName($line_item,$payment)

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
48
						$line_item,
49
						$payment,
50
						$primary_registrant
51
					),
52
					'price'=>$this->format_currency($line_item->unit_price()),
0 ignored issues
show
Deprecated Code introduced by
The method EE_Gateway::format_currency() has been deprecated with message: since 4.9.31 insetad use EventEspresso\core\services\payment_methods\gateways\GatewayDataFormatter::format_currency()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
53
					'sku'=>$line_item->code(),
54
					'quantity'=>$line_item->quantity()
55
				);
56
			}
57
		}else{//its a partial payment
58
			$tax_total = 0;
59
			//partial payment, so just add 1 item
60
			$items[] = array(
61
				'name'=> apply_filters(
62
					'FHEE__EEG_Mijireh__set_redirection_info__partial_amount_line_item_name',
63
					$this->_format_partial_payment_line_item_name( $payment ),
0 ignored issues
show
Deprecated Code introduced by
The method EE_Gateway::_format_part...ayment_line_item_name() has been deprecated with message: since 4.9.31 instead use $this->_get_gateway_formatter()->formatPartialPaymentLineItemName($payment)

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
64
					$payment,
65
					$primary_registrant
66
				),
67
				'price'=> $this->format_currency($payment->amount()),
0 ignored issues
show
Deprecated Code introduced by
The method EE_Gateway::format_currency() has been deprecated with message: since 4.9.31 insetad use EventEspresso\core\services\payment_methods\gateways\GatewayDataFormatter::format_currency()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
68
				'sku'=>$primary_registrant->reg_code(),
69
				'quantity'=>1
70
			);
71
		}
72
		$order = array(
73
			'total'=>$this->format_currency($payment->amount()),
0 ignored issues
show
Deprecated Code introduced by
The method EE_Gateway::format_currency() has been deprecated with message: since 4.9.31 insetad use EventEspresso\core\services\payment_methods\gateways\GatewayDataFormatter::format_currency()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
74
			'return_url'=>$return_url,
75
			'items'=>$this->_prepare_for_mijireh( $items ),
76
			'email'=>$primary_attendee->email(),
77
			'first_name'=>$primary_attendee->fname(),
78
			'last_name'=>$primary_attendee->lname(),
79
			'tax'=>$this->format_currency($tax_total),
0 ignored issues
show
Deprecated Code introduced by
The method EE_Gateway::format_currency() has been deprecated with message: since 4.9.31 insetad use EventEspresso\core\services\payment_methods\gateways\GatewayDataFormatter::format_currency()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
80
			'partner_id'=>'ee');
81
		//setup address?
82
		if(		$primary_attendee->address()  &&
83
				$primary_attendee->city()  &&
84
				$primary_attendee->state_ID()  &&
85
				$primary_attendee->country_ID()  &&
86
				$primary_attendee->zip()  ){
87
			$shipping_address = array(
88
				'first_name'=>$primary_attendee->fname(),
89
				'last_name'=>$primary_attendee->lname(),
90
				'street' => $primary_attendee->address(),
91
				'city' => $primary_attendee->city(),
92
				'state_province' => $primary_attendee->state_name(),
93
				'zip_code' => $primary_attendee->zip(),
94
				'country' => $primary_attendee->country_ID()
95
			);
96
			if( $primary_attendee->address2() ){
97
				$shipping_address[ 'apt_suite' ] = $primary_attendee->address2();
98
			}
99
			if( $primary_attendee->phone() ){
100
				$shipping_address[ 'phone' ] = $primary_attendee->phone();
101
			}
102
			$order[ 'shipping_address' ] = $shipping_address;
103
		}
104
		$order = apply_filters( 'FHEE__EEG_Mijireh__set_redirection_info__order_arguments', $order, $payment, $primary_registrant );
105
		do_action( 'AHEE_log', __FILE__, __FUNCTION__, serialize(get_object_vars($this)) );
106
        $order = $this->_get_unsupported_character_remover()->formatArray($order);
107
108
		$args = array(
109
			'headers' => array(
110
				'Authorization' => 'Basic ' . base64_encode( $this->_access_key . ':' ),
111
				'Accept'=>'application/json'
112
			),
113
			'body'=>  wp_json_encode($order)
114
		);
115
		$response = wp_remote_post( $this->_mijireh_api_orders_url, $args );
116
                $problems_string = false;
117
		$this->log(array('get checkout url request_args' => $args, 'response' => $response ), $payment);
118
		if( ! $response instanceof WP_Error ){
0 ignored issues
show
Bug introduced by
The class WP_Error does not exist. Did you forget a USE statement, or did you not list all dependencies?

This error could be the result of:

1. Missing dependencies

PHP Analyzer uses your composer.json file (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects the composer.json to be in the root folder of your repository.

Are you sure this class is defined by one of your dependencies, or did you maybe not list a dependency in either the require or require-dev section?

2. Missing use statement

PHP does not complain about undefined classes in ìnstanceof checks. For example, the following PHP code will work perfectly fine:

if ($x instanceof DoesNotExist) {
    // Do something.
}

If you have not tested against this specific condition, such errors might go unnoticed.

Loading history...
119
			$response_body = json_decode($response['body']);
120
			if($response_body && isset($response_body->checkout_url)){
121
                            $payment->set_redirect_url($response_body->checkout_url);
122
                            $payment->set_txn_id_chq_nmbr($response_body->order_number);
123
                            $payment->set_details($response['body']);
124
			} else {
125
                           if( is_array( $response_body ) || is_object( $response_body)){
126
                                    $response_body_as_array = (array)$response_body;
127
                                    foreach($response_body_as_array as $problem_parameter => $problems){
128
                                            $problems_string.= sprintf(__('\nProblems with %s: %s','event_espresso'),$problem_parameter,implode(", ",$problems));
129
                                    }
130
                            }else{
131
                                    $problems_string = $response['body'];
132
                            }
133
                            if( ! $problems_string ) {
134
                                //no message to show? wack
135
                                if( isset( $response[ 'headers' ][ 'status' ] ) ){
136
                                        $problems_string = $response[ 'headers' ][ 'status' ];
137
                                }else{
138
                                        $problems_string = __( 'No response from Mijireh', 'event_espresso' );
139
                                }
140
                            }
141
                        }
142
		}else{
143
                    $problems_string = implode( ",", $response->get_error_messages() );
144
		}
145
                
146
                if( $problems_string ) {
147
                    $payment->set_gateway_response( sprintf( __( 'Errors occurred communicating with Mijireh: %1$s', 'event_espresso'), $problems_string ) );
148
                    $payment->set_details( $response );
149
                    $payment->set_redirect_url( null );
150
                    //even though the payment's status is failed at this point anyways,
151
                    //let's be explicit about it. The fact that the redirect url is null
152
                    //should be enough to client code that they can't redirect the user
153
                    $payment->set_status( $this->_pay_model->failed_status() );
154
                }
155
		return $payment;
156
	}
157
158
159
160
	/**
161
	 * goes through $data and ensures there are no percent signs in it
162
	 * (which, strangely, kill mijireh)
163
	 * @param mixed $data
164
	 * @return mixed same type as $data
165
	 */
166
	private function _prepare_for_mijireh( $data ){
167
		if( is_array( $data ) ){
168
			$prepared_data = array();
169
			foreach($data as $key => $datum ){
170
				$prepared_data[ $key ] = $this->_prepare_for_mijireh( $datum );
171
			}
172
			return $prepared_data;
173
		}elseif(is_string( $data ) ){
174
			return str_replace( '%', 'percent', $data );
175
		}else{
176
			return $data;
177
		}
178
	}
179
180
181
182
	/**
183
	 * Handles the payment update (note: mijireh doesn't send an IPN in the usual sense,
184
	 * instead they just redirect the user back to our website and then we need to query them
185
	 * for the payment's status). Also note that the $update_info should be an array with the key
186
	 * 'payment' containing the EEI_Payment to update
187
	 *
188
	 * @param array $update_info unused. We just use the $transaction
189
	 * @param EEI_Transaction $transaction
190
	 * @return \EEI_Payment
191
     * @throws EE_Error
192
	 */
193
	public function handle_payment_update($update_info, $transaction) {
194
        foreach( $transaction->pending_payments() as $payment){
195
		    $payment = $this->check_payment_in_mijireh($payment);
196
            if( $payment->status() === $this->_pay_model->approved_status()){
197
                return $payment;
198
            }
199
        }
200
        $payment = $transaction instanceof EEI_Transaction ? $transaction->last_payment() : NULL;
201
202
        if ( ! $payment instanceof EEI_Payment ){
203
            throw new EE_Error( sprintf( __( "Could not find Mijireh payment for transaction %s", 'event_espresso' ), $transaction->ID() ) );
204
        }
205
        return $payment;
206
	}
207
208
209
210
    /**
211
     * Checks the payment's status in Mijireh for this specific payment
212
     * @param \EEI_Payment $payment
213
     * @return \EEI_Payment
214
     */
215
	public function check_payment_in_mijireh( EEI_Payment $payment ){
216
        $request_args = array(
217
            'headers' => array(
218
                'Authorization' => 'Basic ' . base64_encode( $this->_access_key . ':' ),
219
                'Accept'=>'application/json'
220
            )
221
        );
222
223
        $response = wp_remote_get(
224
            $this->_mijireh_api_orders_url . '/' . $payment->txn_id_chq_nmbr(),
225
            $request_args
226
        );
227
228
        $this->log(
229
            array( 'get payment status request_args' => $request_args, 'response' => $response ),
230
            $payment
231
        );
232
        // validate response
233
        $response_body = isset( $response[ 'body' ] ) ? json_decode( $response[ 'body' ] ) : '';
234
        if( $response && $response_body ){
235
            switch( $response_body->status ){
236
                case 'paid':
237
                    $payment->set_status($this->_pay_model->approved_status());
238
                    break;
239
                case 'pending':
240
                    $payment->set_status($this->_pay_model->pending_status());
241
                    break;
242
                default:
243
                    $payment->set_status($this->_pay_model->declined_status());
244
            }
245
246
        } else {
247
            $payment->set_gateway_response( __( 'Response from Mijireh could not be understood.', 'event_espresso' ) );
248
            $payment->set_details( $response );
249
            $payment->set_status( $this->_pay_model->failed_status() );
250
        }
251
        // the following is ONLY for testing the Mijireh IPN and should NEVER be uncommented for real usage
252
//		$payment->set_status( $this->_pay_model->pending_status() );
253
        return $payment;
254
    }
255
256
}
257
258
// End of file EEG_Mijireh.gateway.php