Test Failed
Push — feature/post-pay ( c18430...6a63dc )
by Reüel
07:10
created

src/Gateway.php (1 issue)

Labels
Severity
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::AFTERPAY,
66
			PaymentMethods::BANCONTACT,
67
			PaymentMethods::CREDIT_CARD,
68
			PaymentMethods::IDEAL,
69
			PaymentMethods::MAESTRO,
70
			PaymentMethods::PAYPAL,
71
		);
72
	}
73
74
	/**
75
	 * Start.
76
	 *
77
	 * @see Core_Gateway::start()
78
	 *
79
	 * @param Payment $payment Payment.
80
	 */
81
	public function start( Payment $payment ) {
82
		// Merchant order ID.
83
		$merchant_order_id = $payment->format_string( $this->config->order_id );
84
85
		$payment->set_meta( 'omnikassa_2_merchant_order_id', $merchant_order_id );
86
87
		// New order.
88
		$order = new Order(
89
			$merchant_order_id,
90
			MoneyTransformer::transform( $payment->get_total_amount() ),
0 ignored issues
show
The method get_total_amount() does not exist on Pronamic\WordPress\Pay\Payments\Payment. ( Ignorable by Annotation )

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

90
			MoneyTransformer::transform( $payment->/** @scrutinizer ignore-call */ get_total_amount() ),

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
91
			$payment->get_return_url()
92
		);
93
94
		// Shipping address.
95
		$order->set_shipping_detail( AddressTransformer::transform( $payment->get_shipping_address() ) );
96
97
		// Billing address.
98
		$order->set_billing_detail( AddressTransformer::transform( $payment->get_billing_address() ) );
99
100
		// Customer information.
101
		$customer = $payment->get_customer();
102
103
		if ( null !== $customer ) {
104
			$order->set_language( $customer->get_language() );
105
106
			$customer_information = new CustomerInformation();
107
108
			$customer_information->set_email_address( $customer->get_email() );
109
			$customer_information->set_date_of_birth( $customer->get_birth_date() );
110
			$customer_information->set_gender( $customer->get_gender() );
111
			$customer_information->set_telephone_number( $customer->get_phone() );
112
113
			$order->set_customer_information( $customer_information );
114
		}
115
116
		// Payment brand.
117
		$payment_brand = PaymentBrands::transform( $payment->get_method() );
118
119
		$order->set_payment_brand( $payment_brand );
120
121
		if ( null !== $payment_brand ) {
122
			// Payment brand force should only be set if payment brand is not empty.
123
			$order->set_payment_brand_force( PaymentBrandForce::FORCE_ONCE );
124
		}
125
126
		// Description.
127
		$order->set_description( substr( $payment->get_description(), 0, 35 ) );
128
129
		// Lines.
130
		if ( null !== $payment->get_lines() ) {
131
			$order_items = $order->new_items();
132
133
			foreach ( $payment->get_lines() as $line ) {
134
				$item = $order_items->new_item(
135
					$line->get_name(),
136
					$line->get_quantity(),
137
					MoneyTransformer::transform( $line->get_total_amount() ),
138
					ProductCategories::transform( $line->get_type() )
139
				);
140
141
				$item->set_id( $line->get_id() );
142
				$item->set_description( $line->get_description() );
143
144
				if ( null !== $line->get_tax_amount() ) {
145
					$item->set_tax( MoneyTransformer::transform( $line->get_tax_amount() ) );
146
				}
147
			}
148
		}
149
150
		// Maybe update access token.
151
		$this->maybe_update_access_token();
152
153
		// Handle errors.
154
		if ( $this->get_client_error() ) {
155
			return;
156
		}
157
158
		// Announce order.
159
		$response = $this->client->order_announce( $this->config, $order );
160
161
		// Handle errors.
162
		if ( $this->get_client_error() ) {
163
			return;
164
		}
165
166
		if ( false === $response ) {
167
			return;
168
		}
169
170
		if ( ! $response->is_valid( $this->config->signing_key ) ) {
171
			return;
172
		}
173
174
		$payment->set_action_url( $response->get_redirect_url() );
175
	}
176
177
	/**
178
	 * Update status of the specified payment.
179
	 *
180
	 * @param Payment $payment Payment.
181
	 */
182
	public function update_status( Payment $payment ) {
183
		if ( ! ReturnParameters::contains( $_GET ) ) { // WPCS: CSRF ok.
184
			return;
185
		}
186
187
		$parameters = ReturnParameters::from_array( $_GET ); // WPCS: CSRF ok.
188
189
		// Note.
190
		$note_values = array(
191
			'order_id'  => $parameters->get_order_id(),
192
			'status'    => $parameters->get_status(),
193
			'signature' => $parameters->get_signature(),
194
			'valid'     => $parameters->is_valid( $this->config->signing_key ) ? 'true' : 'false',
195
		);
196
197
		$note = '';
198
199
		$note .= '<p>';
200
		$note .= __( 'OmniKassa 2.0 return URL requested:', 'pronamic_ideal' );
201
		$note .= '</p>';
202
203
		$note .= '<dl>';
204
205
		foreach ( $note_values as $key => $value ) {
206
			$note .= sprintf( '<dt>%s</dt>', esc_html( $key ) );
207
			$note .= sprintf( '<dd>%s</dd>', esc_html( $value ) );
208
		}
209
210
		$note .= '</dl>';
211
212
		$payment->add_note( $note );
213
214
		// Validate.
215
		if ( ! $parameters->is_valid( $this->config->signing_key ) ) {
216
			return;
217
		}
218
219
		// Status.
220
		$pronamic_status = Statuses::transform( $parameters->get_status() );
221
222
		if ( null !== $pronamic_status ) {
223
			$payment->set_status( $pronamic_status );
224
		}
225
	}
226
227
	/**
228
	 * Handle notification.
229
	 *
230
	 * @param Notification $notification Notification.
231
	 *
232
	 * @return void
233
	 */
234
	public function handle_notification( Notification $notification ) {
235
		if ( ! $notification->is_valid( $this->config->signing_key ) ) {
236
			return;
237
		}
238
239
		switch ( $notification->get_event_name() ) {
240
			case 'merchant.order.status.changed':
241
				$this->handle_merchant_order_status_changed( $notification );
242
		}
243
	}
244
245
	/**
246
	 * Handle `merchant.order.status.changed` event.
247
	 *
248
	 * @param Notification $notification Notification.
249
	 *
250
	 * @return void
251
	 */
252
	private function handle_merchant_order_status_changed( Notification $notification ) {
253
		do {
254
			$order_results = $this->client->get_order_results( $notification->get_authentication() );
255
256
			if ( ! $order_results || $order_results->is_valid( $this->config->signing_key ) ) {
257
				return;
258
			}
259
260
			foreach ( $order_results as $order_result ) {
261
				$payment = get_pronamic_payment_by_meta( '_pronamic_payment_omnikassa_2_merchant_order_id', $order_result->get_merchant_order_id() );
262
263
				if ( empty( $payment ) ) {
264
					continue;
265
				}
266
267
				$payment->set_transaction_id( $order_result->get_omnikassa_order_id() );
268
269
				$pronamic_status = Statuses::transform( $order_result->get_order_status() );
270
271
				if ( null !== $pronamic_status ) {
272
					$payment->set_status( $pronamic_status );
273
				}
274
275
				// Note.
276
				$note = '';
277
278
				$note .= '<p>';
279
				$note .= __( 'OmniKassa 2.0 webhook URL requested:', 'pronamic_ideal' );
280
				$note .= '</p>';
281
				$note .= '<pre>';
282
				$note .= wp_json_encode( $order_result->get_json(), JSON_PRETTY_PRINT );
283
				$note .= '</pre>';
284
285
				$payment->add_note( $note );
286
287
				$payment->save();
288
			}
289
		} while ( $order_results->more_available() );
290
	}
291
292
	/**
293
	 * Maybe update access token.
294
	 *
295
	 * @return void
296
	 */
297
	private function maybe_update_access_token() {
298
		if ( $this->config->is_access_token_valid() ) {
299
			return;
300
		}
301
302
		$data = $this->client->get_access_token_data();
303
304
		if ( ! is_object( $data ) ) {
305
			return;
306
		}
307
308
		if ( isset( $data->token ) ) {
309
			$this->config->access_token = $data->token;
310
311
			update_post_meta( $this->config->post_id, '_pronamic_gateway_omnikassa_2_access_token', $data->token );
312
		}
313
314
		if ( isset( $data->validUntil ) ) {
315
			$this->config->access_token_valid_until = $data->validUntil;
316
317
			update_post_meta(
318
				$this->config->post_id,
319
				'_pronamic_gateway_omnikassa_2_access_token_valid_until',
320
				$data->validUntil
321
			);
322
		}
323
	}
324
325
	/**
326
	 * Get client error.
327
	 *
328
	 * @return \WP_Error|bool
329
	 */
330
	private function get_client_error() {
331
		$error = $this->client->get_error();
332
333
		if ( is_wp_error( $error ) ) {
334
			$this->error = $error;
335
336
			return $error;
337
		}
338
339
		return false;
340
	}
341
}
342