Issues (850)

Security Analysis    4 potential vulnerabilities

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Code Injection (1)
Code Injection enables an attacker to execute arbitrary code on the server.
  Variable Injection (2)
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Cross-Site Scripting (1)
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  Header Injection
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

class-getpaid-paypal-gateway-ipn-handler.php (7 issues)

Labels
Severity
1
<?php
2
/**
3
 * Paypal payment gateway IPN handler
4
 *
5
 */
6
7
defined( 'ABSPATH' ) || exit;
8
9
/**
10
 * Paypal Payment Gateway IPN handler class.
11
 *
12
 */
13
class GetPaid_Paypal_Gateway_IPN_Handler {
14
15
	/**
16
	 * Payment method id.
17
	 *
18
	 * @var string
19
	 */
20
	protected $id = 'paypal';
21
22
	/**
23
	 * Payment method object.
24
	 *
25
	 * @var GetPaid_Paypal_Gateway
26
	 */
27
	protected $gateway;
28
29
	/**
30
	 * Class constructor.
31
	 *
32
	 * @param GetPaid_Paypal_Gateway $gateway
33
	 */
34
	public function __construct( $gateway ) {
35
		$this->gateway = $gateway;
36
		$this->verify_ipn();
37
	}
38
39
	/**
40
	 * Processes ipns and marks payments as complete.
41
	 *
42
	 * @return void
43
	 */
44
	public function verify_ipn() {
45
46
		wpinv_error_log( 'GetPaid PayPal IPN Handler', false );
47
48
		// Validate the IPN.
49
		if ( empty( $_POST ) || ! $this->validate_ipn() ) {
50
			wp_die( 'PayPal IPN Request Failure', 500 );
51
		}
52
53
		// Process the IPN.
54
		$posted  = wp_unslash( $_POST );
55
		$invoice = $this->get_ipn_invoice( $posted );
56
57
		// Abort if it was not paid by our gateway.
58
		if ( $this->id != $invoice->get_gateway() ) {
59
			wpinv_error_log( 'Aborting, Invoice was not paid via PayPal', false );
60
			wp_die( 'Invoice not paid via PayPal', 200 );
61
		}
62
63
		$posted['payment_status'] = isset( $posted['payment_status'] ) ? sanitize_key( strtolower( $posted['payment_status'] ) ) : '';
64
		$posted['txn_type']       = sanitize_key( strtolower( $posted['txn_type'] ) );
65
66
		wpinv_error_log( 'Payment status:' . $posted['payment_status'], false );
67
		wpinv_error_log( 'IPN Type:' . $posted['txn_type'], false );
68
69
		if ( method_exists( $this, 'ipn_txn_' . $posted['txn_type'] ) ) {
70
			call_user_func( array( $this, 'ipn_txn_' . $posted['txn_type'] ), $invoice, $posted );
71
			wpinv_error_log( 'Done processing IPN', false );
72
			wp_die( 'Processed', 200 );
73
		}
74
75
		wpinv_error_log( 'Aborting, Unsupported IPN type:' . $posted['txn_type'], false );
76
		wp_die( 'Unsupported IPN type', 200 );
77
78
	}
79
80
	/**
81
	 * Retrieves IPN Invoice.
82
	 *
83
	 * @param array $posted
84
	 * @return WPInv_Invoice
85
	 */
86
	protected function get_ipn_invoice( $posted ) {
87
88
		wpinv_error_log( 'Retrieving PayPal IPN Response Invoice', false );
89
90
		if ( ! empty( $posted['custom'] ) ) {
91
			$invoice = new WPInv_Invoice( $posted['custom'] );
92
93
			if ( $invoice->exists() ) {
94
				wpinv_error_log( 'Found invoice #' . $invoice->get_number(), false );
95
				return $invoice;
96
			}
97
		}
98
99
		wpinv_error_log( 'Could not retrieve the associated invoice.', false );
100
		wp_die( 'Could not retrieve the associated invoice.', 200 );
101
	}
102
103
	/**
104
	 * Check PayPal IPN validity.
105
	 */
106
	protected function validate_ipn() {
107
108
		wpinv_error_log( 'Validating PayPal IPN response', false );
109
110
		// Retrieve the associated invoice.
111
		$posted  = wp_unslash( $_POST );
112
		$invoice = $this->get_ipn_invoice( $posted );
113
114
		if ( $this->gateway->is_sandbox( $invoice ) ) {
115
			wpinv_error_log( $posted, 'Invoice was processed in sandbox hence logging the posted data', false );
116
		}
117
118
		// Validate the IPN.
119
		$posted['cmd'] = '_notify-validate';
120
121
		// Send back post vars to paypal.
122
		$params = array(
123
			'body'        => $posted,
124
			'timeout'     => 60,
125
			'httpversion' => '1.1',
126
			'compress'    => false,
127
			'decompress'  => false,
128
			'user-agent'  => 'GetPaid/' . WPINV_VERSION,
129
		);
130
131
		// Post back to get a response.
132
		$response = wp_safe_remote_post( $this->gateway->is_sandbox( $invoice ) ? 'https://www.sandbox.paypal.com/cgi-bin/webscr' : 'https://www.paypal.com/cgi-bin/webscr', $params );
133
134
		// Check to see if the request was valid.
135
		if ( ! is_wp_error( $response ) && $response['response']['code'] < 300 && strstr( $response['body'], 'VERIFIED' ) ) {
136
			$invoice->add_note( 'Received valid response from PayPal IPN: ' . $response['body'], false, false, true );
137
			wpinv_error_log( 'Received valid response from PayPal IPN: ' . $response['body'], false );
138
			return true;
139
		}
140
141
		$invoice->add_note( 'IPN message:' . wp_json_encode( $posted ), false, false, true );
142
143
		if ( is_wp_error( $response ) ) {
144
			$invoice->add_note( 'Received invalid response from PayPal IPN: ' . $response->get_error_message(), false, false, true );
145
			wpinv_error_log( $response->get_error_message(), 'Received invalid response from PayPal IPN' );
146
			return false;
147
		}
148
149
		$invoice->add_note( 'Received invalid response from PayPal IPN: ' . $response['body'], false, false, true );
150
		wpinv_error_log( $response['body'], 'Received invalid response from PayPal IPN' );
151
		return false;
152
153
	}
154
155
	/**
156
	 * Check currency from IPN matches the invoice.
157
	 *
158
	 * @param WPInv_Invoice $invoice          Invoice object.
159
	 * @param string   $currency currency to validate.
160
	 */
161
	protected function validate_ipn_currency( $invoice, $currency ) {
162
163
		if ( strtolower( $invoice->get_currency() ) !== strtolower( $currency ) ) {
164
165
			/* translators: %s: currency code. */
166
			$invoice->update_status( 'wpi-processing', wp_sprintf( __( 'Validation error: PayPal currencies do not match (code %s).', 'invoicing' ), $currency ) );
167
			$invoice->add_note( wp_sprintf( __( 'Validation error: PayPal currencies do not match (code %s).', 'invoicing' ), $currency ), false, false, true );
168
169
			wpinv_error_log( "Currencies do not match: {$currency} instead of {$invoice->get_currency()}", 'IPN Error', __FILE__, __LINE__, true );
170
		}
171
172
		wpinv_error_log( $currency, 'Validated IPN Currency', false );
0 ignored issues
show
false of type false is incompatible with the type string expected by parameter $file of wpinv_error_log(). ( Ignorable by Annotation )

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

172
		wpinv_error_log( $currency, 'Validated IPN Currency', /** @scrutinizer ignore-type */ false );
Loading history...
173
	}
174
175
	/**
176
	 * Check payment amount from IPN matches the invoice.
177
	 *
178
	 * @param WPInv_Invoice $invoice          Invoice object.
179
	 * @param float   $amount amount to validate.
180
	 */
181
	protected function validate_ipn_amount( $invoice, $amount ) {
182
		if ( number_format( $invoice->get_total(), 2, '.', '' ) !== number_format( $amount, 2, '.', '' ) ) {
183
184
			/* translators: %s: Amount. */
185
			$invoice->update_status( 'wpi-processing', wp_sprintf( __( 'Validation error: PayPal amounts do not match (gross %s).', 'invoicing' ), $amount ) );
186
			$invoice->add_note( wp_sprintf( __( 'Validation error: PayPal amounts do not match (gross %s).', 'invoicing' ), $amount ), false, false, true );
187
188
			wpinv_error_log( "Amounts do not match: {$amount} instead of {$invoice->get_total()}", 'IPN Error', __FILE__, __LINE__, true );
189
		}
190
191
		wpinv_error_log( $amount, 'Validated IPN Amount', false );
0 ignored issues
show
false of type false is incompatible with the type string expected by parameter $file of wpinv_error_log(). ( Ignorable by Annotation )

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

191
		wpinv_error_log( $amount, 'Validated IPN Amount', /** @scrutinizer ignore-type */ false );
Loading history...
192
	}
193
194
	/**
195
	 * Verify receiver email from PayPal.
196
	 *
197
	 * @param WPInv_Invoice $invoice          Invoice object.
198
	 * @param string   $receiver_email Email to validate.
199
	 */
200
	protected function validate_ipn_receiver_email( $invoice, $receiver_email ) {
201
		$paypal_email = $this->gateway->is_sandbox( $invoice ) ? wpinv_get_option( 'paypal_sandbox_email', wpinv_get_option( 'paypal_email', '' ) ) : wpinv_get_option( 'paypal_email', '' );
202
203
		if ( $receiver_email && strcasecmp( trim( $receiver_email ), trim( $paypal_email ) ) !== 0 ) {
204
			wpinv_record_gateway_error( 'IPN Error', "IPN Response is for another account: {$receiver_email}. Your PayPal email is {$paypal_email}." );
205
206
			/* translators: %s: email address . */
207
			$invoice->update_status( 'wpi-processing', wp_sprintf( __( 'Validation error: PayPal IPN response from a different email address (%s). Your PayPal email is %s.', 'invoicing' ), $receiver_email, $paypal_email ) );
208
			$invoice->add_note( wp_sprintf( __( 'Validation error: PayPal IPN response from a different email address (%s). Your PayPal email is %s.', 'invoicing' ), $receiver_email, $paypal_email ), false, false, true );
209
210
			return wpinv_error_log( "IPN Response is for another account: {$receiver_email}. Your email PayPal is {$paypal_email}.", 'IPN Error', __FILE__, __LINE__, true );
211
		}
212
213
		wpinv_error_log( 'Validated PayPal Email', false );
214
	}
215
216
	/**
217
	 * Handles one time payments.
218
	 *
219
	 * @param WPInv_Invoice $invoice  Invoice object.
220
	 * @param array    $posted Posted data.
221
	 */
222
	protected function ipn_txn_web_accept( $invoice, $posted ) {
223
224
		// Collect payment details
225
		$payment_status = strtolower( $posted['payment_status'] );
226
		$business_email = isset( $posted['business'] ) && is_email( $posted['business'] ) ? trim( $posted['business'] ) : trim( $posted['receiver_email'] );
227
228
		$this->validate_ipn_receiver_email( $invoice, $business_email );
229
		$this->validate_ipn_currency( $invoice, $posted['mc_currency'] );
230
231
		// Update the transaction id.
232
		if ( ! empty( $posted['txn_id'] ) ) {
233
			$invoice->set_transaction_id( wpinv_clean( $posted['txn_id'] ) );
234
			$invoice->save();
235
		}
236
237
		$invoice->add_system_note( __( 'Processing invoice IPN', 'invoicing' ) );
238
239
		// Process a refund.
240
		if ( 'refunded' === $payment_status || 'reversed' === $payment_status ) {
241
242
			update_post_meta( $invoice->get_id(), 'refunded_remotely', 1 );
243
244
			if ( ! $invoice->is_refunded() ) {
245
				$invoice->update_status( 'wpi-refunded', $posted['reason_code'] );
246
			}
247
248
			return wpinv_error_log( $posted['reason_code'], false );
249
		}
250
251
		// Process payments.
252
		if ( 'completed' === $payment_status ) {
253
254
			if ( $invoice->is_paid() && 'wpi_processing' != $invoice->get_status() ) {
255
				return wpinv_error_log( 'Aborting, Invoice #' . $invoice->get_number() . ' is already paid.', false );
256
			}
257
258
			$this->validate_ipn_amount( $invoice, $posted['mc_gross'] );
259
260
			$note = '';
261
262
			if ( ! empty( $posted['mc_fee'] ) ) {
263
				$note = sprintf( __( 'PayPal Transaction Fee %s.', 'invoicing' ), sanitize_text_field( $posted['mc_fee'] ) );
264
			}
265
266
			if ( ! empty( $posted['payer_status'] ) ) {
267
				$note = ' ' . sprintf( __( 'Buyer status %s.', 'invoicing' ), sanitize_text_field( $posted['payer_status'] ) );
268
			}
269
270
			$invoice->mark_paid( ( ! empty( $posted['txn_id'] ) ? sanitize_text_field( $posted['txn_id'] ) : '' ), trim( $note ) );
271
			return wpinv_error_log( 'Invoice marked as paid.', false );
272
273
		}
274
275
		// Pending payments.
276
		if ( 'pending' === $payment_status ) {
277
278
			/* translators: %s: pending reason. */
279
			$invoice->update_status( 'wpi-onhold', wp_sprintf( __( 'Payment pending (%s).', 'invoicing' ), $posted['pending_reason'] ) );
280
			$invoice->add_note( wp_sprintf( __( 'Payment pending (%s).', 'invoicing' ), $posted['pending_reason'] ), false, false, true );
281
282
			return wpinv_error_log( 'Invoice marked as "payment held".', false );
283
		}
284
285
		/* translators: %s: payment status. */
286
		$invoice->update_status( 'wpi-failed', sprintf( __( 'Payment %s via IPN.', 'invoicing' ), sanitize_text_field( $posted['payment_status'] ) ) );
287
288
	}
289
290
	/**
291
	 * Handles one time payments.
292
	 *
293
	 * @param WPInv_Invoice $invoice  Invoice object.
294
	 * @param array    $posted Posted data.
295
	 */
296
	protected function ipn_txn_cart( $invoice, $posted ) {
297
		$this->ipn_txn_web_accept( $invoice, $posted );
298
	}
299
300
	/**
301
	 * Handles subscription sign ups.
302
	 *
303
	 * @param WPInv_Invoice $invoice  Invoice object.
304
	 * @param array    $posted Posted data.
305
	 */
306
	protected function ipn_txn_subscr_signup( $invoice, $posted ) {
307
308
		wpinv_error_log( 'Processing subscription signup', false );
309
310
		// Make sure the invoice has a subscription.
311
		$subscription = getpaid_get_invoice_subscription( $invoice );
312
313
		if ( empty( $subscription ) ) {
314
			return wpinv_error_log( 'Aborting, Subscription for the invoice ' . $invoice->get_id() . ' not found', false );
315
		}
316
317
		wpinv_error_log( 'Found subscription #' . $subscription->get_id(), false );
318
319
		// Validate the IPN.
320
		$business_email = isset( $posted['business'] ) && is_email( $posted['business'] ) ? trim( $posted['business'] ) : trim( $posted['receiver_email'] );
321
		$this->validate_ipn_receiver_email( $invoice, $business_email );
322
		$this->validate_ipn_currency( $invoice, $posted['mc_currency'] );
323
324
		// Activate the subscription.
325
		$duration = strtotime( $subscription->get_expiration() ) - strtotime( $subscription->get_date_created() );
326
		$subscription->set_date_created( current_time( 'mysql' ) );
327
		$subscription->set_expiration( date( 'Y-m-d H:i:s', ( current_time( 'timestamp' ) + $duration ) ) );
328
		$subscription->set_profile_id( sanitize_text_field( $posted['subscr_id'] ) );
329
		$subscription->activate();
330
331
		// Set the transaction id.
332
		if ( ! empty( $posted['txn_id'] ) ) {
333
			$invoice->add_note( sprintf( __( 'PayPal Transaction ID: %s', 'invoicing' ), $posted['txn_id'] ), false, false, true );
334
			$invoice->set_transaction_id( $posted['txn_id'] );
335
		}
336
337
		// Update the payment status.
338
		$invoice->mark_paid();
339
340
		$invoice->add_note( sprintf( __( 'PayPal Subscription ID: %s', 'invoicing' ), $posted['subscr_id'] ), false, false, true );
341
342
		wpinv_error_log( 'Subscription started.', false );
343
	}
344
345
	/**
346
	 * Handles subscription renewals.
347
	 *
348
	 * @param WPInv_Invoice $invoice  Invoice object.
349
	 * @param array    $posted Posted data.
350
	 */
351
	protected function ipn_txn_subscr_payment( $invoice, $posted ) {
352
353
		// Make sure the invoice has a subscription.
354
		$subscription = getpaid_subscriptions()->get_invoice_subscription( $invoice );
355
356
		if ( empty( $subscription ) ) {
357
			return wpinv_error_log( 'Aborting, Subscription for the invoice ' . $invoice->get_id() . ' not found', false );
0 ignored issues
show
Are you sure the usage of wpinv_error_log('Abortin... . ' not found', false) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
358
		}
359
360
		wpinv_error_log( 'Found subscription #' . $subscription->get_id(), false );
361
362
		// PayPal sends a subscr_payment for the first payment too.
363
		$date_completed = getpaid_format_date( $invoice->get_date_completed() );
364
		$date_created   = getpaid_format_date( $invoice->get_date_created() );
365
		$today_date     = getpaid_format_date( current_time( 'mysql' ) );
366
		$payment_date   = getpaid_format_date( $posted['payment_date'] );
367
		$subscribe_date = getpaid_format_date( $subscription->get_date_created() );
368
		$dates          = array_filter( compact( 'date_completed', 'date_created', 'subscribe_date' ) );
369
370
		foreach ( $dates as $date ) {
371
372
			if ( $date !== $today_date && $date !== $payment_date ) {
373
				continue;
374
			}
375
376
			if ( ! empty( $posted['txn_id'] ) ) {
377
				$invoice->set_transaction_id( sanitize_text_field( $posted['txn_id'] ) );
378
				$invoice->add_note( wp_sprintf( __( 'PayPal Transaction ID: %s', 'invoicing' ), sanitize_text_field( $posted['txn_id'] ) ), false, false, true );
379
			}
380
381
			return $invoice->mark_paid();
382
383
		}
384
385
		wpinv_error_log( 'Processing subscription renewal payment for the invoice ' . $invoice->get_id(), false );
386
387
		// Abort if the payment is already recorded.
388
		if ( wpinv_get_id_by_transaction_id( $posted['txn_id'] ) ) {
389
			return wpinv_error_log( 'Aborting, Transaction ' . $posted['txn_id'] . ' has already been processed', false );
390
		}
391
392
		$args = array(
393
			'transaction_id' => $posted['txn_id'],
394
			'gateway'        => $this->id,
395
		);
396
397
		$invoice = wpinv_get_invoice( $subscription->add_payment( $args ) );
398
399
		if ( empty( $invoice ) ) {
400
			return;
401
		}
402
403
		$invoice->add_note( wp_sprintf( __( 'PayPal Transaction ID: %s', 'invoicing' ), $posted['txn_id'] ), false, false, true );
404
		$invoice->add_note( wp_sprintf( __( 'PayPal Subscription ID: %s', 'invoicing' ), $posted['subscr_id'] ), false, false, true );
405
406
		$subscription->renew();
407
		wpinv_error_log( 'Subscription renewed.', false );
408
409
	}
410
411
	/**
412
	 * Handles subscription cancelations.
413
	 *
414
	 * @param WPInv_Invoice $invoice  Invoice object.
415
	 */
416
	protected function ipn_txn_subscr_cancel( $invoice ) {
417
418
		// Make sure the invoice has a subscription.
419
		$subscription = getpaid_subscriptions()->get_invoice_subscription( $invoice );
420
421
		if ( empty( $subscription ) ) {
422
			return wpinv_error_log( 'Aborting, Subscription for the invoice ' . $invoice->get_id() . ' not found', false );
0 ignored issues
show
Are you sure the usage of wpinv_error_log('Abortin... . ' not found', false) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
423
		}
424
425
		wpinv_error_log( 'Processing subscription cancellation for the invoice ' . $invoice->get_id(), false );
426
		$subscription->cancel();
427
		wpinv_error_log( 'Subscription cancelled.', false );
428
429
	}
430
431
	/**
432
	 * Handles subscription completions.
433
	 *
434
	 * @param WPInv_Invoice $invoice  Invoice object.
435
	 * @param array    $posted Posted data.
436
	 */
437
	protected function ipn_txn_subscr_eot( $invoice ) {
438
439
		// Make sure the invoice has a subscription.
440
		$subscription = getpaid_subscriptions()->get_invoice_subscription( $invoice );
441
442
		if ( empty( $subscription ) ) {
443
			return wpinv_error_log( 'Aborting, Subscription for the invoice ' . $invoice->get_id() . ' not found', false );
0 ignored issues
show
Are you sure the usage of wpinv_error_log('Abortin... . ' not found', false) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
444
		}
445
446
		wpinv_error_log( 'Processing subscription end of life for the invoice ' . $invoice->get_id(), false );
447
		$subscription->complete();
448
		wpinv_error_log( 'Subscription completed.', false );
449
450
	}
451
452
	/**
453
	 * Handles subscription fails.
454
	 *
455
	 * @param WPInv_Invoice $invoice  Invoice object.
456
	 * @param array    $posted Posted data.
457
	 */
458
	protected function ipn_txn_subscr_failed( $invoice ) {
459
460
		// Make sure the invoice has a subscription.
461
		$subscription = getpaid_subscriptions()->get_invoice_subscription( $invoice );
462
463
		if ( empty( $subscription ) ) {
464
			return wpinv_error_log( 'Aborting, Subscription for the invoice ' . $invoice->get_id() . ' not found', false );
0 ignored issues
show
Are you sure the usage of wpinv_error_log('Abortin... . ' not found', false) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
465
		}
466
467
		wpinv_error_log( 'Processing subscription payment failure for the invoice ' . $invoice->get_id(), false );
468
		$subscription->failing();
469
		wpinv_error_log( 'Subscription marked as failing.', false );
470
471
	}
472
473
	/**
474
	 * Handles subscription suspensions.
475
	 *
476
	 * @param WPInv_Invoice $invoice  Invoice object.
477
	 * @param array    $posted Posted data.
478
	 */
479
	protected function ipn_txn_recurring_payment_suspended_due_to_max_failed_payment( $invoice ) {
480
481
		// Make sure the invoice has a subscription.
482
		$subscription = getpaid_subscriptions()->get_invoice_subscription( $invoice );
483
484
		if ( empty( $subscription ) ) {
485
			return wpinv_error_log( 'Aborting, Subscription for the invoice ' . $invoice->get_id() . ' not found', false );
0 ignored issues
show
Are you sure the usage of wpinv_error_log('Abortin... . ' not found', false) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
486
		}
487
488
		wpinv_error_log( 'Processing subscription cancellation due to max failed payment for the invoice ' . $invoice->get_id(), false );
489
		$subscription->cancel();
490
		wpinv_error_log( 'Subscription cancelled.', false );
491
	}
492
493
}
494