Passed
Push — develop ( 62eadf...30c393 )
by Reüel
06:12
created

Gateway::maybe_update_access_token()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 19
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 12
nc 3
nop 0
dl 0
loc 19
ccs 0
cts 15
cp 0
crap 12
rs 9.8666
c 0
b 0
f 0
1
<?php
2
/**
3
 * Gateway
4
 *
5
 * @author    Pronamic <[email protected]>
6
 * @copyright 2005-2018 Pronamic
7
 * @license   GPL-3.0-or-later
8
 * @package   Pronamic\WordPress\Pay\Gateways\OmniKassa2
9
 */
10
11
namespace Pronamic\WordPress\Pay\Gateways\OmniKassa2;
12
13
use Pronamic\WordPress\Pay\Core\Util as Core_Util;
14
use Pronamic\WordPress\Pay\Core\Gateway as Core_Gateway;
15
use Pronamic\WordPress\Pay\Core\PaymentMethods;
16
use Pronamic\WordPress\Pay\Payments\Payment;
17
18
/**
19
 * Gateway
20
 *
21
 * @author  Remco Tolsma
22
 * @version 2.0.2
23
 * @since   1.0.0
24
 */
25
class Gateway extends Core_Gateway {
26
	/**
27
	 * Client.
28
	 *
29
	 * @var Client
30
	 */
31
	private $client;
32
33
	/**
34
	 * Constructs and initializes an OmniKassa 2.0 gateway.
35
	 *
36
	 * @param Config $config Config.
37
	 */
38
	public function __construct( Config $config ) {
39
		parent::__construct( $config );
40
41
		$this->set_method( self::METHOD_HTTP_REDIRECT );
42
43
		// Client.
44
		$this->client = new Client();
45
46
		$url = Client::URL_PRODUCTION;
47
48
		if ( self::MODE_TEST === $config->mode ) {
49
			$url = Client::URL_SANDBOX;
50
		}
51
52
		$this->client->set_url( $url );
53
		$this->client->set_refresh_token( $config->refresh_token );
54
		$this->client->set_signing_key( $config->signing_key );
55
	}
56
57
	/**
58
	 * Get supported payment methods.
59
	 *
60
	 * @see \Pronamic_WP_Pay_Gateway::get_supported_payment_methods()
61
	 * @return array
62
	 */
63
	public function get_supported_payment_methods() {
64
		return array(
65
			PaymentMethods::BANCONTACT,
66
			PaymentMethods::CREDIT_CARD,
67
			PaymentMethods::IDEAL,
68
			PaymentMethods::PAYPAL,
69
		);
70
	}
71
72
	/**
73
	 * Start.
74
	 *
75
	 * @see Core_Gateway::start()
76
	 *
77
	 * @param Payment $payment Payment.
78
	 */
79
	public function start( Payment $payment ) {
80
		// Merchant order ID.
81
		$merchant_order_id = $payment->format_string( $this->config->order_id );
82
83
		$payment->set_meta( 'omnikassa_2_merchant_order_id', $merchant_order_id );
84
85
		// New order.
86
		$order = new Order(
87
			$merchant_order_id,
88
			new Money(
89
				$payment->get_currency(),
90
				Core_Util::amount_to_cents( $payment->get_amount()->get_amount() )
91
			),
92
			$payment->get_return_url()
93
		);
94
95
		$order->set_description( $payment->get_description() );
96
		$order->set_language( $payment->get_language() );
97
98
		// Payment brand.
99
		$payment_brand = PaymentBrands::transform( $payment->get_method() );
100
101
		$order->set_payment_brand( $payment_brand );
102
103
		if ( null !== $payment_brand ) {
104
			// Payment brand force should only be set if payment brand is not empty.
105
			$order->set_payment_brand_force( PaymentBrandForce::FORCE_ONCE );
106
		}
107
108
		// Maybe update access token.
109
		$this->maybe_update_access_token();
110
111
		// Handle errors.
112
		if ( $this->get_client_error() ) {
113
			return;
114
		}
115
116
		// Announce order.
117
		$result = $this->client->order_announce( $this->config, $order );
118
119
		// Handle errors.
120
		if ( $this->get_client_error() ) {
121
			return;
122
		}
123
124
		if ( $result ) {
125
			$payment->set_action_url( $result->redirectUrl );
126
		}
127
	}
128
129
	/**
130
	 * Update status of the specified payment.
131
	 *
132
	 * @param Payment $payment Payment.
133
	 */
134
	public function update_status( Payment $payment ) {
135
		if ( ! ReturnParameters::contains( $_GET ) ) { // WPCS: CSRF ok.
136
			return;
137
		}
138
139
		$parameters = ReturnParameters::from_array( $_GET ); // WPCS: CSRF ok.
140
141
		// Note.
142
		$note_values = array(
143
			'order_id'  => $parameters->get_order_id(),
144
			'status'    => $parameters->get_status(),
145
			'signature' => $parameters->get_signature(),
146
			'valid'     => $parameters->is_valid( $this->config->signing_key ) ? 'true' : 'false',
147
		);
148
149
		$note = '';
150
151
		$note .= '<p>';
152
		$note .= __( 'OmniKassa 2.0 return URL requested:', 'pronamic_ideal' );
153
		$note .= '</p>';
154
155
		$note .= '<dl>';
156
157
		foreach ( $note_values as $key => $value ) {
158
			$note .= sprintf( '<dt>%s</dt>', esc_html( $key ) );
159
			$note .= sprintf( '<dd>%s</dd>', esc_html( $value ) );
160
		}
161
162
		$note .= '</dl>';
163
164
		$payment->add_note( $note );
165
166
		// Validate.
167
		if ( ! $parameters->is_valid( $this->config->signing_key ) ) {
168
			return;
169
		}
170
171
		// Status.
172
		$payment->set_status( Statuses::transform( $parameters->get_status() ) );
173
	}
174
175
	/**
176
	 * Handle notification.
177
	 *
178
	 * @param Notification $notification Notification.
179
	 *
180
	 * @return void
181
	 */
182
	public function handle_notification( Notification $notification ) {
183
		if ( ! $notification->is_valid( $this->config->signing_key ) ) {
184
			return;
185
		}
186
187
		switch ( $notification->get_event_name() ) {
188
			case 'merchant.order.status.changed':
189
				$this->handle_merchant_order_status_changed( $notification );
190
		}
191
	}
192
193
	/**
194
	 * Handle `merchant.order.status.changed` event.
195
	 *
196
	 * @param Notification $notification Notification.
197
	 *
198
	 * @return void
199
	 */
200
	private function handle_merchant_order_status_changed( Notification $notification ) {
201
		do {
202
			$order_results = $this->client->get_order_results( $notification->get_authentication() );
203
204
			if ( ! $order_results || $order_results->is_valid( $this->config->signing_key ) ) {
205
				return;
206
			}
207
208
			foreach ( $order_results as $order_result ) {
209
				$payment = get_pronamic_payment_by_meta( '_pronamic_payment_omnikassa_2_merchant_order_id', $order_result->get_merchant_order_id() );
210
211
				if ( empty( $payment ) ) {
212
					continue;
213
				}
214
215
				$payment->set_transaction_id( $order_result->get_omnikassa_order_id() );
216
				$payment->set_status( Statuses::transform( $order_result->get_order_status() ) );
217
218
				// Note.
219
				$note = '';
220
221
				$note .= '<p>';
222
				$note .= __( 'OmniKassa 2.0 webhook URL requested:', 'pronamic_ideal' );
223
				$note .= '</p>';
224
				$note .= '<pre>';
225
				$note .= wp_json_encode( $order_result->get_json(), JSON_PRETTY_PRINT );
226
				$note .= '</pre>';
227
228
				$payment->add_note( $note );
229
230
				$payment->save();
231
			}
232
		} while ( $order_results->more_available() );
233
	}
234
235
	/**
236
	 * Maybe update access token.
237
	 *
238
	 * @return void
239
	 */
240
	private function maybe_update_access_token() {
241
		if ( $this->config->is_access_token_valid() ) {
242
			return;
243
		}
244
245
		$data = $this->client->get_access_token_data();
246
247
		if ( ! is_object( $data ) ) {
248
			return;
249
		}
250
251
		$this->config->access_token             = $data->token;
252
		$this->config->access_token_valid_until = $data->validUntil;
253
254
		update_post_meta( $this->config->post_id, '_pronamic_gateway_omnikassa_2_access_token', $data->token );
255
		update_post_meta(
256
			$this->config->post_id,
257
			'_pronamic_gateway_omnikassa_2_access_token_valid_until',
258
			$data->validUntil
259
		);
260
	}
261
262
	/**
263
	 * Get client error.
264
	 *
265
	 * @return \WP_Error|bool
266
	 */
267
	private function get_client_error() {
268
		$error = $this->client->get_error();
269
270
		if ( is_wp_error( $error ) ) {
271
			$this->error = $error;
272
273
			return $error;
274
		}
275
276
		return false;
277
	}
278
}
279