Failed Conditions
Push — develop ( 041528...a45adf )
by Reüel
05:40
created

Gateway::get_available_payment_methods()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 29
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 14
c 1
b 0
f 0
dl 0
loc 29
ccs 0
cts 19
cp 0
rs 9.4888
cc 5
nc 5
nop 0
crap 30
1
<?php
2
/**
3
 * Gateway
4
 *
5
 * @author    Pronamic <[email protected]>
6
 * @copyright 2005-2019 Pronamic
7
 * @license   GPL-3.0-or-later
8
 * @package   Pronamic\WordPress\Pay\Payments
9
 */
10
11
namespace Pronamic\WordPress\Pay\Gateways\Sisow;
12
13
use Pronamic\WordPress\Pay\Core\Gateway as Core_Gateway;
14
use Pronamic\WordPress\Pay\Core\PaymentMethods;
15
use Pronamic\WordPress\Pay\Payments\PaymentStatus as Core_Statuses;
16
use Pronamic\WordPress\Pay\Payments\Payment;
17
use Pronamic\WordPress\Pay\Payments\PaymentLineType;
18
19
/**
20
 * Title: Sisow gateway
21
 * Description:
22
 * Copyright: 2005-2019 Pronamic
23
 * Company: Pronamic
24
 *
25
 * @author  Remco Tolsma
26
 * @version 2.0.3
27
 * @since   1.0.0
28
 */
29
class Gateway extends Core_Gateway {
30
	/**
31
	 * Client.
32
	 *
33
	 * @var Client
34
	 */
35
	protected $client;
36
37
	/**
38
	 * Constructs and initialize an Sisow gateway
39
	 *
40
	 * @param Config $config Config.
41
	 */
42
	public function __construct( Config $config ) {
43
		parent::__construct( $config );
44
45
		$this->set_method( self::METHOD_HTTP_REDIRECT );
46
47
		// Supported features.
48
		$this->supports = array(
49
			'payment_status_request',
50
			'reservation_payments',
51
		);
52
53
		// Client.
54
		$this->client = new Client( $config->merchant_id, $config->merchant_key );
55
		$this->client->set_test_mode( self::MODE_TEST === $config->mode );
56
	}
57
58
	/**
59
	 * Get issuers
60
	 *
61
	 * @see Core_Gateway::get_issuers()
62
	 */
63
	public function get_issuers() {
64
		$groups = array();
65
66
		$result = $this->client->get_directory();
67
68
		if ( $result ) {
69
			$groups[] = array(
70
				'options' => $result,
71
			);
72
		} else {
73
			$this->error = $this->client->get_error();
0 ignored issues
show
Bug introduced by
The method get_error() does not exist on Pronamic\WordPress\Pay\Gateways\Sisow\Client. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

73
			/** @scrutinizer ignore-call */ 
74
   $this->error = $this->client->get_error();

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.

Loading history...
74
		}
75
76
		return $groups;
77
	}
78
79
	/**
80
	 * Get available payment methods.
81
	 *
82
	 * @see Core_Gateway::get_available_payment_methods()
83
	 */
84
	public function get_available_payment_methods() {
85
		if ( self::MODE_TEST === $this->config->mode ) {
86
			return null;
87
		}
88
89
		$payment_methods = array();
90
91
		// Merchant request.
92
		$request = new MerchantRequest( $this->config->merchant_id );
93
94
		// Get merchant.
95
		try {
96
			$result = $this->client->get_merchant( $request );
97
		} catch ( \Exception $e ) {
98
			$this->error = new \WP_Error( 'sisow_error', $e->getMessage() );
99
100
			return $payment_methods;
101
		}
102
103
		foreach ( $result->payments as $method ) {
104
			// Transform to WordPress payment methods.
105
			$payment_method = Methods::transform_gateway_method( $method );
106
107
			if ( $payment_method ) {
108
				$payment_methods[] = $payment_method;
109
			}
110
		}
111
112
		return $payment_methods;
113
	}
114
115
	/**
116
	 * Get supported payment methods
117
	 *
118
	 * @see Pronamic_WP_Pay_Gateway::get_supported_payment_methods()
119
	 */
120
	public function get_supported_payment_methods() {
121
		return array(
122
			PaymentMethods::AFTERPAY,
123
			PaymentMethods::BANK_TRANSFER,
124
			PaymentMethods::BANCONTACT,
125
			PaymentMethods::BELFIUS,
126
			PaymentMethods::BILLINK,
127
			PaymentMethods::BUNQ,
128
			PaymentMethods::CAPAYABLE,
129
			PaymentMethods::IN3,
130
			PaymentMethods::CREDIT_CARD,
131
			PaymentMethods::FOCUM,
132
			PaymentMethods::GIROPAY,
133
			PaymentMethods::IDEAL,
134
			PaymentMethods::IDEALQR,
135
			PaymentMethods::KLARNA_PAY_LATER,
136
			PaymentMethods::PAYPAL,
137
			PaymentMethods::SOFORT,
138
		);
139
	}
140
141
	/**
142
	 * Is payment method required to start transaction?
143
	 *
144
	 * @see Core_Gateway::payment_method_is_required()
145
	 */
146
	public function payment_method_is_required() {
147
		return true;
148
	}
149
150
	/**
151
	 * Start
152
	 *
153
	 * @param Payment $payment Payment.
154
	 *
155
	 * @throws \Exception Throws exception on transaction error.
156
	 * @see Core_Gateway::start()
157
	 */
158
	public function start( Payment $payment ) {
159
		// Order and purchase ID.
160
		$order_id    = $payment->get_order_id();
161
		$purchase_id = strval( empty( $order_id ) ? $payment->get_id() : $order_id );
162
163
		// Maximum length for purchase ID is 16 characters, otherwise an error will occur:
164
		// ideal_sisow_error - purchaseid too long (16).
165
		$purchase_id = substr( $purchase_id, 0, 16 );
166
167
		// New transaction request.
168
		$request = new TransactionRequest(
169
			$this->config->merchant_id,
170
			$this->config->shop_id
171
		);
172
173
		$request->merge_parameters(
174
			array(
175
				'payment'      => Methods::transform( $payment->get_method(), $payment->get_method() ),
176
				'purchaseid'   => substr( $purchase_id, 0, 16 ),
177
				'entrancecode' => $payment->get_entrance_code(),
178
				'amount'       => $payment->get_total_amount()->get_cents(),
0 ignored issues
show
Deprecated Code introduced by
The function Pronamic\WordPress\Money\Money::get_cents() has been deprecated: 1.2.2 Use `Money::get_minor_units()` instead. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

178
				'amount'       => /** @scrutinizer ignore-deprecated */ $payment->get_total_amount()->get_cents(),

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
179
				'description'  => substr( $payment->get_description(), 0, 32 ),
180
				'testmode'     => ( self::MODE_TEST === $this->config->mode ) ? 'true' : 'false',
181
				'returnurl'    => $payment->get_return_url(),
182
				'cancelurl'    => $payment->get_return_url(),
183
				'notifyurl'    => $payment->get_return_url(),
184
				'callbackurl'  => $payment->get_return_url(),
185
				// Other parameters.
186
				'issuerid'     => $payment->get_issuer(),
187
				'billing_mail' => $payment->get_email(),
188
			)
189
		);
190
191
		// Payment method.
192
		$this->set_payment_method( null === $payment->get_method() ? PaymentMethods::IDEAL : $payment->get_method() );
193
194
		// Additional parameters for payment method.
195
		if ( PaymentMethods::IDEALQR === $payment->get_method() ) {
196
			$request->set_parameter( 'qrcode', 'true' );
197
		}
198
199
		// Customer.
200
		if ( null !== $payment->get_customer() ) {
201
			$customer = $payment->get_customer();
202
203
			$request->merge_parameters(
204
				array(
205
					'ipaddress' => $customer->get_ip_address(),
206
					'gender'    => $customer->get_gender(),
207
				)
208
			);
209
210
			if ( null !== $customer->get_locale() ) {
211
				/*
212
				 * @link https://github.com/wp-pay-gateways/sisow/tree/feature/post-pay/documentation#parameter-locale
213
				 */
214
				$sisow_locale = strtoupper( substr( $customer->get_locale(), -2 ) );
215
216
				$request->set_parameter( 'locale', $sisow_locale );
217
			}
218
219
			if ( null !== $customer->get_birth_date() ) {
220
				$request->set_parameter( 'birthdate', $customer->get_birth_date()->format( 'dmY' ) );
221
			}
222
		}
223
224
		// Billing address.
225
		if ( null !== $payment->get_billing_address() ) {
226
			$address = $payment->get_billing_address();
227
228
			if ( null !== $address->get_name() ) {
229
				$name = $address->get_name();
230
231
				$request->merge_parameters(
232
					array(
233
						'billing_firstname' => $name->get_first_name(),
234
						'billing_lastname'  => $name->get_last_name(),
235
					)
236
				);
237
238
				// Remove accents from first name for AfterPay.
239
				if ( PaymentMethods::AFTERPAY === $payment->get_method() ) {
240
					$request->set_parameter( 'billing_firstname', remove_accents( $name->get_first_name() ) );
241
				}
242
			}
243
244
			$request->merge_parameters(
245
				array(
246
					'billing_mail'        => $address->get_email(),
247
					'billing_company'     => $address->get_company_name(),
248
					'billing_coc'         => $address->get_coc_number(),
249
					'billing_address1'    => $address->get_line_1(),
250
					'billing_address2'    => $address->get_line_2(),
251
					'billing_zip'         => $address->get_postal_code(),
252
					'billing_city'        => $address->get_city(),
253
					'billing_country'     => $address->get_country_name(),
254
					'billing_countrycode' => $address->get_country_code(),
255
					'billing_phone'       => $address->get_phone(),
256
				)
257
			);
258
		}
259
260
		// Shipping address.
261
		if ( null !== $payment->get_shipping_address() ) {
262
			$address = $payment->get_shipping_address();
263
264
			if ( null !== $address->get_name() ) {
265
				$name = $address->get_name();
266
267
				$request->merge_parameters(
268
					array(
269
						'shipping_firstname' => $name->get_first_name(),
270
						'shipping_lastname'  => $name->get_last_name(),
271
					)
272
				);
273
			}
274
275
			$request->merge_parameters(
276
				array(
277
					'shipping_mail'        => $address->get_email(),
278
					'shipping_company'     => $address->get_company_name(),
279
					'shipping_address1'    => $address->get_line_1(),
280
					'shipping_address2'    => $address->get_line_2(),
281
					'shipping_zip'         => $address->get_postal_code(),
282
					'shipping_city'        => $address->get_city(),
283
					'shipping_country'     => $address->get_country_name(),
284
					'shipping_countrycode' => $address->get_country_code(),
285
					'shipping_phone'       => $address->get_phone(),
286
				)
287
			);
288
		}
289
290
		// Lines.
291
		$lines = $payment->get_lines();
292
293
		if ( null !== $lines ) {
294
			$x = 1;
295
296
			foreach ( $lines as $line ) {
297
				// Product ID.
298
				$product_id = $line->get_id();
299
300
				switch ( $line->get_type() ) {
301
					case PaymentLineType::SHIPPING:
302
						$product_id = 'shipping';
303
304
						break;
305
					case PaymentLineType::FEE:
306
						$product_id = 'paymentfee';
307
308
						break;
309
				}
310
311
				// Price.
312
				$unit_price = null;
313
314
				if ( null !== $line->get_unit_price() ) {
315
					$unit_price = $line->get_unit_price()->get_excluding_tax()->get_cents();
316
				}
317
318
				// Request parameters.
319
				$request->merge_parameters(
320
					array(
321
						'product_id_' . $x          => $product_id,
322
						'product_description_' . $x => $line->get_name(),
323
						'product_quantity_' . $x    => $line->get_quantity(),
324
						'product_netprice_' . $x    => $unit_price,
325
						'product_total_' . $x       => $line->get_total_amount()->get_including_tax()->get_cents(),
326
						'product_nettotal_' . $x    => $line->get_total_amount()->get_excluding_tax()->get_cents(),
327
					)
328
				);
329
330
				// Tax request parameters.
331
				$tax_amount = $line->get_tax_amount();
332
333
				if ( null !== $tax_amount ) {
334
					$request->set_parameter( 'product_tax_' . $x, $tax_amount->get_cents() );
335
				}
336
337
				$tax_percentage = $line->get_total_amount()->get_tax_percentage();
338
339
				if ( null !== $tax_percentage ) {
340
					$request->set_parameter( 'product_taxrate_' . $x, $tax_percentage * 100 );
341
				}
342
343
				$x++;
344
			}
345
		}
346
347
		// Create transaction.
348
		$result = $this->client->create_transaction( $request );
349
350
		if ( false !== $result ) {
351
			$payment->set_transaction_id( $result->id );
352
			$payment->set_action_url( $result->issuer_url );
353
		}
354
	}
355
356
	/**
357
	 * Update status of the specified payment
358
	 *
359
	 * @param Payment $payment Payment.
360
	 */
361
	public function update_status( Payment $payment ) {
362
		$request = new StatusRequest(
363
			$payment->get_transaction_id(),
364
			$this->config->merchant_id,
365
			$this->config->shop_id
366
		);
367
368
		$result = $this->client->get_status( $request );
369
370
		if ( false === $result ) {
371
			$this->error = $this->client->get_error();
372
373
			return;
374
		}
375
376
		$transaction = $result;
377
378
		$payment->set_status( Statuses::transform( $transaction->status ) );
379
		$payment->set_consumer_name( $transaction->consumer_name );
380
		$payment->set_consumer_account_number( $transaction->consumer_account );
381
		$payment->set_consumer_city( $transaction->consumer_city );
382
	}
383
384
	/**
385
	 * Create invoice.
386
	 *
387
	 * @param Payment $payment Payment.
388
	 *
389
	 * @return bool|Invoice
390
	 */
391
	public function create_invoice( $payment ) {
392
		$transaction_id = $payment->get_transaction_id();
393
394
		if ( empty( $transaction_id ) ) {
395
			return false;
396
		}
397
398
		// Invoice request.
399
		$request = new InvoiceRequest(
400
			$this->config->merchant_id,
401
			$this->config->shop_id
402
		);
403
404
		$request->set_parameter( 'trxid', $transaction_id );
405
406
		// Create invoice.
407
		$result = $this->client->create_invoice( $request );
408
409
		// Handle errors.
410
		if ( false === $result ) {
411
			$this->error = $this->client->get_error();
412
413
			return false;
414
		}
415
416
		$payment->set_status( Core_Statuses::SUCCESS );
417
418
		$payment->save();
419
420
		return $result;
421
	}
422
423
	/**
424
	 * Cancel reservation.
425
	 *
426
	 * @param Payment $payment Payment.
427
	 *
428
	 * @return bool|Reservation
429
	 */
430
	public function cancel_reservation( $payment ) {
431
		$transaction_id = $payment->get_transaction_id();
432
433
		if ( empty( $transaction_id ) ) {
434
			return false;
435
		}
436
437
		// Cancel reservation request.
438
		$request = new CancelReservationRequest(
439
			$this->config->merchant_id,
440
			$this->config->shop_id
441
		);
442
443
		$request->set_parameter( 'trxid', $transaction_id );
444
445
		// Cancel reservation.
446
		$result = $this->client->cancel_reservation( $request );
447
448
		// Handle errors.
449
		if ( false === $result ) {
450
			$this->error = $this->client->get_error();
451
452
			return false;
453
		}
454
455
		if ( isset( $result->status ) ) {
456
			$payment->set_status( Statuses::transform( $result->status ) );
457
458
			$payment->save();
459
		}
460
461
		return $result;
462
	}
463
}
464