← All changes
|
stripe/controllers/FrmStrpLiteEventsController.php
+181
-40
6.5.3
→
trunk
View file →
| @@ -9,11 +9,26 @@ | ||
| 9 | 9 | * @var string |
| 10 | 10 | */ |
| 11 | 11 | public static $events_to_skip_option_name = 'frm_strp_events_to_skip'; |
| 12 | 12 | |
| 13 | + /** | |
| 14 | + * @var object|null | |
| 15 | + */ | |
| 13 | 16 | private $event; |
| 17 | + | |
| 18 | + /** | |
| 19 | + * @var object|null | |
| 20 | + */ | |
| 14 | 21 | private $invoice; |
| 22 | + | |
| 23 | + /** | |
| 24 | + * @var string|null | |
| 25 | + */ | |
| 15 | 26 | private $charge; |
| 27 | + | |
| 28 | + /** | |
| 29 | + * @var string|null | |
| 30 | + */ | |
| 16 | 31 | private $status; |
| 17 | 32 | |
| 18 | 33 | /** |
| 19 | 34 | * @return void |
| @@ -68,9 +83,11 @@ | ||
| 68 | 83 | } |
| 69 | 84 | |
| 70 | 85 | FrmTransLiteAppHelper::add_note_to_payment( $payment_values, $note ); |
| 71 | 86 | |
| 72 | - $u = $frm_payment->update( $payment->id, $payment_values ); | |
| 87 | + // Read the status again right before the update, in case another request has already changed it. | |
| 88 | + $payment_status_still_does_not_match = $this->payment_status_still_does_not_match( $payment->id ); | |
| 89 | + $updated = $frm_payment->update( $payment->id, $payment_values ); | |
| 73 | 90 | |
| 74 | 91 | echo json_encode( |
| 75 | 92 | array( |
| 76 | 93 | 'response' => 'Payment ' . $payment->id . ' was updated', |
| @@ -76,12 +93,13 @@ | ||
| 76 | 93 | 'response' => 'Payment ' . $payment->id . ' was updated', |
| 77 | 94 | 'success' => true, |
| 78 | 95 | ) |
| 79 | 96 | ); |
| 80 | - if ( ! $is_partial_refund ) { | |
| 97 | + | |
| 98 | + if ( ! $is_partial_refund && $payment_status_still_does_not_match && $updated ) { | |
| 81 | 99 | $run_triggers = true; |
| 82 | 100 | } |
| 83 | - } | |
| 101 | + }//end if | |
| 84 | 102 | |
| 85 | 103 | if ( $run_triggers && $payment && $payment->action_id ) { |
| 86 | 104 | FrmTransLiteActionsController::trigger_payment_status_change( |
| 87 | 105 | array( |
| @@ -92,8 +110,26 @@ | ||
| 92 | 110 | } |
| 93 | 111 | } |
| 94 | 112 | |
| 95 | 113 | /** |
| 114 | + * Double check that the payment status has not changed. | |
| 115 | + * This is to avoid running actions twice by mistake, since a Stripe Link | |
| 116 | + * return URL and a webhook event can both process the same payment. | |
| 117 | + * | |
| 118 | + * @since 6.35 | |
| 119 | + * | |
| 120 | + * @param int $payment_id The id of the payment to check. | |
| 121 | + * | |
| 122 | + * @return bool | |
| 123 | + */ | |
| 124 | + private function payment_status_still_does_not_match( $payment_id ) { | |
| 125 | + $frm_payment = new FrmTransLitePayment(); | |
| 126 | + $payment = $frm_payment->get_one( $payment_id ); | |
| 127 | + | |
| 128 | + return $payment && $payment->status !== $this->status; | |
| 129 | + } | |
| 130 | + | |
| 131 | + /** | |
| 96 | 132 | * Skip updating the payment object for the first recurring payment. |
| 97 | 133 | * This is to prevent double notifications because the first recurring payment creates an invoice and that invoice triggers the payment events. |
| 98 | 134 | * |
| 99 | 135 | * @since 6.5, introduced in v2.07 of the Stripe add on. |
| @@ -98,8 +134,9 @@ | ||
| 98 | 134 | * |
| 99 | 135 | * @since 6.5, introduced in v2.07 of the Stripe add on. |
| 100 | 136 | * |
| 101 | 137 | * @param stdClass $payment |
| 138 | + * | |
| 102 | 139 | * @return bool |
| 103 | 140 | */ |
| 104 | 141 | private function should_skip_status_update_for_first_recurring_payment( $payment ) { |
| 105 | 142 | if ( ! in_array( $this->event->type, array( 'payment_intent.succeeded', 'payment_intent.payment_failed' ), true ) ) { |
| @@ -146,14 +183,16 @@ | ||
| 146 | 183 | /** |
| 147 | 184 | * When a customer is deleted in Stripe, remove the link to a user. |
| 148 | 185 | * |
| 149 | 186 | * @since 6.5, introduced in v2.01 of the Stripe add on. |
| 187 | + * | |
| 150 | 188 | * @return void |
| 151 | 189 | */ |
| 152 | 190 | private function reset_customer() { |
| 153 | 191 | global $wpdb; |
| 154 | 192 | $customer_id = $this->invoice->id; |
| 155 | - if ( empty( $customer_id ) ) { | |
| 193 | + | |
| 194 | + if ( ! $customer_id ) { | |
| 156 | 195 | return; |
| 157 | 196 | } |
| 158 | 197 | $wpdb->query( |
| 159 | 198 | $wpdb->prepare( |
| @@ -167,8 +206,9 @@ | ||
| 167 | 206 | /** |
| 168 | 207 | * @return void |
| 169 | 208 | */ |
| 170 | 209 | private function maybe_subscription_canceled() { |
| 210 | + // phpcs:ignore Universal.Operators.StrictComparisons | |
| 171 | 211 | if ( $this->invoice->cancel_at_period_end == true ) { |
| 172 | 212 | $this->subscription_canceled( 'future_cancel' ); |
| 173 | 213 | } |
| 174 | 214 | } |
| @@ -174,12 +214,14 @@ | ||
| 174 | 214 | } |
| 175 | 215 | |
| 176 | 216 | /** |
| 177 | 217 | * @param string $status |
| 218 | + * | |
| 178 | 219 | * @return bool |
| 179 | 220 | */ |
| 180 | 221 | private function subscription_canceled( $status = 'canceled' ) { |
| 181 | 222 | $sub = $this->get_subscription( $this->invoice->id ); |
| 223 | + | |
| 182 | 224 | if ( ! $sub ) { |
| 183 | 225 | return false; |
| 184 | 226 | } |
| 185 | 227 | |
| @@ -202,12 +244,14 @@ | ||
| 202 | 244 | ); |
| 203 | 245 | return true; |
| 204 | 246 | } |
| 205 | 247 | |
| 248 | + /** | |
| 249 | + * @return false|object | |
| 250 | + */ | |
| 206 | 251 | private function prepare_from_invoice() { |
| 207 | 252 | if ( empty( $this->invoice->subscription ) ) { |
| 208 | 253 | // This isn't a subscription. |
| 209 | - FrmTransLiteLog::log_message( 'Stripe Webhook Message', 'No action taken since this is not a subscription.' ); | |
| 210 | 254 | echo json_encode( |
| 211 | 255 | array( |
| 212 | 256 | 'response' => 'Invoice missing', |
| 213 | 257 | 'success' => false, |
| @@ -216,8 +260,9 @@ | ||
| 216 | 260 | return false; |
| 217 | 261 | } |
| 218 | 262 | |
| 219 | 263 | $sub = $this->get_subscription( $this->invoice->subscription ); |
| 264 | + | |
| 220 | 265 | if ( ! $sub ) { |
| 221 | 266 | return false; |
| 222 | 267 | } |
| 223 | 268 | |
| @@ -231,33 +276,117 @@ | ||
| 231 | 276 | // The first payment for the subscription needs to be updated with the receipt id. |
| 232 | 277 | $frm_payment->update( $payment->id, $payment_values ); |
| 233 | 278 | $payment_id = $payment->id; |
| 234 | 279 | } else { |
| 280 | + $payment_values['test'] = $this->event->livemode ? 0 : 1; | |
| 281 | + | |
| 235 | 282 | // If this isn't the first, create a new payment. |
| 236 | 283 | $payment_id = $frm_payment->create( $payment_values ); |
| 237 | 284 | } |
| 238 | 285 | |
| 286 | + $this->maybe_cancel_subscription( $sub ); | |
| 239 | 287 | $this->update_next_bill_date( $sub, $payment_values ); |
| 288 | + return $frm_payment->get_one( $payment_id ); | |
| 289 | + } | |
| 240 | 290 | |
| 241 | - $payment = $frm_payment->get_one( $payment_id ); | |
| 242 | - return $payment; | |
| 291 | + /** | |
| 292 | + * Check if a subscription has reached its payment limit. | |
| 293 | + * If it has, the subscription will be cancelled by period end. | |
| 294 | + * | |
| 295 | + * @since 6.11 | |
| 296 | + * | |
| 297 | + * @param object $sub | |
| 298 | + * | |
| 299 | + * @return void | |
| 300 | + */ | |
| 301 | + private function maybe_cancel_subscription( $sub ) { | |
| 302 | + $action = FrmFormAction::get_single_action_type( $sub->action_id, 'payment' ); | |
| 303 | + | |
| 304 | + // @phpstan-ignore-next-line | |
| 305 | + if ( ! is_object( $action ) || empty( $action->post_content['payment_limit'] ) ) { | |
| 306 | + return; | |
| 307 | + } | |
| 308 | + | |
| 309 | + $payment_limit = FrmStrpLiteSubscriptionHelper::prepare_payment_limit( | |
| 310 | + $action->post_content['payment_limit'], | |
| 311 | + // Form ID. | |
| 312 | + (int) $action->menu_order, | |
| 313 | + (int) $sub->item_id | |
| 314 | + ); | |
| 315 | + | |
| 316 | + if ( is_wp_error( $payment_limit ) ) { | |
| 317 | + FrmTransLiteLog::log_message( 'Invalid payment limit value', $payment_limit->get_error_message() ); | |
| 318 | + return; | |
| 319 | + } | |
| 320 | + | |
| 321 | + if ( $this->get_payments_count( $sub->id ) < $payment_limit ) { | |
| 322 | + return; | |
| 323 | + } | |
| 324 | + | |
| 325 | + // Flag to cancel subscription at period end. | |
| 326 | + // In this case, we do not want to cancel immediately. | |
| 327 | + $hook = 'frm_stripe_cancel_subscription_at_period_end'; | |
| 328 | + $filter = function () { | |
| 329 | + return true; | |
| 330 | + }; | |
| 331 | + | |
| 332 | + add_filter( $hook, $filter, 99 ); | |
| 333 | + | |
| 334 | + // There is no logged in user when a webhook event is processed, so the customer check has to be skipped here. | |
| 335 | + $cancelled = FrmStrpLiteAppHelper::call_stripe_helper_class( 'cancel_subscription_without_customer_check', $sub->sub_id ); | |
| 336 | + | |
| 337 | + if ( $cancelled ) { | |
| 338 | + FrmTransLiteSubscriptionsController::change_subscription_status( | |
| 339 | + array( | |
| 340 | + 'status' => 'future_cancel', | |
| 341 | + 'sub' => $sub, | |
| 342 | + ) | |
| 343 | + ); | |
| 344 | + } else { | |
| 345 | + FrmTransLiteLog::log_message( 'Stripe Webhook Message', 'Unable to cancel subscription ' . $sub->sub_id . ' after it reached its payment limit.' ); | |
| 346 | + } | |
| 347 | + | |
| 348 | + remove_filter( $hook, $filter, 99 ); | |
| 243 | 349 | } |
| 244 | 350 | |
| 245 | 351 | /** |
| 352 | + * Get the count of completed payments. | |
| 353 | + * | |
| 354 | + * @since 6.11 | |
| 355 | + * | |
| 356 | + * @param string $sub_id Stripe subscriptino id prefixed with 'sub_'. | |
| 357 | + * | |
| 358 | + * @return int | |
| 359 | + */ | |
| 360 | + private function get_payments_count( $sub_id ) { | |
| 361 | + $frm_payment = new FrmTransLitePayment(); | |
| 362 | + $all_payments = $frm_payment->get_all_by( $sub_id, 'sub_id' ); | |
| 363 | + | |
| 364 | + return FrmTransLiteAppHelper::count_completed_payments( $all_payments ); | |
| 365 | + } | |
| 366 | + | |
| 367 | + /** | |
| 246 | 368 | * @since 6.5, introduced in v2.07 of the Stripe add on. |
| 247 | 369 | * |
| 248 | 370 | * @param stdClass $payment |
| 371 | + * | |
| 249 | 372 | * @return bool |
| 250 | 373 | */ |
| 251 | 374 | private function is_first_payment( $payment ) { |
| 252 | - return ! $payment->receipt_id || 0 === strpos( $payment->receipt_id, 'pi_' ); | |
| 375 | + return ! $payment->receipt_id || str_starts_with( $payment->receipt_id, 'pi_' ); | |
| 253 | 376 | } |
| 254 | 377 | |
| 378 | + /** | |
| 379 | + * @param string $sub_id | |
| 380 | + * | |
| 381 | + * @return object|null | |
| 382 | + */ | |
| 255 | 383 | private function get_subscription( $sub_id ) { |
| 256 | 384 | $frm_sub = new FrmTransLiteSubscription(); |
| 257 | 385 | $sub = $frm_sub->get_one_by( $sub_id, 'sub_id' ); |
| 386 | + | |
| 258 | 387 | if ( ! $sub ) { |
| 259 | - // If this isn't an existing subscription, it must be a charge for another site/plugin | |
| 388 | + // If this isn't an existing subscription, it must be a charge for another site/plugin. | |
| 260 | 389 | FrmTransLiteLog::log_message( 'Stripe Webhook Message', 'No action taken since there is not a matching subscription for ' . $sub_id ); |
| 261 | 390 | echo json_encode( |
| 262 | 391 | array( |
| 263 | 392 | 'response' => 'Invoice missing', |
| @@ -268,8 +397,13 @@ | ||
| 268 | 397 | |
| 269 | 398 | return $sub; |
| 270 | 399 | } |
| 271 | 400 | |
| 401 | + /** | |
| 402 | + * @param string $sub_id | |
| 403 | + * | |
| 404 | + * @return object|null | |
| 405 | + */ | |
| 272 | 406 | private function get_payment_for_sub( $sub_id ) { |
| 273 | 407 | $frm_payment = new FrmTransLitePayment(); |
| 274 | 408 | return $frm_payment->get_one_by( $sub_id, 'sub_id' ); |
| 275 | 409 | } |
| @@ -275,8 +409,9 @@ | ||
| 275 | 409 | } |
| 276 | 410 | |
| 277 | 411 | /** |
| 278 | 412 | * @param array $payment_values |
| 413 | + * | |
| 279 | 414 | * @return void |
| 280 | 415 | */ |
| 281 | 416 | private function set_payment_values( &$payment_values ) { |
| 282 | 417 | $payment_values['begin_date'] = gmdate( 'Y-m-d' ); |
| @@ -282,17 +417,17 @@ | ||
| 282 | 417 | $payment_values['begin_date'] = gmdate( 'Y-m-d' ); |
| 283 | 418 | $payment_values['expire_date'] = '0000-00-00'; |
| 284 | 419 | |
| 285 | 420 | foreach ( $this->invoice->lines->data as $line ) { |
| 286 | - $payment_values['amount'] = number_format( ( $line->amount / 100 ), 2, '.', '' ); | |
| 421 | + $payment_values['amount'] = number_format( $line->amount / 100, 2, '.', '' ); | |
| 287 | 422 | $payment_values['begin_date'] = gmdate( 'Y-m-d', $line->period->start ); |
| 288 | 423 | $payment_values['expire_date'] = gmdate( 'Y-m-d', $line->period->end ); |
| 289 | 424 | } |
| 290 | 425 | |
| 291 | - $payment_values['receipt_id'] = $this->charge ? $this->charge : __( 'None', 'formidable' ); | |
| 292 | - $payment_values['status'] = $this->status; | |
| 293 | - $payment_values['meta_value'] = array(); | |
| 294 | - $payment_values['created_at'] = current_time( 'mysql', 1 ); | |
| 426 | + $payment_values['receipt_id'] = $this->charge ? $this->charge : __( 'None', 'formidable' ); | |
| 427 | + $payment_values['status'] = $this->status; | |
| 428 | + $payment_values['meta_value'] = array(); | |
| 429 | + $payment_values['created_at'] = current_time( 'mysql', 1 ); | |
| 295 | 430 | |
| 296 | 431 | FrmTransLiteAppHelper::add_note_to_payment( $payment_values ); |
| 297 | 432 | } |
| 298 | 433 | |
| @@ -298,12 +433,14 @@ | ||
| 298 | 433 | |
| 299 | 434 | /** |
| 300 | 435 | * @param object $sub |
| 301 | 436 | * @param array $payment |
| 437 | + * | |
| 302 | 438 | * @return void |
| 303 | 439 | */ |
| 304 | 440 | private function update_next_bill_date( $sub, $payment ) { |
| 305 | 441 | $frm_sub = new FrmTransLiteSubscription(); |
| 442 | + | |
| 306 | 443 | if ( $payment['status'] === 'complete' ) { |
| 307 | 444 | $frm_sub->update( $sub->id, array( 'next_bill_date' => $payment['expire_date'] ) ); |
| 308 | 445 | } elseif ( $payment['status'] === 'refunded' ) { |
| 309 | 446 | $frm_sub->update( $sub->id, array( 'next_bill_date' => $payment['begin_date'] ) ); |
| @@ -313,19 +450,20 @@ | ||
| 313 | 450 | /** |
| 314 | 451 | * @return bool |
| 315 | 452 | */ |
| 316 | 453 | private function is_partial_refund() { |
| 317 | - $partial = false; | |
| 318 | - if ( $this->status === 'refunded' ) { | |
| 319 | - $amount = $this->invoice->amount; | |
| 320 | - $amount_refunded = $this->invoice->amount_refunded; | |
| 321 | - $partial = $amount != $amount_refunded; | |
| 454 | + if ( $this->status !== 'refunded' ) { | |
| 455 | + return false; | |
| 322 | 456 | } |
| 323 | - return $partial; | |
| 457 | + | |
| 458 | + $amount = $this->invoice->amount; | |
| 459 | + $amount_refunded = $this->invoice->amount_refunded; | |
| 460 | + return $amount !== $amount_refunded; | |
| 324 | 461 | } |
| 325 | 462 | |
| 326 | 463 | /** |
| 327 | 464 | * @param array $payment_values |
| 465 | + * | |
| 328 | 466 | * @return void |
| 329 | 467 | */ |
| 330 | 468 | private function set_partial_refund( &$payment_values ) { |
| 331 | 469 | $payment_values['amount'] = $this->invoice->amount - $this->invoice->amount_refunded; |
| @@ -338,11 +476,13 @@ | ||
| 338 | 476 | public function process_connect_events() { |
| 339 | 477 | $this->flush_response(); |
| 340 | 478 | |
| 341 | 479 | $unprocessed_event_ids = FrmStrpLiteConnectHelper::get_unprocessed_event_ids(); |
| 480 | + | |
| 342 | 481 | if ( $unprocessed_event_ids ) { |
| 343 | 482 | $this->process_event_ids( $unprocessed_event_ids ); |
| 344 | 483 | } |
| 484 | + | |
| 345 | 485 | wp_send_json_success(); |
| 346 | 486 | } |
| 347 | 487 | |
| 348 | 488 | /** |
| @@ -348,8 +488,9 @@ | ||
| 348 | 488 | /** |
| 349 | 489 | * @since 6.5, introduced in v2.07 of the Stripe add on. |
| 350 | 490 | * |
| 351 | 491 | * @param array<string> $event_ids |
| 492 | + * | |
| 352 | 493 | * @return void |
| 353 | 494 | */ |
| 354 | 495 | private function process_event_ids( $event_ids ) { |
| 355 | 496 | foreach ( $event_ids as $event_id ) { |
| @@ -359,15 +500,17 @@ | ||
| 359 | 500 | |
| 360 | 501 | set_transient( 'frm_last_process_' . $event_id, time(), 60 ); |
| 361 | 502 | |
| 362 | 503 | $this->event = FrmStrpLiteConnectHelper::get_event( $event_id ); |
| 363 | - if ( is_object( $this->event ) ) { | |
| 364 | - $this->handle_event(); | |
| 365 | - $this->track_handled_event( $event_id ); | |
| 366 | - FrmStrpLiteConnectHelper::process_event( $event_id ); | |
| 367 | - } else { | |
| 504 | + | |
| 505 | + if ( ! is_object( $this->event ) ) { | |
| 368 | 506 | $this->count_failed_event( $event_id ); |
| 507 | + continue; | |
| 369 | 508 | } |
| 509 | + | |
| 510 | + $this->handle_event(); | |
| 511 | + $this->track_handled_event( $event_id ); | |
| 512 | + FrmStrpLiteConnectHelper::process_event( $event_id ); | |
| 370 | 513 | } |
| 371 | 514 | } |
| 372 | 515 | |
| 373 | 516 | /** |
| @@ -373,8 +516,9 @@ | ||
| 373 | 516 | /** |
| 374 | 517 | * @since 6.5, introduced in v2.07 of the Stripe add on. |
| 375 | 518 | * |
| 376 | 519 | * @param string $event_id |
| 520 | + * | |
| 377 | 521 | * @return bool True if the event should be skipped. |
| 378 | 522 | */ |
| 379 | 523 | private function should_skip_event( $event_id ) { |
| 380 | 524 | if ( $this->last_attempt_to_process_event_is_too_recent( $event_id ) ) { |
| @@ -381,22 +525,20 @@ | ||
| 381 | 525 | return true; |
| 382 | 526 | } |
| 383 | 527 | |
| 384 | 528 | $option = get_option( self::$events_to_skip_option_name ); |
| 385 | - if ( ! is_array( $option ) ) { | |
| 386 | - return false; | |
| 387 | - } | |
| 388 | 529 | |
| 389 | - return in_array( $event_id, $option, true ); | |
| 530 | + return is_array( $option ) && in_array( $event_id, $option, true ); | |
| 390 | 531 | } |
| 391 | 532 | |
| 392 | 533 | /** |
| 393 | 534 | * @param string $event_id |
| 535 | + * | |
| 394 | 536 | * @return bool |
| 395 | 537 | */ |
| 396 | 538 | private function last_attempt_to_process_event_is_too_recent( $event_id ) { |
| 397 | 539 | $last_process_attempt = get_transient( 'frm_last_process_' . $event_id ); |
| 398 | - return is_numeric( $last_process_attempt ) && $last_process_attempt > ( time() - 60 ); | |
| 540 | + return is_numeric( $last_process_attempt ) && $last_process_attempt > time() - 60; | |
| 399 | 541 | } |
| 400 | 542 | |
| 401 | 543 | /** |
| 402 | 544 | * @since 6.5, introduced in v2.07 of the Stripe add on. |
| @@ -401,24 +543,21 @@ | ||
| 401 | 543 | /** |
| 402 | 544 | * @since 6.5, introduced in v2.07 of the Stripe add on. |
| 403 | 545 | * |
| 404 | 546 | * @param string $event_id |
| 547 | + * | |
| 405 | 548 | * @return void |
| 406 | 549 | */ |
| 407 | 550 | private function count_failed_event( $event_id ) { |
| 408 | - $transient_name = 'frm_failed_event_' . $event_id; | |
| 409 | - $transient = get_transient( $transient_name ); | |
| 410 | - if ( is_int( $transient ) ) { | |
| 411 | - $failed_count = $transient + 1; | |
| 412 | - } else { | |
| 413 | - $failed_count = 1; | |
| 414 | - } | |
| 551 | + $transient_name = 'frm_failed_event_' . $event_id; | |
| 552 | + $transient = get_transient( $transient_name ); | |
| 553 | + $failed_count = is_int( $transient ) ? $transient + 1 : 1; | |
| 554 | + $maximum_retries = 3; | |
| 415 | 555 | |
| 416 | - $maximum_retries = 3; | |
| 417 | 556 | if ( $failed_count >= $maximum_retries ) { |
| 418 | 557 | $this->track_handled_event( $event_id ); |
| 419 | 558 | } else { |
| 420 | - set_transient( $transient_name, $failed_count ); | |
| 559 | + set_transient( $transient_name, $failed_count, 4 * DAY_IN_SECONDS ); | |
| 421 | 560 | } |
| 422 | 561 | } |
| 423 | 562 | |
| 424 | 563 | /** |
| @@ -427,8 +566,9 @@ | ||
| 427 | 566 | * |
| 428 | 567 | * @since 6.5, introduced in v2.07 of the Stripe add on. |
| 429 | 568 | * |
| 430 | 569 | * @param string $event_id |
| 570 | + * | |
| 431 | 571 | * @return void |
| 432 | 572 | */ |
| 433 | 573 | private function track_handled_event( $event_id ) { |
| 434 | 574 | $option = get_option( self::$events_to_skip_option_name ); |
| @@ -450,9 +590,10 @@ | ||
| 450 | 590 | * @return void |
| 451 | 591 | */ |
| 452 | 592 | private function handle_event() { |
| 453 | 593 | $this->invoice = $this->event->data->object; |
| 454 | - $this->charge = isset( $this->invoice->charge ) ? $this->invoice->charge : false; | |
| 594 | + $this->charge = $this->invoice->charge ?? false; | |
| 595 | + | |
| 455 | 596 | if ( ! $this->charge && $this->invoice->object === 'payment_intent' ) { |
| 456 | 597 | $this->charge = $this->invoice->id; |
| 457 | 598 | } |
| 458 | 599 | |