Failed Conditions
Push — master ( b549f2...090668 )
by Remco
10:21 queued 03:46
created

Gateway::get_available_payment_methods()   B

Complexity

Conditions 11
Paths 35

Size

Total Lines 66
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 16.8164

Importance

Changes 6
Bugs 0 Features 0
Metric Value
cc 11
eloc 34
c 6
b 0
f 0
nc 35
nop 0
dl 0
loc 66
ccs 21
cts 33
cp 0.6364
crap 16.8164
rs 7.3166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\FailureReason;
21
use Pronamic\WordPress\Pay\Payments\PaymentStatus;
22
use Pronamic\WordPress\Pay\Payments\Payment;
23
use Pronamic\WordPress\Pay\Subscriptions\Subscription;
24
25
/**
26
 * Title: Mollie
27
 * Description:
28
 * Copyright: 2005-2020 Pronamic
29
 * Company: Pronamic
30
 *
31
 * @author  Remco Tolsma
32
 * @version 2.0.9
33
 * @since   1.1.0
34
 */
35
class Gateway extends Core_Gateway {
36
	/**
37
	 * Client.
38
	 *
39
	 * @var Client
40
	 */
41
	protected $client;
42
43
	/**
44
	 * Profile data store.
45
	 *
46
	 * @var ProfileDataStore
47
	 */
48
	private $profile_data_store;
49
50
	/**
51
	 * Customer data store.
52
	 *
53
	 * @var CustomerDataStore
54
	 */
55
	private $customer_data_store;
56
57
	/**
58
	 * Constructs and initializes an Mollie gateway
59
	 *
60
	 * @param Config $config Config.
61
	 */
62 39
	public function __construct( Config $config ) {
63 39
		parent::__construct( $config );
64
65 39
		$this->set_method( self::METHOD_HTTP_REDIRECT );
66
67
		// Supported features.
68 39
		$this->supports = array(
69
			'payment_status_request',
70
			'recurring_direct_debit',
71
			'recurring_credit_card',
72
			'recurring',
73
			'webhook',
74
			'webhook_log',
75
			'webhook_no_config',
76
		);
77
78
		// Client.
79 39
		$this->client = new Client( \strval( $config->api_key ) );
80
81
		// Data Stores.
82 39
		$this->profile_data_store  = new ProfileDataStore();
83 39
		$this->customer_data_store = new CustomerDataStore();
84
85
		// Actions.
86 39
		add_action( 'pronamic_payment_status_update', array( $this, 'copy_customer_id_to_wp_user' ), 99, 1 );
87 39
	}
88
89
	/**
90
	 * Get issuers
91
	 *
92
	 * @see Core_Gateway::get_issuers()
93
	 * @return array<int, array<string, array<string>>>
94
	 */
95 3
	public function get_issuers() {
96 3
		$groups = array();
97
98
		try {
99 3
			$result = $this->client->get_issuers();
100
101
			$groups[] = array(
102
				'options' => $result,
103
			);
104 3
		} catch ( Error $e ) {
105
			// Catch Mollie error.
106 3
			$error = new \WP_Error(
107 3
				'mollie_error',
108 3
				sprintf( '%1$s (%2$s) - %3$s', $e->get_title(), $e->getCode(), $e->get_detail() )
109
			);
110
111 3
			$this->set_error( $error );
112
		} catch ( \Exception $e ) {
113
			// Catch exceptions.
114
			$error = new \WP_Error( 'mollie_error', $e->getMessage() );
115
116
			$this->set_error( $error );
117
		}
118
119 3
		return $groups;
120
	}
121
122
	/**
123
	 * Get available payment methods.
124
	 *
125
	 * @see Core_Gateway::get_available_payment_methods()
126
	 * @return array<string>
127
	 */
128 2
	public function get_available_payment_methods() {
129 2
		$payment_methods = array();
130
131
		// Set sequence types to get payment methods for.
132 2
		$sequence_types = array( Sequence::ONE_OFF, Sequence::RECURRING, Sequence::FIRST );
133
134 2
		$results = array();
135
136 2
		foreach ( $sequence_types as $sequence_type ) {
137
			// Get active payment methods for Mollie account.
138
			try {
139 2
				$result = $this->client->get_payment_methods( $sequence_type );
140 2
			} catch ( Error $e ) {
141
				// Catch Mollie error.
142
				$error = new \WP_Error(
143
					'mollie_error',
144
					sprintf( '%1$s (%2$s) - %3$s', $e->get_title(), $e->getCode(), $e->get_detail() )
145
				);
146
147
				$this->set_error( $error );
148
149
				break;
150 2
			} catch ( \Exception $e ) {
151
				// Catch exceptions.
152 2
				$error = new \WP_Error( 'mollie_error', $e->getMessage() );
153
154 2
				$this->set_error( $error );
155
156 2
				break;
157
			}
158
159 2
			if ( Sequence::FIRST === $sequence_type ) {
160
				foreach ( $result as $method => $title ) {
161
					unset( $result[ $method ] );
162
163
					// Get WordPress payment method for direct debit method.
164
					$method         = Methods::transform_gateway_method( $method );
165
					$payment_method = array_search( $method, PaymentMethods::get_recurring_methods(), true );
166
167
					if ( $payment_method ) {
168
						$results[ $payment_method ] = $title;
169
					}
170
				}
171
			}
172
173 2
			if ( is_array( $result ) ) {
174 2
				$results = array_merge( $results, $result );
175
			}
176
		}
177
178
		// Transform to WordPress payment methods.
179 2
		foreach ( $results as $method => $title ) {
180 2
			if ( PaymentMethods::is_recurring_method( $method ) ) {
181
				$payment_method = $method;
182
			} else {
183 2
				$payment_method = Methods::transform_gateway_method( $method );
184
			}
185
186 2
			if ( $payment_method ) {
187 2
				$payment_methods[] = $payment_method;
188
			}
189
		}
190
191 2
		$payment_methods = array_unique( $payment_methods );
192
193 2
		return $payment_methods;
194
	}
195
196
	/**
197
	 * Get supported payment methods
198
	 *
199
	 * @see Pronamic_WP_Pay_Gateway::get_supported_payment_methods()
200
	 * @return array<string>
201
	 */
202 2
	public function get_supported_payment_methods() {
203
		return array(
204 2
			PaymentMethods::BANCONTACT,
205
			PaymentMethods::BANK_TRANSFER,
206
			PaymentMethods::BELFIUS,
207
			PaymentMethods::CREDIT_CARD,
208
			PaymentMethods::DIRECT_DEBIT,
209
			PaymentMethods::DIRECT_DEBIT_BANCONTACT,
210
			PaymentMethods::DIRECT_DEBIT_IDEAL,
211
			PaymentMethods::DIRECT_DEBIT_SOFORT,
212
			PaymentMethods::EPS,
213
			PaymentMethods::GIROPAY,
214
			PaymentMethods::IDEAL,
215
			PaymentMethods::KBC,
216
			PaymentMethods::PAYPAL,
217
			PaymentMethods::SOFORT,
218
		);
219
	}
220
221
	/**
222
	 * Get webhook URL for Mollie.
223
	 *
224
	 * @return string|null
225
	 */
226 4
	public function get_webhook_url() {
227 4
		$url = \rest_url( Integration::REST_ROUTE_NAMESPACE . '/webhook' );
228
229 4
		$host = wp_parse_url( $url, PHP_URL_HOST );
230
231 4
		if ( is_array( $host ) ) {
232
			// Parsing failure.
233
			$host = '';
234
		}
235
236 4
		if ( 'localhost' === $host ) {
237
			// Mollie doesn't allow localhost.
238 1
			return null;
239 3
		} elseif ( '.dev' === substr( $host, -4 ) ) {
240
			// Mollie doesn't allow the .dev TLD.
241 1
			return null;
242 2
		} elseif ( '.local' === substr( $host, -6 ) ) {
243
			// Mollie doesn't allow the .local TLD.
244 1
			return null;
245 1
		} elseif ( '.test' === substr( $host, -5 ) ) {
246
			// Mollie doesn't allow the .test TLD.
247
			return null;
248
		}
249
250 1
		return $url;
251
	}
252
253
	/**
254
	 * Start
255
	 *
256
	 * @see Pronamic_WP_Pay_Gateway::start()
257
	 * @param Payment $payment Payment.
258
	 * @return void
259
	 */
260
	public function start( Payment $payment ) {
261
		$request = new PaymentRequest(
262
			AmountTransformer::transform( $payment->get_total_amount() ),
263
			\strval( $payment->get_description() )
264
		);
265
266
		$request->redirect_url = $payment->get_return_url();
267
		$request->webhook_url  = $this->get_webhook_url();
268
269
		// Locale.
270
		$customer = $payment->get_customer();
271
272
		if ( null !== $customer ) {
273
			$request->locale = LocaleHelper::transform( $customer->get_locale() );
274
		}
275
276
		// Customer ID.
277
		$customer_id = $this->get_customer_id_for_payment( $payment );
278
279
		if ( null === $customer_id ) {
280
			$customer_id = $this->create_customer_for_payment( $payment );
281
		}
282
283
		if ( null !== $customer_id ) {
284
			$request->customer_id = $customer_id;
285
		}
286
287
		// Payment method.
288
		$payment_method = $payment->get_method();
289
290
		// Recurring payment method.
291
		$is_recurring_method = ( $payment->get_subscription() && PaymentMethods::is_recurring_method( $payment_method ) );
292
293
		// Consumer bank details.
294
		$consumer_bank_details = $payment->get_consumer_bank_details();
295
296
		if ( PaymentMethods::DIRECT_DEBIT === $payment_method && null !== $consumer_bank_details ) {
297
			$consumer_name = $consumer_bank_details->get_name();
298
			$consumer_iban = $consumer_bank_details->get_iban();
299
300
			$request->consumer_name    = $consumer_name;
301
			$request->consumer_account = $consumer_iban;
302
303
			// Check if one-off SEPA Direct Debit can be used, otherwise short circuit payment.
304
			if ( null !== $customer_id ) {
305
				// Find or create mandate.
306
				$mandate_id = $this->client->has_valid_mandate( $customer_id, PaymentMethods::DIRECT_DEBIT, $consumer_iban );
307
308
				if ( false === $mandate_id ) {
309
					$mandate = $this->client->create_mandate( $customer_id, $consumer_bank_details );
310
311
					$mandate_id = $mandate->id;
312
				}
313
314
				// Charge immediately on-demand.
315
				$request->sequence_type = Sequence::RECURRING;
316
				$request->mandate_id    = $mandate_id;
317
318
				$is_recurring_method = true;
319
320
				$payment->recurring = true;
321
			}
322
		}
323
324
		if ( false === $is_recurring_method ) {
325
			// Always use 'direct debit mandate via iDEAL/Bancontact/Sofort' payment methods as recurring method.
326
			$is_recurring_method = PaymentMethods::is_direct_debit_method( $payment_method );
327
		}
328
329
		if ( $is_recurring_method ) {
330
			$request->sequence_type = $payment->get_recurring() ? Sequence::RECURRING : Sequence::FIRST;
331
332
			if ( Sequence::FIRST === $request->sequence_type ) {
333
				$payment_method = PaymentMethods::get_first_payment_method( $payment_method );
334
			}
335
336
			if ( Sequence::RECURRING === $request->sequence_type ) {
337
				$payment->set_action_url( $payment->get_return_url() );
338
			}
339
		}
340
341
		// Leap of faith if the WordPress payment method could not transform to a Mollie method?
342
		$request->method = Methods::transform( $payment_method, $payment_method );
343
344
		// Issuer.
345
		if ( Methods::IDEAL === $request->method ) {
346
			$request->issuer = $payment->get_issuer();
347
		}
348
349
		// Due date.
350
		try {
351
			$due_date = new DateTime( sprintf( '+%s days', $this->config->due_date_days ) );
352
		} catch ( \Exception $e ) {
353
			$due_date = null;
354
		}
355
356
		$request->set_due_date( $due_date );
357
358
		// Create payment.
359
		$result = $this->client->create_payment( $request );
360
361
		// Set transaction ID.
362
		if ( isset( $result->id ) ) {
363
			$payment->set_transaction_id( $result->id );
364
		}
365
366
		// Set expiry date.
367
		/* phpcs:disable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase */
368
		if ( isset( $result->expiresAt ) ) {
369
			try {
370
				$expires_at = new DateTime( $result->expiresAt );
371
			} catch ( \Exception $e ) {
372
				$expires_at = null;
373
			}
374
375
			$payment->set_expiry_date( $expires_at );
376
		}
377
		/* phpcs:enable WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase */
378
379
		// Set status.
380
		if ( isset( $result->status ) ) {
381
			$payment->set_status( Statuses::transform( $result->status ) );
382
		}
383
384
		// Set bank transfer recipient details.
385
		if ( isset( $result->details ) ) {
386
			$bank_transfer_recipient_details = $payment->get_bank_transfer_recipient_details();
387
388
			if ( null === $bank_transfer_recipient_details ) {
389
				$bank_transfer_recipient_details = new BankTransferDetails();
390
391
				$payment->set_bank_transfer_recipient_details( $bank_transfer_recipient_details );
392
			}
393
394
			$bank_details = $bank_transfer_recipient_details->get_bank_account();
395
396
			if ( null === $bank_details ) {
397
				$bank_details = new BankAccountDetails();
398
399
				$bank_transfer_recipient_details->set_bank_account( $bank_details );
400
			}
401
402
			$details = $result->details;
403
404
			/*
405
			 * @codingStandardsIgnoreStart
406
			 *
407
			 * Ignore coding standards because of sniff WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
408
			 */
409
			if ( isset( $details->bankName ) ) {
410
				/**
411
				 * Set `bankName` as bank details name, as result "Stichting Mollie Payments"
412
				 * is not the name of a bank, but the account holder name.
413
				 */
414
				$bank_details->set_name( $details->bankName );
415
			}
416
417
			if ( isset( $details->bankAccount ) ) {
418
				$bank_details->set_iban( $details->bankAccount );
419
			}
420
421
			if ( isset( $details->bankBic ) ) {
422
				$bank_details->set_bic( $details->bankBic );
423
			}
424
425
			if ( isset( $details->transferReference ) ) {
426
				$bank_transfer_recipient_details->set_reference( $details->transferReference );
427
			}
428
			// @codingStandardsIgnoreEnd
429
		}
430
431
		// Set action URL.
432
		if ( isset( $result->_links ) ) {
433
			if ( isset( $result->_links->checkout->href ) ) {
434
				$payment->set_action_url( $result->_links->checkout->href );
435
			}
436
		}
437
	}
438
439
	/**
440
	 * Update status of the specified payment
441
	 *
442
	 * @param Payment $payment Payment.
443
	 * @return void
444
	 */
445
	public function update_status( Payment $payment ) {
446
		$transaction_id = $payment->get_transaction_id();
447
448
		if ( null === $transaction_id ) {
449
			return;
450
		}
451
452
		$mollie_payment = $this->client->get_payment( $transaction_id );
453
454
		if ( isset( $mollie_payment->status ) ) {
455
			$payment->set_status( Statuses::transform( $mollie_payment->status ) );
456
		}
457
458
		/**
459
		 * Mollie profile.
460
		 */
461
		$mollie_profile = new Profile();
462
463
		// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- Mollie.
464
		$mollie_profile->set_id( $mollie_payment->profileId );
465
466
		$profile_internal_id = $this->profile_data_store->get_or_insert_profile( $mollie_profile );
467
468
		/**
469
		 * If the Mollie payment contains a customer ID we will try to connect
470
		 * this Mollie customer ID the WordPress user and subscription.
471
		 * This can be usefull in case when a WordPress user is created after
472
		 * a succesfull payment.
473
		 *
474
		 * @link https://www.gravityforms.com/add-ons/user-registration/
475
		 */
476
477
		// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- Mollie.
478
		if ( isset( $mollie_payment->customerId ) ) {
479
			// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- Mollie.
480
			$mollie_customer = new Customer( $mollie_payment->customerId );
481
482
			$customer_internal_id = $this->customer_data_store->get_or_insert_customer(
0 ignored issues
show
Unused Code introduced by
The assignment to $customer_internal_id is dead and can be removed.
Loading history...
483
				$mollie_customer,
484
				array(
485
					'profile_id' => $profile_internal_id,
486
				),
487
				array(
488
					'profile_id' => '%s',
489
				)
490
			);
491
492
			// Meta.
493
			$customer_id = $payment->get_meta( 'mollie_customer_id' );
494
495
			if ( empty( $customer_id ) ) {
496
				$payment->set_meta( 'mollie_customer_id', $mollie_customer->get_id() );
497
			}
498
499
			// Customer.
500
			$customer = $payment->get_customer();
501
502
			if ( null !== $customer ) {
503
				// Connect to user.
504
				$user_id = $customer->get_user_id();
505
506
				if ( null !== $user_id ) {
507
					$user = \get_user_by( 'id', $user_id );
508
509
					if ( false !== $user ) {
510
						$this->customer_data_store->connect_mollie_customer_to_wp_user( $mollie_customer, $user );
511
					}
512
				}
513
			}
514
515
			// Subscription.
516
			$subscription = $payment->get_subscription();
517
518
			if ( null !== $subscription ) {
519
				$customer_id = $subscription->get_meta( 'mollie_customer_id' );
520
521
				if ( empty( $customer_id ) ) {
522
					$subscription->set_meta( 'mollie_customer_id', $mollie_customer->get_id() );
523
				}
524
			}
525
		}
526
527
		if ( isset( $mollie_payment->details ) ) {
528
			$consumer_bank_details = $payment->get_consumer_bank_details();
529
530
			if ( null === $consumer_bank_details ) {
531
				$consumer_bank_details = new BankAccountDetails();
532
533
				$payment->set_consumer_bank_details( $consumer_bank_details );
534
			}
535
536
			$details = $mollie_payment->details;
537
538
			/*
539
			 * @codingStandardsIgnoreStart
540
			 *
541
			 * Ignore coding standards because of sniff WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
542
			 */
543
			if ( isset( $details->consumerName ) ) {
544
				$consumer_bank_details->set_name( $details->consumerName );
545
			}
546
547
			if ( isset( $details->cardHolder ) ) {
548
				$consumer_bank_details->set_name( $details->cardHolder );
549
			}
550
551
			if ( isset( $details->cardNumber ) ) {
552
				// The last four digits of the card number.
553
				$consumer_bank_details->set_account_number( $details->cardNumber );
554
			}
555
556
			if ( isset( $details->cardCountryCode ) ) {
557
				// The ISO 3166-1 alpha-2 country code of the country the card was issued in.
558
				$consumer_bank_details->set_country( $details->cardCountryCode );
559
			}
560
561
			if ( isset( $details->consumerAccount ) ) {
562
				switch ( $mollie_payment->method ) {
563
					case Methods::BELFIUS:
564
					case Methods::DIRECT_DEBIT:
565
					case Methods::IDEAL:
566
					case Methods::KBC:
567
					case Methods::SOFORT:
568
						$consumer_bank_details->set_iban( $details->consumerAccount );
569
570
						break;
571
					case Methods::BANCONTACT:
572
					case Methods::BANKTRANSFER:
573
					case Methods::PAYPAL:
574
					default:
575
						$consumer_bank_details->set_account_number( $details->consumerAccount );
576
577
						break;
578
				}
579
			}
580
581
			if ( isset( $details->consumerBic ) ) {
582
				$consumer_bank_details->set_bic( $details->consumerBic );
583
			}
584
585
			/*
586
			 * Failure reason.
587
			 */
588
			$failure_reason = $payment->get_failure_reason();
589
590
			if ( null === $failure_reason ) {
591
				$failure_reason = new FailureReason();
592
593
				$payment->set_failure_reason( $failure_reason );
594
			}
595
596
			// SEPA Direct Debit.
597
			if ( isset( $details->bankReasonCode ) ) {
598
				$failure_reason->set_code( $details->bankReasonCode );
599
			}
600
601
			if ( isset( $details->bankReasonCode ) ) {
602
				$failure_reason->set_message( $details->bankReason );
603
			}
604
605
			// Credit card.
606
			if ( isset( $details->failureReason ) ) {
607
				$failure_reason->set_code( $details->failureReason );
608
			}
609
610
			if ( isset( $details->failureMessage ) ) {
611
				$failure_reason->set_message( $details->failureMessage );
612
			}
613
			// @codingStandardsIgnoreEnd
614
		}
615
	}
616
617
	/**
618
	 * Get Mollie customer ID for payment.
619
	 *
620
	 * @param Payment $payment Payment.
621
	 * @return string|null
622
	 */
623 10
	public function get_customer_id_for_payment( Payment $payment ) {
624 10
		$customer_ids = $this->get_customer_ids_for_payment( $payment );
625
626 10
		$customer_id = $this->get_first_existing_customer_id( $customer_ids );
627
628 10
		return $customer_id;
629
	}
630
631
	/**
632
	 * Get Mollie customers for the specified payment.
633
	 *
634
	 * @param Payment $payment Payment.
635
	 * @return array<string>
636
	 */
637 10
	private function get_customer_ids_for_payment( Payment $payment ) {
638 10
		$customer_ids = array();
639
640
		// Customer ID from subscription meta.
641 10
		$subscription = $payment->get_subscription();
642
643 10
		if ( null !== $subscription ) {
644 10
			$customer_id = $this->get_customer_id_for_subscription( $subscription );
645
646 10
			if ( null !== $customer_id ) {
647 4
				$customer_ids[] = $customer_id;
648
			}
649
		}
650
651
		// Customer ID from WordPress user.
652 10
		$customer = $payment->get_customer();
653
654 10
		if ( null !== $customer ) {
655 9
			$user_id = $customer->get_user_id();
656
657 9
			if ( ! empty( $user_id ) ) {
658 7
				$user_customer_ids = $this->get_customer_ids_for_user( $user_id );
659
660 7
				$customer_ids = \array_merge( $customer_ids, $user_customer_ids );
661
			}
662
		}
663
664 10
		return $customer_ids;
665
	}
666
667
	/**
668
	 * Get Mollie customers for the specified WordPress user ID.
669
	 *
670
	 * @param int $user_id WordPress user ID.
671
	 * @return array<string>
672
	 */
673 24
	public function get_customer_ids_for_user( $user_id ) {
674 24
		$customer_query = new CustomerQuery(
675
			array(
676 24
				'user_id' => $user_id,
677
			)
678
		);
679
680 24
		$customers = $customer_query->get_customers();
681
682 24
		$customer_ids = wp_list_pluck( $customers, 'mollie_id' );
683
684 24
		return $customer_ids;
685
	}
686
687
	/**
688
	 * Get customer ID for subscription.
689
	 *
690
	 * @param Subscription $subscription Subscription.
691
	 * @return string|null
692
	 */
693 10
	private function get_customer_id_for_subscription( Subscription $subscription ) {
694 10
		$customer_id = $subscription->get_meta( 'mollie_customer_id' );
695
696 10
		if ( empty( $customer_id ) ) {
697
			// Try to get (legacy) customer ID from first payment.
698 7
			$first_payment = $subscription->get_first_payment();
699
700 7
			if ( null !== $first_payment ) {
701 7
				$customer_id = $first_payment->get_meta( 'mollie_customer_id' );
702
			}
703
		}
704
705 10
		if ( empty( $customer_id ) ) {
706 6
			return null;
707
		}
708
709 4
		return $customer_id;
710
	}
711
712
	/**
713
	 * Get first existing customer from customers list.
714
	 *
715
	 * @param array<string> $customer_ids Customers.
716
	 * @return string|null
717
	 */
718 10
	private function get_first_existing_customer_id( $customer_ids ) {
719 10
		$customer_ids = \array_filter( $customer_ids );
720
721 10
		$customer_ids = \array_unique( $customer_ids );
722
723 10
		foreach ( $customer_ids as $customer_id ) {
724 4
			$customer = $this->client->get_customer( $customer_id );
725
726 4
			if ( null !== $customer ) {
727 4
				return $customer_id;
728
			}
729
		}
730
731 6
		return null;
732
	}
733
734
	/**
735
	 * Create customer for payment.
736
	 *
737
	 * @param Payment $payment Payment.
738
	 * @return string|null
739
	 * @throws Error Throws Error when Mollie error occurs.
740
	 */
741
	private function create_customer_for_payment( Payment $payment ) {
742
		$mollie_customer = new Customer();
743
		$mollie_customer->set_mode( $this->config->is_test_mode() ? 'test' : 'live' );
744
		$mollie_customer->set_email( $payment->get_email() );
745
746
		$pronamic_customer = $payment->get_customer();
747
748
		if ( null !== $pronamic_customer ) {
749
			// Name.
750
			$name = \strval( $pronamic_customer->get_name() );
751
752
			if ( '' !== $name ) {
753
				$mollie_customer->set_name( $name );
754
			}
755
756
			// Locale.
757
			$locale = $pronamic_customer->get_locale();
758
759
			if ( null !== $locale ) {
760
				$mollie_customer->set_locale( LocaleHelper::transform( $locale ) );
761
			}
762
		}
763
764
		// Try to get name from consumer bank details.
765
		$consumer_bank_details = $payment->get_consumer_bank_details();
766
767
		if ( null === $mollie_customer->get_name() && null !== $consumer_bank_details ) {
768
			$name = $consumer_bank_details->get_name();
769
770
			if ( null !== $name ) {
771
				$mollie_customer->set_name( $name );
772
			}
773
		}
774
775
		// Create customer.
776
		$mollie_customer = $this->client->create_customer( $mollie_customer );
777
778
		$customer_id = $this->customer_data_store->insert_customer( $mollie_customer );
0 ignored issues
show
Unused Code introduced by
The assignment to $customer_id is dead and can be removed.
Loading history...
779
780
		// Connect to user.
781
		if ( null !== $pronamic_customer ) {
782
			$user_id = $pronamic_customer->get_user_id();
783
784
			if ( null !== $user_id ) {
785
				$user = \get_user_by( 'id', $user_id );
786
787
				if ( false !== $user ) {
788
					$this->customer_data_store->connect_mollie_customer_to_wp_user( $mollie_customer, $user );
789
				}
790
			}
791
		}
792
793
		// Store customer ID in subscription meta.
794
		$subscription = $payment->get_subscription();
795
796
		if ( null !== $subscription ) {
797
			$subscription->set_meta( 'mollie_customer_id', $mollie_customer->get_id() );
798
		}
799
800
		return $mollie_customer->get_id();
801
	}
802
803
	/**
804
	 * Copy Mollie customer ID from subscription meta to WordPress user meta.
805
	 *
806
	 * @param Payment $payment Payment.
807
	 * @return void
808
	 */
809 27
	public function copy_customer_id_to_wp_user( Payment $payment ) {
810 27
		if ( $this->config->id !== $payment->config_id ) {
811 1
			return;
812
		}
813
814
		// Subscription.
815 26
		$subscription = $payment->get_subscription();
816
817
		// Customer.
818 26
		$customer = $payment->get_customer();
819
820 26
		if ( null === $customer && null !== $subscription ) {
821 17
			$customer = $subscription->get_customer();
822
		}
823
824 26
		if ( null === $customer ) {
825 1
			return;
826
		}
827
828
		// WordPress user.
829 25
		$user_id = $customer->get_user_id();
830
831 25
		if ( null === $user_id ) {
832 2
			return;
833
		}
834
835 23
		$user = \get_user_by( 'id', $user_id );
836
837 23
		if ( false === $user ) {
838 12
			return;
839
		}
840
841
		// Customer IDs.
842 11
		$customer_ids = array();
843
844
		// Payment.
845 11
		$customer_ids[] = $payment->get_meta( 'mollie_customer_id' );
846
847
		// Subscription.
848 11
		if ( null !== $subscription ) {
849 11
			$customer_ids[] = $subscription->get_meta( 'mollie_customer_id' );
850
		}
851
852
		// Connect.
853 11
		$customer_ids = \array_filter( $customer_ids );
854 11
		$customer_ids = \array_unique( $customer_ids );
855
856 11
		foreach ( $customer_ids as $customer_id ) {
857 2
			$customer = new Customer( $customer_id );
858
859 2
			$this->customer_data_store->get_or_insert_customer( $customer );
860
861 2
			$this->customer_data_store->connect_mollie_customer_to_wp_user( $customer, $user );
862
		}
863 11
	}
864
}
865