Completed
Push — master ( 47d6c0...61dad2 )
by Chris
03:16
created

class-edu-klarnacheckout.php (3 issues)

1
<?php
2
defined( 'ABSPATH' ) || die( 'This plugin must be run within the scope of WordPress.' );
3
4
if ( ! class_exists( 'EDU_KlarnaCheckout' ) ) {
5
	class EDU_KlarnaCheckout extends EDU_Integration {
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
6
		public function __construct() {
7
			$this->id          = 'eduadmin-klarnacheckout';
8
			$this->displayName = __( 'Klarna Checkout', 'eduadmin-wp-klarna-checkout' );
9
			$this->description = '';
10
11
			$this->init_form_fields();
12
			$this->init_settings();
13
14
			add_action( 'eduadmin-checkpaymentplugins', array( $this, 'intercept_booking' ) );
15
			add_action( 'eduadmin-processbooking', array( $this, 'process_booking' ) );
16
			add_action( 'eduadmin-bookingcompleted', array( $this, 'process_klarnaresponse' ) );
17
			add_action( 'wp_loaded', array( $this, 'process_paymentstatus' ) );
18
19
			add_shortcode( 'eduadmin-klarna-testpage', array( $this, 'test_page' ) );
20
		}
21
22
		/**
23
		 * @param $attributes
24
		 */
25
		public function test_page( $attributes ) {
26
			$attributes = shortcode_atts(
27
				array(
28
					'bookingid'          => 0,
29
					'programmebookingid' => 0,
30
				),
31
				normalize_empty_atts( $attributes ),
32
				'test_page'
33
			);
34
35
			if ( $attributes['bookingid'] > 0 ) {
36
				$event_booking = EDUAPI()->OData->Bookings->GetItem(
37
					$attributes['bookingid'],
38
					null,
39
					'Customer($select=CustomerId;),ContactPerson($select=PersonId;),OrderRows',
40
					false
41
				);
42
			} elseif ( $attributes['programmebookingid'] > 0 ) {
43
				$event_booking = EDUAPI()->OData->ProgrammeBookings->GetItem(
44
					$attributes['programmebookingid'],
45
					null,
46
					'Customer($select=CustomerId;),ContactPerson($select=PersonId;),OrderRows',
47
					false
48
				);
49
			}
50
51
			$_customer = EDUAPI()->OData->Customers->GetItem(
52
				$event_booking['Customer']['CustomerId'],
53
				null,
54
				null,
55
				false
56
			);
57
58
			$_contact = EDUAPI()->OData->Persons->GetItem(
59
				$event_booking['ContactPerson']['PersonId'],
60
				null,
61
				null,
62
				false
63
			);
64
65
66
			$ebi = new EduAdmin_BookingInfo( $event_booking, $_customer, $_contact );
0 ignored issues
show
It seems like $_contact can also be of type array; however, parameter $contact of EduAdmin_BookingInfo::__construct() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

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

66
			$ebi = new EduAdmin_BookingInfo( $event_booking, $_customer, /** @scrutinizer ignore-type */ $_contact );
Loading history...
It seems like $_customer can also be of type array; however, parameter $customer of EduAdmin_BookingInfo::__construct() does only seem to accept null, maybe add an additional type check? ( Ignorable by Annotation )

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

66
			$ebi = new EduAdmin_BookingInfo( $event_booking, /** @scrutinizer ignore-type */ $_customer, $_contact );
Loading history...
67
68
			if ( ! empty( EDU()->session['klarna-order-id'] ) && ! empty( $_GET['klarna_order_id'] ) && EDU()->session['klarna-order-id'] === $_GET['klarna_order_id'] ) {
69
				do_action( 'eduadmin-bookingcompleted', $ebi );
70
			} else {
71
				do_action( 'eduadmin-processbooking', $ebi );
72
			}
73
		}
74
75
		/**
76
		 * @param EduAdmin_BookingInfo|null $ebi
77
		 */
78
		public function intercept_booking( $ebi = null ) {
79
			if ( 'no' === $this->get_option( 'enabled', 'no' ) ) {
80
				return;
81
			}
82
83
			if ( ! empty( $_POST['act'] ) && ( 'bookCourse' === $_POST['act'] || 'bookProgramme' === $_POST['act'] ) ) {
84
				$ebi->NoRedirect = true;
85
			}
86
		}
87
88
		/**
89
		 * @param EduAdmin_BookingInfo|null $ebi
90
		 */
91
		public function process_booking( $ebi = null ) {
92
			if ( 'no' === $this->get_option( 'enabled', 'no' ) ) {
93
				return;
94
			}
95
96
			$ebi->NoRedirect = true;
97
98
			if ( empty( $_GET['klarna_order_id'] ) || empty( EDU()->session['klarna-order-id'] ) ) {
99
				$checkout = $this->create_checkout( $ebi );
100
101
				$snippet = $checkout['gui']['snippet'];
102
				echo "<div>{$snippet}</div>";
103
			}
104
		}
105
106
		public function process_klarnaresponse() {
107
			if ( 'no' === $this->get_option( 'enabled', 'no' ) ) {
108
				return;
109
			}
110
			$checkout_url  = ! checked( $this->get_option( 'test_mode', 'no' ), '1', false ) ? Klarna_Checkout_Connector::BASE_URL : Klarna_Checkout_Connector::BASE_TEST_URL;
111
			$shared_secret = $this->get_option( 'shared_secret', '' );
112
113
			if ( ! empty( $_GET['klarna_order_id'] ) && ! empty( EDU()->session['klarna-order-id'] ) && EDU()->session['klarna-order-id'] === $_GET['klarna_order_id'] ) {
114
				try {
115
					$connector = Klarna_Checkout_Connector::create(
116
						$shared_secret,
117
						$checkout_url
118
					);
119
120
					$order_id = EDU()->session['klarna-order-id'];
121
122
					$order = new Klarna_Checkout_Order( $connector, $order_id );
123
124
					$order->fetch();
125
126
					$snippet = $order['gui']['snippet'];
127
					echo "<div>{$snippet}</div>";
128
					EDU()->session['klarna-order-id'] = null;
129
130
				} catch ( Klarna_Checkout_ApiErrorException $ex ) {
131
					EDU()->write_debug( $ex->getMessage() );
132
					EDU()->write_debug( $ex->getPayload() );
133
				}
134
			}
135
		}
136
137
		public function init_form_fields() {
138
			$this->setting_fields = array(
139
				'enabled'       => array(
140
					'title'       => __( 'Enabled', 'edauadmin-wp-klarna-checkout' ),
141
					'type'        => 'checkbox',
142
					'description' => __( 'Enables/Disabled the integration with Klarna Checkout', 'eduadmin-wp-klarna-checkout' ),
143
					'default'     => 'no',
144
				),
145
				'eid'           => array(
146
					'title'       => __( 'EID', 'eduadmin-wp-klarna-checkout' ),
147
					'type'        => 'text',
148
					'description' => __( 'The EID to connect to Klarna Checkout v2', 'eduadmin-wp-klarna-checkout' ),
149
					'default'     => '',
150
				),
151
				'shared_secret' => array(
152
					'title'       => __( 'Shared secret', 'eduadmin-wp-klarna-checkout' ),
153
					'type'        => 'password',
154
					'description' => __( 'The shared secret to connect to Klarna Checkout v2', 'eduadmin-wp-klarna-checkout' ),
155
					'default'     => '',
156
				),
157
				'termsurl'      => array(
158
					'title'       => __( 'Terms and Conditions URL', 'eduadmin-wp-klarna-checkout' ),
159
					'type'        => 'text',
160
					'description' => __( 'This URL is required for Klarna Checkout', 'eduadmin-wp-klarna-checkout' ),
161
					'default'     => '',
162
				),
163
				'test_mode'     => array(
164
					'title'       => __( 'Test mode', 'eduadmin-wp-klarna-checkout' ),
165
					'type'        => 'checkbox',
166
					'description' => __( 'Enables test mode, so you can test the integration', 'eduadmin-wp-klarna-checkout' ),
167
					'default'     => 'no',
168
				),
169
			);
170
		}
171
172
		/**
173
		 * @param EduAdmin_BookingInfo|null $ebi
174
		 *
175
		 * @return Klarna_Checkout_Order|null
176
		 */
177
		public function create_checkout( $ebi = null ) {
178
179
			$checkout_url  = ! checked( $this->get_option( 'test_mode', 'no' ), '1', false ) ? Klarna_Checkout_Connector::BASE_URL : Klarna_Checkout_Connector::BASE_TEST_URL;
180
			$shared_secret = $this->get_option( 'shared_secret', '' );
181
182
			$create = array();
183
184
			$create['locale']            = strtolower( str_replace( '_', '-', get_locale() ) );
185
			$create['purchase_country']  = 'SE';
186
			$create['purchase_currency'] = get_option( 'eduadmin-currency', 'SEK' );
187
188
			$merchant              = array();
189
			$merchant['id']        = $this->get_option( 'eid', '' );
190
			$merchant['terms_uri'] = $this->get_option( 'termsurl', '' );
191
192
			$current_url = esc_url( "{$_SERVER['REQUEST_SCHEME']}://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}" );
193
194
			$booking_id           = 0;
195
			$programme_booking_id = 0;
196
197
			if ( ! empty( $ebi->EventBooking['BookingId'] ) ) {
198
				$booking_id = intval( $ebi->EventBooking['BookingId'] );
199
			}
200
201
			if ( ! empty( $ebi->EventBooking['ProgrammeBookingId'] ) ) {
202
				$programme_booking_id = intval( $ebi->EventBooking['ProgrammeBookingId'] );
203
			}
204
205
			$confirmation_url = add_query_arg(
206
				array(
207
					'klarna_order_id'      => '{checkout.order.id}',
208
					'booking_id'           => $booking_id,
209
					'programme_booking_id' => $programme_booking_id,
210
					'edu-valid-form'       => wp_create_nonce( 'edu-booking-confirm' ),
211
					'act'                  => 'paymentCompleted',
212
				),
213
				$current_url
214
			);
215
216
			$push_url = add_query_arg(
217
				array(
218
					'klarna_order_id'      => '{checkout.order.id}',
219
					'booking_id'           => $booking_id,
220
					'programme_booking_id' => $programme_booking_id,
221
					'status'               => 'push',
222
				),
223
				$current_url
224
			);
225
226
			$merchant['checkout_uri']     = $current_url;
227
			$merchant['confirmation_uri'] = $confirmation_url;
228
			$merchant['push_uri']         = $push_url;
229
230
			$create['merchant'] = $merchant;
231
232
			$create['cart']          = array();
233
			$create['cart']['items'] = array();
234
235
			foreach ( $ebi->EventBooking['OrderRows'] as $order_row ) {
236
				$cart_item = array();
237
238
				$cart_item['reference'] = $order_row['ItemNumber'];
239
				$cart_item['name']      = $order_row['Description'];
240
				$cart_item['quantity']  = intval( $order_row['Quantity'] );
241
242
				if ( ! $order_row['PriceIncVat'] ) {
243
					$price_per_unit = $order_row['PricePerUnit'] * ( 1 + ( $order_row['VatPercent'] / 100 ) ) * 100;
244
				} else {
245
					$price_per_unit = $order_row['PricePerUnit'] * 100;
246
				}
247
248
				$cart_item['unit_price']    = $price_per_unit;
249
				$cart_item['tax_rate']      = intval( $order_row['VatPercent'] * 100 );
250
				$cart_item['discount_rate'] = intval( $order_row['DiscountPercent'] * 100 );
251
252
				$create['cart']['items'][] = $cart_item;
253
			}
254
255
			try {
256
				$connector = Klarna_Checkout_Connector::create(
257
					$shared_secret,
258
					$checkout_url
259
				);
260
261
				$order = new Klarna_Checkout_Order( $connector );
262
				$order->create( $create );
263
264
				$order->fetch();
265
266
				$order_id                         = $order['id'];
267
				EDU()->session['klarna-order-id'] = $order_id;
268
269
				return $order;
270
			} catch ( Klarna_Checkout_ApiErrorException $ex ) {
271
				EDU()->write_debug( $ex->getMessage() );
272
				EDU()->write_debug( $ex->getPayload() );
273
274
				return null;
275
			}
276
		}
277
278
		public function process_paymentstatus() {
279
			if ( ! empty( $_GET['klarna_order_id'] ) && ! empty( $_GET['status'] ) ) {
280
				$checkout_url  = ! checked( $this->get_option( 'test_mode', 'no' ), '1', false ) ? Klarna_Checkout_Connector::BASE_URL : Klarna_Checkout_Connector::BASE_TEST_URL;
281
				$shared_secret = $this->get_option( 'shared_secret', '' );
282
283
				try {
284
					$connector = Klarna_Checkout_Connector::create(
285
						$shared_secret,
286
						$checkout_url
287
					);
288
289
					$order_id = $_GET['klarna_order_id'];
290
291
					$order = new Klarna_Checkout_Order( $connector, $order_id );
292
293
					$order->fetch();
294
295
					$booking_id           = intval( $_GET['booking_id'] );
296
					$programme_booking_id = intval( $_GET['programme_booking_id'] );
297
298
299
					if ( 'checkout_complete' === $order['status'] ) {
300
301
						$patch_booking       = new stdClass();
302
						$patch_booking->Paid = true;
303
304
						if ( $booking_id > 0 ) {
305
							EDUAPI()->REST->Booking->PatchBooking(
306
								$booking_id,
307
								$patch_booking
308
							);
309
						}
310
311
						if ( $programme_booking_id > 0 ) {
312
							EDUAPI()->REST->ProgrammeBooking->PatchBooking(
313
								$programme_booking_id,
314
								$patch_booking
315
							);
316
						}
317
318
						$update           = array();
319
						$update['status'] = 'created';
320
						$order->update( $update );
321
					}
322
					exit( 0 );
323
				} catch ( Klarna_Checkout_ApiErrorException $ex ) {
324
					EDU()->write_debug( $ex->getMessage() );
325
					EDU()->write_debug( $ex->getPayload() );
326
					exit( 1 );
327
				}
328
			}
329
		}
330
	}
331
}
332