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 { |
||||||
6 | public function __construct() { |
||||||
7 | $this->id = 'eduadmin-klarnacheckout'; |
||||||
8 | $this->displayName = __( 'Klarna Checkout', 'eduadmin-wp-klarna-checkout' ); |
||||||
9 | $this->description = ''; |
||||||
10 | $this->type = 'payment'; |
||||||
11 | |||||||
12 | $this->init_form_fields(); |
||||||
13 | $this->init_settings(); |
||||||
14 | |||||||
15 | add_action( 'eduadmin-checkpaymentplugins', array( $this, 'intercept_booking' ) ); |
||||||
16 | add_action( 'eduadmin-processbooking', array( $this, 'process_booking' ) ); |
||||||
17 | add_action( 'eduadmin-bookingcompleted', array( $this, 'process_klarnaresponse' ) ); |
||||||
18 | add_action( 'wp_loaded', array( $this, 'process_paymentstatus' ) ); |
||||||
19 | |||||||
20 | add_shortcode( 'eduadmin-klarna-testpage', array( $this, 'test_page' ) ); |
||||||
21 | } |
||||||
22 | |||||||
23 | /** |
||||||
24 | * @param $attributes |
||||||
25 | */ |
||||||
26 | public function test_page( $attributes ) { |
||||||
27 | $attributes = shortcode_atts( |
||||||
28 | array( |
||||||
29 | 'bookingid' => 0, |
||||||
30 | 'programmebookingid' => 0, |
||||||
31 | ), |
||||||
32 | normalize_empty_atts( $attributes ), |
||||||
33 | 'test_page' |
||||||
34 | ); |
||||||
35 | |||||||
36 | if ( $attributes['bookingid'] > 0 ) { |
||||||
37 | $event_booking = EDUAPI()->OData->Bookings->GetItem( |
||||||
0 ignored issues
–
show
Bug
introduced
by
![]() |
|||||||
38 | $attributes['bookingid'], |
||||||
39 | null, |
||||||
40 | 'Customer($select=CustomerId;),ContactPerson($select=PersonId;),OrderRows', |
||||||
41 | false |
||||||
42 | ); |
||||||
43 | } elseif ( $attributes['programmebookingid'] > 0 ) { |
||||||
44 | $event_booking = EDUAPI()->OData->ProgrammeBookings->GetItem( |
||||||
45 | $attributes['programmebookingid'], |
||||||
46 | null, |
||||||
47 | 'Customer($select=CustomerId;),ContactPerson($select=PersonId;),OrderRows', |
||||||
48 | false |
||||||
49 | ); |
||||||
50 | } |
||||||
51 | |||||||
52 | $_customer = EDUAPI()->OData->Customers->GetItem( |
||||||
53 | $event_booking['Customer']['CustomerId'], |
||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||||
54 | null, |
||||||
55 | "BillingInfo", |
||||||
56 | false |
||||||
57 | ); |
||||||
58 | |||||||
59 | $_contact = EDUAPI()->OData->Persons->GetItem( |
||||||
60 | $event_booking['ContactPerson']['PersonId'], |
||||||
61 | null, |
||||||
62 | null, |
||||||
63 | false |
||||||
64 | ); |
||||||
65 | |||||||
66 | $ebi = new EduAdmin_BookingInfo( $event_booking, $_customer, $_contact ); |
||||||
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 | $organization = EDUAPIHelper()->GetOrganization(); |
||||||
185 | $purchase_country = $organization["CountryCode"]; |
||||||
186 | |||||||
187 | $emd_info = array( |
||||||
188 | 'unique_account_identifier' => ( ! empty( $ebi->Contact['Email'] ) ? $ebi->Contact['Email'] : "uid:" . $ebi->Contact['PersonId'] ), |
||||||
189 | 'account_registration_date' => date( 'Y-m-d\TH:i', strtotime( $ebi->Contact['Created'] ) ), |
||||||
190 | 'account_last_modified' => date( 'Y-m-d\TH:i' ) |
||||||
191 | ); |
||||||
192 | |||||||
193 | $emd_info = array( $emd_info ); |
||||||
194 | |||||||
195 | $booking_id = 0; |
||||||
196 | $programme_booking_id = 0; |
||||||
197 | |||||||
198 | $reference_id = 0; |
||||||
199 | |||||||
200 | $_event = null; |
||||||
201 | |||||||
202 | $eventName = ''; |
||||||
203 | |||||||
204 | $locationAddress = ''; |
||||||
205 | $locationCountry = ''; |
||||||
206 | $locationPostalCode = ''; |
||||||
207 | |||||||
208 | if ( ! empty( $ebi->EventBooking['BookingId'] ) ) { |
||||||
209 | $booking_id = intval( $ebi->EventBooking['BookingId'] ); |
||||||
210 | $reference_id = $booking_id; |
||||||
211 | |||||||
212 | $_event = EDUAPI()->OData->Events->GetItem( $ebi->EventBooking['EventId'], null, "LocationAddress" ); |
||||||
0 ignored issues
–
show
The function
EDUAPI was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
213 | |||||||
214 | $eventName = $_event['EventName']; |
||||||
215 | |||||||
216 | if ( ! empty( $_event['LocationAddress'] ) && $_event['LocationAdress'] != null ) { |
||||||
217 | $locationAddress = $_event['LocationAddress']['Address']; |
||||||
218 | $locationCountry = $_event['LocationAddress']['Country']; |
||||||
219 | $locationPostalCode = $_event['LocationAddress']['AddressZip']; |
||||||
220 | } |
||||||
221 | } |
||||||
222 | |||||||
223 | if ( ! empty( $ebi->EventBooking['ProgrammeBookingId'] ) ) { |
||||||
224 | $programme_booking_id = intval( $ebi->EventBooking['ProgrammeBookingId'] ); |
||||||
225 | $reference_id = $programme_booking_id; |
||||||
226 | |||||||
227 | $_event = EDUAPI()->OData->ProgrammeStarts->GetItem( $ebi->EventBooking['ProgrammeStartId'] ); |
||||||
228 | |||||||
229 | $eventName = $_event['ProgrammeStartName']; |
||||||
230 | } |
||||||
231 | |||||||
232 | $emd_event_info = array( |
||||||
233 | 'event_name' => ( ! empty( $eventName ) ? $eventName : "" ), |
||||||
234 | 'event_company' => $organization['OrganisationName'], |
||||||
235 | 'genre_of_event' => ( ! empty( $_event['CategoryName'] ) ? $_event['CategoryName'] : "" ), |
||||||
236 | 'arena_name' => ( ! empty( $_event['AddressName'] ) ? $_event['AddressName'] : "" ), |
||||||
237 | 'arena_location' => array( |
||||||
238 | 'street_address' => $locationAddress, |
||||||
239 | 'postal_code' => $locationPostalCode, |
||||||
240 | 'city' => ( ! empty( $_event['City'] ) ? $_event['City'] : "" ), |
||||||
241 | 'country' => $locationCountry |
||||||
242 | ), |
||||||
243 | 'start_time' => date( 'Y-m-d\TH:i', strtotime( $_event['StartDate'] ) ), |
||||||
244 | 'end_time' => date( 'Y-m-d\TH:i', strtotime( $_event['EndDate'] ) ), |
||||||
245 | 'access_controlled_venue' => false |
||||||
246 | ); |
||||||
247 | |||||||
248 | $emd_event_info = array( $emd_event_info ); |
||||||
249 | |||||||
250 | $emd_attachment = array( |
||||||
251 | 'customer_account_info' => $emd_info, |
||||||
252 | 'event' => $emd_event_info |
||||||
253 | ); |
||||||
254 | |||||||
255 | $create['attachment'] = array(); |
||||||
256 | $create['attachment']['content_type'] = 'application/vnd.klarna.internal.emd-v2+json'; |
||||||
257 | $create['attachment']['body'] = json_encode( $emd_attachment ); |
||||||
258 | |||||||
259 | $create['locale'] = strtolower( str_replace( '_', '-', get_locale() ) ); |
||||||
260 | $create['purchase_country'] = $purchase_country; |
||||||
261 | $create['purchase_currency'] = get_option( 'eduadmin-currency', 'SEK' ); |
||||||
262 | |||||||
263 | $merchant = array(); |
||||||
264 | $merchant['id'] = $this->get_option( 'eid', '' ); |
||||||
265 | $merchant['terms_uri'] = $this->get_option( 'termsurl', '' ); |
||||||
266 | |||||||
267 | $current_url = esc_url( "{$_SERVER['REQUEST_SCHEME']}://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}" ); |
||||||
268 | |||||||
269 | $rowExtraInfo = ""; |
||||||
270 | |||||||
271 | if ( null != $_event ) { |
||||||
272 | if ( ! empty( $_event['City'] ) ) { |
||||||
273 | $rowExtraInfo .= ';' . $_event['City']; |
||||||
274 | } |
||||||
275 | |||||||
276 | if ( ! empty( $_event['StartDate'] ) ) { |
||||||
277 | $rowExtraInfo .= ';' . date( "Y-m-d", strtotime( $_event['StartDate'] ) ); |
||||||
278 | } |
||||||
279 | |||||||
280 | if ( ! empty( $_event['EndDate'] ) ) { |
||||||
281 | $rowExtraInfo .= ';' . date( "Y-m-d", strtotime( $_event['EndDate'] ) ); |
||||||
282 | } |
||||||
283 | } |
||||||
284 | |||||||
285 | $confirmation_url = add_query_arg( |
||||||
286 | array( |
||||||
287 | 'klarna_order_id' => '{checkout.order.id}', |
||||||
288 | 'booking_id' => $booking_id, |
||||||
289 | 'programme_booking_id' => $programme_booking_id, |
||||||
290 | 'edu-valid-form' => wp_create_nonce( 'edu-booking-confirm' ), |
||||||
291 | 'act' => 'paymentCompleted', |
||||||
292 | 'edu-thankyou' => $reference_id |
||||||
293 | ), |
||||||
294 | $current_url |
||||||
295 | ); |
||||||
296 | |||||||
297 | $push_url = add_query_arg( |
||||||
298 | array( |
||||||
299 | 'klarna_order_id' => '{checkout.order.id}', |
||||||
300 | 'booking_id' => $booking_id, |
||||||
301 | 'programme_booking_id' => $programme_booking_id, |
||||||
302 | 'status' => 'push', |
||||||
303 | ), |
||||||
304 | $current_url |
||||||
305 | ); |
||||||
306 | |||||||
307 | $merchant['checkout_uri'] = $current_url; |
||||||
308 | $merchant['confirmation_uri'] = $confirmation_url; |
||||||
309 | $merchant['push_uri'] = $push_url; |
||||||
310 | |||||||
311 | $create['merchant'] = $merchant; |
||||||
312 | |||||||
313 | $create['merchant_reference'] = array(); |
||||||
314 | $create['merchant_reference']['orderid1'] = $reference_id; |
||||||
315 | $create['merchant_reference']['orderid2'] = $reference_id; |
||||||
316 | |||||||
317 | $create['cart'] = array(); |
||||||
318 | $create['cart']['items'] = array(); |
||||||
319 | |||||||
320 | foreach ( $ebi->EventBooking['OrderRows'] as $order_row ) { |
||||||
321 | $cart_item = array(); |
||||||
322 | |||||||
323 | $cart_item['reference'] = $order_row['ItemNumber']; |
||||||
324 | $cart_item['name'] = $order_row['Description'] . $rowExtraInfo; |
||||||
325 | $cart_item['quantity'] = intval( $order_row['Quantity'] ); |
||||||
326 | |||||||
327 | if ( ! $order_row['PriceIncVat'] ) { |
||||||
328 | $price_per_unit = $order_row['PricePerUnit'] * ( 1 + ( $order_row['VatPercent'] / 100 ) ) * 100; |
||||||
329 | } else { |
||||||
330 | $price_per_unit = $order_row['PricePerUnit'] * 100; |
||||||
331 | } |
||||||
332 | |||||||
333 | $cart_item['unit_price'] = $price_per_unit; |
||||||
334 | $cart_item['tax_rate'] = intval( $order_row['VatPercent'] * 100 ); |
||||||
335 | $cart_item['discount_rate'] = intval( $order_row['DiscountPercent'] * 100 ); |
||||||
336 | |||||||
337 | $create['cart']['items'][] = $cart_item; |
||||||
338 | } |
||||||
339 | |||||||
340 | try { |
||||||
341 | $connector = Klarna_Checkout_Connector::create( |
||||||
342 | $shared_secret, |
||||||
343 | $checkout_url |
||||||
344 | ); |
||||||
345 | |||||||
346 | $order = new Klarna_Checkout_Order( $connector ); |
||||||
347 | $order->create( $create ); |
||||||
348 | |||||||
349 | $order->fetch(); |
||||||
350 | |||||||
351 | $order_id = $order['id']; |
||||||
352 | EDU()->session['klarna-order-id'] = $order_id; |
||||||
353 | |||||||
354 | return $order; |
||||||
355 | } catch ( Klarna_Checkout_ApiErrorException $ex ) { |
||||||
356 | EDU()->write_debug( $ex->getMessage() ); |
||||||
357 | EDU()->write_debug( $ex->getPayload() ); |
||||||
358 | |||||||
359 | return null; |
||||||
360 | } |
||||||
361 | } |
||||||
362 | |||||||
363 | public function process_paymentstatus() { |
||||||
364 | if ( ! empty( $_GET['klarna_order_id'] ) && ! empty( $_GET['status'] ) ) { |
||||||
365 | $checkout_url = ! checked( $this->get_option( 'test_mode', 'no' ), '1', false ) ? Klarna_Checkout_Connector::BASE_URL : Klarna_Checkout_Connector::BASE_TEST_URL; |
||||||
366 | $shared_secret = $this->get_option( 'shared_secret', '' ); |
||||||
367 | |||||||
368 | try { |
||||||
369 | $connector = Klarna_Checkout_Connector::create( |
||||||
370 | $shared_secret, |
||||||
371 | $checkout_url |
||||||
372 | ); |
||||||
373 | |||||||
374 | $order_id = $_GET['klarna_order_id']; |
||||||
375 | |||||||
376 | $order = new Klarna_Checkout_Order( $connector, $order_id ); |
||||||
377 | |||||||
378 | $order->fetch(); |
||||||
379 | |||||||
380 | $booking_id = intval( $_GET['booking_id'] ); |
||||||
381 | $programme_booking_id = intval( $_GET['programme_booking_id'] ); |
||||||
382 | |||||||
383 | |||||||
384 | if ( 'checkout_complete' === $order['status'] ) { |
||||||
385 | |||||||
386 | $patch_booking = new stdClass(); |
||||||
387 | $patch_booking->Paid = true; |
||||||
388 | |||||||
389 | // We're setting this as a Card Payment, so that our service in the background will remove it if it doesn't get paid in time (15 minute slot) |
||||||
390 | $patch_booking->PaymentMethodId = 2; |
||||||
391 | |||||||
392 | if ( $booking_id > 0 ) { |
||||||
393 | EDUAPI()->REST->Booking->PatchBooking( |
||||||
0 ignored issues
–
show
The function
EDUAPI was not found. Maybe you did not declare it correctly or list all dependencies?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
![]() |
|||||||
394 | $booking_id, |
||||||
395 | $patch_booking |
||||||
396 | ); |
||||||
397 | } |
||||||
398 | |||||||
399 | if ( $programme_booking_id > 0 ) { |
||||||
400 | EDUAPI()->REST->ProgrammeBooking->PatchBooking( |
||||||
401 | $programme_booking_id, |
||||||
402 | $patch_booking |
||||||
403 | ); |
||||||
404 | } |
||||||
405 | |||||||
406 | $update = array(); |
||||||
407 | $update['status'] = 'created'; |
||||||
408 | $order->update( $update ); |
||||||
409 | } |
||||||
410 | exit( 0 ); |
||||||
0 ignored issues
–
show
|
|||||||
411 | } catch ( Klarna_Checkout_ApiErrorException $ex ) { |
||||||
412 | EDU()->write_debug( $ex->getMessage() ); |
||||||
413 | EDU()->write_debug( $ex->getPayload() ); |
||||||
414 | exit( 1 ); |
||||||
0 ignored issues
–
show
|
|||||||
415 | } |
||||||
416 | } |
||||||
417 | } |
||||||
418 | } |
||||||
419 | } |
||||||
420 |