1 | <?php |
||||
2 | |||||
3 | namespace Pronamic\WordPress\Pay\Gateways\IDealBasic; |
||||
4 | |||||
5 | use InvalidArgumentException; |
||||
6 | use DateTime; |
||||
7 | use DateTimeZone; |
||||
8 | use Pronamic\WordPress\Money\Money; |
||||
9 | use Pronamic\WordPress\Pay\Plugin; |
||||
10 | |||||
11 | /** |
||||
12 | * Title: iDEAL Basic client |
||||
13 | * Description: |
||||
14 | * Copyright: 2005-2021 Pronamic |
||||
15 | * Company: Pronamic |
||||
16 | * |
||||
17 | * @author Remco Tolsma |
||||
18 | * @version 2.0.0 |
||||
19 | * @since 1.0.0 |
||||
20 | */ |
||||
21 | class Client { |
||||
22 | /** |
||||
23 | * An payment type indicator for iDEAL |
||||
24 | * |
||||
25 | * @var string |
||||
26 | */ |
||||
27 | const PAYMENT_TYPE_IDEAL = 'ideal'; |
||||
28 | |||||
29 | /** |
||||
30 | * The expire date format (yyyy-MMddTHH:mm:ss.SSSZ) |
||||
31 | * The Z stands for the time zone (CET). |
||||
32 | * |
||||
33 | * @var string |
||||
34 | */ |
||||
35 | const DATE_EXPIRE_FORMAT = 'Y-m-d\TH:i:s.000\Z'; |
||||
36 | |||||
37 | /** |
||||
38 | * The default expire date modifier |
||||
39 | * |
||||
40 | * @var string |
||||
41 | */ |
||||
42 | const EXPIRE_DATE_MODIFIER = '+30 minutes'; |
||||
43 | |||||
44 | /** |
||||
45 | * Forbidden characters |
||||
46 | * |
||||
47 | * @doc Manual iDEAL Lite.pdf (4.2 Explanation of the hash code) |
||||
48 | * @var string |
||||
49 | */ |
||||
50 | const FORBIDDEN_CHARACHTERS = "\t\n\r "; |
||||
51 | |||||
52 | /** |
||||
53 | * The URL for testing |
||||
54 | * |
||||
55 | * @var string |
||||
56 | */ |
||||
57 | private $payment_server_url; |
||||
58 | |||||
59 | /** |
||||
60 | * The merchant ID |
||||
61 | * |
||||
62 | * @var string |
||||
63 | */ |
||||
64 | private $merchant_id; |
||||
65 | |||||
66 | /** |
||||
67 | * The sub ID |
||||
68 | * |
||||
69 | * @var string |
||||
70 | */ |
||||
71 | private $sub_id; |
||||
72 | |||||
73 | /** |
||||
74 | * The hash key |
||||
75 | * |
||||
76 | * @var string |
||||
77 | */ |
||||
78 | private $hash_key; |
||||
79 | |||||
80 | /** |
||||
81 | * The purchase ID |
||||
82 | * |
||||
83 | * @var string |
||||
84 | */ |
||||
85 | private $purchase_id; |
||||
86 | |||||
87 | /** |
||||
88 | * The language |
||||
89 | * |
||||
90 | * @var string |
||||
91 | */ |
||||
92 | private $language; |
||||
93 | |||||
94 | /** |
||||
95 | * Description |
||||
96 | * |
||||
97 | * @var string |
||||
98 | */ |
||||
99 | private $description; |
||||
100 | |||||
101 | /** |
||||
102 | * The currency |
||||
103 | * |
||||
104 | * @var string |
||||
105 | */ |
||||
106 | private $currency; |
||||
107 | |||||
108 | /** |
||||
109 | * Payment method |
||||
110 | * |
||||
111 | * @var string |
||||
112 | */ |
||||
113 | private $payment_type; |
||||
114 | |||||
115 | /** |
||||
116 | * The expire date |
||||
117 | * |
||||
118 | * @var DateTime |
||||
119 | */ |
||||
120 | private $expire_date; |
||||
121 | |||||
122 | /** |
||||
123 | * The expire date format |
||||
124 | * |
||||
125 | * @var string |
||||
126 | */ |
||||
127 | private $expire_date_format; |
||||
128 | |||||
129 | /** |
||||
130 | * The expire date modifier |
||||
131 | * |
||||
132 | * @var string |
||||
133 | */ |
||||
134 | private $expire_date_modifier; |
||||
135 | |||||
136 | /** |
||||
137 | * The forbidden characters |
||||
138 | * |
||||
139 | * @var string |
||||
140 | */ |
||||
141 | private $forbidden_characters; |
||||
142 | |||||
143 | /** |
||||
144 | * The items |
||||
145 | * |
||||
146 | * @var Items |
||||
147 | */ |
||||
148 | private $items; |
||||
149 | |||||
150 | /** |
||||
151 | * The consumer is automatically directed to this URL after a successful payment. |
||||
152 | * |
||||
153 | * @var string |
||||
154 | */ |
||||
155 | private $success_url; |
||||
156 | |||||
157 | /** |
||||
158 | * The consumer is automatically directed to this URL after the transaction has been cancelled. |
||||
159 | * |
||||
160 | * @var string |
||||
161 | */ |
||||
162 | private $cancel_url; |
||||
163 | |||||
164 | /** |
||||
165 | * The consumer is directed to this URL if an error has occurred. |
||||
166 | * |
||||
167 | * @var string |
||||
168 | */ |
||||
169 | private $error_url; |
||||
170 | |||||
171 | /** |
||||
172 | * Constructs and initialize a iDEAL basic object |
||||
173 | */ |
||||
174 | 2 | public function __construct() { |
|||
175 | 2 | $this->items = new Items(); |
|||
176 | |||||
177 | 2 | $this->forbidden_characters = array(); |
|||
0 ignored issues
–
show
|
|||||
178 | |||||
179 | 2 | $this->set_payment_type( self::PAYMENT_TYPE_IDEAL ); |
|||
180 | 2 | $this->set_expire_date_format( self::DATE_EXPIRE_FORMAT ); |
|||
181 | 2 | $this->set_expire_date_modifier( self::EXPIRE_DATE_MODIFIER ); |
|||
182 | 2 | $this->set_forbidden_characters( self::FORBIDDEN_CHARACHTERS ); |
|||
183 | 2 | } |
|||
184 | |||||
185 | /** |
||||
186 | * Get the payment server URL |
||||
187 | * |
||||
188 | * @return string |
||||
189 | */ |
||||
190 | public function get_payment_server_url() { |
||||
191 | return $this->payment_server_url; |
||||
192 | } |
||||
193 | |||||
194 | /** |
||||
195 | * Set the payment server URL |
||||
196 | * |
||||
197 | * @param string $url Payment server URL. |
||||
198 | */ |
||||
199 | public function set_payment_server_url( $url ) { |
||||
200 | $this->payment_server_url = $url; |
||||
201 | } |
||||
202 | |||||
203 | /** |
||||
204 | * Get the merchant ID. |
||||
205 | * |
||||
206 | * @return string |
||||
207 | */ |
||||
208 | 1 | public function get_merchant_id() { |
|||
209 | 1 | return $this->merchant_id; |
|||
210 | } |
||||
211 | |||||
212 | /** |
||||
213 | * Set the merchant ID. |
||||
214 | * |
||||
215 | * @param string $merchant_id Merchant ID. |
||||
216 | */ |
||||
217 | 1 | public function set_merchant_id( $merchant_id ) { |
|||
218 | 1 | $this->merchant_id = $merchant_id; |
|||
219 | 1 | } |
|||
220 | |||||
221 | /** |
||||
222 | * Get the sub id |
||||
223 | * |
||||
224 | * @return string Sub id |
||||
225 | */ |
||||
226 | 1 | public function get_sub_id() { |
|||
227 | 1 | return $this->sub_id; |
|||
228 | } |
||||
229 | |||||
230 | /** |
||||
231 | * Set the sub id |
||||
232 | * |
||||
233 | * @param string $sub_id Sub ID. |
||||
234 | */ |
||||
235 | 1 | public function set_sub_id( $sub_id ) { |
|||
236 | 1 | $this->sub_id = $sub_id; |
|||
237 | 1 | } |
|||
238 | |||||
239 | /** |
||||
240 | * Get the hash key |
||||
241 | * |
||||
242 | * @return string Hash key |
||||
243 | */ |
||||
244 | 1 | public function get_hash_key() { |
|||
245 | 1 | return $this->hash_key; |
|||
246 | } |
||||
247 | |||||
248 | /** |
||||
249 | * Set the hash key |
||||
250 | * N..max50 |
||||
251 | * |
||||
252 | * @param string $hash_key Hash key. |
||||
253 | */ |
||||
254 | 1 | public function set_hash_key( $hash_key ) { |
|||
255 | 1 | $this->hash_key = $hash_key; |
|||
256 | 1 | } |
|||
257 | |||||
258 | /** |
||||
259 | * Get the purchase id |
||||
260 | * |
||||
261 | * @return string Purchase id |
||||
262 | */ |
||||
263 | 1 | public function get_purchase_id() { |
|||
264 | 1 | return $this->purchase_id; |
|||
265 | } |
||||
266 | |||||
267 | /** |
||||
268 | * Set the purchase id |
||||
269 | * AN..max16 (AN = Alphanumeric, free text) |
||||
270 | * |
||||
271 | * @param string $purchase_id Purchase ID. |
||||
272 | */ |
||||
273 | 1 | public function set_purchase_id( $purchase_id ) { |
|||
274 | 1 | $this->purchase_id = substr( $purchase_id, 0, 16 ); |
|||
275 | 1 | } |
|||
276 | |||||
277 | /** |
||||
278 | * Get the language |
||||
279 | * |
||||
280 | * @return string Language |
||||
281 | */ |
||||
282 | public function get_language() { |
||||
283 | return $this->language; |
||||
284 | } |
||||
285 | |||||
286 | /** |
||||
287 | * Set the language |
||||
288 | * |
||||
289 | * @param string $language Language. |
||||
290 | */ |
||||
291 | 1 | public function set_language( $language ) { |
|||
292 | 1 | $this->language = $language; |
|||
293 | 1 | } |
|||
294 | |||||
295 | /** |
||||
296 | * Get the description |
||||
297 | * |
||||
298 | * @return string Description |
||||
299 | */ |
||||
300 | 1 | public function get_description() { |
|||
301 | 1 | return $this->description; |
|||
302 | } |
||||
303 | |||||
304 | /** |
||||
305 | * Set the description |
||||
306 | * AN..max32 (AN = Alphanumeric, free text) |
||||
307 | * |
||||
308 | * @param string $description Description. |
||||
309 | */ |
||||
310 | 2 | public function set_description( $description ) { |
|||
311 | 2 | $this->description = DataHelper::an32( $description ); |
|||
312 | 2 | } |
|||
313 | |||||
314 | /** |
||||
315 | * Get the currency |
||||
316 | * |
||||
317 | * @return string Currency |
||||
318 | */ |
||||
319 | public function get_currency() { |
||||
320 | return $this->currency; |
||||
321 | } |
||||
322 | |||||
323 | /** |
||||
324 | * Set the currency |
||||
325 | * |
||||
326 | * @param string $currency Currency. |
||||
327 | */ |
||||
328 | 1 | public function set_currency( $currency ) { |
|||
329 | 1 | $this->currency = $currency; |
|||
330 | 1 | } |
|||
331 | |||||
332 | /** |
||||
333 | * Get the payment type |
||||
334 | * |
||||
335 | * @return string Payment type |
||||
336 | */ |
||||
337 | 1 | public function get_payment_type() { |
|||
338 | 1 | return $this->payment_type; |
|||
339 | } |
||||
340 | |||||
341 | /** |
||||
342 | * Set the payment type |
||||
343 | * AN..max10 |
||||
344 | * |
||||
345 | * @param string $payment_type Payment type. |
||||
346 | */ |
||||
347 | 2 | public function set_payment_type( $payment_type ) { |
|||
348 | 2 | $this->payment_type = $payment_type; |
|||
349 | 2 | } |
|||
350 | |||||
351 | /** |
||||
352 | * Get the expire date |
||||
353 | * |
||||
354 | * @param boolean $create_new Indicator for creating a new expire date. |
||||
355 | * |
||||
356 | * @return DateTime |
||||
357 | */ |
||||
358 | 1 | public function get_expire_date( $create_new = false ) { |
|||
359 | 1 | if ( null === $this->expire_date || $create_new ) { |
|||
360 | $this->expire_date = new DateTime( null, new DateTimeZone( Plugin::TIMEZONE ) ); |
||||
361 | $this->expire_date->modify( $this->expire_date_modifier ); |
||||
362 | } |
||||
363 | |||||
364 | 1 | return $this->expire_date; |
|||
365 | } |
||||
366 | |||||
367 | /** |
||||
368 | * Get the expire date format |
||||
369 | * |
||||
370 | * @return string the expire date format |
||||
371 | */ |
||||
372 | 1 | public function get_expire_date_format() { |
|||
373 | 1 | return $this->expire_date_format; |
|||
374 | } |
||||
375 | |||||
376 | /** |
||||
377 | * Set the expire date format |
||||
378 | * |
||||
379 | * @param string $expire_date_format Expire date format. |
||||
380 | */ |
||||
381 | 2 | public function set_expire_date_format( $expire_date_format ) { |
|||
382 | 2 | $this->expire_date_format = $expire_date_format; |
|||
383 | 2 | } |
|||
384 | |||||
385 | /** |
||||
386 | * Get the expire date modifier |
||||
387 | * |
||||
388 | * @return string Expire date modifier |
||||
389 | */ |
||||
390 | public function get_expire_date_modifier() { |
||||
391 | return $this->expire_date_modifier; |
||||
392 | } |
||||
393 | |||||
394 | /** |
||||
395 | * Set the expire date modifier |
||||
396 | * |
||||
397 | * @param string $expire_date_modifier Expire date modifier. |
||||
398 | */ |
||||
399 | 2 | public function set_expire_date_modifier( $expire_date_modifier ) { |
|||
400 | 2 | $this->expire_date_modifier = $expire_date_modifier; |
|||
401 | 2 | } |
|||
402 | |||||
403 | /** |
||||
404 | * Set the expire date |
||||
405 | * |
||||
406 | * @param DateTime $date Expire date. |
||||
407 | */ |
||||
408 | 1 | public function set_expire_date( DateTime $date ) { |
|||
409 | 1 | $this->expire_date = $date; |
|||
410 | 1 | } |
|||
411 | |||||
412 | /** |
||||
413 | * Get the forbidden characters |
||||
414 | * |
||||
415 | * @return array |
||||
416 | */ |
||||
417 | 1 | public function get_forbidden_characters() { |
|||
418 | 1 | return $this->forbidden_characters; |
|||
0 ignored issues
–
show
|
|||||
419 | } |
||||
420 | |||||
421 | /** |
||||
422 | * Set the forbidden characters |
||||
423 | * |
||||
424 | * @param mixed $characters Array or string with forbidden characters. |
||||
425 | * |
||||
426 | * @throws InvalidArgumentException Passed characters is not an array or string. |
||||
427 | */ |
||||
428 | 2 | public function set_forbidden_characters( $characters ) { |
|||
429 | 2 | if ( ! is_array( $characters ) && ! is_string( $characters ) ) { |
|||
430 | throw new InvalidArgumentException( 'Invalid characters argument.' ); |
||||
431 | } |
||||
432 | |||||
433 | 2 | if ( is_string( $characters ) ) { |
|||
434 | 2 | $characters = str_split( $characters ); |
|||
435 | } |
||||
436 | |||||
437 | 2 | $this->forbidden_characters = $characters; |
|||
0 ignored issues
–
show
It seems like
$characters of type true or array is incompatible with the declared type string of property $forbidden_characters .
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property. Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property.. ![]() |
|||||
438 | 2 | } |
|||
439 | |||||
440 | /** |
||||
441 | * Get the success URL |
||||
442 | * |
||||
443 | * @return string URL |
||||
444 | */ |
||||
445 | public function get_success_url() { |
||||
446 | return $this->success_url; |
||||
447 | } |
||||
448 | |||||
449 | /** |
||||
450 | * Set the success URL |
||||
451 | * |
||||
452 | * @param string $url Success URL. |
||||
453 | */ |
||||
454 | 1 | public function set_success_url( $url ) { |
|||
455 | 1 | $this->success_url = $url; |
|||
456 | 1 | } |
|||
457 | |||||
458 | /** |
||||
459 | * Get the cancel URL |
||||
460 | * |
||||
461 | * @return string Cancel URL |
||||
462 | */ |
||||
463 | public function get_cancel_url() { |
||||
464 | return $this->cancel_url; |
||||
465 | } |
||||
466 | |||||
467 | /** |
||||
468 | * Set the cancel URL |
||||
469 | * |
||||
470 | * @param string $url Cancel URL. |
||||
471 | */ |
||||
472 | 1 | public function set_cancel_url( $url ) { |
|||
473 | 1 | $this->cancel_url = $url; |
|||
474 | 1 | } |
|||
475 | |||||
476 | /** |
||||
477 | * Get the error URL |
||||
478 | * |
||||
479 | * @return string Error URL |
||||
480 | */ |
||||
481 | public function get_error_url() { |
||||
482 | return $this->error_url; |
||||
483 | } |
||||
484 | |||||
485 | /** |
||||
486 | * Set the error URL |
||||
487 | * |
||||
488 | * @param string $url Error URL. |
||||
489 | */ |
||||
490 | 1 | public function set_error_url( $url ) { |
|||
491 | 1 | $this->error_url = $url; |
|||
492 | 1 | } |
|||
493 | |||||
494 | /** |
||||
495 | * Get the items |
||||
496 | * |
||||
497 | * @return Items |
||||
498 | */ |
||||
499 | 1 | public function get_items() { |
|||
500 | 1 | return $this->items; |
|||
501 | } |
||||
502 | |||||
503 | /** |
||||
504 | * Set the items |
||||
505 | * |
||||
506 | * @param Items $items Items. |
||||
507 | */ |
||||
508 | public function set_items( Items $items ) { |
||||
509 | $this->items = $items; |
||||
510 | } |
||||
511 | |||||
512 | /** |
||||
513 | * Calculate the total amount of all items |
||||
514 | * |
||||
515 | * @return Money |
||||
516 | */ |
||||
517 | 1 | public function get_amount() { |
|||
518 | 1 | return $this->items->get_amount(); |
|||
519 | } |
||||
520 | |||||
521 | /** |
||||
522 | * Create hash string |
||||
523 | */ |
||||
524 | 1 | public function create_hash_string() { |
|||
525 | 1 | $string = array(); |
|||
526 | |||||
527 | // SHA1 hashcode, used only with the hashcode approach (Chapter 4). |
||||
528 | 1 | $string[] = $this->get_hash_key(); |
|||
529 | |||||
530 | // Your AcceptorID is provided in the registration process, also known as merchant id. |
||||
531 | 1 | $string[] = $this->get_merchant_id(); |
|||
532 | |||||
533 | // Provided in the registration process, value is normally '0' (zero). |
||||
534 | 1 | $string[] = $this->get_sub_id(); |
|||
535 | |||||
536 | // Total amount of transaction. |
||||
537 | 1 | $string[] = $this->get_amount()->get_minor_units()->format( 0, '', '' ); |
|||
0 ignored issues
–
show
The method
format() does not exist on integer .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces. This is most likely a typographical error or the method has been renamed. ![]() |
|||||
538 | |||||
539 | // The online shop's unique order number, also known as purchase id. |
||||
540 | 1 | $string[] = $this->get_purchase_id(); |
|||
541 | |||||
542 | // ?? Fixed value = ideal |
||||
543 | 1 | $string[] = $this->get_payment_type(); |
|||
544 | |||||
545 | // yyyy-MMddTHH:mm:ss.SSS Z Time at which the transaction expires (maximum of 1 hour later). |
||||
546 | // The consumer has time until then to pay with iDEAL. |
||||
547 | 1 | $string[] = $this->get_expire_date()->format( $this->get_expire_date_format() ); |
|||
548 | |||||
549 | // Iterate through the items and concat. |
||||
550 | 1 | foreach ( $this->get_items() as $item ) { |
|||
551 | // Article number. <n> is 1 for the first product, 2 for the second, etc. |
||||
552 | // N.B. Note that for every product type the parameters |
||||
553 | // itemNumber<n>, itemDescription<n>, itemQuantity<n> and itemPrice<n> are mandatory. |
||||
554 | 1 | $string[] = $item->get_number(); |
|||
555 | |||||
556 | // Description of article <n>. |
||||
557 | 1 | $string[] = $item->get_description(); |
|||
558 | |||||
559 | // Number of items of article <n> that the consumer wants to buy. |
||||
560 | 1 | $string[] = $item->get_quantity(); |
|||
561 | |||||
562 | // Price of article <n> in whole eurocents. |
||||
563 | 1 | $string[] = $item->get_price()->get_minor_units()->format( 0, '', '' ); |
|||
564 | } |
||||
565 | |||||
566 | 1 | $concat_string = implode( '', $string ); |
|||
567 | |||||
568 | // The characters "\t", "\n", "\r", " " (spaces) may not exist in the string. |
||||
569 | 1 | $forbidden_characters = $this->get_forbidden_characters(); |
|||
570 | 1 | $concat_string = str_replace( $forbidden_characters, '', $concat_string ); |
|||
571 | |||||
572 | // Delete special HTML entities. |
||||
573 | 1 | $concat_string = html_entity_decode( $concat_string, ENT_COMPAT, 'UTF-8' ); |
|||
574 | |||||
575 | 1 | return $concat_string; |
|||
576 | } |
||||
577 | |||||
578 | /** |
||||
579 | * Create hash |
||||
580 | * |
||||
581 | * @return string Hash |
||||
582 | */ |
||||
583 | 1 | public function create_hash() { |
|||
584 | 1 | return sha1( $this->create_hash_string() ); |
|||
585 | } |
||||
586 | |||||
587 | /** |
||||
588 | * Get the iDEAL HTML fields |
||||
589 | * |
||||
590 | * @since 1.1.1 |
||||
591 | * @return array |
||||
592 | */ |
||||
593 | public function get_fields() { |
||||
594 | $fields = array(); |
||||
595 | |||||
596 | $fields['merchantID'] = $this->get_merchant_id(); |
||||
597 | $fields['subID'] = $this->get_sub_id(); |
||||
598 | |||||
599 | $fields['amount'] = $this->get_amount()->get_minor_units()->format( 0, '', '' ); |
||||
600 | $fields['purchaseID'] = $this->get_purchase_id(); |
||||
601 | $fields['language'] = $this->get_language(); |
||||
602 | $fields['currency'] = $this->get_currency(); |
||||
603 | $fields['description'] = $this->get_description(); |
||||
604 | $fields['hash'] = $this->create_hash(); |
||||
605 | $fields['paymentType'] = $this->get_payment_type(); |
||||
606 | $fields['validUntil'] = $this->get_expire_date()->format( $this->get_expire_date_format() ); |
||||
607 | |||||
608 | $serial_number = 1; |
||||
609 | foreach ( $this->get_items() as $item ) { |
||||
610 | $fields[ 'itemNumber' . $serial_number ] = $item->get_number(); |
||||
611 | $fields[ 'itemDescription' . $serial_number ] = $item->get_description(); |
||||
612 | $fields[ 'itemQuantity' . $serial_number ] = $item->get_quantity(); |
||||
613 | $fields[ 'itemPrice' . $serial_number ] = $item->get_price()->get_minor_units()->format( 0, '', '' ); |
||||
614 | |||||
615 | $serial_number ++; |
||||
616 | } |
||||
617 | |||||
618 | $fields['urlCancel'] = $this->get_cancel_url(); |
||||
619 | $fields['urlSuccess'] = $this->get_success_url(); |
||||
620 | $fields['urlError'] = $this->get_error_url(); |
||||
621 | |||||
622 | return $fields; |
||||
623 | } |
||||
624 | } |
||||
625 |
Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.
Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..