PluginProbe ʕ •ᴥ•ʔ
Paid Membership Plugin, Ecommerce, User Registration Form, Login Form, User Profile & Restrict Content – ProfilePress / 4.17.0
Paid Membership Plugin, Ecommerce, User Registration Form, Login Form, User Profile & Restrict Content – ProfilePress v4.17.0
4.17.0 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 4 years ago CheckoutController.php 6 days ago CheckoutResponse.php 4 years ago CheckoutSessionData.php 3 years ago CheckoutTrait.php 3 months ago FrontendController.php 1 month ago SubscriptionPlanController.php 3 months ago index.php 3 years ago
CheckoutController.php
597 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 throw new \Exception(esc_html__('Please enter a plan ID.', 'wp-user-avatar'));
479 }
480
481 global $cart_vars;
482
483 parse_str($_POST['post_data'], $post_data);
484
485 $GLOBALS['ppress_checkout_post_data'] = $post_data;
486
487 $planObj = ppress_get_plan(absint($_POST['plan_id']));
488
489 $groupObj = GroupFactory::fromId(absint(ppress_var($post_data, 'group_id', 0)));
490
491 $changePlanSubId = false;
492
493 // if group selector input is changed/ticked/checked/toggled
494 if (ppressPOST_var('isChangePlanUpdate') == 'true') {
495
496 $changePlanSubId = absint(ppress_var($post_data, 'change_plan_sub_id', 0));
497
498 $selectedGroupPlanId = absint($post_data['group_selector']);
499
500 if ($selectedGroupPlanId > 0) $planObj = ppress_get_plan($selectedGroupPlanId);
501 }
502
503 $country_code = sanitize_text_field(ppressPOST_var('country', '', true));
504 $country_state_code = sanitize_text_field(ppressPOST_var('state', '', true));
505 $vat_number = sanitize_text_field(ppressPOST_var('vat_number', '', true));
506
507 $tax_rate = $this->get_checkout_tax_rate($country_code, $country_state_code, $vat_number, $planObj);
508
509 ppress_session()->set(CheckoutSessionData::TAX_RATE, [
510 'plan_id' => $planObj->id,
511 'tax_rate' => $tax_rate,
512 'country' => $country_code,
513 'state' => $country_state_code
514 ]);
515
516 $cart_vars = OrderService::init()->checkout_order_calculation([
517 'plan_id' => $planObj->id,
518 'coupon_code' => CheckoutSessionData::get_coupon_code($planObj->id),
519 'tax_rate' => CheckoutSessionData::get_tax_rate($planObj->id),
520 'change_plan_sub_id' => $changePlanSubId
521 ]);
522
523 if (ppressPOST_var('isChangePlanUpdate') == 'true') {
524
525 ob_start();
526 echo '<div class="ppress-checkout__form">';
527 ppress_render_view('checkout/form-checkout', [
528 'groupObj' => $groupObj,
529 'planObj' => $planObj,
530 'changePlanSubId' => $changePlanSubId
531 ]);
532 echo '</div>';
533
534 $fragments = ['.ppress-checkout__form' => ob_get_clean()];
535
536 } else {
537
538 ob_start();
539 ppress_render_view(
540 'checkout/form-checkout-sidebar', [
541 'plan' => $planObj,
542 'cart_vars' => $cart_vars,
543 'isChangePlanIdSelected' => false
544 ]
545 );
546 $checkout_sidebar_html = ob_get_clean();
547
548 ob_start();
549 ppress_render_view('checkout/form-payment-methods', [
550 'plan' => $planObj,
551 'cart_vars' => $cart_vars
552 ]);
553 $checkout_payment_methods_html = ob_get_clean();
554
555 ob_start();
556 ppress_render_view('checkout/form-checkout-submit-btn', [
557 'order_total' => $cart_vars->total,
558 'plan' => $planObj
559 ]);
560 $checkout_submit_btn = ob_get_clean();
561
562 $fragments = [
563 '.ppress-checkout_order_summary-wrap' => $checkout_sidebar_html,
564 '.ppress-checkout_payment_methods-wrap' => $checkout_payment_methods_html,
565 '.ppress-checkout-submit' => $checkout_submit_btn
566 ];
567 }
568
569 do_action('ppress_update_order_review_actions', $post_data, $planObj, $cart_vars);
570
571 wp_send_json_success(
572 apply_filters('ppress_update_order_review_response', [
573 'fragments' => apply_filters('ppress_update_order_review_fragments', $fragments)
574 ], $cart_vars, $planObj)
575 );
576
577 } catch (\Exception $e) {
578
579 wp_send_json_error(
580 $this->alert_message($e->getMessage())
581 );
582 }
583 }
584
585 public function redirect_to_referrer_after_checkout()
586 {
587 if (ppress_is_redirect_to_referrer_after_checkout()) {
588
589 $referrer = ppress_session()->get('ppress_checkout_referrer');
590
591 if ( ! empty($referrer) && ppress_is_success_page()) {
592 wp_safe_redirect($referrer);
593 exit;
594 }
595 }
596 }
597 }