Failed Conditions
Push — develop ( d7c062...d3bbf1 )
by Reüel
11:56 queued 04:26
created

Client   D

Complexity

Total Complexity 58

Size/Duplication

Total Lines 689
Duplicated Lines 0 %

Test Coverage

Coverage 27.32%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 152
c 3
b 0
f 0
dl 0
loc 689
ccs 50
cts 183
cp 0.2732
rs 4.5599
wmc 58

40 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A get_payment_server_url() 0 2 1
A set_amount() 0 2 1
A set_payment_id() 0 2 1
A get_push_url() 0 2 1
A set_ideal_issuer() 0 2 1
A get_return_reject_url() 0 2 1
A set_excluded_services() 0 2 1
A set_invoice_number() 0 2 1
A set_website_key() 0 2 1
A get_currency() 0 2 1
A get_invoice_number() 0 2 1
A set_secret_key() 0 2 1
A get_requested_services() 0 2 1
A get_fields() 0 30 1
A get_return_url() 0 2 1
A set_return_reject_url() 0 2 1
A set_culture() 0 2 1
A get_amount() 0 2 1
A set_return_cancel_url() 0 2 1
A get_excluded_services() 0 2 1
D get_issuers() 0 86 18
A verify_request() 0 33 2
A get_payment_id() 0 2 1
A add_requested_service() 0 2 1
A get_ideal_issuer() 0 2 1
A get_description() 0 2 1
A set_description() 0 2 1
A get_return_cancel_url() 0 2 1
A set_currency() 0 2 1
A get_culture() 0 2 1
A set_return_error_url() 0 2 1
A set_payment_method() 0 2 1
A get_return_error_url() 0 2 1
A set_push_url() 0 2 1
A set_payment_server_url() 0 2 1
A get_payment_method() 0 2 1
A set_return_url() 0 2 1
A get_secret_key() 0 2 1
A get_website_key() 0 2 1

How to fix   Complexity   

Complex Class

Complex classes like Client often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Client, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace Pronamic\WordPress\Pay\Gateways\Buckaroo;
4
5
/**
6
 * Title: Buckaroo client
7
 * Description:
8
 * Copyright: 2005-2021 Pronamic
9
 * Company: Pronamic
10
 *
11
 * @author Remco Tolsma
12
 * @version 2.1.1
13
 * @since 1.0.0
14
 */
15
class Client {
16
	/**
17
	 * Gateway URL
18
	 *
19
	 * @var string
20
	 */
21
	const GATEWAY_URL = 'https://checkout.buckaroo.nl/html/';
22
23
	/**
24
	 * Gateway test URL
25
	 *
26
	 * @var string
27
	 */
28
	const GATEWAY_TEST_URL = 'https://testcheckout.buckaroo.nl/html/';
29
30
	/**
31
	 * Gateway Name-Value-Pair URL
32
	 *
33
	 * @var string
34
	 */
35
	const GATEWAY_NVP_URL = 'https://checkout.buckaroo.nl/nvp/';
36
37
	/**
38
	 * Gateway Name-Value-Pair test URL
39
	 *
40
	 * @var string
41
	 */
42
	const GATEWAY_NVP_TEST_URL = 'https://testcheckout.buckaroo.nl/nvp/';
43
44
	/**
45
	 * Indicator for the iDEAL payment method
46
	 *
47
	 * @var string
48
	 */
49
	const PAYMENT_METHOD_IDEAL = 'ideal';
50
51
	/**
52
	 * The payment server URL
53
	 *
54
	 * @var string
55
	 */
56
	private $payment_server_url;
57
58
	/**
59
	 * The amount
60
	 *
61
	 * @var float|null
62
	 */
63
	private $amount;
64
65
	/**
66
	 * The website key
67
	 *
68
	 * @var string|null
69
	 */
70
	private $website_key;
71
72
	/**
73
	 * The secret key
74
	 *
75
	 * @var string|null
76
	 */
77
	private $secret_key;
78
79
	/**
80
	 * The payment method
81
	 *
82
	 * @var string|null
83
	 */
84
	private $payment_method;
85
86
	/**
87
	 * The iDEAL issuer
88
	 *
89
	 * @since 1.2.4
90
	 * @var string|null
91
	 */
92
	private $ideal_issuer;
93
94
	/**
95
	 * The country code (culture)
96
	 *
97
	 * @var string|null
98
	 */
99
	private $culture;
100
101
	/**
102
	 * The currency
103
	 *
104
	 * @var string|null
105
	 */
106
	private $currency;
107
108
	/**
109
	 * The invoice number
110
	 *
111
	 * @var string|null
112
	 */
113
	private $invoice_number;
114
115
	/**
116
	 * The description
117
	 *
118
	 * @var string|null
119
	 */
120
	private $description;
121
122
	/**
123
	 * The return url
124
	 *
125
	 * @var string|null
126
	 */
127
	private $return_url;
128
129
	/**
130
	 * The return reject url
131
	 *
132
	 * @var string|null
133
	 */
134
	private $return_reject_url;
135
136
	/**
137
	 * The return error url
138
	 *
139
	 * @var string|null
140
	 */
141
	private $return_error_url;
142
143
	/**
144
	 * The return cancel url
145
	 *
146
	 * @var string|null
147
	 */
148
	private $return_cancel_url;
149
150
	/**
151
	 * Push URL
152
	 *
153
	 * @var string|null
154
	 */
155
	private $push_url;
156
157
	/**
158
	 * Requested services
159
	 *
160
	 * @var array
161
	 */
162
	private $requested_services;
163
164
	/**
165
	 * Excluded services
166
	 *
167
	 * @var string|null
168
	 */
169
	private $excluded_services;
170
171
	/**
172
	 * Pronamic payment ID
173
	 *
174
	 * @var string|null
175
	 */
176
	private $payment_id;
177
178
	/**
179
	 * Constructs and initialize a iDEAL kassa object
180
	 */
181 1
	public function __construct() {
182 1
		$this->set_payment_server_url( self::GATEWAY_URL );
183
184 1
		$this->requested_services = array();
185 1
	}
186
187
	/**
188
	 * Get the payment server URL
189
	 *
190
	 * @return string the payment server URL
191
	 */
192
	public function get_payment_server_url() {
193
		return $this->payment_server_url;
194
	}
195
196
	/**
197
	 * Set the payment server URL
198
	 *
199
	 * @param string $url an URL
200
	 * @return void
201
	 */
202 1
	public function set_payment_server_url( $url ) {
203 1
		$this->payment_server_url = $url;
204 1
	}
205
206
	/**
207
	 * Get website key.
208
	 *
209
	 * @return string|null
210
	 */
211 1
	public function get_website_key() {
212 1
		return $this->website_key;
213
	}
214
215
	/**
216
	 * Set website key.
217
	 *
218
	 * @param string|null $website_key Website key.
219
	 * @return void
220
	 */
221 1
	public function set_website_key( $website_key ) {
222 1
		$this->website_key = $website_key;
223 1
	}
224
225
	/**
226
	 * Get secret key.
227
	 *
228
	 * @return string|null
229
	 */
230 1
	public function get_secret_key() {
231 1
		return $this->secret_key;
232
	}
233
234
	/**
235
	 * Set secret key.
236
	 *
237
	 * @param string|null $secret_key Secret key.
238
	 * @return void
239
	 */
240 1
	public function set_secret_key( $secret_key ) {
241 1
		$this->secret_key = $secret_key;
242 1
	}
243
244
	/**
245
	 * Get payment method.
246
	 *
247
	 * @return string|null
248
	 */
249
	public function get_payment_method() {
250
		return $this->payment_method;
251
	}
252
253
	/**
254
	 * Set payment method.
255
	 *
256
	 * @param string|null $payment_method Payment method.
257
	 * @return void
258
	 */
259
	public function set_payment_method( $payment_method ) {
260
		$this->payment_method = $payment_method;
261
	}
262
263
	/**
264
	 * Get iDEAL issuer.
265
	 *
266
	 * @since 1.2.4
267
	 * @return string|null
268
	 */
269
	public function get_ideal_issuer() {
270
		return $this->ideal_issuer;
271
	}
272
273
	/**
274
	 * Set iDEAL issuer.
275
	 *
276
	 * @since 1.2.4
277
	 *
278
	 * @param string|null $issuer
279
	 * @return void
280
	 */
281
	public function set_ideal_issuer( $issuer ) {
282
		$this->ideal_issuer = $issuer;
283
	}
284
285
	/**
286
	 * Get requested services.
287
	 *
288
	 * @return array
289
	 */
290
	public function get_requested_services() {
291
		return $this->requested_services;
292
	}
293
294
	/**
295
	 * Add requested service.
296
	 *
297
	 * @param string $service Service.
298
	 * @return void
299
	 */
300
	public function add_requested_service( $service ) {
301
		$this->requested_services[] = $service;
302
	}
303
304
	/**
305
	 * Get excluded services.
306
	 *
307
	 * @return string|null
308
	 */
309
	public function get_excluded_services() {
310
		return $this->excluded_services;
311
	}
312
313
	/**
314
	 * Set excluded services.
315
	 *
316
	 * @param string|null $service Excluded services.
317
	 * @return void
318
	 */
319
	public function set_excluded_services( $service ) {
320
		$this->excluded_services = $service;
321
	}
322
323
	/**
324
	 * Get culture.
325
	 *
326
	 * @return string|null
327
	 */
328
	public function get_culture() {
329
		return $this->culture;
330
	}
331
332
	/**
333
	 * Set culture.
334
	 *
335
	 * @param string|null $culture Culture.
336
	 * @return void
337
	 */
338
	public function set_culture( $culture ) {
339
		$this->culture = $culture;
340
	}
341
342
	/**
343
	 * Get currency.
344
	 *
345
	 * @return string|null
346
	 */
347
	public function get_currency() {
348
		return $this->currency;
349
	}
350
351
	/**
352
	 * Set currency.
353
	 *
354
	 * @param string|null $currency Currency.
355
	 * @return void
356
	 */
357
	public function set_currency( $currency ) {
358
		$this->currency = $currency;
359
	}
360
361
	/**
362
	 * Get invoice number.
363
	 *
364
	 * @return string|null
365
	 */
366
	public function get_invoice_number() {
367
		return $this->invoice_number;
368
	}
369
370
	/**
371
	 * Set invoice number.
372
	 *
373
	 * @param string|null $invoice_number Invoice number.
374
	 * @return void
375
	 */
376
	public function set_invoice_number( $invoice_number ) {
377
		$this->invoice_number = $invoice_number;
378
	}
379
380
	/**
381
	 * Get description.
382
	 *
383
	 * @return string|null
384
	 */
385
	public function get_description() {
386
		return $this->description;
387
	}
388
389
	/**
390
	 * Set description.
391
	 *
392
	 * @param string|null $description Description.
393
	 * @return void
394
	 */
395
	public function set_description( $description ) {
396
		$this->description = $description;
397
	}
398
399
	/**
400
	 * Get amount.
401
	 *
402
	 * @return float|null
403
	 */
404
	public function get_amount() {
405
		return $this->amount;
406
	}
407
408
	/**
409
	 * Set amount.
410
	 *
411
	 * @param float|null $amount Amount.
412
	 * @return void
413
	 */
414
	public function set_amount( $amount ) {
415
		$this->amount = $amount;
416
	}
417
418
	/**
419
	 * Get return URL
420
	 *
421
	 * @return string|null
422
	 */
423
	public function get_return_url() {
424
		return $this->return_url;
425
	}
426
427
	/**
428
	 * Set return URL
429
	 *
430
	 * @param string|null $url Return URL.
431
	 * @return void
432
	 */
433
	public function set_return_url( $url ) {
434
		$this->return_url = $url;
435
	}
436
437
	/**
438
	 * Get return reject URL
439
	 *
440
	 * @return string|null
441
	 */
442
	public function get_return_reject_url() {
443
		return $this->return_reject_url;
444
	}
445
446
	/**
447
	 * Set return reject URL
448
	 *
449
	 * @param string|null $url Return reject URL.
450
	 * @return void
451
	 */
452
	public function set_return_reject_url( $url ) {
453
		$this->return_reject_url = $url;
454
	}
455
456
	/**
457
	 * Get return error URL
458
	 *
459
	 * @return string|null
460
	 */
461
	public function get_return_error_url() {
462
		return $this->return_error_url;
463
	}
464
465
	/**
466
	 * Set return error URL
467
	 *
468
	 * @param string|null $url Return error URL.
469
	 * @return void
470
	 */
471
	public function set_return_error_url( $url ) {
472
		$this->return_error_url = $url;
473
	}
474
475
	/**
476
	 * Get return cancel URL
477
	 *
478
	 * @return string|null
479
	 */
480
	public function get_return_cancel_url() {
481
		return $this->return_cancel_url;
482
	}
483
484
	/**
485
	 * Set return cancel URL
486
	 *
487
	 * @param string|null $url Return cancel URL.
488
	 * @return void
489
	 */
490
	public function set_return_cancel_url( $url ) {
491
		$this->return_cancel_url = $url;
492
	}
493
494
	/**
495
	 * Get push URL
496
	 *
497
	 * @return string|null
498
	 */
499
	public function get_push_url() {
500
		return $this->push_url;
501
	}
502
503
	/**
504
	 * Set push URL
505
	 *
506
	 * @param string|null $url Push URL.
507
	 * @return void
508
	 */
509
	public function set_push_url( $url ) {
510
		$this->push_url = $url;
511
	}
512
513
	/**
514
	 * Get Pronamic payment ID
515
	 *
516
	 * @return string|null
517
	 */
518
	public function get_payment_id() {
519
		return $this->payment_id;
520
	}
521
522
	/**
523
	 * Set Pronamic payment ID
524
	 *
525
	 * @param string|null $payment_id Payment ID.
526
	 * @return void
527
	 */
528
	public function set_payment_id( $payment_id ) {
529
		$this->payment_id = $payment_id;
530
	}
531
532
	/**
533
	 * Get issuers
534
	 *
535
	 * @since 1.2.4
536
	 * @link http://support.buckaroo.nl/index.php/Service_iDEAL#iDEAL_banken_lijst_opvragen
537
	 * @return array
538
	 */
539 1
	public function get_issuers() {
540 1
		$issuers = array();
541
542 1
		$url = add_query_arg( 'op', 'TransactionRequestSpecification', self::GATEWAY_NVP_TEST_URL );
543
544
		$data = array(
545 1
			'brq_websitekey'        => $this->get_website_key(),
546 1
			'brq_services'          => 'ideal',
547 1
			'brq_latestversiononly' => 'True',
548
		);
549
550 1
		$signature = Security::create_signature( $data, (string) $this->get_secret_key() );
551
552 1
		$data[ Parameters::SIGNATURE ] = $signature;
553
554 1
		$result = wp_remote_post(
555 1
			$url,
556
			array(
557 1
				'body' => http_build_query( $data ),
558
			)
559
		);
560
561 1
		$body = wp_remote_retrieve_body( $result );
562
563 1
		wp_parse_str( $body, $data );
564
565 1
		$data = Util::transform_flat_response( $data );
566
567 1
		$error_msg = __( 'Unable to retrieve issuers from Buckaroo.', 'pronamic_ideal' );
568
569 1
		if ( 200 !== wp_remote_retrieve_response_code( $result ) ) {
570
			throw new \Exception( $error_msg );
571
		}
572
573 1
		if ( isset( $data['BRQ_APIRESULT'] ) && 'Fail' === $data['BRQ_APIRESULT'] ) {
574
			if ( isset( $data['BRQ_APIERRORMESSAGE'] ) && is_string( $data['BRQ_APIERRORMESSAGE'] ) ) {
575
				$error_msg = sprintf( '%s %s', $error_msg, $data['BRQ_APIERRORMESSAGE'] );
576
			}
577
578
			throw new \Exception( $error_msg );
579
		}
580
581 1
		if ( ! isset( $data['BRQ_SERVICES'] ) ) {
582
			return $issuers;
583
		}
584
585 1
		if ( \is_array( $data['BRQ_SERVICES'] ) ) {
586 1
			foreach ( $data['BRQ_SERVICES'] as $service ) {
587 1
				if ( ! isset( $service['NAME'], $service['VERSION'], $service['ACTIONDESCRIPTION'] ) ) {
588
					return $issuers;
589
				}
590
591 1
				if ( PaymentMethods::IDEAL !== $service['NAME'] ) {
592
					continue;
593
				}
594
595 1
				foreach ( $service['ACTIONDESCRIPTION'] as $action ) {
596 1
					if ( ! isset( $action['NAME'], $action['REQUESTPARAMETERS'] ) ) {
597
						return $issuers;
598
					}
599
600 1
					if ( 'Pay' !== $action['NAME'] ) {
601 1
						continue;
602
					}
603
604 1
					foreach ( $action['REQUESTPARAMETERS'] as $parameter ) {
605
606 1
						if ( ! isset( $parameter['NAME'], $parameter['LISTITEMDESCRIPTION'] ) ) {
607
							return $issuers;
608
						}
609
610 1
						if ( 'issuer' !== $parameter['NAME'] ) {
611
							continue;
612
						}
613
614 1
						foreach ( $parameter['LISTITEMDESCRIPTION'] as $issuer ) {
615 1
							$issuers[ $issuer['VALUE'] ] = $issuer['DESCRIPTION'];
616
						}
617
618 1
						break;
619
					}
620
				}
621
			}
622
		}
623
624 1
		return $issuers;
625
	}
626
627
	/**
628
	 * Get HTML fields
629
	 *
630
	 * @since 1.1.1
631
	 * @return array<string, array|float|int|string|null>
632
	 */
633
	public function get_fields() {
634
		// Description with HTML entities such as `&#038;` decoded into `&`, to prevent invalid signature.
635
		$description = html_entity_decode( (string) $this->get_description() );
636
637
		// Data.
638
		$data = array(
639
			Parameters::ADD_PRONAMIC_PAYMENT_ID => $this->get_payment_id(),
640
			Parameters::WEBSITE_KEY             => $this->get_website_key(),
641
			Parameters::INVOICE_NUMBER          => $this->get_invoice_number(),
642
			Parameters::AMOUNT                  => number_format( floatval( $this->get_amount() ), 2, '.', '' ),
643
			Parameters::CURRENCY                => $this->get_currency(),
644
			Parameters::CULTURE                 => $this->get_culture(),
645
			Parameters::DESCRIPTION             => $description,
646
			Parameters::PAYMENT_METHOD          => $this->get_payment_method(),
647
			Parameters::RETURN_URL              => $this->get_return_url(),
648
			Parameters::RETURN_REJECT_URL       => $this->get_return_reject_url(),
649
			Parameters::RETURN_ERROR_URL        => $this->get_return_error_url(),
650
			Parameters::RETURN_CANCEL_URL       => $this->get_return_cancel_url(),
651
			Parameters::PUSH_URL                => $this->get_push_url(),
652
			Parameters::PUSH_FAILURE_URL        => $this->get_push_url(),
653
			Parameters::REQUESTED_SERVICES      => implode( ',', $this->get_requested_services() ),
654
			Parameters::EXCLUDED_SERVICES       => $this->get_excluded_services(),
655
			Parameters::IDEAL_ISSUER            => $this->get_ideal_issuer(),
656
		);
657
658
		$signature = Security::create_signature( $data, (string) $this->get_secret_key() );
659
660
		$data[ Parameters::SIGNATURE ] = $signature;
661
662
		return $data;
663
	}
664
665
	/**
666
	 * Verify request Buckaroo
667
	 *
668
	 * @param array $data Data.
669
	 * @return false|array<string, float|int|string>
670
	 */
671
	public function verify_request( $data ) {
672
		$result = false;
673
674
		$signature = (string) Security::get_signature( $data );
675
676
		$signature_check = Security::create_signature( $data, (string) $this->get_secret_key() );
677
678
		if ( 0 === strcasecmp( $signature, $signature_check ) ) {
679
			$data = array_change_key_case( $data, CASE_LOWER );
680
681
			$result = filter_var_array(
682
				$data,
683
				array(
684
					Parameters::ADD_PRONAMIC_PAYMENT_ID    => FILTER_SANITIZE_STRING,
685
					Parameters::PAYMENT                    => FILTER_SANITIZE_STRING,
686
					Parameters::PAYMENT_METHOD             => FILTER_SANITIZE_STRING,
687
					Parameters::STATUS_CODE                => FILTER_VALIDATE_INT,
688
					Parameters::STATUS_CODE_DETAIL         => FILTER_SANITIZE_STRING,
689
					Parameters::STATUS_MESSAGE             => FILTER_SANITIZE_STRING,
690
					Parameters::INVOICE_NUMBER             => FILTER_SANITIZE_STRING,
691
					Parameters::AMOUNT                     => FILTER_VALIDATE_FLOAT,
692
					Parameters::CURRENCY                   => FILTER_SANITIZE_STRING,
693
					Parameters::TIMESTAMP                  => FILTER_SANITIZE_STRING,
694
					Parameters::SERVICE_IDEAL_CONSUMER_ISSUER => FILTER_SANITIZE_STRING,
695
					Parameters::SERVICE_IDEAL_CONSUMER_NAME => FILTER_SANITIZE_STRING,
696
					Parameters::SERVICE_IDEAL_CONSUMER_IBAN => FILTER_SANITIZE_STRING,
697
					Parameters::SERVICE_IDEAL_CONSUMER_BIC => FILTER_SANITIZE_STRING,
698
					Parameters::TRANSACTIONS               => FILTER_SANITIZE_STRING,
699
				)
700
			);
701
		}
702
703
		return $result;
704
	}
705
}
706