Passed
Push — develop ( 8b98d9...426279 )
by Reüel
06:39
created

Client   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 316
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 35
eloc 103
dl 0
loc 316
c 0
b 0
f 0
ccs 0
cts 140
cp 0
rs 9.6

11 Methods

Rating   Name   Duplication   Size   Complexity  
B parse_document() 0 37 7
A get_merchant() 0 16 3
A get_error() 0 2 1
A get_directory() 0 25 4
A create_transaction() 0 16 3
A send_request() 0 36 6
A cancel_reservation() 0 18 3
A set_test_mode() 0 2 1
A create_invoice() 0 16 3
A get_status() 0 16 3
A __construct() 0 3 1
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\Payments
9
 */
10
11
namespace Pronamic\WordPress\Pay\Gateways\Sisow;
12
13
use Pronamic\WordPress\Pay\Core\Util as Core_Util;
14
use Pronamic\WordPress\Pay\Gateways\Sisow\XML\ErrorParser;
15
use Pronamic\WordPress\Pay\Gateways\Sisow\XML\InvoiceParser;
16
use Pronamic\WordPress\Pay\Gateways\Sisow\XML\MerchantParser;
17
use Pronamic\WordPress\Pay\Gateways\Sisow\XML\ReservationParser;
18
use Pronamic\WordPress\Pay\Gateways\Sisow\XML\TransactionParser;
19
use SimpleXMLElement;
20
use WP_Error;
21
22
/**
23
 * Title: Sisow
24
 * Description:
25
 * Copyright: 2005-2019 Pronamic
26
 * Company: Pronamic
27
 *
28
 * @author  Remco Tolsma
29
 * @version 2.0.0
30
 * @since   1.0.0
31
 */
32
class Client {
33
	/**
34
	 * Sisow REST API endpoint URL.
35
	 *
36
	 * @var string
37
	 */
38
	const API_URL = 'https://www.sisow.nl/Sisow/iDeal/RestHandler.ashx';
39
40
	/**
41
	 * Sisow merchant ID.
42
	 *
43
	 * @var string
44
	 */
45
	private $merchant_id;
46
47
	/**
48
	 * Sisow merchant key.
49
	 *
50
	 * @var string
51
	 */
52
	private $merchant_key;
53
54
	/**
55
	 * Indicator to use test mode or not.
56
	 *
57
	 * @var boolean
58
	 */
59
	private $test_mode;
60
61
	/**
62
	 * Error.
63
	 *
64
	 * @var WP_Error|null
65
	 */
66
	private $error;
67
68
	/**
69
	 * Constructs and initializes a Sisow client object.
70
	 *
71
	 * @param string $merchant_id  Merchant ID.
72
	 * @param string $merchant_key Merchant key.
73
	 */
74
	public function __construct( $merchant_id, $merchant_key ) {
75
		$this->merchant_id  = $merchant_id;
76
		$this->merchant_key = $merchant_key;
77
	}
78
79
	/**
80
	 * Error.
81
	 *
82
	 * @return WP_Error|null
83
	 */
84
	public function get_error() {
85
		return $this->error;
86
	}
87
88
	/**
89
	 * Set test mode.
90
	 *
91
	 * @param boolean $test_mode True if test mode, false otherwise.
92
	 */
93
	public function set_test_mode( $test_mode ) {
94
		$this->test_mode = $test_mode;
95
	}
96
97
	/**
98
	 * Send request with the specified action and parameters.
99
	 *
100
	 * @param string       $method  Method.
101
	 * @param Request|null $request Request.
102
	 *
103
	 * @return false|SimpleXMLElement
104
	 */
105
	private function send_request( $method, Request $request = null ) {
106
		$url = self::API_URL . '/' . $method;
107
108
		if ( null !== $request ) {
109
			$request->sign( $this->merchant_key );
110
		}
111
112
		$result = Core_Util::remote_get_body(
113
			$url,
114
			200,
115
			array(
116
				'method' => 'POST',
117
				'body'   => ( null === $request ) ? null : $request->get_parameters(),
118
			)
119
		);
120
121
		if ( $result instanceof WP_Error ) {
122
			$this->error = $result;
123
124
			return false;
125
		}
126
127
		if ( ! is_string( $result ) ) {
128
			return false;
129
		}
130
131
		// XML.
132
		$xml = Core_Util::simplexml_load_string( $result );
133
134
		if ( $xml instanceof WP_Error ) {
0 ignored issues
show
introduced by
$xml is never a sub-type of WP_Error.
Loading history...
135
			$this->error = $xml;
136
137
			return false;
138
		}
139
140
		return $xml;
141
	}
142
143
	/**
144
	 * Parse the specified document and return parsed result.
145
	 *
146
	 * @param SimpleXMLElement $document Document.
147
	 *
148
	 * @return WP_Error|Invoice|Merchant|Reservation|Transaction|Error
149
	 */
150
	private function parse_document( SimpleXMLElement $document ) {
151
		$this->error = null;
152
153
		$name = $document->getName();
154
155
		switch ( $name ) {
156
			case 'cancelreservationresponse':
157
				$reservation = ReservationParser::parse( $document->reservation );
158
159
				return $reservation;
160
			case 'checkmerchantresponse':
161
				$merchant = MerchantParser::parse( $document->merchant );
162
163
				return $merchant;
164
			case 'errorresponse':
165
				$sisow_error = ErrorParser::parse( $document->error );
166
167
				$this->error = new WP_Error( 'ideal_sisow_error', $sisow_error->message, $sisow_error );
168
169
				return $sisow_error;
170
			case 'invoiceresponse':
171
				$invoice = InvoiceParser::parse( $document->invoice );
172
173
				return $invoice;
174
			case 'transactionrequest':
175
				$transaction = TransactionParser::parse( $document->transaction );
176
177
				return $transaction;
178
			case 'statusresponse':
179
				$transaction = TransactionParser::parse( $document->transaction );
180
181
				return $transaction;
182
			default:
183
				return new WP_Error(
184
					'ideal_sisow_error',
185
					/* translators: %s: XML document element name */
186
					sprintf( __( 'Unknwon Sisow message (%s)', 'pronamic_ideal' ), $name )
187
				);
188
		}
189
	}
190
191
	/**
192
	 * Get directory.
193
	 *
194
	 * @return array|false
195
	 */
196
	public function get_directory() {
197
		if ( $this->test_mode ) {
198
			return array(
199
				'99' => __( 'Sisow Bank (test)', 'pronamic_ideal' ),
200
			);
201
		}
202
203
		// Request.
204
		$result = $this->send_request( RequestMethods::DIRECTORY_REQUEST );
205
206
		if ( false === $result ) {
207
			return false;
208
		}
209
210
		// Parse.
211
		$directory = array();
212
213
		foreach ( $result->directory->issuer as $issuer ) {
214
			$id   = (string) $issuer->issuerid;
215
			$name = (string) $issuer->issuername;
216
217
			$directory[ $id ] = $name;
218
		}
219
220
		return $directory;
221
	}
222
223
	/**
224
	 * Get merchant.
225
	 *
226
	 * @param MerchantRequest $merchant_request Merchant request.
227
	 *
228
	 * @return Merchant|bool
229
	 */
230
	public function get_merchant( MerchantRequest $merchant_request ) {
231
		// Request.
232
		$response = $this->send_request( RequestMethods::CHECK_MERCHANT_REQUEST, $merchant_request );
233
234
		if ( false === $response ) {
235
			return false;
236
		}
237
238
		// Parse.
239
		$message = $this->parse_document( $response );
240
241
		if ( $message instanceof Merchant ) {
242
			return $message;
243
		}
244
245
		return false;
246
	}
247
248
	/**
249
	 * Create an transaction with the specified parameters.
250
	 *
251
	 * @param TransactionRequest $request Transaction request.
252
	 *
253
	 * @return Transaction|false
254
	 */
255
	public function create_transaction( TransactionRequest $request ) {
256
		// Request.
257
		$response = $this->send_request( RequestMethods::TRANSACTION_REQUEST, $request );
258
259
		if ( false === $response ) {
260
			return false;
261
		}
262
263
		// Parse.
264
		$message = $this->parse_document( $response );
265
266
		if ( $message instanceof Transaction ) {
267
			return $message;
268
		}
269
270
		return false;
271
	}
272
273
	/**
274
	 * Create invoice for reservation payment.
275
	 *
276
	 * @param InvoiceRequest $request Invoice request.
277
	 *
278
	 * @return Invoice|false
279
	 */
280
	public function create_invoice( InvoiceRequest $request ) {
281
		// Request.
282
		$response = $this->send_request( RequestMethods::INVOICE_REQUEST, $request );
283
284
		if ( false === $response ) {
285
			return false;
286
		}
287
288
		// Parse.
289
		$message = $this->parse_document( $response );
290
291
		if ( $message instanceof Invoice ) {
292
			return $message;
293
		}
294
295
		return false;
296
	}
297
298
	/**
299
	 * Cancel reservation payment.
300
	 *
301
	 * @param CancelReservationRequest $request Reservation cancellation request.
302
	 *
303
	 * @return Reservation|false
304
	 */
305
	public function cancel_reservation( CancelReservationRequest $request ) {
306
		$request->set_parameter( 'shopid', null );
307
308
		// Request.
309
		$response = $this->send_request( RequestMethods::CANCEL_RESERVATION_REQUEST, $request );
310
311
		if ( false === $response ) {
312
			return false;
313
		}
314
315
		// Parse.
316
		$message = $this->parse_document( $response );
317
318
		if ( $message instanceof Reservation ) {
319
			return $message;
320
		}
321
322
		return false;
323
	}
324
325
	/**
326
	 * Get the status of the specified transaction ID.
327
	 *
328
	 * @param StatusRequest $request Status request object.
329
	 *
330
	 * @return Transaction|false
331
	 */
332
	public function get_status( StatusRequest $request ) {
333
		// Request.
334
		$response = $this->send_request( RequestMethods::STATUS_REQUEST, $request );
335
336
		if ( false === $response ) {
337
			return false;
338
		}
339
340
		// Parse.
341
		$message = $this->parse_document( $response );
342
343
		if ( $message instanceof Transaction ) {
344
			return $message;
345
		}
346
347
		return false;
348
	}
349
}
350