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

src/Gateway.php (1 issue)

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
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() ) {
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:
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