Issues (9)

src/Client.php (3 issues)

1
<?php
2
3
namespace Pronamic\WordPress\Pay\Gateways\OmniKassa;
4
5
use Pronamic\WordPress\DateTime\DateTime;
6
use Pronamic\WordPress\Pay\Core\Util as Core_Util;
7
8
/**
9
 * Title: OmniKassa client
10
 * Description:
11
 * Copyright: 2005-2020 Pronamic
12
 * Company: Pronamic
13
 *
14
 * @author  Remco Tolsma
15
 * @version 2.0.3
16
 * @since   1.0.0
17
 */
18
class Client {
19
	/**
20
	 * Action URL to start a payment request in the test environment,
21
	 * the POST data is sent to.
22
	 *
23
	 * @see page 14 - http://pronamic.nl/wp-content/uploads/2013/10/integratiehandleiding_rabo_omnikassa_en_versie_5_0_juni_2013_10_29451215.pdf
24
	 * @var string
25
	 */
26
	const ACTION_URL_TEST = 'https://payment-webinit.simu.omnikassa.rabobank.nl/paymentServlet';
27
28
	/**
29
	 * Action URL For a payment request in the production environment,
30
	 * the POST data is sent to
31
	 *
32
	 * @see page 14 - http://pronamic.nl/wp-content/uploads/2013/10/integratiehandleiding_rabo_omnikassa_en_versie_5_0_juni_2013_10_29451215.pdf
33
	 * @var string
34
	 */
35
	const ACTION_URL_PRUDCTION = 'https://payment-webinit.omnikassa.rabobank.nl/paymentServlet';
36
37
	const ISO_639_1_ENGLISH = 'en';
38
39
	const ISO_639_1_FRENCH = 'fr';
40
41
	const ISO_639_1_GERMAN = 'de';
42
43
	const ISO_639_1_ITALIAN = 'it';
44
45
	const ISO_639_1_SPANISH = 'es';
46
47
	const ISO_639_1_DUTCH = 'nl';
48
49
	public static function get_supported_language_codes() {
50
		return array(
51
			self::ISO_639_1_ENGLISH,
52
			self::ISO_639_1_FRENCH,
53
			self::ISO_639_1_GERMAN,
54
			self::ISO_639_1_ITALIAN,
55
			self::ISO_639_1_SPANISH,
56
			self::ISO_639_1_DUTCH,
57
		);
58
	}
59
60
	public static function is_supported_language( $language ) {
61
		$languages = self::get_supported_language_codes();
62
63
		return in_array( $language, $languages, true );
64
	}
65
66
	/**
67
	 * Interface version HP 1.0
68
	 *
69
	 * @var string
70
	 */
71
	const INTERFACE_VERSION_HP_1_0 = 'HP_1.0';
72
73
	/**
74
	 * Interface version HP 2.12
75
	 *
76
	 * @var string
77
	 */
78
	const INTERFACE_VERSION_HP_2_12 = 'HP_2.12';
79
80
	/**
81
	 * Hash algorithm SHA256 indicator
82
	 *
83
	 * @var string
84
	 */
85
	const HASH_ALGORITHM_SHA256 = 'sha256';
86
87
	/**
88
	 * The action URL
89
	 *
90
	 * @var string
91
	 */
92
	private $action_url;
93
94
	/**
95
	 * The interface version
96
	 *
97
	 * @var string
98
	 */
99
	private $interface_version;
100
101
	/**
102
	 * Currency code in ISO 4217-Numeric codification
103
	 *
104
	 * @link https://en.wikipedia.org/wiki/ISO_4217
105
	 * @link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm
106
	 *
107
	 * @var string N3
108
	 */
109
	private $currency_numeric_code;
110
111
	/**
112
	 * Merchant ID
113
	 *
114
	 * @var string N15
115
	 */
116
	private $merchant_id;
117
118
	/**
119
	 * Normal return URL
120
	 *
121
	 * @var string ANS512 url
122
	 */
123
	private $normal_return_url;
124
125
	/**
126
	 * Amount
127
	 *
128
	 * @var string N12
129
	 */
130
	private $amount;
131
132
	/**
133
	 * Transaction reference
134
	 *
135
	 * @var string AN35
136
	 */
137
	private $transaction_reference;
138
139
	/**
140
	 * Key version
141
	 *
142
	 * @var string N10
143
	 */
144
	private $key_version;
145
146
	/**
147
	 * Automatic response URL
148
	 *
149
	 * @var string ANS512 url
150
	 */
151
	private $automatic_response_url;
152
153
	/**
154
	 * Customer language in ISO 639‐1 Alpha2
155
	 *
156
	 * @link https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
157
	 * @var string A2
158
	 */
159
	private $customer_language;
160
161
	/**
162
	 * Payment mean brand list
163
	 *
164
	 * @var array
165
	 */
166
	private $payment_mean_brand_list;
167
168
	/**
169
	 * Order ID
170
	 *
171
	 * @var string AN32
172
	 */
173
	private $order_id;
174
175
	/**
176
	 * Expiration date
177
	 *
178
	 * @var DateTime
179
	 */
180
	private $expiration_date;
181
182
	/**
183
	 * Secret key
184
	 *
185
	 * @var string
186
	 */
187
	private $secret_key;
188
189
	/**
190
	 * Constructs and initalize an OmniKassa object
191
	 */
192 2
	public function __construct() {
193 2
		$this->payment_mean_brand_list = array();
194
195 2
		$this->set_interface_version( self::INTERFACE_VERSION_HP_1_0 );
196 2
	}
197
198
	/**
199
	 * Get the action URL
200
	 *
201
	 * @return the action URL
0 ignored issues
show
The type Pronamic\WordPress\Pay\Gateways\OmniKassa\the was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
202
	 */
203
	public function get_action_url() {
204
		return $this->action_url;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->action_url returns the type string which is incompatible with the documented return type Pronamic\WordPress\Pay\Gateways\OmniKassa\the.
Loading history...
205
	}
206
207
	/**
208
	 * Set the action URL
209
	 *
210
	 * @param string $url an URL
211
	 */
212
	public function set_action_url( $url ) {
213
		$this->action_url = $url;
214
	}
215
216
	/**
217
	 * Get interface version
218
	 *
219
	 * @return string
220
	 */
221
	public function get_interface_version() {
222
		return $this->interface_version;
223
	}
224
225
	/**
226
	 * Set interface version
227
	 *
228
	 * @param string $interface_version
229
	 */
230 2
	public function set_interface_version( $interface_version ) {
231 2
		$this->interface_version = $interface_version;
232 2
	}
233
234
	/**
235
	 * Get the currency numeric code
236
	 *
237
	 * @return string currency numeric code
238
	 */
239 2
	public function get_currency_numeric_code() {
240 2
		return $this->currency_numeric_code;
241
	}
242
243
	/**
244
	 * Set the currency code
245
	 *
246
	 * @param string $currency_numeric_code
247
	 */
248 2
	public function set_currency_numeric_code( $currency_numeric_code ) {
249 2
		$this->currency_numeric_code = $currency_numeric_code;
250 2
	}
251
252
	/**
253
	 * Get merchant ID
254
	 *
255
	 * @return string
256
	 */
257 2
	public function get_merchant_id() {
258 2
		return $this->merchant_id;
259
	}
260
261
	/**
262
	 * Set the merchant ID
263
	 *
264
	 * @param string $merchant_id
265
	 */
266 2
	public function set_merchant_id( $merchant_id ) {
267 2
		$this->merchant_id = $merchant_id;
268 2
	}
269
270
	/**
271
	 * Get normal return URL
272
	 *
273
	 * @return string
274
	 */
275 2
	public function get_normal_return_url() {
276 2
		return $this->normal_return_url;
277
	}
278
279
	/**
280
	 * Set the normal return URL
281
	 *
282
	 * LET OP! De URL mag geen parameters bevatten.
283
	 *
284
	 * @param string $normal_return_url
285
	 */
286 2
	public function set_normal_return_url( $normal_return_url ) {
287 2
		$this->normal_return_url = $normal_return_url;
288 2
	}
289
290
	/**
291
	 * Get amount
292
	 *
293
	 * @return float
294
	 */
295 2
	public function get_amount() {
296 2
		return $this->amount;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->amount returns the type string which is incompatible with the documented return type double.
Loading history...
297
	}
298
299
	/**
300
	 * Set amount
301
	 *
302
	 * @param float $amount
303
	 */
304 2
	public function set_amount( $amount ) {
305 2
		$this->amount = $amount;
306 2
	}
307
308
	/**
309
	 * Get transaction reference
310
	 *
311
	 * @return string
312
	 */
313 2
	public function get_transaction_reference() {
314 2
		return $this->transaction_reference;
315
	}
316
317
	/**
318
	 * Set transaction reference
319
	 * AN..max35 (AN = Alphanumeric, free text)
320
	 *
321
	 * @param string $transaction_reference
322
	 */
323 2
	public function set_transaction_reference( $transaction_reference ) {
324 2
		$this->transaction_reference = DataHelper::filter_an( $transaction_reference, 35 );
325 2
	}
326
327
	/**
328
	 * Get key version
329
	 *
330
	 * @return string
331
	 */
332 2
	public function get_key_version() {
333 2
		return $this->key_version;
334
	}
335
336
	/**
337
	 * Set key version
338
	 *
339
	 * @param string $key_version
340
	 */
341 2
	public function set_key_version( $key_version ) {
342 2
		$this->key_version = $key_version;
343 2
	}
344
345
	/**
346
	 * Get automatic response URL
347
	 *
348
	 * @return string
349
	 */
350 2
	public function get_automatic_response_url() {
351 2
		return $this->automatic_response_url;
352
	}
353
354
	/**
355
	 * Set automatic response URL
356
	 *
357
	 * LET OP! De URL mag geen parameters bevatten.
358
	 *
359
	 * @param string $automatic_response_url
360
	 */
361 2
	public function set_automatic_response_url( $automatic_response_url ) {
362 2
		$this->automatic_response_url = $automatic_response_url;
363 2
	}
364
365
	/**
366
	 * Get customer language
367
	 *
368
	 * @return string
369
	 */
370 2
	public function get_customer_language() {
371 2
		return $this->customer_language;
372
	}
373
374
	/**
375
	 * Set customer language
376
	 *
377
	 * @param string $customer_language
378
	 */
379
	public function set_customer_language( $customer_language ) {
380
		$this->customer_language = $customer_language;
381
	}
382
383
	/**
384
	 * Add the specified payment mean brand to the payment mean brand list
385
	 *
386
	 * @param string $payment_mean_brand
387
	 */
388
	public function add_payment_mean_brand( $payment_mean_brand ) {
389
		$this->payment_mean_brand_list[] = $payment_mean_brand;
390
	}
391
392
	/**
393
	 * Get payment mean brand list
394
	 *
395
	 * @return string ANS128 listString comma separated list
396
	 */
397 2
	public function get_payment_mean_brand_list() {
398 2
		return apply_filters( 'pronamic_pay_omnikassa_payment_mean_brand_list', implode( ', ', $this->payment_mean_brand_list ) );
399
	}
400
401
	/**
402
	 * Get order ID
403
	 *
404
	 * @return string
405
	 */
406 2
	public function get_order_id() {
407 2
		return $this->order_id;
408
	}
409
410
	/**
411
	 * Set order ID
412
	 *
413
	 * @param string $order_id
414
	 */
415 2
	public function set_order_id( $order_id ) {
416 2
		$this->order_id = $order_id;
417 2
	}
418
419
	/**
420
	 * Get expiration date
421
	 *
422
	 * @return DateTime
423
	 */
424
	public function get_expiration_date() {
425
		return $this->expiration_date;
426
	}
427
428
	/**
429
	 * Get expiration date
430
	 *
431
	 * @return string
432
	 */
433 2
	public function get_formatted_expiration_date() {
434 2
		$result = null;
435
436 2
		if ( null !== $this->expiration_date ) {
437
			$result = $this->expiration_date->format( DATE_ISO8601 );
438
		}
439
440 2
		return $result;
441
	}
442
443
	/**
444
	 * Set expiration date
445
	 *
446
	 * @param DateTime $date
447
	 */
448
	public function set_expiration_date( DateTime $date = null ) {
449
		$this->expiration_date = $date;
450
	}
451
452 2
	public function get_data_array() {
453
		// Payment Request - required fields
454
		$required_fields = array(
455 2
			'amount'               => strval( $this->get_amount() ),
456 2
			'currencyCode'         => strval( $this->get_currency_numeric_code() ),
457 2
			'merchantId'           => $this->get_merchant_id(),
458 2
			'normalReturnUrl'      => $this->get_normal_return_url(),
459 2
			'transactionReference' => $this->get_transaction_reference(),
460 2
			'keyVersion'           => strval( $this->get_key_version() ),
461
		);
462
463
		// Payment request - optional fields
464
		$optional_fields = array(
465 2
			'automaticResponseUrl' => $this->get_automatic_response_url(),
466 2
			'customerLanguage'     => $this->get_customer_language(),
467 2
			'paymentMeanBrandList' => $this->get_payment_mean_brand_list(),
468 2
			'orderId'              => $this->get_order_id(),
469 2
			'expirationDate'       => $this->get_formatted_expiration_date(),
470
		);
471
472
		// @link http://briancray.com/2009/04/25/remove-null-values-php-arrays/
473 2
		$optional_fields = array_filter( $optional_fields );
474
475
		// Data
476 2
		$data = $required_fields + $optional_fields;
477
478 2
		return $data;
479
	}
480
481
	/**
482
	 * Get data
483
	 *
484
	 * @return string
485
	 */
486 1
	public function get_data() {
487 1
		$data = $this->get_data_array();
488
489 1
		return self::create_piped_string( $data );
490
	}
491
492
	/**
493
	 * Get secret key
494
	 *
495
	 * @return string
496
	 */
497 1
	public function get_secret_key() {
498 1
		return $this->secret_key;
499
	}
500
501
	/**
502
	 * Set secret key
503
	 *
504
	 * @return string
505
	 */
506 1
	public function set_secret_key( $secret_key ) {
507 1
		$this->secret_key = $secret_key;
508 1
	}
509
510
	/**
511
	 * Get seal
512
	 *
513
	 * @return string
514
	 */
515 1
	public function get_seal() {
516 1
		$data       = $this->get_data();
517 1
		$secret_key = $this->get_secret_key();
518
519 1
		return self::compute_seal( $data, $secret_key );
520
	}
521
522
	/**
523
	 * Compute seal
524
	 *
525
	 * @param string $data
526
	 * @param string $secret_key
527
	 *
528
	 * @return string seal
529
	 */
530 1
	public static function compute_seal( $data, $secret_key ) {
531 1
		$value = $data . $secret_key;
532 1
		$value = utf8_encode( $value );
533
534 1
		return hash( self::HASH_ALGORITHM_SHA256, $value );
535
	}
536
537
	/**
538
	 * Get fields
539
	 *
540
	 * @since 1.1.2
541
	 * @return array
542
	 */
543
	public function get_fields() {
544
		return array(
545
			'Data'             => $this->get_data(),
546
			'InterfaceVersion' => $this->get_interface_version(),
547
			'Seal'             => $this->get_seal(),
548
		);
549
	}
550
551
	/**
552
	 * Create an piped string for the specified data array
553
	 *
554
	 * @param array $data
555
	 *
556
	 * @return string
557
	 */
558 1
	public static function create_piped_string( array $data ) {
559
		// @link http://core.trac.wordpress.org/browser/tags/3.3.1/wp-includes/functions.php#L1385
560 1
		return _http_build_query( $data, null, '|', '', false );
561
	}
562
563
	/**
564
	 * Parse piped string
565
	 *
566
	 * @param string $string
567
	 *
568
	 * @return array
569
	 */
570 1
	public static function parse_piped_string( $string ) {
571 1
		$data = array();
572
573 1
		$pairs = explode( '|', $string );
574 1
		foreach ( $pairs as $pair ) {
575 1
			list( $key, $value ) = explode( '=', $pair );
576
577 1
			$data[ $key ] = $value;
578
		}
579
580 1
		return $data;
581
	}
582
583
	public function get_response_code_description() {
584
		return array(
585
			'00' => 'Transaction success, authorization accepted',
586
			'02' => 'Please call the bank because the authorization limit on the card has been exceeded',
587
			'03' => 'Invalid merchant contract',
588
			'05' => 'Do not honor, authorization refused',
589
			'12' => 'Invalid transaction, check the parameters sent in the request',
590
			'14' => 'Invalid card number or invalid Card Security Code or Card (for MasterCard) or invalid Card Verification Value (for Visa/MAESTRO)',
591
			'17' => 'Cancellation of payment by the end user',
592
			'24' => 'Invalid status',
593
			'25' => 'Transaction not found in database',
594
			'30' => 'Invalid format',
595
			'34' => 'Fraud suspicion',
596
			'40' => 'Operation not allowed to this Merchant',
597
			'60' => 'Pending transaction',
598
			'63' => 'Security breach detected, transaction stopped',
599
			'75' => 'The number of attempts to enter the card number has been exceeded (three tries exhausted)',
600
			'90' => 'Acquirer server temporarily unavailable',
601
			'94' => 'Duplicate transaction',
602
			'97' => 'Request time-out; transaction refused',
603
			'99' => 'Payment page temporarily unavailable',
604
		);
605
	}
606
}
607