|
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 ), |
|
48
|
|
|
$line_item, |
|
49
|
|
|
$payment, |
|
50
|
|
|
$primary_registrant |
|
51
|
|
|
), |
|
52
|
|
|
'price'=>$this->format_currency($line_item->unit_price()), |
|
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 ), |
|
64
|
|
|
$payment, |
|
65
|
|
|
$primary_registrant |
|
66
|
|
|
), |
|
67
|
|
|
'price'=> $this->format_currency($payment->amount()), |
|
68
|
|
|
'sku'=>$primary_registrant->reg_code(), |
|
69
|
|
|
'quantity'=>1 |
|
70
|
|
|
); |
|
71
|
|
|
} |
|
72
|
|
|
$order = array( |
|
73
|
|
|
'total'=>$this->format_currency($payment->amount()), |
|
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), |
|
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
|
|
|
$args = array( |
|
107
|
|
|
'headers' => array( |
|
108
|
|
|
'Authorization' => 'Basic ' . base64_encode( $this->_access_key . ':' ), |
|
109
|
|
|
'Accept'=>'application/json' |
|
110
|
|
|
), |
|
111
|
|
|
'body'=> wp_json_encode($order) |
|
112
|
|
|
); |
|
113
|
|
|
$response = wp_remote_post( $this->_mijireh_api_orders_url, $args ); |
|
114
|
|
|
$problems_string = false; |
|
115
|
|
|
$this->log(array('get checkout url request_args' => $args, 'response' => $response ), $payment); |
|
116
|
|
|
if( ! $response instanceof WP_Error ){ |
|
|
|
|
|
|
117
|
|
|
$response_body = json_decode($response['body']); |
|
118
|
|
|
if($response_body && isset($response_body->checkout_url)){ |
|
119
|
|
|
$payment->set_redirect_url($response_body->checkout_url); |
|
120
|
|
|
$payment->set_txn_id_chq_nmbr($response_body->order_number); |
|
121
|
|
|
$payment->set_details($response['body']); |
|
122
|
|
|
} else { |
|
123
|
|
|
if( is_array( $response_body ) || is_object( $response_body)){ |
|
124
|
|
|
$response_body_as_array = (array)$response_body; |
|
125
|
|
|
foreach($response_body_as_array as $problem_parameter => $problems){ |
|
126
|
|
|
$problems_string.= sprintf(__('\nProblems with %s: %s','event_espresso'),$problem_parameter,implode(", ",$problems)); |
|
127
|
|
|
} |
|
128
|
|
|
}else{ |
|
129
|
|
|
$problems_string = $response['body']; |
|
130
|
|
|
} |
|
131
|
|
|
if( ! $problems_string ) { |
|
132
|
|
|
//no message to show? wack |
|
133
|
|
|
if( isset( $response[ 'headers' ][ 'status' ] ) ){ |
|
134
|
|
|
$problems_string = $response[ 'headers' ][ 'status' ]; |
|
135
|
|
|
}else{ |
|
136
|
|
|
$problems_string = __( 'No response from Mijireh', 'event_espresso' ); |
|
137
|
|
|
} |
|
138
|
|
|
} |
|
139
|
|
|
} |
|
140
|
|
|
}else{ |
|
141
|
|
|
$problems_string = implode( ",", $response->get_error_messages() ); |
|
142
|
|
|
} |
|
143
|
|
|
|
|
144
|
|
|
if( $problems_string ) { |
|
145
|
|
|
$payment->set_gateway_response( sprintf( __( 'Errors occurred communicating with Mijireh: %1$s', 'event_espresso'), $problems_string ) ); |
|
146
|
|
|
$payment->set_details( $response ); |
|
147
|
|
|
$payment->set_redirect_url( null ); |
|
148
|
|
|
//even though the payment's status is failed at this point anyways, |
|
149
|
|
|
//let's be explicit about it. The fact that the redirect url is null |
|
150
|
|
|
//should be enough to client code that they can't redirect the user |
|
151
|
|
|
$payment->set_status( $this->_pay_model->failed_status() ); |
|
152
|
|
|
} |
|
153
|
|
|
return $payment; |
|
154
|
|
|
} |
|
155
|
|
|
|
|
156
|
|
|
|
|
157
|
|
|
|
|
158
|
|
|
/** |
|
159
|
|
|
* goes through $data and ensures there are no percent signs in it |
|
160
|
|
|
* (which, strangely, kill mijireh) |
|
161
|
|
|
* @param mixed $data |
|
162
|
|
|
* @return mixed same type as $data |
|
163
|
|
|
*/ |
|
164
|
|
|
private function _prepare_for_mijireh( $data ){ |
|
165
|
|
|
if( is_array( $data ) ){ |
|
166
|
|
|
$prepared_data = array(); |
|
167
|
|
|
foreach($data as $key => $datum ){ |
|
168
|
|
|
$prepared_data[ $key ] = $this->_prepare_for_mijireh( $datum ); |
|
169
|
|
|
} |
|
170
|
|
|
return $prepared_data; |
|
171
|
|
|
}elseif(is_string( $data ) ){ |
|
172
|
|
|
return str_replace( '%', 'percent', $data ); |
|
173
|
|
|
}else{ |
|
174
|
|
|
return $data; |
|
175
|
|
|
} |
|
176
|
|
|
} |
|
177
|
|
|
|
|
178
|
|
|
|
|
179
|
|
|
|
|
180
|
|
|
/** |
|
181
|
|
|
* Handles the payment update (note: mijireh doesn't send an IPN in the usual sense, |
|
182
|
|
|
* instead they just redirect the user back to our website and then we need to query them |
|
183
|
|
|
* for the payment's status). Also note that the $update_info should be an array with the key |
|
184
|
|
|
* 'payment' containing the EEI_Payment to update |
|
185
|
|
|
* |
|
186
|
|
|
* @param array $update_info unused. We just use the $transaction |
|
187
|
|
|
* @param EEI_Transaction $transaction |
|
188
|
|
|
* @return \EEI_Payment|null |
|
189
|
|
|
*/ |
|
190
|
|
|
public function handle_payment_update($update_info, $transaction) { |
|
191
|
|
|
|
|
192
|
|
|
$payment = $transaction instanceof EEI_Transaction ? $transaction->last_payment() : NULL; |
|
193
|
|
|
|
|
194
|
|
|
if ( ! $payment instanceof EEI_Payment ){ |
|
195
|
|
|
throw new EE_Error( sprintf( __( "Could not find Mijireh payment for transaction %s", 'event_espresso' ), $transaction->ID() ) ); |
|
196
|
|
|
} |
|
197
|
|
|
|
|
198
|
|
|
$payment_to_return = nulll; |
|
199
|
|
|
foreach( $transaction->pending_payments() as $payment){ |
|
200
|
|
|
$payment = $this->check_payment_in_mijireh($payment); |
|
201
|
|
|
if( ! $payment_to_return instanceof EEI_Payment |
|
202
|
|
|
|| $payment->status() === $this->_pay_model->approved_status()){ |
|
203
|
|
|
$payment_to_return = $payment; |
|
204
|
|
|
} |
|
205
|
|
|
} |
|
206
|
|
|
return $payment; |
|
207
|
|
|
} |
|
208
|
|
|
|
|
209
|
|
|
|
|
210
|
|
|
|
|
211
|
|
|
/** |
|
212
|
|
|
* Checks the payment's status in Mijireh for this specific payment |
|
213
|
|
|
* @param \EEI_Payment $payment |
|
214
|
|
|
* @return \EEI_Payment |
|
215
|
|
|
*/ |
|
216
|
|
|
public function check_payment_in_mijireh( EEI_Payment $payment ){ |
|
217
|
|
|
$request_args = array( |
|
218
|
|
|
'headers' => array( |
|
219
|
|
|
'Authorization' => 'Basic ' . base64_encode( $this->_access_key . ':' ), |
|
220
|
|
|
'Accept'=>'application/json' |
|
221
|
|
|
) |
|
222
|
|
|
); |
|
223
|
|
|
|
|
224
|
|
|
$response = wp_remote_get( |
|
225
|
|
|
$this->_mijireh_api_orders_url . '/' . $payment->txn_id_chq_nmbr(), |
|
226
|
|
|
$request_args |
|
227
|
|
|
); |
|
228
|
|
|
|
|
229
|
|
|
$this->log( |
|
230
|
|
|
array( 'get payment status request_args' => $request_args, 'response' => $response ), |
|
231
|
|
|
$payment |
|
232
|
|
|
); |
|
233
|
|
|
// validate response |
|
234
|
|
|
$response_body = isset( $response[ 'body' ] ) ? json_decode( $response[ 'body' ] ) : ''; |
|
235
|
|
|
if( $response && $response_body ){ |
|
236
|
|
|
switch( $response_body->status ){ |
|
237
|
|
|
case 'paid': |
|
238
|
|
|
$payment->set_status($this->_pay_model->approved_status()); |
|
239
|
|
|
break; |
|
240
|
|
|
case 'pending': |
|
241
|
|
|
$payment->set_status($this->_pay_model->pending_status()); |
|
242
|
|
|
break; |
|
243
|
|
|
default: |
|
244
|
|
|
$payment->set_status($this->_pay_model->declined_status()); |
|
245
|
|
|
} |
|
246
|
|
|
|
|
247
|
|
|
} else { |
|
248
|
|
|
$payment->set_gateway_response( __( 'Response from Mijireh could not be understood.', 'event_espresso' ) ); |
|
249
|
|
|
$payment->set_details( $response ); |
|
250
|
|
|
$payment->set_status( $this->_pay_model->failed_status() ); |
|
251
|
|
|
} |
|
252
|
|
|
// the following is ONLY for testing the Mijireh IPN and should NEVER be uncommented for real usage |
|
253
|
|
|
// $payment->set_status( $this->_pay_model->pending_status() ); |
|
254
|
|
|
return $payment; |
|
255
|
|
|
} |
|
256
|
|
|
|
|
257
|
|
|
} |
|
258
|
|
|
|
|
259
|
|
|
// End of file EEG_Mijireh.gateway.php |
This error could be the result of:
1. Missing dependencies
PHP Analyzer uses your
composer.jsonfile (if available) to determine the dependencies of your project and to determine all the available classes and functions. It expects thecomposer.jsonto 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
requireorrequire-devsection?2. Missing use statement
PHP does not complain about undefined classes in
ìnstanceofchecks. For example, the following PHP code will work perfectly fine:If you have not tested against this specific condition, such errors might go unnoticed.