Failed Conditions
Push — develop ( a65457...184cc4 )
by Reüel
06:23
created

Gateway::get_issuers()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 37
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 24
nc 5
nop 0
dl 0
loc 37
ccs 0
cts 24
cp 0
crap 30
rs 9.2248
c 1
b 0
f 0
1
<?php
2
3
namespace Pronamic\WordPress\Pay\Gateways\Icepay;
4
5
use Exception;
6
use Icepay_Api_Webservice;
7
use Icepay_Basicmode;
8
use Icepay_Paymentmethod_Creditcard;
9
use Icepay_Paymentmethod_Ddebit;
10
use Icepay_Paymentmethod_Directebank;
11
use Icepay_Paymentmethod_Ideal;
12
use Icepay_Paymentmethod_Mistercash;
13
use Icepay_PaymentObject;
14
use Icepay_Postback;
15
use Icepay_Result;
16
use Icepay_StatusCode;
17
use Pronamic\WordPress\Pay\Core\Gateway as Core_Gateway;
18
use Pronamic\WordPress\Pay\Core\PaymentMethods;
19
use Pronamic\WordPress\Pay\Core\Server;
20
use Pronamic\WordPress\Pay\Payments\PaymentStatus;
21
use Pronamic\WordPress\Pay\Payments\Payment;
22
use WP_Error;
23
24
/**
25
 * Title: ICEPAY gateway
26
 * Description:
27
 * Copyright: 2005-2021 Pronamic
28
 * Company: Pronamic
29
 *
30
 * @author Remco Tolsma
31
 * @version 2.0.6
32
 * @since 1.0.0
33
 */
34
class Gateway extends Core_Gateway {
35
	/**
36
	 * Construct and initialize an ICEPAY gateway
37
	 *
38
	 * @param Config $config Config.
39
	 */
40 1
	public function __construct( Config $config ) {
41 1
		parent::__construct( $config );
42
43
		// Default properties for this gateway.
44 1
		$this->set_method( self::METHOD_HTTP_REDIRECT );
45
46
		// Supported features.
47 1
		$this->supports = array();
48 1
	}
49
50
	/**
51
	 * Filter iDEAL
52
	 *
53
	 * @param array $method Payment method.
54
	 *
55
	 * @return bool
56
	 */
57
	private function filter_ideal( $method ) {
58
		return is_array( $method ) && isset( $method['PaymentMethodCode'] ) && 'IDEAL' === $method['PaymentMethodCode'];
59
	}
60
61
	/**
62
	 * Get issuers
63
	 *
64
	 * @see Core_Gateway::get_issuers()
65
	 */
66
	public function get_issuers() {
67
		$groups  = array();
68
		$issuers = array();
69
70
		try {
71
			$methods = Icepay_Api_Webservice::getInstance()
72
						->paymentmethodService()
73
						->setMerchantID( $this->config->merchant_id )
74
						->setSecretCode( $this->config->secret_code )
75
						->retrieveAllPaymentmethods()
76
						->asArray();
77
		} catch ( Exception $e ) {
78
			return $groups;
79
		}
80
81
		$ideal_methods = array_filter( $methods, array( $this, 'filter_ideal' ) );
82
83
		if ( ! empty( $ideal_methods ) ) {
84
			$issuers = Icepay_Api_Webservice::getInstance()->singleMethod()
85
						->loadFromArray( $methods )
86
						->selectPaymentMethodByCode( 'IDEAL' )
87
						->getIssuers();
88
		}
89
90
		if ( $issuers ) {
91
			$options = array();
92
93
			foreach ( $issuers as $issuer ) {
94
				$options[ $issuer['IssuerKeyword'] ] = $issuer['Description'];
95
			}
96
97
			$groups[] = array(
98
				'options' => $options,
99
			);
100
		}
101
102
		return $groups;
103
	}
104
105
	/**
106
	 * Get issuers
107
	 *
108
	 * @see Core_Gateway::get_issuers()
109
	 */
110
	public function get_credit_card_issuers() {
111
		$groups  = array();
112
		$issuers = array();
113
114
		$method = new Icepay_Paymentmethod_Creditcard();
115
116
		if ( isset( $method->_issuer ) ) {
117
			$issuers = $method->_issuer;
118
		}
119
120
		if ( $issuers ) {
121
			$options = array();
122
123
			foreach ( $issuers as $issuer ) {
124
				switch ( $issuer ) {
125
					case 'AMEX':
126
						$name = _x( 'AMEX', 'Payment method name', 'pronamic_ideal' );
127
128
						break;
129
					case 'MASTER':
130
						$name = _x( 'MASTER', 'Payment method name', 'pronamic_ideal' );
131
132
						break;
133
					case 'VISA':
134
						$name = _x( 'VISA', 'Payment method name', 'pronamic_ideal' );
135
136
						break;
137
					default:
138
						$name = $issuer;
139
140
						break;
141
				}
142
143
				$options[ $issuer ] = $name;
144
			}
145
146
			$groups[] = array(
147
				'options' => $options,
148
			);
149
		}
150
151
		return $groups;
152
	}
153
154
	/**
155
	 * Get supported payment methods
156
	 *
157
	 * @see Core_Gateway::get_supported_payment_methods()
158
	 */
159
	public function get_supported_payment_methods() {
160
		return array(
161
			PaymentMethods::IDEAL,
162
			PaymentMethods::CREDIT_CARD,
163
			PaymentMethods::DIRECT_DEBIT,
164
			PaymentMethods::BANCONTACT,
165
			PaymentMethods::SOFORT,
166
		);
167
	}
168
169
	/**
170
	 * Start an transaction
171
	 *
172
	 * @see Core_Gateway::start()
173
	 *
174
	 * @param Payment $payment Payment.
175
	 */
176
	public function start( Payment $payment ) {
177
		try {
178
			/*
179
			 * Order ID
180
			 * Your unique order number.
181
			 * This can be auto incremental number from your payments table
182
			 *
183
			 * Data type  = String
184
			 * Max length = 10
185
			 * Required   = Yes
186
			 */
187
188
			// Locale, country and language.
189
			$locale   = get_locale();
190
			$language = substr( $locale, 0, 2 );
191
			$country  = strtoupper( substr( $locale, 3, 2 ) );
192
193
			$customer = $payment->get_customer();
194
195
			if ( null !== $customer ) {
196
				$locale = $customer->get_locale();
197
198
				if ( null !== $locale ) {
199
					$locale_parts = \explode( '_', $locale );
200
201
					// Locale not always contains `_`, e.g. "Nederlands" in Firefox.
202
					if ( count( $locale_parts ) > 1 ) {
203
						$country = $locale_parts[1];
204
					}
205
				}
206
207
				$language = strtoupper( (string) $customer->get_language() );
208
			}
209
210
			// Set country from billing address.
211
			$billing_address = $payment->get_billing_address();
212
213
			if ( null !== $billing_address ) {
214
				$country_code = $billing_address->get_country_code();
215
216
				if ( ! empty( $country_code ) ) {
217
					$country = $country_code;
218
				}
219
			}
220
221
			// Payment object.
222
			$payment_object = new Icepay_PaymentObject();
223
			$payment_object
224
				->setAmount( $payment->get_total_amount()->get_minor_units()->to_int() )
225
				->setCountry( $country )
226
				->setLanguage( $language )
227
				->setReference( $payment->get_order_id() )
228
				->setDescription( $payment->get_description() )
229
				->setCurrency( $payment->get_total_amount()->get_currency()->get_alphabetic_code() )
230
				->setIssuer( $payment->get_meta( 'issuer' ) )
0 ignored issues
show
Bug introduced by
It seems like $payment->get_meta('issuer') can also be of type false; however, parameter $issuer of Icepay_PaymentObject::setIssuer() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

230
				->setIssuer( /** @scrutinizer ignore-type */ $payment->get_meta( 'issuer' ) )
Loading history...
231
				->setOrderID( $payment->format_string( $this->config->order_id ) );
232
233
			/*
234
			 * Payment method
235
			 * @since 1.2.0
236
			 */
237
			$icepay_method = null;
238
239
			switch ( $payment->get_payment_method() ) {
0 ignored issues
show
Bug introduced by
The method get_payment_method() does not exist on Pronamic\WordPress\Pay\Payments\Payment. ( Ignorable by Annotation )

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

239
			switch ( $payment->/** @scrutinizer ignore-call */ get_payment_method() ) {

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...
240
				case PaymentMethods::CREDIT_CARD:
241
					// @link https://github.com/icepay/icepay/blob/2.4.0/api/paymentmethods/creditcard.php
242
					$icepay_method = new Icepay_Paymentmethod_Creditcard();
243
244
					break;
245
				case PaymentMethods::DIRECT_DEBIT:
246
					// @link https://github.com/icepay/icepay/blob/2.4.0/api/paymentmethods/ddebit.php
247
					$icepay_method = new Icepay_Paymentmethod_Ddebit();
248
249
					break;
250
				case PaymentMethods::IDEAL:
251
					// @link https://github.com/icepay/icepay/blob/2.4.0/api/paymentmethods/ideal.php
252
					$icepay_method = new Icepay_Paymentmethod_Ideal();
253
254
					break;
255
				case PaymentMethods::BANCONTACT:
256
				case PaymentMethods::MISTER_CASH:
0 ignored issues
show
Deprecated Code introduced by
The constant Pronamic\WordPress\Pay\C...entMethods::MISTER_CASH has been deprecated: "Bancontact/Mister Cash" was renamed to just "Bancontact". ( Ignorable by Annotation )

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

256
				case /** @scrutinizer ignore-deprecated */ PaymentMethods::MISTER_CASH:

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

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

Loading history...
257
					// @link https://github.com/icepay/icepay/blob/2.4.0/api/paymentmethods/mistercash.php
258
					$icepay_method = new Icepay_Paymentmethod_Mistercash();
259
260
					break;
261
				case PaymentMethods::SOFORT:
262
					// @link https://github.com/icepay/icepay/blob/2.4.0/api/paymentmethods/directebank.php
263
					$icepay_method = new Icepay_Paymentmethod_Directebank();
264
265
					// Set issuer.
266
					$issuer = 'DIGITAL';
267
268
					$lines = $payment->get_lines();
269
270
					if ( null !== $lines ) {
271
						foreach ( $lines as $line ) {
272
							$issuer = DirectebankIssuers::transform( $line->get_type() );
273
274
							break;
275
						}
276
					}
277
278
					$payment_object->setIssuer( $issuer );
279
			}
280
281
			if ( isset( $icepay_method ) ) {
282
				// @link https://github.com/icepay/icepay/blob/2.4.0/api/icepay_api_base.php#L342-L353
283
				$payment_object->setPaymentMethod( $icepay_method->getCode() );
284
285
				// Force language 'NL' for unsupported languages (i.e. 'EN' for iDEAL).
286
				if ( ! in_array( $language, $icepay_method->getSupportedLanguages(), true ) ) {
287
					$payment_object->setLanguage( 'NL' );
288
				}
289
			}
290
291
			// Protocol.
292
			$protocol = is_ssl() ? 'https' : 'http';
293
294
			// Basic mode.
295
			$basicmode = Icepay_Basicmode::getInstance();
296
			$basicmode
297
				->setMerchantID( $this->config->merchant_id )
298
				->setSecretCode( $this->config->secret_code )
299
				->setProtocol( $protocol )
300
				->setSuccessURL( $payment->get_return_url() )
301
				->setErrorURL( $payment->get_return_url() )
302
				->validatePayment( $payment_object );
303
304
			// Action URL.
305
			$payment->set_action_url( $basicmode->getURL() );
306
		} catch ( Exception $exception ) {
307
			$this->error = new WP_Error( 'icepay_error', $exception->getMessage(), $exception );
308
		}
309
	}
310
311
	/**
312
	 * Update the status of the specified payment
313
	 *
314
	 * @param Payment $payment Payment.
315
	 */
316
	public function update_status( Payment $payment ) {
317
		// Get the Icepay Result and set the required fields.
318
		$result = ( 'POST' === Server::get( 'REQUEST_METHOD' ) ? new Icepay_Postback() : new Icepay_Result() );
319
320
		try {
321
			$result
322
				->setMerchantID( $this->config->merchant_id )
323
				->setSecretCode( $this->config->secret_code );
324
325
			// Determine if the result can be validated.
326
			if ( $result->validate() ) {
327
				// What was the status response.
328
				switch ( $result->getStatus() ) {
329
					case Icepay_StatusCode::SUCCESS:
330
						$payment->set_status( PaymentStatus::SUCCESS );
331
332
						break;
333
					case Icepay_StatusCode::OPEN:
334
						$payment->set_status( PaymentStatus::OPEN );
335
336
						break;
337
					case Icepay_StatusCode::ERROR:
338
						$status = PaymentStatus::FAILURE;
339
340
						$data = null;
341
342
						// Check if payment is cancelled.
343
						if ( $result instanceof \Icepay_Postback ) {
344
							$data = $result->getPostback();
345
						} else {
346
							$data = $result->getResultData();
347
						}
348
349
						// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
350
						if ( \is_object( $data ) && isset( $data->statusCode ) && 'Cancelled' === $data->statusCode ) {
351
							$status = PaymentStatus::CANCELLED;
352
						}
353
354
						$payment->set_status( $status );
355
356
						break;
357
				}
358
			}
359
		} catch ( Exception $exception ) {
360
			$this->error = new WP_Error( 'icepay_error', $exception->getMessage(), $exception );
361
		}
362
	}
363
}
364