Test Failed
Push — develop ( 5f6097...889b97 )
by Remco
04:40
created

src/Gateway.php (6 issues)

1
<?php
2
/**
3
 * Mollie gateway.
4
 *
5
 * @author    Pronamic <[email protected]>
6
 * @copyright 2005-2020 Pronamic
7
 * @license   GPL-3.0-or-later
8
 * @package   Pronamic\WordPress\Pay
9
 */
10
11
namespace Pronamic\WordPress\Pay\Gateways\Mollie;
12
13
use DateInterval;
14
use Pronamic\WordPress\DateTime\DateTime;
15
use Pronamic\WordPress\Pay\Banks\BankAccountDetails;
16
use Pronamic\WordPress\Pay\Banks\BankTransferDetails;
17
use Pronamic\WordPress\Pay\Core\Gateway as Core_Gateway;
18
use Pronamic\WordPress\Pay\Core\PaymentMethods;
19
use Pronamic\WordPress\Pay\Core\Recurring as Core_Recurring;
20
use Pronamic\WordPress\Pay\Payments\PaymentStatus;
21
use Pronamic\WordPress\Pay\Payments\Payment;
22
use Pronamic\WordPress\Pay\Subscriptions\Subscription;
23
24
/**
25
 * Title: Mollie
26
 * Description:
27
 * Copyright: 2005-2020 Pronamic
28
 * Company: Pronamic
29
 *
30
 * @author  Remco Tolsma
31
 * @version 2.0.9
32
 * @since   1.1.0
33
 */
34
class Gateway extends Core_Gateway {
35
	/**
36
	 * Client.
37
	 *
38
	 * @var Client
39
	 */
40
	protected $client;
41
42
	/**
43
	 * Constructs and initializes an Mollie gateway
44
	 *
45
	 * @param Config $config Config.
46
	 */
47
	public function __construct( Config $config ) {
48
		parent::__construct( $config );
49
50
		$this->set_method( self::METHOD_HTTP_REDIRECT );
51
52
		// Supported features.
53 39
		$this->supports = array(
54 39
			'payment_status_request',
55
			'recurring_direct_debit',
56 39
			'recurring_credit_card',
57
			'recurring',
58
			'webhook',
59 39
			'webhook_log',
60
			'webhook_no_config',
61
		);
62
63
		// Client.
64
		$this->client = new Client( \strval( $config->api_key ) );
65
66
		// Data Stores.
67
		$this->profile_data_store  = new ProfileDataStore();
0 ignored issues
show
Bug Best Practice introduced by
The property profile_data_store does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
68
		$this->customer_data_store = new CustomerDataStore();
0 ignored issues
show
Bug Best Practice introduced by
The property customer_data_store does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
69
	}
70 39
71 39
	/**
72
	 * Get issuers
73
	 *
74 39
	 * @see Core_Gateway::get_issuers()
75 38
	 * @return array<int, array<string, array<string>>>
76
	 */
77
	public function get_issuers() {
78
		$groups = array();
79 39
80 39
		try {
81
			$result = $this->client->get_issuers();
82
83
			$groups[] = array(
84
				'options' => $result,
85
			);
86
		} catch ( Error $e ) {
87 3
			// Catch Mollie error.
88 3
			$error = new \WP_Error(
89
				'mollie_error',
90
				sprintf( '%1$s (%2$s) - %3$s', $e->get_title(), $e->getCode(), $e->get_detail() )
91 3
			);
92
93
			$this->set_error( $error );
94
		} catch ( \Exception $e ) {
95
			// Catch exceptions.
96 3
			$error = new \WP_Error( 'mollie_error', $e->getMessage() );
97
98 3
			$this->set_error( $error );
99 3
		}
100 3
101
		return $groups;
102
	}
103 3
104
	/**
105
	 * Get available payment methods.
106
	 *
107
	 * @see Core_Gateway::get_available_payment_methods()
108
	 * @return array<string>
109
	 */
110
	public function get_available_payment_methods() {
111 3
		$payment_methods = array();
112
113
		// Set sequence types to get payment methods for.
114
		$sequence_types = array( Sequence::ONE_OFF, Sequence::RECURRING, Sequence::FIRST );
115
116
		$results = array();
117
118
		foreach ( $sequence_types as $sequence_type ) {
119 2
			// Get active payment methods for Mollie account.
120 2
			try {
121
				$result = $this->client->get_payment_methods( $sequence_type );
122
			} catch ( Error $e ) {
123 2
				// Catch Mollie error.
124
				$error = new \WP_Error(
125 2
					'mollie_error',
126
					sprintf( '%1$s (%2$s) - %3$s', $e->get_title(), $e->getCode(), $e->get_detail() )
127 2
				);
128
129
				$this->set_error( $error );
130 2
131 2
				break;
132
			} catch ( \Exception $e ) {
133
				// Catch exceptions.
134
				$error = new \WP_Error( 'mollie_error', $e->getMessage() );
135
136
				$this->set_error( $error );
137
138
				break;
139
			}
140
141 2
			if ( Sequence::FIRST === $sequence_type ) {
142
				foreach ( $result as $method => $title ) {
143 2
					unset( $result[ $method ] );
144
145 2
					// Get WordPress payment method for direct debit method.
146
					$method         = Methods::transform_gateway_method( $method );
147 2
					$payment_method = array_search( $method, PaymentMethods::get_recurring_methods(), true );
148
149
					if ( $payment_method ) {
150 2
						$results[ $payment_method ] = $title;
151
					}
152
				}
153
			}
154
155
			if ( is_array( $result ) ) {
156
				$results = array_merge( $results, $result );
157
			}
158
		}
159
160
		// Transform to WordPress payment methods.
161
		foreach ( $results as $method => $title ) {
162
			if ( PaymentMethods::is_recurring_method( $method ) ) {
163
				$payment_method = $method;
164 2
			} else {
165 2
				$payment_method = Methods::transform_gateway_method( $method );
166
			}
167
168
			if ( $payment_method ) {
169
				$payment_methods[] = $payment_method;
170 2
			}
171 2
		}
172
173
		$payment_methods = array_unique( $payment_methods );
174 2
175
		return $payment_methods;
176
	}
177 2
178 2
	/**
179
	 * Get supported payment methods
180
	 *
181
	 * @see Pronamic_WP_Pay_Gateway::get_supported_payment_methods()
182 2
	 * @return array<string>
183
	 */
184 2
	public function get_supported_payment_methods() {
185
		return array(
186
			PaymentMethods::BANCONTACT,
187
			PaymentMethods::BANK_TRANSFER,
188
			PaymentMethods::BELFIUS,
189
			PaymentMethods::CREDIT_CARD,
190
			PaymentMethods::DIRECT_DEBIT,
191
			PaymentMethods::DIRECT_DEBIT_BANCONTACT,
192
			PaymentMethods::DIRECT_DEBIT_IDEAL,
193 2
			PaymentMethods::DIRECT_DEBIT_SOFORT,
194
			PaymentMethods::EPS,
195 2
			PaymentMethods::GIROPAY,
196
			PaymentMethods::IDEAL,
197
			PaymentMethods::KBC,
198
			PaymentMethods::PAYPAL,
199
			PaymentMethods::SOFORT,
200
		);
201
	}
202
203
	/**
204
	 * Get webhook URL for Mollie.
205
	 *
206
	 * @return string|null
207
	 */
208
	public function get_webhook_url() {
209
		$url = home_url( '/' );
210
211
		$host = wp_parse_url( $url, PHP_URL_HOST );
212
213
		if ( is_array( $host ) ) {
214
			// Parsing failure.
215
			$host = '';
216
		}
217 4
218 4
		if ( 'localhost' === $host ) {
219
			// Mollie doesn't allow localhost.
220 4
			return null;
221
		} elseif ( '.dev' === substr( $host, -4 ) ) {
222 4
			// Mollie doesn't allow the .dev TLD.
223
			return null;
224
		} elseif ( '.local' === substr( $host, -6 ) ) {
225
			// Mollie doesn't allow the .local TLD.
226
			return null;
227 4
		} elseif ( '.test' === substr( $host, -5 ) ) {
228
			// Mollie doesn't allow the .test TLD.
229 1
			return null;
230 3
		}
231
232 1
		$url = \rest_url( self::REST_ROUTE_NAMESPACE . '/webhook' );
0 ignored issues
show
The constant Pronamic\WordPress\Pay\G...y::REST_ROUTE_NAMESPACE was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
233 2
234
		return $url;
235 1
	}
236 1
237
	/**
238
	 * Start
239
	 *
240
	 * @see Pronamic_WP_Pay_Gateway::start()
241 1
	 * @param Payment $payment Payment.
242
	 * @return void
243 1
	 */
244
	public function start( Payment $payment ) {
245
		$request = new PaymentRequest(
246
			AmountTransformer::transform( $payment->get_total_amount() ),
247
			\strval( $payment->get_description() )
248
		);
249
250
		$request->redirect_url = $payment->get_return_url();
251
		$request->webhook_url  = $this->get_webhook_url();
252
253
		// Locale.
254
		$customer = $payment->get_customer();
255
256
		if ( null !== $customer ) {
257
			$request->locale = LocaleHelper::transform( $customer->get_locale() );
258
		}
259
260
		// Customer ID.
261
		$customer_id = $this->get_customer_id_for_payment( $payment );
262
263
		if ( null === $customer_id ) {
264
			$customer_id = $this->create_customer_for_payment( $payment );
265
		}
266
267
		if ( null !== $customer_id ) {
268
			$request->customer_id = $customer_id;
269
		}
270
271
		// Payment method.
272
		$payment_method = $payment->get_method();
273
274
		// Recurring payment method.
275
		$is_recurring_method = ( $payment->get_subscription() && PaymentMethods::is_recurring_method( $payment_method ) );
276
277
		// Consumer bank details.
278
		$consumer_bank_details = $payment->get_consumer_bank_details();
279
280
		if ( PaymentMethods::DIRECT_DEBIT === $payment_method && null !== $consumer_bank_details ) {
281
			$consumer_name = $consumer_bank_details->get_name();
282
			$consumer_iban = $consumer_bank_details->get_iban();
283
284
			$request->consumer_name    = $consumer_name;
285
			$request->consumer_account = $consumer_iban;
286
287
			// Check if one-off SEPA Direct Debit can be used, otherwise short circuit payment.
288
			if ( null !== $customer_id ) {
289
				// Find or create mandate.
290
				$mandate_id = $this->client->has_valid_mandate( $customer_id, PaymentMethods::DIRECT_DEBIT, $consumer_iban );
291
292
				if ( false === $mandate_id ) {
293
					$mandate = $this->client->create_mandate( $customer_id, $consumer_bank_details );
294
295
					$mandate_id = $mandate->id;
296
				}
297
298
				// Charge immediately on-demand.
299
				$request->sequence_type = Sequence::RECURRING;
300
				$request->mandate_id    = $mandate_id;
301
302
				$is_recurring_method = true;
303
304
				$payment->recurring = true;
305
			}
306
		}
307
308
		if ( false === $is_recurring_method ) {
309
			// Always use 'direct debit mandate via iDEAL/Bancontact/Sofort' payment methods as recurring method.
310
			$is_recurring_method = PaymentMethods::is_direct_debit_method( $payment_method );
311
		}
312
313
		if ( $is_recurring_method ) {
314
			$request->sequence_type = $payment->get_recurring() ? Sequence::RECURRING : Sequence::FIRST;
315
316
			if ( Sequence::FIRST === $request->sequence_type ) {
317
				$payment_method = PaymentMethods::get_first_payment_method( $payment_method );
318
			}
319
320
			if ( Sequence::RECURRING === $request->sequence_type ) {
321
				$payment->set_action_url( $payment->get_return_url() );
322
			}
323
		}
324
325
		// Leap of faith if the WordPress payment method could not transform to a Mollie method?
326
		$request->method = Methods::transform( $payment_method, $payment_method );
327
328
		// Issuer.
329
		if ( Methods::IDEAL === $request->method ) {
330
			$request->issuer = $payment->get_issuer();
331
		}
332
333
		// Due date.
334
		try {
335
			$due_date = new DateTime( sprintf( '+%s days', $this->config->due_date_days ) );
336
		} catch ( \Exception $e ) {
337
			$due_date = null;
338
		}
339
340
		$request->set_due_date( $due_date );
341
342
		// Create payment.
343
		$result = $this->client->create_payment( $request );
344
345
		// Set transaction ID.
346
		if ( isset( $result->id ) ) {
347
			$payment->set_transaction_id( $result->id );
348
		}
349
350
		// Set expiry date.
351
		/* phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase */
352
		if ( isset( $result->expiresAt ) ) {
353
			try {
354
				$expires_at = new DateTime( $result->expiresAt );
355
			} catch ( \Exception $e ) {
356
				$expires_at = null;
357
			}
358
359
			$payment->set_expiry_date( $expires_at );
360
		}
361
		/* phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase */
362
363
		// Set status.
364
		if ( isset( $result->status ) ) {
365
			$payment->set_status( Statuses::transform( $result->status ) );
366
		}
367
368
		// Set bank transfer recipient details.
369
		if ( isset( $result->details ) ) {
370
			$bank_transfer_recipient_details = $payment->get_bank_transfer_recipient_details();
371
372
			if ( null === $bank_transfer_recipient_details ) {
373
				$bank_transfer_recipient_details = new BankTransferDetails();
374
375
				$payment->set_bank_transfer_recipient_details( $bank_transfer_recipient_details );
376
			}
377
378
			$bank_details = $bank_transfer_recipient_details->get_bank_account();
379
380
			if ( null === $bank_details ) {
381
				$bank_details = new BankAccountDetails();
382
383
				$bank_transfer_recipient_details->set_bank_account( $bank_details );
384
			}
385
386
			$details = $result->details;
387
388
			/*
389
			 * @codingStandardsIgnoreStart
390
			 *
391
			 * Ignore coding standards because of sniff WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
392
			 */
393
			if ( isset( $details->bankName ) ) {
394
				/**
395
				 * Set `bankName` as bank details name, as result "Stichting Mollie Payments"
396
				 * is not the name of a bank, but the account holder name.
397
				 */
398
				$bank_details->set_name( $details->bankName );
399
			}
400
401
			if ( isset( $details->bankAccount ) ) {
402
				$bank_details->set_iban( $details->bankAccount );
403
			}
404
405
			if ( isset( $details->bankBic ) ) {
406
				$bank_details->set_bic( $details->bankBic );
407
			}
408
409
			if ( isset( $details->transferReference ) ) {
410
				$bank_transfer_recipient_details->set_reference( $details->transferReference );
411
			}
412
			// @codingStandardsIgnoreEnd
413
		}
414
415
		// Set action URL.
416
		if ( isset( $result->_links ) ) {
417
			if ( isset( $result->_links->checkout->href ) ) {
418
				$payment->set_action_url( $result->_links->checkout->href );
419
			}
420
		}
421
	}
422
423
	/**
424
	 * Update status of the specified payment
425
	 *
426
	 * @param Payment $payment Payment.
427
	 * @return void
428
	 */
429
	public function update_status( Payment $payment ) {
430
		$transaction_id = $payment->get_transaction_id();
431
432
		if ( null === $transaction_id ) {
433
			return;
434
		}
435
436
		$mollie_payment = $this->client->get_payment( $transaction_id );
437
438
		if ( isset( $mollie_payment->status ) ) {
439
			$payment->set_status( Statuses::transform( $mollie_payment->status ) );
440
		}
441
442
		/**
443
		 * Mollie profile.
444
		 */
445
		$mollie_profile = new Profile();
446
		$mollie_profile->set_id( $mollie_payment->profileId );
447
448
		$profile_id = $this->profile_data_store->save_profile( $mollie_profile );
449
450
		/**
451
		 * If the Mollie payment contains a customer ID we will try to connect
452
		 * this Mollie customer ID the WordPress user and subscription.
453
		 * This can be usefull in case when a WordPress user is created after 
454
		 * a succesfull payment.
455
		 *
456
		 * @link https://www.gravityforms.com/add-ons/user-registration/
457
		 */
458
		if ( isset( $mollie_payment->customerId ) ) {
459
			$mollie_customer = new Customer();
460
			$mollie_customer->set_id( $mollie_payment->customerId );
461
462
			$mollie_customer_data = $this->customer_data_store->get_customer( $mollie_customer );
463
464
			if ( null === $mollie_customer_data ) {
465
				$this->customer_data_store->insert_customer(
466
					$mollie_customer,
467
					array(
468
						'profile_id' => $profile_id,
469
					),
470
					array(
471
						'profile_id' => '%s',
472
					)
473
				);
474
			}
475
476
			$customer = $payment->get_customer();
477
478
			if ( null !== $customer ) {
479
				// Connect to user.
480
				$user = \get_user_by( 'id', $customer->get_user_id() );
481
482
				$this->customer_data_store->connect_mollie_customer_to_wp_user( $mollie_customer, $user );
0 ignored issues
show
It seems like $user can also be of type false; however, parameter $user of Pronamic\WordPress\Pay\G...e_customer_to_wp_user() does only seem to accept WP_User, 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

482
				$this->customer_data_store->connect_mollie_customer_to_wp_user( $mollie_customer, /** @scrutinizer ignore-type */ $user );
Loading history...
483 10
			}
484 10
485
			$subscription = $payment->get_subscription();
486
487 10
			if ( null !== $subscription ) {
488
				$customer_id = $subscription->get_meta( 'mollie_customer_id' );
489
490 10
				if ( empty( $customer_id ) ) {
491
492 10
				}
493
			}
494
		}
495 10
496 10
		if ( isset( $mollie_payment->details ) ) {
497
			$consumer_bank_details = $payment->get_consumer_bank_details();
498
499 10
			if ( null === $consumer_bank_details ) {
500 7
				$consumer_bank_details = new BankAccountDetails();
501
502 7
				$payment->set_consumer_bank_details( $consumer_bank_details );
503
			}
504
505 10
			$details = $mollie_payment->details;
506 4
507
			/*
508
			 * @codingStandardsIgnoreStart
509
			 *
510
			 * Ignore coding standards because of sniff WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
511 10
			 */
512
			if ( isset( $details->consumerName ) ) {
513
				$consumer_bank_details->set_name( $details->consumerName );
514
			}
515
516
			if ( isset( $details->cardHolder ) ) {
517
				$consumer_bank_details->set_name( $details->cardHolder );
518
			}
519
520
			if ( isset( $details->cardNumber ) ) {
521
				// The last four digits of the card number.
522
				$consumer_bank_details->set_account_number( $details->cardNumber );
523
			}
524 10
525
			if ( isset( $details->cardCountryCode ) ) {
526
				// The ISO 3166-1 alpha-2 country code of the country the card was issued in.
527
				$consumer_bank_details->set_country( $details->cardCountryCode );
528
			}
529 10
530
			if ( isset( $details->consumerAccount ) ) {
531 10
				switch ( $mollie_payment->method ) {
532
					case Methods::BELFIUS:
533
					case Methods::DIRECT_DEBIT:
534
					case Methods::IDEAL:
535
					case Methods::KBC:
536
					case Methods::SOFORT:
537
						$consumer_bank_details->set_iban( $details->consumerAccount );
538
539
						break;
540 27
					case Methods::BANCONTACT:
541 27
					case Methods::BANKTRANSFER:
542 11
					case Methods::PAYPAL:
543
					default:
544
						$consumer_bank_details->set_account_number( $details->consumerAccount );
545 16
546
						break;
547
				}
548
			}
549
550
			if ( isset( $details->consumerBic ) ) {
551
				$consumer_bank_details->set_bic( $details->consumerBic );
552
			}
553
			// @codingStandardsIgnoreEnd
554
		}
555 15
	}
556 15
557 3
	/**
558
	 * Get Mollie customer ID for payment.
559
	 *
560 12
	 * @param Payment $payment Payment.
561 11
	 * @return string|null
562
	 */
563
	public function get_customer_id_for_payment( Payment $payment ) {
564 4
		$customer_ids = $this->get_customer_ids_for_payment( $payment );
565 4
566
		$customer_id = $this->get_first_existing_customer_id( $customer_ids );
567
568
		return $customer_id;
569
	}
570
571
	/**
572
	 * Get Mollie customers for the specified payment.
573 27
	 *
574 27
	 * @param Payment $payment Payment.
575 1
	 * @return array<string>
576
	 */
577
	private function get_customer_ids_for_payment( Payment $payment ) {
578 26
		$customer_ids = array();
579
580 26
		// Customer ID from subscription meta.
581
		$subscription = $payment->get_subscription();
582
583
		if ( null !== $subscription ) {
584 26
			$customer_id = $this->get_customer_id_for_subscription( $payment->get_subscription() );
0 ignored issues
show
It seems like $payment->get_subscription() can also be of type null; however, parameter $subscription of Pronamic\WordPress\Pay\G...r_id_for_subscription() does only seem to accept Pronamic\WordPress\Pay\Subscriptions\Subscription, 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

584
			$customer_id = $this->get_customer_id_for_subscription( /** @scrutinizer ignore-type */ $payment->get_subscription() );
Loading history...
585
586 26
			if ( null !== $customer_id ) {
587 1
				$customer_ids[] = $customer_id;
588
			}
589
		}
590 25
591
		// Customer ID from WordPress user.
592 25
		$customer = $payment->get_customer();
593 10
594
		if ( null !== $customer ) {
595
			$user_id = $customer->get_user_id();
596
597 15
			if ( ! empty( $user_id ) ) {
598
				$user_customer_ids = $this->get_customer_ids_for_user( $user_id );
599 15
600
				$customer_ids = \array_merge( $customer_ids, $user_customer_ids );
601 15
			}
602
		}
603 15
604
		return $customer_ids;
605 15
	}
606
607
	/**
608
	 * Get Mollie customers for the specified WordPress user ID.
609
	 *
610
	 * @param int $user_id WordPress user ID.
611
	 * @return array<string>
612
	 */
613
	private function get_customer_ids_for_user( $user_id ) {
614
		$customer_query = new CustomerQuery(
615
			array(
616
				'user_id' => $user_id,
617
			)
618
		);
619
620
		$customers = $customer_query->get_customers();
621
622
		$customer_ids = wp_list_pluck( $customers, 'mollie_id' );
623
624
		return $customer_ids;
625
	}
626
627
	/**
628
	 * Get customer ID for subscription.
629
	 *
630
	 * @param Subscription $subscription Subscription.
631
	 * @return string|null
632
	 */
633
	private function get_customer_id_for_subscription( Subscription $subscription ) {
634
		$customer_id = $subscription->get_meta( 'mollie_customer_id' );
635
636
		if ( empty( $customer_id ) ) {
637
			// Try to get (legacy) customer ID from first payment.
638
			$first_payment = $subscription->get_first_payment();
639
640
			if ( null !== $first_payment ) {
641
				$customer_id = $first_payment->get_meta( 'mollie_customer_id' );
642
			}
643
		}
644
645
		if ( empty( $customer_id ) ) {
646
			return null;
647
		}
648
649
		return $customer_id;
650
	}
651
652
	/**
653
	 * Get first existing customer from customers list.
654
	 *
655
	 * @param array $customer_ids Customers.
656
	 * @return string|null
657
	 */
658
	private function get_first_existing_customer_id( $customer_ids ) {
659
		$customer_ids = \array_filter( $customer_ids );
660
661
		$customer_ids = \array_unique( $customer_ids );
662
663
		foreach ( $customer_ids as $customer_id ) {
664
			$customer = $this->client->get_customer( $customer_id );
665
666
			if ( null !== $customer ) {
667
				return $customer_id;
668
			}
669
		}
670
671
		return null;
672
	}
673
674
	/**
675
	 * Create customer for payment.
676
	 *
677
	 * @param Payment $payment
678
	 * @return string|null
679
	 * @throws Error Throws Error when Mollie error occurs.
680
	 */
681
	private function create_customer_for_payment( Payment $payment ) {
682
		$mollie_customer = new Customer();
683
		$mollie_customer->set_mode( $this->config->is_test_mode() ? 'test' : 'live' );
684
		$mollie_customer->set_email( $payment->get_email() );
685
686
		$pronamic_customer = $payment->get_customer();
687
688
		if ( null !== $pronamic_customer ) {
689
			$name = $pronamic_customer->get_name();
690
691
			if ( null !== $name ) {
692
				$mollie_customer->set_name( \strval( $name ) );
693
			}
694
		}
695
696
		// Create customer.
697
		$mollie_customer = $this->client->create_customer( $mollie_customer );
698
699
		$customer_id = $this->customer_data_store->insert_customer( $mollie_customer );
700
701
		// Connect to user.
702
		$user = \get_user_by( 'id', $pronamic_customer->get_user_id() );
703
704
		$this->customer_data_store->connect_mollie_customer_to_wp_user( $mollie_customer, $user );
0 ignored issues
show
It seems like $user can also be of type false; however, parameter $user of Pronamic\WordPress\Pay\G...e_customer_to_wp_user() does only seem to accept WP_User, 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

704
		$this->customer_data_store->connect_mollie_customer_to_wp_user( $mollie_customer, /** @scrutinizer ignore-type */ $user );
Loading history...
705
706
		// Store customer ID in subscription meta.
707
		$subscription = $payment->get_subscription();
708
709
		if ( null !== $subscription ) {
710
			$subscription->set_meta( 'mollie_customer_id', $mollie_customer->get_id() );
711
		}
712
713
		return $mollie_customer->get_id();
714
	}
715
}
716