RApiPaymentPluginHelperPayment::getMerchantID()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
c 0
b 0
f 0
dl 0
loc 11
rs 10
cc 3
nc 2
nop 0
1
<?php
2
/**
3
 * @package     Redcore
4
 * @subpackage  Base
5
 *
6
 * @copyright   Copyright (C) 2008 - 2021 redWEB.dk. All rights reserved.
7
 * @license     GNU General Public License version 2 or later, see LICENSE.
8
 */
9
10
defined('JPATH_REDCORE') or die;
11
12
use Joomla\Utilities\ArrayHelper;
13
14
/**
15
 * redCORE Payment plugin base Class
16
 *
17
 * @package     Redcore
18
 * @subpackage  Payment
19
 * @since       1.5
20
 */
21
abstract class RApiPaymentPluginHelperPayment extends JObject implements RApiPaymentPluginInterface
0 ignored issues
show
Deprecated Code introduced by
The class JObject has been deprecated: 4.0 ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

21
abstract class RApiPaymentPluginHelperPayment extends /** @scrutinizer ignore-deprecated */ JObject implements RApiPaymentPluginInterface
Loading history...
22
{
23
	/**
24
	 * Payment Name
25
	 * @var string
26
	 */
27
	public $paymentName = '';
28
29
	public $offlinePayment = false;
30
31
	/**
32
	 * Plugin parameters
33
	 * @var JRegistry
0 ignored issues
show
Bug introduced by
The type JRegistry was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
34
	 */
35
	public $params = null;
36
37
	/**
38
	 * URL to the payment gateway
39
	 * @var string
40
	 */
41
	public $paymentUrl = '';
42
43
	/**
44
	 * Path on host of the payment gateway to post request to (ex. '/cgi-bin/webscr')
45
	 * @var string
46
	 */
47
	protected $requestPath = '';
48
49
	/**
50
	 * Sandbox URL to the payment gateway
51
	 * @var string
52
	 */
53
	public $paymentUrlSandbox = '';
54
55
	/**
56
	 * Sandbox path on host of the payment gateway to post request to (ex. '/cgi-bin/webscr')
57
	 * @var string
58
	 */
59
	protected $requestPathSandbox = '';
60
61
	/**
62
	 * Port on FTP host of the payment gateway to post request to. Used only in fsockopen request method. (443 for https and 80 for http)
63
	 * @var string
64
	 */
65
	protected $fsockPort = '443';
66
67
	/**
68
	 * Plugin can be disabled for specific extension this is set in payment configuration
69
	 * @var bool
70
	 */
71
	public $pluginEnabled = true;
72
73
	/**
74
	 * This flag is sent to the layout where it can be used to auto submit the form.
75
	 * It can be overridden from passed parameters with $data['autoSubmit']
76
	 * @var bool
77
	 */
78
	public $autoSubmit = false;
79
80
	/**
81
	 * There are two types of calculating fee based on percentage:
82
	 * 'add' adds a percentage based fee to the total amount (ex. 100$ + 10% = 110$)
83
	 * 'include' Fee is calculated as a commission rate (ex. 100$ + include commission = 111,11$ that will result of giving shopper full amount of 100$)
84
	 * @var string
85
	 */
86
	public $paymentFeeType = 'include';
87
88
	/**
89
	 * Payment api will use given folder path to load custom (not official) omnipay payment classes
90
	 * @var string
91
	 */
92
	protected $omnipayCustomClassPath = '';
93
94
	/**
95
	 * If using omnipay this property must be the name of the omnipay payment gateway ex. Stripe
96
	 * @var string
97
	 */
98
	protected $omnipayGatewayName = '';
99
100
	/**
101
	 * Constructor
102
	 *
103
	 * @param   JRegistry  $params  Parameters from the plugin
104
	 *
105
	 * @since   1.5
106
	 */
107
	public function __construct($params = null)
108
	{
109
		$this->params = $params;
110
	}
111
112
	/**
113
	 * Handle the reception of notification from the payment gateway
114
	 * This method validates request that came from Payment gateway to check if it is valid and that it came through Payment gateway
115
	 *
116
	 * @param   string  $extensionName  Name of the extension
117
	 * @param   string  $ownerName      Name of the owner
118
	 * @param   array   $data           Data to fill out Payment form
119
	 * @param   array   &$logData       Log data for payment api
120
	 *
121
	 * @return bool paid status
122
	 */
123
	public function handleCallback($extensionName, $ownerName, $data, &$logData)
124
	{
125
		// This function should be implemented in the child class if needed
126
		// This method is not set as abstract because many of the payment gateways do not support it
127
		$logData['message_text'] = JText::sprintf('LIB_REDCORE_PAYMENT_LOG_METHOD_NOT_SUPPORTED', 'handleCallback', $this->paymentName);
128
129
		return false;
130
	}
131
132
	/**
133
	 * Handle the reception of notification from the payment gateway
134
	 * This method validates request that came from Payment gateway to check if it is valid and that it came through Payment gateway
135
	 *
136
	 * @param   string  $extensionName  Name of the extension
137
	 * @param   string  $ownerName      Name of the owner
138
	 * @param   array   $data           Request data
139
	 * @param   array   &$logData       Log data
140
	 * @param   bool    &$isAccepted    If process is successful then this flag should be true
141
	 *
142
	 * @return bool paid status
143
	 */
144
	public function handleProcess($extensionName, $ownerName, $data, &$logData, &$isAccepted)
0 ignored issues
show
Unused Code introduced by
The parameter $ownerName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

144
	public function handleProcess($extensionName, /** @scrutinizer ignore-unused */ $ownerName, $data, &$logData, &$isAccepted)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $extensionName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

144
	public function handleProcess(/** @scrutinizer ignore-unused */ $extensionName, $ownerName, $data, &$logData, &$isAccepted)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $data is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

144
	public function handleProcess($extensionName, $ownerName, /** @scrutinizer ignore-unused */ $data, &$logData, &$isAccepted)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
145
	{
146
		// This function should be implemented in the child class if needed
147
		// This method is not set as abstract because many of the payment gateways do not support it
148
		$logData['message_text'] = JText::sprintf('LIB_REDCORE_PAYMENT_LOG_METHOD_NOT_SUPPORTED', 'handleProcess', $this->paymentName);
149
		$isAccepted = false;
150
151
		return false;
152
	}
153
154
	/**
155
	 * Handle the accept notification from the payment gateway
156
	 * This method is called when Payment gateway redirect customer on success but we still do not know if the payment is confirmed
157
	 *
158
	 * @param   string  $extensionName  Name of the extension
159
	 * @param   string  $ownerName      Name of the owner
160
	 * @param   array   $data           Request data
161
	 * @param   array   &$logData       Log data
162
	 *
163
	 * @return void
164
	 */
165
	public function handleAcceptRequest($extensionName, $ownerName, $data, &$logData)
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

165
	public function handleAcceptRequest($extensionName, $ownerName, /** @scrutinizer ignore-unused */ $data, &$logData)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $ownerName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

165
	public function handleAcceptRequest($extensionName, /** @scrutinizer ignore-unused */ $ownerName, $data, &$logData)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $extensionName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

165
	public function handleAcceptRequest(/** @scrutinizer ignore-unused */ $extensionName, $ownerName, $data, &$logData)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $logData is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

165
	public function handleAcceptRequest($extensionName, $ownerName, $data, /** @scrutinizer ignore-unused */ &$logData)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
166
	{
167
		// This function should be implemented in the child class if needed
168
		// This method is not set as abstract because many of the payment gateways do not support/need it
169
	}
170
171
	/**
172
	 * Handle the cancel notification from the payment gateway
173
	 * This method is called when Payment gateway redirect customer on cancel button
174
	 *
175
	 * @param   string  $extensionName  Name of the extension
176
	 * @param   string  $ownerName      Name of the owner
177
	 * @param   array   $data           Request data
178
	 * @param   array   &$logData       Log data
179
	 *
180
	 * @return void
181
	 */
182
	public function handleCancelRequest($extensionName, $ownerName, $data, &$logData)
0 ignored issues
show
Unused Code introduced by
The parameter $ownerName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

182
	public function handleCancelRequest($extensionName, /** @scrutinizer ignore-unused */ $ownerName, $data, &$logData)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $data is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

182
	public function handleCancelRequest($extensionName, $ownerName, /** @scrutinizer ignore-unused */ $data, &$logData)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $extensionName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

182
	public function handleCancelRequest(/** @scrutinizer ignore-unused */ $extensionName, $ownerName, $data, &$logData)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $logData is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

182
	public function handleCancelRequest($extensionName, $ownerName, $data, /** @scrutinizer ignore-unused */ &$logData)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
183
	{
184
		// This function should be implemented in the child class if needed
185
		// This method is not set as abstract because many of the payment gateways do not support/need it
186
	}
187
188
	/**
189
	 * Handle the refund of the payment
190
	 * This method tries to call Refund process on the Payment plugin
191
	 *
192
	 * @param   string  $extensionName  Name of the extension
193
	 * @param   string  $ownerName      Name of the owner
194
	 * @param   object  $data           Payment data
195
	 * @param   array   &$logData       Log data
196
	 * @param   bool    &$isRefunded    If process is successful then this flag should be true
197
	 *
198
	 * @return bool paid status
199
	 */
200
	public function handleRefundPayment($extensionName, $ownerName, $data, &$logData, &$isRefunded)
0 ignored issues
show
Unused Code introduced by
The parameter $data is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

200
	public function handleRefundPayment($extensionName, $ownerName, /** @scrutinizer ignore-unused */ $data, &$logData, &$isRefunded)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $extensionName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

200
	public function handleRefundPayment(/** @scrutinizer ignore-unused */ $extensionName, $ownerName, $data, &$logData, &$isRefunded)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $ownerName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

200
	public function handleRefundPayment($extensionName, /** @scrutinizer ignore-unused */ $ownerName, $data, &$logData, &$isRefunded)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
201
	{
202
		// This function should be implemented in the child class if needed
203
		// This method is not set as abstract because many of the payment gateways do not support it
204
		$logData['message_text'] = JText::sprintf('LIB_REDCORE_PAYMENT_LOG_METHOD_NOT_SUPPORTED', 'handleRefundPayment', $this->paymentName);
205
		$isRefunded = false;
206
207
		return false;
208
	}
209
210
	/**
211
	 * Handle the capture of the payment
212
	 * This method tries to call Capture process on the Payment plugin
213
	 *
214
	 * @param   string  $extensionName  Name of the extension
215
	 * @param   string  $ownerName      Name of the owner
216
	 * @param   object  $data           Payment data
217
	 * @param   array   &$logData       Log data
218
	 * @param   bool    &$isCaptured    If process is successful then this flag should be true
219
	 *
220
	 * @return bool paid status
221
	 */
222
	public function handleCapturePayment($extensionName, $ownerName, $data, &$logData, &$isCaptured)
0 ignored issues
show
Unused Code introduced by
The parameter $ownerName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

222
	public function handleCapturePayment($extensionName, /** @scrutinizer ignore-unused */ $ownerName, $data, &$logData, &$isCaptured)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $extensionName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

222
	public function handleCapturePayment(/** @scrutinizer ignore-unused */ $extensionName, $ownerName, $data, &$logData, &$isCaptured)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $data is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

222
	public function handleCapturePayment($extensionName, $ownerName, /** @scrutinizer ignore-unused */ $data, &$logData, &$isCaptured)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
223
	{
224
		// This function should be implemented in the child class if needed
225
		// This method is not set as abstract because many of the payment gateways do not support it
226
		$logData['message_text'] = JText::sprintf('LIB_REDCORE_PAYMENT_LOG_METHOD_NOT_SUPPORTED', 'handleCapturePayment', $this->paymentName);
227
		$isCaptured = false;
228
229
		return false;
230
	}
231
232
	/**
233
	 * Handle the deletion of the payment on Payment Gateway
234
	 * This method tries to call Delete process on the Payment plugin
235
	 *
236
	 * @param   string  $extensionName  Name of the extension
237
	 * @param   string  $ownerName      Name of the owner
238
	 * @param   object  $data           Payment data
239
	 * @param   array   &$logData       Log data
240
	 * @param   bool    &$isDeleted     If process is successful then this flag should be true
241
	 *
242
	 * @return bool paid status
243
	 */
244
	public function handleDeletePayment($extensionName, $ownerName, $data, &$logData, &$isDeleted)
0 ignored issues
show
Unused Code introduced by
The parameter $ownerName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

244
	public function handleDeletePayment($extensionName, /** @scrutinizer ignore-unused */ $ownerName, $data, &$logData, &$isDeleted)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $extensionName is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

244
	public function handleDeletePayment(/** @scrutinizer ignore-unused */ $extensionName, $ownerName, $data, &$logData, &$isDeleted)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $data is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

244
	public function handleDeletePayment($extensionName, $ownerName, /** @scrutinizer ignore-unused */ $data, &$logData, &$isDeleted)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
245
	{
246
		// This function should be implemented in the child class if needed
247
		// This method is not set as abstract because many of the payment gateways do not support it
248
		$logData['message_text'] = JText::sprintf('LIB_REDCORE_PAYMENT_LOG_METHOD_NOT_SUPPORTED', 'handleDeletePayment', $this->paymentName);
249
		$isDeleted = false;
250
251
		return false;
252
	}
253
254
	/**
255
	 * Check for new status change from Payment Gateway
256
	 *
257
	 * @param   int    $paymentId  Payment Id
258
	 * @param   array  &$status    Payment check status
259
	 *
260
	 * @return array
261
	 */
262
	public function handleCheckPayment($paymentId, &$status)
0 ignored issues
show
Unused Code introduced by
The parameter $paymentId is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

262
	public function handleCheckPayment(/** @scrutinizer ignore-unused */ $paymentId, &$status)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
263
	{
264
		$status = array(
265
			'message' => JText::sprintf('LIB_REDCORE_PAYMENT_ERROR_MANUAL_PAYMENT_CHECK_NOT_IMPLEMENTED', $this->paymentName),
266
			'type'    => 'error'
267
		);
268
	}
269
270
	/**
271
	 * Process data before outputting it to the form
272
	 *
273
	 * @param   string  $extensionName  Extension name
274
	 * @param   string  $ownerName      Owner name
275
	 * @param   array   $data           Data for the payment form
276
	 * @param   object  $payment        Payment object from saved payment table
277
	 *
278
	 * @return array on success
279
	 */
280
	public function preparePaymentSubmitData($extensionName, $ownerName, $data, $payment)
281
	{
282
		return $data;
283
	}
284
285
	/**
286
	 * Prepare data for omnipay from payment object
287
	 *
288
	 * @param   object  $payment  Payment object from saved payment table
289
	 *
290
	 * @return array
291
	 */
292
	public function prepareOmnipayData($payment)
293
	{
294
		$data = !is_array($payment) ? ArrayHelper::fromObject($payment) : $payment;
0 ignored issues
show
introduced by
The condition is_array($payment) is always false.
Loading history...
295
296
		$data['amount']     = $data['amount_total'];
297
		$data['transactionId'] = $data['transaction_id'];
298
		$data['returnUrl'] = $this->getResponseUrl($payment, 'callback');
299
		$data['cancelUrl'] = $this->getResponseUrl($payment, 'cancel');
300
301
		return $data;
302
	}
303
304
	/**
305
	 * Create new payment
306
	 *
307
	 * @param   string  $extensionName  Extension name
308
	 * @param   string  $ownerName      Owner name
309
	 * @param   array   $data           Data for the payment
310
	 *
311
	 * @return int|boolean Id of the payment or false
312
	 */
313
	public function createPayment($extensionName, $ownerName, $data)
314
	{
315
		// Is payment new
316
		$isNew = empty($data['id']);
317
318
		// Only calculate amount if set in provided data
319
		if (isset($data['calculate_total_amount_manually_redpayment']) && $data['calculate_total_amount_manually_redpayment'] === true)
320
		{
321
			// Calculate price
322
			$data['amount_total'] = (float) $data['amount_original'];
323
324
			// Add tax
325
			if (!empty($data['amount_order_tax']))
326
			{
327
				$data['amount_total'] += (float) $data['amount_order_tax'];
328
			}
329
330
			// Add shipping
331
			if (!empty($data['amount_shipping']))
332
			{
333
				$data['amount_total'] += (float) $data['amount_shipping'];
334
			}
335
336
			// Calculate payment fee
337
			$paymentFee = $this->getPaymentFee($data['amount_total'], $data['currency']);
338
			$data['amount_payment_fee'] = $paymentFee;
339
340
			$data['amount_total'] += $data['amount_payment_fee'];
341
		}
342
		elseif (empty($data['amount_total']) && isset($data['amount_original']))
343
		{
344
			$data['amount_total'] = (float) $data['amount_original'];
345
		}
346
347
		// Set cancel URL
348
		if (empty($data['url_cancel']))
349
		{
350
			$data['url_cancel'] = JUri::root() . 'index.php?option=' . $data['extension_name'];
351
		}
352
353
		// Set accept URL
354
		if (empty($data['url_accept']))
355
		{
356
			$data['url_accept'] = JUri::root() . 'index.php?option=' . $data['extension_name'];
357
		}
358
359
		// Set sandbox flag
360
		if (empty($data['sandbox']))
361
		{
362
			$data['sandbox'] = $this->params->get('sandbox', 0);
363
		}
364
365
		// Set order name
366
		if (empty($data['order_name']))
367
		{
368
			$data['order_name'] = $data['order_id'];
369
		}
370
371
		// Set payment name
372
		if (empty($data['payment_name']))
373
		{
374
			$data['payment_name'] = $this->paymentName;
375
		}
376
377
		// Set extension name
378
		if (empty($data['extension_name']))
379
		{
380
			$data['extension_name'] = $extensionName;
381
		}
382
383
		// Set owner name
384
		if (empty($data['owner_name']))
385
		{
386
			$data['owner_name'] = $ownerName;
387
		}
388
389
		// This field sets how many times does the plugin try to get response from Payment Gateway for the transaction status.
390
		if (!isset($data['retry_counter']))
391
		{
392
			$data['retry_counter'] = $this->params->get('retry_counter', RBootstrap::getConfig('payment_number_of_payment_check_retries', 30));
393
		}
394
395
		$paymentId = RApiPaymentHelper::updatePaymentData($data);
396
397
		if (empty($paymentId))
398
		{
399
			return false;
400
		}
401
402
		$data['id'] = $paymentId;
403
		$updateMainPaymentStatus = true;
404
405
		if (empty($data['payment_log']))
406
		{
407
			$paymentStatus = RApiPaymentStatus::getStatusCreated();
408
409
			if (!$isNew)
410
			{
411
				// If the payment not new and any other log not found, then current event must inherit the last payment status
412
				$prevLog = RApiPaymentHelper::getLastPaymentLog($paymentId);
0 ignored issues
show
Bug introduced by
$paymentId of type boolean is incompatible with the type integer expected by parameter $paymentId of RApiPaymentHelper::getLastPaymentLog(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

412
				$prevLog = RApiPaymentHelper::getLastPaymentLog(/** @scrutinizer ignore-type */ $paymentId);
Loading history...
413
414
				if ($prevLog)
0 ignored issues
show
introduced by
$prevLog is of type object, thus it always evaluated to true.
Loading history...
415
				{
416
					$paymentStatus = $prevLog->status;
417
					$updateMainPaymentStatus = false;
418
				}
419
			}
420
421
			$data['payment_log'] = RApiPaymentHelper::generatePaymentLog(
422
				$paymentStatus,
423
				$data,
424
				JText::sprintf('LIB_REDCORE_PAYMENT_LOG_' . ($isNew ? 'CREATE' : 'UPDATE') . '_MESSAGE', $data['extension_name'], $this->paymentName)
425
			);
426
		}
427
428
		RApiPaymentHelper::saveNewPaymentLog($data['payment_log'], $updateMainPaymentStatus);
429
430
		return $paymentId;
431
	}
432
433
	/**
434
	 * Returns details about the payment
435
	 *
436
	 * @param   string  $extensionName  Extension name (ex: com_content)
437
	 * @param   array   $orderData      Extension Order data
438
	 *
439
	 * @return object
440
	 */
441
	protected function getPaymentByExtensionOrderData($extensionName, $orderData)
442
	{
443
		$orderId = empty($orderData['order_id']) ? $orderData['id'] : $orderData['order_id'];
444
		$payment = RApiPaymentHelper::getPaymentByExtensionId($extensionName, $orderId);
445
		$restrictedData = array(
446
			'id', 'extension_name', 'payment_name', 'sandbox', 'created_date', 'modified_date', 'confirmed_date', 'transaction_id',
447
			'amount_paid', 'coupon_code', 'customer_note', 'status'
448
		);
449
450
		if (!$payment)
0 ignored issues
show
introduced by
$payment is of type object, thus it always evaluated to true.
Loading history...
451
		{
452
			array_push($restrictedData, 'amount_total');
453
454
			$ownerName = !empty($orderData['owner_name']) ? $orderData['owner_name'] : '';
455
			$createData = array();
456
457
			foreach ($orderData as $key => $value)
458
			{
459
				if (!in_array($key, $restrictedData))
460
				{
461
					$createData[$key] = $orderData[$key];
462
				}
463
			}
464
465
			// Create new payment based on order data
466
			$this->createPayment($extensionName, $ownerName, $createData);
467
468
			$payment = RApiPaymentHelper::getPaymentByExtensionId($extensionName, $orderId);
469
		}
470
		else
471
		{
472
			array_push($restrictedData, 'amount_original');
473
474
			// We will update payment with provided data if it is different than originally provided
475
			$ownerName = !empty($orderData['owner_name']) ? $orderData['owner_name'] : $payment->owner_name;
476
			$updateData = ArrayHelper::fromObject($payment);
477
478
			foreach ($orderData as $key => $value)
479
			{
480
				if (!in_array($key, $restrictedData))
481
				{
482
					$updateData[$key] = $orderData[$key];
483
				}
484
			}
485
486
			// Create new payment based on order data
487
			$this->createPayment($extensionName, $ownerName, $updateData);
488
		}
489
490
		return $payment;
491
	}
492
493
	/**
494
	 * Gets request method as it is defined in plugin, some servers do not support specific request methods
495
	 *
496
	 * @return string
497
	 */
498
	public function getRequestMethod()
499
	{
500
		// If defined on a level of the payment plugin (no alternative methods but use specific one)
501
		if (!empty($this->requestMethod))
0 ignored issues
show
Bug introduced by
The property requestMethod does not exist on RApiPaymentPluginHelperPayment. Did you mean requestPath?
Loading history...
502
		{
503
			return $this->requestMethod;
504
		}
505
		// If defined in payment plugin parameters we use this one then
506
		elseif ($this->params->get('payment_request_method', null) !== null)
507
		{
508
			return $this->params->get('payment_request_method', 'curl');
509
		}
510
511
		// If no alternative, we use global settings for request method
512
		return RBootstrap::getConfig('payment_request_method', 'curl');
513
	}
514
515
	/**
516
	 * Gets the form action URL for the payment
517
	 *
518
	 * @return string
519
	 */
520
	protected function getPaymentURL()
521
	{
522
		$sandbox = $this->params->get('sandbox', 0);
523
524
		if ($sandbox && !empty($this->paymentUrlSandbox))
525
		{
526
			return $this->paymentUrlSandbox . $this->requestPathSandbox;
527
		}
528
		else
529
		{
530
			return $this->paymentUrl . $this->requestPath;
531
		}
532
	}
533
534
	/**
535
	 * Gets the Merchant ID (usually the email address)
536
	 *
537
	 * @return string
538
	 */
539
	protected function getMerchantID()
540
	{
541
		$sandbox = $this->params->get('sandbox', 0);
542
543
		if ($sandbox && $this->params->get('merchant_id_sandbox', ''))
544
		{
545
			return $this->params->get('merchant_id_sandbox', '');
546
		}
547
		else
548
		{
549
			return $this->params->get('merchant_id', '');
550
		}
551
	}
552
553
	/**
554
	 * Gets the URL for Payment api
555
	 *
556
	 * @param   object  $payment  Payment data
557
	 *
558
	 * @return string
559
	 */
560
	protected function getPaymentApiUrl($payment)
561
	{
562
		return JUri::root()
563
			. 'index.php?option=com_redcore&api=payment'
564
			. '&payment_id=' . $payment->id
565
			. '&order_id=' . $payment->order_id
566
			. '&payment_name=' . $payment->payment_name
567
			. '&owner_name=' . $payment->owner_name
568
			. '&extension_name=' . $payment->extension_name;
569
	}
570
571
	/**
572
	 * returns state uri object (notify, cancel, etc...)
573
	 *
574
	 * @param   object  $payment  Payment data
575
	 * @param   string  $state    The state for the url
576
	 *
577
	 * @return string
578
	 */
579
	protected function getResponseUrl($payment, $state)
580
	{
581
		$uri = $this->getPaymentApiUrl($payment);
582
583
		switch ($state)
584
		{
585
			case 'cancel':
586
				$uri .= '&task=cancel';
587
				break;
588
			case 'accept':
589
				$uri .= '&task=accept';
590
				break;
591
			case 'process':
592
				$uri .= '&task=process';
593
				break;
594
			case 'callback':
595
				$uri .= '&task=callback';
596
				break;
597
			default:
598
				$uri .= '&task=callback';
599
				break;
600
		}
601
602
		return $uri;
603
	}
604
605
	/**
606
	 * Check for notifications from Payment Gateway
607
	 *
608
	 * @param   string  $data  Data to post
609
	 *
610
	 * @return string
611
	 */
612
	public function getRequestFromGateway($data = '')
613
	{
614
615
		if ($this->getRequestMethod() == 'fsockopen')
616
		{
617
			if ($this->params->get('sandbox', 0) && !empty($this->paymentUrlSandbox))
618
			{
619
				$requestPath = $this->requestPathSandbox;
620
				$paymentUrl = $this->paymentUrlSandbox;
621
			}
622
			else
623
			{
624
				$requestPath = $this->requestPath;
625
				$paymentUrl = $this->paymentUrl;
626
			}
627
628
			$http_request  = "POST $requestPath HTTP/1.0\r\n";
629
			$http_request .= "Host: $paymentUrl\r\n";
630
			$http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
631
			$http_request .= "Content-Length: " . strlen($data) . "\r\n";
632
			$http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
633
			$http_request .= "\r\n";
634
			$http_request .= $data;
635
636
			$response = '';
637
638
			if (($fs = @fsockopen($paymentUrl, $this->fsockPort, $errno, $errstr, 10)) == false )
0 ignored issues
show
Bug introduced by
$this->fsockPort of type string is incompatible with the type integer expected by parameter $port of fsockopen(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

638
			if (($fs = @fsockopen($paymentUrl, /** @scrutinizer ignore-type */ $this->fsockPort, $errno, $errstr, 10)) == false )
Loading history...
639
			{
640
				JFactory::getApplication()->enqueueMessage('LIB_REDCORE_PAYMENT_ERROR_FSOCK_COULD_NOT_OPEN', 'error');
641
642
				return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type string.
Loading history...
643
			}
644
645
			fwrite($fs, $http_request);
646
647
			while (!feof($fs))
648
			{
649
				// One TCP-IP packet
650
				$response .= fgets($fs, 1160);
651
			}
652
653
			fclose($fs);
654
		}
655
		else
656
		{
657
			$ch = curl_init();
658
			curl_setopt($ch, CURLOPT_URL, $this->getPaymentURL());
659
			curl_setopt($ch, CURLOPT_POST, 1);
660
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
661
			curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
662
			curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
663
			curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
664
665
			$response = curl_exec($ch);
666
			curl_close($ch);
667
		}
668
669
		return $response;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $response also could return the type true which is incompatible with the documented return type string.
Loading history...
670
	}
671
672
	/**
673
	 * Check if we can use this plugin for given currency
674
	 *
675
	 * @param   string  $currencyCode  3 letters iso code
676
	 *
677
	 * @return true if plugin supports this currency
678
	 */
679
	public function currencyIsAllowed($currencyCode)
680
	{
681
		$allowed = trim($this->params->get('allowed_currencies'));
682
683
		if (!$allowed) // Allow everything
684
		{
685
			return true;
686
		}
687
688
		// Otherwise returns only currencies specified in allowed_currencies plugin parameters
689
		$allowed = explode(',', $allowed);
690
		$allowed = array_map('trim', $allowed);
691
692
		if (!in_array($currencyCode, $allowed))
693
		{
694
			return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type true.
Loading history...
695
		}
696
697
		return true;
698
	}
699
700
	/**
701
	 * Check if the currency is supported by the gateway (otherwise might require conversion)
702
	 *
703
	 * @param   string  $currencyCode  3 letters iso code
704
	 *
705
	 * @return true if currency is supported
706
	 */
707
	protected function currencyIsSupported($currencyCode)
0 ignored issues
show
Unused Code introduced by
The parameter $currencyCode is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

707
	protected function currencyIsSupported(/** @scrutinizer ignore-unused */ $currencyCode)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
708
	{
709
		return true;
710
	}
711
712
	/**
713
	 * Convert price to another currency @todo Bring the logic from redshop to a plugin maybe?
714
	 *
715
	 * @param   float   $price         price to convert
716
	 * @param   string  $currencyFrom  currency to convert from
717
	 * @param   string  $currencyTo    currency to convert to
718
	 *
719
	 * @return float converted price
720
	 */
721
	protected function convertPrice($price, $currencyFrom, $currencyTo)
722
	{
723
		JPluginHelper::importPlugin('currencyconverter');
724
725
		$result = false;
726
		JFactory::getApplication()->triggerEvent('onCurrencyConvert', array($price, $currencyFrom, $currencyTo, &$result));
727
728
		return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result returns the type false which is incompatible with the documented return type double.
Loading history...
729
	}
730
731
	/**
732
	 * Display or redirect to the payment page for the gateway
733
	 *
734
	 * @param   string  $extensionName  Extension name
735
	 * @param   string  $ownerName      Owner name
736
	 * @param   array   $data           Data for the payment form
737
	 * @param   string  &$html          Html output
738
	 *
739
	 * @return string
740
	 */
741
	public function displayPayment($extensionName, $ownerName, $data, &$html)
742
	{
743
		if (is_object($data))
0 ignored issues
show
introduced by
The condition is_object($data) is always false.
Loading history...
744
		{
745
			$data = ArrayHelper::fromObject($data);
746
		}
747
748
		if (empty($data['order_id']))
749
		{
750
			JFactory::getApplication()->enqueueMessage(JText::sprintf('LIB_REDCORE_PAYMENT_ERROR_ORDER_ID_NOT_PROVIDED', $this->paymentName), 'error');
751
		}
752
753
		$payment = $this->getPaymentByExtensionOrderData($extensionName, $data);
754
755
		if (!isset($data['hiddenFields']))
756
		{
757
			// Prepare the data
758
			$data['hiddenFields'] = $this->preparePaymentSubmitData($extensionName, $ownerName, $data, $payment);
759
		}
760
761
		// Handle shipping data @todo we will insert static method here to call up shipping api
762
		JPluginHelper::importPlugin('redshipping');
763
		JFactory::getApplication()->triggerEvent('onRedshippingPrepareSubmitData', array($extensionName, $ownerName, &$data, $payment));
764
765
		$paths = $this->getPaymentLayoutPaths($extensionName);
766
767
		$fullPath = JPath::find($paths, 'form/form.php');
768
769
		$displayData = array(
770
			'options' => array(
771
				'paymentData'   => $data,
772
				'extensionName' => $extensionName,
773
				'ownerName'     => $ownerName,
774
				'paymentName'   => $this->paymentName,
775
				'paymentTitle'  => $this->params->get('payment_title', $this->paymentName),
776
				'action'        => $this->getPaymentURL(),
777
				'autoSubmit'    => isset($data['autoSubmit']) ? $data['autoSubmit'] : $this->autoSubmit,
778
				'params'        => $this->params,
779
				'payment'       => $payment,
780
				'formName'      => 'redpaymentForm' . $payment->id,
781
			)
782
		);
783
784
		$html .= $this->renderLayout($fullPath, $displayData);
0 ignored issues
show
Bug introduced by
It seems like $fullPath can also be of type false; however, parameter $path of RApiPaymentPluginHelperPayment::renderLayout() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

784
		$html .= $this->renderLayout(/** @scrutinizer ignore-type */ $fullPath, $displayData);
Loading history...
785
786
		return $html;
787
	}
788
789
	/**
790
	 * Get layout paths including plugin path and path to template. We are not using JLayouts because they do not support plugin layouts auto find
791
	 *
792
	 * @param   string  $extensionName  Extension name
793
	 *
794
	 * @return  array
795
	 */
796
	protected function getPaymentLayoutPaths($extensionName)
797
	{
798
		$app = JFactory::getApplication();
799
		$paths = array();
800
801
		// Extension Template override
802
		$paths[] = JPATH_THEMES . '/' . $app->getTemplate() . '/html/layouts/' . $extensionName . '/plugins/redpayment/' . $this->paymentName;
803
804
		// Plugin Template override
805
		$paths[] = JPATH_ROOT . '/templates/' . $app->getTemplate() . '/html/layouts/plugins/redpayment/' . $this->paymentName;
806
807
		// Extension override
808
		$paths[] = JPATH_SITE . '/components/' . $extensionName . '/layouts/plugins/redpayment/' . $this->paymentName;
809
810
		// Root Joomla override
811
		$paths[] = JPATH_ROOT . '/layouts/plugins/redpayment/' . $this->paymentName;
812
813
		// Current Plugin
814
		$paths[] = JPATH_PLUGINS . '/redpayment/' . $this->paymentName;
815
816
		// If not found plugin then use default layout
817
		$paths[] = JPATH_LIBRARIES . '/redcore/layouts/redpayment';
818
819
		return $paths;
820
	}
821
822
	/**
823
	 * Method to render the layout.
824
	 *
825
	 * @param   string  $path         Path to the layout file
826
	 * @param   array   $displayData  Object which properties are used inside the layout file to build displayed output
827
	 *
828
	 * @return  string  The necessary HTML to display the layout
829
	 *
830
	 * @since   1.0
831
	 */
832
	protected function renderLayout($path, $displayData)
833
	{
834
		$layoutOutput = '';
835
836
		// If there exists such a layout file, include it and collect its output
837
		if (!empty($path))
838
		{
839
			ob_start();
840
			include $path;
841
			$layoutOutput = ob_get_contents();
842
			ob_end_clean();
843
		}
844
845
		return $layoutOutput;
846
	}
847
848
	/**
849
	 * Calculates fee based on given amount and currency
850
	 *
851
	 * @param   float   $amount    Amount to calculate fee
852
	 * @param   string  $currency  Iso 4217 3 letters currency code
853
	 *
854
	 * @return float
855
	 */
856
	public function getPaymentFee($amount, $currency = '')
0 ignored issues
show
Unused Code introduced by
The parameter $currency is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

856
	public function getPaymentFee($amount, /** @scrutinizer ignore-unused */ $currency = '')

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
857
	{
858
		$paymentFee = $this->params->get('payment_fee', 0);
859
		$paymentFeeType = $this->params->get('payment_fee_type', $this->paymentFeeType);
860
861
		if (strpos($paymentFee, '%') === false || $paymentFee == 0)
862
		{
863
			return (float) $paymentFee;
864
		}
865
866
		$paymentFee = (float) $paymentFee;
867
868
		if ($paymentFeeType == 'add')
869
		{
870
			// Adds a percentage based fee to the total amount
871
			$fee = $amount * ($paymentFee / 100);
872
		}
873
		else
874
		{
875
			// The fee is calculated as a commission rate
876
			$fee = ($amount / (1 - ($paymentFee / 100))) - $amount;
877
		}
878
879
		return $fee;
880
	}
881
882
	/**
883
	 * Load omnipay library and this payment gateway classes if needed
884
	 *
885
	 * @return boolean
886
	 */
887
	public function loadOmnipay()
888
	{
889
		// Load omnipay libraries
890
		$omnipayLibraries = JPATH_LIBRARIES . '/redpayment_omnipay/vendor/autoload.php';
891
892
		if (!file_exists($omnipayLibraries))
893
		{
894
			return false;
895
		}
896
897
		$loader = require $omnipayLibraries;
898
899
		// If custom class path is set we will load additional classes for omnipay
900
		if (!empty($this->omnipayCustomClassPath))
901
		{
902
			$map = array(
903
				'Omnipay\\' . $this->omnipayGatewayName . '\\' => array($this->omnipayCustomClassPath),
904
			);
905
906
			foreach ($map as $namespace => $path)
907
			{
908
				$loader->setPsr4($namespace, $path);
909
			}
910
911
			$loader->register(true);
912
		}
913
914
		return true;
915
	}
916
917
	/**
918
	 * Get the payment amount as an integer.
919
	 *
920
	 * @param   float   $amount    Amount
921
	 * @param   string  $currency  Iso 4217 3 letters currency code
922
	 *
923
	 * @return integer
924
	 */
925
	public function getAmountInteger($amount, $currency)
926
	{
927
		return (int) round($amount * pow(10, RHelperCurrency::getPrecision($currency)));
928
	}
929
930
	/**
931
	 * Get the payment amount as an float.
932
	 *
933
	 * @param   int     $amount    Amount
934
	 * @param   string  $currency  Iso 4217 3 letters currency code
935
	 *
936
	 * @return float
937
	 */
938
	public function getAmountToFloat($amount, $currency)
939
	{
940
		return (float) round($amount / pow(10, RHelperCurrency::getPrecision($currency)));
941
	}
942
}
943