Test Failed
Push — develop ( bf165b...42667f )
by Reüel
04:04
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 . ').', $response );
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
		$payment_methods = array();
214
215
		if ( isset( $response->_embedded->methods ) ) {
216
			foreach ( $response->_embedded->methods as $payment_method ) {
217
				$id   = Security::filter( $payment_method->id );
218
				$name = Security::filter( $payment_method->description );
219
220
				$payment_methods[ $id ] = $name;
221
			}
222
		}
223
224
		return $payment_methods;
225 1
	}
226 1
227
	/**
228 1
	 * Create customer.
229 1
	 *
230
	 * @since 1.1.6
231
	 *
232 1
	 * @param string $email Customer email address.
233
	 * @param string $name  Customer name.
234 1
	 *
235 1
	 * @return string|bool
236
	 */
237
	public function create_customer( $email, $name ) {
238
		if ( empty( $email ) ) {
239
			return false;
240
		}
241
242
		$response = $this->send_request(
243
			'customers',
244
			'POST',
245
			array(
246
				'name'  => $name,
247
				'email' => $email,
248
			),
249
			201
250
		);
251
252
		if ( ! isset( $response->id ) ) {
253
			return false;
254
		}
255
256
		return $response->id;
257
	}
258
259
	/**
260
	 * Get customer.
261
	 *
262
	 * @param string $customer_id Mollie customer ID.
263
	 *
264
	 * @since unreleased
265
	 *
266
	 * @return object|bool
267
	 */
268
	public function get_customer( $customer_id ) {
269
		if ( empty( $customer_id ) ) {
270
			return false;
271
		}
272
273
		try {
274
			$response = $this->send_request( 'customers/' . $customer_id, 'GET', array(), 200 );
275
		} catch ( \Pronamic\WordPress\Pay\GatewayException $e ) {
276
			return false;
277
		}
278
279
		return $response;
280
	}
281
282
	/**
283
	 * Get mandates for customer.
284
	 *
285
	 * @param string $customer_id Mollie customer ID.
286
	 *
287
	 * @return object|bool
288
	 */
289
	public function get_mandates( $customer_id ) {
290
		if ( '' === $customer_id ) {
291
			return false;
292
		}
293
294
		return $this->send_request( 'customers/' . $customer_id . '/mandates?limit=250', 'GET' );
295
	}
296
297 5
	/**
298 5
	 * Is there a valid mandate for customer?
299
	 *
300
	 * @param string      $customer_id    Mollie customer ID.
301
	 * @param string|null $payment_method Payment method to find mandates for.
302 5
	 *
303
	 * @return boolean
304 5
	 */
305 5
	public function has_valid_mandate( $customer_id, $payment_method = null ) {
306
		$mandates = $this->get_mandates( $customer_id );
307
308
		if ( ! $mandates ) {
309
			return false;
310
		}
311
312
		$mollie_method = Methods::transform( $payment_method );
313
314
		foreach ( $mandates->_embedded as $mandate ) {
315
			if ( $mollie_method !== $mandate->method ) {
316
				continue;
317
			}
318
319
			if ( 'valid' === $mandate->status ) {
320
				return true;
321
			}
322
		}
323
324
		return false;
325
	}
326
327
	/**
328
	 * Get formatted date and time of first valid mandate.
329
	 *
330
	 * @param string $customer_id    Mollie customer ID.
331
	 * @param string $payment_method Payment method.
332
	 *
333
	 * @return null|DateTime
334
	 */
335
	public function get_first_valid_mandate_datetime( $customer_id, $payment_method = null ) {
336
		$mandates = $this->get_mandates( $customer_id );
337
338
		if ( ! $mandates ) {
339
			return null;
340
		}
341
342
		$mollie_method = Methods::transform( $payment_method );
343
344
		foreach ( $mandates->_embedded as $mandate ) {
345
			if ( $mollie_method !== $mandate->method ) {
346
				continue;
347
			}
348
349
			if ( 'valid' !== $mandate->status ) {
350
				continue;
351
			}
352
353
			if ( ! isset( $valid_mandates ) ) {
354
				$valid_mandates = array();
355
			}
356
357
			// @codingStandardsIgnoreStart
358
			$valid_mandates[ $mandate->createdAt ] = $mandate;
359
			// @codingStandardsIgnoreEnd
360
		}
361
362
		if ( isset( $valid_mandates ) ) {
363
			ksort( $valid_mandates );
364
365
			$mandate = array_shift( $valid_mandates );
366
367
			// @codingStandardsIgnoreStart
368
			$create_date = new DateTime( $mandate->createdAt );
369
			// @codingStandardsIgnoreEnd
370
371
			return $create_date;
372
		}
373
374
		return null;
375
	}
376
}
377