Failed Conditions
Push — develop ( c0dbff...cede1f )
by Remco
03:36
created

src/Client.php (7 issues)

1
<?php
2
/**
3
 * Adyen client
4
 *
5
 * @author    Pronamic <[email protected]>
6
 * @copyright 2005-2019 Pronamic
7
 * @license   GPL-3.0-or-later
8
 * @package   Pronamic\WordPress\Pay\Gateways\Adyen
9
 */
10
11
namespace Pronamic\WordPress\Pay\Gateways\Adyen;
12
13
use Pronamic\WordPress\Pay\Core\Gateway as Core_Gateway;
14
use Pronamic\WordPress\Pay\Core\XML\Security;
15
use WP_Error;
16
17
/**
18
 * Adyen client
19
 *
20
 * @author  Remco Tolsma
21
 * @version 1.0.0
22
 * @since   1.0.0
23
 * @link    https://github.com/adyenpayments/php/blob/master/generatepaymentform.php
24
 */
25
class Client {
26
	/**
27
	 * Config.
28
	 *
29
	 * @var Config
30
	 */
31
	private $config;
32
33
	/**
34
	 * Error
35
	 *
36
	 * @var WP_Error
37
	 */
38
	private $error;
39
40
	/**
41
	 * Constructs and initializes an Adyen client object.
42
	 *
43
	 * @param Config $config Adyen config.
44
	 */
45
	public function __construct( Config $config ) {
46
		$this->config = $config;
47
	}
48
49
	/**
50
	 * Error
51
	 *
52
	 * @return WP_Error
53
	 */
54
	public function get_error() {
55
		return $this->error;
56
	}
57
58
	/**
59
	 * Send request with the specified action and parameters
60
	 *
61
	 * @param string $api_method     Adyen API method.
62
	 * @param string $request_method HTTP method to use.
63
	 * @param object $data           Request data.
64
	 *
65
	 * @return object
66
	 */
67
	private function send_request( $api_method, $request_method = 'GET', $data ) {
68
		// Request.
69
		$url = $this->config->get_api_url( $api_method );
70
71
		$response = wp_remote_request(
72
			$url,
73
			array(
74
				'method'  => $request_method,
75
				'headers' => array(
76
					'X-API-key'    => $this->config->get_api_key(),
77
					'Content-Type' => 'application/json',
78
				),
79
				'body'    => wp_json_encode( $data ),
80
			)
81
		);
82
83
		// Response code.
84
		$response_code = wp_remote_retrieve_response_code( $response );
0 ignored issues
show
It seems like $response can also be of type WP_Error; however, parameter $response of wp_remote_retrieve_response_code() does only seem to accept array, 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

84
		$response_code = wp_remote_retrieve_response_code( /** @scrutinizer ignore-type */ $response );
Loading history...
85
86
		if ( $expected_response_code != $response_code ) { // WPCS: loose comparison ok.
87
			$this->error = new WP_Error( 'adyen_error', 'Unexpected response code.' );
88
		}
89
90
		// Body.
91
		$body = wp_remote_retrieve_body( $response );
0 ignored issues
show
It seems like $response can also be of type WP_Error; however, parameter $response of wp_remote_retrieve_body() does only seem to accept array, 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

91
		$body = wp_remote_retrieve_body( /** @scrutinizer ignore-type */ $response );
Loading history...
92
93
		$data = json_decode( $body );
94
95
		if ( ! is_object( $data ) ) {
96
			$this->error = new WP_Error( 'adyen_error', 'Could not parse response.' );
97
98
			return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type object.
Loading history...
99
		}
100
101
		// Adyen error.
102
		if ( isset( $data->errorCode, $data->message ) ) {
103
			$message = sprintf(
104
				'%1$s %2$s - %3$s',
105
				$data->status,
106
				$data->errorCode,
107
				$data->message
108
			);
109
110
			$this->error = new WP_Error( 'adyen_error', $message, $data->errorCode );
111
112
			return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type object.
Loading history...
113
		}
114
115
		return $data;
116
	}
117
118
	/**
119
	 * Create payment.
120
	 *
121
	 * @param PaymentRequest $request Payment request.
122
	 *
123
	 * @return bool|object
124
	 */
125
	public function create_payment( PaymentRequest $request ) {
126
		return $this->send_request( 'payments/', 'POST', $request->get_json(), 200 );
127
	}
128
129
	/**
130
	 * Create payment session.
131
	 *
132
	 * @param PaymentSessionRequest $request Payment session request.
133
	 *
134
	 * @return bool|object
135
	 */
136
	public function create_payment_session( PaymentSessionRequest $request ) {
137
		return $this->send_request( 'paymentSession', 'POST', $request->get_json(), 200 );
138
	}
139
140
	/**
141
	 * Get payment details.
142
	 *
143
	 * @param string $payload Payload to get payment details for.
144
	 *
145
	 * @return bool|object
146
	 */
147
	public function get_payment_details( $payload ) {
148
		if ( empty( $payload ) ) {
149
			return false;
150
		}
151
152
		$data = array(
153
			'details' => array(
154
				'payload' => $payload,
155
			),
156
		);
157
158
		return $this->send_request( 'payments/details', 'POST', $data );
0 ignored issues
show
$data of type array<string,array<string,string>> is incompatible with the type object expected by parameter $data of Pronamic\WordPress\Pay\G...\Client::send_request(). ( Ignorable by Annotation )

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

158
		return $this->send_request( 'payments/details', 'POST', /** @scrutinizer ignore-type */ $data );
Loading history...
159
	}
160
161
	/**
162
	 * Get payment result.
163
	 *
164
	 * @param string $payload Payload to get payment details for.
165
	 *
166
	 * @return bool|object
167
	 */
168
	public function get_payment_result( $payload ) {
169
		if ( empty( $payload ) ) {
170
			return false;
171
		}
172
173
		$data = array(
174
			'payload' => $payload,
175
		);
176
177
		return $this->send_request( 'payments/result', 'POST', $data );
0 ignored issues
show
$data of type array<string,string> is incompatible with the type object expected by parameter $data of Pronamic\WordPress\Pay\G...\Client::send_request(). ( Ignorable by Annotation )

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

177
		return $this->send_request( 'payments/result', 'POST', /** @scrutinizer ignore-type */ $data );
Loading history...
178
	}
179
180
	/**
181
	 * Get issuers.
182
	 *
183
	 * @param string $payment_method Payment method.
184
	 *
185
	 * @return array|bool
186
	 */
187
	public function get_issuers( $payment_method = null ) {
188
		// Check payment method.
189
		if ( empty( $payment_method ) ) {
190
			return false;
191
		}
192
193
		// Get issuers.
194
		$methods = $this->get_payment_methods();
195
196
		if ( false === $methods ) {
197
			return false;
198
		}
199
200
		$issuers = array();
201
202
		foreach ( $methods as $method_type => $method ) {
203
			if ( $payment_method !== $method_type ) {
204
				continue;
205
			}
206
207
			if ( ! isset( $method['details']['issuer'] ) ) {
208
				return false;
209
			}
210
211
			foreach ( $method['details']['issuer']->items as $issuer ) {
212
				$id   = Security::filter( $issuer->id );
213
				$name = Security::filter( $issuer->name );
214
215
				$issuers[ $id ] = $name;
216
			}
217
		}
218
219
		return $issuers;
220
	}
221
222
	/**
223
	 * Get payment methods.
224
	 *
225
	 * @return array|bool
226
	 */
227
	public function get_payment_methods() {
228
		$data = array(
229
			'merchantAccount'       => $this->config->get_merchant_account(),
230
			'allowedPaymentMethods' => array(),
231
		);
232
233
		$response = $this->send_request( 'paymentMethods/', 'POST', $data );
0 ignored issues
show
$data of type array<string,array|string> is incompatible with the type object expected by parameter $data of Pronamic\WordPress\Pay\G...\Client::send_request(). ( Ignorable by Annotation )

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

233
		$response = $this->send_request( 'paymentMethods/', 'POST', /** @scrutinizer ignore-type */ $data );
Loading history...
234
235
		if ( false === $response ) {
236
			return false;
237
		}
238
239
		$payment_methods = array();
240
241
		if ( isset( $response->paymentMethods ) ) {
242
			foreach ( $response->paymentMethods as $payment_method ) {
243
				$type = Security::filter( $payment_method->type );
244
				$name = Security::filter( $payment_method->name );
245
246
				$method = array(
247
					'name'    => $name,
248
					'details' => array(),
249
				);
250
251
				if ( isset( $payment_method->details ) ) {
252
					foreach ( $payment_method->details as $detail ) {
253
						$key = $detail->key;
254
255
						$method['details'][ $key ] = $detail;
256
257
						unset( $method['details'][ $key ]->key );
258
					}
259
				}
260
261
				$payment_methods[ $type ] = $method;
262
			}
263
		}
264
265
		return $payment_methods;
266
	}
267
}
268