PluginProbe
Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More / 2.1.1
Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More v2.1.1
2.4.1 2.4.0 2.3.4 2.3.3 2.3.2 2.3.1 2.3.0 2.2.2 2.2.1 2.2.0 2.1.2 2.1.1 trunk 0.0.1 0.0.2 0.0.3 0.0.4 0.0.5 0.0.6 0.0.7 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 All 68 releases
better-payment / includes / Classes / Handler.php

Handler.php in Better Payment – Instant Payments, Donations, Fundraising with Subscriptions & More 2.1.1, at includes/Classes/Handler.php

1,660 lines 100.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Better_Payment\Lite\Classes;
4
5 use Better_Payment\Lite\Admin\DB;
6 use Better_Payment\Lite\Controller;
7 use Better_Payment\Lite\Classes\Helper;
8 use Better_Payment\Lite\Traits\Helper as TraitsHelper;
9
10 /**
11 * Exit if accessed directly
12 */
13 if (!defined('ABSPATH')) {
14 exit;
15 }
16
17 /**
18 * The plugin handler class
19 *
20 * @since 0.0.1
21 */
22 class Handler extends Controller{
23 use TraitsHelper;
24
25 /**
26 * PayPal button
27 *
28 * @since 0.0.1
29 */
30 public static function paypal_button( $widget_id = '' , $settings = [], $args = [] ) {
31 global $wp;
32
33 $args['extra_classes'] = ! empty( $args['extra_classes'] ) ? $args['extra_classes'] : '';
34 $args['extra_classes'] = is_array($args['extra_classes']) ? implode(' ', $args['extra_classes']) : $args['extra_classes'];
35 $args['button_text_default'] = ! empty( $args['button_text_default'] ) ? sanitize_text_field( $args['button_text_default'] ) : 'Proceed to Payment';
36
37 $paypal_button_text = ! empty( $settings["better_payment_form_form_buttons_paypal_button_text"] ) ? sanitize_text_field( $settings["better_payment_form_form_buttons_paypal_button_text"] ) : __( $args['button_text_default'], 'better-payment' );
38
39 $return_url = add_query_arg( $wp->query_vars, get_the_permalink() . '?better_payment_paypal_status=success&better_payment_widget_id=' . $widget_id );
40 $cancel_url = add_query_arg( $wp->query_vars, get_the_permalink() . '?better_payment_error_status=error&better_payment_widget_id=' . $widget_id );
41
42 ob_start();
43 $error_info = [
44 'business_email' => !empty($settings['better_payment_paypal_business_email'])
45 ];
46 ?>
47 <input type="hidden" name="return" value="<?php echo esc_url( $return_url ); ?>">
48 <input type="hidden" name="action" value="paypal_form_handle">
49 <input type="hidden" name="security" value="<?php echo esc_attr( wp_create_nonce('better-payment-paypal') ); ?>">
50 <input type="hidden" name="cancel_return" value="<?php echo esc_url( $cancel_url ); ?>">
51 <button data-paypal-info = <?php echo esc_attr(wp_json_encode( $error_info) ) ; ?> class="button is-medium is-fullwidth better-payment-paypal-bt <?php echo esc_attr( self::hide_show_payment_button_class($settings, 'paypal') ); ?> <?php echo esc_attr( $args['extra_classes'] ); ?>" ><?php echo esc_html( $paypal_button_text ); ?></button>
52
53 <?php
54 $paypal_button_html = ob_get_clean();
55 $paypal_button_html = apply_filters( 'better_payment/elementor/editor/paypal_button_html', $paypal_button_html, $widget_id, $settings );
56
57 echo $paypal_button_html;
58 }
59
60 /**
61 * Stripe button
62 *
63 * @since 0.0.1
64 */
65 public static function stripe_button( $widget_id = '' , $settings = [], $args = [] ) {
66 $args['extra_classes'] = ! empty( $args['extra_classes'] ) ? $args['extra_classes'] : '';
67 $args['extra_classes'] = is_array($args['extra_classes']) ? implode(' ', $args['extra_classes']) : $args['extra_classes'];
68 $args['button_text_default'] = ! empty( $args['button_text_default'] ) ? sanitize_text_field( $args['button_text_default'] ) : 'Proceed to Payment';
69
70 $stripe_button_text = ! empty( $settings["better_payment_form_form_buttons_stripe_button_text"] ) ? sanitize_text_field( $settings["better_payment_form_form_buttons_stripe_button_text"] ) : __( $args['button_text_default'], 'better-payment' );
71
72 ob_start();
73 ?>
74 <button class="button is-medium is-fullwidth better-payment-stripe-bt <?php echo esc_attr( self::hide_show_payment_button_class($settings, 'stripe') ); ?> <?php echo esc_attr( $args['extra_classes'] ); ?>" ><?php echo esc_html( $stripe_button_text ); ?></button>
75 <?php
76 $stripe_button_html = ob_get_clean();
77 $stripe_button_html = apply_filters( 'better_payment/elementor/editor/stripe_button_html', $stripe_button_html, $widget_id, $settings );
78
79 echo wp_kses( $stripe_button_html, (new Handler())->bp_allowed_tags() );
80 }
81
82 /**
83 * Paystack button
84 *
85 * @since 0.0.1
86 */
87 public static function paystack_button( $widget_id = '' , $settings = [], $args = [] ) {
88 $args['extra_classes'] = ! empty( $args['extra_classes'] ) ? $args['extra_classes'] : '';
89 $args['extra_classes'] = is_array($args['extra_classes']) ? implode(' ', $args['extra_classes']) : $args['extra_classes'];
90 $args['button_text_default'] = ! empty( $args['button_text_default'] ) ? sanitize_text_field( $args['button_text_default'] ) : 'Proceed to Payment';
91
92 $paystack_button_text = ! empty( $settings["better_payment_form_form_buttons_paystack_button_text"] ) ? sanitize_text_field( $settings["better_payment_form_form_buttons_paystack_button_text"] ) : __( $args['button_text_default'], 'better-payment' );
93
94 ob_start();
95 ?>
96 <button class="button is-medium is-fullwidth better-payment-paystack-bt <?php echo esc_attr( self::hide_show_payment_button_class($settings, 'paystack') ); ?> <?php echo esc_attr( $args['extra_classes'] ); ?>" ><?php echo esc_html( $paystack_button_text ); ?></button>
97 <?php
98 $paystack_button_html = ob_get_clean();
99 $paystack_button_html = apply_filters( 'better_payment/elementor/editor/paystack_button_html', $paystack_button_html, $widget_id, $settings );
100
101 echo wp_kses( $paystack_button_html, (new Handler())->bp_allowed_tags() );
102 }
103
104 public static function hide_show_payment_button_class( $settings, $type = 'paypal' ){
105 $button_hidden_class = 'is-hidden';
106 $types = ['paypal', 'stripe', 'paystack'];
107
108 if( ! in_array($type, $types) ){
109 return $button_hidden_class;
110 }
111
112 $is_type_enable = ! empty( $settings[ "better_payment_form_{$type}_enable" ] ) && 'yes' === $settings[ "better_payment_form_{$type}_enable" ];
113
114 if( ! $is_type_enable ){
115 return $button_hidden_class;
116 }
117
118 $is_paypal_enable = ! empty( $settings[ "better_payment_form_paypal_enable" ] ) && 'yes' === $settings[ "better_payment_form_paypal_enable" ];
119 $is_stripe_enable = ! empty( $settings[ "better_payment_form_stripe_enable" ] ) && 'yes' === $settings[ "better_payment_form_stripe_enable" ];
120 $is_paystack_enable = ! empty( $settings[ "better_payment_form_paystack_enable" ] ) && 'yes' === $settings[ "better_payment_form_paystack_enable" ];
121
122 switch( $type ){
123 case 'paypal':
124 $button_hidden_class = '';
125 break;
126
127 case 'stripe':
128 if( ( ! $is_paypal_enable ) ){
129 $button_hidden_class = '';
130 }
131
132 break;
133
134 case 'paystack':
135 if( ( ! $is_paypal_enable ) && ( ! $is_stripe_enable ) ){
136 $button_hidden_class = '';
137 }
138 break;
139
140 default:
141 break;
142 }
143
144 return $button_hidden_class;
145 }
146
147 /**
148 * Payment create in db
149 *
150 * @since 0.0.1
151 */
152 public static function payment_create( $data ) {
153 global $wpdb;
154 $table = "{$wpdb->prefix}better_payment";
155 $wpdb->insert( $table, $data );
156 if ( $wpdb->insert_id ) {
157 return $wpdb->insert_id;
158 } else {
159 return false;
160 }
161 }
162
163 /**
164 * Mamage response
165 *
166 * @since 0.0.1
167 */
168 public static function manage_response( $settings = [], $widget_id = '' ) {
169 $status = false;
170
171 //if widget id is different then return false
172 if ( !empty( $_REQUEST[ 'better_payment_widget_id' ] ) && $_REQUEST[ 'better_payment_widget_id' ] !== $widget_id ) {
173 return $status;
174 }
175
176 if ( !empty( $_REQUEST[ 'better_payment_error_status' ] ) ) {
177 // Determine order_id based on payment method
178 $order_id = '';
179 if ( !empty( $_REQUEST['better_payment_stripe_id'] ) ) {
180 $order_id = sanitize_text_field( $_REQUEST['better_payment_stripe_id'] );
181 } elseif ( !empty( $_REQUEST['better_payment_paystack_id'] ) ) {
182 $order_id = sanitize_text_field( $_REQUEST['better_payment_paystack_id'] );
183 } elseif ( !empty( $_REQUEST['better_payment_paypal_id'] ) ) {
184 $order_id = sanitize_text_field( $_REQUEST['better_payment_paypal_id'] );
185 }
186
187 // Fetch transaction data from database
188 $transaction_data = self::get_failed_transaction_data( $order_id );
189
190 self::failed_message_template( $settings, $transaction_data );
191 $redirection_url_error = ! empty( $settings['better_payment_form_error_page_url']['url'] ) ? esc_url( $settings['better_payment_form_error_page_url']['url'] ) : '';
192
193 if( $redirection_url_error ){
194 ?>
195 <script>
196 setTimeout(function(){
197 window.location.replace("<?php echo esc_url( $redirection_url_error ); ?>");
198 }, 2000);
199 </script>
200 <?php
201 }
202
203 return $status;
204 }
205
206 if ( !empty( $_REQUEST[ 'better_payment_paypal_status' ] ) && $_REQUEST[ 'better_payment_paypal_status' ] == 'success' ) {
207 $status = self::paypal_payment_success( $settings );
208 } elseif ( !empty( $_REQUEST[ 'better_payment_stripe_status' ] ) && $_REQUEST[ 'better_payment_stripe_status' ] == 'success' ) {
209 $status = self::stripe_payment_success( $settings );
210 } elseif ( !empty( $_REQUEST[ 'better_payment_paystack_status' ] ) && $_REQUEST[ 'better_payment_paystack_status' ] == 'success' ) {
211 $status = self::paystack_payment_success( $settings );
212 }
213
214 if ( $status ) {
215 self::success_message_template( $settings, $status );
216 $redirection_url_success = ! empty( $settings['better_payment_form_success_page_url']['url'] ) ? esc_url( $settings['better_payment_form_success_page_url']['url'] ) : '';
217
218 if( $redirection_url_success ){
219 ?>
220 <script>
221 setTimeout(function(){
222 window.location.replace("<?php echo esc_url( $redirection_url_success ); ?>");
223 }, 2000);
224 </script>
225 <?php
226 }
227 }
228 self::remove_arg();
229
230 return $status;
231 }
232
233 /**
234 * Paypal payment success
235 *
236 * @since 0.0.1
237 */
238 public static function paypal_payment_success( $settings = [] ) {
239 $data = $_REQUEST;
240 $frontend_data = [
241 'amount' => ! empty( $data['payment_gross'] ) ? floatval( $data['payment_gross'] ) : 0,
242 'email' => ! empty( $data['payer_email'] ) ? sanitize_email( $data['payer_email'] ) : '',
243 'transaction_id' => ! empty( $data[ 'txn_id' ] ) ? sanitize_text_field( $data[ 'txn_id' ] ) : '',
244 'currency' => ! empty( $data['mc_currency'] ) ? sanitize_text_field( $data['mc_currency'] ) : __( 'USD', 'better-payment' ),
245 'method' => 'paypal',
246 ];
247 if ( !empty( $data[ 'payment_status' ] ) && !empty( $data[ 'payer_id' ] ) && !empty( $data[ 'payer_status' ] ) ) {
248 global $wpdb;
249 $table = "{$wpdb->prefix}better_payment";
250 $results = $wpdb->get_row(
251 $wpdb->prepare( "SELECT id,form_fields_info,referer FROM $table WHERE order_id=%s and status is NULL limit 1", sanitize_text_field( $_REQUEST[ 'item_number' ] ) )
252 );
253
254 if ( !empty( $results->id ) ) {
255 $updated = $wpdb->update(
256 $table,
257 array(
258 'transaction_id' => sanitize_text_field( $data[ 'txn_id' ] ),
259 'status' => sanitize_text_field( $data[ 'payment_status' ] ),
260 'email' => sanitize_email( $data[ 'payer_email' ] ),
261 'customer_info' => maybe_serialize( $data ),
262 ),
263 array( 'ID' => $results->id )
264 );
265
266 if ( false !== $updated ) {
267 //Send email notification
268 if (
269 ( isset($settings[ 'better_payment_form_email_enable' ]) && $settings[ 'better_payment_form_email_enable' ] == 'yes' )
270 || ( $results->referer === 'elementor-form' )
271 ) {
272 $is_elementor_form = ! empty( $results->referer ) && $results->referer === 'elementor-form' ? 1 : 0;
273 self::better_email_notification(sanitize_text_field( $data[ 'txn_id' ] ), sanitize_email( $data[ 'payer_email' ] ), $settings, 'PayPal', $results->form_fields_info, $is_elementor_form);
274 }
275
276 return $frontend_data;
277 }
278 }
279 }else if($data['better_payment_paypal_status'] === 'success'){
280 return ( isset($data[ 'txn_id' ]) && !empty( sanitize_text_field( $data[ 'txn_id' ] ) ) ) ? $frontend_data : __('Payment under processing!', 'better-payment');
281 }
282 return false;
283 }
284
285 /**
286 * Stripe payment success
287 *
288 * @since 0.0.1
289 */
290 public static function stripe_payment_success( $settings = [] ) {
291
292 $data = $_REQUEST;
293
294 if ( !empty( $data[ 'better_payment_stripe_id' ] ) ) {
295 global $wpdb;
296 $table = "{$wpdb->prefix}better_payment";
297 $results = $wpdb->get_row(
298 $wpdb->prepare( "SELECT id, obj_id, amount, transaction_id, currency, form_fields_info, referer FROM $table WHERE order_id=%s and status = 'unpaid' limit 1", sanitize_text_field( $data[ 'better_payment_stripe_id' ] ) )
299 );
300
301 if ( !empty( $results->obj_id ) && !empty( $settings[ 'better_payment_stripe_secret_key' ] ) ) {
302 $header = array(
303 'Authorization' => 'Basic ' . base64_encode( sanitize_text_field( $settings[ 'better_payment_stripe_secret_key' ] ) . ':' ),
304 'Stripe-Version' => '2019-05-16',
305 );
306
307 $request = [
308 'expand' => [
309 'subscription.latest_invoice.payment_intent',
310 'payment_intent'
311 ]
312 ];
313 $form_fields_info = maybe_unserialize($results->form_fields_info);
314 $is_payment_recurring = ! empty( $form_fields_info['mode'] ) && 'subscription' === $form_fields_info['mode'];
315 $is_payment_split_payment = ( $is_payment_recurring ) && ( ! empty( $form_fields_info['is_payment_split_payment'] ) && 1 === intval( $form_fields_info['is_payment_split_payment'] ) );
316
317 $action_data = [
318 'form_fields_info' => $form_fields_info,
319 'is_payment_recurring' => $is_payment_recurring,
320 'is_payment_split_payment' => $is_payment_split_payment,
321 'checkout_session_id' => $results->obj_id,
322 ];
323
324 $response = wp_safe_remote_post(
325 'https://api.stripe.com/v1/checkout/sessions/' . $results->obj_id,
326 array(
327 'method' => 'GET',
328 'headers' => $header,
329 'timeout' => 70,
330 'body' => $request
331 )
332 );
333
334 if ( is_wp_error( $response ) || empty( $response[ 'body' ] ) ) {
335 return new \WP_Error( 'stripe_error', __( 'There was a problem connecting to the Stripe API endpoint.', 'better-payment' ) );
336 }
337
338 $response = json_decode( $response[ 'body' ] );
339 $transaction_id = ! empty( $results->transaction_id ) ? sanitize_text_field( $results->transaction_id ) : '';
340
341 if ( $is_payment_recurring && ! empty( $response->subscription->id ) ) {
342 $transaction_id = sanitize_text_field( $response->subscription->id );
343 $subscription_obj = $response->subscription;
344 $form_fields_info['subscription_id'] = sanitize_text_field( $transaction_id );
345 $form_fields_info['subscription_customer_id'] = ! empty( $response->customer ) ? sanitize_text_field( $response->customer ) : '';
346 $form_fields_info['subscription_plan_id'] = ! empty( $subscription_obj->items->data[0]->plan->id ) ? sanitize_text_field( $subscription_obj->items->data[0]->plan->id ) : '';
347 $form_fields_info['subscription_interval'] = ! empty( $subscription_obj->items->data[0]->plan->interval_count ) ? intval( $subscription_obj->items->data[0]->plan->interval_count ) : '';
348 $form_fields_info['subscription_interval'] .= ! empty( $subscription_obj->items->data[0]->plan->interval ) ? ' ' . sanitize_text_field( $subscription_obj->items->data[0]->plan->interval ) : $form_fields_info['subscription_interval'];
349 $form_fields_info['subscription_current_period_start'] = ! empty( $subscription_obj->current_period_start ) ? intval( $subscription_obj->current_period_start ) : 0;
350 $form_fields_info['subscription_current_period_end'] = ! empty( $subscription_obj->current_period_end ) ? intval( $subscription_obj->current_period_end ) : 0;
351 $form_fields_info['subscription_status'] = sanitize_text_field( $response->status );
352 $form_fields_info['subscription_created_date'] = sanitize_text_field( $subscription_obj->created );
353 }
354
355 if ( isset( $response->error->message ) ) {
356 return new \WP_Error( 'stripe_error', __( 'There was a problem connecting to the Stripe API endpoint.', 'better-payment' ) );
357 }
358
359 $customer_email = $is_payment_recurring && ( ! empty( $response->customer_email ) ) ? sanitize_email( $response->customer_email ) : '';
360 $customer_email_optional = '';
361 if (
362 isset( $response->payment_intent ) &&
363 isset( $response->payment_intent->charges ) &&
364 isset( $response->payment_intent->charges->data ) &&
365 ! empty( $response->payment_intent->charges->data )
366 ) {
367 $charge = current( $response->payment_intent->charges->data );
368
369 if (
370 isset( $charge->billing_details ) &&
371 isset( $charge->billing_details->email ) &&
372 ! empty( $charge->billing_details->email )
373 ) {
374 $customer_email_optional = sanitize_email( $charge->billing_details->email );
375 }
376 }
377
378 $form_fields_info['is_coupon_applied'] = 0;
379 $exact_paid_amount = ! empty( $response->amount_total ) ? floatval( $response->amount_total ) : $results->amount * 100;
380 $exact_paid_amount = $exact_paid_amount / 100;
381 $form_fields_info['exact_paid_amount'] = $exact_paid_amount;
382 if( (int)$exact_paid_amount != (int)$results->amount ) {
383 $form_fields_info['paid_amount_diff'] = $results->amount - $exact_paid_amount;
384 $form_fields_info['is_coupon_applied'] = 1;
385 }
386
387 $updated = $wpdb->update(
388 $table,
389 array(
390 'amount' => $exact_paid_amount,
391 'status' => sanitize_text_field( $response->payment_status ),
392 'email' => $is_payment_recurring ? $customer_email : $customer_email_optional,
393 'customer_info' => maybe_serialize( $response ),
394 'form_fields_info' => maybe_serialize( $form_fields_info ),
395 'transaction_id' => $transaction_id,
396 ),
397 array( 'ID' => $results->id )
398 );
399
400 do_action('better_payment/stripe_payment/success', $action_data);
401
402 $frontend_data = [
403 'amount' => $exact_paid_amount,
404 'email' => $is_payment_recurring ? $customer_email : $customer_email_optional,
405 'transaction_id' => $transaction_id,
406 'currency' => ! empty( $results->currency ) ? $results->currency : __( 'USD', 'better-payment' ),
407 'method' => 'stripe',
408 'is_payment_recurring' => $is_payment_recurring,
409 'is_payment_split_payment' => $is_payment_split_payment,
410 'is_payment_mixed' => ! empty( $form_fields_info['is_payment_mixed'] ) ? intval( $form_fields_info['is_payment_mixed'] ) : 0,
411 'mixed_payment_selected_type' => ! empty( $form_fields_info['mixed_payment_selected_type'] ) ? sanitize_text_field( $form_fields_info['mixed_payment_selected_type'] ) : '',
412 ];
413
414 if ( $is_payment_split_payment ) {
415 $total_amount = ! empty( $form_fields_info['split_payment_total_amount'] )
416 ? sanitize_text_field( $form_fields_info['split_payment_total_amount'] )
417 : 0;
418 $total_installment = ! empty( $form_fields_info['split_payment_installment_iteration'] )
419 ? sanitize_text_field( $form_fields_info['split_payment_installment_iteration'] )
420 : 1;
421
422 // $frontend_data['amount'] = floatval( $total_amount / $total_installment );
423 $frontend_data['total_amount'] = $total_amount;
424 }
425
426 if ( false !== $updated ) {
427 //Send email notification
428 $better_customer_email = $is_payment_recurring ? $customer_email : $customer_email_optional;
429
430 if (
431 (isset($settings[ 'better_payment_form_email_enable' ]) && $settings[ 'better_payment_form_email_enable' ] == 'yes' )
432 || ( $results->referer === 'elementor-form' )
433 ) {
434 $is_elementor_form = ! empty( $results->referer ) && $results->referer === 'elementor-form' ? 1 : 0;
435 self::better_email_notification($transaction_id, $better_customer_email, $settings, 'Stripe', $results->form_fields_info, $is_elementor_form);
436 }
437
438 return $frontend_data;
439 }
440 }
441 }
442 return false;
443 }
444
445 /**
446 * Paystack payment success
447 *
448 * @since 0.0.1
449 */
450 public static function paystack_payment_success( $settings = [] ) {
451 $data = $_REQUEST;
452
453 if ( ! empty( $data[ 'better_payment_paystack_id' ] ) ) {
454 global $wpdb;
455 $table = "{$wpdb->prefix}better_payment";
456 $results = $wpdb->get_row(
457 $wpdb->prepare( "SELECT id,obj_id,transaction_id,form_fields_info,referer FROM $table WHERE order_id=%s and status = 'unpaid' limit 1", sanitize_text_field( $data[ 'better_payment_paystack_id' ] ) )
458 );
459
460 $header_info = array(
461 'Authorization' => 'Bearer ' . sanitize_text_field( $settings[ 'better_payment_paystack_secret_key' ] ),
462 "Cache-Control: no-cache",
463 );
464
465 $response = wp_safe_remote_get(
466 'https://api.paystack.co/transaction/verify/'. sanitize_text_field( $data[ 'reference' ] ),
467 array(
468 'headers' => $header_info,
469 'timeout' => 70,
470 )
471 );
472
473 $response = json_decode(wp_remote_retrieve_body($response));
474
475 if ( ! empty( $response->status ) ) {
476 $updated = $wpdb->update(
477 $table,
478 array(
479 'status' => ! empty( $response->data->status ) ? sanitize_text_field( $response->data->status ) : '',
480 'amount' => ! empty( $response->data->amount ) ? floatval( ( $response->data->amount ) / 100 ) : 0,
481 'obj_id' => ! empty( $response->data->id ) ? sanitize_text_field( $response->data->id ) : '',
482 'transaction_id' => ! empty( $response->data->reference ) ? sanitize_text_field( $response->data->reference ) : '',
483 'customer_info' => ! empty( $response->data->customer ) ? maybe_serialize( $response->data->customer ) : '',
484 'email' => ! empty( $response->data->customer->email ) ? sanitize_email( $response->data->customer->email ) : '',
485 ),
486 array( 'ID' => $results->id )
487 );
488 }
489
490 $better_customer_email = ! empty( $response->data->customer->email ) ? maybe_serialize( $response->data->customer->email ) : '';
491 $transaction_id = ! empty( $response->data->reference ) ? sanitize_text_field( $response->data->reference ) : '';
492
493 $frontend_data = [
494 'amount' => ! empty( $response->data->amount ) ? floatval( ( $response->data->amount ) / 100 ) : 0,
495 'email' => ! empty( $better_customer_email ) ? $better_customer_email : '',
496 'transaction_id' => $transaction_id,
497 'currency' => ! empty( $response->data->currency ) ? sanitize_text_field( $response->data->currency ) : __( 'USD', 'better-payment' ),
498 'method' => 'paystack',
499 ];
500
501 if ( ! empty( $updated ) && $better_customer_email ) {
502 //Send email notification
503 if (
504 (isset($settings[ 'better_payment_form_email_enable' ]) && $settings[ 'better_payment_form_email_enable' ] == 'yes' )
505 || ( $results->referer === 'elementor-form' )
506 ) {
507 $is_elementor_form = ! empty( $results->referer ) && $results->referer === 'elementor-form' ? 1 : 0;
508 self::better_email_notification($transaction_id, $better_customer_email, $settings, 'Paystack', $results->form_fields_info, $is_elementor_form);
509 }
510
511 return $frontend_data;
512 }
513 }
514 return false;
515 }
516
517 /**
518 * Success message template
519 *
520 * @since 0.0.1
521 */
522 public static function success_message_template( $settings = [], $tr_id = '' ) {
523 if ( empty( $tr_id ) || is_wp_error($tr_id)) {
524 return false;
525 }
526 wp_enqueue_script('better-payment-admin-script');
527 $image_url = BETTER_PAYMENT_ASSETS . '/img/success.svg';
528 $show_icon = 0;
529 $default_icon = 1;
530 $helper_obj = new Helper();
531
532 $store_name = ( isset( $settings['better_payment_form_payment_source'] ) && $settings['better_payment_form_payment_source'] === 'manual' && !empty( $settings['better_payment_form_title'] ) )
533 ? esc_html($settings['better_payment_form_title'])
534 : esc_html( get_bloginfo('name') );
535
536 $payment_desc_text = !empty( $settings['better_payment_form_success_message_heading'] )
537 ? esc_html($settings['better_payment_form_success_message_heading'])
538 : esc_html( __('You paid', 'better-payment') . ' [currency_symbol][amount] ' . __('to', 'better-payment') . ' [store_name]');
539
540 $bp__currency_symbol = esc_html( ! empty( $tr_id['currency'] ) ? $helper_obj->get_currency_symbol( $tr_id['currency'] ) : '' );
541
542 $payment_desc_text = str_replace( '[currency_symbol]', '<span class="bp-bold">' . $bp__currency_symbol . '</span>', $payment_desc_text );
543
544 $payment_desc_text = str_replace( '[amount]', '<span class="bp-bold">' . esc_html( ! empty( $tr_id['amount'] ) ? $tr_id['amount'] : 0 ) . '</span>', $payment_desc_text );
545
546 $payment_desc_text = str_replace( '[store_name]', '<span class="bp-bold">' . esc_html( $store_name ) . '</span>', $payment_desc_text );
547
548 $payment_mail_text = !empty( $settings['better_payment_form_success_message_sub_heading'] ) ? esc_html($settings['better_payment_form_success_message_sub_heading']) : esc_html( __('Payment Confirmation email will be sent to ', 'better-payment') . '[customer_email]');
549
550 $payment_mail_text = str_replace( '[customer_email]', '<span class="bp-bold">' . esc_html( ! empty( $tr_id['email'] ) ? $tr_id['email'] : '' ) . '</span>', $payment_mail_text );
551
552 if ( !empty( $settings[ 'better_payment_form_success_message_icon' ][ 'library' ] ) ) {
553 if ( $settings[ 'better_payment_form_success_message_icon' ][ 'library' ] == 'svg' ) {
554 $image_url = $settings[ 'better_payment_form_success_message_icon' ][ 'value' ][ 'url' ];
555 $default_icon = 0;
556 } else {
557 $show_icon = 1;
558 $image_url = $settings[ 'better_payment_form_success_message_icon' ][ 'value' ];
559 $default_icon = 0;
560 }
561 }
562
563
564 $allowed_payment_methods = [
565 'paypal' => BETTER_PAYMENT_ASSETS . '/img/paypal-2.svg',
566 'stripe' => BETTER_PAYMENT_ASSETS . '/img/stripe-2.svg',
567 'paystack' => BETTER_PAYMENT_ASSETS . '/img/paystack-2.svg',
568 ];
569 $payment_method_logo = isset( $tr_id['method'] ) && isset( $allowed_payment_methods[ $tr_id['method'] ] ) ? $allowed_payment_methods[ $tr_id['method'] ] : '';
570
571 $better_payment_form_success_message_thanks = !empty( $settings['better_payment_form_success_message_thanks'] )
572 ? esc_html( $settings['better_payment_form_success_message_thanks'] )
573 : esc_html__('Thank You!', 'better-payment');
574 $better_payment_form_success_message_transaction = !empty( $settings['better_payment_form_success_message_transaction'] )
575 ? esc_html__( $settings['better_payment_form_success_message_transaction'], 'better-payment' )
576 : esc_html__('Transaction ID', 'better-payment');
577 $better_payment_form_success_message_amount_text = !empty( $settings['better_payment_form_success_message_amount_text'] )
578 ? esc_html( $settings['better_payment_form_success_message_amount_text'] )
579 : esc_html__( 'Amount', 'better-payment' );
580 $better_payment_form_success_message_currency_text = !empty( $settings['better_payment_form_success_message_currency_text'] )
581 ? esc_html( $settings['better_payment_form_success_message_currency_text'] )
582 : esc_html__( 'Currency', 'better-payment' );
583 $better_payment_form_success_message_pay_method_text = !empty( $settings['better_payment_form_success_message_pay_method_text'] ) ? esc_html( $settings['better_payment_form_success_message_pay_method_text'] ) : esc_html__( 'Payment Method', 'better-payment' );
584 $better_payment_form_success_message_pay_type_text = !empty( $settings['better_payment_form_success_message_pay_type_text'] )
585 ? esc_html( $settings['better_payment_form_success_message_pay_type_text'] )
586 : esc_html__( 'Payment Type', 'better-payment' );
587 $better_payment_form_payment_type = !empty( $settings['better_payment_form_payment_type'] )
588 ? esc_html( $settings['better_payment_form_payment_type'] )
589 : '';
590 if ( ! empty( $better_payment_form_payment_type ) ) {
591 if ( 'one-time' === $better_payment_form_payment_type ) {
592 $better_payment_form_payment_type_value = esc_html__( 'One Time Payment', 'better-payment' );
593 } elseif ( 'recurring' === $better_payment_form_payment_type ) {
594 $better_payment_form_payment_type_value = esc_html__( 'Recurring Payment', 'better-payment' );
595 } elseif ( 'mixed' === $better_payment_form_payment_type ) {
596 $mixed_payment_selected_type = ! empty( $tr_id['mixed_payment_selected_type'] ) ? sanitize_text_field( $tr_id['mixed_payment_selected_type'] ) : '';
597 $is_mixed_recurring = 'recurring' === $mixed_payment_selected_type;
598
599 if ( empty( $mixed_payment_selected_type ) ) {
600 $is_mixed_recurring = ! empty( $tr_id['is_payment_recurring'] ) && empty( $tr_id['is_payment_split_payment'] );
601 }
602
603 $better_payment_form_payment_type_value = $is_mixed_recurring
604 ? esc_html__( 'Recurring Payment', 'better-payment' )
605 : esc_html__( 'One Time Payment', 'better-payment' );
606 } else {
607 $better_payment_form_payment_type_value = esc_html__( 'Split Payment', 'better-payment' );
608 }
609 }
610 $better_payment_form_success_message_merchant_details_text = !empty( $settings['better_payment_form_success_message_merchant_details_text'] )
611 ? esc_html( $settings['better_payment_form_success_message_merchant_details_text'] )
612 : esc_html__( 'Merchant Details', 'better-payment' );
613 $better_payment_form_success_message_merchant_details_value = isset( $settings['better_payment_form_payment_source'] ) && $settings['better_payment_form_payment_source'] === 'manual' && ! empty( $settings['better_payment_form_title'] )
614 ? esc_html($settings['better_payment_form_title'])
615 : esc_html( get_bloginfo( 'name' ) );
616 $better_payment_form_success_message_paid_amount_text = !empty( $settings['better_payment_form_success_message_paid_amount_text'] )
617 ? esc_html( $settings['better_payment_form_success_message_paid_amount_text'] )
618 : esc_html__( 'Paid Amount', 'better-payment' );
619 $better_payment_form_success_message_purchase_details_text = !empty( $settings['better_payment_form_success_message_purchase_details_text'] )
620 ? esc_html( $settings['better_payment_form_success_message_purchase_details_text'] )
621 : esc_html__( 'Purchase Details', 'better-payment' );
622 $better_payment_form_success_message_print_text = !empty( $settings['better_payment_form_success_message_print_text'] )
623 ? esc_html( $settings['better_payment_form_success_message_print_text'] )
624 : esc_html__( 'Print', 'better-payment' );
625 $better_payment_form_success_message_view_details_btn_text = !empty( $settings['better_payment_form_success_message_view_details_btn_text'] )
626 ? esc_html( $settings['better_payment_form_success_message_view_details_btn_text'] )
627 : esc_html__( 'View Details', 'better-payment' );
628 $better_payment_form_success_page_view_details_url = !empty( $settings['better_payment_form_success_page_view_details_url']['url'] ) ? esc_url( $settings['better_payment_form_success_page_view_details_url']['url'] ) : 'javascript:void(0)';
629 ?>
630 <section class="bp-thank_page">
631 <div class="bp-thank_page-wrapper">
632 <div class="bp-thank_page-logo">
633 <?php if( $default_icon ): ?>
634 <span class="bp-thank_page-logo_wrapper">
635 <img src="<?php echo esc_url( BETTER_PAYMENT_ASSETS . '/img/success-2.svg' ); ?>" alt="Better Payment logo">
636 </span>
637 <?php endif; ?>
638 <?php if( ! $default_icon ): ?>
639 <?php if( $show_icon ): ?>
640 <?php
641 // Add 'pf-block' class if this is a Gutenberg block (not Elementor)
642 $success_wrapper_class = 'bp-thank_page-custom-logo_wrapper-success';
643 if ( ! empty( $settings['better_payment_form_source'] ) && 'block' === $settings['better_payment_form_source'] ) {
644 $success_wrapper_class .= ' pf-block';
645 }
646 ?>
647 <div class="<?php echo esc_attr( $success_wrapper_class ); ?>">
648 <?php
649 // Render icon safely (handles FontAwesome, Dashicons, SVG with or without Elementor)
650 if (!empty($settings['better_payment_form_success_message_icon'])) {
651 self::render_icon($settings['better_payment_form_success_message_icon'], ['aria-hidden' => 'true']);
652 } else {
653 // Fallback to default icons
654 echo '<i class="' . esc_attr($image_url) . '"></i>';
655 }
656 ?>
657 </div>
658 <?php endif; ?>
659 <?php if( ! $show_icon ): ?>
660 <span class="bp-thank_page-logo_wrapper">
661 <img src="<?php echo esc_url($image_url); ?>" alt="Success logo">
662 </span>
663 <?php endif; ?>
664 <?php endif; ?>
665 </div>
666 <div class="bp-thank_page-text">
667 <h2 class="bp-font_ibm bp-page_header">
668 <?php echo wp_kses_post( $better_payment_form_success_message_thanks ); ?>
669 <span> &#127881;</span>
670 </h2>
671 <p class="bp-font_ibm bp-reason_for-text">
672 <?php echo wp_kses_post( $payment_desc_text ); ?>
673 </p>
674 <?php if (isset( $settings['better_payment_form_email_enable'] ) && !empty( $tr_id['email'] )): ?>
675 <p class="bp-font_ibm bp-payment_info">
676 <?php echo wp_kses_post( $payment_mail_text ); ?>
677 </p>
678 <?php endif; ?>
679
680 <div class="bp-flex bp-transaction_info-wrapper">
681 <p class="bp-flex bp-font_ibm bp-transaction_info"> <span class="line-height-0">
682 <img src="<?php echo esc_url( BETTER_PAYMENT_ASSETS . '/img/wallet.svg' ); ?>" alt="Better Payment wallet">
683 </span>
684 <span>
685 <?php echo wp_kses_post( $better_payment_form_success_message_transaction ); ?>:
686 </span>
687 <span class="bp-bold bp-transaction_id"><?php echo esc_html( ! empty( $tr_id['transaction_id']) ? $tr_id['transaction_id'] : '' ); ?></span>
688 </p>
689
690 <button class="bp-transaction_data-copy_btn ">
691 <svg width="20" height="20" viewBox="0 0 20 20"
692 fill="none" xmlns="http://www.w3.org/2000/svg">
693 <path
694 d="M15.0002 15.601C16.3257 15.601 17.4002 14.5265 17.4002 13.201V8.40098C17.4002 5.38399 17.4002 3.87549 16.463 2.93823C15.5257 2.00098 14.0172 2.00098 11.0002 2.00098H7.80024C6.47476 2.00098 5.40024 3.07549 5.40024 4.40098M10.2002 18.001H7.80024C5.5375 18.001 4.40613 18.001 3.70319 17.298C3.00024 16.5951 3.00024 15.4637 3.00024 13.201V9.20098C3.00024 6.93823 3.00024 5.80686 3.70319 5.10392C4.40613 4.40098 5.5375 4.40098 7.80024 4.40098H10.2002C12.463 4.40098 13.5944 4.40098 14.2973 5.10392C15.0002 5.80686 15.0002 6.93824 15.0002 9.20098V13.201C15.0002 15.4637 15.0002 16.5951 14.2973 17.298C13.5944 18.001 12.463 18.001 10.2002 18.001Z"
695 stroke-width="1.152" />
696 </svg>
697 </button>
698 </div>
699 </div>
700
701 <div class="bp-thank_page-info">
702 <ul class="bp-page_info-list">
703 <li class="bp-flex bp-font_ibm bp-page_info-list_item">
704 <span class="bp-info_content">
705 <?php
706 echo wp_kses_post( $better_payment_form_success_message_amount_text );
707 ?>
708 </span>
709 <span class="bp-info_content bp-bold"><?php echo $bp__currency_symbol . esc_html( ! empty( $tr_id['amount'] ) ? $tr_id['amount'] : 0 ); ?></span>
710 </li>
711 <li class="bp-flex bp-font_ibm bp-page_info-list_item">
712 <span class=" bp-info_content">
713 <?php
714 echo wp_kses_post( $better_payment_form_success_message_currency_text );
715 ?>
716 </span>
717 <span class="bp-info_content bp-bold"><?php echo esc_html( ! empty( $tr_id['currency'] ) ? $tr_id['currency'] : '' ); ?></span>
718 </li>
719 <li class="bp-flex bp-font_ibm bp-page_info-list_item">
720 <span class="bp-info_content">
721 <?php
722 echo wp_kses_post( $better_payment_form_success_message_pay_method_text );
723 ?>
724 </span>
725 <div class="bp-payment_method-logo-wrapper">
726 <?php if ( !empty( $payment_method_logo ) ) : ?>
727 <img src="<?php echo esc_url( $payment_method_logo ); ?>" alt="<?php echo esc_attr( $tr_id['method'] ); ?>" class="bp-payment_method-logo">
728 <?php endif; ?>
729 </div>
730 </li>
731 <?php if( !empty( $better_payment_form_payment_type ) ): ?>
732 <li class="bp-flex bp-font_ibm bp-page_info-list_item">
733 <span class="bp-info_content">
734 <?php
735 echo wp_kses_post( $better_payment_form_success_message_pay_type_text );
736 ?>
737 </span>
738 <span class="bp-info_content bp-bold"><?php echo wp_kses_post( $better_payment_form_payment_type_value ); ?></span>
739 </li>
740 <?php endif; ?>
741 <li class="bp-flex bp-font_ibm bp-page_info-list_item">
742 <span class="bp-info_content">
743 <?php
744 echo wp_kses_post( $better_payment_form_success_message_merchant_details_text );
745 ?>
746 </span>
747 <span class="bp-info_content bp-bold">
748 <?php echo wp_kses_post( $better_payment_form_success_message_merchant_details_value ); ?>
749 </span>
750 </li>
751 <?php if( isset( $tr_id['is_payment_split_payment'] ) && $tr_id['is_payment_split_payment'] ): ?>
752 <li class="bp-flex bp-font_ibm bp-page_info-list_item">
753 <span class="bp-info_content">
754 <?php
755 echo wp_kses_post( $better_payment_form_success_message_paid_amount_text );
756 ?>
757 </span>
758 <span class="bp-info_content bp-bold">
759 <?php echo $bp__currency_symbol . esc_html($tr_id['amount']); ?> out of <?php echo $bp__currency_symbol . esc_html($tr_id['total_amount']); ?>
760 </span>
761 </li>
762 <?php endif; ?>
763 <?php
764 $has_woo_products = !empty($settings['better_payment_form_woocommerce_product_id']) || !empty($settings['better_payment_form_woocommerce_product_ids']);
765 $has_fluentcart_products = !empty($settings['better_payment_form_fluentcart_product_id']) || !empty($settings['better_payment_form_fluentcart_product_ids']);
766
767 if( $has_woo_products || $has_fluentcart_products ):
768 ?>
769 <li class="bp-flex bp-font_ibm bp-page_info-list_item">
770 <span class="bp-info_content">
771 <?php
772 echo wp_kses_post( $better_payment_form_success_message_purchase_details_text );
773 ?>
774 </span>
775 <?php
776 $product_names = [];
777
778 if( !empty( $settings['better_payment_form_woocommerce_product_id'] ) ):
779 $product_names[] = get_the_title( $settings['better_payment_form_woocommerce_product_id'] );
780 endif;
781
782 if( !empty( $settings['better_payment_form_woocommerce_product_ids'] ) ):
783 $product_ids = $settings['better_payment_form_woocommerce_product_ids'];
784 foreach( $product_ids as $product_id ):
785 $product_names[] = get_the_title( $product_id );
786 endforeach;
787 endif;
788
789 if( !empty( $settings['better_payment_form_fluentcart_product_id'] ) && function_exists('fluentCart') && class_exists( '\FluentCart\App\Models\Product' ) ):
790 try {
791 $fluentcart_product = \FluentCart\App\Models\Product::query()->find($settings['better_payment_form_fluentcart_product_id']);
792 if ($fluentcart_product) {
793 $product_names[] = sanitize_text_field( $fluentcart_product->post_title );
794 }
795 } catch ( \Exception $e ) {
796 //
797 }
798 endif;
799
800 if( !empty( $settings['better_payment_form_fluentcart_product_ids'] ) && function_exists('fluentCart') && class_exists( '\FluentCart\App\Models\Product' ) ):
801 $product_ids = $settings['better_payment_form_fluentcart_product_ids'];
802 foreach( $product_ids as $product_id ):
803 try {
804 $fluentcart_product = \FluentCart\App\Models\Product::query()->find($product_id);
805 if ($fluentcart_product) {
806 $product_names[] = sanitize_text_field( $fluentcart_product->post_title );
807 }
808 } catch ( \Exception $e ) {
809 //
810 }
811 endforeach;
812 endif;
813
814 if( !empty($product_names) ):
815 echo '<span class="bp-info_content bp-bold">' . implode( ', ', $product_names ) . '</span>';
816 endif;
817 ?>
818 </li>
819 <?php endif; ?>
820 </ul>
821 </div>
822
823 <div class="bp-flex bp-button_group">
824 <button class="bp-flex bp-font_ibm bp-print_btn">
825 <span style="line-height: 0;">
826 <img src="<?php echo esc_url( BETTER_PAYMENT_ASSETS . '/img/print.svg' ); ?>" alt="Better Payment print">
827 </span>
828 <span class="bp-font_ibm">
829 <?php echo wp_kses_post( $better_payment_form_success_message_print_text ); ?>
830 </span>
831 </button>
832
833 <div class="bp-flex bp-btn_wrapper">
834 <a href="<?php echo $better_payment_form_success_page_view_details_url; ?>" target="_blank" class="bp-font_ibm bp-details_btn">
835 <?php echo wp_kses_post( $better_payment_form_success_message_view_details_btn_text ); ?>
836 </a>
837 </div>
838 </div>
839 </div>
840 </section>
841 <?php
842 }
843
844 /**
845 * Error message template
846 *
847 * @since 0.0.1
848 */
849 public static function failed_message_template( $settings = [], $transaction_data = false ) {
850
851 $image_url = BETTER_PAYMENT_ASSETS . '/img/fail.svg';
852 $show_icon = 0;
853 $default_icon = 1;
854 $failed_heading = !empty( $settings['better_payment_form_error_message_heading'] ) ? esc_html( $settings['better_payment_form_error_message_heading'] ) : esc_html__( 'Payment Failed!', 'better-payment' );
855 $failed_sub_heading = !empty( $settings['better_payment_form_error_message_sub_heading'] ) ? esc_html( $settings['better_payment_form_error_message_sub_heading'] ) : esc_html__( 'Your payment has failed. Please check your payment details', 'better-payment' );
856 $transaction_id_text = !empty( $settings['better_payment_form_error_message_transaction_id_text'] ) ? esc_html( $settings['better_payment_form_error_message_transaction_id_text'] ) : esc_html__( 'Transaction ID', 'better-payment' );
857 $show_details_button = !empty( $settings['better_payment_form_error_details_button_switch'] ) && $settings['better_payment_form_error_details_button_switch'] == 'yes' ? true : false;
858 $details_button_text = !empty( $settings['better_payment_form_error_details_button_text'] ) ? esc_html( $settings['better_payment_form_error_details_button_text'] ) : esc_html__( 'View Details', 'better-payment' );
859 $better_payment_form_error_details_page_url = !empty( $settings['better_payment_form_error_details_page_url']['url'] ) ? esc_url( $settings['better_payment_form_error_details_page_url']['url'] ) : 'javascript:void(0)';
860 $store_name = ( isset( $settings['better_payment_form_payment_source'] ) && $settings['better_payment_form_payment_source'] === 'manual' && !empty( $settings['better_payment_form_title'] ) )
861 ? esc_html($settings['better_payment_form_title'])
862 : esc_html( get_bloginfo('name') );
863
864 // Get transaction details
865 $transaction_amount = '';
866 $transaction_id = '';
867 $currency_symbol = '';
868
869 if ( !empty( $transaction_data ) ) {
870 $transaction_amount = !empty( $transaction_data['amount'] ) ? floatval( $transaction_data['amount'] ) : '';
871 $currency_symbol = !empty( $transaction_data['currency_symbol'] ) ? esc_html( $transaction_data['currency_symbol'] ) : '';
872 $transaction_id = !empty( $transaction_data['transaction_id'] ) ? esc_html( $transaction_data['transaction_id'] ) : '';
873 }
874
875 if ( !empty( $settings[ 'better_payment_form_error_message_icon' ][ 'library' ] ) ) {
876 if ( $settings[ 'better_payment_form_error_message_icon' ][ 'library' ] == 'svg' ) {
877 $image_url = $settings[ 'better_payment_form_error_message_icon' ][ 'value' ][ 'url' ];
878 $default_icon = 0;
879 } else {
880 $show_icon = 1;
881 $image_url = $settings[ 'better_payment_form_error_message_icon' ][ 'value' ];
882 $default_icon = 0;
883 }
884 }
885 // dd($settings[ 'better_payment_form_error_message_icon' ]);
886 ?>
887 <section class="payment-failed-screen-section">
888 <div class="bp-thank_page-wrapper">
889 <div class="bp-thank_page-logo">
890 <?php if( $default_icon ): ?>
891 <span class="bp-thank_page-logo_wrapper">
892 <svg width="58" height="58" viewBox="0 0 58 58" fill="none" xmlns="http://www.w3.org/2000/svg">
893 <path d="M40.804 10.7998H16.8039C13.9409 10.8041 11.1964 11.9434 9.17192 13.9678C7.14746 15.9923 6.00822 18.7368 6.00391 21.5998H51.604C51.5997 18.7368 50.4604 15.9923 48.436 13.9678C46.4115 11.9434 43.667 10.8041 40.804 10.7998ZM6.00391 26.3998V35.9998C6.00822 38.8628 7.14746 41.6073 9.17192 43.6318C11.1964 45.6562 13.9409 46.7955 16.8039 46.7998H40.804C43.667 46.7955 46.4115 45.6562 48.436 43.6318C50.4604 41.6073 51.5997 38.8628 51.604 35.9998V26.3998H6.00391ZM24.0039 38.3998H16.8039C16.1674 38.3998 15.557 38.1469 15.1069 37.6968C14.6568 37.2468 14.4039 36.6363 14.4039 35.9998C14.4039 35.3633 14.6568 34.7529 15.1069 34.3028C15.557 33.8527 16.1674 33.5998 16.8039 33.5998H24.0039C24.6404 33.5998 25.2509 33.8527 25.7009 34.3028C26.151 34.7529 26.4039 35.3633 26.4039 35.9998C26.4039 36.6363 26.151 37.2468 25.7009 37.6968C25.2509 38.1469 24.6404 38.3998 24.0039 38.3998Z" fill="#F44336"></path>
894 <circle cx="45.5" cy="41.5" r="6.5" fill="white"></circle>
895 <foreignObject x="21.4686" y="17.3701" width="47.2066" height="47.3399">
896 <div xmlns="http://www.w3.org/1999/xhtml" style="backdrop-filter:blur(6.36px);clip-path:url(#bgblur_0_3595_8284_clip_path);height:100%;width:100%">
897 </div>
898 </foreignObject>
899 <g filter="url(#filter0_d_3595_8284)" data-figma-bg-blur-radius="12.71">
900 <path d="M55.765 38.782C55.3067 36.6386 54.2191 34.6825 52.6429 33.1664C50.6276 31.1788 47.9133 30.0699 45.0893 30.0804C42.1969 30.0848 39.4243 31.2411 37.3791 33.2958C35.334 35.3505 34.183 38.136 34.1786 41.0417V41.8849C34.2614 43.0459 34.5336 44.1853 34.9843 45.2576C36.0299 47.7766 37.9733 49.8131 40.4344 50.9688C42.8955 52.1245 45.6972 52.3162 48.2915 51.5064C50.8859 50.6967 53.0862 48.9437 54.4622 46.5904C55.8381 44.2371 56.2907 41.4528 55.7314 38.782H55.765ZM46.4154 44.7686L45.0893 43.4364L43.7632 44.7686C43.6072 44.9266 43.4215 45.0521 43.217 45.1377C43.0124 45.2233 42.793 45.2674 42.5714 45.2674C42.3498 45.2674 42.1304 45.2233 41.9259 45.1377C41.7213 45.0521 41.5357 44.9266 41.3796 44.7686C41.2223 44.6118 41.0974 44.4253 41.0122 44.2198C40.927 44.0143 40.8831 43.7939 40.8831 43.5713C40.8831 43.3486 40.927 43.1282 41.0122 42.9227C41.0974 42.7172 41.2223 42.5307 41.3796 42.374L41.8664 41.8849L42.7057 41.0417L41.3796 39.7095C41.0636 39.3919 40.886 38.9613 40.886 38.5122C40.886 38.0631 41.0636 37.6324 41.3796 37.3149C41.6957 36.9973 42.1244 36.8189 42.5714 36.8189C43.0184 36.8189 43.4471 36.9973 43.7632 37.3149L45.0893 38.6471L46.4154 37.3149C46.7314 36.9973 47.1601 36.8189 47.6071 36.8189C48.0541 36.8189 48.4828 36.9973 48.7989 37.3149C49.115 37.6324 49.2926 38.0631 49.2926 38.5122C49.2926 38.9613 49.115 39.3919 48.7989 39.7095L47.4729 41.0417L48.2618 41.8343L48.7989 42.374C48.9563 42.5307 49.0811 42.7172 49.1664 42.9227C49.2516 43.1282 49.2954 43.3486 49.2954 43.5713C49.2954 43.7939 49.2516 44.0143 49.1664 44.2198C49.0811 44.4253 48.9563 44.6118 48.7989 44.7686C48.6429 44.9266 48.4572 45.0521 48.2527 45.1377C48.0481 45.2233 47.8287 45.2674 47.6071 45.2674C47.3855 45.2674 47.1661 45.2233 46.9616 45.1377C46.7571 45.0521 46.5714 44.9266 46.4154 44.7686Z" fill="#F44336" fill-opacity="0.5" shape-rendering="crispEdges"></path>
901 </g>
902 <defs>
903 <filter id="filter0_d_3595_8284" x="21.4686" y="17.3701" width="47.2066" height="47.3399" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
904 <feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood>
905 <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"></feColorMatrix>
906 <feOffset dx="-4"></feOffset>
907 <feGaussianBlur stdDeviation="2"></feGaussianBlur>
908 <feComposite in2="hardAlpha" operator="out"></feComposite>
909 <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.04 0"></feColorMatrix>
910 <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3595_8284"></feBlend>
911 <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3595_8284" result="shape"></feBlend>
912 </filter>
913 <clipPath id="bgblur_0_3595_8284_clip_path" transform="translate(-21.4686 -17.3701)">
914 <path d="M55.765 38.782C55.3067 36.6386 54.2191 34.6825 52.6429 33.1664C50.6276 31.1788 47.9133 30.0699 45.0893 30.0804C42.1969 30.0848 39.4243 31.2411 37.3791 33.2958C35.334 35.3505 34.183 38.136 34.1786 41.0417V41.8849C34.2614 43.0459 34.5336 44.1853 34.9843 45.2576C36.0299 47.7766 37.9733 49.8131 40.4344 50.9688C42.8955 52.1245 45.6972 52.3162 48.2915 51.5064C50.8859 50.6967 53.0862 48.9437 54.4622 46.5904C55.8381 44.2371 56.2907 41.4528 55.7314 38.782H55.765ZM46.4154 44.7686L45.0893 43.4364L43.7632 44.7686C43.6072 44.9266 43.4215 45.0521 43.217 45.1377C43.0124 45.2233 42.793 45.2674 42.5714 45.2674C42.3498 45.2674 42.1304 45.2233 41.9259 45.1377C41.7213 45.0521 41.5357 44.9266 41.3796 44.7686C41.2223 44.6118 41.0974 44.4253 41.0122 44.2198C40.927 44.0143 40.8831 43.7939 40.8831 43.5713C40.8831 43.3486 40.927 43.1282 41.0122 42.9227C41.0974 42.7172 41.2223 42.5307 41.3796 42.374L41.8664 41.8849L42.7057 41.0417L41.3796 39.7095C41.0636 39.3919 40.886 38.9613 40.886 38.5122C40.886 38.0631 41.0636 37.6324 41.3796 37.3149C41.6957 36.9973 42.1244 36.8189 42.5714 36.8189C43.0184 36.8189 43.4471 36.9973 43.7632 37.3149L45.0893 38.6471L46.4154 37.3149C46.7314 36.9973 47.1601 36.8189 47.6071 36.8189C48.0541 36.8189 48.4828 36.9973 48.7989 37.3149C49.115 37.6324 49.2926 38.0631 49.2926 38.5122C49.2926 38.9613 49.115 39.3919 48.7989 39.7095L47.4729 41.0417L48.2618 41.8343L48.7989 42.374C48.9563 42.5307 49.0811 42.7172 49.1664 42.9227C49.2516 43.1282 49.2954 43.3486 49.2954 43.5713C49.2954 43.7939 49.2516 44.0143 49.1664 44.2198C49.0811 44.4253 48.9563 44.6118 48.7989 44.7686C48.6429 44.9266 48.4572 45.0521 48.2527 45.1377C48.0481 45.2233 47.8287 45.2674 47.6071 45.2674C47.3855 45.2674 47.1661 45.2233 46.9616 45.1377C46.7571 45.0521 46.5714 44.9266 46.4154 44.7686Z"></path>
915 </clipPath>
916 </defs>
917 </svg>
918 </span>
919 <?php else: ?>
920 <?php if( $show_icon ): ?>
921 <?php
922 // Add 'pf-block' class if this is a Gutenberg block (not Elementor)
923 $error_wrapper_class = 'bp-thank_page-custom-logo_wrapper-error';
924 if ( ! empty( $settings['better_payment_form_source'] ) && 'block' === $settings['better_payment_form_source'] ) {
925 $error_wrapper_class .= ' pf-block';
926 }
927 ?>
928 <div class="<?php echo esc_attr( $error_wrapper_class ); ?>">
929 <?php
930 // Render icon safely (handles FontAwesome, Dashicons, SVG with or without Elementor)
931 if (!empty($settings['better_payment_form_error_message_icon'])) {
932 self::render_icon($settings['better_payment_form_error_message_icon'], ['aria-hidden' => 'true']);
933 } else {
934 // Fallback to default icons
935 echo '<i class="' . esc_attr($image_url) . '"></i>';
936 }
937 ?>
938 </div>
939 <?php else: ?>
940 <span class="bp-thank_page-logo_wrapper">
941 <img src="<?php echo esc_url($image_url); ?>" alt="Error logo">
942 </span>
943 <?php endif; ?>
944 <?php endif; ?>
945 </div>
946 <div class="bp-thank_page-text">
947 <h2 class="bp-font_ibm bp-page_header"><?php echo wp_kses_post( $failed_heading ); ?></h2>
948 <p class="bp-font_ibm bp-reason_for-text">Payment of <?php echo $currency_symbol . $transaction_amount; ?> to <?php echo $store_name; ?> failed.</p>
949 <p class="bp-font_ibm bp-payment_info"><?php echo wp_kses_post( $failed_sub_heading ); ?></p>
950
951 <div class="bp-flex bp-transaction_info-wrapper">
952 <p class="bp-flex bp-font_ibm bp-transaction_info"> <span>
953 <svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
954 <g clip-path="url(#clip0_2914_6421)">
955 <path d="M12.2002 12.825C11.8821 12.825 11.6242 13.0829 11.6242 13.401C11.6242 13.7191 11.8821 13.977 12.2002 13.977V12.825ZM17.0002 13.401L17.4075 13.8083C17.5156 13.7002 17.5762 13.5537 17.5762 13.401C17.5762 13.2482 17.5156 13.1017 17.4075 12.9937L17.0002 13.401ZM14.993 14.5937C14.768 14.8186 14.768 15.1833 14.993 15.4083C15.2179 15.6332 15.5826 15.6332 15.8075 15.4083L14.993 14.5937ZM15.8075 11.3937C15.5826 11.1687 15.2179 11.1687 14.993 11.3937C14.768 11.6186 14.768 11.9833 14.993 12.2083L15.8075 11.3937ZM10.6002 16.377C10.9184 16.377 11.1762 16.1191 11.1762 15.801C11.1762 15.4829 10.9184 15.225 10.6002 15.225V16.377ZM16.4242 9.40098C16.4242 9.71909 16.6821 9.97698 17.0002 9.97698C17.3184 9.97698 17.5762 9.71909 17.5762 9.40098H16.4242ZM7.40024 13.177C7.71836 13.177 7.97624 12.9191 7.97624 12.601C7.97624 12.2829 7.71836 12.025 7.40024 12.025V13.177ZM4.20024 12.025C3.88213 12.025 3.62424 12.2829 3.62424 12.601C3.62424 12.9191 3.88213 13.177 4.20024 13.177V12.025ZM9.80024 13.177C10.1184 13.177 10.3762 12.9191 10.3762 12.601C10.3762 12.2829 10.1184 12.025 9.80024 12.025V13.177ZM9.40024 12.025C9.08213 12.025 8.82424 12.2829 8.82424 12.601C8.82424 12.9191 9.08213 13.177 9.40024 13.177V12.025ZM1.00024 7.22498C0.682128 7.22498 0.424244 7.48286 0.424244 7.80098C0.424244 8.11909 0.682128 8.37698 1.00024 8.37698V7.22498ZM17.0002 8.37698C17.3184 8.37698 17.5762 8.11909 17.5762 7.80098C17.5762 7.48286 17.3184 7.22498 17.0002 7.22498V8.37698ZM12.2002 13.977H17.0002V12.825H12.2002V13.977ZM16.593 12.9937L14.993 14.5937L15.8075 15.4083L17.4075 13.8083L16.593 12.9937ZM17.4075 12.9937L15.8075 11.3937L14.993 12.2083L16.593 13.8083L17.4075 12.9937ZM7.40024 3.57698H10.6002V2.42498H7.40024V3.57698ZM10.6002 15.225H7.40024V16.377H10.6002V15.225ZM7.40024 15.225C5.87547 15.225 4.78983 15.2238 3.96572 15.113C3.15819 15.0044 2.68857 14.8002 2.3448 14.4564L1.53021 15.271C2.1237 15.8645 2.87695 16.1289 3.81222 16.2547C4.73093 16.3782 5.90803 16.377 7.40024 16.377V15.225ZM0.424244 9.40098C0.424244 10.8932 0.423021 12.0703 0.546538 12.989C0.672282 13.9243 0.936721 14.6775 1.53021 15.271L2.3448 14.4564C2.00103 14.1127 1.79684 13.643 1.68827 12.8355C1.57747 12.0114 1.57624 10.9258 1.57624 9.40098H0.424244ZM10.6002 3.57698C12.125 3.57698 13.2107 3.5782 14.0348 3.689C14.8423 3.79757 15.3119 4.00176 15.6557 4.34553L16.4703 3.53094C15.8768 2.93745 15.1235 2.67301 14.1883 2.54727C13.2696 2.42375 12.0925 2.42498 10.6002 2.42498V3.57698ZM17.5762 9.40098C17.5762 7.90876 17.5775 6.73166 17.4539 5.81296C17.3282 4.87768 17.0638 4.12443 16.4703 3.53094L15.6557 4.34553C15.9995 4.6893 16.2037 5.15892 16.3122 5.96646C16.423 6.79056 16.4242 7.8762 16.4242 9.40098H17.5762ZM7.40024 2.42498C5.90803 2.42498 4.73093 2.42375 3.81222 2.54727C2.87695 2.67301 2.1237 2.93745 1.53021 3.53094L2.3448 4.34553C2.68857 4.00176 3.15819 3.79757 3.96572 3.689C4.78983 3.5782 5.87547 3.57698 7.40024 3.57698V2.42498ZM1.57624 9.40098C1.57624 7.8762 1.57747 6.79056 1.68827 5.96646C1.79684 5.15892 2.00103 4.6893 2.3448 4.34553L1.53021 3.53094C0.936721 4.12443 0.672282 4.87768 0.546538 5.81296C0.423021 6.73166 0.424244 7.90876 0.424244 9.40098H1.57624ZM7.40024 12.025H4.20024V13.177H7.40024V12.025ZM9.80024 12.025H9.40024V13.177H9.80024V12.025ZM1.00024 8.37698H17.0002V7.22498H1.00024V8.37698Z" fill="#8F9AB0"></path>
956 </g>
957 <defs>
958 <clipPath id="clip0_2914_6421">
959 <rect width="18" height="18" fill="white"></rect>
960 </clipPath>
961 </defs>
962 </svg>
963 </span>
964 <span><?php echo wp_kses_post( $transaction_id_text ); ?>:</span>
965 <span class="bp-bolt bp-transaction_id"><?php echo $transaction_id; ?></span>
966 </p>
967
968 <button class="bp-transaction_data-copy_btn ">
969 <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
970 <path d="M15.0002 15.601C16.3257 15.601 17.4002 14.5265 17.4002 13.201V8.40098C17.4002 5.38399 17.4002 3.87549 16.463 2.93823C15.5257 2.00098 14.0172 2.00098 11.0002 2.00098H7.80024C6.47476 2.00098 5.40024 3.07549 5.40024 4.40098M10.2002 18.001H7.80024C5.5375 18.001 4.40613 18.001 3.70319 17.298C3.00024 16.5951 3.00024 15.4637 3.00024 13.201V9.20098C3.00024 6.93823 3.00024 5.80686 3.70319 5.10392C4.40613 4.40098 5.5375 4.40098 7.80024 4.40098H10.2002C12.463 4.40098 13.5944 4.40098 14.2973 5.10392C15.0002 5.80686 15.0002 6.93824 15.0002 9.20098V13.201C15.0002 15.4637 15.0002 16.5951 14.2973 17.298C13.5944 18.001 12.463 18.001 10.2002 18.001Z" stroke-width="1.152"></path>
971 </svg>
972 </button>
973 </div>
974 </div>
975 <?php if( $show_details_button ): ?>
976 <div class="bp-btn_wrapper">
977 <a href="<?php echo $better_payment_form_error_details_page_url; ?>" target="_blank" class="bp-font_ibm bp-details_btn"><?php echo $details_button_text; ?></a>
978 </div>
979 <?php endif; ?>
980 </div>
981 </section>
982 <?php
983 }
984
985 /**
986 * Remove args from url
987 *
988 * @since 0.0.1
989 */
990 public static function remove_arg() {
991 ?>
992 <script>
993
994 if(typeof params === 'undefined'){
995 let params = '';
996 }
997
998 params = new URLSearchParams(location.search);
999
1000 if (params.has('better_payment_paypal_status') || params.has('better_payment_stripe_status') || params.has('better_payment_paystack_status')) {
1001 params.delete('better_payment_paypal_status');
1002 params.delete('better_payment_stripe_status');
1003 params.delete('better_payment_paystack_status');
1004 params.delete('better_payment_widget_id');
1005 params.delete('better_payment_stripe_id');
1006 params.delete('better_payment_paystack_id');
1007 window.history.replaceState({}, '', `${location.pathname}?${params}`);
1008 }
1009 </script>
1010 <?php
1011 }
1012
1013 /**
1014 * Get failed transaction data
1015 *
1016 * @since 1.0.0
1017 */
1018 public static function get_failed_transaction_data( $order_id = '' ) {
1019 if ( empty( $order_id ) ) {
1020 return false;
1021 }
1022
1023 global $wpdb;
1024 $table = "{$wpdb->prefix}better_payment";
1025
1026 $result = $wpdb->get_row(
1027 $wpdb->prepare(
1028 "SELECT amount, currency, transaction_id, order_id, source FROM $table WHERE order_id=%s LIMIT 1",
1029 $order_id
1030 )
1031 );
1032
1033 if ( !empty( $result ) ) {
1034 $helper_obj = new Helper();
1035 return [
1036 'amount' => floatval( $result->amount ),
1037 'currency' => sanitize_text_field( $result->currency ),
1038 'currency_symbol' => $helper_obj->get_currency_symbol( $result->currency ),
1039 'transaction_id' => !empty( $result->transaction_id ) ? sanitize_text_field( $result->transaction_id ) : 'N/A',
1040 'method' => sanitize_text_field( $result->source ),
1041 ];
1042 }
1043
1044 return false;
1045 }
1046
1047 /**
1048 * Email template
1049 *
1050 * @since 0.0.1
1051 */
1052 public static function better_email_notification($transaction_id, $customer_email, $settings, $referrer='Stripe', $form_fields_info='', $is_elementor_form = 0){
1053 //Send Email: customer and admin
1054 $better_txn_id = sanitize_text_field( $transaction_id );
1055 $better_cus_email = sanitize_email( $customer_email );
1056 $default_subject = sprintf(__('Better Payment transaction on %s', 'better-payment'), esc_html(get_option('blogname')));
1057 $better_payment_global_settings = DB::get_settings();
1058
1059 $better_payment_email_to = !empty($better_payment_global_settings['better_payment_settings_general_email_to']) ? $better_payment_global_settings['better_payment_settings_general_email_to'] : get_option( 'admin_email' );
1060
1061 $better_payment_email_subject = !empty($better_payment_global_settings['better_payment_settings_general_email_subject']) ? $better_payment_global_settings['better_payment_settings_general_email_subject'] : $default_subject;
1062 $better_payment_email_content = !empty($better_payment_global_settings['better_payment_settings_general_email_message_admin']) ? $better_payment_global_settings['better_payment_settings_general_email_message_admin'] : 'Email Content';
1063 $better_payment_email_from = !empty($better_payment_global_settings['better_payment_settings_general_email_from_email']) ? $better_payment_global_settings['better_payment_settings_general_email_from_email'] : '';
1064 $better_payment_email_from_name = !empty($better_payment_global_settings['better_payment_settings_general_email_from_name']) ? $better_payment_global_settings['better_payment_settings_general_email_from_name'] : '';
1065 $better_payment_email_reply_to = !empty($better_payment_global_settings['better_payment_settings_general_email_reply_to']) ? $better_payment_global_settings['better_payment_settings_general_email_reply_to'] : '';
1066 $better_payment_email_cc = !empty($better_payment_global_settings['better_payment_settings_general_email_cc']) ? $better_payment_global_settings['better_payment_settings_general_email_cc'] : '';
1067 $better_payment_email_bcc = !empty($better_payment_global_settings['better_payment_settings_general_email_bcc']) ? $better_payment_global_settings['better_payment_settings_general_email_bcc'] : '';
1068 $better_payment_email_content_type = !empty($better_payment_global_settings['better_payment_settings_general_email_send_as']) ? $better_payment_global_settings['better_payment_settings_general_email_send_as'] : 'html';
1069
1070 $better_payment_email_subject_customer = !empty($better_payment_global_settings['better_payment_settings_general_email_subject_customer']) ? $better_payment_global_settings['better_payment_settings_general_email_subject_customer'] : $default_subject;
1071 $better_payment_email_content_customer = !empty($better_payment_global_settings['better_payment_settings_general_email_message_customer']) ? $better_payment_global_settings['better_payment_settings_general_email_message_customer'] : 'Email Content';
1072 $better_payment_email_from_customer = !empty($better_payment_global_settings['better_payment_settings_general_email_from_email_customer']) ? $better_payment_global_settings['better_payment_settings_general_email_from_email_customer'] : '';
1073 $better_payment_email_from_name_customer = !empty($better_payment_global_settings['better_payment_settings_general_email_from_name_customer']) ? $better_payment_global_settings['better_payment_settings_general_email_from_name_customer'] : '';
1074 $better_payment_email_reply_to_customer = !empty($better_payment_global_settings['better_payment_settings_general_email_reply_to_customer']) ? $better_payment_global_settings['better_payment_settings_general_email_reply_to_customer'] : '';
1075 $better_payment_email_cc_customer = !empty($better_payment_global_settings['better_payment_settings_general_email_cc_customer']) ? $better_payment_global_settings['better_payment_settings_general_email_cc_customer'] : '';
1076 $better_payment_email_bcc_customer = !empty($better_payment_global_settings['better_payment_settings_general_email_bcc_customer']) ? $better_payment_global_settings['better_payment_settings_general_email_bcc_customer'] : '';
1077 $better_payment_email_content_type_customer = !empty($better_payment_global_settings['better_payment_settings_general_email_send_as_customer']) ? $better_payment_global_settings['better_payment_settings_general_email_send_as_customer'] : 'html';
1078 $args = [];
1079
1080 $args['email_form_name'] = ! empty( $settings['better_payment_form_title'] ) ? sanitize_text_field( $settings['better_payment_form_title'] ) : 'N/A';
1081 $args['email_content_heading_show'] = ! empty( $settings['better_payment_email_content_heading'] ) && 'yes' === $settings['better_payment_email_content_heading'] ? 1 : 0;
1082 $args['email_content_from_section_show'] = ! empty( $settings['better_payment_email_content_from_section'] ) && 'yes' === $settings['better_payment_email_content_from_section'] ? 1 : 0;
1083 $args['email_content_to_section_show'] = ! empty( $settings['better_payment_email_content_to_section'] ) && 'yes' === $settings['better_payment_email_content_to_section'] ? 1 : 0;
1084 $args['email_content_transaction_summary_show'] = ! empty( $settings['better_payment_email_content_transaction_summary'] ) && 'yes' === $settings['better_payment_email_content_transaction_summary'] ? 1 : 0;
1085 $args['email_content_footer_text_show'] = ! empty( $settings['better_payment_email_content_footer_text'] ) && 'yes' === $settings['better_payment_email_content_footer_text'] ? 1 : 0;
1086 $args['email_content_customer'] = ! empty( $settings['better_payment_email_content_customer'] ) ? $settings['better_payment_email_content_customer'] : '';
1087 $args['email_content_admin'] = ! empty( $settings['better_payment_email_content'] ) ? $settings['better_payment_email_content'] : '';
1088 $args['is_elementor_form'] = $is_elementor_form;
1089
1090 if ( ! empty( $settings['better_payment_email_content_greeting'] ) ) {
1091 $args['email_content_greeting'] = $settings['better_payment_email_content_greeting'];
1092 }
1093
1094 if ( ! empty( $settings['better_payment_form_email_logo']['url'] ) ) {
1095 $args['email_logo_url'] = $settings['better_payment_form_email_logo']['url'];
1096 }
1097
1098 if ( ! empty( $settings['better_payment_form_email_attachment']['id'] ) ) {
1099 $args['email_attachment_id'] = intval( $settings['better_payment_form_email_attachment']['id'] );
1100 $args['email_attachment_path'] = get_attached_file( $args['email_attachment_id'] );
1101 }
1102
1103 if ( ! empty( $settings['better_payment_form_email_attachment_pdf_show'] ) && ! empty( $settings['better_payment_form_email_attachment_pdf']['id'] ) ) {
1104 $args['email_attachment_id'] = intval( $settings['better_payment_form_email_attachment_pdf']['id'] );
1105 $args['email_attachment_path'] = get_attached_file( $args['email_attachment_id'] );
1106 }
1107
1108 if(isset($settings['better_payment_email_to'])){
1109 $better_payment_email_to = sanitize_email($settings['better_payment_email_to']);
1110 }
1111
1112 if(isset($settings['better_payment_email_subject'])){
1113 $better_payment_email_subject = sanitize_text_field($settings['better_payment_email_subject']);
1114 }
1115
1116 if(isset($settings['better_payment_email_subject_customer'])){
1117 $better_payment_email_subject_customer = sanitize_text_field($settings['better_payment_email_subject_customer']);
1118 }
1119
1120 if(isset($settings['better_payment_email_content_type'])){
1121 $better_payment_email_content_type = sanitize_text_field($settings['better_payment_email_content_type']);
1122 }
1123
1124 if(isset($settings['better_payment_email_content_type_customer'])){
1125 $better_payment_email_content_type_customer = sanitize_text_field($settings['better_payment_email_content_type_customer']);
1126 }
1127
1128 $args['email_content_type'] = $better_payment_email_content_type;
1129 $args['email_content_type_customer'] = $better_payment_email_content_type_customer;
1130
1131 $line_break = $better_payment_email_content_type == 'html' ? '<br>' : "\n";
1132 $line_break_customer = $better_payment_email_content_type_customer == 'html' ? '<br>' : "\n";
1133
1134 global $wpdb;
1135 $table = "{$wpdb->prefix}better_payment";
1136 $transaction_obj = $wpdb->get_row(
1137 $wpdb->prepare( "SELECT * FROM $table WHERE transaction_id=%s limit 1", sanitize_text_field( $transaction_id ) )
1138 );
1139
1140 if(isset($settings['better_payment_email_content'])){
1141 $better_payment_email_content = sanitize_text_field($settings['better_payment_email_content']);
1142 $better_payment_email_content = self::better_render_email_body( $better_payment_email_content, $form_fields_info, $line_break, 'admin', $transaction_obj, $args );
1143 } else if ( !empty($better_payment_email_content) ){
1144 $better_payment_email_content = self::better_render_email_body( $better_payment_email_content, $form_fields_info, $line_break, 'admin', $transaction_obj, $args );
1145 }
1146
1147 if(isset($settings['better_payment_email_content_customer'])){
1148 $better_payment_email_content_customer = sanitize_text_field($settings['better_payment_email_content_customer']);
1149 $better_payment_email_content_customer = self::better_render_email_body( $better_payment_email_content_customer, $form_fields_info, $line_break_customer, 'customer', $transaction_obj, $args );
1150 } else if ( !empty($better_payment_email_content_customer) ){
1151 $better_payment_email_content_customer = self::better_render_email_body( $better_payment_email_content_customer, $form_fields_info, $line_break, 'customer', $transaction_obj, $args ); //$line_break_customer not used : need to check type on parent method and add headers accordingly.
1152 }
1153
1154 if(isset($settings['better_payment_email_from'])){
1155 $better_payment_email_from = sanitize_email($settings['better_payment_email_from']);
1156 }
1157
1158 if(isset($settings['better_payment_email_from_name'])){
1159 $better_payment_email_from_name = sanitize_text_field($settings['better_payment_email_from_name']);
1160 }
1161
1162 if(isset($settings['better_payment_email_reply_to'])){
1163 $better_payment_email_reply_to = sanitize_email($settings['better_payment_email_reply_to']);
1164 }
1165
1166 if(isset($settings['better_payment_email_cc'])){
1167 $better_payment_email_cc = sanitize_email($settings['better_payment_email_cc']);
1168 }
1169
1170 if(isset($settings['better_payment_email_bcc'])){
1171 $better_payment_email_bcc = sanitize_email($settings['better_payment_email_bcc']);
1172 }
1173
1174 //Customer Email
1175 if(isset($settings['better_payment_email_from_customer'])){
1176 $better_payment_email_from_customer = sanitize_email($settings['better_payment_email_from_customer']);
1177 }
1178
1179 if(isset($settings['better_payment_email_from_name_customer'])){
1180 $better_payment_email_from_name_customer = sanitize_text_field($settings['better_payment_email_from_name_customer']);
1181 }
1182
1183 if(isset($settings['better_payment_email_reply_to_customer'])){
1184 $better_payment_email_reply_to_customer = sanitize_email($settings['better_payment_email_reply_to_customer']);
1185 }
1186
1187 if(isset($settings['better_payment_email_cc_customer'])){
1188 $better_payment_email_cc_customer = sanitize_email($settings['better_payment_email_cc_customer']);
1189 }
1190
1191 if(isset($settings['better_payment_email_bcc_customer'])){
1192 $better_payment_email_bcc_customer = sanitize_email($settings['better_payment_email_bcc_customer']);
1193 }
1194
1195 if($better_payment_email_content == ''){
1196 $better_payment_email_content = __('New better payment transaction! ', 'better-payment');
1197 }
1198
1199 if($better_payment_email_content_customer == ''){
1200 $better_payment_email_content_customer = __('New better payment transaction! ', 'better-payment');
1201 }
1202
1203 $better_payment_email_headers = [];
1204 $better_payment_email_headers_customer = [];
1205
1206 if($better_payment_email_content_type == 'html'){
1207 $better_payment_email_headers[] = 'Content-Type: text/html; charset=UTF-8';
1208 }
1209
1210 if($better_payment_email_content_type_customer == 'html'){
1211 $better_payment_email_headers_customer[] = 'Content-Type: text/html; charset=UTF-8';
1212 }
1213
1214 if($better_payment_email_from != ''){
1215 $better_payment_email_headers[] = "From: $better_payment_email_from_name <$better_payment_email_from>";
1216 }
1217
1218 if($better_payment_email_cc != ''){
1219 $better_payment_email_headers[] = "Cc: <$better_payment_email_cc>";
1220 }
1221
1222 if($better_payment_email_bcc != ''){
1223 $better_payment_email_headers[] = "BCc: $better_payment_email_bcc";
1224 }
1225
1226 if($better_payment_email_reply_to != ''){
1227 $better_payment_email_headers[] = "Reply-To: $better_payment_email_reply_to";
1228 }
1229
1230 //Customer Email
1231 if($better_payment_email_from_customer != ''){
1232 $better_payment_email_headers_customer[] = "From: $better_payment_email_from_name_customer <$better_payment_email_from_customer>";
1233 }
1234
1235 $form_fields_info_array = [];
1236
1237 if( ! empty( $form_fields_info ) ){
1238 $form_fields_info_array = maybe_unserialize( $form_fields_info );
1239 }
1240
1241 $form_fields_info_cus_email = ! empty( $form_fields_info_array['primary_email'] ) ? sanitize_email( $form_fields_info_array['primary_email'] ) : '';
1242
1243 if($better_payment_email_cc_customer != '' || ! empty( $form_fields_info_cus_email ) ){
1244 $better_payment_email_cc_customer_multiple = implode(',', [$form_fields_info_cus_email, $better_payment_email_cc_customer]);
1245 $better_payment_email_headers_customer[] = "Cc: $better_payment_email_cc_customer_multiple";
1246 }
1247
1248 if($better_payment_email_bcc_customer != ''){
1249 $better_payment_email_headers_customer[] = "BCc: $better_payment_email_bcc_customer";
1250 }
1251
1252 if($better_payment_email_reply_to_customer != ''){
1253 $better_payment_email_headers_customer[] = "Reply-To: $better_payment_email_reply_to_customer";
1254 }
1255
1256 $email_attachments = ! empty( $args['email_attachment_path'] ) ? [ $args['email_attachment_path'] ] : [];
1257 $allowed_extensions = array('jpg', 'jpeg', 'png', 'pdf');
1258
1259 $file_info = count( $email_attachments ) ? pathinfo($email_attachments[0]) : [];
1260 $file_extension = count( $file_info ) ? strtolower($file_info['extension']) : '';
1261
1262 if ( ! in_array( $file_extension, $allowed_extensions ) ){
1263 $email_attachments = [];
1264 }
1265
1266 self::send_better_email($better_cus_email, $better_payment_email_subject_customer, $better_payment_email_content_customer, $better_payment_email_headers_customer, $email_attachments); //customer mail
1267 self::send_better_email($better_payment_email_to, $better_payment_email_subject, $better_payment_email_content, $better_payment_email_headers); //admin mail
1268 }
1269
1270 /**
1271 * Sends an HTML email.
1272 *
1273 * @since 0.0.2
1274 *
1275 * @param string $to
1276 * @param string $subject
1277 * @param array $message
1278 *
1279 * @return bool false indicates mail sending failed while true doesn't gurantee that mail sent.
1280 * true just indicate script processed successfully without any errors.
1281 * Ref: https://developer.wordpress.org/reference/functions/wp_mail/
1282 */
1283 public static function send_better_email( $to, $subject, $message, $headers=[], $attachments = [] ) {
1284 $response = false;
1285
1286 $mailValidated = filter_var($to, FILTER_VALIDATE_EMAIL);
1287
1288 if ($mailValidated) {
1289 $response = wp_mail( $to, $subject, $message, $headers, $attachments );
1290 }
1291
1292 return $response;
1293 }
1294
1295 /**
1296 * Email body
1297 *
1298 *
1299 * @return string
1300 * @since 0.0.1
1301 */
1302 public static function better_render_email_body( $email_body, $form_fields_info, $line_break, $type = 'admin', $transaction_obj = null, $args = [] ) {
1303 $transaction_id =
1304 $currency =
1305 $payment_date =
1306 $customer_name =
1307 $customer_first_name =
1308 $customer_last_name =
1309 $amount = '';
1310 $helper_obj = new Helper();
1311
1312 if(null !== $transaction_obj && is_object($transaction_obj)){
1313 $transaction_id = $transaction_obj->transaction_id;
1314 $amount = $transaction_obj->amount;
1315 $status = $transaction_obj->status;
1316 $source = $transaction_obj->source;
1317 $currency = $transaction_obj->currency;
1318 $currency_symbol = $helper_obj->get_currency_symbol( esc_html($currency) );
1319 $payment_date = wp_date(get_option('date_format').' '.get_option('time_format'), strtotime($transaction_obj->payment_date));
1320 }
1321
1322 $is_empty_email_body = empty($email_body);
1323
1324 $email_body = do_shortcode( $email_body );
1325 $bp_form_fields_html_content = $email_body;
1326
1327 $bp_all_fields_shortcode = 'bp-all-fields';
1328 $referer_content_page_link = '#';
1329
1330 $field_text = __('Field', 'better-payment');
1331 $value_text = __('Entry', 'better-payment');
1332
1333 $form_fields_info_arr = maybe_unserialize($form_fields_info);
1334
1335 $email_logo_url = ! empty( $args['email_logo_url'] ) ? $args['email_logo_url'] : '';
1336 $email_content_greeting = ! empty( $args['email_content_greeting'] ) ? 1 : 0;
1337 $email_form_name = ! empty( $args['email_form_name'] ) ? $args['email_form_name'] : 'N/A';
1338
1339 $bp_form_fields_html_header = '<table style="margin-bottom: 20px; font-size: 14px; border-collapse: collapse; width: 100%;">';
1340
1341 $bp_form_fields_html_footer = "</table>";
1342
1343 $content = ''. $line_break;
1344
1345 foreach ( $form_fields_info_arr as $key => $field ) {
1346 if ( $key === 'is_payment_split_payment' ) {
1347 $is_payment_split_payment = 1;
1348 }
1349 //Hide few fields
1350 if(
1351 $key === 'referer_page_id' || $key === 'referer_widget_id' || $key === 'source' || $key === 'el_form_fields'
1352 || $key === 'is_woo_layout'
1353 || $key === 'is_payment_split_payment'
1354 || $key === 'split_payment_total_amount'
1355 || $key === 'split_payment_total_amount_price_id'
1356 || $key === 'split_payment_installment_price_id'
1357 ) {
1358 if($key === 'referer_page_id'){
1359 $referer_content_page_link = !empty($field) ? get_permalink( $field ) : $referer_content_page_link;
1360 }
1361
1362 continue;
1363 }
1364
1365 if($key === 'primary_first_name'){
1366 $key = 'first_name';
1367 $customer_first_name = $field;
1368 }
1369 if($key === 'primary_last_name'){
1370 $key = 'last_name';
1371 $customer_last_name = $field;
1372 }
1373
1374 if($key === 'primary_email'){
1375 $key = 'email';
1376 }
1377
1378 if($key === 'primary_payment_amount'){
1379 $key = 'payment_amount';
1380 }
1381
1382 $key_formatted = self::better_title_case($key);
1383 if($key_formatted === 'Amount'){
1384 $key_formatted = __('Paid', 'better-payment');
1385
1386 if ( ! empty( $is_payment_split_payment ) ) {
1387 $key_formatted = __('Product Price: ', 'better-payment');
1388 }
1389 }
1390
1391 $content .= "<tr>
1392 <td style='padding: 7px; border: 1px solid #666;'> <strong>$key_formatted</strong> </td>
1393 <td style='padding: 7px; border: 1px solid #666;'> $field </td>
1394 </tr>";
1395 }
1396
1397 if($customer_first_name) {
1398 $customer_name = $customer_first_name . ' ';
1399 }
1400 if($customer_last_name) {
1401 $customer_name .= $customer_last_name . ' ';
1402 }
1403
1404 $allowed_sources = ['paypal', 'stripe', 'paystack'];
1405 $source_image_url = BETTER_PAYMENT_ASSETS . '/img/stripe.png';
1406 $source_image_alt = 'Stripe';
1407
1408 if( in_array( strtolower( $transaction_obj->source ), $allowed_sources ) ){
1409 $source_image_url = strtolower( $transaction_obj->source ) == 'paypal' ? BETTER_PAYMENT_ASSETS . '/img/paypal.png' : BETTER_PAYMENT_ASSETS . "/img/{$transaction_obj->source}.png";
1410 $source_image_alt = strtolower( $transaction_obj->source ) == 'paypal' ? 'PayPal' : ucfirst( strtolower( $transaction_obj->source ) );
1411 }
1412
1413 $amount_quantity = ! empty( $form_fields_info_arr['amount_quantity'] ) ? intval( $form_fields_info_arr['amount_quantity'] ) : 1;
1414 // #ToDo Product id or ids with comma
1415 $woo_product_id = ! empty( $form_fields_info_arr['woo_product_id'] ) ? intval( $form_fields_info_arr['woo_product_id'] ) : 0;
1416 $fluentcart_product_id = ! empty( $form_fields_info_arr['fluentcart_product_id'] ) ? intval( $form_fields_info_arr['fluentcart_product_id'] ) : 0;
1417 $woo_product_ids = ! empty( $form_fields_info_arr['woo_product_ids'] ) ? maybe_unserialize( $form_fields_info_arr['woo_product_ids'] ) : [0];
1418 $fluentcart_product_ids = ! empty( $form_fields_info_arr['fluentcart_product_ids'] ) ? maybe_unserialize( $form_fields_info_arr['fluentcart_product_ids'] ) : [0];
1419 $product_name = '';
1420 $product_permalink = '';
1421 $product_image_src = '';
1422
1423 // Handle WooCommerce products
1424 if (function_exists('wc_get_product') && $woo_product_id ) {
1425 $bp_woocommerce_product = wc_get_product($woo_product_id);
1426 $product = $bp_woocommerce_product;
1427
1428 if ($product) {
1429 $product_name = $product->get_name();
1430 $product_permalink = get_permalink($product->get_id());
1431 $product_price = $product->get_price();
1432 $product_image_src_array = wp_get_attachment_image_src( get_post_thumbnail_id( $product->get_id() ), 'single-post-thumbnail' );
1433 $product_image_src = is_array( $product_image_src_array ) && count( $product_image_src_array ) ? $product_image_src_array[0] : '';
1434 }
1435 }
1436
1437 if (function_exists('fluentCart') && $fluentcart_product_id ) {
1438 try {
1439 $fluentcart_product = \FluentCart\App\Models\Product::query()
1440 ->with(['detail', 'variants'])
1441 ->find($fluentcart_product_id);
1442
1443 if ($fluentcart_product) {
1444 $product_name = $fluentcart_product->post_title;
1445 $product_permalink = get_permalink($fluentcart_product->ID);
1446
1447 // Get price from the first variant or detail
1448 $product_price = 0;
1449 if (!empty($fluentcart_product->variants) && count($fluentcart_product->variants) > 0) {
1450 $product_price = $fluentcart_product->variants[0]->item_price;
1451 } elseif (!empty($fluentcart_product->detail)) {
1452 $product_price = $fluentcart_product->detail->min_price;
1453 }
1454
1455 $product_image_src_array = wp_get_attachment_image_src( get_post_thumbnail_id( $fluentcart_product->ID ), 'single-post-thumbnail' );
1456 $product_image_src = is_array( $product_image_src_array ) && count( $product_image_src_array ) ? $product_image_src_array[0] : '';
1457 }
1458 } catch ( \Exception $e ) {
1459 // Handle error silently
1460 }
1461 }
1462
1463 $detailed_product_info = isset( $form_fields_info_arr['detailed_product_info'] ) ? maybe_unserialize( $form_fields_info_arr['detailed_product_info'] ) : [];
1464
1465 $all_data = [
1466 'amount' => $amount,
1467 'amount_quantity' => $amount_quantity,
1468 'woo_product_id' => $woo_product_id,
1469 'woo_product_ids' => $woo_product_ids,
1470 'fluentcart_product_id' => $fluentcart_product_id,
1471 'fluentcart_product_ids' => $fluentcart_product_ids,
1472 'product_name' => $product_name,
1473 'product_permalink' => $product_permalink,
1474 'product_image_src' => $product_image_src,
1475 'detailed_product_info' => $detailed_product_info,
1476 'amount_single' => $amount_quantity > 0 ? floatval( $amount / $amount_quantity ) : $amount,
1477 'currency' => ! empty( $currency ) ? $currency : '',
1478 'currency_symbol' => ! empty( $currency_symbol ) ? $currency_symbol : '',
1479 'payment_date_time' => ! empty( $payment_date ) ? $payment_date : '',
1480 'transaction_id' => ! empty( $transaction_id ) ? $transaction_id : '',
1481 'payment_date_only' => wp_date(get_option('date_format'), strtotime($transaction_obj->payment_date)),
1482 'status' => ucfirst( $status ),
1483 'form_fields_info_arr' => $form_fields_info_arr,
1484 // 'admin_name' => $admin_name,
1485 'customer_name' => $customer_name,
1486 'site_title' => get_bloginfo( 'name' ),
1487 'site_admin_email' => get_bloginfo( 'admin_email' ),
1488 'form_name' => $email_form_name,
1489 'payment_method' => ucfirst( $source ),
1490 'email_logo_url' => $email_logo_url,
1491 'source_image_url' => $source_image_url,
1492 'source_image_alt' => $source_image_alt,
1493 'view_transaction_link' => admin_url("admin.php?page=better-payment-transactions&action=view&id={$transaction_obj->id}"),
1494 'email_content_heading_show' => intval( $args['email_content_heading_show'] ),
1495 'email_content_from_section_show' => intval( $args['email_content_from_section_show'] ),
1496 'email_content_to_section_show' => intval( $args['email_content_to_section_show'] ),
1497 'email_content_transaction_summary_show' => intval( $args['email_content_transaction_summary_show'] ),
1498 'email_content_footer_text_show' => intval( $args['email_content_footer_text_show'] ),
1499 'email_content_customer' => wp_kses_post( $args['email_content_customer'] ),
1500 'email_content_admin' => wp_kses_post( $args['email_content_admin'] ),
1501 'is_elementor_form' => intval( $args['is_elementor_form'] ),
1502 'email_content_type' => $args['email_content_type'] ?? 'html',
1503 'email_content_type_customer' => $args['email_content_type_customer'] ?? 'html',
1504 ];
1505
1506 $bp_form_fields_html_body = $content;
1507 $bp_form_fields_html_content = $bp_form_fields_html_header . $bp_form_fields_html_body . $bp_form_fields_html_footer ;
1508
1509 //Replace shortcode with form fields info
1510 $email_body = str_replace( "[$bp_all_fields_shortcode]", $bp_form_fields_html_content, $email_body );
1511
1512 // Email V2
1513 // General content
1514 $form_name =
1515
1516 ob_start();
1517
1518 include BETTER_PAYMENT_ADMIN_VIEWS_PATH . "/template-email-notification.php";
1519
1520 $email_body = ob_get_contents();
1521 ob_end_clean();
1522
1523 return $email_body;
1524 }
1525
1526 /**
1527 * String helper method
1528 * helps to convert string to title case
1529 *
1530 * @return string
1531 * @since 0.0.1
1532 */
1533 public static function better_title_case($string){
1534 $string = str_replace('_',' ', $string);
1535 $string = ucwords($string);
1536 return $string;
1537 }
1538
1539 /**
1540 * Safe icon rendering for payment form messages
1541 *
1542 * Handles multiple icon types: FontAwesome, Dashicons, SVG from media library
1543 * Works with or without Elementor being active
1544 *
1545 * @param array $icon_settings Icon settings from block/widget controls
1546 * @param array $html_attributes Optional HTML attributes for the icon element
1547 *
1548 * @return void (outputs HTML directly)
1549 * @since 2.0.4
1550 */
1551 public static function render_icon( $icon_settings = [], $html_attributes = [] ) {
1552 // Bail if no settings provided
1553 if ( empty( $icon_settings ) || ! is_array( $icon_settings ) ) {
1554 return;
1555 }
1556
1557 // If value is empty, nothing to render
1558 if ( empty( $icon_settings['value'] ) ) {
1559 return;
1560 }
1561
1562 $library = ! empty( $icon_settings['library'] ) ? $icon_settings['library'] : '';
1563 $value = $icon_settings['value'];
1564
1565 // Try to use Elementor's Icons_Manager if it's available and loaded
1566 if ( did_action( 'elementor/loaded' ) && class_exists( '\Elementor\Icons_Manager' ) ) {
1567 try {
1568 \Elementor\Icons_Manager::render_icon( $icon_settings, $html_attributes );
1569 return;
1570 } catch ( \Exception $e ) {
1571 // If Elementor rendering fails, fall back to manual rendering
1572 }
1573 }
1574
1575 // Handle SVG (uploaded via media library)
1576 if ( $library === 'svg' ) {
1577 if ( is_array( $value ) && ! empty( $value['url'] ) ) {
1578 $svg_url = esc_url( $value['url'] );
1579 echo '<img src="' . $svg_url . '" alt="Icon" class="bp-icon-svg" />';
1580 return;
1581 }
1582 }
1583
1584 // Handle FontAwesome icons (all variants: fa, fas, far, fab, fal, fad, etc.)
1585 if ( in_array( $library, [ 'fa', 'fas', 'far', 'fab', 'fal', 'fad', 'fontawesome', 'font-awesome' ], true ) ) {
1586 if ( is_string( $value ) && ! empty( $value ) ) {
1587 // Build complete FontAwesome class
1588 $icon_class = 'fa';
1589
1590 // Add variant if specified (fas, far, fab, fal)
1591 if ( ! empty( $library ) && $library !== 'fa' && $library !== 'fontawesome' && $library !== 'font-awesome' ) {
1592 $icon_class = esc_attr( $library );
1593 } else {
1594 // Default to 'fas' if no variant specified
1595 $icon_class = 'fas';
1596 }
1597
1598 // Add the specific icon class
1599 $icon_class .= ' ' . esc_attr( $value );
1600
1601 $html_class = ! empty( $html_attributes['class'] ) ? ' ' . $html_attributes['class'] : '';
1602 $aria_hidden = isset( $html_attributes['aria-hidden'] ) ? ' aria-hidden="' . esc_attr( $html_attributes['aria-hidden'] ) . '"' : ' aria-hidden="true"';
1603
1604 echo '<i class="' . $icon_class . $html_class . '"' . $aria_hidden . '></i>';
1605 return;
1606 }
1607 }
1608
1609 // Handle Dashicons
1610 if ( in_array( $library, [ 'dashicons' ], true ) ) {
1611 if ( is_string( $value ) && ! empty( $value ) ) {
1612 $icon_class = 'dashicons dashicons-' . esc_attr( $value );
1613
1614 $html_class = ! empty( $html_attributes['class'] ) ? ' ' . $html_attributes['class'] : '';
1615 $aria_hidden = isset( $html_attributes['aria-hidden'] ) ? ' aria-hidden="' . esc_attr( $html_attributes['aria-hidden'] ) . '"' : ' aria-hidden="true"';
1616
1617 echo '<span class="' . $icon_class . $html_class . '"' . $aria_hidden . '></span>';
1618 return;
1619 }
1620 }
1621
1622 // Handle custom CSS classes (like 'bp-icon bp-check-circle')
1623 // These are custom icon fonts or CSS-based icons defined by the theme/plugin
1624 if ( 'custom' === $library ) {
1625 if ( is_string( $value ) && ! empty( $value ) ) {
1626 $html_class = ! empty( $html_attributes['class'] ) ? ' ' . $html_attributes['class'] : '';
1627 $aria_hidden = isset( $html_attributes['aria-hidden'] ) ? ' aria-hidden="' . esc_attr( $html_attributes['aria-hidden'] ) . '"' : ' aria-hidden="true"';
1628
1629 echo '<i class="' . esc_attr( $value ) . $html_class . '"' . $aria_hidden . '></i>';
1630 return;
1631 }
1632 }
1633
1634 // If value is a plain string (might be a FontAwesome class without library specified)
1635 if ( is_string( $value ) && ! empty( $value ) && empty( $library ) ) {
1636 // Check if it looks like a FontAwesome class
1637 if ( strpos( $value, 'fa' ) !== false || strpos( $value, 'fa-' ) !== false ) {
1638 $icon_class = 'fas ' . esc_attr( $value );
1639
1640 $html_class = ! empty( $html_attributes['class'] ) ? ' ' . $html_attributes['class'] : '';
1641 $aria_hidden = isset( $html_attributes['aria-hidden'] ) ? ' aria-hidden="' . esc_attr( $html_attributes['aria-hidden'] ) . '"' : ' aria-hidden="true"';
1642
1643 echo '<i class="' . $icon_class . $html_class . '"' . $aria_hidden . '></i>';
1644 return;
1645 }
1646
1647 // Check if it looks like a dashicon
1648 if ( strpos( $value, 'dashicon' ) !== false || strpos( $value, 'dashicons-' ) !== false ) {
1649 $icon_class = 'dashicons ' . esc_attr( $value );
1650
1651 $html_class = ! empty( $html_attributes['class'] ) ? ' ' . $html_attributes['class'] : '';
1652 $aria_hidden = isset( $html_attributes['aria-hidden'] ) ? ' aria-hidden="' . esc_attr( $html_attributes['aria-hidden'] ) . '"' : ' aria-hidden="true"';
1653
1654 echo '<span class="' . $icon_class . $html_class . '"' . $aria_hidden . '></span>';
1655 return;
1656 }
1657 }
1658 }
1659 }
1660