Failed Conditions
Push — feature/post-pay ( ae1305...eeb3ed )
by Remco
04:59
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\Gateway as Core_Gateway;
14
use Pronamic\WordPress\Pay\Core\PaymentMethods;
15
use Pronamic\WordPress\Pay\Payments\Payment;
16
17
/**
18
 * Gateway
19
 *
20
 * @author  Remco Tolsma
21
 * @version 2.0.2
22
 * @since   1.0.0
23
 */
24
class Gateway extends Core_Gateway {
25
	/**
26
	 * Client.
27
	 *
28
	 * @var Client
29
	 */
30
	private $client;
31
32
	/**
33
	 * Constructs and initializes an OmniKassa 2.0 gateway.
34
	 *
35
	 * @param Config $config Config.
36
	 */
37
	public function __construct( Config $config ) {
38
		parent::__construct( $config );
39
40
		$this->set_method( self::METHOD_HTTP_REDIRECT );
41
42
		// Client.
43
		$this->client = new Client();
44
45
		$url = Client::URL_PRODUCTION;
46
47
		if ( self::MODE_TEST === $config->mode ) {
48
			$url = Client::URL_SANDBOX;
49
		}
50
51
		$this->client->set_url( $url );
52
		$this->client->set_refresh_token( $config->refresh_token );
53
		$this->client->set_signing_key( $config->signing_key );
54
	}
55
56
	/**
57
	 * Get supported payment methods.
58
	 *
59
	 * @see \Pronamic_WP_Pay_Gateway::get_supported_payment_methods()
60
	 * @return array
61
	 */
62
	public function get_supported_payment_methods() {
63
		return array(
64
			PaymentMethods::AFTERPAY,
65
			PaymentMethods::BANCONTACT,
66
			PaymentMethods::CREDIT_CARD,
67
			PaymentMethods::IDEAL,
68
			PaymentMethods::MAESTRO,
69
			PaymentMethods::PAYPAL,
70
		);
71
	}
72
73
	/**
74
	 * Start.
75
	 *
76
	 * @see Core_Gateway::start()
77
	 *
78
	 * @param Payment $payment Payment.
79
	 */
80
	public function start( Payment $payment ) {
81
		// Merchant order ID.
82
		$merchant_order_id = $payment->format_string( $this->config->order_id );
83
84
		$payment->set_meta( 'omnikassa_2_merchant_order_id', $merchant_order_id );
85
86
		// New order.
87
		$merchant_return_url = $payment->get_return_url();
88
		$merchant_return_url = apply_filters( 'pronamic_pay_omnikassa_2_merchant_return_url', $merchant_return_url );
89
90
		$order = new Order(
91
			$merchant_order_id,
92
			MoneyTransformer::transform( $payment->get_total_amount() ),
93
			$merchant_return_url
94
		);
95
96
		// Shipping address.
97
		$order->set_shipping_detail( AddressTransformer::transform( $payment->get_shipping_address() ) );
98
99
		// Billing address.
100
		$order->set_billing_detail( AddressTransformer::transform( $payment->get_billing_address() ) );
101
102
		// Customer information.
103
		$customer = $payment->get_customer();
104
105
		if ( null !== $customer ) {
106
			$order->set_language( strtoupper( $customer->get_language() ) );
107
108
			$customer_information = new CustomerInformation();
109
110
			$customer_information->set_email_address( $customer->get_email() );
111
			$customer_information->set_date_of_birth( $customer->get_birth_date() );
112
			$customer_information->set_gender( $customer->get_gender() );
113
			$customer_information->set_telephone_number( $customer->get_phone() );
114
115
			if ( null !== $customer->get_name() ) {
116
				$customer_information->set_initials( $customer->get_name()->get_initials() );
0 ignored issues
show
The method get_initials() does not exist on Pronamic\WordPress\Pay\ContactName. ( Ignorable by Annotation )

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

116
				$customer_information->set_initials( $customer->get_name()->/** @scrutinizer ignore-call */ get_initials() );

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...
117
			}
118
119
			$order->set_customer_information( $customer_information );
120
		}
121
122
		// Payment brand.
123
		$payment_brand = PaymentBrands::transform( $payment->get_method() );
124
125
		$order->set_payment_brand( $payment_brand );
126
127
		if ( null !== $payment_brand ) {
128
			// Payment brand force should only be set if payment brand is not empty.
129
			$order->set_payment_brand_force( PaymentBrandForce::FORCE_ONCE );
130
		}
131
132
		// Description.
133
		$order->set_description( substr( $payment->get_description(), 0, 35 ) );
134
135
		// Lines.
136
		if ( null !== $payment->get_lines() ) {
137
			$order_items = $order->new_items();
138
139
			foreach ( $payment->get_lines() as $line ) {
140
				$item = $order_items->new_item(
141
					$line->get_name(),
142
					$line->get_quantity(),
143
					MoneyTransformer::transform( $line->get_total_amount() ),
144
					ProductCategories::transform( $line->get_type() )
145
				);
146
147
				$item->set_id( $line->get_id() );
148
149
				// Description.
150
				$description = $line->get_description();
151
152
				if ( empty( $description ) && PaymentBrands::AFTERPAY === $payment_brand ) {
153
					/*
154
					 * The `OrderItem.description` field is documentated as `0..1` (optional),
155
					 * but for AfterPay payments it is required.
156
					 *
157
					 * @link https://github.com/wp-pay-gateways/omnikassa-2/tree/feature/post-pay/documentation#error-5024
158
					 */
159
					$description = $line->get_name();
160
				}
161
162
				$item->set_description( $description );
163
164
				if ( null !== $line->get_tax_amount() ) {
165
					$item->set_tax( MoneyTransformer::transform( $line->get_tax_amount() ) );
166
				}
167
			}
168
		}
169
170
		// Maybe update access token.
171
		$this->maybe_update_access_token();
172
173
		// Handle errors.
174
		if ( $this->get_client_error() ) {
175
			return;
176
		}
177
178
		// Announce order.
179
		$response = $this->client->order_announce( $this->config, $order );
180
181
		// Handle errors.
182
		if ( $this->get_client_error() ) {
183
			return;
184
		}
185
186
		if ( false === $response ) {
187
			return;
188
		}
189
190
		if ( ! $response->is_valid( $this->config->signing_key ) ) {
191
			return;
192
		}
193
194
		$payment->set_action_url( $response->get_redirect_url() );
195
	}
196
197
	/**
198
	 * Update status of the specified payment.
199
	 *
200
	 * @param Payment $payment Payment.
201
	 */
202
	public function update_status( Payment $payment ) {
203
		if ( ! ReturnParameters::contains( $_GET ) ) { // WPCS: CSRF ok.
204
			return;
205
		}
206
207
		$parameters = ReturnParameters::from_array( $_GET ); // WPCS: CSRF ok.
208
209
		// Note.
210
		$note_values = array(
211
			'order_id'  => $parameters->get_order_id(),
212
			'status'    => $parameters->get_status(),
213
			'signature' => $parameters->get_signature(),
214
			'valid'     => $parameters->is_valid( $this->config->signing_key ) ? 'true' : 'false',
215
		);
216
217
		$note = '';
218
219
		$note .= '<p>';
220
		$note .= __( 'OmniKassa 2.0 return URL requested:', 'pronamic_ideal' );
221
		$note .= '</p>';
222
223
		$note .= '<dl>';
224
225
		foreach ( $note_values as $key => $value ) {
226
			$note .= sprintf( '<dt>%s</dt>', esc_html( $key ) );
227
			$note .= sprintf( '<dd>%s</dd>', esc_html( $value ) );
228
		}
229
230
		$note .= '</dl>';
231
232
		$payment->add_note( $note );
233
234
		// Validate.
235
		if ( ! $parameters->is_valid( $this->config->signing_key ) ) {
236
			return;
237
		}
238
239
		// Status.
240
		$pronamic_status = Statuses::transform( $parameters->get_status() );
241
242
		if ( null !== $pronamic_status ) {
243
			$payment->set_status( $pronamic_status );
244
		}
245
	}
246
247
	/**
248
	 * Handle notification.
249
	 *
250
	 * @param Notification $notification Notification.
251
	 *
252
	 * @return void
253
	 */
254
	public function handle_notification( Notification $notification ) {
255
		if ( ! $notification->is_valid( $this->config->signing_key ) ) {
256
			return;
257
		}
258
259
		switch ( $notification->get_event_name() ) {
260
			case 'merchant.order.status.changed':
261
				$this->handle_merchant_order_status_changed( $notification );
262
		}
263
	}
264
265
	/**
266
	 * Handle `merchant.order.status.changed` event.
267
	 *
268
	 * @param Notification $notification Notification.
269
	 *
270
	 * @return void
271
	 */
272
	private function handle_merchant_order_status_changed( Notification $notification ) {
273
		do {
274
			$order_results = $this->client->get_order_results( $notification->get_authentication() );
275
276
			if ( ! $order_results || $order_results->is_valid( $this->config->signing_key ) ) {
277
				return;
278
			}
279
280
			foreach ( $order_results as $order_result ) {
281
				$payment = get_pronamic_payment_by_meta( '_pronamic_payment_omnikassa_2_merchant_order_id', $order_result->get_merchant_order_id() );
282
283
				if ( empty( $payment ) ) {
284
					continue;
285
				}
286
287
				$payment->set_transaction_id( $order_result->get_omnikassa_order_id() );
288
289
				$pronamic_status = Statuses::transform( $order_result->get_order_status() );
290
291
				if ( null !== $pronamic_status ) {
292
					$payment->set_status( $pronamic_status );
293
				}
294
295
				// Note.
296
				$note = '';
297
298
				$note .= '<p>';
299
				$note .= __( 'OmniKassa 2.0 webhook URL requested:', 'pronamic_ideal' );
300
				$note .= '</p>';
301
				$note .= '<pre>';
302
				$note .= wp_json_encode( $order_result->get_json(), JSON_PRETTY_PRINT );
303
				$note .= '</pre>';
304
305
				$payment->add_note( $note );
306
307
				$payment->save();
308
			}
309
		} while ( $order_results->more_available() );
310
	}
311
312
	/**
313
	 * Maybe update access token.
314
	 *
315
	 * @return void
316
	 */
317
	private function maybe_update_access_token() {
318
		if ( $this->config->is_access_token_valid() ) {
319
			return;
320
		}
321
322
		$data = $this->client->get_access_token_data();
323
324
		if ( ! is_object( $data ) ) {
325
			return;
326
		}
327
328
		if ( isset( $data->token ) ) {
329
			$this->config->access_token = $data->token;
330
331
			update_post_meta( $this->config->post_id, '_pronamic_gateway_omnikassa_2_access_token', $data->token );
332
		}
333
334
		/*
335
		 * @codingStandardsIgnoreStart
336
		 *
337
		 * Ignore coding standards because of sniff WordPress.NamingConventions.ValidVariableName.NotSnakeCaseMemberVar
338
		 */
339
		if ( isset( $data->validUntil ) ) {
340
			$this->config->access_token_valid_until = $data->validUntil;
341
342
			update_post_meta(
343
				$this->config->post_id,
344
				'_pronamic_gateway_omnikassa_2_access_token_valid_until',
345
				$data->validUntil
346
			);
347
		}
348
		// @codingStandardsIgnoreEnd
349
	}
350
351
	/**
352
	 * Get client error.
353
	 *
354
	 * @return \WP_Error|bool
355
	 */
356
	private function get_client_error() {
357
		$error = $this->client->get_error();
358
359
		if ( is_wp_error( $error ) ) {
360
			$this->error = $error;
361
362
			return $error;
363
		}
364
365
		return false;
366
	}
367
}
368