Completed
Push — feature/post-pay ( 4cda7d...b926bb )
by Remco
08:32
created

Client::get_status()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 40
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 19
dl 0
loc 40
rs 9.3222
c 0
b 0
f 0
cc 5
nc 5
nop 1
1
<?php
2
/**
3
 * Client
4
 *
5
 * @author    Pronamic <[email protected]>
6
 * @copyright 2005-2018 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\TransactionParser;
16
use SimpleXMLElement;
17
use WP_Error;
18
19
/**
20
 * Title: Sisow
21
 * Description:
22
 * Copyright: Copyright (c) 2005 - 2018
23
 * Company: Pronamic
24
 *
25
 * @author  Remco Tolsma
26
 * @version 2.0.0
27
 * @since   1.0.0
28
 */
29
class Client {
30
	/**
31
	 * Sisow REST API endpoint URL.
32
	 *
33
	 * @var string
34
	 */
35
	const API_URL = 'https://www.sisow.nl/Sisow/iDeal/RestHandler.ashx';
36
37
	/**
38
	 * Sisow merchant ID.
39
	 *
40
	 * @var string
41
	 */
42
	private $merchant_id;
43
44
	/**
45
	 * Sisow merchant key.
46
	 *
47
	 * @var string
48
	 */
49
	private $merchant_key;
50
51
	/**
52
	 * Indicator to use test mode or not.
53
	 *
54
	 * @var boolean
55
	 */
56
	private $test_mode;
57
58
	/**
59
	 * Error.
60
	 *
61
	 * @var WP_Error|null
62
	 */
63
	private $error;
64
65
	/**
66
	 * Constructs and initializes a Sisow client object.
67
	 *
68
	 * @param string $merchant_id  Merchant ID.
69
	 * @param string $merchant_key Merchant key.
70
	 */
71
	public function __construct( $merchant_id, $merchant_key ) {
72
		$this->merchant_id  = $merchant_id;
73
		$this->merchant_key = $merchant_key;
74
	}
75
76
	/**
77
	 * Error.
78
	 *
79
	 * @return WP_Error
80
	 */
81
	public function get_error() {
82
		return $this->error;
83
	}
84
85
	/**
86
	 * Set test mode.
87
	 *
88
	 * @param boolean $test_mode True if test mode, false otherwise.
89
	 */
90
	public function set_test_mode( $test_mode ) {
91
		$this->test_mode = $test_mode;
92
	}
93
94
	/**
95
	 * Send request with the specified action and parameters.
96
	 *
97
	 * @param string $method     Method.
98
	 * @param array  $parameters Parameters.
99
	 * @return string|WP_Error
100
	 */
101
	private function send_request( $method, array $parameters = array() ) {
102
		$url = self::API_URL . '/' . $method;
103
104
		return Core_Util::remote_get_body(
105
			$url,
106
			200,
107
			array(
108
				'method' => 'POST',
109
				'body'   => $parameters,
110
			)
111
		);
112
	}
113
114
	/**
115
	 * Parse the specified document and return parsed result.
116
	 *
117
	 * @param SimpleXMLElement $document Document.
118
	 * @return WP_Error|Transaction
119
	 */
120
	private function parse_document( SimpleXMLElement $document ) {
121
		$this->error = null;
122
123
		$name = $document->getName();
124
125
		switch ( $name ) {
126
			case 'errorresponse':
127
				$sisow_error = ErrorParser::parse( $document->error );
128
129
				$this->error = new WP_Error( 'ideal_sisow_error', $sisow_error->message, $sisow_error );
130
131
				return $sisow_error;
132
			case 'transactionrequest':
133
				$transaction = TransactionParser::parse( $document->transaction );
134
135
				return $transaction;
136
			case 'statusresponse':
137
				$transaction = TransactionParser::parse( $document->transaction );
138
139
				return $transaction;
140
			default:
141
				return new WP_Error(
142
					'ideal_sisow_error',
143
					/* translators: %s: XML document element name */
144
					sprintf( __( 'Unknwon Sisow message (%s)', 'pronamic_ideal' ), $name )
145
				);
146
		}
147
	}
148
149
	/**
150
	 * Get directory.
151
	 *
152
	 * @return array<int|string, string>|false
153
	 */
154
	public function get_directory() {
155
		$directory = false;
156
157
		if ( $this->test_mode ) {
158
			$directory = array( '99' => __( 'Sisow Bank (test)', 'pronamic_ideal' ) );
159
		} else {
160
			// Request.
161
			$result = $this->send_request( RequestMethods::DIRECTORY_REQUEST );
162
163
			if ( $result instanceof WP_Error ) {
164
				$this->error = $result;
165
166
				return $directory;
167
			}
168
169
			// XML.
170
			$xml = Core_Util::simplexml_load_string( $result );
171
172
			if ( is_wp_error( $xml ) ) {
173
				$this->error = $xml;
174
175
				return $directory;
176
			}
177
178
			// Parse.
179
			if ( $xml instanceof SimpleXMLElement ) {
180
				$directory = array();
181
182
				foreach ( $xml->directory->issuer as $issuer ) {
183
					$id   = (string) $issuer->issuerid;
184
					$name = (string) $issuer->issuername;
185
186
					$directory[ $id ] = $name;
187
				}
188
			}
189
		}
190
191
		return $directory;
192
	}
193
194
	/**
195
	 * Create an transaction with the specified parameters.
196
	 *
197
	 * @param TransactionRequest $request Transaction request.
198
	 * @return Transaction|false
199
	 */
200
	public function create_transaction( TransactionRequest $request ) {
201
		$result = false;
202
203
		// Request.
204
		$request->sign( $this->merchant_key );
205
206
		$response = $this->send_request( RequestMethods::TRANSACTION_REQUEST, $request->get_parameters() );
207
208
		if ( $response instanceof WP_Error ) {
209
			$this->error = $response;
210
211
			return $result;
212
		}
213
214
		// XML.
215
		$xml = Core_Util::simplexml_load_string( $response );
216
217
		if ( $xml instanceof WP_Error) ) {
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected ')' on line 217 at column 33
Loading history...
218
			$this->error = $xml;
219
220
			return $result;
221
		}
222
223
		// Parse.
224
		if ( $xml instanceof SimpleXMLElement ) {
225
			$message = $this->parse_document( $xml );
226
227
			if ( $message instanceof Transaction ) {
228
				$result = $message;
229
			}
230
		}
231
232
		return $result;
233
	}
234
235
	/**
236
	 * Create an SHA1 for an status request.
237
	 *
238
	 * @param string $transaction_id Transaction ID.
239
	 * @param string $shop_id        Shop ID.
240
	 * @param string $merchant_id    Merchant ID.
241
	 * @param string $merchant_key   Merchant key.
242
	 */
243
	public static function create_status_sha1( $transaction_id, $shop_id, $merchant_id, $merchant_key ) {
244
		return sha1(
245
			$transaction_id .
246
			$shop_id .
247
			$merchant_id .
248
			$merchant_key
249
		);
250
	}
251
252
	/**
253
	 * Get the status of the specified transaction ID.
254
	 *
255
	 * @param string $transaction_id Transaction ID.
256
	 * @return Transaction|false
257
	 */
258
	public function get_status( $transaction_id ) {
259
		$status = false;
260
261
		if ( '' === $transaction_id ) {
262
			return $status;
263
		}
264
265
		// Parameters.
266
		$parameters = array(
267
			'merchantid' => $this->merchant_id,
268
			'trxid'      => $transaction_id,
269
			'sha1'       => self::create_status_sha1( $transaction_id, '', $this->merchant_id, $this->merchant_key ),
270
		);
271
272
		// Request.
273
		$result = $this->send_request( RequestMethods::STATUS_REQUEST, $parameters );
274
275
		if ( $result instanceof WP_Error ) {
276
			$this->error = $result;
277
278
			return $status;
279
		}
280
281
		// XML.
282
		$xml = Core_Util::simplexml_load_string( $result );
283
284
		if ( $xml instanceof WP_Error ) {
285
			$this->error = $xml;
286
287
			return $status;
288
		}
289
290
		// Parse.
291
		if ( $xml instanceof SimpleXMLElement ) {
292
			$status = $this->parse_document( $xml );
293
294
			return $status;
295
		}
296
297
		return $status;
298
	}
299
}
300