Failed Conditions
Push — develop ( 7ab430...20d773 )
by Reüel
05:20
created

src/Gateway.php (2 issues)

Labels
Severity
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
	 * Constructs and intializes 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 Pronamic_WP_Pay_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 Pronamic_WP_Pay_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 Pronamic_WP_Pay_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
192
			if ( null !== $payment->get_customer() ) {
193
				$locale = $payment->get_customer()->get_locale();
194
195
				$language = strtoupper( $payment->get_customer()->get_language() );
0 ignored issues
show
It seems like $payment->get_customer()->get_language() can also be of type null; however, parameter $string of strtoupper() 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

195
				$language = strtoupper( /** @scrutinizer ignore-type */ $payment->get_customer()->get_language() );
Loading history...
196
			}
197
198
			$country = strtoupper( substr( $locale, 3, 2 ) );
0 ignored issues
show
It seems like $locale can also be of type null; however, parameter $string of substr() 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

198
			$country = strtoupper( substr( /** @scrutinizer ignore-type */ $locale, 3, 2 ) );
Loading history...
199
200
			// Set country from billing address.
201
			if ( null !== $payment->get_billing_address() ) {
202
				$country_code = $payment->get_billing_address()->get_country_code();
203
204
				if ( ! empty( $country_code ) ) {
205
					$country = $country_code;
206
				}
207
			}
208
209
			// Payment object.
210
			$payment_object = new Icepay_PaymentObject();
211
			$payment_object
212
				->setAmount( $payment->get_total_amount()->get_minor_units() )
213
				->setCountry( $country )
214
				->setLanguage( $language )
215
				->setReference( $payment->get_order_id() )
216
				->setDescription( $payment->get_description() )
217
				->setCurrency( $payment->get_total_amount()->get_currency()->get_alphabetic_code() )
218
				->setIssuer( $payment->get_issuer() )
219
				->setOrderID( $payment->format_string( $this->config->order_id ) );
220
221
			/*
222
			 * Payment method
223
			 * @since 1.2.0
224
			 */
225
			$icepay_method = null;
226
227
			switch ( $payment->get_method() ) {
228
				case PaymentMethods::CREDIT_CARD:
229
					// @link https://github.com/icepay/icepay/blob/2.4.0/api/paymentmethods/creditcard.php
230
					$icepay_method = new Icepay_Paymentmethod_Creditcard();
231
232
					break;
233
				case PaymentMethods::DIRECT_DEBIT:
234
					// @link https://github.com/icepay/icepay/blob/2.4.0/api/paymentmethods/ddebit.php
235
					$icepay_method = new Icepay_Paymentmethod_Ddebit();
236
237
					break;
238
				case PaymentMethods::IDEAL:
239
					// @link https://github.com/icepay/icepay/blob/2.4.0/api/paymentmethods/ideal.php
240
					$icepay_method = new Icepay_Paymentmethod_Ideal();
241
242
					break;
243
				case PaymentMethods::BANCONTACT:
244
				case PaymentMethods::MISTER_CASH:
245
					// @link https://github.com/icepay/icepay/blob/2.4.0/api/paymentmethods/mistercash.php
246
					$icepay_method = new Icepay_Paymentmethod_Mistercash();
247
248
					break;
249
				case PaymentMethods::SOFORT:
250
					// @link https://github.com/icepay/icepay/blob/2.4.0/api/paymentmethods/directebank.php
251
					$icepay_method = new Icepay_Paymentmethod_Directebank();
252
253
					// Set issuer.
254
					$issuer = 'DIGITAL';
255
256
					$lines = $payment->get_lines();
257
258
					if ( null !== $lines ) {
259
						foreach ( $lines as $line ) {
260
							$issuer = DirectebankIssuers::transform( $line->get_type() );
261
262
							break;
263
						}
264
					}
265
266
					$payment_object->setIssuer( $issuer );
267
			}
268
269
			if ( isset( $icepay_method ) ) {
270
				// @link https://github.com/icepay/icepay/blob/2.4.0/api/icepay_api_base.php#L342-L353
271
				$payment_object->setPaymentMethod( $icepay_method->getCode() );
272
273
				// Force language 'NL' for unsupported languages (i.e. 'EN' for iDEAL).
274
				if ( ! in_array( $language, $icepay_method->getSupportedLanguages(), true ) ) {
275
					$payment_object->setLanguage( 'NL' );
276
				}
277
			}
278
279
			// Protocol.
280
			$protocol = is_ssl() ? 'https' : 'http';
281
282
			// Basic mode.
283
			$basicmode = Icepay_Basicmode::getInstance();
284
			$basicmode
285
				->setMerchantID( $this->config->merchant_id )
286
				->setSecretCode( $this->config->secret_code )
287
				->setProtocol( $protocol )
288
				->setSuccessURL( $payment->get_return_url() )
289
				->setErrorURL( $payment->get_return_url() )
290
				->validatePayment( $payment_object );
291
292
			// Action URL.
293
			$payment->set_action_url( $basicmode->getURL() );
294
		} catch ( Exception $exception ) {
295
			$this->error = new WP_Error( 'icepay_error', $exception->getMessage(), $exception );
296
		}
297
	}
298
299
	/**
300
	 * Update the status of the specified payment
301
	 *
302
	 * @param Payment $payment Payment.
303
	 */
304
	public function update_status( Payment $payment ) {
305
		// Get the Icepay Result and set the required fields.
306
		$result = ( 'POST' === Server::get( 'REQUEST_METHOD' ) ? new Icepay_Postback() : new Icepay_Result() );
307
308
		try {
309
			$result
310
				->setMerchantID( $this->config->merchant_id )
311
				->setSecretCode( $this->config->secret_code );
312
313
			// Determine if the result can be validated.
314
			if ( $result->validate() ) {
315
				// What was the status response.
316
				switch ( $result->getStatus() ) {
317
					case Icepay_StatusCode::SUCCESS:
318
						$payment->set_status( PaymentStatus::SUCCESS );
319
320
						break;
321
					case Icepay_StatusCode::OPEN:
322
						$payment->set_status( PaymentStatus::OPEN );
323
324
						break;
325
					case Icepay_StatusCode::ERROR:
326
						$status = PaymentStatus::FAILURE;
327
328
						$data = null;
329
330
						// Check if payment is cancelled.
331
						if ( $result instanceof \Icepay_Postback ) {
332
							$data = $result->getPostback();
333
						} else {
334
							$data = $result->getResultData();
335
						}
336
337
						// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
338
						if ( \is_object( $data ) && isset( $data->statusCode ) && 'Cancelled' === $data->statusCode ) {
339
							$status = PaymentStatus::CANCELLED;
340
						}
341
342
						$payment->set_status( $status );
343
344
						break;
345
				}
346
			}
347
		} catch ( Exception $exception ) {
348
			$this->error = new WP_Error( 'icepay_error', $exception->getMessage(), $exception );
349
		}
350
	}
351
}
352