PluginProbe ʕ •ᴥ•ʔ
Paid Membership Plugin, Ecommerce, User Registration Form, Login Form, User Profile & Restrict Content – ProfilePress / trunk
Paid Membership Plugin, Ecommerce, User Registration Form, Login Form, User Profile & Restrict Content – ProfilePress vtrunk
4.16.19 4.16.18 4.16.17 4.16.16 trunk 1.0 1.0.1 1.0.2 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5a 1.1.6 1.1.7 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.4 1.4.1 1.4.2 1.5 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.7 1.7.1 1.7.2 1.8 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.1.9 2.2.10 2.2.11 2.2.12 2.2.13 2.2.14 2.2.15 2.2.16 2.2.2 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 3.0 3.1 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.18 3.1.19 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.10 3.2.11 3.2.12 3.2.13 3.2.14 3.2.15 3.2.16 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 4.0.0 4.0.1 4.0.2 4.0.3 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.10.0 4.10.1 4.10.2 4.10.3 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.13.3 4.13.4 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.15.0 4.15.1 4.15.10 4.15.11 4.15.12 4.15.13 4.15.14 4.15.15 4.15.16 4.15.17 4.15.18 4.15.19 4.15.2 4.15.20 4.15.20.1 4.15.21 4.15.22 4.15.23 4.15.24 4.15.25 4.15.3 4.15.4 4.15.5 4.15.6 4.15.7 4.15.8 4.15.9 4.16.0 4.16.1 4.16.10 4.16.11 4.16.12 4.16.13 4.16.14 4.16.15 4.16.2 4.16.3 4.16.4 4.16.5 4.16.6 4.16.7 4.16.8 4.16.9 4.2.0 4.3.0 4.3.1 4.3.2 4.4.0 4.4.1 4.5.0 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.7.0 4.8.0 4.9.0
wp-user-avatar / src / Membership / Controllers / CheckoutController.php
wp-user-avatar / src / Membership / Controllers Last commit date
BaseController.php 3 years ago CheckoutController.php 2 months ago CheckoutResponse.php 3 years ago CheckoutSessionData.php 3 years ago CheckoutTrait.php 2 months ago FrontendController.php 2 weeks ago SubscriptionPlanController.php 2 months ago index.php 3 years ago
CheckoutController.php
598 lines
1 <?php
2
3 namespace ProfilePress\Core\Membership\Controllers;
4
5 use ProfilePress\Core\Classes\LoginAuth;
6 use ProfilePress\Core\Membership\Emails\SubscriptionCancelledNotification;
7 use ProfilePress\Core\Membership\Emails\SubscriptionExpiredNotification;
8 use ProfilePress\Core\Membership\Models\Coupon\CouponFactory;
9 use ProfilePress\Core\Membership\Models\Customer\CustomerFactory;
10 use ProfilePress\Core\Membership\Models\Group\GroupFactory;
11 use ProfilePress\Core\Membership\Models\Order\OrderEntity;
12 use ProfilePress\Core\Membership\Models\Order\OrderFactory;
13 use ProfilePress\Core\Membership\Models\Order\OrderType;
14 use ProfilePress\Core\Membership\Models\Plan\PlanEntity;
15 use ProfilePress\Core\Membership\Models\Subscription\SubscriptionFactory;
16 use ProfilePress\Core\Membership\PaymentMethods\PaymentMethods;
17 use ProfilePress\Core\Membership\PaymentMethods\StoreGateway;
18 use ProfilePress\Core\Membership\Repositories\OrderRepository;
19 use ProfilePress\Core\Membership\Repositories\SubscriptionRepository;
20 use ProfilePress\Core\Membership\Services\EUVATChecker\EuVatApi;
21 use ProfilePress\Core\Membership\Services\OrderService;
22 use ProfilePress\Core\Membership\Services\TaxService;
23
24 class CheckoutController extends BaseController
25 {
26 use CheckoutTrait;
27
28 public function __construct()
29 {
30 add_action('wp_ajax_nopriv_ppress_process_checkout_login', [$this, 'process_checkout_login']);
31
32 add_action('wp_ajax_ppress_process_checkout', [$this, 'process_checkout']);
33 add_action('wp_ajax_nopriv_ppress_process_checkout', [$this, 'process_checkout']);
34
35 add_action('wp_ajax_ppress_checkout_apply_discount', [$this, 'apply_discount']);
36 add_action('wp_ajax_nopriv_ppress_checkout_apply_discount', [$this, 'apply_discount']);
37
38 add_action('wp_ajax_ppress_checkout_remove_discount', [$this, 'remove_discount']);
39 add_action('wp_ajax_nopriv_ppress_checkout_remove_discount', [$this, 'remove_discount']);
40
41 add_action('wp_ajax_ppress_update_order_review', [$this, 'update_order_review']);
42 add_action('wp_ajax_nopriv_ppress_update_order_review', [$this, 'update_order_review']);
43
44 add_action('wp_ajax_ppress_contextual_state_field', [$this, 'contextual_state_field']);
45 add_action('wp_ajax_nopriv_ppress_contextual_state_field', [$this, 'contextual_state_field']);
46
47 add_action('wp', [$this, 'validate_checkout_coupon']);
48 add_action('wp', [$this, 'redirect_to_referrer_after_checkout']);
49 }
50
51 public function contextual_state_field()
52 {
53 check_ajax_referer('ppress_process_checkout', 'csrf');
54
55 $country = ppressPOST_var('country', '');
56 $nameAttr = ppressPOST_var('name', '');
57 $idAttr = ppressPOST_var('id', '');
58 $classAttr = ppressPOST_var('class', '');
59
60 $states = ! empty($country) ? ppress_array_of_world_states(sanitize_text_field($country)) : [];
61
62 ob_start();
63
64 if ( ! empty($states)) {
65
66 printf('<select name="%s" id="%s" class="%s" autocomplete="address-level1" required="required">', $nameAttr, $idAttr, $classAttr);
67 echo '<option value="">&mdash;&mdash;&mdash;</option>';
68 foreach ($states as $id => $label) {
69 printf('<option value="%s">%s</option>', $id, $label);
70 }
71 echo '</select>';
72
73 } else {
74
75 printf(
76 '<input name="%s" type="text" id="%s" class="%s" autocomplete="address-level1" required="required">',
77 $nameAttr, $idAttr, $classAttr
78 );
79 }
80
81 wp_send_json_success(ob_get_clean());
82 }
83
84 public function validate_checkout_coupon()
85 {
86 if ( ! ppress_is_checkout()) return;
87
88 $plan_id = (int)ppressGET_var('plan', 0);
89
90 $coupon = ppress_session()->get(CheckoutSessionData::COUPON_CODE);
91
92 if (isset($coupon['coupon_code'])) {
93
94 $coupon = CouponFactory::fromCode($coupon['coupon_code']);
95
96 if ( ! $coupon->is_valid($plan_id)) {
97 ppress_session()->set(CheckoutSessionData::COUPON_CODE, null);
98 }
99 }
100 }
101
102 public function process_checkout_login()
103 {
104 $nonce_check = check_ajax_referer('ppress_process_checkout', 'ppress_checkout_nonce', false);
105
106 if (false === $nonce_check) {
107 wp_send_json_error(
108 $this->alert_message(
109 esc_html__('Error processing login. Nonce failed', 'wp-user-avatar')
110 )
111 );
112 }
113
114 $response = LoginAuth::login_auth(
115 trim($_POST['ppmb_user_login']),
116 $_POST['ppmb_user_pass'],
117 true
118 );
119
120 if (is_wp_error($response)) {
121 wp_send_json_error($this->alert_message($response->get_error_message()));
122 }
123
124 wp_send_json_success();
125 }
126
127 public function apply_discount()
128 {
129 try {
130
131 $nonce_check = check_ajax_referer('ppress_process_checkout', 'ppress_checkout_nonce', false);
132
133 if (false === $nonce_check) {
134
135 throw new \Exception(
136 esc_html__('Error applying coupon code. Nonce failed', 'wp-user-avatar')
137 );
138 }
139
140 if (empty($_POST['coupon_code'])) {
141
142 throw new \Exception(
143 esc_html__('Please enter a coupon code.', 'wp-user-avatar')
144 );
145 }
146
147 if (empty($_POST['plan_id'])) {
148
149 throw new \Exception(
150 esc_html__('Please enter a plan ID.', 'wp-user-avatar')
151 );
152 }
153
154 $plan_id = absint($_POST['plan_id']);
155 $coupon_code = sanitize_text_field($_POST['coupon_code']);
156
157 $coupon = CouponFactory::fromCode($coupon_code);
158
159 if ( ! $coupon->exists()) {
160
161 throw new \Exception(
162 sprintf(esc_html__('Coupon code "%s" not found.', 'wp-user-avatar'), $coupon_code)
163 );
164 }
165
166 $order_type = CheckoutSessionData::get_order_type($plan_id);
167
168 if ( ! $order_type) $order_type = OrderType::NEW_ORDER;
169
170 if ( ! $coupon->is_valid($plan_id, $order_type)) {
171
172 throw new \Exception(
173 esc_html__('Sorry, this coupon is not valid.', 'wp-user-avatar')
174 );
175 }
176
177 ppress_session()->set(CheckoutSessionData::COUPON_CODE, [
178 'plan_id' => $plan_id,
179 'coupon_code' => $coupon->code,
180 ]);
181
182 wp_send_json_success();
183
184 } catch (\Exception $e) {
185
186 wp_send_json_error(
187 $this->alert_message($e->getMessage())
188 );
189 }
190 }
191
192 public function remove_discount()
193 {
194 try {
195
196 check_ajax_referer('ppress_process_checkout', 'ppress_checkout_nonce');
197
198 if (empty($_POST['plan_id'])) {
199
200 throw new \Exception(
201 esc_html__('Please enter a plan ID.', 'wp-user-avatar')
202 );
203 }
204
205 $plan_id = absint($_POST['plan_id']);
206
207 $session_coupon = ppress_session()->get(CheckoutSessionData::COUPON_CODE);
208
209 if (isset($session_coupon['plan_id'], $session_coupon['coupon_code']) && $plan_id == $session_coupon['plan_id']) {
210 ppress_session()->set(CheckoutSessionData::COUPON_CODE, null);
211 }
212
213 wp_send_json_success();
214
215 } catch (\Exception $e) {
216
217 wp_send_json_error(
218 $this->alert_message($e->getMessage())
219 );
220 }
221 }
222
223 public function process_checkout()
224 {
225 try {
226
227 $nonce_check = check_ajax_referer('ppress_process_checkout', 'ppress_checkout_nonce', false);
228
229 if (false === $nonce_check) {
230 throw new \Exception(esc_html__('Error processing checkout. Nonce failed', 'wp-user-avatar'));
231 }
232
233 $GLOBALS['ppress_checkout_post_data'] = $_POST;
234
235 $_POST = $this->cleanup_posted_data($_POST);
236
237 if ( ! isset($_POST['_ppress_timestamp']) || intval($_POST['_ppress_timestamp']) > (time() - 2)) {
238 throw new \Exception('spam');
239 }
240
241 if ( ! isset($_POST['_ppress_honeypot']) || ! empty($_POST['_ppress_honeypot'])) {
242 throw new \Exception('spam');
243 }
244
245 $plan_id = (int)$_POST['plan_id'];
246
247 $change_plan_sub_id = (int)$_POST['change_plan_sub_id'];
248
249 if (empty($change_plan_sub_id) && $plan_id > 0) {
250
251 if ( ! ppress_get_plan($plan_id)->is_active()) {
252 throw new \Exception(
253 esc_html__('Invalid membership plan.', 'wp-user-avatar')
254 );
255 }
256 }
257
258 $checkout_errors = apply_filters('ppress_checkout_validation', new \WP_Error(), $plan_id, $_POST);
259
260 if (is_wp_error($checkout_errors) && $checkout_errors->get_error_code() != '') {
261 throw new \Exception($checkout_errors->get_error_message());
262 }
263
264 if ( ! empty(ppress_settings_by_key('terms_page_id')) && empty($_POST['ppress-terms'])) {
265 throw new \Exception(
266 esc_html__('Please read and accept the terms and conditions to proceed with your order.', 'wp-user-avatar')
267 );
268 }
269
270 $changePlanSub = SubscriptionFactory::fromId($change_plan_sub_id);
271
272 if ( ! empty($change_plan_sub_id) && ! $changePlanSub->exists()) {
273 throw new \Exception(esc_html__('Invalid subscription ID provided for plan change.', 'wp-user-avatar'));
274 }
275
276 $cart_vars = OrderService::init()->checkout_order_calculation([
277 'plan_id' => $plan_id,
278 'coupon_code' => CheckoutSessionData::get_coupon_code($plan_id),
279 'tax_rate' => CheckoutSessionData::get_tax_rate($plan_id),
280 'change_plan_sub_id' => $change_plan_sub_id
281 ]);
282
283 $is_free_checkout = OrderService::init()->is_free_checkout($cart_vars);
284
285 $payment_method = PaymentMethods::get_instance()->get_by_id(ppressPOST_var('ppress_payment_method', ''));
286
287 if ((empty($_POST['ppress_payment_method']) || ! $payment_method) && $is_free_checkout === false) {
288
289 throw new \Exception(
290 esc_html__('No payment method selected. Please try again.', 'wp-user-avatar')
291 );
292 }
293
294 if ($is_free_checkout) {
295 add_filter('ppress_checkout_billing_validation', '__return_false');
296 } else {
297
298 $validation_response = $payment_method->validate_fields();
299
300 if (is_wp_error($validation_response)) {
301 throw new \Exception($validation_response->get_error_message());
302 }
303 }
304
305 $customer_id = $this->register_update_user();
306
307 if (is_wp_error($customer_id)) {
308 throw new \Exception(json_encode($customer_id->get_error_messages()));
309 }
310
311 if (
312 $changePlanSub->exists() &&
313 $customer_id !== $changePlanSub->get_customer_id()) {
314 throw new \Exception(
315 esc_html__('You are not allowed to switch from this plan.', 'wp-user-avatar')
316 );
317 }
318
319 $order_id = $this->create_order($customer_id, $cart_vars);
320
321 if (is_wp_error($order_id)) {
322 throw new \Exception($order_id->get_error_message());
323 }
324
325 $subscription_id = $this->create_subscription($customer_id, $cart_vars);
326
327 if (is_wp_error($subscription_id)) {
328 throw new \Exception($subscription_id->get_error_message());
329 }
330
331 do_action('ppress_process_checkout_after_order_subscription_creation', $order_id, $subscription_id);
332
333 SubscriptionRepository::init()->updateColumn($subscription_id, 'parent_order_id', $order_id);
334 OrderRepository::init()->updateColumn($order_id, 'subscription_id', $subscription_id);
335
336 if ( ! $payment_method || ! $payment_method->get_id()) {
337 $payment_method = StoreGateway::get_instance();
338 }
339
340 $this->save_eu_vat_details($payment_method->id, $order_id);
341
342 if ($is_free_checkout) {
343 OrderFactory::fromId($order_id)->complete_order();
344 SubscriptionFactory::fromId($subscription_id)->activate_subscription();
345
346 $process_payment = (new CheckoutResponse())->set_is_success(true);
347
348 } else {
349
350 if ($changePlanSub->exists() && $changePlanSub->get_customer_id() == $customer_id) {
351
352 // do not send subscription cancelled email
353 remove_action('ppress_subscription_cancelled', [SubscriptionCancelledNotification::init(), 'dispatch_email']);
354 remove_action('ppress_subscription_expired', [SubscriptionExpiredNotification::init(), 'dispatch_email']);
355
356 $changePlanSub->cancel(true);
357 $changePlanSub->expire();
358
359 SubscriptionFactory::fromId($subscription_id)->update_meta('_upgraded_from_sub_id', $changePlanSub->get_id());
360 $changePlanSub->update_meta('_upgraded_to_sub_id', $subscription_id);
361 }
362
363 /** @var CheckoutResponse $process_payment */
364 $process_payment = $payment_method->process_payment(
365 $order_id,
366 $subscription_id,
367 $customer_id
368 );
369 }
370
371 $order = OrderFactory::fromId($order_id);
372
373 $is_checkout_autologin = ppress_settings_by_key('enable_checkout_autologin') == 'true';
374
375 if (apply_filters('ppress_autologin_after_checkout', $is_checkout_autologin, $order, $subscription_id)) {
376
377 if ( ! is_user_logged_in()) {
378 $user_id = CustomerFactory::fromId($customer_id)->get_user_id();
379 wp_set_auth_cookie($user_id, true);
380 wp_set_current_user($user_id);
381 }
382 }
383
384 wp_send_json([
385 'success' => $process_payment->is_success,
386 'redirect_url' => $process_payment->redirect_url,
387 'gateway_response' => $process_payment->gateway_response,
388 'error_message' => $this->alert_message($process_payment->error_message),
389 'order_success_url' => ppress_get_success_url($order->order_key, $order->payment_method),
390 ]);
391
392 } catch (\Exception $e) {
393
394 $error_message = ppress_is_json($e->getMessage()) ? json_decode($e->getMessage(), true) : $e->getMessage();
395
396 ppress_log_error($error_message);
397
398 wp_send_json_error(
399 $this->alert_message($error_message)
400 );
401 }
402 }
403
404 /**
405 * @param $country_code
406 * @param $country_state_code
407 * @param $vat_number
408 * @param PlanEntity $planObj
409 *
410 * @return float|int|string
411 * @throws \Exception
412 */
413 private function get_checkout_tax_rate($country_code, $country_state_code, $vat_number, $planObj)
414 {
415 if ( ! TaxService::init()->is_tax_enabled()) return 0;
416
417 if (TaxService::init()->calculate_tax_based_on_setting() == 'base') {
418 $base_country = ppress_business_country();
419 if ( ! empty($base_country)) {
420 $country_code = $base_country;
421 $country_state_code = ppress_business_state();
422 }
423 }
424
425 $tax_rate = TaxService::init()->get_country_tax_rate($country_code, $country_state_code);
426
427 if (TaxService::init()->is_eu_vat_enabled() && TaxService::init()->is_eu_countries($country_code)) {
428
429 $business_country = ppress_business_country();
430 $same_country_rule_setting = TaxService::init()->eu_vat_same_country_rule_setting();
431
432 if ($business_country == $country_code && $same_country_rule_setting == 'charge_always') {
433 return $tax_rate;
434 }
435
436 if ($business_country == $country_code && $same_country_rule_setting == 'no_charge') {
437 return 0;
438 }
439
440 if (empty($vat_number)) return $tax_rate;
441
442 $session_data = [
443 'plan_id' => $planObj->id,
444 'vat_number' => $vat_number,
445 'country_code' => $country_code
446 ];
447
448 if (TaxService::init()->is_vat_number_validation_active()) {
449
450 $response = EuVatApi::check_vat($vat_number, $country_code);
451
452 if ( ! $response->is_valid()) {
453 throw new \Exception($response->get_error_message(), $response->error);
454 }
455
456 $session_data['company_name'] = $response->name;
457 $session_data['company_address'] = $response->address;
458 $session_data['is_valid'] = $response->is_valid();
459 }
460
461 $session_data['reverse_charged'] = true;
462
463 ppress_session()->set(CheckoutSessionData::EU_VAT_NUMBER, $session_data);
464
465 $tax_rate = 0;
466 }
467
468 return $tax_rate;
469 }
470
471 public function update_order_review()
472 {
473 check_ajax_referer('ppress_process_checkout', 'csrf');
474
475 try {
476
477 if (empty($_POST['plan_id'])) {
478
479 throw new \Exception(
480 esc_html__('Please enter a plan ID.', 'wp-user-avatar')
481 );
482 }
483
484 global $cart_vars;
485
486 parse_str($_POST['post_data'], $post_data);
487
488 $GLOBALS['ppress_checkout_post_data'] = $post_data;
489
490 $planObj = ppress_get_plan(absint($_POST['plan_id']));
491
492 $groupObj = GroupFactory::fromId(absint(ppress_var($post_data, 'group_id', 0)));
493
494 $changePlanSubId = false;
495
496 // if group selector input is changed/ticked/checked/toggled
497 if (ppressPOST_var('isChangePlanUpdate') == 'true') {
498
499 $changePlanSubId = absint(ppress_var($post_data, 'change_plan_sub_id', 0));
500
501 $selectedGroupPlanId = absint($post_data['group_selector']);
502
503 if ($selectedGroupPlanId > 0) $planObj = ppress_get_plan($selectedGroupPlanId);
504 }
505
506 $country_code = sanitize_text_field(ppressPOST_var('country', '', true));
507 $country_state_code = sanitize_text_field(ppressPOST_var('state', '', true));
508 $vat_number = sanitize_text_field(ppressPOST_var('vat_number', '', true));
509
510 $tax_rate = $this->get_checkout_tax_rate($country_code, $country_state_code, $vat_number, $planObj);
511
512 ppress_session()->set(CheckoutSessionData::TAX_RATE, [
513 'plan_id' => $planObj->id,
514 'tax_rate' => $tax_rate,
515 'country' => $country_code,
516 'state' => $country_state_code
517 ]);
518
519 $cart_vars = OrderService::init()->checkout_order_calculation([
520 'plan_id' => $planObj->id,
521 'coupon_code' => CheckoutSessionData::get_coupon_code($planObj->id),
522 'tax_rate' => CheckoutSessionData::get_tax_rate($planObj->id),
523 'change_plan_sub_id' => $changePlanSubId
524 ]);
525
526 if (ppressPOST_var('isChangePlanUpdate') == 'true') {
527
528 ob_start();
529 echo '<div class="ppress-checkout__form">';
530 ppress_render_view('checkout/form-checkout', [
531 'groupObj' => $groupObj,
532 'planObj' => $planObj,
533 'changePlanSubId' => $changePlanSubId
534 ]);
535 echo '</div>';
536
537 $fragments = ['.ppress-checkout__form' => ob_get_clean()];
538
539 } else {
540
541 ob_start();
542 ppress_render_view(
543 'checkout/form-checkout-sidebar', [
544 'plan' => $planObj,
545 'cart_vars' => $cart_vars,
546 'isChangePlanIdSelected' => false
547 ]
548 );
549 $checkout_sidebar_html = ob_get_clean();
550
551 ob_start();
552 ppress_render_view('checkout/form-payment-methods', [
553 'plan' => $planObj,
554 'cart_vars' => $cart_vars
555 ]);
556 $checkout_payment_methods_html = ob_get_clean();
557
558 ob_start();
559 ppress_render_view('checkout/form-checkout-submit-btn', [
560 'order_total' => $cart_vars->total,
561 'plan' => $planObj
562 ]);
563 $checkout_submit_btn = ob_get_clean();
564
565 $fragments = [
566 '.ppress-checkout_order_summary-wrap' => $checkout_sidebar_html,
567 '.ppress-checkout_payment_methods-wrap' => $checkout_payment_methods_html,
568 '.ppress-checkout-submit' => $checkout_submit_btn
569 ];
570 }
571
572 wp_send_json_success(
573 apply_filters('ppress_update_order_review_response', [
574 'fragments' => apply_filters('ppress_update_order_review_fragments', $fragments)
575 ], $cart_vars, $planObj)
576 );
577
578 } catch (\Exception $e) {
579
580 wp_send_json_error(
581 $this->alert_message($e->getMessage())
582 );
583 }
584 }
585
586 public function redirect_to_referrer_after_checkout()
587 {
588 if (ppress_is_redirect_to_referrer_after_checkout()) {
589
590 $referrer = ppress_session()->get('ppress_checkout_referrer');
591
592 if ( ! empty($referrer) && ppress_is_success_page()) {
593 wp_safe_redirect($referrer);
594 exit;
595 }
596 }
597 }
598 }