Test Failed
Branch develop (9b7a55)
by Reüel
03:15
created

src/Client.php (2 issues)

Labels
Severity
1
<?php
2
/**
3
 * Mollie client.
4
 *
5
 * @author    Pronamic <[email protected]>
6
 * @copyright 2005-2019 Pronamic
7
 * @license   GPL-3.0-or-later
8
 * @package   Pronamic\WordPress\Pay
9
 */
10
11
namespace Pronamic\WordPress\Pay\Gateways\Mollie;
12
13
use Pronamic\WordPress\DateTime\DateTime;
14
use Pronamic\WordPress\Pay\Core\XML\Security;
15
16
/**
17
 * Title: Mollie
18
 * Description:
19
 * Copyright: 2005-2019 Pronamic
20
 * Company: Pronamic
21
 *
22
 * @author  Remco Tolsma
23
 * @version 2.1.0
24
 * @since   1.0.0
25
 */
26
class Client {
27
	/**
28
	 * Mollie API endpoint URL
29
	 *
30
	 * @var string
31
	 */
32
	const API_URL = 'https://api.mollie.com/v2/';
33
34
	/**
35
	 * Mollie API Key ID
36
	 *
37
	 * @var string
38
	 */
39
	private $api_key;
40
41
	/**
42
	 * Mode
43
	 *
44
	 * @since 1.1.9
45
	 * @var string
46
	 */
47
	private $mode;
48
49
	/**
50
	 * Constructs and initializes an Mollie client object
51
	 *
52
	 * @param string $api_key Mollie API key.
53
	 */
54
	public function __construct( $api_key ) {
55
		$this->api_key = $api_key;
56
	}
57
58
	/**
59
	 * Set mode
60
	 *
61
	 * @since 1.1.9
62 38
	 * @param string $mode Mode (test or live).
63 38
	 */
64 38
	public function set_mode( $mode ) {
65
		$this->mode = $mode;
66
	}
67
68
	/**
69
	 * Send request with the specified action and parameters
70
	 *
71
	 * @param string $end_point              Requested endpoint.
72 38
	 * @param string $method                 HTTP method to use.
73 38
	 * @param array  $data                   Request data.
74 38
	 * @param int    $expected_response_code Expected response code.
75
	 * @return bool|object
76
	 * @throws \Pronamic\WordPress\Pay\GatewayException Throws exception when error occurs.
77
	 */
78
	private function send_request( $end_point, $method = 'GET', array $data = array(), $expected_response_code = 200 ) {
79
		// Request.
80
		$url = self::API_URL . $end_point;
81 3
82 3
		$response = wp_remote_request(
83
			$url,
84
			array(
85
				'method'  => $method,
86
				'headers' => array(
87
					'Authorization' => 'Bearer ' . $this->api_key,
88
				),
89
				'body'    => $data,
90
			)
91
		);
92
93
		if ( $response instanceof \WP_Error ) {
94
			throw new \Pronamic\WordPress\Pay\GatewayException( 'mollie', $response->get_error_message() );
0 ignored issues
show
The type Pronamic\WordPress\Pay\GatewayException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
95 8
		}
96
97 8
		// Response code.
98
		$response_code = wp_remote_retrieve_response_code( $response );
99 8
100 8
		// phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
101
		if ( $expected_response_code != $response_code ) {
102 8
			throw new \Pronamic\WordPress\Pay\GatewayException( 'mollie', 'Unexpected response code (' . $response_code . ').' );
103
		}
104 8
105
		// Body.
106 8
		$body = wp_remote_retrieve_body( $response );
107
108
		$data = json_decode( $body );
109
110 8
		// JSON error.
111
		$json_error = \json_last_error();
112
113
		if ( \JSON_ERROR_NONE !== $json_error ) {
114
			throw new Pronamic\WordPress\Pay\GatewayException(
0 ignored issues
show
The type Pronamic\WordPress\Pay\G...ss\Pay\GatewayException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
115 8
				'mollie',
116
				\sprintf( 'JSON: %s', \json_last_error_msg() ),
117
				$json_error
118 8
			);
119 8
		}
120
121
		// Object.
122
		if ( ! \is_object( $data ) ) {
123 8
			$code = \wp_remote_retrieve_response_code( $response );
124
125 8
			throw new Pronamic\WordPress\Pay\GatewayException(
126
				'mollie',
127
				\sprintf( 'Could not JSON decode Mollie response to an object (HTTP Status Code: %s).', $code ),
128 8
				\intval( $code )
129
			);
130 8
		}
131
132
		// Mollie error.
133
		if ( isset( $data->status, $data->title, $data->detail ) ) {
134
			throw new Pronamic\WordPress\Pay\GatewayException( 'mollie', $data->detail, $data );
135
		}
136
137
		return $data;
138 8
	}
139
140
	/**
141
	 * Create payment.
142
	 *
143
	 * @param PaymentRequest $request Payment request.
144
	 *
145
	 * @return bool|object
146
	 */
147
	public function create_payment( PaymentRequest $request ) {
148 8
		return $this->send_request( 'payments', 'POST', $request->get_array(), 201 );
149 8
	}
150
151 8
	/**
152
	 * Get payments.
153
	 *
154
	 * @return bool|object
155
	 */
156
	public function get_payments() {
157
		return $this->send_request( 'payments', 'GET' );
158
	}
159
160
	/**
161
	 * Get payment.
162
	 *
163
	 * @param string $payment_id Payment ID.
164
	 *
165
	 * @return bool|object
166
	 */
167
	public function get_payment( $payment_id ) {
168
		if ( empty( $payment_id ) ) {
169
			return false;
170
		}
171
172
		return $this->send_request( 'payments/' . $payment_id, 'GET' );
173
	}
174
175
	/**
176
	 * Get issuers
177
	 *
178
	 * @return array|bool
179
	 */
180
	public function get_issuers() {
181
		$response = $this->send_request( 'methods/ideal?include=issuers', 'GET' );
182
183
		$issuers = array();
184
185
		if ( isset( $response->issuers ) ) {
186
			foreach ( $response->issuers as $issuer ) {
187
				$id   = Security::filter( $issuer->id );
188
				$name = Security::filter( $issuer->name );
189
190
				$issuers[ $id ] = $name;
191
			}
192
		}
193
194
		return $issuers;
195
	}
196
197 2
	/**
198 2
	 * Get payment methods
199
	 *
200 2
	 * @param string $sequence_type Sequence type.
201 2
	 *
202
	 * @return array|bool
203
	 */
204
	public function get_payment_methods( $sequence_type = '' ) {
205
		$data = array();
206
207
		if ( '' !== $sequence_type ) {
208
			$data['sequenceType'] = $sequence_type;
209
		}
210
211
		$response = $this->send_request( 'methods', 'GET', $data );
212
213
		if ( false === $response ) {
214
			return false;
215
		}
216
217
		$payment_methods = array();
218
219
		if ( isset( $response->_embedded->methods ) ) {
220
			foreach ( $response->_embedded->methods as $payment_method ) {
221
				$id   = Security::filter( $payment_method->id );
222
				$name = Security::filter( $payment_method->description );
223
224
				$payment_methods[ $id ] = $name;
225 1
			}
226 1
		}
227
228 1
		return $payment_methods;
229 1
	}
230
231
	/**
232 1
	 * Create customer.
233
	 *
234 1
	 * @since 1.1.6
235 1
	 *
236
	 * @param string $email Customer email address.
237
	 * @param string $name  Customer name.
238
	 *
239
	 * @return string|bool
240
	 */
241
	public function create_customer( $email, $name ) {
242
		if ( empty( $email ) ) {
243
			return false;
244
		}
245
246
		$response = $this->send_request(
247
			'customers',
248
			'POST',
249
			array(
250
				'name'  => $name,
251
				'email' => $email,
252
			),
253
			201
254
		);
255
256
		if ( false === $response ) {
257
			return false;
258
		}
259
260
		if ( ! isset( $response->id ) ) {
261
			return false;
262
		}
263
264
		return $response->id;
265
	}
266
267
	/**
268
	 * Get customer.
269
	 *
270
	 * @param string $customer_id Mollie customer ID.
271
	 *
272
	 * @since unreleased
273
	 *
274
	 * @return object|bool
275
	 */
276
	public function get_customer( $customer_id ) {
277
		if ( empty( $customer_id ) ) {
278
			return false;
279
		}
280
281
		try {
282
			$response = $this->send_request( 'customers/' . $customer_id, 'GET', array(), 200 );
283
		} catch ( \Pronamic\WordPress\Pay\GatewayException $e ) {
284
			return false;
285
		}
286
287
		return $response;
288
	}
289
290
	/**
291
	 * Get mandates for customer.
292
	 *
293
	 * @param string $customer_id Mollie customer ID.
294
	 *
295
	 * @return object|bool
296
	 */
297 5
	public function get_mandates( $customer_id ) {
298 5
		if ( '' === $customer_id ) {
299
			return false;
300
		}
301
302 5
		return $this->send_request( 'customers/' . $customer_id . '/mandates?limit=250', 'GET' );
303
	}
304 5
305 5
	/**
306
	 * Is there a valid mandate for customer?
307
	 *
308
	 * @param string      $customer_id    Mollie customer ID.
309
	 * @param string|null $payment_method Payment method to find mandates for.
310
	 *
311
	 * @return boolean
312
	 */
313
	public function has_valid_mandate( $customer_id, $payment_method = null ) {
314
		$mandates = $this->get_mandates( $customer_id );
315
316
		if ( ! $mandates ) {
317
			return false;
318
		}
319
320
		$mollie_method = Methods::transform( $payment_method );
321
322
		foreach ( $mandates->_embedded as $mandate ) {
323
			if ( $mollie_method !== $mandate->method ) {
324
				continue;
325
			}
326
327
			if ( 'valid' === $mandate->status ) {
328
				return true;
329
			}
330
		}
331
332
		return false;
333
	}
334
335
	/**
336
	 * Get formatted date and time of first valid mandate.
337
	 *
338
	 * @param string $customer_id    Mollie customer ID.
339
	 * @param string $payment_method Payment method.
340
	 *
341
	 * @return null|DateTime
342
	 */
343
	public function get_first_valid_mandate_datetime( $customer_id, $payment_method = null ) {
344
		$mandates = $this->get_mandates( $customer_id );
345
346
		if ( ! $mandates ) {
347
			return null;
348
		}
349
350
		$mollie_method = Methods::transform( $payment_method );
351
352
		foreach ( $mandates->_embedded as $mandate ) {
353
			if ( $mollie_method !== $mandate->method ) {
354
				continue;
355
			}
356
357
			if ( 'valid' !== $mandate->status ) {
358
				continue;
359
			}
360
361
			if ( ! isset( $valid_mandates ) ) {
362
				$valid_mandates = array();
363
			}
364
365
			// @codingStandardsIgnoreStart
366
			$valid_mandates[ $mandate->createdAt ] = $mandate;
367
			// @codingStandardsIgnoreEnd
368
		}
369
370
		if ( isset( $valid_mandates ) ) {
371
			ksort( $valid_mandates );
372
373
			$mandate = array_shift( $valid_mandates );
374
375
			// @codingStandardsIgnoreStart
376
			$create_date = new DateTime( $mandate->createdAt );
377
			// @codingStandardsIgnoreEnd
378
379
			return $create_date;
380
		}
381
382
		return null;
383
	}
384
}
385