Completed
Branch paypal-refactor (661b26)
by
unknown
12:13 queued 09:37
created
core/libraries/payment_methods/EE_Gateway.lib.php 1 patch
Indentation   +500 added lines, -500 removed lines patch added patch discarded remove patch
@@ -23,504 +23,504 @@
 block discarded – undo
23 23
  */
24 24
 abstract class EE_Gateway
25 25
 {
26
-    /**
27
-     * a constant used as a possible value for $_currencies_supported to indicate
28
-     * that ALL currencies are supported by this gateway
29
-     */
30
-    const all_currencies_supported = 'all_currencies_supported';
31
-    /**
32
-     * Where values are 3-letter currency codes
33
-     *
34
-     * @var array
35
-     */
36
-    protected $_currencies_supported = array();
37
-    /**
38
-     * Whether or not this gateway can support SENDING a refund request (ie, initiated by
39
-     * admin in EE's wp-admin page)
40
-     *
41
-     * @var boolean
42
-     */
43
-    protected $_supports_sending_refunds = false;
44
-
45
-    /**
46
-     * Whether or not this gateway can support RECEIVING a refund request from the payment
47
-     * provider (ie, initiated by admin on the payment prover's website who sends an IPN to EE)
48
-     *
49
-     * @var boolean
50
-     */
51
-    protected $_supports_receiving_refunds = false;
52
-    /**
53
-     * Model for querying for existing payments
54
-     *
55
-     * @var EEMI_Payment
56
-     */
57
-    protected $_pay_model;
58
-
59
-    /**
60
-     * Model used for adding to the payments log
61
-     *
62
-     * @var EEMI_Payment_Log
63
-     */
64
-    protected $_pay_log;
65
-
66
-    /**
67
-     * Used for formatting some input to gateways
68
-     *
69
-     * @var EEHI_Template
70
-     */
71
-    protected $_template;
72
-
73
-    /**
74
-     * Concrete class that implements EEHI_Money, used by most gateways
75
-     *
76
-     * @var EEHI_Money
77
-     */
78
-    protected $_money;
79
-
80
-    /**
81
-     * Concrete class that implements EEHI_Line_Item, used for manipulating the line item tree
82
-     *
83
-     * @var EEHI_Line_Item
84
-     */
85
-    protected $_line_item;
86
-
87
-    /**
88
-     * @var GatewayDataFormatterInterface
89
-     */
90
-    protected $_gateway_data_formatter;
91
-
92
-    /**
93
-     * @var FormatterInterface
94
-     */
95
-    protected $_unsupported_character_remover;
96
-
97
-    /**
98
-     * The ID of the payment method using this gateway
99
-     *
100
-     * @var int
101
-     */
102
-    protected $_ID;
103
-
104
-    /**
105
-     * @var $_debug_mode boolean whether to send requests to teh sandbox site or not
106
-     */
107
-    protected $_debug_mode;
108
-    /**
109
-     *
110
-     * @var string $_name name to show for this payment method
111
-     */
112
-    protected $_name;
113
-    /**
114
-     *
115
-     * @var string name to show fir this payment method to admin-type users
116
-     */
117
-    protected $_admin_name;
118
-
119
-    /**
120
-     * EE_Gateway constructor
121
-     */
122
-    public function __construct()
123
-    {
124
-    }
125
-
126
-    /**
127
-     * We don't want to serialize models as they often have circular structures
128
-     * (eg a payment model has a reference to each payment model object; and most
129
-     * payments have a transaction, most transactions have a payment method;
130
-     * most payment methods have a payment method type; most payment method types
131
-     * have a gateway. And if a gateway serializes its models, we start at the
132
-     * beginning again)
133
-     *
134
-     * @return array
135
-     */
136
-    public function __sleep()
137
-    {
138
-        $properties = get_object_vars($this);
139
-        unset($properties['_pay_model'], $properties['_pay_log']);
140
-        return array_keys($properties);
141
-    }
142
-
143
-    /**
144
-     * Returns whether or not this gateway should support SENDING refunds
145
-     * see $_supports_sending_refunds
146
-     *
147
-     * @return boolean
148
-     */
149
-    public function supports_sending_refunds()
150
-    {
151
-        return $this->_supports_sending_refunds;
152
-    }
153
-
154
-    /**
155
-     * Returns whether or not this gateway should support RECEIVING refunds
156
-     * see $_supports_receiving_refunds
157
-     *
158
-     * @return boolean
159
-     */
160
-    public function supports_receiving_refunds()
161
-    {
162
-        return $this->_supports_receiving_refunds;
163
-    }
164
-
165
-
166
-    /**
167
-     * Tries to refund the payment specified, taking into account the extra
168
-     * refund info. Note that if the gateway's _supports_sending_refunds is false,
169
-     * this should just throw an exception.
170
-     *
171
-     * @param EE_Payment $payment
172
-     * @param array      $refund_info
173
-     * @return EE_Payment for the refund
174
-     * @throws EE_Error
175
-     */
176
-    public function do_direct_refund(EE_Payment $payment, $refund_info = null)
177
-    {
178
-        return null;
179
-    }
180
-
181
-
182
-    /**
183
-     * Sets the payment method's settings so the gateway knows where to send the request
184
-     * etc
185
-     *
186
-     * @param array $settings_array
187
-     */
188
-    public function set_settings($settings_array)
189
-    {
190
-        foreach ($settings_array as $name => $value) {
191
-            $property_name = "_" . $name;
192
-            $this->{$property_name} = $value;
193
-        }
194
-    }
195
-
196
-    /**
197
-     * See this class description
198
-     *
199
-     * @param EEMI_Payment $payment_model
200
-     */
201
-    public function set_payment_model($payment_model)
202
-    {
203
-        $this->_pay_model = $payment_model;
204
-    }
205
-
206
-    /**
207
-     * See this class description
208
-     *
209
-     * @param EEMI_Payment_Log $payment_log_model
210
-     */
211
-    public function set_payment_log($payment_log_model)
212
-    {
213
-        $this->_pay_log = $payment_log_model;
214
-    }
215
-
216
-    /**
217
-     * See this class description
218
-     *
219
-     * @param EEHI_Template $template_helper
220
-     */
221
-    public function set_template_helper($template_helper)
222
-    {
223
-        $this->_template = $template_helper;
224
-    }
225
-
226
-    /**
227
-     * See this class description
228
-     *
229
-     * @param EEHI_Line_Item $line_item_helper
230
-     */
231
-    public function set_line_item_helper($line_item_helper)
232
-    {
233
-        $this->_line_item = $line_item_helper;
234
-    }
235
-
236
-    /**
237
-     * See this class description
238
-     *
239
-     * @param EEHI_Money $money_helper
240
-     */
241
-    public function set_money_helper($money_helper)
242
-    {
243
-        $this->_money = $money_helper;
244
-    }
245
-
246
-
247
-    /**
248
-     * Sets the gateway data formatter helper
249
-     *
250
-     * @param GatewayDataFormatterInterface $gateway_data_formatter
251
-     * @throws InvalidEntityException if it's not set properly
252
-     */
253
-    public function set_gateway_data_formatter(GatewayDataFormatterInterface $gateway_data_formatter)
254
-    {
255
-        if (! $gateway_data_formatter instanceof GatewayDataFormatterInterface) {
256
-            throw new InvalidEntityException(
257
-                is_object($gateway_data_formatter)
258
-                    ? get_class($gateway_data_formatter)
259
-                    : esc_html__('Not an object', 'event_espresso'),
260
-                '\\EventEspresso\\core\\services\\payment_methods\\gateways\\GatewayDataFormatterInterface'
261
-            );
262
-        }
263
-        $this->_gateway_data_formatter = $gateway_data_formatter;
264
-    }
265
-
266
-    /**
267
-     * Gets the gateway data formatter
268
-     *
269
-     * @return GatewayDataFormatterInterface
270
-     * @throws InvalidEntityException if it's not set properly
271
-     */
272
-    protected function _get_gateway_formatter()
273
-    {
274
-        if (! $this->_gateway_data_formatter instanceof GatewayDataFormatterInterface) {
275
-            throw new InvalidEntityException(
276
-                is_object($this->_gateway_data_formatter)
277
-                    ? get_class($this->_gateway_data_formatter)
278
-                    : esc_html__('Not an object', 'event_espresso'),
279
-                '\\EventEspresso\\core\\services\\payment_methods\\gateways\\GatewayDataFormatterInterface'
280
-            );
281
-        }
282
-        return $this->_gateway_data_formatter;
283
-    }
284
-
285
-
286
-    /**
287
-     * Sets the helper which will remove unsupported characters for most gateways
288
-     *
289
-     * @param FormatterInterface $formatter
290
-     * @return FormatterInterface
291
-     * @throws InvalidEntityException
292
-     */
293
-    public function set_unsupported_character_remover(FormatterInterface $formatter)
294
-    {
295
-        if (! $formatter instanceof FormatterInterface) {
296
-            throw new InvalidEntityException(
297
-                is_object($formatter)
298
-                    ? get_class($formatter)
299
-                    : esc_html__('Not an object', 'event_espresso'),
300
-                '\\EventEspresso\\core\\services\\formatters\\FormatterInterface'
301
-            );
302
-        }
303
-        $this->_unsupported_character_remover = $formatter;
304
-    }
305
-
306
-    /**
307
-     * Gets the helper which removes characters which gateways might not support, like emojis etc.
308
-     *
309
-     * @return FormatterInterface
310
-     * @throws InvalidEntityException
311
-     */
312
-    protected function _get_unsupported_character_remover()
313
-    {
314
-        if (! $this->_unsupported_character_remover instanceof FormatterInterface) {
315
-            throw new InvalidEntityException(
316
-                is_object($this->_unsupported_character_remover)
317
-                    ? get_class($this->_unsupported_character_remover)
318
-                    : esc_html__('Not an object', 'event_espresso'),
319
-                '\\EventEspresso\\core\\services\\formatters\\FormatterInterface'
320
-            );
321
-        }
322
-        return $this->_unsupported_character_remover;
323
-    }
324
-
325
-
326
-    /**
327
-     * @param $message
328
-     * @param $payment
329
-     */
330
-    public function log($message, $object_logged)
331
-    {
332
-        if ($object_logged instanceof EEI_Payment) {
333
-            $type = 'Payment';
334
-            $id = $object_logged->ID();
335
-        } elseif ($object_logged instanceof EEI_Transaction) {
336
-            $type = 'Transaction';
337
-            $id = $object_logged->ID();
338
-        } else {
339
-            $type = 'Payment_Method';
340
-            $id = $this->_ID;
341
-        }
342
-        // only log if we're going to store it for longer than the minimum time
343
-        $reg_config = LoaderFactory::getLoader()->load('EE_Registration_Config');
344
-        if ($reg_config->gateway_log_lifespan !== '1 second') {
345
-            $this->_pay_log->gateway_log($message, $id, $type);
346
-        }
347
-    }
348
-
349
-    /**
350
-     * Formats the amount so it can generally be sent to gateways
351
-     *
352
-     * @param float $amount
353
-     * @return string
354
-     * @deprecated since 4.9.31 insetad use
355
-     *             EventEspresso\core\services\payment_methods\gateways\GatewayDataFormatter::format_currency()
356
-     */
357
-    public function format_currency($amount)
358
-    {
359
-        return $this->_get_gateway_formatter()->formatCurrency($amount);
360
-    }
361
-
362
-    /**
363
-     * Returns either an array of all the currency codes supported,
364
-     * or a string indicating they're all supported (EE_gateway::all_currencies_supported)
365
-     *
366
-     * @return mixed array or string
367
-     */
368
-    public function currencies_supported()
369
-    {
370
-        return $this->_currencies_supported;
371
-    }
372
-
373
-    /**
374
-     * Returns what a simple summing of items and taxes for this transaction. This
375
-     * can be used to determine if some more complex line items, like promotions,
376
-     * surcharges, or cancellations occurred (in which case we might want to forget
377
-     * about creating an itemized list of purchases and instead only send the total due)
378
-     *
379
-     * @param EE_Transaction $transaction
380
-     * @return float
381
-     */
382
-    protected function _sum_items_and_taxes(EE_Transaction $transaction)
383
-    {
384
-        $total_line_item = $transaction->total_line_item();
385
-        $total = 0;
386
-        foreach ($total_line_item->get_items() as $item_line_item) {
387
-            $total += max($item_line_item->total(), 0);
388
-        }
389
-        foreach ($total_line_item->tax_descendants() as $tax_line_item) {
390
-            $total += max($tax_line_item->total(), 0);
391
-        }
392
-        return $total;
393
-    }
394
-
395
-    /**
396
-     * Determines whether or not we can easily itemize the transaction using only
397
-     * items and taxes (ie, no promotions or surcharges or cancellations needed)
398
-     *
399
-     * @param EEI_Payment $payment
400
-     * @return boolean
401
-     */
402
-    protected function _can_easily_itemize_transaction_for(EEI_Payment $payment)
403
-    {
404
-        return $this->_money->compare_floats(
405
-            $this->_sum_items_and_taxes($payment->transaction()),
406
-            $payment->transaction()->total()
407
-        )
408
-               && $this->_money->compare_floats(
409
-                   $payment->amount(),
410
-                   $payment->transaction()->total()
411
-               );
412
-    }
413
-
414
-    /**
415
-     * Handles updating the transaction and any other related data based on the payment.
416
-     * You may be tempted to do this as part of do_direct_payment or handle_payment_update,
417
-     * but doing so on those functions might be too early. It's possible that the changes
418
-     * you make to teh transaction or registration or line items may just get overwritten
419
-     * at that point. Instead, you should store any info you need on the payment during those
420
-     * functions, and use that information at this step, which client code will decide
421
-     * for you when it should be called.
422
-     *
423
-     * @param EE_Payment $payment
424
-     * @return void
425
-     */
426
-    public function update_txn_based_on_payment($payment)
427
-    {
428
-        // maybe update the transaction or line items or registrations
429
-        // but most gateways don't need to do this, because they only update the payment
430
-    }
431
-
432
-    /**
433
-     * Gets the first event for this payment (it's possible that it could be for multiple)
434
-     *
435
-     * @param EEI_Payment $payment
436
-     * @return EEI_Event|null
437
-     * @deprecated since 4.9.31 instead use EEI_Payment::get_first_event()
438
-     */
439
-    protected function _get_first_event_for_payment(EEI_Payment $payment)
440
-    {
441
-        return $payment->get_first_event();
442
-    }
443
-
444
-    /**
445
-     * Gets the name of the first event for which is being paid
446
-     *
447
-     * @param EEI_Payment $payment
448
-     * @return string
449
-     * @deprecated since 4.9.31 instead use EEI_Payment::get_first_event_name()
450
-     */
451
-    protected function _get_first_event_name_for_payment(EEI_Payment $payment)
452
-    {
453
-        return $payment->get_first_event_name();
454
-    }
455
-
456
-    /**
457
-     * Gets the text to use for a gateway's line item name when this is a partial payment
458
-     *
459
-     * @deprecated since 4.9.31 instead use $this->_get_gateway_formatter()->formatPartialPaymentLineItemName($payment)
460
-     * @param EE_Payment $payment
461
-     * @return string
462
-     */
463
-    protected function _format_partial_payment_line_item_name(EEI_Payment $payment)
464
-    {
465
-        return $this->_get_gateway_formatter()->formatPartialPaymentLineItemName($payment);
466
-    }
467
-
468
-    /**
469
-     * Gets the text to use for a gateway's line item description when this is a partial payment
470
-     *
471
-     * @deprecated since 4.9.31 instead use $this->_get_gateway_formatter()->formatPartialPaymentLineItemDesc()
472
-     * @param EEI_Payment $payment
473
-     * @return string
474
-     */
475
-    protected function _format_partial_payment_line_item_desc(EEI_Payment $payment)
476
-    {
477
-        return $this->_get_gateway_formatter()->formatPartialPaymentLineItemDesc($payment);
478
-    }
479
-
480
-    /**
481
-     * Gets the name to use for a line item when sending line items to the gateway
482
-     *
483
-     * @deprecated since 4.9.31 instead use $this->_get_gateway_formatter()->formatLineItemName($line_item,$payment)
484
-     * @param EE_Line_Item $line_item
485
-     * @param EEI_Payment   $payment
486
-     * @return string
487
-     */
488
-    protected function _format_line_item_name(EE_Line_Item $line_item, EEI_Payment $payment)
489
-    {
490
-        return $this->_get_gateway_formatter()->formatLineItemName($line_item, $payment);
491
-    }
492
-
493
-    /**
494
-     * Gets the description to use for a line item when sending line items to the gateway
495
-     *
496
-     * @deprecated since 4.9.31 instead use $this->_get_gateway_formatter()->formatLineItemDesc($line_item, $payment))
497
-     * @param EE_Line_Item $line_item
498
-     * @param EEI_Payment   $payment
499
-     * @return string
500
-     */
501
-    protected function _format_line_item_desc(EE_Line_Item $line_item, EEI_Payment $payment)
502
-    {
503
-        return $this->_get_gateway_formatter()->formatLineItemDesc($line_item, $payment);
504
-    }
505
-
506
-    /**
507
-     * Gets the order description that should generlly be sent to gateways
508
-     *
509
-     * @deprecated since 4.9.31 instead use $this->_get_gateway_formatter()->formatOrderDescription($payment)
510
-     * @param EEI_Payment $payment
511
-     * @return type
512
-     */
513
-    protected function _format_order_description(EEI_Payment $payment)
514
-    {
515
-        return $this->_get_gateway_formatter()->formatOrderDescription($payment);
516
-    }
517
-
518
-
519
-    /**
520
-     * @return bool
521
-     */
522
-    public function isInSandboxMode(): bool
523
-    {
524
-        return $this->_debug_mode;
525
-    }
26
+	/**
27
+	 * a constant used as a possible value for $_currencies_supported to indicate
28
+	 * that ALL currencies are supported by this gateway
29
+	 */
30
+	const all_currencies_supported = 'all_currencies_supported';
31
+	/**
32
+	 * Where values are 3-letter currency codes
33
+	 *
34
+	 * @var array
35
+	 */
36
+	protected $_currencies_supported = array();
37
+	/**
38
+	 * Whether or not this gateway can support SENDING a refund request (ie, initiated by
39
+	 * admin in EE's wp-admin page)
40
+	 *
41
+	 * @var boolean
42
+	 */
43
+	protected $_supports_sending_refunds = false;
44
+
45
+	/**
46
+	 * Whether or not this gateway can support RECEIVING a refund request from the payment
47
+	 * provider (ie, initiated by admin on the payment prover's website who sends an IPN to EE)
48
+	 *
49
+	 * @var boolean
50
+	 */
51
+	protected $_supports_receiving_refunds = false;
52
+	/**
53
+	 * Model for querying for existing payments
54
+	 *
55
+	 * @var EEMI_Payment
56
+	 */
57
+	protected $_pay_model;
58
+
59
+	/**
60
+	 * Model used for adding to the payments log
61
+	 *
62
+	 * @var EEMI_Payment_Log
63
+	 */
64
+	protected $_pay_log;
65
+
66
+	/**
67
+	 * Used for formatting some input to gateways
68
+	 *
69
+	 * @var EEHI_Template
70
+	 */
71
+	protected $_template;
72
+
73
+	/**
74
+	 * Concrete class that implements EEHI_Money, used by most gateways
75
+	 *
76
+	 * @var EEHI_Money
77
+	 */
78
+	protected $_money;
79
+
80
+	/**
81
+	 * Concrete class that implements EEHI_Line_Item, used for manipulating the line item tree
82
+	 *
83
+	 * @var EEHI_Line_Item
84
+	 */
85
+	protected $_line_item;
86
+
87
+	/**
88
+	 * @var GatewayDataFormatterInterface
89
+	 */
90
+	protected $_gateway_data_formatter;
91
+
92
+	/**
93
+	 * @var FormatterInterface
94
+	 */
95
+	protected $_unsupported_character_remover;
96
+
97
+	/**
98
+	 * The ID of the payment method using this gateway
99
+	 *
100
+	 * @var int
101
+	 */
102
+	protected $_ID;
103
+
104
+	/**
105
+	 * @var $_debug_mode boolean whether to send requests to teh sandbox site or not
106
+	 */
107
+	protected $_debug_mode;
108
+	/**
109
+	 *
110
+	 * @var string $_name name to show for this payment method
111
+	 */
112
+	protected $_name;
113
+	/**
114
+	 *
115
+	 * @var string name to show fir this payment method to admin-type users
116
+	 */
117
+	protected $_admin_name;
118
+
119
+	/**
120
+	 * EE_Gateway constructor
121
+	 */
122
+	public function __construct()
123
+	{
124
+	}
125
+
126
+	/**
127
+	 * We don't want to serialize models as they often have circular structures
128
+	 * (eg a payment model has a reference to each payment model object; and most
129
+	 * payments have a transaction, most transactions have a payment method;
130
+	 * most payment methods have a payment method type; most payment method types
131
+	 * have a gateway. And if a gateway serializes its models, we start at the
132
+	 * beginning again)
133
+	 *
134
+	 * @return array
135
+	 */
136
+	public function __sleep()
137
+	{
138
+		$properties = get_object_vars($this);
139
+		unset($properties['_pay_model'], $properties['_pay_log']);
140
+		return array_keys($properties);
141
+	}
142
+
143
+	/**
144
+	 * Returns whether or not this gateway should support SENDING refunds
145
+	 * see $_supports_sending_refunds
146
+	 *
147
+	 * @return boolean
148
+	 */
149
+	public function supports_sending_refunds()
150
+	{
151
+		return $this->_supports_sending_refunds;
152
+	}
153
+
154
+	/**
155
+	 * Returns whether or not this gateway should support RECEIVING refunds
156
+	 * see $_supports_receiving_refunds
157
+	 *
158
+	 * @return boolean
159
+	 */
160
+	public function supports_receiving_refunds()
161
+	{
162
+		return $this->_supports_receiving_refunds;
163
+	}
164
+
165
+
166
+	/**
167
+	 * Tries to refund the payment specified, taking into account the extra
168
+	 * refund info. Note that if the gateway's _supports_sending_refunds is false,
169
+	 * this should just throw an exception.
170
+	 *
171
+	 * @param EE_Payment $payment
172
+	 * @param array      $refund_info
173
+	 * @return EE_Payment for the refund
174
+	 * @throws EE_Error
175
+	 */
176
+	public function do_direct_refund(EE_Payment $payment, $refund_info = null)
177
+	{
178
+		return null;
179
+	}
180
+
181
+
182
+	/**
183
+	 * Sets the payment method's settings so the gateway knows where to send the request
184
+	 * etc
185
+	 *
186
+	 * @param array $settings_array
187
+	 */
188
+	public function set_settings($settings_array)
189
+	{
190
+		foreach ($settings_array as $name => $value) {
191
+			$property_name = "_" . $name;
192
+			$this->{$property_name} = $value;
193
+		}
194
+	}
195
+
196
+	/**
197
+	 * See this class description
198
+	 *
199
+	 * @param EEMI_Payment $payment_model
200
+	 */
201
+	public function set_payment_model($payment_model)
202
+	{
203
+		$this->_pay_model = $payment_model;
204
+	}
205
+
206
+	/**
207
+	 * See this class description
208
+	 *
209
+	 * @param EEMI_Payment_Log $payment_log_model
210
+	 */
211
+	public function set_payment_log($payment_log_model)
212
+	{
213
+		$this->_pay_log = $payment_log_model;
214
+	}
215
+
216
+	/**
217
+	 * See this class description
218
+	 *
219
+	 * @param EEHI_Template $template_helper
220
+	 */
221
+	public function set_template_helper($template_helper)
222
+	{
223
+		$this->_template = $template_helper;
224
+	}
225
+
226
+	/**
227
+	 * See this class description
228
+	 *
229
+	 * @param EEHI_Line_Item $line_item_helper
230
+	 */
231
+	public function set_line_item_helper($line_item_helper)
232
+	{
233
+		$this->_line_item = $line_item_helper;
234
+	}
235
+
236
+	/**
237
+	 * See this class description
238
+	 *
239
+	 * @param EEHI_Money $money_helper
240
+	 */
241
+	public function set_money_helper($money_helper)
242
+	{
243
+		$this->_money = $money_helper;
244
+	}
245
+
246
+
247
+	/**
248
+	 * Sets the gateway data formatter helper
249
+	 *
250
+	 * @param GatewayDataFormatterInterface $gateway_data_formatter
251
+	 * @throws InvalidEntityException if it's not set properly
252
+	 */
253
+	public function set_gateway_data_formatter(GatewayDataFormatterInterface $gateway_data_formatter)
254
+	{
255
+		if (! $gateway_data_formatter instanceof GatewayDataFormatterInterface) {
256
+			throw new InvalidEntityException(
257
+				is_object($gateway_data_formatter)
258
+					? get_class($gateway_data_formatter)
259
+					: esc_html__('Not an object', 'event_espresso'),
260
+				'\\EventEspresso\\core\\services\\payment_methods\\gateways\\GatewayDataFormatterInterface'
261
+			);
262
+		}
263
+		$this->_gateway_data_formatter = $gateway_data_formatter;
264
+	}
265
+
266
+	/**
267
+	 * Gets the gateway data formatter
268
+	 *
269
+	 * @return GatewayDataFormatterInterface
270
+	 * @throws InvalidEntityException if it's not set properly
271
+	 */
272
+	protected function _get_gateway_formatter()
273
+	{
274
+		if (! $this->_gateway_data_formatter instanceof GatewayDataFormatterInterface) {
275
+			throw new InvalidEntityException(
276
+				is_object($this->_gateway_data_formatter)
277
+					? get_class($this->_gateway_data_formatter)
278
+					: esc_html__('Not an object', 'event_espresso'),
279
+				'\\EventEspresso\\core\\services\\payment_methods\\gateways\\GatewayDataFormatterInterface'
280
+			);
281
+		}
282
+		return $this->_gateway_data_formatter;
283
+	}
284
+
285
+
286
+	/**
287
+	 * Sets the helper which will remove unsupported characters for most gateways
288
+	 *
289
+	 * @param FormatterInterface $formatter
290
+	 * @return FormatterInterface
291
+	 * @throws InvalidEntityException
292
+	 */
293
+	public function set_unsupported_character_remover(FormatterInterface $formatter)
294
+	{
295
+		if (! $formatter instanceof FormatterInterface) {
296
+			throw new InvalidEntityException(
297
+				is_object($formatter)
298
+					? get_class($formatter)
299
+					: esc_html__('Not an object', 'event_espresso'),
300
+				'\\EventEspresso\\core\\services\\formatters\\FormatterInterface'
301
+			);
302
+		}
303
+		$this->_unsupported_character_remover = $formatter;
304
+	}
305
+
306
+	/**
307
+	 * Gets the helper which removes characters which gateways might not support, like emojis etc.
308
+	 *
309
+	 * @return FormatterInterface
310
+	 * @throws InvalidEntityException
311
+	 */
312
+	protected function _get_unsupported_character_remover()
313
+	{
314
+		if (! $this->_unsupported_character_remover instanceof FormatterInterface) {
315
+			throw new InvalidEntityException(
316
+				is_object($this->_unsupported_character_remover)
317
+					? get_class($this->_unsupported_character_remover)
318
+					: esc_html__('Not an object', 'event_espresso'),
319
+				'\\EventEspresso\\core\\services\\formatters\\FormatterInterface'
320
+			);
321
+		}
322
+		return $this->_unsupported_character_remover;
323
+	}
324
+
325
+
326
+	/**
327
+	 * @param $message
328
+	 * @param $payment
329
+	 */
330
+	public function log($message, $object_logged)
331
+	{
332
+		if ($object_logged instanceof EEI_Payment) {
333
+			$type = 'Payment';
334
+			$id = $object_logged->ID();
335
+		} elseif ($object_logged instanceof EEI_Transaction) {
336
+			$type = 'Transaction';
337
+			$id = $object_logged->ID();
338
+		} else {
339
+			$type = 'Payment_Method';
340
+			$id = $this->_ID;
341
+		}
342
+		// only log if we're going to store it for longer than the minimum time
343
+		$reg_config = LoaderFactory::getLoader()->load('EE_Registration_Config');
344
+		if ($reg_config->gateway_log_lifespan !== '1 second') {
345
+			$this->_pay_log->gateway_log($message, $id, $type);
346
+		}
347
+	}
348
+
349
+	/**
350
+	 * Formats the amount so it can generally be sent to gateways
351
+	 *
352
+	 * @param float $amount
353
+	 * @return string
354
+	 * @deprecated since 4.9.31 insetad use
355
+	 *             EventEspresso\core\services\payment_methods\gateways\GatewayDataFormatter::format_currency()
356
+	 */
357
+	public function format_currency($amount)
358
+	{
359
+		return $this->_get_gateway_formatter()->formatCurrency($amount);
360
+	}
361
+
362
+	/**
363
+	 * Returns either an array of all the currency codes supported,
364
+	 * or a string indicating they're all supported (EE_gateway::all_currencies_supported)
365
+	 *
366
+	 * @return mixed array or string
367
+	 */
368
+	public function currencies_supported()
369
+	{
370
+		return $this->_currencies_supported;
371
+	}
372
+
373
+	/**
374
+	 * Returns what a simple summing of items and taxes for this transaction. This
375
+	 * can be used to determine if some more complex line items, like promotions,
376
+	 * surcharges, or cancellations occurred (in which case we might want to forget
377
+	 * about creating an itemized list of purchases and instead only send the total due)
378
+	 *
379
+	 * @param EE_Transaction $transaction
380
+	 * @return float
381
+	 */
382
+	protected function _sum_items_and_taxes(EE_Transaction $transaction)
383
+	{
384
+		$total_line_item = $transaction->total_line_item();
385
+		$total = 0;
386
+		foreach ($total_line_item->get_items() as $item_line_item) {
387
+			$total += max($item_line_item->total(), 0);
388
+		}
389
+		foreach ($total_line_item->tax_descendants() as $tax_line_item) {
390
+			$total += max($tax_line_item->total(), 0);
391
+		}
392
+		return $total;
393
+	}
394
+
395
+	/**
396
+	 * Determines whether or not we can easily itemize the transaction using only
397
+	 * items and taxes (ie, no promotions or surcharges or cancellations needed)
398
+	 *
399
+	 * @param EEI_Payment $payment
400
+	 * @return boolean
401
+	 */
402
+	protected function _can_easily_itemize_transaction_for(EEI_Payment $payment)
403
+	{
404
+		return $this->_money->compare_floats(
405
+			$this->_sum_items_and_taxes($payment->transaction()),
406
+			$payment->transaction()->total()
407
+		)
408
+			   && $this->_money->compare_floats(
409
+				   $payment->amount(),
410
+				   $payment->transaction()->total()
411
+			   );
412
+	}
413
+
414
+	/**
415
+	 * Handles updating the transaction and any other related data based on the payment.
416
+	 * You may be tempted to do this as part of do_direct_payment or handle_payment_update,
417
+	 * but doing so on those functions might be too early. It's possible that the changes
418
+	 * you make to teh transaction or registration or line items may just get overwritten
419
+	 * at that point. Instead, you should store any info you need on the payment during those
420
+	 * functions, and use that information at this step, which client code will decide
421
+	 * for you when it should be called.
422
+	 *
423
+	 * @param EE_Payment $payment
424
+	 * @return void
425
+	 */
426
+	public function update_txn_based_on_payment($payment)
427
+	{
428
+		// maybe update the transaction or line items or registrations
429
+		// but most gateways don't need to do this, because they only update the payment
430
+	}
431
+
432
+	/**
433
+	 * Gets the first event for this payment (it's possible that it could be for multiple)
434
+	 *
435
+	 * @param EEI_Payment $payment
436
+	 * @return EEI_Event|null
437
+	 * @deprecated since 4.9.31 instead use EEI_Payment::get_first_event()
438
+	 */
439
+	protected function _get_first_event_for_payment(EEI_Payment $payment)
440
+	{
441
+		return $payment->get_first_event();
442
+	}
443
+
444
+	/**
445
+	 * Gets the name of the first event for which is being paid
446
+	 *
447
+	 * @param EEI_Payment $payment
448
+	 * @return string
449
+	 * @deprecated since 4.9.31 instead use EEI_Payment::get_first_event_name()
450
+	 */
451
+	protected function _get_first_event_name_for_payment(EEI_Payment $payment)
452
+	{
453
+		return $payment->get_first_event_name();
454
+	}
455
+
456
+	/**
457
+	 * Gets the text to use for a gateway's line item name when this is a partial payment
458
+	 *
459
+	 * @deprecated since 4.9.31 instead use $this->_get_gateway_formatter()->formatPartialPaymentLineItemName($payment)
460
+	 * @param EE_Payment $payment
461
+	 * @return string
462
+	 */
463
+	protected function _format_partial_payment_line_item_name(EEI_Payment $payment)
464
+	{
465
+		return $this->_get_gateway_formatter()->formatPartialPaymentLineItemName($payment);
466
+	}
467
+
468
+	/**
469
+	 * Gets the text to use for a gateway's line item description when this is a partial payment
470
+	 *
471
+	 * @deprecated since 4.9.31 instead use $this->_get_gateway_formatter()->formatPartialPaymentLineItemDesc()
472
+	 * @param EEI_Payment $payment
473
+	 * @return string
474
+	 */
475
+	protected function _format_partial_payment_line_item_desc(EEI_Payment $payment)
476
+	{
477
+		return $this->_get_gateway_formatter()->formatPartialPaymentLineItemDesc($payment);
478
+	}
479
+
480
+	/**
481
+	 * Gets the name to use for a line item when sending line items to the gateway
482
+	 *
483
+	 * @deprecated since 4.9.31 instead use $this->_get_gateway_formatter()->formatLineItemName($line_item,$payment)
484
+	 * @param EE_Line_Item $line_item
485
+	 * @param EEI_Payment   $payment
486
+	 * @return string
487
+	 */
488
+	protected function _format_line_item_name(EE_Line_Item $line_item, EEI_Payment $payment)
489
+	{
490
+		return $this->_get_gateway_formatter()->formatLineItemName($line_item, $payment);
491
+	}
492
+
493
+	/**
494
+	 * Gets the description to use for a line item when sending line items to the gateway
495
+	 *
496
+	 * @deprecated since 4.9.31 instead use $this->_get_gateway_formatter()->formatLineItemDesc($line_item, $payment))
497
+	 * @param EE_Line_Item $line_item
498
+	 * @param EEI_Payment   $payment
499
+	 * @return string
500
+	 */
501
+	protected function _format_line_item_desc(EE_Line_Item $line_item, EEI_Payment $payment)
502
+	{
503
+		return $this->_get_gateway_formatter()->formatLineItemDesc($line_item, $payment);
504
+	}
505
+
506
+	/**
507
+	 * Gets the order description that should generlly be sent to gateways
508
+	 *
509
+	 * @deprecated since 4.9.31 instead use $this->_get_gateway_formatter()->formatOrderDescription($payment)
510
+	 * @param EEI_Payment $payment
511
+	 * @return type
512
+	 */
513
+	protected function _format_order_description(EEI_Payment $payment)
514
+	{
515
+		return $this->_get_gateway_formatter()->formatOrderDescription($payment);
516
+	}
517
+
518
+
519
+	/**
520
+	 * @return bool
521
+	 */
522
+	public function isInSandboxMode(): bool
523
+	{
524
+		return $this->_debug_mode;
525
+	}
526 526
 }
Please login to merge, or discard this patch.
core/libraries/payment_methods/EE_Offsite_Gateway.lib.php 1 patch
Indentation   +102 added lines, -102 removed lines patch added patch discarded remove patch
@@ -15,117 +15,117 @@
 block discarded – undo
15 15
 abstract class EE_Offsite_Gateway extends EE_Gateway
16 16
 {
17 17
 
18
-    /**
19
-     * whether or not the gateway uses an IPN
20
-     * that is sent in a separate request than the returning registrant.
21
-     * if false, then we need to process the payment results manually
22
-     * as soon as the registrant returns from the off-site gateway
23
-     *
24
-     * @type bool
25
-     */
26
-    protected $_uses_separate_IPN_request = false;
18
+	/**
19
+	 * whether or not the gateway uses an IPN
20
+	 * that is sent in a separate request than the returning registrant.
21
+	 * if false, then we need to process the payment results manually
22
+	 * as soon as the registrant returns from the off-site gateway
23
+	 *
24
+	 * @type bool
25
+	 */
26
+	protected $_uses_separate_IPN_request = false;
27 27
 
28 28
 
29
-    /**
30
-     * EE_Offsite_Gateway constructor
31
-     */
32
-    public function __construct()
33
-    {
34
-        $this->_supports_receiving_refunds = true;
35
-        parent::__construct();
36
-    }
29
+	/**
30
+	 * EE_Offsite_Gateway constructor
31
+	 */
32
+	public function __construct()
33
+	{
34
+		$this->_supports_receiving_refunds = true;
35
+		parent::__construct();
36
+	}
37 37
 
38 38
 
39
-    /**
40
-     * Adds information into the payment object's redirect_url and redirect_args so
41
-     * client code can use that payment to know where (and with what information)
42
-     * to redirect the user to in order to make the payment on the offsite gateway's website.
43
-     * Saving the payment from within this method is unnecessary,
44
-     * as it is the responsibility of client code to save it.
45
-     *
46
-     * @param EE_Payment $payment    to process
47
-     * @param array      $billing_info
48
-     * @param string     $return_url URL to send the user to after a successful payment on the payment provider's
49
-     *                               website
50
-     * @param string     $notify_url URL to send the instant payment notification
51
-     * @param string     $cancel_url URL to send the user to after a cancelled payment attempt on teh payment
52
-     *                               provider's website
53
-     * @return EE_Payment
54
-     */
55
-    abstract public function set_redirection_info(
56
-        $payment,
57
-        $billing_info = array(),
58
-        $return_url = null,
59
-        $notify_url = null,
60
-        $cancel_url = null
61
-    );
39
+	/**
40
+	 * Adds information into the payment object's redirect_url and redirect_args so
41
+	 * client code can use that payment to know where (and with what information)
42
+	 * to redirect the user to in order to make the payment on the offsite gateway's website.
43
+	 * Saving the payment from within this method is unnecessary,
44
+	 * as it is the responsibility of client code to save it.
45
+	 *
46
+	 * @param EE_Payment $payment    to process
47
+	 * @param array      $billing_info
48
+	 * @param string     $return_url URL to send the user to after a successful payment on the payment provider's
49
+	 *                               website
50
+	 * @param string     $notify_url URL to send the instant payment notification
51
+	 * @param string     $cancel_url URL to send the user to after a cancelled payment attempt on teh payment
52
+	 *                               provider's website
53
+	 * @return EE_Payment
54
+	 */
55
+	abstract public function set_redirection_info(
56
+		$payment,
57
+		$billing_info = array(),
58
+		$return_url = null,
59
+		$notify_url = null,
60
+		$cancel_url = null
61
+	);
62 62
 
63 63
 
64
-    /**
65
-     * Often used for IPNs. But applies the info in $update_info to the payment.
66
-     * What is $update_info? Often the contents of $_REQUEST, but not necessarily. Whatever
67
-     * the payment method passes in. Saving the payment from within this method is unnecessary,
68
-     * as it is the responsibility of client code to save it.
69
-     *
70
-     * @param array           $update_info of whatever
71
-     * @param EEI_Transaction $transaction
72
-     * @return EEI_Payment updated
73
-     */
74
-    abstract public function handle_payment_update($update_info, $transaction);
64
+	/**
65
+	 * Often used for IPNs. But applies the info in $update_info to the payment.
66
+	 * What is $update_info? Often the contents of $_REQUEST, but not necessarily. Whatever
67
+	 * the payment method passes in. Saving the payment from within this method is unnecessary,
68
+	 * as it is the responsibility of client code to save it.
69
+	 *
70
+	 * @param array           $update_info of whatever
71
+	 * @param EEI_Transaction $transaction
72
+	 * @return EEI_Payment updated
73
+	 */
74
+	abstract public function handle_payment_update($update_info, $transaction);
75 75
 
76 76
 
77
-    /**
78
-     * uses_separate_IPN_request
79
-     *
80
-     * return true or false for whether or not the gateway uses an IPN
81
-     * that is sent in a separate request than the returning registrant.
82
-     * if false, then we need to process the payment results manually
83
-     * as soon as the registrant returns from the off-site gateway
84
-     *
85
-     * @deprecated since version 4.8.39.rc.001 please use handle_IPN_in_this_request() instead
86
-     *
87
-     * @return bool
88
-     */
89
-    public function uses_separate_IPN_request()
90
-    {
91
-        return $this->_uses_separate_IPN_request;
92
-    }
77
+	/**
78
+	 * uses_separate_IPN_request
79
+	 *
80
+	 * return true or false for whether or not the gateway uses an IPN
81
+	 * that is sent in a separate request than the returning registrant.
82
+	 * if false, then we need to process the payment results manually
83
+	 * as soon as the registrant returns from the off-site gateway
84
+	 *
85
+	 * @deprecated since version 4.8.39.rc.001 please use handle_IPN_in_this_request() instead
86
+	 *
87
+	 * @return bool
88
+	 */
89
+	public function uses_separate_IPN_request()
90
+	{
91
+		return $this->_uses_separate_IPN_request;
92
+	}
93 93
 
94 94
 
95
-    /**
96
-     * set_uses_separate_IPN_request
97
-     *
98
-     * @access protected
99
-     * @param boolean $uses_separate_IPN_request
100
-     */
101
-    protected function set_uses_separate_IPN_request($uses_separate_IPN_request)
102
-    {
103
-        $this->_uses_separate_IPN_request = filter_var($uses_separate_IPN_request, FILTER_VALIDATE_BOOLEAN);
104
-    }
95
+	/**
96
+	 * set_uses_separate_IPN_request
97
+	 *
98
+	 * @access protected
99
+	 * @param boolean $uses_separate_IPN_request
100
+	 */
101
+	protected function set_uses_separate_IPN_request($uses_separate_IPN_request)
102
+	{
103
+		$this->_uses_separate_IPN_request = filter_var($uses_separate_IPN_request, FILTER_VALIDATE_BOOLEAN);
104
+	}
105 105
 
106
-    /**
107
-     * Allows gateway to dynamically decide whether or not to handle a payment update
108
-     * by overriding this method. By default, if this is a "true" IPN (meaning
109
-     * it's a separate request from when the user returns from the offsite gateway)
110
-     * and this gateway class is setup to handle IPNs in separate "true" IPNs, then
111
-     * this will return true, otherwise it will return false.
112
-     * If however, this is a request when the user is returning
113
-     * from an offsite gateway, and this gateway class is setup to process the payment
114
-     * data when the user returns, then this will return true.
115
-     *
116
-     * @param array   $request_data
117
-     * @param boolean $separate_IPN_request
118
-     * @return boolean
119
-     */
120
-    public function handle_IPN_in_this_request($request_data, $separate_IPN_request)
121
-    {
122
-        if ($separate_IPN_request) {
123
-            // payment data being sent in a request separate from the user
124
-            // it is this other request that will update the TXN and payment info
125
-            return $this->_uses_separate_IPN_request;
126
-        } else {
127
-            // it's a request where the user returned from an offsite gateway WITH the payment data
128
-            return ! $this->_uses_separate_IPN_request;
129
-        }
130
-    }
106
+	/**
107
+	 * Allows gateway to dynamically decide whether or not to handle a payment update
108
+	 * by overriding this method. By default, if this is a "true" IPN (meaning
109
+	 * it's a separate request from when the user returns from the offsite gateway)
110
+	 * and this gateway class is setup to handle IPNs in separate "true" IPNs, then
111
+	 * this will return true, otherwise it will return false.
112
+	 * If however, this is a request when the user is returning
113
+	 * from an offsite gateway, and this gateway class is setup to process the payment
114
+	 * data when the user returns, then this will return true.
115
+	 *
116
+	 * @param array   $request_data
117
+	 * @param boolean $separate_IPN_request
118
+	 * @return boolean
119
+	 */
120
+	public function handle_IPN_in_this_request($request_data, $separate_IPN_request)
121
+	{
122
+		if ($separate_IPN_request) {
123
+			// payment data being sent in a request separate from the user
124
+			// it is this other request that will update the TXN and payment info
125
+			return $this->_uses_separate_IPN_request;
126
+		} else {
127
+			// it's a request where the user returned from an offsite gateway WITH the payment data
128
+			return ! $this->_uses_separate_IPN_request;
129
+		}
130
+	}
131 131
 }
Please login to merge, or discard this patch.
payment_methods/Paypal_Express/polyfills.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -1,6 +1,6 @@
 block discarded – undo
1 1
 <?php
2 2
 
3
-if (! function_exists('mb_strcut')) {
3
+if ( ! function_exists('mb_strcut')) {
4 4
     /**
5 5
      * Quickfix to address https://events.codebasehq.com/projects/event-espresso/tickets/11089 ASAP
6 6
      * Very simple mimic of mb_substr (which WP ensures exists in wp-includes/compat.php). Still has all the problems of mb_substr
Please login to merge, or discard this patch.
Indentation   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -1,18 +1,18 @@
 block discarded – undo
1 1
 <?php
2 2
 
3 3
 if (! function_exists('mb_strcut')) {
4
-    /**
5
-     * Quickfix to address https://events.codebasehq.com/projects/event-espresso/tickets/11089 ASAP
6
-     * Very simple mimic of mb_substr (which WP ensures exists in wp-includes/compat.php). Still has all the problems of mb_substr
7
-     * (namely, that we might send too many characters to PayPal; however in this case they just issue a warning but nothing breaks)
8
-     *
9
-     * @param $string
10
-     * @param $start
11
-     * @param $length
12
-     * @return string
13
-     */
14
-    function mb_strcut($string, $start, $length = null): string
15
-    {
16
-        return mb_substr($string, $start, $length);
17
-    }
4
+	/**
5
+	 * Quickfix to address https://events.codebasehq.com/projects/event-espresso/tickets/11089 ASAP
6
+	 * Very simple mimic of mb_substr (which WP ensures exists in wp-includes/compat.php). Still has all the problems of mb_substr
7
+	 * (namely, that we might send too many characters to PayPal; however in this case they just issue a warning but nothing breaks)
8
+	 *
9
+	 * @param $string
10
+	 * @param $start
11
+	 * @param $length
12
+	 * @return string
13
+	 */
14
+	function mb_strcut($string, $start, $length = null): string
15
+	{
16
+		return mb_substr($string, $start, $length);
17
+	}
18 18
 }
19 19
\ No newline at end of file
Please login to merge, or discard this patch.
payment_methods/Paypal_Standard/EEG_Paypal_Standard.gateway.php 2 patches
Indentation   +550 added lines, -550 removed lines patch added patch discarded remove patch
@@ -20,554 +20,554 @@
 block discarded – undo
20 20
 class EEG_Paypal_Standard extends EE_Offsite_Gateway
21 21
 {
22 22
 
23
-    /**
24
-     * Name for the wp option used to save the itemized payment
25
-     */
26
-    const itemized_payment_option_name = '_itemized_payment';
27
-
28
-    protected $_paypal_id;
29
-
30
-    protected $_image_url;
31
-
32
-    protected $_shipping_details;
33
-
34
-    protected $_paypal_shipping;
35
-
36
-    protected $_paypal_taxes;
37
-
38
-    protected $_gateway_url;
39
-
40
-    protected $_currencies_supported = array(
41
-        'USD',
42
-        'GBP',
43
-        'CAD',
44
-        'AUD',
45
-        'BRL',
46
-        'CHF',
47
-        'CZK',
48
-        'DKK',
49
-        'EUR',
50
-        'HKD',
51
-        'HUF',
52
-        'ILS',
53
-        'JPY',
54
-        'MXN',
55
-        'MYR',
56
-        'NOK',
57
-        'NZD',
58
-        'PHP',
59
-        'PLN',
60
-        'SEK',
61
-        'SGD',
62
-        'THB',
63
-        'TRY',
64
-        'TWD',
65
-        'RUB'
66
-    );
67
-
68
-    /**
69
-     * @var ItemizedOrder
70
-     * @since $VID:$
71
-     */
72
-    protected $itemized_order;
73
-
74
-
75
-    /**
76
-     * EEG_Paypal_Standard constructor.
77
-     */
78
-    public function __construct()
79
-    {
80
-        $this->set_uses_separate_IPN_request(true);
81
-        parent::__construct();
82
-    }
83
-
84
-
85
-    /**
86
-     * @return mixed
87
-     */
88
-    public function gatewayUrl()
89
-    {
90
-        return $this->_gateway_url;
91
-    }
92
-
93
-
94
-    /**
95
-     * @return mixed
96
-     */
97
-    public function imageUrl()
98
-    {
99
-        return $this->_image_url;
100
-    }
101
-
102
-
103
-    /**
104
-     * @return mixed
105
-     */
106
-    public function paypalId()
107
-    {
108
-        return $this->_paypal_id;
109
-    }
110
-
111
-
112
-    /**
113
-     * @return mixed
114
-     */
115
-    public function paypalShipping()
116
-    {
117
-        return $this->_paypal_shipping;
118
-    }
119
-
120
-
121
-
122
-    /**
123
-     * @return mixed
124
-     */
125
-    public function paypalTaxes()
126
-    {
127
-        return $this->_paypal_taxes;
128
-    }
129
-
130
-
131
-    /**
132
-     * @return mixed
133
-     */
134
-    public function shippingDetails()
135
-    {
136
-        return $this->_shipping_details;
137
-    }
138
-
139
-
140
-    /**
141
-     * Also sets the gateway url class variable based on whether debug mode is enabled or not.
142
-     *
143
-     * @param array $settings_array
144
-     */
145
-    public function set_settings($settings_array)
146
-    {
147
-        parent::set_settings($settings_array);
148
-        $this->_gateway_url = $this->_debug_mode
149
-            ? 'https://www.sandbox.paypal.com/cgi-bin/webscr'
150
-            : 'https://www.paypal.com/cgi-bin/webscr';
151
-    }
152
-
153
-
154
-    /**
155
-     * @param EEI_Payment $payment      the payment to process
156
-     * @param array       $billing_info but should be empty for this gateway
157
-     * @param string      $return_url   URL to send the user to after payment on the payment provider's website
158
-     * @param string      $notify_url   URL to send the instant payment notification
159
-     * @param string      $cancel_url   URL to send the user to after a cancelled payment attempt
160
-     *                                  on the payment provider's website
161
-     * @return EEI_Payment
162
-     * @throws EE_Error
163
-     * @throws ReflectionException
164
-     */
165
-    public function set_redirection_info(
166
-        $payment,
167
-        $billing_info = array(),
168
-        $return_url = null,
169
-        $notify_url = null,
170
-        $cancel_url = null
171
-    ) {
172
-        $this->itemized_order = new ItemizedOrder($this->_get_gateway_formatter(), $this);
173
-        $redirect_args = apply_filters(
174
-            "FHEE__EEG_Paypal_Standard__set_redirection_info__arguments",
175
-            $this->itemized_order->generateItemizedOrderForPayment(
176
-                $payment,
177
-                $return_url,
178
-                $notify_url,
179
-                $cancel_url
180
-            ),
181
-            $this
182
-        );
183
-
184
-        $payment->set_redirect_url($this->_gateway_url);
185
-        $payment->set_redirect_args($redirect_args);
186
-        // log the results
187
-        $this->log(
188
-            array(
189
-                'message'     => esc_html__('PayPal payment request initiated.', 'event_espresso'),
190
-                'transaction' => $payment->transaction()->model_field_array(),
191
-            ),
192
-            $payment
193
-        );
194
-        return $payment;
195
-    }
196
-
197
-
198
-    /**
199
-     * Often used for IPNs. But applies the info in $update_info to the payment.
200
-     * What is $update_info? Often the contents of $_REQUEST, but not necessarily. Whatever
201
-     * the payment method passes in.
202
-     *
203
-     * @param array $update_info like $_POST
204
-     * @param EEI_Transaction $transaction
205
-     * @return EEI_Payment updated
206
-     * @throws EE_Error, IpnException
207
-     */
208
-    public function handle_payment_update($update_info, $transaction)
209
-    {
210
-        // verify there's payment data that's been sent
211
-        if (empty($update_info['payment_status']) || empty($update_info['txn_id'])) {
212
-            // log the results
213
-            $this->log(
214
-                array(
215
-                    'message'     => esc_html__(
216
-                        'PayPal IPN response is missing critical payment data. This may indicate a PDT request and require your PayPal account settings to be corrected.',
217
-                        'event_espresso'
218
-                    ),
219
-                    'update_info' => $update_info,
220
-                ),
221
-                $transaction
222
-            );
223
-            // waaaait... is this a PDT request? (see https://developer.paypal.com/docs/classic/products/payment-data-transfer/)
224
-            // indicated by the "tx" argument? If so, we don't need it. We'll just use the IPN data when it comes
225
-            if (isset($update_info['tx'])) {
226
-                return $transaction->last_payment();
227
-            } else {
228
-                return null;
229
-            }
230
-        }
231
-        $payment = $this->_pay_model->get_payment_by_txn_id_chq_nmbr($update_info['txn_id']);
232
-        if (! $payment instanceof EEI_Payment) {
233
-            $payment = $transaction->last_payment();
234
-        }
235
-        // ok, then validate the IPN. Even if we've already processed this payment,
236
-        // let PayPal know we don't want to hear from them anymore!
237
-        if (! $this->validate_ipn($update_info, $payment)) {
238
-            return $payment;
239
-        }
240
-        // kill request here if this is a refund, we don't support them yet (we'd need to adjust the transaction,
241
-        // registrations, ticket counts, etc)
242
-        if (
243
-            (
244
-                $update_info['payment_status'] === 'Refunded'
245
-                || $update_info['payment_status'] === 'Partially_Refunded'
246
-            )
247
-            && apply_filters('FHEE__EEG_Paypal_Standard__handle_payment_update__kill_refund_request', true)
248
-        ) {
249
-            throw new EventEspresso\core\exceptions\IpnException(
250
-                sprintf(
251
-                    esc_html__('Event Espresso does not yet support %1$s IPNs from PayPal', 'event_espresso'),
252
-                    $update_info['payment_status']
253
-                ),
254
-                EventEspresso\core\exceptions\IpnException::UNSUPPORTED,
255
-                null,
256
-                $payment,
257
-                $update_info
258
-            );
259
-        }
260
-        // ok, well let's process this payment then!
261
-        switch ($update_info['payment_status']) {
262
-            case 'Completed':
263
-                $status = $this->_pay_model->approved_status();
264
-                $gateway_response = esc_html__('The payment is approved.', 'event_espresso');
265
-                break;
266
-
267
-            case 'Pending':
268
-                $status = $this->_pay_model->pending_status();
269
-                $gateway_response = esc_html__(
270
-                    'The payment is in progress. Another message will be sent when payment is approved.',
271
-                    'event_espresso'
272
-                );
273
-                break;
274
-
275
-            case 'Denied':
276
-                $status = $this->_pay_model->declined_status();
277
-                $gateway_response = esc_html__('The payment has been declined.', 'event_espresso');
278
-                break;
279
-
280
-            case 'Expired':
281
-            case 'Failed':
282
-                $status = $this->_pay_model->failed_status();
283
-                $gateway_response = esc_html__('The payment failed for technical reasons or expired.', 'event_espresso');
284
-                break;
285
-
286
-            case 'Refunded':
287
-            case 'Partially_Refunded':
288
-                // even though it's a refund, we consider the payment as approved, it just has a negative value
289
-                $status = $this->_pay_model->approved_status();
290
-                $gateway_response = esc_html__(
291
-                    'The payment has been refunded. Please update registrations accordingly.',
292
-                    'event_espresso'
293
-                );
294
-                break;
295
-
296
-            case 'Voided':
297
-            case 'Reversed':
298
-            case 'Canceled_Reversal':
299
-            default:
300
-                $status = $this->_pay_model->cancelled_status();
301
-                $gateway_response = esc_html__(
302
-                    'The payment was cancelled, reversed, or voided. Please update registrations accordingly.',
303
-                    'event_espresso'
304
-                );
305
-                break;
306
-        }
307
-
308
-        // check if we've already processed this payment
309
-        if ($payment instanceof EEI_Payment) {
310
-            // payment exists. if this has the exact same status and amount, don't bother updating. just return
311
-            if ($payment->status() === $status && $payment->amount() === (float) $update_info['mc_gross']) {
312
-                // DUPLICATED IPN! don't bother updating transaction
313
-                throw new IpnException(
314
-                    sprintf(
315
-                        esc_html__(
316
-                            'It appears we have received a duplicate IPN from PayPal for payment %d',
317
-                            'event_espresso'
318
-                        ),
319
-                        $payment->ID()
320
-                    ),
321
-                    IpnException::DUPLICATE,
322
-                    null,
323
-                    $payment,
324
-                    $update_info
325
-                );
326
-            } else {
327
-                // new payment yippee !!!
328
-                $payment->set_status($status);
329
-                $payment->set_amount((float) $update_info['mc_gross']);
330
-                $payment->set_gateway_response($gateway_response);
331
-                $payment->set_details($update_info);
332
-                $payment->set_txn_id_chq_nmbr($update_info['txn_id']);
333
-                $this->log(
334
-                    array(
335
-                        'message'  => esc_html__(
336
-                            'Updated payment either from IPN or as part of POST from PayPal',
337
-                            'event_espresso'
338
-                        ),
339
-                        'url'      => $this->_process_response_url(),
340
-                        'payment'  => $payment->model_field_array(),
341
-                        'IPN_data' => $update_info
342
-                    ),
343
-                    $payment
344
-                );
345
-            }
346
-        }
347
-        do_action('FHEE__EEG_Paypal_Standard__handle_payment_update__payment_processed', $payment, $this);
348
-        return $payment;
349
-    }
350
-
351
-
352
-    /**
353
-     * Validate the IPN notification.
354
-     *
355
-     * @param array                  $update_info like $_REQUEST
356
-     * @param EE_Payment|EEI_Payment $payment
357
-     * @return boolean
358
-     * @throws EE_Error
359
-     */
360
-    public function validate_ipn($update_info, $payment)
361
-    {
362
-        // allow us to skip validating IPNs with PayPal (useful for testing)
363
-        if (apply_filters('FHEE__EEG_Paypal_Standard__validate_ipn__skip', false)) {
364
-            return true;
365
-        }
366
-        // ...otherwise, we actually don't care what the $update_info is, we need to look
367
-        // at the request directly because we can't use $update_info because it has issues with quotes
368
-        // Reading POSTed data directly from $_POST causes serialization issues with array data in the POST.
369
-        // Instead, read raw POST data from the input stream.
370
-        // @see https://gist.github.com/xcommerce-gists/3440401
371
-        $raw_post_data = file_get_contents('php://input');
372
-        $raw_post_array = explode('&', $raw_post_data);
373
-        $update_info = array();
374
-        foreach ($raw_post_array as $keyval) {
375
-            $keyval = explode('=', $keyval);
376
-            if (count($keyval) === 2) {
377
-                $update_info[ $keyval[0] ] = urldecode($keyval[1]);
378
-            }
379
-        }
380
-        // read the IPN message sent from PayPal and prepend 'cmd=_notify-validate'
381
-        $req = 'cmd=_notify-validate';
382
-        $uses_get_magic_quotes = function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() === 1;
383
-        foreach ($update_info as $key => $value) {
384
-            $value = $uses_get_magic_quotes ? urlencode(stripslashes($value)) : urlencode($value);
385
-            $req .= "&$key=$value";
386
-        }
387
-        // HTTP POST the complete, unaltered IPN back to PayPal
388
-        $response = wp_remote_post(
389
-            $this->_gateway_url,
390
-            array(
391
-                'body'              => $req,
392
-                'sslverify'         => false,
393
-                'timeout'           => 60,
394
-                // make sure to set a site specific unique "user-agent" string since the WordPres default gets declined by PayPal
395
-                // plz see: https://github.com/websharks/s2member/issues/610
396
-                'user-agent'        => 'Event Espresso v' . EVENT_ESPRESSO_VERSION . '; ' . home_url(),
397
-                'httpversion'       => '1.1'
398
-            )
399
-        );
400
-        // then check the response
401
-        if (
402
-            array_key_exists('body', $response)
403
-            && ! is_wp_error($response)
404
-            && strcmp($response['body'], "VERIFIED") === 0
405
-        ) {
406
-            return true;
407
-        }
408
-        // huh, something's wack... the IPN didn't validate. We must have replied to the IPN incorrectly,
409
-        // or their API must have changed: http://www.paypalobjects.com/en_US/ebook/PP_OrderManagement_IntegrationGuide/ipn.html
410
-        if ($response instanceof WP_Error) {
411
-            $error_msg = sprintf(
412
-                esc_html__('WP Error. Code: "%1$s", Message: "%2$s", Data: "%3$s"', 'event_espresso'),
413
-                $response->get_error_code(),
414
-                $response->get_error_message(),
415
-                print_r($response->get_error_data(), true)
416
-            );
417
-        } elseif (is_array($response) && isset($response['body'])) {
418
-            $error_msg = $response['body'];
419
-        } else {
420
-            $error_msg = print_r($response, true);
421
-        }
422
-        $payment->set_gateway_response(
423
-            sprintf(
424
-                esc_html__("IPN Validation failed! Paypal responded with '%s'", "event_espresso"),
425
-                $error_msg
426
-            )
427
-        );
428
-        $payment->set_details(array('REQUEST' => $update_info, 'VALIDATION_RESPONSE' => $response));
429
-        $payment->set_status(EEM_Payment::status_id_failed);
430
-        // log the results
431
-        $this->log(
432
-            array(
433
-                'url'     => $this->_process_response_url(),
434
-                'message' => $payment->gateway_response(),
435
-                'details' => $payment->details(),
436
-            ),
437
-            $payment
438
-        );
439
-        return false;
440
-    }
441
-
442
-
443
-    /**
444
-     * _process_response_url
445
-     * @return string
446
-     */
447
-    protected function _process_response_url(): string
448
-    {
449
-        if (isset($_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'])) {
450
-            $url = is_ssl() ? 'https://' : 'http://';
451
-            $url .= EEH_URL::filter_input_server_url('HTTP_HOST');
452
-            $url .= EEH_URL::filter_input_server_url();
453
-        } else {
454
-            $url = 'unknown';
455
-        }
456
-        return $url;
457
-    }
458
-
459
-
460
-    /**
461
-     * Updates the transaction and line items based on the payment IPN data from PayPal,
462
-     * like the taxes or shipping
463
-     *
464
-     * @param EEI_Payment $payment
465
-     * @throws EE_Error
466
-     * @throws ReflectionException
467
-     */
468
-    public function update_txn_based_on_payment($payment)
469
-    {
470
-        $update_info = $payment->details();
471
-        /** @var EE_Transaction $transaction */
472
-        $transaction = $payment->transaction();
473
-        $payment_was_itemized = $payment->get_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, true, false);
474
-        if (! $transaction) {
475
-            $this->log(
476
-                esc_html__(
477
-                    // @codingStandardsIgnoreStart
478
-                    'Payment with ID %d has no related transaction, and so update_txn_based_on_payment couldn\'t be executed properly',
479
-                    // @codingStandardsIgnoreEnd
480
-                    'event_espresso'
481
-                ),
482
-                $payment
483
-            );
484
-            return;
485
-        }
486
-        if (
487
-            ! is_array($update_info)
488
-            || ! isset($update_info['mc_shipping'])
489
-            || ! isset($update_info['tax'])
490
-        ) {
491
-            $this->log(
492
-                array(
493
-                    'message' => esc_html__(
494
-                        // @codingStandardsIgnoreStart
495
-                        'Could not update transaction based on payment because the payment details have not yet been put on the payment. This normally happens during the IPN or returning from PayPal',
496
-                        // @codingStandardsIgnoreEnd
497
-                        'event_espresso'
498
-                    ),
499
-                    'url'     => $this->_process_response_url(),
500
-                    'payment' => $payment->model_field_array()
501
-                ),
502
-                $payment
503
-            );
504
-            return;
505
-        }
506
-        if ($payment->status() !== $this->_pay_model->approved_status()) {
507
-            $this->log(
508
-                array(
509
-                    'message' => esc_html__(
510
-                        'We shouldn\'t update transactions taxes or shipping data from non-approved payments',
511
-                        'event_espresso'
512
-                    ),
513
-                    'url'     => $this->_process_response_url(),
514
-                    'payment' => $payment->model_field_array()
515
-                ),
516
-                $payment
517
-            );
518
-            return;
519
-        }
520
-        $grand_total_needs_resaving = false;
521
-        /** @var EE_Line_Item $transaction_total_line_item */
522
-        $transaction_total_line_item = $transaction->total_line_item();
523
-
524
-        // might paypal have changed the taxes?
525
-        if ($this->_paypal_taxes && $payment_was_itemized) {
526
-            // note that we're doing this BEFORE adding shipping;
527
-            // we actually want PayPal's shipping to remain non-taxable
528
-            $this->_line_item->set_line_items_taxable($transaction_total_line_item, true, 'paypal_shipping');
529
-            $this->_line_item->set_total_tax_to(
530
-                $transaction_total_line_item,
531
-                (float) $update_info['tax'],
532
-                esc_html__('Taxes', 'event_espresso'),
533
-                esc_html__('Calculated by Paypal', 'event_espresso'),
534
-                'paypal_tax'
535
-            );
536
-            $grand_total_needs_resaving = true;
537
-        }
538
-
539
-        $shipping_amount = (float) $update_info['mc_shipping'];
540
-        // might paypal have added shipping?
541
-        if ($this->_paypal_shipping && $shipping_amount && $payment_was_itemized) {
542
-            $this->_line_item->add_unrelated_item(
543
-                $transaction_total_line_item,
544
-                sprintf(esc_html__('Shipping for transaction %1$s', 'event_espresso'), $transaction->ID()),
545
-                $shipping_amount,
546
-                esc_html__('Shipping charges calculated by Paypal', 'event_espresso'),
547
-                1,
548
-                false,
549
-                'paypal_shipping_' . $transaction->ID()
550
-            );
551
-            $grand_total_needs_resaving = true;
552
-        }
553
-
554
-        if ($grand_total_needs_resaving) {
555
-            $transaction_total_line_item->save_this_and_descendants_to_txn($transaction->ID());
556
-            /** @var EE_Registration_Processor $registration_processor */
557
-            $registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
558
-            $registration_processor->update_registration_final_prices($transaction);
559
-        }
560
-        $this->log(
561
-            array(
562
-                'message'                     => esc_html__('Updated transaction related to payment', 'event_espresso'),
563
-                'url'                         => $this->_process_response_url(),
564
-                'transaction (updated)'       => $transaction->model_field_array(),
565
-                'payment (updated)'           => $payment->model_field_array(),
566
-                'use_paypal_shipping'         => $this->_paypal_shipping,
567
-                'use_paypal_tax'              => $this->_paypal_taxes,
568
-                'grand_total_needed_resaving' => $grand_total_needs_resaving,
569
-            ),
570
-            $payment
571
-        );
572
-    }
23
+	/**
24
+	 * Name for the wp option used to save the itemized payment
25
+	 */
26
+	const itemized_payment_option_name = '_itemized_payment';
27
+
28
+	protected $_paypal_id;
29
+
30
+	protected $_image_url;
31
+
32
+	protected $_shipping_details;
33
+
34
+	protected $_paypal_shipping;
35
+
36
+	protected $_paypal_taxes;
37
+
38
+	protected $_gateway_url;
39
+
40
+	protected $_currencies_supported = array(
41
+		'USD',
42
+		'GBP',
43
+		'CAD',
44
+		'AUD',
45
+		'BRL',
46
+		'CHF',
47
+		'CZK',
48
+		'DKK',
49
+		'EUR',
50
+		'HKD',
51
+		'HUF',
52
+		'ILS',
53
+		'JPY',
54
+		'MXN',
55
+		'MYR',
56
+		'NOK',
57
+		'NZD',
58
+		'PHP',
59
+		'PLN',
60
+		'SEK',
61
+		'SGD',
62
+		'THB',
63
+		'TRY',
64
+		'TWD',
65
+		'RUB'
66
+	);
67
+
68
+	/**
69
+	 * @var ItemizedOrder
70
+	 * @since $VID:$
71
+	 */
72
+	protected $itemized_order;
73
+
74
+
75
+	/**
76
+	 * EEG_Paypal_Standard constructor.
77
+	 */
78
+	public function __construct()
79
+	{
80
+		$this->set_uses_separate_IPN_request(true);
81
+		parent::__construct();
82
+	}
83
+
84
+
85
+	/**
86
+	 * @return mixed
87
+	 */
88
+	public function gatewayUrl()
89
+	{
90
+		return $this->_gateway_url;
91
+	}
92
+
93
+
94
+	/**
95
+	 * @return mixed
96
+	 */
97
+	public function imageUrl()
98
+	{
99
+		return $this->_image_url;
100
+	}
101
+
102
+
103
+	/**
104
+	 * @return mixed
105
+	 */
106
+	public function paypalId()
107
+	{
108
+		return $this->_paypal_id;
109
+	}
110
+
111
+
112
+	/**
113
+	 * @return mixed
114
+	 */
115
+	public function paypalShipping()
116
+	{
117
+		return $this->_paypal_shipping;
118
+	}
119
+
120
+
121
+
122
+	/**
123
+	 * @return mixed
124
+	 */
125
+	public function paypalTaxes()
126
+	{
127
+		return $this->_paypal_taxes;
128
+	}
129
+
130
+
131
+	/**
132
+	 * @return mixed
133
+	 */
134
+	public function shippingDetails()
135
+	{
136
+		return $this->_shipping_details;
137
+	}
138
+
139
+
140
+	/**
141
+	 * Also sets the gateway url class variable based on whether debug mode is enabled or not.
142
+	 *
143
+	 * @param array $settings_array
144
+	 */
145
+	public function set_settings($settings_array)
146
+	{
147
+		parent::set_settings($settings_array);
148
+		$this->_gateway_url = $this->_debug_mode
149
+			? 'https://www.sandbox.paypal.com/cgi-bin/webscr'
150
+			: 'https://www.paypal.com/cgi-bin/webscr';
151
+	}
152
+
153
+
154
+	/**
155
+	 * @param EEI_Payment $payment      the payment to process
156
+	 * @param array       $billing_info but should be empty for this gateway
157
+	 * @param string      $return_url   URL to send the user to after payment on the payment provider's website
158
+	 * @param string      $notify_url   URL to send the instant payment notification
159
+	 * @param string      $cancel_url   URL to send the user to after a cancelled payment attempt
160
+	 *                                  on the payment provider's website
161
+	 * @return EEI_Payment
162
+	 * @throws EE_Error
163
+	 * @throws ReflectionException
164
+	 */
165
+	public function set_redirection_info(
166
+		$payment,
167
+		$billing_info = array(),
168
+		$return_url = null,
169
+		$notify_url = null,
170
+		$cancel_url = null
171
+	) {
172
+		$this->itemized_order = new ItemizedOrder($this->_get_gateway_formatter(), $this);
173
+		$redirect_args = apply_filters(
174
+			"FHEE__EEG_Paypal_Standard__set_redirection_info__arguments",
175
+			$this->itemized_order->generateItemizedOrderForPayment(
176
+				$payment,
177
+				$return_url,
178
+				$notify_url,
179
+				$cancel_url
180
+			),
181
+			$this
182
+		);
183
+
184
+		$payment->set_redirect_url($this->_gateway_url);
185
+		$payment->set_redirect_args($redirect_args);
186
+		// log the results
187
+		$this->log(
188
+			array(
189
+				'message'     => esc_html__('PayPal payment request initiated.', 'event_espresso'),
190
+				'transaction' => $payment->transaction()->model_field_array(),
191
+			),
192
+			$payment
193
+		);
194
+		return $payment;
195
+	}
196
+
197
+
198
+	/**
199
+	 * Often used for IPNs. But applies the info in $update_info to the payment.
200
+	 * What is $update_info? Often the contents of $_REQUEST, but not necessarily. Whatever
201
+	 * the payment method passes in.
202
+	 *
203
+	 * @param array $update_info like $_POST
204
+	 * @param EEI_Transaction $transaction
205
+	 * @return EEI_Payment updated
206
+	 * @throws EE_Error, IpnException
207
+	 */
208
+	public function handle_payment_update($update_info, $transaction)
209
+	{
210
+		// verify there's payment data that's been sent
211
+		if (empty($update_info['payment_status']) || empty($update_info['txn_id'])) {
212
+			// log the results
213
+			$this->log(
214
+				array(
215
+					'message'     => esc_html__(
216
+						'PayPal IPN response is missing critical payment data. This may indicate a PDT request and require your PayPal account settings to be corrected.',
217
+						'event_espresso'
218
+					),
219
+					'update_info' => $update_info,
220
+				),
221
+				$transaction
222
+			);
223
+			// waaaait... is this a PDT request? (see https://developer.paypal.com/docs/classic/products/payment-data-transfer/)
224
+			// indicated by the "tx" argument? If so, we don't need it. We'll just use the IPN data when it comes
225
+			if (isset($update_info['tx'])) {
226
+				return $transaction->last_payment();
227
+			} else {
228
+				return null;
229
+			}
230
+		}
231
+		$payment = $this->_pay_model->get_payment_by_txn_id_chq_nmbr($update_info['txn_id']);
232
+		if (! $payment instanceof EEI_Payment) {
233
+			$payment = $transaction->last_payment();
234
+		}
235
+		// ok, then validate the IPN. Even if we've already processed this payment,
236
+		// let PayPal know we don't want to hear from them anymore!
237
+		if (! $this->validate_ipn($update_info, $payment)) {
238
+			return $payment;
239
+		}
240
+		// kill request here if this is a refund, we don't support them yet (we'd need to adjust the transaction,
241
+		// registrations, ticket counts, etc)
242
+		if (
243
+			(
244
+				$update_info['payment_status'] === 'Refunded'
245
+				|| $update_info['payment_status'] === 'Partially_Refunded'
246
+			)
247
+			&& apply_filters('FHEE__EEG_Paypal_Standard__handle_payment_update__kill_refund_request', true)
248
+		) {
249
+			throw new EventEspresso\core\exceptions\IpnException(
250
+				sprintf(
251
+					esc_html__('Event Espresso does not yet support %1$s IPNs from PayPal', 'event_espresso'),
252
+					$update_info['payment_status']
253
+				),
254
+				EventEspresso\core\exceptions\IpnException::UNSUPPORTED,
255
+				null,
256
+				$payment,
257
+				$update_info
258
+			);
259
+		}
260
+		// ok, well let's process this payment then!
261
+		switch ($update_info['payment_status']) {
262
+			case 'Completed':
263
+				$status = $this->_pay_model->approved_status();
264
+				$gateway_response = esc_html__('The payment is approved.', 'event_espresso');
265
+				break;
266
+
267
+			case 'Pending':
268
+				$status = $this->_pay_model->pending_status();
269
+				$gateway_response = esc_html__(
270
+					'The payment is in progress. Another message will be sent when payment is approved.',
271
+					'event_espresso'
272
+				);
273
+				break;
274
+
275
+			case 'Denied':
276
+				$status = $this->_pay_model->declined_status();
277
+				$gateway_response = esc_html__('The payment has been declined.', 'event_espresso');
278
+				break;
279
+
280
+			case 'Expired':
281
+			case 'Failed':
282
+				$status = $this->_pay_model->failed_status();
283
+				$gateway_response = esc_html__('The payment failed for technical reasons or expired.', 'event_espresso');
284
+				break;
285
+
286
+			case 'Refunded':
287
+			case 'Partially_Refunded':
288
+				// even though it's a refund, we consider the payment as approved, it just has a negative value
289
+				$status = $this->_pay_model->approved_status();
290
+				$gateway_response = esc_html__(
291
+					'The payment has been refunded. Please update registrations accordingly.',
292
+					'event_espresso'
293
+				);
294
+				break;
295
+
296
+			case 'Voided':
297
+			case 'Reversed':
298
+			case 'Canceled_Reversal':
299
+			default:
300
+				$status = $this->_pay_model->cancelled_status();
301
+				$gateway_response = esc_html__(
302
+					'The payment was cancelled, reversed, or voided. Please update registrations accordingly.',
303
+					'event_espresso'
304
+				);
305
+				break;
306
+		}
307
+
308
+		// check if we've already processed this payment
309
+		if ($payment instanceof EEI_Payment) {
310
+			// payment exists. if this has the exact same status and amount, don't bother updating. just return
311
+			if ($payment->status() === $status && $payment->amount() === (float) $update_info['mc_gross']) {
312
+				// DUPLICATED IPN! don't bother updating transaction
313
+				throw new IpnException(
314
+					sprintf(
315
+						esc_html__(
316
+							'It appears we have received a duplicate IPN from PayPal for payment %d',
317
+							'event_espresso'
318
+						),
319
+						$payment->ID()
320
+					),
321
+					IpnException::DUPLICATE,
322
+					null,
323
+					$payment,
324
+					$update_info
325
+				);
326
+			} else {
327
+				// new payment yippee !!!
328
+				$payment->set_status($status);
329
+				$payment->set_amount((float) $update_info['mc_gross']);
330
+				$payment->set_gateway_response($gateway_response);
331
+				$payment->set_details($update_info);
332
+				$payment->set_txn_id_chq_nmbr($update_info['txn_id']);
333
+				$this->log(
334
+					array(
335
+						'message'  => esc_html__(
336
+							'Updated payment either from IPN or as part of POST from PayPal',
337
+							'event_espresso'
338
+						),
339
+						'url'      => $this->_process_response_url(),
340
+						'payment'  => $payment->model_field_array(),
341
+						'IPN_data' => $update_info
342
+					),
343
+					$payment
344
+				);
345
+			}
346
+		}
347
+		do_action('FHEE__EEG_Paypal_Standard__handle_payment_update__payment_processed', $payment, $this);
348
+		return $payment;
349
+	}
350
+
351
+
352
+	/**
353
+	 * Validate the IPN notification.
354
+	 *
355
+	 * @param array                  $update_info like $_REQUEST
356
+	 * @param EE_Payment|EEI_Payment $payment
357
+	 * @return boolean
358
+	 * @throws EE_Error
359
+	 */
360
+	public function validate_ipn($update_info, $payment)
361
+	{
362
+		// allow us to skip validating IPNs with PayPal (useful for testing)
363
+		if (apply_filters('FHEE__EEG_Paypal_Standard__validate_ipn__skip', false)) {
364
+			return true;
365
+		}
366
+		// ...otherwise, we actually don't care what the $update_info is, we need to look
367
+		// at the request directly because we can't use $update_info because it has issues with quotes
368
+		// Reading POSTed data directly from $_POST causes serialization issues with array data in the POST.
369
+		// Instead, read raw POST data from the input stream.
370
+		// @see https://gist.github.com/xcommerce-gists/3440401
371
+		$raw_post_data = file_get_contents('php://input');
372
+		$raw_post_array = explode('&', $raw_post_data);
373
+		$update_info = array();
374
+		foreach ($raw_post_array as $keyval) {
375
+			$keyval = explode('=', $keyval);
376
+			if (count($keyval) === 2) {
377
+				$update_info[ $keyval[0] ] = urldecode($keyval[1]);
378
+			}
379
+		}
380
+		// read the IPN message sent from PayPal and prepend 'cmd=_notify-validate'
381
+		$req = 'cmd=_notify-validate';
382
+		$uses_get_magic_quotes = function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc() === 1;
383
+		foreach ($update_info as $key => $value) {
384
+			$value = $uses_get_magic_quotes ? urlencode(stripslashes($value)) : urlencode($value);
385
+			$req .= "&$key=$value";
386
+		}
387
+		// HTTP POST the complete, unaltered IPN back to PayPal
388
+		$response = wp_remote_post(
389
+			$this->_gateway_url,
390
+			array(
391
+				'body'              => $req,
392
+				'sslverify'         => false,
393
+				'timeout'           => 60,
394
+				// make sure to set a site specific unique "user-agent" string since the WordPres default gets declined by PayPal
395
+				// plz see: https://github.com/websharks/s2member/issues/610
396
+				'user-agent'        => 'Event Espresso v' . EVENT_ESPRESSO_VERSION . '; ' . home_url(),
397
+				'httpversion'       => '1.1'
398
+			)
399
+		);
400
+		// then check the response
401
+		if (
402
+			array_key_exists('body', $response)
403
+			&& ! is_wp_error($response)
404
+			&& strcmp($response['body'], "VERIFIED") === 0
405
+		) {
406
+			return true;
407
+		}
408
+		// huh, something's wack... the IPN didn't validate. We must have replied to the IPN incorrectly,
409
+		// or their API must have changed: http://www.paypalobjects.com/en_US/ebook/PP_OrderManagement_IntegrationGuide/ipn.html
410
+		if ($response instanceof WP_Error) {
411
+			$error_msg = sprintf(
412
+				esc_html__('WP Error. Code: "%1$s", Message: "%2$s", Data: "%3$s"', 'event_espresso'),
413
+				$response->get_error_code(),
414
+				$response->get_error_message(),
415
+				print_r($response->get_error_data(), true)
416
+			);
417
+		} elseif (is_array($response) && isset($response['body'])) {
418
+			$error_msg = $response['body'];
419
+		} else {
420
+			$error_msg = print_r($response, true);
421
+		}
422
+		$payment->set_gateway_response(
423
+			sprintf(
424
+				esc_html__("IPN Validation failed! Paypal responded with '%s'", "event_espresso"),
425
+				$error_msg
426
+			)
427
+		);
428
+		$payment->set_details(array('REQUEST' => $update_info, 'VALIDATION_RESPONSE' => $response));
429
+		$payment->set_status(EEM_Payment::status_id_failed);
430
+		// log the results
431
+		$this->log(
432
+			array(
433
+				'url'     => $this->_process_response_url(),
434
+				'message' => $payment->gateway_response(),
435
+				'details' => $payment->details(),
436
+			),
437
+			$payment
438
+		);
439
+		return false;
440
+	}
441
+
442
+
443
+	/**
444
+	 * _process_response_url
445
+	 * @return string
446
+	 */
447
+	protected function _process_response_url(): string
448
+	{
449
+		if (isset($_SERVER['HTTP_HOST'], $_SERVER['REQUEST_URI'])) {
450
+			$url = is_ssl() ? 'https://' : 'http://';
451
+			$url .= EEH_URL::filter_input_server_url('HTTP_HOST');
452
+			$url .= EEH_URL::filter_input_server_url();
453
+		} else {
454
+			$url = 'unknown';
455
+		}
456
+		return $url;
457
+	}
458
+
459
+
460
+	/**
461
+	 * Updates the transaction and line items based on the payment IPN data from PayPal,
462
+	 * like the taxes or shipping
463
+	 *
464
+	 * @param EEI_Payment $payment
465
+	 * @throws EE_Error
466
+	 * @throws ReflectionException
467
+	 */
468
+	public function update_txn_based_on_payment($payment)
469
+	{
470
+		$update_info = $payment->details();
471
+		/** @var EE_Transaction $transaction */
472
+		$transaction = $payment->transaction();
473
+		$payment_was_itemized = $payment->get_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, true, false);
474
+		if (! $transaction) {
475
+			$this->log(
476
+				esc_html__(
477
+					// @codingStandardsIgnoreStart
478
+					'Payment with ID %d has no related transaction, and so update_txn_based_on_payment couldn\'t be executed properly',
479
+					// @codingStandardsIgnoreEnd
480
+					'event_espresso'
481
+				),
482
+				$payment
483
+			);
484
+			return;
485
+		}
486
+		if (
487
+			! is_array($update_info)
488
+			|| ! isset($update_info['mc_shipping'])
489
+			|| ! isset($update_info['tax'])
490
+		) {
491
+			$this->log(
492
+				array(
493
+					'message' => esc_html__(
494
+						// @codingStandardsIgnoreStart
495
+						'Could not update transaction based on payment because the payment details have not yet been put on the payment. This normally happens during the IPN or returning from PayPal',
496
+						// @codingStandardsIgnoreEnd
497
+						'event_espresso'
498
+					),
499
+					'url'     => $this->_process_response_url(),
500
+					'payment' => $payment->model_field_array()
501
+				),
502
+				$payment
503
+			);
504
+			return;
505
+		}
506
+		if ($payment->status() !== $this->_pay_model->approved_status()) {
507
+			$this->log(
508
+				array(
509
+					'message' => esc_html__(
510
+						'We shouldn\'t update transactions taxes or shipping data from non-approved payments',
511
+						'event_espresso'
512
+					),
513
+					'url'     => $this->_process_response_url(),
514
+					'payment' => $payment->model_field_array()
515
+				),
516
+				$payment
517
+			);
518
+			return;
519
+		}
520
+		$grand_total_needs_resaving = false;
521
+		/** @var EE_Line_Item $transaction_total_line_item */
522
+		$transaction_total_line_item = $transaction->total_line_item();
523
+
524
+		// might paypal have changed the taxes?
525
+		if ($this->_paypal_taxes && $payment_was_itemized) {
526
+			// note that we're doing this BEFORE adding shipping;
527
+			// we actually want PayPal's shipping to remain non-taxable
528
+			$this->_line_item->set_line_items_taxable($transaction_total_line_item, true, 'paypal_shipping');
529
+			$this->_line_item->set_total_tax_to(
530
+				$transaction_total_line_item,
531
+				(float) $update_info['tax'],
532
+				esc_html__('Taxes', 'event_espresso'),
533
+				esc_html__('Calculated by Paypal', 'event_espresso'),
534
+				'paypal_tax'
535
+			);
536
+			$grand_total_needs_resaving = true;
537
+		}
538
+
539
+		$shipping_amount = (float) $update_info['mc_shipping'];
540
+		// might paypal have added shipping?
541
+		if ($this->_paypal_shipping && $shipping_amount && $payment_was_itemized) {
542
+			$this->_line_item->add_unrelated_item(
543
+				$transaction_total_line_item,
544
+				sprintf(esc_html__('Shipping for transaction %1$s', 'event_espresso'), $transaction->ID()),
545
+				$shipping_amount,
546
+				esc_html__('Shipping charges calculated by Paypal', 'event_espresso'),
547
+				1,
548
+				false,
549
+				'paypal_shipping_' . $transaction->ID()
550
+			);
551
+			$grand_total_needs_resaving = true;
552
+		}
553
+
554
+		if ($grand_total_needs_resaving) {
555
+			$transaction_total_line_item->save_this_and_descendants_to_txn($transaction->ID());
556
+			/** @var EE_Registration_Processor $registration_processor */
557
+			$registration_processor = EE_Registry::instance()->load_class('Registration_Processor');
558
+			$registration_processor->update_registration_final_prices($transaction);
559
+		}
560
+		$this->log(
561
+			array(
562
+				'message'                     => esc_html__('Updated transaction related to payment', 'event_espresso'),
563
+				'url'                         => $this->_process_response_url(),
564
+				'transaction (updated)'       => $transaction->model_field_array(),
565
+				'payment (updated)'           => $payment->model_field_array(),
566
+				'use_paypal_shipping'         => $this->_paypal_shipping,
567
+				'use_paypal_tax'              => $this->_paypal_taxes,
568
+				'grand_total_needed_resaving' => $grand_total_needs_resaving,
569
+			),
570
+			$payment
571
+		);
572
+	}
573 573
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -229,12 +229,12 @@  discard block
 block discarded – undo
229 229
             }
230 230
         }
231 231
         $payment = $this->_pay_model->get_payment_by_txn_id_chq_nmbr($update_info['txn_id']);
232
-        if (! $payment instanceof EEI_Payment) {
232
+        if ( ! $payment instanceof EEI_Payment) {
233 233
             $payment = $transaction->last_payment();
234 234
         }
235 235
         // ok, then validate the IPN. Even if we've already processed this payment,
236 236
         // let PayPal know we don't want to hear from them anymore!
237
-        if (! $this->validate_ipn($update_info, $payment)) {
237
+        if ( ! $this->validate_ipn($update_info, $payment)) {
238 238
             return $payment;
239 239
         }
240 240
         // kill request here if this is a refund, we don't support them yet (we'd need to adjust the transaction,
@@ -374,7 +374,7 @@  discard block
 block discarded – undo
374 374
         foreach ($raw_post_array as $keyval) {
375 375
             $keyval = explode('=', $keyval);
376 376
             if (count($keyval) === 2) {
377
-                $update_info[ $keyval[0] ] = urldecode($keyval[1]);
377
+                $update_info[$keyval[0]] = urldecode($keyval[1]);
378 378
             }
379 379
         }
380 380
         // read the IPN message sent from PayPal and prepend 'cmd=_notify-validate'
@@ -393,7 +393,7 @@  discard block
 block discarded – undo
393 393
                 'timeout'           => 60,
394 394
                 // make sure to set a site specific unique "user-agent" string since the WordPres default gets declined by PayPal
395 395
                 // plz see: https://github.com/websharks/s2member/issues/610
396
-                'user-agent'        => 'Event Espresso v' . EVENT_ESPRESSO_VERSION . '; ' . home_url(),
396
+                'user-agent'        => 'Event Espresso v'.EVENT_ESPRESSO_VERSION.'; '.home_url(),
397 397
                 'httpversion'       => '1.1'
398 398
             )
399 399
         );
@@ -471,7 +471,7 @@  discard block
 block discarded – undo
471 471
         /** @var EE_Transaction $transaction */
472 472
         $transaction = $payment->transaction();
473 473
         $payment_was_itemized = $payment->get_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, true, false);
474
-        if (! $transaction) {
474
+        if ( ! $transaction) {
475 475
             $this->log(
476 476
                 esc_html__(
477 477
                     // @codingStandardsIgnoreStart
@@ -546,7 +546,7 @@  discard block
 block discarded – undo
546 546
                 esc_html__('Shipping charges calculated by Paypal', 'event_espresso'),
547 547
                 1,
548 548
                 false,
549
-                'paypal_shipping_' . $transaction->ID()
549
+                'paypal_shipping_'.$transaction->ID()
550 550
             );
551 551
             $grand_total_needs_resaving = true;
552 552
         }
Please login to merge, or discard this patch.
payment_methods/Paypal_Standard/ItemizedOrder.php 2 patches
Indentation   +251 added lines, -251 removed lines patch added patch discarded remove patch
@@ -14,282 +14,282 @@
 block discarded – undo
14 14
 
15 15
 class ItemizedOrder
16 16
 {
17
-    /**
18
-     * @var float
19
-     */
20
-    private $existing_shipping_charges = 0.00;
17
+	/**
18
+	 * @var float
19
+	 */
20
+	private $existing_shipping_charges = 0.00;
21 21
 
22
-    /**
23
-     * keeps track of exactly how much the itemized order amount equals
24
-     *
25
-     * @var float
26
-     */
27
-    private $itemized_order_sum = 0.00;
22
+	/**
23
+	 * keeps track of exactly how much the itemized order amount equals
24
+	 *
25
+	 * @var float
26
+	 */
27
+	private $itemized_order_sum = 0.00;
28 28
 
29
-    /**
30
-     * @var GatewayDataFormatterInterface
31
-     */
32
-    protected $gateway_data_formatter;
29
+	/**
30
+	 * @var GatewayDataFormatterInterface
31
+	 */
32
+	protected $gateway_data_formatter;
33 33
 
34
-    /**
35
-     * @var array
36
-     */
37
-    private $order_items;
34
+	/**
35
+	 * @var array
36
+	 */
37
+	private $order_items;
38 38
 
39
-    /**
40
-     * the payment being processed
41
-     *
42
-     * @var EE_Payment
43
-     */
44
-    protected $payment;
39
+	/**
40
+	 * the payment being processed
41
+	 *
42
+	 * @var EE_Payment
43
+	 */
44
+	protected $payment;
45 45
 
46
-    /**
47
-     * @var EEG_Paypal_Standard
48
-     */
49
-    protected $paypal_gateway;
46
+	/**
47
+	 * @var EEG_Paypal_Standard
48
+	 */
49
+	protected $paypal_gateway;
50 50
 
51
-    /**
52
-     * @var float
53
-     */
54
-    private $total_discounts = 0.00;
51
+	/**
52
+	 * @var float
53
+	 */
54
+	private $total_discounts = 0.00;
55 55
 
56
-    /**
57
-     * @var EE_Transaction
58
-     */
59
-    private $transaction;
56
+	/**
57
+	 * @var EE_Transaction
58
+	 */
59
+	private $transaction;
60 60
 
61 61
 
62
-    /**
63
-     * @param GatewayDataFormatterInterface $gateway_data_formatter
64
-     * @param EEG_Paypal_Standard           $paypal_gateway
65
-     */
66
-    public function __construct(GatewayDataFormatterInterface $gateway_data_formatter, EEG_Paypal_Standard $paypal_gateway)
67
-    {
68
-        $this->gateway_data_formatter = $gateway_data_formatter;
69
-        $this->paypal_gateway = $paypal_gateway;
70
-    }
62
+	/**
63
+	 * @param GatewayDataFormatterInterface $gateway_data_formatter
64
+	 * @param EEG_Paypal_Standard           $paypal_gateway
65
+	 */
66
+	public function __construct(GatewayDataFormatterInterface $gateway_data_formatter, EEG_Paypal_Standard $paypal_gateway)
67
+	{
68
+		$this->gateway_data_formatter = $gateway_data_formatter;
69
+		$this->paypal_gateway = $paypal_gateway;
70
+	}
71 71
 
72 72
 
73
-    /**
74
-     * @param EE_Payment $payment
75
-     * @param string     $return_url    URL to send the user to after payment on the payment provider's website
76
-     * @param string     $notify_url    URL to send the instant payment notification
77
-     * @param string     $cancel_url    URL to send the user to after a cancelled payment attempt
78
-     *                                  on the payment provider's website
79
-     * @return array
80
-     * @throws EE_Error
81
-     * @throws ReflectionException
82
-     */
83
-    public function generateItemizedOrderForPayment(
84
-        EE_Payment $payment,
85
-        string     $return_url = '',
86
-        string     $notify_url = '',
87
-        string     $cancel_url = ''
88
-    ): array {
89
-        $this->payment         = $payment;
90
-        $this->transaction     = $this->payment->transaction();
91
-        $this->total_discounts = $this->transaction->paid();
92
-        $total_line_item       = $this->transaction->total_line_item();
73
+	/**
74
+	 * @param EE_Payment $payment
75
+	 * @param string     $return_url    URL to send the user to after payment on the payment provider's website
76
+	 * @param string     $notify_url    URL to send the instant payment notification
77
+	 * @param string     $cancel_url    URL to send the user to after a cancelled payment attempt
78
+	 *                                  on the payment provider's website
79
+	 * @return array
80
+	 * @throws EE_Error
81
+	 * @throws ReflectionException
82
+	 */
83
+	public function generateItemizedOrderForPayment(
84
+		EE_Payment $payment,
85
+		string     $return_url = '',
86
+		string     $notify_url = '',
87
+		string     $cancel_url = ''
88
+	): array {
89
+		$this->payment         = $payment;
90
+		$this->transaction     = $this->payment->transaction();
91
+		$this->total_discounts = $this->transaction->paid();
92
+		$total_line_item       = $this->transaction->total_line_item();
93 93
 
94
-        // only itemize the order if we're paying for the rest of the order's amount
95
-        $item_num = 1;
96
-        $item_num = $this->paymentIsForTransactionTotal()
97
-            ? $this->itemizeOrderForFullPayment($total_line_item, $item_num)
98
-            : $this->handlePartialPayment($item_num);
94
+		// only itemize the order if we're paying for the rest of the order's amount
95
+		$item_num = 1;
96
+		$item_num = $this->paymentIsForTransactionTotal()
97
+			? $this->itemizeOrderForFullPayment($total_line_item, $item_num)
98
+			: $this->handlePartialPayment($item_num);
99 99
 
100
-        if ($this->paypal_gateway->isInSandboxMode()) {
101
-            $this->addSandboxModeArgs($item_num, $notify_url, $return_url);
102
-        }
103
-        $this->addGeneralOrderItems($cancel_url, $notify_url, $return_url);
104
-        return $this->order_items;
105
-    }
100
+		if ($this->paypal_gateway->isInSandboxMode()) {
101
+			$this->addSandboxModeArgs($item_num, $notify_url, $return_url);
102
+		}
103
+		$this->addGeneralOrderItems($cancel_url, $notify_url, $return_url);
104
+		return $this->order_items;
105
+	}
106 106
 
107 107
 
108
-    /**
109
-     * @return bool
110
-     * @throws ReflectionException
111
-     * @throws EE_Error
112
-     */
113
-    private function paymentIsForTransactionTotal(): bool
114
-    {
115
-        return EEH_Money::compare_floats($this->payment->amount(), $this->transaction->total(), '==');
116
-    }
108
+	/**
109
+	 * @return bool
110
+	 * @throws ReflectionException
111
+	 * @throws EE_Error
112
+	 */
113
+	private function paymentIsForTransactionTotal(): bool
114
+	{
115
+		return EEH_Money::compare_floats($this->payment->amount(), $this->transaction->total(), '==');
116
+	}
117 117
 
118 118
 
119
-    /**
120
-     * if the payment is for the remaining transaction amount,
121
-     * keep track of exactly how much the itemized order amount equals
122
-     *
123
-     * @param EE_Line_Item $total_line_item
124
-     * @param int          $item_num
125
-     * @return int
126
-     * @throws EE_Error
127
-     * @throws ReflectionException
128
-     */
129
-    private function itemizeOrderForFullPayment(EE_Line_Item $total_line_item, int $item_num): int
130
-    {
131
-        $this->payment->update_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, true);
132
-        // this payment is for the remaining transaction amount, so let's show all the line items
133
-        $item_num = $this->addOrderItemsForLineItems($total_line_item, $item_num);
134
-        // and make adjustments as needed
135
-        $item_num = $this->handleItemizedOrderSumDifference($total_line_item, $item_num);
136
-        // add our taxes to the order if we're NOT using PayPal's
137
-        if (! $this->paypal_gateway->paypalTaxes()) {
138
-            $this->order_items['tax_cart'] = $total_line_item->get_total_tax();
139
-        }
140
-        return $item_num;
141
-    }
119
+	/**
120
+	 * if the payment is for the remaining transaction amount,
121
+	 * keep track of exactly how much the itemized order amount equals
122
+	 *
123
+	 * @param EE_Line_Item $total_line_item
124
+	 * @param int          $item_num
125
+	 * @return int
126
+	 * @throws EE_Error
127
+	 * @throws ReflectionException
128
+	 */
129
+	private function itemizeOrderForFullPayment(EE_Line_Item $total_line_item, int $item_num): int
130
+	{
131
+		$this->payment->update_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, true);
132
+		// this payment is for the remaining transaction amount, so let's show all the line items
133
+		$item_num = $this->addOrderItemsForLineItems($total_line_item, $item_num);
134
+		// and make adjustments as needed
135
+		$item_num = $this->handleItemizedOrderSumDifference($total_line_item, $item_num);
136
+		// add our taxes to the order if we're NOT using PayPal's
137
+		if (! $this->paypal_gateway->paypalTaxes()) {
138
+			$this->order_items['tax_cart'] = $total_line_item->get_total_tax();
139
+		}
140
+		return $item_num;
141
+	}
142 142
 
143 143
 
144
-    /**
145
-     * @param int $item_num
146
-     * @return int
147
-     * @throws EE_Error
148
-     * @throws ReflectionException
149
-     */
150
-    private function handlePartialPayment(int $item_num): int
151
-    {
152
-        $this->payment->update_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, false);
153
-        // partial payment that's not for the remaining amount, so we can't send an itemized list
154
-        $this->order_items["item_name_{$item_num}"] = substr(
155
-            $this->gateway_data_formatter->formatPartialPaymentLineItemName($this->payment),
156
-            0,
157
-            127
158
-        );
159
-        $this->order_items["amount_{$item_num}"]    = $this->payment->amount();
160
-        $this->order_items["shipping_{$item_num}"]  = '0';
161
-        $this->order_items["shipping2_{$item_num}"] = '0';
162
-        $this->order_items['tax_cart']              = '0';
163
-        $item_num++;
164
-        return $item_num;
165
-    }
144
+	/**
145
+	 * @param int $item_num
146
+	 * @return int
147
+	 * @throws EE_Error
148
+	 * @throws ReflectionException
149
+	 */
150
+	private function handlePartialPayment(int $item_num): int
151
+	{
152
+		$this->payment->update_extra_meta(EEG_Paypal_Standard::itemized_payment_option_name, false);
153
+		// partial payment that's not for the remaining amount, so we can't send an itemized list
154
+		$this->order_items["item_name_{$item_num}"] = substr(
155
+			$this->gateway_data_formatter->formatPartialPaymentLineItemName($this->payment),
156
+			0,
157
+			127
158
+		);
159
+		$this->order_items["amount_{$item_num}"]    = $this->payment->amount();
160
+		$this->order_items["shipping_{$item_num}"]  = '0';
161
+		$this->order_items["shipping2_{$item_num}"] = '0';
162
+		$this->order_items['tax_cart']              = '0';
163
+		$item_num++;
164
+		return $item_num;
165
+	}
166 166
 
167 167
 
168
-    /**
169
-     * @param EE_Line_Item $total_line_item
170
-     * @param int          $item_num
171
-     * @return int
172
-     * @throws EE_Error
173
-     * @throws ReflectionException
174
-     */
175
-    private function addOrderItemsForLineItems(EE_Line_Item $total_line_item, int $item_num): int
176
-    {
177
-        foreach ($total_line_item->get_items() as $line_item) {
178
-            if ($line_item instanceof EE_Line_Item) {
179
-                // it's some kind of discount
180
-                if (EEH_Money::compare_floats($line_item->pretaxTotal(), 0.00, '<')) {
181
-                    $this->total_discounts    += abs($line_item->pretaxTotal());
182
-                    $this->itemized_order_sum += $line_item->pretaxTotal();
183
-                    continue;
184
-                }
185
-                // dont include shipping again.
186
-                if (strpos($line_item->code(), 'paypal_shipping_') === 0) {
187
-                    $this->existing_shipping_charges = $line_item->pretaxTotal();
188
-                    continue;
189
-                }
190
-                $this->order_items["item_name_{$item_num}"] = substr(
191
-                    $this->gateway_data_formatter->formatLineItemName($line_item, $this->payment),
192
-                    0,
193
-                    127
194
-                );
195
-                $this->order_items["amount_{$item_num}"]    = $line_item->unit_price();
196
-                $this->order_items["quantity_{$item_num}"]  = $line_item->quantity();
197
-                // if we're not letting PayPal calculate shipping, tell them its 0
198
-                if (! $this->paypal_gateway->paypalShipping()) {
199
-                    $this->order_items["shipping_{$item_num}"]  = '0';
200
-                    $this->order_items["shipping2_{$item_num}"] = '0';
201
-                }
202
-                $this->itemized_order_sum += $line_item->pretaxTotal();
203
-                $item_num++;
204
-            }
205
-        }
206
-        return $item_num;
207
-    }
168
+	/**
169
+	 * @param EE_Line_Item $total_line_item
170
+	 * @param int          $item_num
171
+	 * @return int
172
+	 * @throws EE_Error
173
+	 * @throws ReflectionException
174
+	 */
175
+	private function addOrderItemsForLineItems(EE_Line_Item $total_line_item, int $item_num): int
176
+	{
177
+		foreach ($total_line_item->get_items() as $line_item) {
178
+			if ($line_item instanceof EE_Line_Item) {
179
+				// it's some kind of discount
180
+				if (EEH_Money::compare_floats($line_item->pretaxTotal(), 0.00, '<')) {
181
+					$this->total_discounts    += abs($line_item->pretaxTotal());
182
+					$this->itemized_order_sum += $line_item->pretaxTotal();
183
+					continue;
184
+				}
185
+				// dont include shipping again.
186
+				if (strpos($line_item->code(), 'paypal_shipping_') === 0) {
187
+					$this->existing_shipping_charges = $line_item->pretaxTotal();
188
+					continue;
189
+				}
190
+				$this->order_items["item_name_{$item_num}"] = substr(
191
+					$this->gateway_data_formatter->formatLineItemName($line_item, $this->payment),
192
+					0,
193
+					127
194
+				);
195
+				$this->order_items["amount_{$item_num}"]    = $line_item->unit_price();
196
+				$this->order_items["quantity_{$item_num}"]  = $line_item->quantity();
197
+				// if we're not letting PayPal calculate shipping, tell them its 0
198
+				if (! $this->paypal_gateway->paypalShipping()) {
199
+					$this->order_items["shipping_{$item_num}"]  = '0';
200
+					$this->order_items["shipping2_{$item_num}"] = '0';
201
+				}
202
+				$this->itemized_order_sum += $line_item->pretaxTotal();
203
+				$item_num++;
204
+			}
205
+		}
206
+		return $item_num;
207
+	}
208 208
 
209 209
 
210
-    /**
211
-     * @param EE_Line_Item $total_line_item
212
-     * @param int          $item_num
213
-     * @return int
214
-     * @throws EE_Error
215
-     * @throws ReflectionException
216
-     */
217
-    private function handleItemizedOrderSumDifference(EE_Line_Item $total_line_item, int $item_num): int
218
-    {
219
-        $taxes_li = EEH_Line_Item::get_taxes_subtotal($total_line_item);
220
-        // calculate the difference between the TXN total and the itemized order sum
221
-        $itemized_order_sum_difference = round(
222
-            $this->transaction->total()
223
-            - $this->itemized_order_sum
224
-            - $taxes_li->total()
225
-            - $this->existing_shipping_charges,
226
-            2
227
-        );
228
-        // ideally the itemized order sum equals the transaction total, but if not (which is weird),
229
-        // and the itemized sum is LESS than the transaction total...
230
-        if (EEH_Money::compare_floats($itemized_order_sum_difference, 0.00, '<')) {
231
-            // add the difference to the discounts
232
-            $this->total_discounts += abs($itemized_order_sum_difference);
233
-        } elseif (EEH_Money::compare_floats($itemized_order_sum_difference, 0.00, '>')) {
234
-            // the itemized order sum is MORE than the transaction total
235
-            $this->order_items["item_name_{$item_num}"] = substr(
236
-                esc_html__('additional charges', 'event_espresso'),
237
-                0,
238
-                127
239
-            );
240
-            $this->order_items["amount_{$item_num}"]    = $this->gateway_data_formatter->formatCurrency(
241
-                $itemized_order_sum_difference
242
-            );
243
-            $this->order_items["quantity_{$item_num}"]  = 1;
244
-            $item_num++;
245
-        }
246
-        if (EEH_Money::compare_floats($this->total_discounts, 0.00, '>')) {
247
-            $this->order_items['discount_amount_cart'] = $this->gateway_data_formatter->formatCurrency(
248
-                $this->total_discounts
249
-            );
250
-        }
251
-        return $item_num;
252
-    }
210
+	/**
211
+	 * @param EE_Line_Item $total_line_item
212
+	 * @param int          $item_num
213
+	 * @return int
214
+	 * @throws EE_Error
215
+	 * @throws ReflectionException
216
+	 */
217
+	private function handleItemizedOrderSumDifference(EE_Line_Item $total_line_item, int $item_num): int
218
+	{
219
+		$taxes_li = EEH_Line_Item::get_taxes_subtotal($total_line_item);
220
+		// calculate the difference between the TXN total and the itemized order sum
221
+		$itemized_order_sum_difference = round(
222
+			$this->transaction->total()
223
+			- $this->itemized_order_sum
224
+			- $taxes_li->total()
225
+			- $this->existing_shipping_charges,
226
+			2
227
+		);
228
+		// ideally the itemized order sum equals the transaction total, but if not (which is weird),
229
+		// and the itemized sum is LESS than the transaction total...
230
+		if (EEH_Money::compare_floats($itemized_order_sum_difference, 0.00, '<')) {
231
+			// add the difference to the discounts
232
+			$this->total_discounts += abs($itemized_order_sum_difference);
233
+		} elseif (EEH_Money::compare_floats($itemized_order_sum_difference, 0.00, '>')) {
234
+			// the itemized order sum is MORE than the transaction total
235
+			$this->order_items["item_name_{$item_num}"] = substr(
236
+				esc_html__('additional charges', 'event_espresso'),
237
+				0,
238
+				127
239
+			);
240
+			$this->order_items["amount_{$item_num}"]    = $this->gateway_data_formatter->formatCurrency(
241
+				$itemized_order_sum_difference
242
+			);
243
+			$this->order_items["quantity_{$item_num}"]  = 1;
244
+			$item_num++;
245
+		}
246
+		if (EEH_Money::compare_floats($this->total_discounts, 0.00, '>')) {
247
+			$this->order_items['discount_amount_cart'] = $this->gateway_data_formatter->formatCurrency(
248
+				$this->total_discounts
249
+			);
250
+		}
251
+		return $item_num;
252
+	}
253 253
 
254 254
 
255
-    /**
256
-     * @param int    $item_num
257
-     * @param string $notify_url
258
-     * @param string $return_url
259
-     */
260
-    private function addSandboxModeArgs(int $item_num, string $notify_url, string $return_url)
261
-    {
262
-        $this->order_items["item_name_{$item_num}"] = 'DEBUG INFO (this item only added in sandbox mode';
263
-        $this->order_items["amount_{$item_num}"]    = 0;
264
-        $this->order_items["on0_{$item_num}"]       = 'NOTIFY URL';
265
-        $this->order_items["os0_{$item_num}"]       = $notify_url;
266
-        $this->order_items["on1_{$item_num}"]       = 'RETURN URL';
267
-        $this->order_items["os1_{$item_num}"]       = $return_url;
268
-        $this->order_items["shipping_{$item_num}"]  = '0';
269
-        $this->order_items["shipping2_{$item_num}"] = '0';
270
-        // $this->order_items['option_index_' . $item_num] = 1; // <-- dunno if this is needed ?
271
-    }
255
+	/**
256
+	 * @param int    $item_num
257
+	 * @param string $notify_url
258
+	 * @param string $return_url
259
+	 */
260
+	private function addSandboxModeArgs(int $item_num, string $notify_url, string $return_url)
261
+	{
262
+		$this->order_items["item_name_{$item_num}"] = 'DEBUG INFO (this item only added in sandbox mode';
263
+		$this->order_items["amount_{$item_num}"]    = 0;
264
+		$this->order_items["on0_{$item_num}"]       = 'NOTIFY URL';
265
+		$this->order_items["os0_{$item_num}"]       = $notify_url;
266
+		$this->order_items["on1_{$item_num}"]       = 'RETURN URL';
267
+		$this->order_items["os1_{$item_num}"]       = $return_url;
268
+		$this->order_items["shipping_{$item_num}"]  = '0';
269
+		$this->order_items["shipping2_{$item_num}"] = '0';
270
+		// $this->order_items['option_index_' . $item_num] = 1; // <-- dunno if this is needed ?
271
+	}
272 272
 
273 273
 
274
-    /**
275
-     * @param string $cancel_url
276
-     * @param string $notify_url
277
-     * @param string $return_url
278
-     */
279
-    private function addGeneralOrderItems(string $cancel_url, string $notify_url, string $return_url)
280
-    {
281
-        $this->order_items['business']      = $this->paypal_gateway->paypalId();
282
-        $this->order_items['return']        = $return_url;
283
-        $this->order_items['cancel_return'] = $cancel_url;
284
-        $this->order_items['notify_url']    = $notify_url;
285
-        $this->order_items['cmd']           = '_cart';
286
-        $this->order_items['upload']        = 1;
287
-        $this->order_items['currency_code'] = $this->payment->currency_code();
288
-        $this->order_items['rm']            = 2;// makes the user return with method=POST
289
-        $this->order_items['no_shipping']   = $this->paypal_gateway->shippingDetails();
290
-        $this->order_items['bn']            = 'EventEspresso_SP';// EE will blow up if you change this
291
-        if ($this->paypal_gateway->imageUrl()) {
292
-            $this->order_items['image_url'] = $this->paypal_gateway->imageUrl();
293
-        }
294
-    }
274
+	/**
275
+	 * @param string $cancel_url
276
+	 * @param string $notify_url
277
+	 * @param string $return_url
278
+	 */
279
+	private function addGeneralOrderItems(string $cancel_url, string $notify_url, string $return_url)
280
+	{
281
+		$this->order_items['business']      = $this->paypal_gateway->paypalId();
282
+		$this->order_items['return']        = $return_url;
283
+		$this->order_items['cancel_return'] = $cancel_url;
284
+		$this->order_items['notify_url']    = $notify_url;
285
+		$this->order_items['cmd']           = '_cart';
286
+		$this->order_items['upload']        = 1;
287
+		$this->order_items['currency_code'] = $this->payment->currency_code();
288
+		$this->order_items['rm']            = 2;// makes the user return with method=POST
289
+		$this->order_items['no_shipping']   = $this->paypal_gateway->shippingDetails();
290
+		$this->order_items['bn']            = 'EventEspresso_SP';// EE will blow up if you change this
291
+		if ($this->paypal_gateway->imageUrl()) {
292
+			$this->order_items['image_url'] = $this->paypal_gateway->imageUrl();
293
+		}
294
+	}
295 295
 }
296 296
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -134,7 +134,7 @@  discard block
 block discarded – undo
134 134
         // and make adjustments as needed
135 135
         $item_num = $this->handleItemizedOrderSumDifference($total_line_item, $item_num);
136 136
         // add our taxes to the order if we're NOT using PayPal's
137
-        if (! $this->paypal_gateway->paypalTaxes()) {
137
+        if ( ! $this->paypal_gateway->paypalTaxes()) {
138 138
             $this->order_items['tax_cart'] = $total_line_item->get_total_tax();
139 139
         }
140 140
         return $item_num;
@@ -195,7 +195,7 @@  discard block
 block discarded – undo
195 195
                 $this->order_items["amount_{$item_num}"]    = $line_item->unit_price();
196 196
                 $this->order_items["quantity_{$item_num}"]  = $line_item->quantity();
197 197
                 // if we're not letting PayPal calculate shipping, tell them its 0
198
-                if (! $this->paypal_gateway->paypalShipping()) {
198
+                if ( ! $this->paypal_gateway->paypalShipping()) {
199 199
                     $this->order_items["shipping_{$item_num}"]  = '0';
200 200
                     $this->order_items["shipping2_{$item_num}"] = '0';
201 201
                 }
@@ -285,9 +285,9 @@  discard block
 block discarded – undo
285 285
         $this->order_items['cmd']           = '_cart';
286 286
         $this->order_items['upload']        = 1;
287 287
         $this->order_items['currency_code'] = $this->payment->currency_code();
288
-        $this->order_items['rm']            = 2;// makes the user return with method=POST
288
+        $this->order_items['rm']            = 2; // makes the user return with method=POST
289 289
         $this->order_items['no_shipping']   = $this->paypal_gateway->shippingDetails();
290
-        $this->order_items['bn']            = 'EventEspresso_SP';// EE will blow up if you change this
290
+        $this->order_items['bn']            = 'EventEspresso_SP'; // EE will blow up if you change this
291 291
         if ($this->paypal_gateway->imageUrl()) {
292 292
             $this->order_items['image_url'] = $this->paypal_gateway->imageUrl();
293 293
         }
Please login to merge, or discard this patch.
payment_methods/Paypal_Express/ItemizedOrder.php 2 patches
Indentation   +264 added lines, -264 removed lines patch added patch discarded remove patch
@@ -16,291 +16,291 @@
 block discarded – undo
16 16
 {
17 17
 
18 18
 
19
-    /**
20
-     * number of decimal places to round numbers to when performing calculations
21
-     *
22
-     * @var integer
23
-     */
24
-    protected $decimal_precision = 6;
19
+	/**
20
+	 * number of decimal places to round numbers to when performing calculations
21
+	 *
22
+	 * @var integer
23
+	 */
24
+	protected $decimal_precision = 6;
25 25
 
26
-    /**
27
-     * @var GatewayDataFormatterInterface
28
-     */
29
-    protected $gateway_data_formatter;
26
+	/**
27
+	 * @var GatewayDataFormatterInterface
28
+	 */
29
+	protected $gateway_data_formatter;
30 30
 
31
-    /**
32
-     * keeps track of exactly how much the itemized order amount equals
33
-     *
34
-     * @var float
35
-     */
36
-    private $itemized_order_sum = 0.00;
31
+	/**
32
+	 * keeps track of exactly how much the itemized order amount equals
33
+	 *
34
+	 * @var float
35
+	 */
36
+	private $itemized_order_sum = 0.00;
37 37
 
38
-    /**
39
-     * @var array
40
-     */
41
-    private $order_items;
38
+	/**
39
+	 * @var array
40
+	 */
41
+	private $order_items;
42 42
 
43
-    /**
44
-     * the payment being processed
45
-     *
46
-     * @var EE_Payment
47
-     */
48
-    protected $payment;
43
+	/**
44
+	 * the payment being processed
45
+	 *
46
+	 * @var EE_Payment
47
+	 */
48
+	protected $payment;
49 49
 
50
-    /**
51
-     * @var EE_Transaction
52
-     */
53
-    private $transaction;
50
+	/**
51
+	 * @var EE_Transaction
52
+	 */
53
+	private $transaction;
54 54
 
55 55
 
56
-    /**
57
-     * @param GatewayDataFormatterInterface $gateway_data_formatter
58
-     */
59
-    public function __construct(GatewayDataFormatterInterface $gateway_data_formatter)
60
-    {
61
-        $this->decimal_precision      = EE_Registry::instance()->CFG->currency->dec_plc;
62
-        $this->gateway_data_formatter = $gateway_data_formatter;
63
-        $this->order_items            = [];
64
-    }
56
+	/**
57
+	 * @param GatewayDataFormatterInterface $gateway_data_formatter
58
+	 */
59
+	public function __construct(GatewayDataFormatterInterface $gateway_data_formatter)
60
+	{
61
+		$this->decimal_precision      = EE_Registry::instance()->CFG->currency->dec_plc;
62
+		$this->gateway_data_formatter = $gateway_data_formatter;
63
+		$this->order_items            = [];
64
+	}
65 65
 
66 66
 
67
-    /**
68
-     * @param array $request_response_args
69
-     * @return array
70
-     */
71
-    public function getExistingItemizedOrder(array $request_response_args): array
72
-    {
73
-        // If we have data from a previous communication with PP (on this transaction) we may use that for our list...
74
-        if (
75
-            ! empty($request_response_args)
76
-            && array_key_exists('L_PAYMENTREQUEST_0_AMT0', $request_response_args)
77
-            && array_key_exists('PAYMENTREQUEST_0_ITEMAMT', $request_response_args)
78
-        ) {
79
-            foreach ($request_response_args as $arg_key => $arg_val) {
80
-                if (
81
-                    strpos($arg_key, 'PAYMENTREQUEST_') !== false
82
-                    && strpos($arg_key, 'NOTIFYURL') === false
83
-                ) {
84
-                    $this->order_items[ $arg_key ] = $arg_val;
85
-                }
86
-            }
87
-            // If we only get a few Items then something is not right.
88
-            if (count($this->order_items) < 3) {
89
-                throw new RuntimeException(
90
-                    sprintf(
91
-                        esc_html__(
92
-                            'Unable to continue with the checkout because a proper purchase list could not be generated. The purchased list we could have sent was %1$s',
93
-                            'event_espresso'
94
-                        ),
95
-                        wp_json_encode($this->order_items)
96
-                    )
97
-                );
98
-            }
99
-        }
100
-        return $this->order_items;
101
-    }
67
+	/**
68
+	 * @param array $request_response_args
69
+	 * @return array
70
+	 */
71
+	public function getExistingItemizedOrder(array $request_response_args): array
72
+	{
73
+		// If we have data from a previous communication with PP (on this transaction) we may use that for our list...
74
+		if (
75
+			! empty($request_response_args)
76
+			&& array_key_exists('L_PAYMENTREQUEST_0_AMT0', $request_response_args)
77
+			&& array_key_exists('PAYMENTREQUEST_0_ITEMAMT', $request_response_args)
78
+		) {
79
+			foreach ($request_response_args as $arg_key => $arg_val) {
80
+				if (
81
+					strpos($arg_key, 'PAYMENTREQUEST_') !== false
82
+					&& strpos($arg_key, 'NOTIFYURL') === false
83
+				) {
84
+					$this->order_items[ $arg_key ] = $arg_val;
85
+				}
86
+			}
87
+			// If we only get a few Items then something is not right.
88
+			if (count($this->order_items) < 3) {
89
+				throw new RuntimeException(
90
+					sprintf(
91
+						esc_html__(
92
+							'Unable to continue with the checkout because a proper purchase list could not be generated. The purchased list we could have sent was %1$s',
93
+							'event_espresso'
94
+						),
95
+						wp_json_encode($this->order_items)
96
+					)
97
+				);
98
+			}
99
+		}
100
+		return $this->order_items;
101
+	}
102 102
 
103 103
 
104
-    /**
105
-     *  Make a list of items that are in the giver transaction.
106
-     *
107
-     * @param EE_Payment $payment
108
-     * @return array
109
-     * @throws EE_Error
110
-     * @throws ReflectionException
111
-     */
112
-    public function generateItemizedOrder(EE_Payment $payment): array
113
-    {
114
-        $this->payment     = $payment;
115
-        $this->transaction = $this->payment->transaction();
116
-        // reset order items
117
-        $this->order_items = [];
118
-        if ($this->paymentIsForTransactionTotal()) {
119
-            $this->itemizeOrderForFullPayment();
120
-        } else {
121
-            $this->handlePartialPayment();
122
-        }
123
-        return $this->order_items;
124
-    }
104
+	/**
105
+	 *  Make a list of items that are in the giver transaction.
106
+	 *
107
+	 * @param EE_Payment $payment
108
+	 * @return array
109
+	 * @throws EE_Error
110
+	 * @throws ReflectionException
111
+	 */
112
+	public function generateItemizedOrder(EE_Payment $payment): array
113
+	{
114
+		$this->payment     = $payment;
115
+		$this->transaction = $this->payment->transaction();
116
+		// reset order items
117
+		$this->order_items = [];
118
+		if ($this->paymentIsForTransactionTotal()) {
119
+			$this->itemizeOrderForFullPayment();
120
+		} else {
121
+			$this->handlePartialPayment();
122
+		}
123
+		return $this->order_items;
124
+	}
125 125
 
126 126
 
127
-    /**
128
-     * @return bool
129
-     * @throws ReflectionException
130
-     * @throws EE_Error
131
-     */
132
-    private function paymentIsForTransactionTotal(): bool
133
-    {
134
-        return EEH_Money::compare_floats($this->payment->amount(), $this->transaction->total(), '==');
135
-    }
127
+	/**
128
+	 * @return bool
129
+	 * @throws ReflectionException
130
+	 * @throws EE_Error
131
+	 */
132
+	private function paymentIsForTransactionTotal(): bool
133
+	{
134
+		return EEH_Money::compare_floats($this->payment->amount(), $this->transaction->total(), '==');
135
+	}
136 136
 
137 137
 
138
-    /**
139
-     * @return void
140
-     * @throws EE_Error
141
-     * @throws ReflectionException
142
-     */
143
-    private function itemizeOrderForFullPayment()
144
-    {
145
-        $item_num        = 0;
146
-        $total_line_item = $this->transaction->total_line_item();
147
-        $item_num        = $this->addOrderItemsForLineItems($total_line_item, $item_num);
148
-        $this->addOrderItemsForAdditionalCharges($total_line_item);
149
-        $this->handleItemizedOrderSumDifference($total_line_item, $item_num);
150
-    }
138
+	/**
139
+	 * @return void
140
+	 * @throws EE_Error
141
+	 * @throws ReflectionException
142
+	 */
143
+	private function itemizeOrderForFullPayment()
144
+	{
145
+		$item_num        = 0;
146
+		$total_line_item = $this->transaction->total_line_item();
147
+		$item_num        = $this->addOrderItemsForLineItems($total_line_item, $item_num);
148
+		$this->addOrderItemsForAdditionalCharges($total_line_item);
149
+		$this->handleItemizedOrderSumDifference($total_line_item, $item_num);
150
+	}
151 151
 
152 152
 
153
-    /**
154
-     * @return void
155
-     * @throws EE_Error
156
-     */
157
-    private function handlePartialPayment()
158
-    {
159
-        // Item Name.
160
-        $this->order_items['L_PAYMENTREQUEST_0_NAME0'] = mb_strcut(
161
-            $this->gateway_data_formatter->formatPartialPaymentLineItemName($this->payment),
162
-            0,
163
-            127
164
-        );
165
-        // Item description.
166
-        $this->order_items['L_PAYMENTREQUEST_0_DESC0'] = mb_strcut(
167
-            $this->gateway_data_formatter->formatPartialPaymentLineItemDesc($this->payment),
168
-            0,
169
-            127
170
-        );
171
-        // Cost of individual item.
172
-        $this->order_items['L_PAYMENTREQUEST_0_AMT0'] = $this->gateway_data_formatter->formatCurrency(
173
-            $this->payment->amount(),
174
-            $this->decimal_precision
175
-        );
176
-        // Item Number.
177
-        $this->order_items['L_PAYMENTREQUEST_0_NUMBER0'] = 1;
178
-        // Item quantity.
179
-        $this->order_items['L_PAYMENTREQUEST_0_QTY0'] = 1;
180
-        // Digital item is sold.
181
-        $this->order_items['L_PAYMENTREQUEST_0_ITEMCATEGORY0'] = 'Physical';
182
-        // Item's sales S/H and tax amount.
183
-        $this->order_items['PAYMENTREQUEST_0_ITEMAMT']     = $this->gateway_data_formatter->formatCurrency(
184
-            $this->payment->amount(),
185
-            $this->decimal_precision
186
-        );
187
-        $this->order_items['PAYMENTREQUEST_0_TAXAMT']      = '0';
188
-        $this->order_items['PAYMENTREQUEST_0_SHIPPINGAMT'] = '0';
189
-        $this->order_items['PAYMENTREQUEST_0_HANDLINGAMT'] = '0';
190
-    }
153
+	/**
154
+	 * @return void
155
+	 * @throws EE_Error
156
+	 */
157
+	private function handlePartialPayment()
158
+	{
159
+		// Item Name.
160
+		$this->order_items['L_PAYMENTREQUEST_0_NAME0'] = mb_strcut(
161
+			$this->gateway_data_formatter->formatPartialPaymentLineItemName($this->payment),
162
+			0,
163
+			127
164
+		);
165
+		// Item description.
166
+		$this->order_items['L_PAYMENTREQUEST_0_DESC0'] = mb_strcut(
167
+			$this->gateway_data_formatter->formatPartialPaymentLineItemDesc($this->payment),
168
+			0,
169
+			127
170
+		);
171
+		// Cost of individual item.
172
+		$this->order_items['L_PAYMENTREQUEST_0_AMT0'] = $this->gateway_data_formatter->formatCurrency(
173
+			$this->payment->amount(),
174
+			$this->decimal_precision
175
+		);
176
+		// Item Number.
177
+		$this->order_items['L_PAYMENTREQUEST_0_NUMBER0'] = 1;
178
+		// Item quantity.
179
+		$this->order_items['L_PAYMENTREQUEST_0_QTY0'] = 1;
180
+		// Digital item is sold.
181
+		$this->order_items['L_PAYMENTREQUEST_0_ITEMCATEGORY0'] = 'Physical';
182
+		// Item's sales S/H and tax amount.
183
+		$this->order_items['PAYMENTREQUEST_0_ITEMAMT']     = $this->gateway_data_formatter->formatCurrency(
184
+			$this->payment->amount(),
185
+			$this->decimal_precision
186
+		);
187
+		$this->order_items['PAYMENTREQUEST_0_TAXAMT']      = '0';
188
+		$this->order_items['PAYMENTREQUEST_0_SHIPPINGAMT'] = '0';
189
+		$this->order_items['PAYMENTREQUEST_0_HANDLINGAMT'] = '0';
190
+	}
191 191
 
192 192
 
193
-    /**
194
-     * @param EE_Line_Item $total_line_item
195
-     * @param int          $item_num
196
-     * @return int
197
-     * @throws EE_Error
198
-     * @throws ReflectionException
199
-     */
200
-    private function addOrderItemsForLineItems(EE_Line_Item $total_line_item, int $item_num): int
201
-    {
202
-        // Go through each item in the list.
203
-        foreach ($total_line_item->get_items() as $line_item) {
204
-            if ($line_item instanceof EE_Line_Item) {
205
-                // PayPal doesn't like line items with 0.00 amount, so we may skip those.
206
-                if (EEH_Money::compare_floats($line_item->pretaxTotal(), '0.00', '==')) {
207
-                    continue;
208
-                }
209
-                $unit_price         = $this->gateway_data_formatter->formatCurrency(
210
-                    $line_item->unit_price(),
211
-                    $this->decimal_precision
212
-                );
213
-                $line_item_quantity = $line_item->quantity();
214
-                // This is a discount.
215
-                if ($line_item->is_percent()) {
216
-                    $unit_price         = $line_item->pretaxTotal();
217
-                    $line_item_quantity = 1;
218
-                }
219
-                // Item Name.
220
-                $this->order_items["L_PAYMENTREQUEST_0_NAME{$item_num}"] = mb_strcut(
221
-                    $this->gateway_data_formatter->formatLineItemName($line_item, $this->payment),
222
-                    0,
223
-                    127
224
-                );
225
-                // Item description.
226
-                $this->order_items["L_PAYMENTREQUEST_0_DESC{$item_num}"] = mb_strcut(
227
-                    $this->gateway_data_formatter->formatLineItemDesc($line_item, $this->payment),
228
-                    0,
229
-                    127
230
-                );
231
-                // Cost of individual item.
232
-                $this->order_items["L_PAYMENTREQUEST_0_AMT{$item_num}"] = $unit_price;
233
-                // Item Number.
234
-                $this->order_items["L_PAYMENTREQUEST_0_NUMBER{$item_num}"] = $item_num + 1;
235
-                // Item quantity.
236
-                $this->order_items["L_PAYMENTREQUEST_0_QTY{$item_num}"] = $line_item_quantity;
237
-                // Digital item is sold.
238
-                $this->order_items["L_PAYMENTREQUEST_0_ITEMCATEGORY{$item_num}"] = 'Physical';
239
-                $this->itemized_order_sum                                        += $unit_price * $line_item_quantity;
240
-                ++$item_num;
241
-            }
242
-        }
243
-        return $item_num;
244
-    }
193
+	/**
194
+	 * @param EE_Line_Item $total_line_item
195
+	 * @param int          $item_num
196
+	 * @return int
197
+	 * @throws EE_Error
198
+	 * @throws ReflectionException
199
+	 */
200
+	private function addOrderItemsForLineItems(EE_Line_Item $total_line_item, int $item_num): int
201
+	{
202
+		// Go through each item in the list.
203
+		foreach ($total_line_item->get_items() as $line_item) {
204
+			if ($line_item instanceof EE_Line_Item) {
205
+				// PayPal doesn't like line items with 0.00 amount, so we may skip those.
206
+				if (EEH_Money::compare_floats($line_item->pretaxTotal(), '0.00', '==')) {
207
+					continue;
208
+				}
209
+				$unit_price         = $this->gateway_data_formatter->formatCurrency(
210
+					$line_item->unit_price(),
211
+					$this->decimal_precision
212
+				);
213
+				$line_item_quantity = $line_item->quantity();
214
+				// This is a discount.
215
+				if ($line_item->is_percent()) {
216
+					$unit_price         = $line_item->pretaxTotal();
217
+					$line_item_quantity = 1;
218
+				}
219
+				// Item Name.
220
+				$this->order_items["L_PAYMENTREQUEST_0_NAME{$item_num}"] = mb_strcut(
221
+					$this->gateway_data_formatter->formatLineItemName($line_item, $this->payment),
222
+					0,
223
+					127
224
+				);
225
+				// Item description.
226
+				$this->order_items["L_PAYMENTREQUEST_0_DESC{$item_num}"] = mb_strcut(
227
+					$this->gateway_data_formatter->formatLineItemDesc($line_item, $this->payment),
228
+					0,
229
+					127
230
+				);
231
+				// Cost of individual item.
232
+				$this->order_items["L_PAYMENTREQUEST_0_AMT{$item_num}"] = $unit_price;
233
+				// Item Number.
234
+				$this->order_items["L_PAYMENTREQUEST_0_NUMBER{$item_num}"] = $item_num + 1;
235
+				// Item quantity.
236
+				$this->order_items["L_PAYMENTREQUEST_0_QTY{$item_num}"] = $line_item_quantity;
237
+				// Digital item is sold.
238
+				$this->order_items["L_PAYMENTREQUEST_0_ITEMCATEGORY{$item_num}"] = 'Physical';
239
+				$this->itemized_order_sum                                        += $unit_price * $line_item_quantity;
240
+				++$item_num;
241
+			}
242
+		}
243
+		return $item_num;
244
+	}
245 245
 
246 246
 
247
-    /**
248
-     * @param EE_Line_Item $total_line_item
249
-     * @return void
250
-     * @throws EE_Error
251
-     * @throws ReflectionException
252
-     */
253
-    private function addOrderItemsForAdditionalCharges(EE_Line_Item $total_line_item)
254
-    {
255
-        // Item's sales S/H and tax amount.
256
-        $this->order_items['PAYMENTREQUEST_0_ITEMAMT']     = $total_line_item->get_items_total();
257
-        $this->order_items['PAYMENTREQUEST_0_TAXAMT']      = $total_line_item->get_total_tax();
258
-        $this->order_items['PAYMENTREQUEST_0_SHIPPINGAMT'] = '0';
259
-        $this->order_items['PAYMENTREQUEST_0_HANDLINGAMT'] = '0';
260
-    }
247
+	/**
248
+	 * @param EE_Line_Item $total_line_item
249
+	 * @return void
250
+	 * @throws EE_Error
251
+	 * @throws ReflectionException
252
+	 */
253
+	private function addOrderItemsForAdditionalCharges(EE_Line_Item $total_line_item)
254
+	{
255
+		// Item's sales S/H and tax amount.
256
+		$this->order_items['PAYMENTREQUEST_0_ITEMAMT']     = $total_line_item->get_items_total();
257
+		$this->order_items['PAYMENTREQUEST_0_TAXAMT']      = $total_line_item->get_total_tax();
258
+		$this->order_items['PAYMENTREQUEST_0_SHIPPINGAMT'] = '0';
259
+		$this->order_items['PAYMENTREQUEST_0_HANDLINGAMT'] = '0';
260
+	}
261 261
 
262 262
 
263
-    /**
264
-     * @param EE_Line_Item $total_line_item
265
-     * @param int          $item_num
266
-     * @return void
267
-     * @throws EE_Error
268
-     * @throws ReflectionException
269
-     */
270
-    private function handleItemizedOrderSumDifference(EE_Line_Item $total_line_item, int $item_num)
271
-    {
272
-        // calculate the difference between the TXN total and the itemized order sum
273
-        $itemized_order_sum_difference = round(
274
-            $this->transaction->total()
275
-            - $this->itemized_order_sum
276
-            - $total_line_item->get_total_tax(),
277
-            $this->decimal_precision
278
-        );
279
-        // If we were not able to recognize some item like promotion, surcharge or cancellation,
280
-        // add the difference as an extra line item.
281
-        if (EEH_Money::compare_floats($itemized_order_sum_difference, 0, '!=')) {
282
-            // Item Name.
283
-            $this->order_items["L_PAYMENTREQUEST_0_NAME{$item_num}"] = mb_strcut(
284
-                esc_html__(
285
-                    'Other (promotion/surcharge/cancellation)',
286
-                    'event_espresso'
287
-                ),
288
-                0,
289
-                127
290
-            );
291
-            // Item description.
292
-            $this->order_items["L_PAYMENTREQUEST_0_DESC{$item_num}"] = '';
293
-            // Cost of individual item.
294
-            $this->order_items["L_PAYMENTREQUEST_0_AMT{$item_num}"] = $this->gateway_data_formatter->formatCurrency(
295
-                $itemized_order_sum_difference,
296
-                $this->decimal_precision
297
-            );
298
-            // Item Number.
299
-            $this->order_items["L_PAYMENTREQUEST_0_NUMBER{$item_num}"] = $item_num + 1;
300
-            // Item quantity.
301
-            $this->order_items["L_PAYMENTREQUEST_0_QTY{$item_num}"] = 1;
302
-            // Digital item is sold.
303
-            $this->order_items["L_PAYMENTREQUEST_0_ITEMCATEGORY{$item_num}"] = 'Physical';
304
-        }
305
-    }
263
+	/**
264
+	 * @param EE_Line_Item $total_line_item
265
+	 * @param int          $item_num
266
+	 * @return void
267
+	 * @throws EE_Error
268
+	 * @throws ReflectionException
269
+	 */
270
+	private function handleItemizedOrderSumDifference(EE_Line_Item $total_line_item, int $item_num)
271
+	{
272
+		// calculate the difference between the TXN total and the itemized order sum
273
+		$itemized_order_sum_difference = round(
274
+			$this->transaction->total()
275
+			- $this->itemized_order_sum
276
+			- $total_line_item->get_total_tax(),
277
+			$this->decimal_precision
278
+		);
279
+		// If we were not able to recognize some item like promotion, surcharge or cancellation,
280
+		// add the difference as an extra line item.
281
+		if (EEH_Money::compare_floats($itemized_order_sum_difference, 0, '!=')) {
282
+			// Item Name.
283
+			$this->order_items["L_PAYMENTREQUEST_0_NAME{$item_num}"] = mb_strcut(
284
+				esc_html__(
285
+					'Other (promotion/surcharge/cancellation)',
286
+					'event_espresso'
287
+				),
288
+				0,
289
+				127
290
+			);
291
+			// Item description.
292
+			$this->order_items["L_PAYMENTREQUEST_0_DESC{$item_num}"] = '';
293
+			// Cost of individual item.
294
+			$this->order_items["L_PAYMENTREQUEST_0_AMT{$item_num}"] = $this->gateway_data_formatter->formatCurrency(
295
+				$itemized_order_sum_difference,
296
+				$this->decimal_precision
297
+			);
298
+			// Item Number.
299
+			$this->order_items["L_PAYMENTREQUEST_0_NUMBER{$item_num}"] = $item_num + 1;
300
+			// Item quantity.
301
+			$this->order_items["L_PAYMENTREQUEST_0_QTY{$item_num}"] = 1;
302
+			// Digital item is sold.
303
+			$this->order_items["L_PAYMENTREQUEST_0_ITEMCATEGORY{$item_num}"] = 'Physical';
304
+		}
305
+	}
306 306
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -81,7 +81,7 @@  discard block
 block discarded – undo
81 81
                     strpos($arg_key, 'PAYMENTREQUEST_') !== false
82 82
                     && strpos($arg_key, 'NOTIFYURL') === false
83 83
                 ) {
84
-                    $this->order_items[ $arg_key ] = $arg_val;
84
+                    $this->order_items[$arg_key] = $arg_val;
85 85
                 }
86 86
             }
87 87
             // If we only get a few Items then something is not right.
@@ -180,7 +180,7 @@  discard block
 block discarded – undo
180 180
         // Digital item is sold.
181 181
         $this->order_items['L_PAYMENTREQUEST_0_ITEMCATEGORY0'] = 'Physical';
182 182
         // Item's sales S/H and tax amount.
183
-        $this->order_items['PAYMENTREQUEST_0_ITEMAMT']     = $this->gateway_data_formatter->formatCurrency(
183
+        $this->order_items['PAYMENTREQUEST_0_ITEMAMT'] = $this->gateway_data_formatter->formatCurrency(
184 184
             $this->payment->amount(),
185 185
             $this->decimal_precision
186 186
         );
@@ -206,7 +206,7 @@  discard block
 block discarded – undo
206 206
                 if (EEH_Money::compare_floats($line_item->pretaxTotal(), '0.00', '==')) {
207 207
                     continue;
208 208
                 }
209
-                $unit_price         = $this->gateway_data_formatter->formatCurrency(
209
+                $unit_price = $this->gateway_data_formatter->formatCurrency(
210 210
                     $line_item->unit_price(),
211 211
                     $this->decimal_precision
212 212
                 );
@@ -236,7 +236,7 @@  discard block
 block discarded – undo
236 236
                 $this->order_items["L_PAYMENTREQUEST_0_QTY{$item_num}"] = $line_item_quantity;
237 237
                 // Digital item is sold.
238 238
                 $this->order_items["L_PAYMENTREQUEST_0_ITEMCATEGORY{$item_num}"] = 'Physical';
239
-                $this->itemized_order_sum                                        += $unit_price * $line_item_quantity;
239
+                $this->itemized_order_sum += $unit_price * $line_item_quantity;
240 240
                 ++$item_num;
241 241
             }
242 242
         }
Please login to merge, or discard this patch.
payment_methods/Paypal_Express/EEG_Paypal_Express.gateway.php 2 patches
Indentation   +544 added lines, -544 removed lines patch added patch discarded remove patch
@@ -14,548 +14,548 @@
 block discarded – undo
14 14
 class EEG_Paypal_Express extends EE_Offsite_Gateway
15 15
 {
16 16
 
17
-    /**
18
-     * Merchant API Username.
19
-     *
20
-     * @var string
21
-     */
22
-    protected $_api_username;
23
-
24
-    /**
25
-     * Merchant API Password.
26
-     *
27
-     * @var string
28
-     */
29
-    protected $_api_password;
30
-
31
-    /**
32
-     * API Signature.
33
-     *
34
-     * @var string
35
-     */
36
-    protected $_api_signature;
37
-
38
-    /**
39
-     * Request Shipping address on PP checkout page.
40
-     *
41
-     * @var string
42
-     */
43
-    protected $_request_shipping_addr;
44
-
45
-    /**
46
-     * Business/personal logo.
47
-     *
48
-     * @var string
49
-     */
50
-    protected $_image_url = '';
51
-
52
-    /**
53
-     * gateway URL variable
54
-     *
55
-     * @var string
56
-     */
57
-    protected $_base_gateway_url = '';
58
-
59
-
60
-    /**
61
-     * number of decimal places to round numbers to when performing calculations
62
-     *
63
-     * @var integer
64
-     */
65
-    protected $decimal_precision = 6;
66
-
67
-    /**
68
-     * @var ItemizedOrder
69
-     * @since $VID:$
70
-     */
71
-    protected $itemized_order;
72
-
73
-    /**
74
-     * @var TokenRequest
75
-     * @since $VID:$
76
-     */
77
-    protected $token_request;
78
-
79
-
80
-    /**
81
-     * EEG_Paypal_Express constructor.
82
-     */
83
-    public function __construct()
84
-    {
85
-        require_once 'polyfills.php';
86
-        $this->_currencies_supported = [
87
-            'USD',
88
-            'AUD',
89
-            'BRL',
90
-            'CAD',
91
-            'CZK',
92
-            'DKK',
93
-            'EUR',
94
-            'HKD',
95
-            'HUF',
96
-            'ILS',
97
-            'JPY',
98
-            'MYR',
99
-            'MXN',
100
-            'NOK',
101
-            'NZD',
102
-            'PHP',
103
-            'PLN',
104
-            'GBP',
105
-            'RUB',
106
-            'SGD',
107
-            'SEK',
108
-            'CHF',
109
-            'TWD',
110
-            'THB',
111
-            'TRY',
112
-            'INR',
113
-        ];
114
-        parent::__construct();
115
-        $this->decimal_precision = EE_Registry::instance()->CFG->currency->dec_plc;
116
-    }
117
-
118
-
119
-    /**
120
-     * Sets the gateway URL variable based on whether debug mode is enabled or not.
121
-     *
122
-     * @param array $settings_array
123
-     */
124
-    public function set_settings($settings_array)
125
-    {
126
-        parent::set_settings($settings_array);
127
-        // Redirect URL.
128
-        $this->_base_gateway_url = $this->_debug_mode
129
-            ? 'https://api-3t.sandbox.paypal.com/nvp'
130
-            : 'https://api-3t.paypal.com/nvp';
131
-    }
132
-
133
-
134
-    /**
135
-     * @param EEI_Payment $payment
136
-     * @param array       $billing_info
137
-     * @param string      $return_url
138
-     * @param string      $notify_url
139
-     * @param string      $cancel_url
140
-     * @return EE_Payment|EEI_Payment
141
-     * @throws EE_Error
142
-     * @throws ReflectionException
143
-     * @throws Exception
144
-     */
145
-    public function set_redirection_info(
146
-        $payment,
147
-        $billing_info = [],
148
-        $return_url = null,
149
-        $notify_url = null,
150
-        $cancel_url = null
151
-    ) {
152
-        if (! $this->validatePayment($payment)) {
153
-            return $payment;
154
-        }
155
-        if (! $this->validateTransaction($payment)) {
156
-            return $payment;
157
-        }
158
-        $this->token_request = new TokenRequest($this->_get_gateway_formatter());
159
-        $token_request_details = apply_filters(
160
-            'FHEE__EEG_Paypal_Express__set_redirection_info__arguments',
161
-            $this->token_request->generateDetails(
162
-                $payment,
163
-                $this->getOrderItems($payment),
164
-                $return_url ?? '',
165
-                $cancel_url ?? '',
166
-                $this->_image_url ?? '',
167
-                $this->_request_shipping_addr ?? ''
168
-            ),
169
-            $this
170
-        );
171
-        // Request PayPal token.
172
-        $token_request_response = $this->_ppExpress_request($token_request_details, 'Payment Token', $payment);
173
-        $token_request_status   = $this->_ppExpress_check_response($token_request_response);
174
-        $this->token_request->processResponse($payment, $token_request_status, $this->isInSandboxMode());
175
-
176
-        return $payment;
177
-    }
178
-
179
-
180
-    /**
181
-     * @param array           $update_info {
182
-     * @type string           $gateway_txn_id
183
-     * @type string           $status      an EEMI_Payment status
184
-     *                                     }
185
-     * @param EEI_Transaction $transaction
186
-     * @return EEI_Payment
187
-     * @throws Exception
188
-     */
189
-    public function handle_payment_update($update_info, $transaction): EEI_Payment
190
-    {
191
-        // if the supplied transaction is valid, we'll retrieve the actual payment object from it
192
-        // but we'll use a temporary payment for now that we can return with errors if things go wrong
193
-        $payment = EE_Payment::new_instance();
194
-        if (! $this->validateTransaction($payment, $transaction)) {
195
-            return $payment;
196
-        }
197
-        $payment = $transaction->last_payment();
198
-        if (! $this->validatePayment($payment)) {
199
-            return $payment;
200
-        }
201
-        // payment appears to be good... so far
202
-        $this->log(['Return from Authorization' => $update_info], $payment);
203
-        $payment_token = $this->getPaymentToken($payment);
204
-        $customer_details = $this->requestCustomerDetails($payment, $payment_token);
205
-        // We got the PayerID so now we can Complete the transaction.
206
-        $this->processPayment($payment, $payment_token, $customer_details);
207
-
208
-        return $payment;
209
-    }
210
-
211
-
212
-    /**
213
-     * @throws Exception
214
-     */
215
-    private function getOrderItems(EE_Payment $payment, array $request_response_args = []): array
216
-    {
217
-        $this->itemized_order = new ItemizedOrder($this->_get_gateway_formatter());
218
-        try {
219
-            $itemized_order = $this->itemized_order->getExistingItemizedOrder($request_response_args);
220
-        } catch (Exception $exception) {
221
-            if (WP_DEBUG) {
222
-                throw $exception;
223
-            }
224
-            // Reset the list and log an error, maybe allow to try and generate a new list (below).
225
-            $itemized_order = [];
226
-            $this->log(
227
-                [
228
-                    esc_html__(
229
-                        'Could not generate a proper item list with:',
230
-                        'event_espresso'
231
-                    ) => $request_response_args,
232
-                ],
233
-                $payment
234
-            );
235
-        }
236
-        if (empty($itemized_order)) {
237
-            $itemized_order = $this->itemized_order->generateItemizedOrder($payment);
238
-        }
239
-        return $itemized_order;
240
-    }
241
-
242
-
243
-    /**
244
-     *  Make the Express checkout request.
245
-     *
246
-     * @param array       $request_params
247
-     * @param string      $request_text
248
-     * @param EEI_Payment $payment
249
-     * @return array|WP_Error
250
-     */
251
-    public function _ppExpress_request(array $request_params, string $request_text, EEI_Payment $payment)
252
-    {
253
-        $request_dtls = [
254
-            'VERSION'      => '204.0',
255
-            'USER'         => $this->_api_username,
256
-            'PWD'          => $this->_api_password,
257
-            'SIGNATURE'    => $this->_api_signature,
258
-            // EE will blow up if you change this
259
-            'BUTTONSOURCE' => 'EventEspresso_SP',
260
-        ];
261
-        $dtls         = array_merge($request_dtls, $request_params);
262
-        $this->_log_clean_request($dtls, $payment, $request_text . ' Request');
263
-        // Request Customer Details.
264
-        $request_response = wp_remote_post(
265
-            $this->_base_gateway_url,
266
-            [
267
-                'method'      => 'POST',
268
-                'timeout'     => 45,
269
-                'httpversion' => '1.1',
270
-                'cookies'     => [],
271
-                'headers'     => [],
272
-                'body'        => http_build_query($dtls),
273
-            ]
274
-        );
275
-        // Log the response.
276
-        $this->log([$request_text . ' Response' => $request_response], $payment);
277
-        return $request_response;
278
-    }
279
-
280
-
281
-    /**
282
-     *  Check the response status.
283
-     *
284
-     * @param mixed $request_response
285
-     * @return array
286
-     */
287
-    public function _ppExpress_check_response($request_response): array
288
-    {
289
-        if (is_wp_error($request_response) || empty($request_response['body'])) {
290
-            // If we got here then there was an error in this request.
291
-            return ['status' => false, 'args' => $request_response];
292
-        }
293
-        $response_args = [];
294
-        parse_str(urldecode($request_response['body']), $response_args);
295
-        if (! isset($response_args['ACK'])) {
296
-            return ['status' => false, 'args' => $request_response];
297
-        }
298
-        if (
299
-            (
300
-                isset($response_args['PAYERID'])
301
-                || isset($response_args['TOKEN'])
302
-                || isset($response_args['PAYMENTINFO_0_TRANSACTIONID'])
303
-                || (isset($response_args['PAYMENTSTATUS']) && $response_args['PAYMENTSTATUS'] === 'Completed')
304
-            )
305
-            && in_array($response_args['ACK'], ['Success', 'SuccessWithWarning'], true)
306
-        ) {
307
-            // Response status OK, return response parameters for further processing.
308
-            return ['status' => true, 'args' => $response_args];
309
-        }
310
-        $errors = $this->_get_errors($response_args);
311
-        return ['status' => false, 'args' => $errors];
312
-    }
313
-
314
-
315
-    /**
316
-     *  Log a "Cleared" request.
317
-     *
318
-     * @param array       $request
319
-     * @param EEI_Payment $payment
320
-     * @param string      $info
321
-     * @return void
322
-     */
323
-    private function _log_clean_request(array $request, EEI_Payment $payment, string $info)
324
-    {
325
-        $cleaned_request_data = $request;
326
-        unset($cleaned_request_data['PWD'], $cleaned_request_data['USER'], $cleaned_request_data['SIGNATURE']);
327
-        $this->log([$info => $cleaned_request_data], $payment);
328
-    }
329
-
330
-
331
-    /**
332
-     *  Get error from the response data.
333
-     *
334
-     * @param array $data_array
335
-     * @return array
336
-     */
337
-    private function _get_errors(array $data_array): array
338
-    {
339
-        $errors = [];
340
-        $n      = 0;
341
-        while (isset($data_array["L_ERRORCODE{$n}"])) {
342
-            $l_error_code    = $data_array["L_ERRORCODE{$n}"] ?? '';
343
-            $l_severity_code = $data_array["L_SEVERITYCODE{$n}"] ?? '';
344
-            $l_short_message = $data_array["L_SHORTMESSAGE{$n}"] ?? '';
345
-            $l_long_message  = $data_array["L_LONGMESSAGE{$n}"] ?? '';
346
-            if ($n === 0) {
347
-                $errors = [
348
-                    'L_ERRORCODE'    => $l_error_code,
349
-                    'L_SHORTMESSAGE' => $l_short_message,
350
-                    'L_LONGMESSAGE'  => $l_long_message,
351
-                    'L_SEVERITYCODE' => $l_severity_code,
352
-                ];
353
-            } else {
354
-                $errors['L_ERRORCODE']    .= ', ' . $l_error_code;
355
-                $errors['L_SHORTMESSAGE'] .= ', ' . $l_short_message;
356
-                $errors['L_LONGMESSAGE']  .= ', ' . $l_long_message;
357
-                $errors['L_SEVERITYCODE'] .= ', ' . $l_severity_code;
358
-            }
359
-            $n++;
360
-        }
361
-        return $errors;
362
-    }
363
-
364
-
365
-    /**
366
-     * @param EE_Payment $payment
367
-     * @return mixed|null
368
-     * @throws EE_Error
369
-     * @since   $VID:$
370
-     */
371
-    private function getPaymentToken(EE_Payment $payment)
372
-    {
373
-        $payment_details = $payment->details();
374
-        // Check if we still have the token.
375
-        if (! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN'])) {
376
-            $payment->set_status($this->_pay_model->failed_status());
377
-            return null;
378
-        }
379
-        return $payment_details['TOKEN'];
380
-    }
381
-
382
-    /**
383
-     * @param EE_Payment $payment
384
-     * @param array      $checkout_response
385
-     * @param array      $customer_data
386
-     * @throws EE_Error
387
-     * @throws ReflectionException
388
-     * @since   $VID:$
389
-     */
390
-    private function paymentApproved(EE_Payment $payment, array $checkout_response, array $customer_data)
391
-    {
392
-        $primary_registrant = $payment->transaction()->primary_registration();
393
-        $primary_registration_code = $primary_registrant instanceof EE_Registration ?
394
-            $primary_registrant->reg_code()
395
-            : '';
396
-        $payment->set_extra_accntng($primary_registration_code);
397
-        $payment_amount = $checkout_response['PAYMENTINFO_0_AMT'] ?? 0;
398
-        $payment->set_amount((float) $payment_amount);
399
-        $payment->set_txn_id_chq_nmbr($checkout_response['PAYMENTINFO_0_TRANSACTIONID'] ?? null);
400
-        $payment->set_details($customer_data);
401
-        $payment->set_gateway_response($checkout_response['PAYMENTINFO_0_ACK'] ?? '');
402
-        $payment->set_status($this->_pay_model->approved_status());
403
-    }
404
-
405
-
406
-    /**
407
-     * @param EE_Payment $payment
408
-     * @param array      $checkout_response
409
-     * @throws EE_Error
410
-     * @since   $VID:$
411
-     */
412
-    private function paymentDeclined(EE_Payment $payment, array $checkout_response)
413
-    {
414
-        $gateway_response = isset($checkout_response['L_ERRORCODE'])
415
-            ? $checkout_response['L_ERRORCODE'] . '; ' . $checkout_response['L_SHORTMESSAGE']
416
-            : esc_html__('Error occurred while trying to Capture the funds.', 'event_espresso');
417
-
418
-        $payment->set_gateway_response($gateway_response);
419
-        $payment->set_details($checkout_response);
420
-        $payment->set_status($this->_pay_model->declined_status());
421
-    }
422
-
423
-
424
-    /**
425
-     * @param EE_Payment $payment
426
-     * @param array $customer_data
427
-     * @throws EE_Error
428
-     * @since   $VID:$
429
-     */
430
-    private function paymentFailed(EE_Payment $payment, array $customer_data)
431
-    {
432
-        $gateway_response = isset($customer_data['L_ERRORCODE'])
433
-            ? $customer_data['L_ERRORCODE'] . '; ' . $customer_data['L_SHORTMESSAGE']
434
-            : esc_html__('Error occurred while trying to get payment Details from PayPal.', 'event_espresso');
435
-
436
-        $payment->set_gateway_response($gateway_response);
437
-        $payment->set_details($customer_data);
438
-        $payment->set_status($this->_pay_model->failed_status());
439
-    }
440
-
441
-
442
-    /**
443
-     * @param EE_Payment $payment
444
-     * @param string     $payment_token
445
-     * @param array      $customer_details
446
-     * @return void
447
-     * @throws EE_Error
448
-     * @throws ReflectionException
449
-     * @throws Exception
450
-     * @since   $VID:$
451
-     */
452
-    private function processPayment(EE_Payment $payment, string $payment_token, array $customer_details)
453
-    {
454
-        $checkout_request_dtls = [
455
-            'METHOD'                         => 'DoExpressCheckoutPayment',
456
-            'PAYERID'                        => $customer_details['PAYERID'],
457
-            'TOKEN'                          => $payment_token,
458
-            'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
459
-            'PAYMENTREQUEST_0_AMT'           => $payment->amount(),
460
-            'PAYMENTREQUEST_0_CURRENCYCODE'  => $payment->currency_code(),
461
-        ];
462
-        // Include itemized list.
463
-        $itemized_list         = $this->getOrderItems($payment, $customer_details);
464
-        $checkout_request_dtls = array_merge($checkout_request_dtls, $itemized_list);
465
-        // Payment Checkout/Capture.
466
-        $checkout_request_response = $this->_ppExpress_request(
467
-            $checkout_request_dtls,
468
-            'Do Payment',
469
-            $payment
470
-        );
471
-        $checkout_request_status   = $this->_ppExpress_check_response($checkout_request_response);
472
-        $checkout_response         =
473
-            isset($checkout_request_status['args']) && is_array($checkout_request_status['args'])
474
-                ? $checkout_request_status['args']
475
-                : [];
476
-        if ($checkout_request_status['status']) {
477
-            // All is well, payment approved.
478
-            $this->paymentApproved($payment, $checkout_response, $customer_details);
479
-        } else {
480
-            $this->paymentDeclined($payment, $checkout_response);
481
-        }
482
-    }
483
-
484
-
485
-    /**
486
-     * @param EE_Payment $payment
487
-     * @param string $payment_token
488
-     * @return array
489
-     * @throws EE_Error
490
-     * @since   $VID:$
491
-     */
492
-    private function requestCustomerDetails(EE_Payment $payment, string $payment_token): array
493
-    {
494
-        $customer_details_request_dtls = [
495
-            'METHOD' => 'GetExpressCheckoutDetails',
496
-            'TOKEN'  => $payment_token,
497
-        ];
498
-        // Request Customer Details.
499
-        $customer_details_request_response = $this->_ppExpress_request(
500
-            $customer_details_request_dtls,
501
-            'Customer Details',
502
-            $payment
503
-        );
504
-        $customer_details_rstatus          = $this->_ppExpress_check_response($customer_details_request_response);
505
-        $customer_details = isset($customer_details_rstatus['args']) && is_array($customer_details_rstatus['args'])
506
-            ? $customer_details_rstatus['args']
507
-            : [];
508
-        if (! $customer_details_rstatus['status']) {
509
-            $this->paymentFailed($payment, $customer_details);
510
-        }
511
-        return $customer_details;
512
-    }
513
-
514
-
515
-
516
-    /**
517
-     * @param EE_Payment|null $payment
518
-     * @return bool
519
-     * @throws EE_Error
520
-     * @since   $VID:$
521
-     */
522
-    private function validatePayment(?EE_Payment $payment): bool
523
-    {
524
-        if (! $payment instanceof EE_Payment) {
525
-            $payment = EE_Payment::new_instance();
526
-            $payment->set_gateway_response(
527
-                esc_html__(
528
-                    'An error occurred while trying to process the payment.',
529
-                    'event_espresso'
530
-                )
531
-            );
532
-            $payment->set_status($this->_pay_model->failed_status());
533
-            return false;
534
-        }
535
-        return true;
536
-    }
537
-
538
-
539
-    /**
540
-     * @param EE_Payment          $payment
541
-     * @param EE_Transaction|null $transaction
542
-     * @return bool
543
-     * @throws EE_Error
544
-     * @since   $VID:$
545
-     */
546
-    private function validateTransaction(EE_Payment $payment, ?EE_Transaction $transaction = null): bool
547
-    {
548
-        $transaction = $transaction ?? $payment->transaction();
549
-        if (! $transaction instanceof EE_Transaction) {
550
-            $payment->set_gateway_response(
551
-                esc_html__(
552
-                    'Could not process this payment because it has no associated transaction.',
553
-                    'event_espresso'
554
-                )
555
-            );
556
-            $payment->set_status($this->_pay_model->failed_status());
557
-            return false;
558
-        }
559
-        return true;
560
-    }
17
+	/**
18
+	 * Merchant API Username.
19
+	 *
20
+	 * @var string
21
+	 */
22
+	protected $_api_username;
23
+
24
+	/**
25
+	 * Merchant API Password.
26
+	 *
27
+	 * @var string
28
+	 */
29
+	protected $_api_password;
30
+
31
+	/**
32
+	 * API Signature.
33
+	 *
34
+	 * @var string
35
+	 */
36
+	protected $_api_signature;
37
+
38
+	/**
39
+	 * Request Shipping address on PP checkout page.
40
+	 *
41
+	 * @var string
42
+	 */
43
+	protected $_request_shipping_addr;
44
+
45
+	/**
46
+	 * Business/personal logo.
47
+	 *
48
+	 * @var string
49
+	 */
50
+	protected $_image_url = '';
51
+
52
+	/**
53
+	 * gateway URL variable
54
+	 *
55
+	 * @var string
56
+	 */
57
+	protected $_base_gateway_url = '';
58
+
59
+
60
+	/**
61
+	 * number of decimal places to round numbers to when performing calculations
62
+	 *
63
+	 * @var integer
64
+	 */
65
+	protected $decimal_precision = 6;
66
+
67
+	/**
68
+	 * @var ItemizedOrder
69
+	 * @since $VID:$
70
+	 */
71
+	protected $itemized_order;
72
+
73
+	/**
74
+	 * @var TokenRequest
75
+	 * @since $VID:$
76
+	 */
77
+	protected $token_request;
78
+
79
+
80
+	/**
81
+	 * EEG_Paypal_Express constructor.
82
+	 */
83
+	public function __construct()
84
+	{
85
+		require_once 'polyfills.php';
86
+		$this->_currencies_supported = [
87
+			'USD',
88
+			'AUD',
89
+			'BRL',
90
+			'CAD',
91
+			'CZK',
92
+			'DKK',
93
+			'EUR',
94
+			'HKD',
95
+			'HUF',
96
+			'ILS',
97
+			'JPY',
98
+			'MYR',
99
+			'MXN',
100
+			'NOK',
101
+			'NZD',
102
+			'PHP',
103
+			'PLN',
104
+			'GBP',
105
+			'RUB',
106
+			'SGD',
107
+			'SEK',
108
+			'CHF',
109
+			'TWD',
110
+			'THB',
111
+			'TRY',
112
+			'INR',
113
+		];
114
+		parent::__construct();
115
+		$this->decimal_precision = EE_Registry::instance()->CFG->currency->dec_plc;
116
+	}
117
+
118
+
119
+	/**
120
+	 * Sets the gateway URL variable based on whether debug mode is enabled or not.
121
+	 *
122
+	 * @param array $settings_array
123
+	 */
124
+	public function set_settings($settings_array)
125
+	{
126
+		parent::set_settings($settings_array);
127
+		// Redirect URL.
128
+		$this->_base_gateway_url = $this->_debug_mode
129
+			? 'https://api-3t.sandbox.paypal.com/nvp'
130
+			: 'https://api-3t.paypal.com/nvp';
131
+	}
132
+
133
+
134
+	/**
135
+	 * @param EEI_Payment $payment
136
+	 * @param array       $billing_info
137
+	 * @param string      $return_url
138
+	 * @param string      $notify_url
139
+	 * @param string      $cancel_url
140
+	 * @return EE_Payment|EEI_Payment
141
+	 * @throws EE_Error
142
+	 * @throws ReflectionException
143
+	 * @throws Exception
144
+	 */
145
+	public function set_redirection_info(
146
+		$payment,
147
+		$billing_info = [],
148
+		$return_url = null,
149
+		$notify_url = null,
150
+		$cancel_url = null
151
+	) {
152
+		if (! $this->validatePayment($payment)) {
153
+			return $payment;
154
+		}
155
+		if (! $this->validateTransaction($payment)) {
156
+			return $payment;
157
+		}
158
+		$this->token_request = new TokenRequest($this->_get_gateway_formatter());
159
+		$token_request_details = apply_filters(
160
+			'FHEE__EEG_Paypal_Express__set_redirection_info__arguments',
161
+			$this->token_request->generateDetails(
162
+				$payment,
163
+				$this->getOrderItems($payment),
164
+				$return_url ?? '',
165
+				$cancel_url ?? '',
166
+				$this->_image_url ?? '',
167
+				$this->_request_shipping_addr ?? ''
168
+			),
169
+			$this
170
+		);
171
+		// Request PayPal token.
172
+		$token_request_response = $this->_ppExpress_request($token_request_details, 'Payment Token', $payment);
173
+		$token_request_status   = $this->_ppExpress_check_response($token_request_response);
174
+		$this->token_request->processResponse($payment, $token_request_status, $this->isInSandboxMode());
175
+
176
+		return $payment;
177
+	}
178
+
179
+
180
+	/**
181
+	 * @param array           $update_info {
182
+	 * @type string           $gateway_txn_id
183
+	 * @type string           $status      an EEMI_Payment status
184
+	 *                                     }
185
+	 * @param EEI_Transaction $transaction
186
+	 * @return EEI_Payment
187
+	 * @throws Exception
188
+	 */
189
+	public function handle_payment_update($update_info, $transaction): EEI_Payment
190
+	{
191
+		// if the supplied transaction is valid, we'll retrieve the actual payment object from it
192
+		// but we'll use a temporary payment for now that we can return with errors if things go wrong
193
+		$payment = EE_Payment::new_instance();
194
+		if (! $this->validateTransaction($payment, $transaction)) {
195
+			return $payment;
196
+		}
197
+		$payment = $transaction->last_payment();
198
+		if (! $this->validatePayment($payment)) {
199
+			return $payment;
200
+		}
201
+		// payment appears to be good... so far
202
+		$this->log(['Return from Authorization' => $update_info], $payment);
203
+		$payment_token = $this->getPaymentToken($payment);
204
+		$customer_details = $this->requestCustomerDetails($payment, $payment_token);
205
+		// We got the PayerID so now we can Complete the transaction.
206
+		$this->processPayment($payment, $payment_token, $customer_details);
207
+
208
+		return $payment;
209
+	}
210
+
211
+
212
+	/**
213
+	 * @throws Exception
214
+	 */
215
+	private function getOrderItems(EE_Payment $payment, array $request_response_args = []): array
216
+	{
217
+		$this->itemized_order = new ItemizedOrder($this->_get_gateway_formatter());
218
+		try {
219
+			$itemized_order = $this->itemized_order->getExistingItemizedOrder($request_response_args);
220
+		} catch (Exception $exception) {
221
+			if (WP_DEBUG) {
222
+				throw $exception;
223
+			}
224
+			// Reset the list and log an error, maybe allow to try and generate a new list (below).
225
+			$itemized_order = [];
226
+			$this->log(
227
+				[
228
+					esc_html__(
229
+						'Could not generate a proper item list with:',
230
+						'event_espresso'
231
+					) => $request_response_args,
232
+				],
233
+				$payment
234
+			);
235
+		}
236
+		if (empty($itemized_order)) {
237
+			$itemized_order = $this->itemized_order->generateItemizedOrder($payment);
238
+		}
239
+		return $itemized_order;
240
+	}
241
+
242
+
243
+	/**
244
+	 *  Make the Express checkout request.
245
+	 *
246
+	 * @param array       $request_params
247
+	 * @param string      $request_text
248
+	 * @param EEI_Payment $payment
249
+	 * @return array|WP_Error
250
+	 */
251
+	public function _ppExpress_request(array $request_params, string $request_text, EEI_Payment $payment)
252
+	{
253
+		$request_dtls = [
254
+			'VERSION'      => '204.0',
255
+			'USER'         => $this->_api_username,
256
+			'PWD'          => $this->_api_password,
257
+			'SIGNATURE'    => $this->_api_signature,
258
+			// EE will blow up if you change this
259
+			'BUTTONSOURCE' => 'EventEspresso_SP',
260
+		];
261
+		$dtls         = array_merge($request_dtls, $request_params);
262
+		$this->_log_clean_request($dtls, $payment, $request_text . ' Request');
263
+		// Request Customer Details.
264
+		$request_response = wp_remote_post(
265
+			$this->_base_gateway_url,
266
+			[
267
+				'method'      => 'POST',
268
+				'timeout'     => 45,
269
+				'httpversion' => '1.1',
270
+				'cookies'     => [],
271
+				'headers'     => [],
272
+				'body'        => http_build_query($dtls),
273
+			]
274
+		);
275
+		// Log the response.
276
+		$this->log([$request_text . ' Response' => $request_response], $payment);
277
+		return $request_response;
278
+	}
279
+
280
+
281
+	/**
282
+	 *  Check the response status.
283
+	 *
284
+	 * @param mixed $request_response
285
+	 * @return array
286
+	 */
287
+	public function _ppExpress_check_response($request_response): array
288
+	{
289
+		if (is_wp_error($request_response) || empty($request_response['body'])) {
290
+			// If we got here then there was an error in this request.
291
+			return ['status' => false, 'args' => $request_response];
292
+		}
293
+		$response_args = [];
294
+		parse_str(urldecode($request_response['body']), $response_args);
295
+		if (! isset($response_args['ACK'])) {
296
+			return ['status' => false, 'args' => $request_response];
297
+		}
298
+		if (
299
+			(
300
+				isset($response_args['PAYERID'])
301
+				|| isset($response_args['TOKEN'])
302
+				|| isset($response_args['PAYMENTINFO_0_TRANSACTIONID'])
303
+				|| (isset($response_args['PAYMENTSTATUS']) && $response_args['PAYMENTSTATUS'] === 'Completed')
304
+			)
305
+			&& in_array($response_args['ACK'], ['Success', 'SuccessWithWarning'], true)
306
+		) {
307
+			// Response status OK, return response parameters for further processing.
308
+			return ['status' => true, 'args' => $response_args];
309
+		}
310
+		$errors = $this->_get_errors($response_args);
311
+		return ['status' => false, 'args' => $errors];
312
+	}
313
+
314
+
315
+	/**
316
+	 *  Log a "Cleared" request.
317
+	 *
318
+	 * @param array       $request
319
+	 * @param EEI_Payment $payment
320
+	 * @param string      $info
321
+	 * @return void
322
+	 */
323
+	private function _log_clean_request(array $request, EEI_Payment $payment, string $info)
324
+	{
325
+		$cleaned_request_data = $request;
326
+		unset($cleaned_request_data['PWD'], $cleaned_request_data['USER'], $cleaned_request_data['SIGNATURE']);
327
+		$this->log([$info => $cleaned_request_data], $payment);
328
+	}
329
+
330
+
331
+	/**
332
+	 *  Get error from the response data.
333
+	 *
334
+	 * @param array $data_array
335
+	 * @return array
336
+	 */
337
+	private function _get_errors(array $data_array): array
338
+	{
339
+		$errors = [];
340
+		$n      = 0;
341
+		while (isset($data_array["L_ERRORCODE{$n}"])) {
342
+			$l_error_code    = $data_array["L_ERRORCODE{$n}"] ?? '';
343
+			$l_severity_code = $data_array["L_SEVERITYCODE{$n}"] ?? '';
344
+			$l_short_message = $data_array["L_SHORTMESSAGE{$n}"] ?? '';
345
+			$l_long_message  = $data_array["L_LONGMESSAGE{$n}"] ?? '';
346
+			if ($n === 0) {
347
+				$errors = [
348
+					'L_ERRORCODE'    => $l_error_code,
349
+					'L_SHORTMESSAGE' => $l_short_message,
350
+					'L_LONGMESSAGE'  => $l_long_message,
351
+					'L_SEVERITYCODE' => $l_severity_code,
352
+				];
353
+			} else {
354
+				$errors['L_ERRORCODE']    .= ', ' . $l_error_code;
355
+				$errors['L_SHORTMESSAGE'] .= ', ' . $l_short_message;
356
+				$errors['L_LONGMESSAGE']  .= ', ' . $l_long_message;
357
+				$errors['L_SEVERITYCODE'] .= ', ' . $l_severity_code;
358
+			}
359
+			$n++;
360
+		}
361
+		return $errors;
362
+	}
363
+
364
+
365
+	/**
366
+	 * @param EE_Payment $payment
367
+	 * @return mixed|null
368
+	 * @throws EE_Error
369
+	 * @since   $VID:$
370
+	 */
371
+	private function getPaymentToken(EE_Payment $payment)
372
+	{
373
+		$payment_details = $payment->details();
374
+		// Check if we still have the token.
375
+		if (! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN'])) {
376
+			$payment->set_status($this->_pay_model->failed_status());
377
+			return null;
378
+		}
379
+		return $payment_details['TOKEN'];
380
+	}
381
+
382
+	/**
383
+	 * @param EE_Payment $payment
384
+	 * @param array      $checkout_response
385
+	 * @param array      $customer_data
386
+	 * @throws EE_Error
387
+	 * @throws ReflectionException
388
+	 * @since   $VID:$
389
+	 */
390
+	private function paymentApproved(EE_Payment $payment, array $checkout_response, array $customer_data)
391
+	{
392
+		$primary_registrant = $payment->transaction()->primary_registration();
393
+		$primary_registration_code = $primary_registrant instanceof EE_Registration ?
394
+			$primary_registrant->reg_code()
395
+			: '';
396
+		$payment->set_extra_accntng($primary_registration_code);
397
+		$payment_amount = $checkout_response['PAYMENTINFO_0_AMT'] ?? 0;
398
+		$payment->set_amount((float) $payment_amount);
399
+		$payment->set_txn_id_chq_nmbr($checkout_response['PAYMENTINFO_0_TRANSACTIONID'] ?? null);
400
+		$payment->set_details($customer_data);
401
+		$payment->set_gateway_response($checkout_response['PAYMENTINFO_0_ACK'] ?? '');
402
+		$payment->set_status($this->_pay_model->approved_status());
403
+	}
404
+
405
+
406
+	/**
407
+	 * @param EE_Payment $payment
408
+	 * @param array      $checkout_response
409
+	 * @throws EE_Error
410
+	 * @since   $VID:$
411
+	 */
412
+	private function paymentDeclined(EE_Payment $payment, array $checkout_response)
413
+	{
414
+		$gateway_response = isset($checkout_response['L_ERRORCODE'])
415
+			? $checkout_response['L_ERRORCODE'] . '; ' . $checkout_response['L_SHORTMESSAGE']
416
+			: esc_html__('Error occurred while trying to Capture the funds.', 'event_espresso');
417
+
418
+		$payment->set_gateway_response($gateway_response);
419
+		$payment->set_details($checkout_response);
420
+		$payment->set_status($this->_pay_model->declined_status());
421
+	}
422
+
423
+
424
+	/**
425
+	 * @param EE_Payment $payment
426
+	 * @param array $customer_data
427
+	 * @throws EE_Error
428
+	 * @since   $VID:$
429
+	 */
430
+	private function paymentFailed(EE_Payment $payment, array $customer_data)
431
+	{
432
+		$gateway_response = isset($customer_data['L_ERRORCODE'])
433
+			? $customer_data['L_ERRORCODE'] . '; ' . $customer_data['L_SHORTMESSAGE']
434
+			: esc_html__('Error occurred while trying to get payment Details from PayPal.', 'event_espresso');
435
+
436
+		$payment->set_gateway_response($gateway_response);
437
+		$payment->set_details($customer_data);
438
+		$payment->set_status($this->_pay_model->failed_status());
439
+	}
440
+
441
+
442
+	/**
443
+	 * @param EE_Payment $payment
444
+	 * @param string     $payment_token
445
+	 * @param array      $customer_details
446
+	 * @return void
447
+	 * @throws EE_Error
448
+	 * @throws ReflectionException
449
+	 * @throws Exception
450
+	 * @since   $VID:$
451
+	 */
452
+	private function processPayment(EE_Payment $payment, string $payment_token, array $customer_details)
453
+	{
454
+		$checkout_request_dtls = [
455
+			'METHOD'                         => 'DoExpressCheckoutPayment',
456
+			'PAYERID'                        => $customer_details['PAYERID'],
457
+			'TOKEN'                          => $payment_token,
458
+			'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
459
+			'PAYMENTREQUEST_0_AMT'           => $payment->amount(),
460
+			'PAYMENTREQUEST_0_CURRENCYCODE'  => $payment->currency_code(),
461
+		];
462
+		// Include itemized list.
463
+		$itemized_list         = $this->getOrderItems($payment, $customer_details);
464
+		$checkout_request_dtls = array_merge($checkout_request_dtls, $itemized_list);
465
+		// Payment Checkout/Capture.
466
+		$checkout_request_response = $this->_ppExpress_request(
467
+			$checkout_request_dtls,
468
+			'Do Payment',
469
+			$payment
470
+		);
471
+		$checkout_request_status   = $this->_ppExpress_check_response($checkout_request_response);
472
+		$checkout_response         =
473
+			isset($checkout_request_status['args']) && is_array($checkout_request_status['args'])
474
+				? $checkout_request_status['args']
475
+				: [];
476
+		if ($checkout_request_status['status']) {
477
+			// All is well, payment approved.
478
+			$this->paymentApproved($payment, $checkout_response, $customer_details);
479
+		} else {
480
+			$this->paymentDeclined($payment, $checkout_response);
481
+		}
482
+	}
483
+
484
+
485
+	/**
486
+	 * @param EE_Payment $payment
487
+	 * @param string $payment_token
488
+	 * @return array
489
+	 * @throws EE_Error
490
+	 * @since   $VID:$
491
+	 */
492
+	private function requestCustomerDetails(EE_Payment $payment, string $payment_token): array
493
+	{
494
+		$customer_details_request_dtls = [
495
+			'METHOD' => 'GetExpressCheckoutDetails',
496
+			'TOKEN'  => $payment_token,
497
+		];
498
+		// Request Customer Details.
499
+		$customer_details_request_response = $this->_ppExpress_request(
500
+			$customer_details_request_dtls,
501
+			'Customer Details',
502
+			$payment
503
+		);
504
+		$customer_details_rstatus          = $this->_ppExpress_check_response($customer_details_request_response);
505
+		$customer_details = isset($customer_details_rstatus['args']) && is_array($customer_details_rstatus['args'])
506
+			? $customer_details_rstatus['args']
507
+			: [];
508
+		if (! $customer_details_rstatus['status']) {
509
+			$this->paymentFailed($payment, $customer_details);
510
+		}
511
+		return $customer_details;
512
+	}
513
+
514
+
515
+
516
+	/**
517
+	 * @param EE_Payment|null $payment
518
+	 * @return bool
519
+	 * @throws EE_Error
520
+	 * @since   $VID:$
521
+	 */
522
+	private function validatePayment(?EE_Payment $payment): bool
523
+	{
524
+		if (! $payment instanceof EE_Payment) {
525
+			$payment = EE_Payment::new_instance();
526
+			$payment->set_gateway_response(
527
+				esc_html__(
528
+					'An error occurred while trying to process the payment.',
529
+					'event_espresso'
530
+				)
531
+			);
532
+			$payment->set_status($this->_pay_model->failed_status());
533
+			return false;
534
+		}
535
+		return true;
536
+	}
537
+
538
+
539
+	/**
540
+	 * @param EE_Payment          $payment
541
+	 * @param EE_Transaction|null $transaction
542
+	 * @return bool
543
+	 * @throws EE_Error
544
+	 * @since   $VID:$
545
+	 */
546
+	private function validateTransaction(EE_Payment $payment, ?EE_Transaction $transaction = null): bool
547
+	{
548
+		$transaction = $transaction ?? $payment->transaction();
549
+		if (! $transaction instanceof EE_Transaction) {
550
+			$payment->set_gateway_response(
551
+				esc_html__(
552
+					'Could not process this payment because it has no associated transaction.',
553
+					'event_espresso'
554
+				)
555
+			);
556
+			$payment->set_status($this->_pay_model->failed_status());
557
+			return false;
558
+		}
559
+		return true;
560
+	}
561 561
 }
Please login to merge, or discard this patch.
Spacing   +19 added lines, -19 removed lines patch added patch discarded remove patch
@@ -149,10 +149,10 @@  discard block
 block discarded – undo
149 149
         $notify_url = null,
150 150
         $cancel_url = null
151 151
     ) {
152
-        if (! $this->validatePayment($payment)) {
152
+        if ( ! $this->validatePayment($payment)) {
153 153
             return $payment;
154 154
         }
155
-        if (! $this->validateTransaction($payment)) {
155
+        if ( ! $this->validateTransaction($payment)) {
156 156
             return $payment;
157 157
         }
158 158
         $this->token_request = new TokenRequest($this->_get_gateway_formatter());
@@ -191,11 +191,11 @@  discard block
 block discarded – undo
191 191
         // if the supplied transaction is valid, we'll retrieve the actual payment object from it
192 192
         // but we'll use a temporary payment for now that we can return with errors if things go wrong
193 193
         $payment = EE_Payment::new_instance();
194
-        if (! $this->validateTransaction($payment, $transaction)) {
194
+        if ( ! $this->validateTransaction($payment, $transaction)) {
195 195
             return $payment;
196 196
         }
197 197
         $payment = $transaction->last_payment();
198
-        if (! $this->validatePayment($payment)) {
198
+        if ( ! $this->validatePayment($payment)) {
199 199
             return $payment;
200 200
         }
201 201
         // payment appears to be good... so far
@@ -258,8 +258,8 @@  discard block
 block discarded – undo
258 258
             // EE will blow up if you change this
259 259
             'BUTTONSOURCE' => 'EventEspresso_SP',
260 260
         ];
261
-        $dtls         = array_merge($request_dtls, $request_params);
262
-        $this->_log_clean_request($dtls, $payment, $request_text . ' Request');
261
+        $dtls = array_merge($request_dtls, $request_params);
262
+        $this->_log_clean_request($dtls, $payment, $request_text.' Request');
263 263
         // Request Customer Details.
264 264
         $request_response = wp_remote_post(
265 265
             $this->_base_gateway_url,
@@ -273,7 +273,7 @@  discard block
 block discarded – undo
273 273
             ]
274 274
         );
275 275
         // Log the response.
276
-        $this->log([$request_text . ' Response' => $request_response], $payment);
276
+        $this->log([$request_text.' Response' => $request_response], $payment);
277 277
         return $request_response;
278 278
     }
279 279
 
@@ -292,7 +292,7 @@  discard block
 block discarded – undo
292 292
         }
293 293
         $response_args = [];
294 294
         parse_str(urldecode($request_response['body']), $response_args);
295
-        if (! isset($response_args['ACK'])) {
295
+        if ( ! isset($response_args['ACK'])) {
296 296
             return ['status' => false, 'args' => $request_response];
297 297
         }
298 298
         if (
@@ -351,10 +351,10 @@  discard block
 block discarded – undo
351 351
                     'L_SEVERITYCODE' => $l_severity_code,
352 352
                 ];
353 353
             } else {
354
-                $errors['L_ERRORCODE']    .= ', ' . $l_error_code;
355
-                $errors['L_SHORTMESSAGE'] .= ', ' . $l_short_message;
356
-                $errors['L_LONGMESSAGE']  .= ', ' . $l_long_message;
357
-                $errors['L_SEVERITYCODE'] .= ', ' . $l_severity_code;
354
+                $errors['L_ERRORCODE']    .= ', '.$l_error_code;
355
+                $errors['L_SHORTMESSAGE'] .= ', '.$l_short_message;
356
+                $errors['L_LONGMESSAGE']  .= ', '.$l_long_message;
357
+                $errors['L_SEVERITYCODE'] .= ', '.$l_severity_code;
358 358
             }
359 359
             $n++;
360 360
         }
@@ -372,7 +372,7 @@  discard block
 block discarded – undo
372 372
     {
373 373
         $payment_details = $payment->details();
374 374
         // Check if we still have the token.
375
-        if (! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN'])) {
375
+        if ( ! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN'])) {
376 376
             $payment->set_status($this->_pay_model->failed_status());
377 377
             return null;
378 378
         }
@@ -412,7 +412,7 @@  discard block
 block discarded – undo
412 412
     private function paymentDeclined(EE_Payment $payment, array $checkout_response)
413 413
     {
414 414
         $gateway_response = isset($checkout_response['L_ERRORCODE'])
415
-            ? $checkout_response['L_ERRORCODE'] . '; ' . $checkout_response['L_SHORTMESSAGE']
415
+            ? $checkout_response['L_ERRORCODE'].'; '.$checkout_response['L_SHORTMESSAGE']
416 416
             : esc_html__('Error occurred while trying to Capture the funds.', 'event_espresso');
417 417
 
418 418
         $payment->set_gateway_response($gateway_response);
@@ -430,7 +430,7 @@  discard block
 block discarded – undo
430 430
     private function paymentFailed(EE_Payment $payment, array $customer_data)
431 431
     {
432 432
         $gateway_response = isset($customer_data['L_ERRORCODE'])
433
-            ? $customer_data['L_ERRORCODE'] . '; ' . $customer_data['L_SHORTMESSAGE']
433
+            ? $customer_data['L_ERRORCODE'].'; '.$customer_data['L_SHORTMESSAGE']
434 434
             : esc_html__('Error occurred while trying to get payment Details from PayPal.', 'event_espresso');
435 435
 
436 436
         $payment->set_gateway_response($gateway_response);
@@ -501,11 +501,11 @@  discard block
 block discarded – undo
501 501
             'Customer Details',
502 502
             $payment
503 503
         );
504
-        $customer_details_rstatus          = $this->_ppExpress_check_response($customer_details_request_response);
504
+        $customer_details_rstatus = $this->_ppExpress_check_response($customer_details_request_response);
505 505
         $customer_details = isset($customer_details_rstatus['args']) && is_array($customer_details_rstatus['args'])
506 506
             ? $customer_details_rstatus['args']
507 507
             : [];
508
-        if (! $customer_details_rstatus['status']) {
508
+        if ( ! $customer_details_rstatus['status']) {
509 509
             $this->paymentFailed($payment, $customer_details);
510 510
         }
511 511
         return $customer_details;
@@ -521,7 +521,7 @@  discard block
 block discarded – undo
521 521
      */
522 522
     private function validatePayment(?EE_Payment $payment): bool
523 523
     {
524
-        if (! $payment instanceof EE_Payment) {
524
+        if ( ! $payment instanceof EE_Payment) {
525 525
             $payment = EE_Payment::new_instance();
526 526
             $payment->set_gateway_response(
527 527
                 esc_html__(
@@ -546,7 +546,7 @@  discard block
 block discarded – undo
546 546
     private function validateTransaction(EE_Payment $payment, ?EE_Transaction $transaction = null): bool
547 547
     {
548 548
         $transaction = $transaction ?? $payment->transaction();
549
-        if (! $transaction instanceof EE_Transaction) {
549
+        if ( ! $transaction instanceof EE_Transaction) {
550 550
             $payment->set_gateway_response(
551 551
                 esc_html__(
552 552
                     'Could not process this payment because it has no associated transaction.',
Please login to merge, or discard this patch.
payment_methods/Paypal_Express/TokenRequest.php 2 patches
Indentation   +113 added lines, -113 removed lines patch added patch discarded remove patch
@@ -13,124 +13,124 @@
 block discarded – undo
13 13
 class TokenRequest
14 14
 {
15 15
 
16
-    /**
17
-     * @var GatewayDataFormatterInterface
18
-     */
19
-    protected $gateway_data_formatter;
16
+	/**
17
+	 * @var GatewayDataFormatterInterface
18
+	 */
19
+	protected $gateway_data_formatter;
20 20
 
21 21
 
22
-    /**
23
-     * @param GatewayDataFormatterInterface $gateway_data_formatter
24
-     */
25
-    public function __construct(GatewayDataFormatterInterface $gateway_data_formatter)
26
-    {
27
-        $this->gateway_data_formatter = $gateway_data_formatter;
28
-    }
22
+	/**
23
+	 * @param GatewayDataFormatterInterface $gateway_data_formatter
24
+	 */
25
+	public function __construct(GatewayDataFormatterInterface $gateway_data_formatter)
26
+	{
27
+		$this->gateway_data_formatter = $gateway_data_formatter;
28
+	}
29 29
 
30 30
 
31
-    /**
32
-     * @param EE_Payment $payment
33
-     * @param array      $itemized_order
34
-     * @param string     $return_url
35
-     * @param string     $cancel_url
36
-     * @param string $logo_image_url
37
-     * @param bool       $request_shipping_address
38
-     * @return array
39
-     * @throws EE_Error
40
-     * @throws ReflectionException
41
-     */
42
-    public function generateDetails(
43
-        EE_Payment $payment,
44
-        array      $itemized_order = [],
45
-        string     $return_url = '',
46
-        string     $cancel_url = '',
47
-        string     $logo_image_url = '',
48
-        bool       $request_shipping_address = false
49
-    ): array {
50
-        $locale               = explode('-', get_bloginfo('language'));
51
-        // Gather request parameters.
52
-        $token_request_details = [
53
-            'METHOD'                         => 'SetExpressCheckout',
54
-            'PAYMENTREQUEST_0_AMT'           => $payment->amount(),
55
-            'PAYMENTREQUEST_0_CURRENCYCODE'  => $payment->currency_code(),
56
-            'PAYMENTREQUEST_0_DESC'          => mb_strcut(
57
-                $this->gateway_data_formatter->formatOrderDescription($payment),
58
-                0,
59
-                127
60
-            ),
61
-            'RETURNURL'                      => $return_url,
62
-            'CANCELURL'                      => $cancel_url,
63
-            'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
64
-            // Buyer does not need to create a PayPal account to check out.
65
-            // This is referred to as PayPal Account Optional.
66
-            'SOLUTIONTYPE'                   => 'Sole',
67
-            // Locale of the pages displayed by PayPal during Express Checkout.
68
-            'LOCALECODE'                     => $locale[1],
69
-        ];
70
-        $token_request_details = array_merge($token_request_details, $itemized_order);
71
-        if (! $request_shipping_address) {
72
-            // Do not request shipping details on the PP Checkout page.
73
-            $token_request_details['NOSHIPPING']         = '1';
74
-            $token_request_details['REQCONFIRMSHIPPING'] = '0';
75
-        } else {
76
-            // Automatically filling out shipping and contact information.
77
-            $transaction          = $payment->transaction();
78
-            $primary_registration = $transaction->primary_registration();
79
-            $primary_attendee     = $primary_registration instanceof EE_Registration
80
-                ? $primary_registration->attendee()
81
-                : false;
82
-            if ($primary_attendee instanceof EE_Attendee) {
83
-                // If you do not pass the shipping address, PayPal obtains it from the buyer's account profile.
84
-                $token_request_details['NOSHIPPING']                         = '2';
85
-                $token_request_details['PAYMENTREQUEST_0_SHIPTOSTREET']      = $primary_attendee->address();
86
-                $token_request_details['PAYMENTREQUEST_0_SHIPTOSTREET2']     = $primary_attendee->address2();
87
-                $token_request_details['PAYMENTREQUEST_0_SHIPTOCITY']        = $primary_attendee->city();
88
-                $token_request_details['PAYMENTREQUEST_0_SHIPTOSTATE']       = $primary_attendee->state_abbrev();
89
-                $token_request_details['PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE'] = $primary_attendee->country_ID();
90
-                $token_request_details['PAYMENTREQUEST_0_SHIPTOZIP']         = $primary_attendee->zip();
91
-                $token_request_details['PAYMENTREQUEST_0_EMAIL']             = $primary_attendee->email();
92
-                $token_request_details['PAYMENTREQUEST_0_SHIPTOPHONENUM']    = $primary_attendee->phone();
93
-            }
94
-        }
95
-        // Used a business/personal logo on the PayPal page.
96
-        if (! empty($logo_image_url)) {
97
-            $token_request_details['LOGOIMG'] = $logo_image_url;
98
-        }
99
-        return $token_request_details;
100
-    }
31
+	/**
32
+	 * @param EE_Payment $payment
33
+	 * @param array      $itemized_order
34
+	 * @param string     $return_url
35
+	 * @param string     $cancel_url
36
+	 * @param string $logo_image_url
37
+	 * @param bool       $request_shipping_address
38
+	 * @return array
39
+	 * @throws EE_Error
40
+	 * @throws ReflectionException
41
+	 */
42
+	public function generateDetails(
43
+		EE_Payment $payment,
44
+		array      $itemized_order = [],
45
+		string     $return_url = '',
46
+		string     $cancel_url = '',
47
+		string     $logo_image_url = '',
48
+		bool       $request_shipping_address = false
49
+	): array {
50
+		$locale               = explode('-', get_bloginfo('language'));
51
+		// Gather request parameters.
52
+		$token_request_details = [
53
+			'METHOD'                         => 'SetExpressCheckout',
54
+			'PAYMENTREQUEST_0_AMT'           => $payment->amount(),
55
+			'PAYMENTREQUEST_0_CURRENCYCODE'  => $payment->currency_code(),
56
+			'PAYMENTREQUEST_0_DESC'          => mb_strcut(
57
+				$this->gateway_data_formatter->formatOrderDescription($payment),
58
+				0,
59
+				127
60
+			),
61
+			'RETURNURL'                      => $return_url,
62
+			'CANCELURL'                      => $cancel_url,
63
+			'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
64
+			// Buyer does not need to create a PayPal account to check out.
65
+			// This is referred to as PayPal Account Optional.
66
+			'SOLUTIONTYPE'                   => 'Sole',
67
+			// Locale of the pages displayed by PayPal during Express Checkout.
68
+			'LOCALECODE'                     => $locale[1],
69
+		];
70
+		$token_request_details = array_merge($token_request_details, $itemized_order);
71
+		if (! $request_shipping_address) {
72
+			// Do not request shipping details on the PP Checkout page.
73
+			$token_request_details['NOSHIPPING']         = '1';
74
+			$token_request_details['REQCONFIRMSHIPPING'] = '0';
75
+		} else {
76
+			// Automatically filling out shipping and contact information.
77
+			$transaction          = $payment->transaction();
78
+			$primary_registration = $transaction->primary_registration();
79
+			$primary_attendee     = $primary_registration instanceof EE_Registration
80
+				? $primary_registration->attendee()
81
+				: false;
82
+			if ($primary_attendee instanceof EE_Attendee) {
83
+				// If you do not pass the shipping address, PayPal obtains it from the buyer's account profile.
84
+				$token_request_details['NOSHIPPING']                         = '2';
85
+				$token_request_details['PAYMENTREQUEST_0_SHIPTOSTREET']      = $primary_attendee->address();
86
+				$token_request_details['PAYMENTREQUEST_0_SHIPTOSTREET2']     = $primary_attendee->address2();
87
+				$token_request_details['PAYMENTREQUEST_0_SHIPTOCITY']        = $primary_attendee->city();
88
+				$token_request_details['PAYMENTREQUEST_0_SHIPTOSTATE']       = $primary_attendee->state_abbrev();
89
+				$token_request_details['PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE'] = $primary_attendee->country_ID();
90
+				$token_request_details['PAYMENTREQUEST_0_SHIPTOZIP']         = $primary_attendee->zip();
91
+				$token_request_details['PAYMENTREQUEST_0_EMAIL']             = $primary_attendee->email();
92
+				$token_request_details['PAYMENTREQUEST_0_SHIPTOPHONENUM']    = $primary_attendee->phone();
93
+			}
94
+		}
95
+		// Used a business/personal logo on the PayPal page.
96
+		if (! empty($logo_image_url)) {
97
+			$token_request_details['LOGOIMG'] = $logo_image_url;
98
+		}
99
+		return $token_request_details;
100
+	}
101 101
 
102 102
 
103
-    /**
104
-     * @param EE_Payment $payment
105
-     * @param array      $token_request_status
106
-     * @param bool       $is_in_sandbox_mode
107
-     * @throws EE_Error
108
-     * @throws ReflectionException
109
-     */
110
-    public function processResponse(EE_Payment $payment, array $token_request_status, bool $is_in_sandbox_mode)
111
-    {
112
-        $response_args = (isset($token_request_status['args']) && is_array($token_request_status['args']))
113
-            ? $token_request_status['args']
114
-            : [];
115
-        if ($token_request_status['status']) {
116
-            // We got the Token so we may continue with the payment and redirect the client.
117
-            $payment->set_details($response_args);
118
-            $gateway_url = $is_in_sandbox_mode ? 'https://www.sandbox.paypal.com' : 'https://www.paypal.com';
119
-            $token = $response_args['TOKEN'];
120
-            $payment->set_redirect_url(
121
-                "{$gateway_url}/checkoutnow?useraction=commit&cmd=_express-checkout&token={$token}"
122
-            );
123
-            return;
124
-        }
125
-        $gateway_response = isset($response_args['L_ERRORCODE'])
126
-            ? $response_args['L_ERRORCODE'] . '; ' . $response_args['L_SHORTMESSAGE']
127
-            : esc_html__(
128
-                'Error occurred while trying to setup the Express Checkout.',
129
-                'event_espresso'
130
-            );
103
+	/**
104
+	 * @param EE_Payment $payment
105
+	 * @param array      $token_request_status
106
+	 * @param bool       $is_in_sandbox_mode
107
+	 * @throws EE_Error
108
+	 * @throws ReflectionException
109
+	 */
110
+	public function processResponse(EE_Payment $payment, array $token_request_status, bool $is_in_sandbox_mode)
111
+	{
112
+		$response_args = (isset($token_request_status['args']) && is_array($token_request_status['args']))
113
+			? $token_request_status['args']
114
+			: [];
115
+		if ($token_request_status['status']) {
116
+			// We got the Token so we may continue with the payment and redirect the client.
117
+			$payment->set_details($response_args);
118
+			$gateway_url = $is_in_sandbox_mode ? 'https://www.sandbox.paypal.com' : 'https://www.paypal.com';
119
+			$token = $response_args['TOKEN'];
120
+			$payment->set_redirect_url(
121
+				"{$gateway_url}/checkoutnow?useraction=commit&cmd=_express-checkout&token={$token}"
122
+			);
123
+			return;
124
+		}
125
+		$gateway_response = isset($response_args['L_ERRORCODE'])
126
+			? $response_args['L_ERRORCODE'] . '; ' . $response_args['L_SHORTMESSAGE']
127
+			: esc_html__(
128
+				'Error occurred while trying to setup the Express Checkout.',
129
+				'event_espresso'
130
+			);
131 131
 
132
-        $payment->set_gateway_response($gateway_response);
133
-        $payment->set_details($response_args);
134
-        $payment->set_status(EEM_Payment::instance()->failed_status());
135
-    }
132
+		$payment->set_gateway_response($gateway_response);
133
+		$payment->set_details($response_args);
134
+		$payment->set_status(EEM_Payment::instance()->failed_status());
135
+	}
136 136
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -47,7 +47,7 @@  discard block
 block discarded – undo
47 47
         string     $logo_image_url = '',
48 48
         bool       $request_shipping_address = false
49 49
     ): array {
50
-        $locale               = explode('-', get_bloginfo('language'));
50
+        $locale = explode('-', get_bloginfo('language'));
51 51
         // Gather request parameters.
52 52
         $token_request_details = [
53 53
             'METHOD'                         => 'SetExpressCheckout',
@@ -68,7 +68,7 @@  discard block
 block discarded – undo
68 68
             'LOCALECODE'                     => $locale[1],
69 69
         ];
70 70
         $token_request_details = array_merge($token_request_details, $itemized_order);
71
-        if (! $request_shipping_address) {
71
+        if ( ! $request_shipping_address) {
72 72
             // Do not request shipping details on the PP Checkout page.
73 73
             $token_request_details['NOSHIPPING']         = '1';
74 74
             $token_request_details['REQCONFIRMSHIPPING'] = '0';
@@ -93,7 +93,7 @@  discard block
 block discarded – undo
93 93
             }
94 94
         }
95 95
         // Used a business/personal logo on the PayPal page.
96
-        if (! empty($logo_image_url)) {
96
+        if ( ! empty($logo_image_url)) {
97 97
             $token_request_details['LOGOIMG'] = $logo_image_url;
98 98
         }
99 99
         return $token_request_details;
@@ -123,7 +123,7 @@  discard block
 block discarded – undo
123 123
             return;
124 124
         }
125 125
         $gateway_response = isset($response_args['L_ERRORCODE'])
126
-            ? $response_args['L_ERRORCODE'] . '; ' . $response_args['L_SHORTMESSAGE']
126
+            ? $response_args['L_ERRORCODE'].'; '.$response_args['L_SHORTMESSAGE']
127 127
             : esc_html__(
128 128
                 'Error occurred while trying to setup the Express Checkout.',
129 129
                 'event_espresso'
Please login to merge, or discard this patch.