1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* 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\ING\KassaCompleet |
9
|
|
|
*/ |
10
|
|
|
|
11
|
|
|
namespace Pronamic\WordPress\Pay\Gateways\ING\KassaCompleet; |
12
|
|
|
|
13
|
|
|
use Pronamic\WordPress\Pay\Core\XML\Security; |
14
|
|
|
use WP_Error; |
15
|
|
|
|
16
|
|
|
/** |
17
|
|
|
* Title: ING Kassa Compleet client |
18
|
|
|
* Description: |
19
|
|
|
* Copyright: 2005-2019 Pronamic |
20
|
|
|
* Company: Pronamic |
21
|
|
|
* |
22
|
|
|
* @author Reüel van der Steege |
23
|
|
|
* @version 2.0.0 |
24
|
|
|
* @since 1.0.0 |
25
|
|
|
*/ |
26
|
|
|
class Client { |
27
|
|
|
/** |
28
|
|
|
* ING Kasse Compleet API endpoint URL |
29
|
|
|
* |
30
|
|
|
* @var string url |
31
|
|
|
*/ |
32
|
|
|
const API_URL = 'https://api.kassacompleet.nl/v1/'; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* API Key |
36
|
|
|
* |
37
|
|
|
* @var string |
38
|
|
|
*/ |
39
|
|
|
private $api_key; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* Error |
43
|
|
|
* |
44
|
|
|
* @var WP_Error |
45
|
|
|
*/ |
46
|
|
|
private $error; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* Constructs and initalize an ING Kassa Compleet client object |
50
|
|
|
* |
51
|
|
|
* @param string $api_key API key. |
52
|
|
|
*/ |
53
|
|
|
public function __construct( $api_key ) { |
54
|
|
|
$this->api_key = $api_key; |
55
|
|
|
} |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* Error |
59
|
|
|
* |
60
|
|
|
* @return WP_Error |
61
|
|
|
*/ |
62
|
|
|
public function get_error() { |
63
|
|
|
return $this->error; |
64
|
|
|
} |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* Send request with the specified action and parameters |
68
|
|
|
* |
69
|
|
|
* @param string $endpoint API endpoint. |
70
|
|
|
* @param string $method HTTP method to use for request. |
71
|
|
|
* @param array $data Data to send. |
72
|
|
|
* |
73
|
|
|
* @return array|WP_Error |
74
|
|
|
*/ |
75
|
|
|
private function send_request( $endpoint, $method = 'POST', array $data = array() ) { |
76
|
|
|
$url = self::API_URL . $endpoint; |
77
|
|
|
|
78
|
|
|
$headers = array( |
79
|
|
|
'Authorization' => 'Basic ' . base64_encode( $this->api_key . ':' ), |
80
|
|
|
); |
81
|
|
|
|
82
|
|
|
if ( is_array( $data ) && ! empty( $data ) ) { |
83
|
|
|
$data = wp_json_encode( $data ); |
84
|
|
|
|
85
|
|
|
$headers['Content-Type'] = 'application/json'; |
86
|
|
|
} |
87
|
|
|
|
88
|
|
|
$return = wp_remote_request( |
89
|
|
|
$url, |
90
|
|
|
array( |
91
|
|
|
'method' => $method, |
92
|
|
|
'headers' => $headers, |
93
|
|
|
'body' => $data, |
94
|
|
|
) |
95
|
|
|
); |
96
|
|
|
|
97
|
|
|
return $return; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* Create order. |
102
|
|
|
* |
103
|
|
|
* @param OrderRequest $request Order request. |
104
|
|
|
* |
105
|
|
|
* @return array|mixed|object|null |
106
|
|
|
*/ |
107
|
|
|
public function create_order( OrderRequest $request ) { |
108
|
|
|
$result = null; |
109
|
|
|
|
110
|
|
|
$data = $request->get_array(); |
111
|
|
|
|
112
|
|
|
$response = $this->send_request( 'orders/', 'POST', $data ); |
113
|
|
|
|
114
|
|
|
if ( is_wp_error( $response ) ) { |
115
|
|
|
$this->error = $response; |
|
|
|
|
116
|
|
|
|
117
|
|
|
return $result; |
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
$response_code = wp_remote_retrieve_response_code( $response ); |
|
|
|
|
121
|
|
|
|
122
|
|
|
$body = wp_remote_retrieve_body( $response ); |
|
|
|
|
123
|
|
|
|
124
|
|
|
// NULL is returned if the json cannot be decoded or if the encoded data is deeper than the recursion limit. |
125
|
|
|
$ing_result = json_decode( $body ); |
126
|
|
|
|
127
|
|
|
if ( 201 === $response_code ) { |
128
|
|
|
if ( $ing_result && 'error' === $ing_result->status ) { |
129
|
|
|
$error_msg = $ing_result->transactions[0]->reason; |
130
|
|
|
$error = $ing_result->transactions[0]; |
131
|
|
|
} else { |
132
|
|
|
$result = $ing_result; |
133
|
|
|
} |
134
|
|
|
} else { |
135
|
|
|
$error_msg = ''; |
136
|
|
|
$error = ''; |
137
|
|
|
|
138
|
|
|
if ( $ing_result ) { |
139
|
|
|
$error_msg = $ing_result->error->value; |
140
|
|
|
$error = $ing_result->error; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
if ( 401 === $response_code ) { |
144
|
|
|
// The default error message for an unauthorized API call does not mention the API key in any way. |
145
|
|
|
$error_msg .= ' Please check the API key.'; |
146
|
|
|
} |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
if ( isset( $error_msg, $error ) ) { |
150
|
|
|
$this->error = new WP_Error( 'ing_kassa_compleet_error', $error_msg, $error ); |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
return $result; |
154
|
|
|
} |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* Get order. |
158
|
|
|
* |
159
|
|
|
* @param string $order_id Order ID. |
160
|
|
|
* |
161
|
|
|
* @return array|mixed|object|null |
162
|
|
|
*/ |
163
|
|
|
public function get_order( $order_id ) { |
164
|
|
|
$result = null; |
165
|
|
|
|
166
|
|
|
$response = $this->send_request( 'orders/' . $order_id . '/', 'GET' ); |
167
|
|
|
|
168
|
|
|
if ( is_wp_error( $response ) ) { |
169
|
|
|
$this->error = $response; |
|
|
|
|
170
|
|
|
|
171
|
|
|
return $result; |
172
|
|
|
} |
173
|
|
|
|
174
|
|
|
$response_code = wp_remote_retrieve_response_code( $response ); |
|
|
|
|
175
|
|
|
|
176
|
|
|
if ( 200 === $response_code ) { |
177
|
|
|
$body = wp_remote_retrieve_body( $response ); |
|
|
|
|
178
|
|
|
|
179
|
|
|
// NULL is returned if the json cannot be decoded or if the encoded data is deeper than the recursion limit. |
180
|
|
|
$result = json_decode( $body ); |
181
|
|
|
} |
182
|
|
|
|
183
|
|
|
return $result; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* Get issuers. |
188
|
|
|
* |
189
|
|
|
* @return array|bool |
190
|
|
|
*/ |
191
|
|
|
public function get_issuers() { |
192
|
|
|
$issuers = false; |
193
|
|
|
|
194
|
|
|
$response = $this->send_request( 'ideal/issuers/', 'GET' ); |
195
|
|
|
|
196
|
|
|
if ( is_wp_error( $response ) ) { |
197
|
|
|
$this->error = $response; |
|
|
|
|
198
|
|
|
|
199
|
|
|
return $issuers; |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
$response_code = wp_remote_retrieve_response_code( $response ); |
|
|
|
|
203
|
|
|
|
204
|
|
|
if ( 200 === $response_code ) { |
205
|
|
|
$body = wp_remote_retrieve_body( $response ); |
|
|
|
|
206
|
|
|
|
207
|
|
|
// NULL is returned if the json cannot be decoded or if the encoded data is deeper than the recursion limit. |
208
|
|
|
$result = json_decode( $body ); |
209
|
|
|
|
210
|
|
|
if ( null !== $result ) { |
211
|
|
|
$issuers = array(); |
212
|
|
|
|
213
|
|
|
foreach ( $result as $issuer ) { |
214
|
|
|
$id = Security::filter( $issuer->id ); |
215
|
|
|
$name = Security::filter( $issuer->name ); |
216
|
|
|
|
217
|
|
|
$issuers[ $id ] = $name; |
218
|
|
|
} |
219
|
|
|
} |
220
|
|
|
} else { |
221
|
|
|
$body = wp_remote_retrieve_body( $response ); |
222
|
|
|
|
223
|
|
|
$ing_result = json_decode( $body ); |
224
|
|
|
|
225
|
|
|
$error_msg = $ing_result->error->value; |
226
|
|
|
|
227
|
|
|
if ( 401 === $response_code ) { |
228
|
|
|
// An unauthorized API call has nothing to do with the browser of the user in our case, remove to prevent confusion. |
229
|
|
|
$error_msg = str_replace( "You either supplied the wrong credentials (e.g. a bad password), or your browser doesn't understand how to supply the credentials required.", '', $error_msg ); |
230
|
|
|
|
231
|
|
|
// The default error message for an unauthorized API call does not mention the API key in any way. |
232
|
|
|
$error_msg .= ' Please check the API key.'; |
233
|
|
|
} |
234
|
|
|
|
235
|
|
|
$this->error = new WP_Error( 'ing_kassa_compleet_error', $error_msg, $ing_result->error ); |
236
|
|
|
} |
237
|
|
|
|
238
|
|
|
return $issuers; |
239
|
|
|
} |
240
|
|
|
} |
241
|
|
|
|
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountId
that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theid
property of an instance of theAccount
class. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.