Issues (8)

src/Client.php (3 issues)

1
<?php
2
3
namespace Pronamic\WordPress\Pay\Gateways\EMS\ECommerce;
4
5
use Pronamic\WordPress\DateTime\DateTime;
6
use Pronamic\WordPress\DateTime\DateTimeZone;
7
use Pronamic\WordPress\Money\Money;
8
9
/**
10
 * Title: EMS e-Commerce client
11
 * Description:
12
 * Copyright: 2005-2022 Pronamic
13
 * Company: Pronamic
14
 *
15
 * @author Reüel van der Steege
16
 * @version 3.0.1
17
 * @since 1.0.0
18
 */
19
class Client {
20
	/**
21
	 * Action URL to start a payment request in the test environment,
22
	 * the POST data is sent to.
23
	 *
24
	 * @see page 14 - http://pronamic.nl/wp-content/uploads/2013/10/integratiehandleiding_rabo_omnikassa_en_versie_5_0_juni_2013_10_29451215.pdf
25
	 * @var string
26
	 */
27
	const ACTION_URL_TEST = 'https://test.ipg-online.com/connect/gateway/processing';
28
29
	/**
30
	 * Action URL For a payment request in the production environment,
31
	 * the POST data is sent to
32
	 *
33
	 * @see page 14 - http://pronamic.nl/wp-content/uploads/2013/10/integratiehandleiding_rabo_omnikassa_en_versie_5_0_juni_2013_10_29451215.pdf
34
	 * @var string
35
	 */
36
	const ACTION_URL_PRODUCTION = 'https://www.ipg-online.com/connect/gateway/processing';
37
38
	/**
39
	 * Hash algorithm SHA256 indicator
40
	 *
41
	 * @var string
42
	 */
43
	const HASH_ALGORITHM_SHA256 = 'sha256';
44
45
	/**
46
	 * The action URL
47
	 *
48
	 * @var string
49
	 */
50
	private $action_url;
51
52
	/**
53
	 * Currency code in ISO 4217-Numeric codification
54
	 *
55
	 * @link https://en.wikipedia.org/wiki/ISO_4217
56
	 * @link http://www.iso.org/iso/support/faqs/faqs_widely_used_standards/widely_used_standards_other/currency_codes/currency_codes_list-1.htm
57
	 *
58
	 * @var string N3
59
	 */
60
	private $currency_numeric_code;
61
62
	/**
63
	 * Storename
64
	 *
65
	 * @var string N15 @todo DOC - Storename format requirement
66
	 */
67
	private $storename;
68
69
	/**
70
	 * Normal return URL
71
	 *
72
	 * @var string ANS512 url
73
	 */
74
	private $return_url;
75
76
	/**
77
	 * Amount.
78
	 *
79
	 * @var Money
80
	 */
81
	private $amount;
82
83
	/**
84
	 * Notification URL
85
	 *
86
	 * @var string ANS512 url
87
	 */
88
	private $notification_url;
89
90
	/**
91
	 * Language in ISO 639‐1 Alpha2
92
	 *
93
	 * @link https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
94
	 * @var string A2
95
	 */
96
	private $language;
97
98
	/**
99
	 * Payment method
100
	 *
101
	 * @var array
102
	 */
103
	private $payment_method;
104
105
	/**
106
	 * Order ID
107
	 *
108
	 * @var string AN32
109
	 */
110
	private $order_id;
111
112
	/**
113
	 * Payment ID
114
	 *
115
	 * @var string AN32
116
	 */
117
	private $payment_id;
118
119
	/**
120
	 * Shared secret
121
	 *
122
	 * @var string
123
	 */
124
	private $secret;
125
126
	/**
127
	 * Issuer ID.
128
	 *
129
	 * @var string
130
	 */
131
	private $issuer_id;
132
133
	/**
134
	 * Transaction datetime.
135
	 *
136
	 * @var DateTime
137
	 */
138
	private $transaction_datetime;
139
140
	/**
141
	 * Construct and initialize an EMS e-Commerce object
142
	 */
143
	public function __construct() {
144
	}
145
146
	/**
147
	 * Get the action URL
148
	 *
149
	 * @return string action URL
150
	 */
151
	public function get_action_url() {
152
		return $this->action_url;
153
	}
154
155
	/**
156
	 * Set the action URL
157
	 *
158
	 * @param string $url Action URL.
159
	 * @return void
160
	 */
161
	public function set_action_url( $url ) {
162
		$this->action_url = $url;
163
	}
164
165
	/**
166
	 * Get the currency numeric code
167
	 *
168
	 * @return string currency numeric code
169
	 */
170
	public function get_currency_numeric_code() {
171
		return $this->currency_numeric_code;
172
	}
173
174
	/**
175
	 * Set the currency code
176
	 *
177
	 * @param string $code Currency numeric code.
178
	 * @return void
179
	 */
180
	public function set_currency_numeric_code( $code ) {
181
		$this->currency_numeric_code = $code;
182
	}
183
184
	/**
185
	 * Get storename
186
	 *
187
	 * @return string
188
	 */
189
	public function get_storename() {
190
		return $this->storename;
191
	}
192
193
	/**
194
	 * Set the storename
195
	 *
196
	 * @param string $storename Storename.
197
	 * @return void
198
	 */
199
	public function set_storename( $storename ) {
200
		$this->storename = $storename;
201
	}
202
203
	/**
204
	 * Get normal return URL
205
	 *
206
	 * @return string
207
	 */
208
	public function get_return_url() {
209
		return $this->return_url;
210
	}
211
212
	/**
213
	 * Set the normal return URL
214
	 *
215
	 * LET OP! De URL mag geen parameters bevatten.
216
	 *
217
	 * @param string $return_url Return URL.
218
	 * @return void
219
	 */
220
	public function set_return_url( $return_url ) {
221
		$this->return_url = $return_url;
222
	}
223
224
	/**
225
	 * Get amount
226
	 *
227
	 * @return Money
228
	 */
229
	public function get_amount() {
230
		return $this->amount;
231
	}
232
233
	/**
234
	 * Set amount
235
	 *
236
	 * @param Money $amount Amount.
237
	 * @return void
238
	 */
239
	public function set_amount( $amount ) {
240
		$this->amount = $amount;
241
	}
242
243
	/**
244
	 * Get notification URL
245
	 *
246
	 * @return string
247
	 */
248
	public function get_notification_url() {
249
		return $this->notification_url;
250
	}
251
252
	/**
253
	 * Set notification URL
254
	 *
255
	 * @param string $notification_url Notification URL.
256
	 * @return void
257
	 */
258
	public function set_notification_url( $notification_url ) {
259
		$this->notification_url = $notification_url;
260
	}
261
262
	/**
263
	 * Get language.
264
	 *
265
	 * @return string
266
	 */
267
	public function get_language() {
268
		return $this->language;
269
	}
270
271
	/**
272
	 * Set language.
273
	 *
274
	 * @param string $language Language.
275
	 * @return void
276
	 */
277
	public function set_language( $language ) {
278
		$this->language = $language;
279
	}
280
281
	/**
282
	 * Set the payment method.
283
	 *
284
	 * @param string $payment_method Payment method.
285
	 * @return void
286
	 */
287
	public function set_payment_method( $payment_method ) {
288
		$this->payment_method = $payment_method;
0 ignored issues
show
Documentation Bug introduced by
It seems like $payment_method of type string is incompatible with the declared type array of property $payment_method.

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..

Loading history...
289
	}
290
291
	/**
292
	 * Get the payment method.
293
	 *
294
	 * @return string ANS128 listString comma separated list
295
	 */
296
	public function get_payment_method() {
297
		return $this->payment_method;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->payment_method returns the type array which is incompatible with the documented return type string.
Loading history...
298
	}
299
300
	/**
301
	 * Get order ID
302
	 *
303
	 * @return string
304
	 */
305
	public function get_order_id() {
306
		return $this->order_id;
307
	}
308
309
	/**
310
	 * Set order ID
311
	 *
312
	 * @param string $order_id Order ID.
313
	 * @return void
314
	 */
315
	public function set_order_id( $order_id ) {
316
		$this->order_id = $order_id;
317
	}
318
319
	/**
320
	 * Get payment ID
321
	 *
322
	 * @return int
323
	 */
324
	public function get_payment_id() {
325
		return $this->payment_id;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->payment_id returns the type string which is incompatible with the documented return type integer.
Loading history...
326
	}
327
328
	/**
329
	 * Set payment ID
330
	 *
331
	 * @param int $payment_id Payment ID.
332
	 * @return void
333
	 */
334
	public function set_payment_id( $payment_id ) {
335
		$this->payment_id = $payment_id;
336
	}
337
338
	/**
339
	 * Get the transaction datetime.
340
	 *
341
	 * @param boolean $create_new Indicator for creating a new expire date.
342
	 * @return DateTime
343
	 */
344
	public function get_transaction_datetime( $create_new = false ) {
345
		if ( null === $this->transaction_datetime || $create_new ) {
346
			$this->transaction_datetime = new DateTime( null, new DateTimeZone( 'UTC' ) );
347
		}
348
349
		return $this->transaction_datetime;
350
	}
351
352
	/**
353
	 * Set transaction datetime.
354
	 *
355
	 * @param DateTime $datetime Transaction date time.
356
	 * @return void
357
	 */
358
	public function set_transaction_datetime( DateTime $datetime ) {
359
		$this->transaction_datetime = $datetime;
360
	}
361
362
	/**
363
	 * Get data
364
	 *
365
	 * @return array
366
	 */
367
	public function get_data() {
368
		// Required fields for payment request.
369
		$required_fields = array(
370
			'txntype'        => 'sale',
371
			// According the EMS documentation the timezone should be in `Area/Location` notation, but it seems like `UTC` is also working.
372
			'timezone'       => 'UTC',
373
			// In WordPress, PHP's `time()` will always return `UTC` and is the same as calling `current_time( 'timestamp', true )`.
374
			'txndatetime'    => $this->get_transaction_datetime()->format( 'Y:m:d-H:i:s' ),
375
			'hash_algorithm' => 'SHA256',
376
			'storename'      => $this->get_storename(),
377
			'mode'           => 'payonly',
378
			/**
379
			 * This is the total amount of the transaction using a dot or comma
380
			 * as decimal separator, e. g. 12.34 for an amount of 12 Euro and
381
			 * 34 Cent. Group separators like1,000.01 / 1.000,01 are not
382
			 * allowed.
383
			 * 
384
			 * @link https://github.com/wp-pay-gateways/ems-e-commerce/blob/5bb23be651fa54ce39244946525416796a5c3342/documentation/EMS-Manual-e-Comm-Gateway-HPP-tech-2017-6.pdf
385
			 */
386
			'chargetotal'    => $this->amount->number_format( null, '.', '' ),
387
			'currency'       => $this->get_currency_numeric_code(),
388
		);
389
390
		// Optional fields for payment request.
391
		$optional_fields = array(
392
			'oid'                        => $this->get_order_id(),
393
			'language'                   => $this->get_language(),
394
			'paymentMethod'              => $this->get_payment_method(),
395
			'responseFailURL'            => $this->get_return_url(),
396
			'responseSuccessURL'         => $this->get_return_url(),
397
			'transactionNotificationURL' => $this->get_notification_url(),
398
			'idealIssuerID'              => $this->get_issuer_id(),
399
			'ems_notify_payment_id'      => $this->get_payment_id(),
400
		);
401
402
		// @link http://briancray.com/2009/04/25/remove-null-values-php-arrays/
403
		$optional_fields = array_filter( $optional_fields );
404
405
		// Data.
406
		$data = $required_fields + $optional_fields;
407
408
		return $data;
409
	}
410
411
	/**
412
	 * Get shared secret
413
	 *
414
	 * @return string
415
	 */
416
	public function get_secret() {
417
		return $this->secret;
418
	}
419
420
	/**
421
	 * Set shared secret.
422
	 *
423
	 * @param string $secret Secret.
424
	 * @return void
425
	 */
426
	public function set_secret( $secret ) {
427
		$this->secret = $secret;
428
	}
429
430
	/**
431
	 * Get hash
432
	 *
433
	 * @return string
434
	 */
435
	public function get_hash() {
436
		$data   = $this->get_data();
437
		$secret = $this->get_secret();
438
439
		$values = array(
440
			$data['storename'],
441
			$data['txndatetime'],
442
			$data['chargetotal'],
443
			$data['currency'],
444
			$secret,
445
		);
446
447
		return self::compute_hash( $values );
448
	}
449
450
	/**
451
	 * Compute hash
452
	 *
453
	 * @param array $values Values to compute hash for.
454
	 * @return string
455
	 */
456
	public static function compute_hash( $values ) {
457
		$value = implode( '', $values );
458
		$value = bin2hex( $value );
459
460
		return hash( self::HASH_ALGORITHM_SHA256, $value );
461
	}
462
463
	/**
464
	 * Get fields
465
	 *
466
	 * @since 1.0.0
467
	 * @return array
468
	 */
469
	public function get_fields() {
470
		$fields = $this->get_data();
471
472
		$fields['hash'] = $this->get_hash();
473
474
		return $fields;
475
	}
476
477
	/**
478
	 * Set issuer ID.
479
	 *
480
	 * @param string $issuer_id Issuer ID.
481
	 * @return void
482
	 */
483
	public function set_issuer_id( $issuer_id ) {
484
		$this->issuer_id = $issuer_id;
485
	}
486
487
	/**
488
	 * Get issuer ID.
489
	 *
490
	 * @return string
491
	 */
492
	public function get_issuer_id() {
493
		return $this->issuer_id;
494
	}
495
}
496