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 | |||
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 | $ebi = new EduAdmin_BookingInfo( $event_booking, $_customer, $_contact ); |
||
66 | |||
67 | if ( ! empty( EDU()->session['klarna-order-id'] ) && ! empty( $_GET['klarna_order_id'] ) && EDU()->session['klarna-order-id'] === $_GET['klarna_order_id'] ) { |
||
68 | do_action( 'eduadmin-bookingcompleted', $ebi ); |
||
69 | } else { |
||
70 | do_action( 'eduadmin-processbooking', $ebi ); |
||
71 | } |
||
72 | } |
||
73 | |||
74 | /** |
||
75 | * @param EduAdmin_BookingInfo|null $ebi |
||
76 | */ |
||
77 | public function intercept_booking( $ebi = null ) { |
||
78 | if ( 'no' === $this->get_option( 'enabled', 'no' ) ) { |
||
79 | return; |
||
80 | } |
||
81 | |||
82 | if ( ! empty( $_POST['act'] ) && ( 'bookCourse' === $_POST['act'] || 'bookProgramme' === $_POST['act'] ) ) { |
||
83 | $ebi->NoRedirect = true; |
||
84 | } |
||
85 | } |
||
86 | |||
87 | /** |
||
88 | * @param EduAdmin_BookingInfo|null $ebi |
||
89 | */ |
||
90 | public function process_booking( $ebi = null ) { |
||
91 | if ( 'no' === $this->get_option( 'enabled', 'no' ) ) { |
||
92 | return; |
||
93 | } |
||
94 | |||
95 | $ebi->NoRedirect = true; |
||
96 | |||
97 | if ( empty( $_GET['klarna_order_id'] ) || empty( EDU()->session['klarna-order-id'] ) ) { |
||
98 | $checkout = $this->create_checkout( $ebi ); |
||
99 | |||
100 | $snippet = $checkout['gui']['snippet']; |
||
101 | echo "<div>{$snippet}</div>"; |
||
102 | } |
||
103 | } |
||
104 | |||
105 | public function process_klarnaresponse() { |
||
106 | if ( 'no' === $this->get_option( 'enabled', 'no' ) ) { |
||
107 | return; |
||
108 | } |
||
109 | $checkout_url = ! checked( $this->get_option( 'test_mode', 'no' ), '1', false ) ? Klarna_Checkout_Connector::BASE_URL : Klarna_Checkout_Connector::BASE_TEST_URL; |
||
110 | $shared_secret = $this->get_option( 'shared_secret', '' ); |
||
111 | |||
112 | if ( ! empty( $_GET['klarna_order_id'] ) && ! empty( EDU()->session['klarna-order-id'] ) && EDU()->session['klarna-order-id'] === $_GET['klarna_order_id'] ) { |
||
113 | try { |
||
114 | $connector = Klarna_Checkout_Connector::create( |
||
115 | $shared_secret, |
||
116 | $checkout_url |
||
117 | ); |
||
118 | |||
119 | $order_id = EDU()->session['klarna-order-id']; |
||
120 | |||
121 | $order = new Klarna_Checkout_Order( $connector, $order_id ); |
||
122 | |||
123 | $order->fetch(); |
||
124 | |||
125 | $snippet = $order['gui']['snippet']; |
||
126 | echo "<div>{$snippet}</div>"; |
||
127 | EDU()->session['klarna-order-id'] = null; |
||
128 | |||
129 | } catch ( Klarna_Checkout_ApiErrorException $ex ) { |
||
130 | EDU()->write_debug( $ex->getMessage() ); |
||
131 | EDU()->write_debug( $ex->getPayload() ); |
||
132 | } |
||
133 | } |
||
134 | } |
||
135 | |||
136 | public function init_form_fields() { |
||
137 | $this->setting_fields = array( |
||
138 | 'enabled' => array( |
||
139 | 'title' => __( 'Enabled', 'edauadmin-wp-klarna-checkout' ), |
||
140 | 'type' => 'checkbox', |
||
141 | 'description' => __( 'Enables/Disabled the integration with Klarna Checkout', 'eduadmin-wp-klarna-checkout' ), |
||
142 | 'default' => 'no', |
||
143 | ), |
||
144 | 'eid' => array( |
||
145 | 'title' => __( 'EID', 'eduadmin-wp-klarna-checkout' ), |
||
146 | 'type' => 'text', |
||
147 | 'description' => __( 'The EID to connect to Klarna Checkout v2', 'eduadmin-wp-klarna-checkout' ), |
||
148 | 'default' => '', |
||
149 | ), |
||
150 | 'shared_secret' => array( |
||
151 | 'title' => __( 'Shared secret', 'eduadmin-wp-klarna-checkout' ), |
||
152 | 'type' => 'password', |
||
153 | 'description' => __( 'The shared secret to connect to Klarna Checkout v2', 'eduadmin-wp-klarna-checkout' ), |
||
154 | 'default' => '', |
||
155 | ), |
||
156 | 'termsurl' => array( |
||
157 | 'title' => __( 'Terms and Conditions URL', 'eduadmin-wp-klarna-checkout' ), |
||
158 | 'type' => 'text', |
||
159 | 'description' => __( 'This URL is required for Klarna Checkout', 'eduadmin-wp-klarna-checkout' ), |
||
160 | 'default' => '', |
||
161 | ), |
||
162 | 'test_mode' => array( |
||
163 | 'title' => __( 'Test mode', 'eduadmin-wp-klarna-checkout' ), |
||
164 | 'type' => 'checkbox', |
||
165 | 'description' => __( 'Enables test mode, so you can test the integration', 'eduadmin-wp-klarna-checkout' ), |
||
166 | 'default' => 'no', |
||
167 | ), |
||
168 | ); |
||
169 | } |
||
170 | |||
171 | /** |
||
172 | * @param EduAdmin_BookingInfo|null $ebi |
||
173 | * |
||
174 | * @return Klarna_Checkout_Order|null |
||
175 | */ |
||
176 | public function create_checkout( $ebi = null ) { |
||
177 | |||
178 | $checkout_url = ! checked( $this->get_option( 'test_mode', 'no' ), '1', false ) ? Klarna_Checkout_Connector::BASE_URL : Klarna_Checkout_Connector::BASE_TEST_URL; |
||
179 | $shared_secret = $this->get_option( 'shared_secret', '' ); |
||
180 | |||
181 | $create = array(); |
||
182 | |||
183 | $create['locale'] = strtolower( str_replace( '_', '-', get_locale() ) ); |
||
184 | $create['purchase_country'] = 'SE'; |
||
185 | $create['purchase_currency'] = get_option( 'eduadmin-currency', 'SEK' ); |
||
186 | |||
187 | $merchant = array(); |
||
188 | $merchant['id'] = $this->get_option( 'eid', '' ); |
||
189 | $merchant['terms_uri'] = $this->get_option( 'termsurl', '' ); |
||
190 | |||
191 | $current_url = esc_url( "{$_SERVER['REQUEST_SCHEME']}://{$_SERVER['HTTP_HOST']}{$_SERVER['REQUEST_URI']}" ); |
||
192 | |||
193 | $booking_id = 0; |
||
194 | $programme_booking_id = 0; |
||
195 | |||
196 | $reference_id = 0; |
||
197 | |||
198 | $_event = null; |
||
199 | |||
200 | if ( ! empty( $ebi->EventBooking['BookingId'] ) ) { |
||
201 | $booking_id = intval( $ebi->EventBooking['BookingId'] ); |
||
202 | $reference_id = $booking_id; |
||
203 | |||
204 | $_event = EDUAPI()->OData->Events->GetItem( $ebi->EventBooking['EventId'] ); |
||
205 | } |
||
206 | |||
207 | if ( ! empty( $ebi->EventBooking['ProgrammeBookingId'] ) ) { |
||
208 | $programme_booking_id = intval( $ebi->EventBooking['ProgrammeBookingId'] ); |
||
209 | $reference_id = $programme_booking_id; |
||
210 | |||
211 | $_event = EDUAPI()->OData->ProgrammeStarts->GetItem( $ebi->EventBooking['ProgrammeStartId'] ); |
||
212 | } |
||
213 | |||
214 | $rowExtraInfo = ""; |
||
0 ignored issues
–
show
|
|||
215 | |||
216 | if ( null != $_event ) { |
||
217 | if ( ! empty( $_event['City'] ) ) { |
||
218 | $rowExtraInfo .= ';' . $_event['City']; |
||
219 | } |
||
220 | |||
221 | if ( ! empty( $_event['StartDate'] ) ) { |
||
222 | $rowExtraInfo .= ';' . date( "Y-m-d", strtotime( $_event['StartDate'] ) ); |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
The string literal
Y-m-d does not require double quotes, as per coding-style, please use single quotes.
PHP provides two ways to mark string literals. Either with single quotes String literals in single quotes on the other hand are evaluated very literally and the only two
characters that needs escaping in the literal are the single quote itself ( Double quoted string literals may contain other variables or more complex escape sequences. <?php
$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";
print $doubleQuoted;
will print an indented: If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear. For more information on PHP string literals and available escape sequences see the PHP core documentation. ![]() |
|||
223 | } |
||
224 | |||
225 | if ( ! empty( $_event['EndDate'] ) ) { |
||
226 | $rowExtraInfo .= ';' . date( "Y-m-d", strtotime( $_event['EndDate'] ) ); |
||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
The string literal
Y-m-d does not require double quotes, as per coding-style, please use single quotes.
PHP provides two ways to mark string literals. Either with single quotes String literals in single quotes on the other hand are evaluated very literally and the only two
characters that needs escaping in the literal are the single quote itself ( Double quoted string literals may contain other variables or more complex escape sequences. <?php
$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";
print $doubleQuoted;
will print an indented: If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear. For more information on PHP string literals and available escape sequences see the PHP core documentation. ![]() |
|||
227 | } |
||
228 | } |
||
229 | |||
230 | $confirmation_url = add_query_arg( |
||
231 | array( |
||
232 | 'klarna_order_id' => '{checkout.order.id}', |
||
233 | 'booking_id' => $booking_id, |
||
234 | 'programme_booking_id' => $programme_booking_id, |
||
235 | 'edu-valid-form' => wp_create_nonce( 'edu-booking-confirm' ), |
||
236 | 'act' => 'paymentCompleted', |
||
237 | ), |
||
238 | $current_url |
||
239 | ); |
||
240 | |||
241 | $push_url = add_query_arg( |
||
242 | array( |
||
243 | 'klarna_order_id' => '{checkout.order.id}', |
||
244 | 'booking_id' => $booking_id, |
||
245 | 'programme_booking_id' => $programme_booking_id, |
||
246 | 'status' => 'push', |
||
247 | ), |
||
248 | $current_url |
||
249 | ); |
||
250 | |||
251 | $merchant['checkout_uri'] = $current_url; |
||
252 | $merchant['confirmation_uri'] = $confirmation_url; |
||
253 | $merchant['push_uri'] = $push_url; |
||
254 | |||
255 | $create['merchant'] = $merchant; |
||
256 | |||
257 | $create['merchant_reference'] = array(); |
||
258 | $create['merchant_reference']['orderid1'] = $reference_id; |
||
259 | $create['merchant_reference']['orderid2'] = $reference_id; |
||
260 | |||
261 | $create['cart'] = array(); |
||
262 | $create['cart']['items'] = array(); |
||
263 | |||
264 | foreach ( $ebi->EventBooking['OrderRows'] as $order_row ) { |
||
265 | $cart_item = array(); |
||
266 | |||
267 | $cart_item['reference'] = $order_row['ItemNumber']; |
||
268 | $cart_item['name'] = $order_row['Description'] . $rowExtraInfo; |
||
269 | $cart_item['quantity'] = intval( $order_row['Quantity'] ); |
||
270 | |||
271 | if ( ! $order_row['PriceIncVat'] ) { |
||
272 | $price_per_unit = $order_row['PricePerUnit'] * ( 1 + ( $order_row['VatPercent'] / 100 ) ) * 100; |
||
273 | } else { |
||
274 | $price_per_unit = $order_row['PricePerUnit'] * 100; |
||
275 | } |
||
276 | |||
277 | $cart_item['unit_price'] = $price_per_unit; |
||
278 | $cart_item['tax_rate'] = intval( $order_row['VatPercent'] * 100 ); |
||
279 | $cart_item['discount_rate'] = intval( $order_row['DiscountPercent'] * 100 ); |
||
280 | |||
281 | $create['cart']['items'][] = $cart_item; |
||
282 | } |
||
283 | |||
284 | try { |
||
285 | $connector = Klarna_Checkout_Connector::create( |
||
286 | $shared_secret, |
||
287 | $checkout_url |
||
288 | ); |
||
289 | |||
290 | $order = new Klarna_Checkout_Order( $connector ); |
||
291 | $order->create( $create ); |
||
292 | |||
293 | $order->fetch(); |
||
294 | |||
295 | $order_id = $order['id']; |
||
296 | EDU()->session['klarna-order-id'] = $order_id; |
||
297 | |||
298 | return $order; |
||
299 | } catch ( Klarna_Checkout_ApiErrorException $ex ) { |
||
300 | EDU()->write_debug( $ex->getMessage() ); |
||
301 | EDU()->write_debug( $ex->getPayload() ); |
||
302 | |||
303 | return null; |
||
304 | } |
||
305 | } |
||
306 | |||
307 | public function process_paymentstatus() { |
||
308 | if ( ! empty( $_GET['klarna_order_id'] ) && ! empty( $_GET['status'] ) ) { |
||
309 | $checkout_url = ! checked( $this->get_option( 'test_mode', 'no' ), '1', false ) ? Klarna_Checkout_Connector::BASE_URL : Klarna_Checkout_Connector::BASE_TEST_URL; |
||
310 | $shared_secret = $this->get_option( 'shared_secret', '' ); |
||
311 | |||
312 | try { |
||
313 | $connector = Klarna_Checkout_Connector::create( |
||
314 | $shared_secret, |
||
315 | $checkout_url |
||
316 | ); |
||
317 | |||
318 | $order_id = $_GET['klarna_order_id']; |
||
319 | |||
320 | $order = new Klarna_Checkout_Order( $connector, $order_id ); |
||
321 | |||
322 | $order->fetch(); |
||
323 | |||
324 | $booking_id = intval( $_GET['booking_id'] ); |
||
325 | $programme_booking_id = intval( $_GET['programme_booking_id'] ); |
||
326 | |||
327 | |||
328 | if ( 'checkout_complete' === $order['status'] ) { |
||
329 | |||
330 | $patch_booking = new stdClass(); |
||
331 | $patch_booking->Paid = true; |
||
332 | |||
333 | // 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) |
||
334 | $patch_booking->PaymentMethodId = 2; |
||
335 | |||
336 | if ( $booking_id > 0 ) { |
||
337 | EDUAPI()->REST->Booking->PatchBooking( |
||
338 | $booking_id, |
||
339 | $patch_booking |
||
340 | ); |
||
341 | } |
||
342 | |||
343 | if ( $programme_booking_id > 0 ) { |
||
344 | EDUAPI()->REST->ProgrammeBooking->PatchBooking( |
||
345 | $programme_booking_id, |
||
346 | $patch_booking |
||
347 | ); |
||
348 | } |
||
349 | |||
350 | $update = array(); |
||
351 | $update['status'] = 'created'; |
||
352 | $order->update( $update ); |
||
353 | } |
||
354 | exit( 0 ); |
||
355 | } catch ( Klarna_Checkout_ApiErrorException $ex ) { |
||
356 | EDU()->write_debug( $ex->getMessage() ); |
||
357 | EDU()->write_debug( $ex->getPayload() ); |
||
358 | exit( 1 ); |
||
359 | } |
||
360 | } |
||
361 | } |
||
362 | } |
||
363 | } |
||
364 |
PHP provides two ways to mark string literals. Either with single quotes
'literal'
or with double quotes"literal"
. The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (
\'
) and the backslash (\\
). Every other character is displayed as is.Double quoted string literals may contain other variables or more complex escape sequences.
will print an indented:
Single is Value
If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.
For more information on PHP string literals and available escape sequences see the PHP core documentation.