| 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 ( ! empty( $status['pending'] ) ) { |
| 215 |
// Use home_url() instead of HTTP_HOST to avoid open-redirect via forged Host headers. |
| 216 |
$return_url = home_url( $_SERVER['REQUEST_URI'] ); |
| 217 |
// PayPal uses rm=2 (POST redirect), so item_number arrives in $_POST and is absent from the URL. |
| 218 |
// Add it explicitly so the poll-complete redirect (a plain GET) still carries item_number. |
| 219 |
if ( ! empty( $status['order_id'] ) && strpos( $return_url, 'item_number=' ) === false ) { |
| 220 |
$return_url = add_query_arg( 'item_number', $status['order_id'], $return_url ); |
| 221 |
} |
| 222 |
?> |
| 223 |
<section class="bp-thank_page"> |
| 224 |
<div class="bp-thank_page-wrapper bp-paypal-pending" |
| 225 |
data-order-id="<?php echo esc_attr( $status['order_id'] ); ?>" |
| 226 |
data-return-url="<?php echo esc_url( $return_url ); ?>"> |
| 227 |
|
| 228 |
<div class="bp-thank_page-logo"> |
| 229 |
<span class="bp-paypal-pending__spinner-wrap"> |
| 230 |
<span class="bp-paypal-pending__ring"></span> |
| 231 |
<img class="bp-paypal-pending__logo" |
| 232 |
src="<?php echo esc_url( BETTER_PAYMENT_ASSETS . '/img/paypal-2.svg' ); ?>" |
| 233 |
alt="PayPal"> |
| 234 |
</span> |
| 235 |
</div> |
| 236 |
|
| 237 |
<div class="bp-thank_page-text bp-paypal-pending__body"> |
| 238 |
<h2 class="bp-font_ibm bp-page_header bp-paypal-pending__heading"> |
| 239 |
<?php esc_html_e( 'Verifying your payment…', 'better-payment' ); ?> |
| 240 |
</h2> |
| 241 |
<p class="bp-font_ibm bp-payment_info bp-paypal-pending__sub"> |
| 242 |
<?php esc_html_e( 'Please do not close this page. This usually takes a few seconds.', 'better-payment' ); ?> |
| 243 |
</p> |
| 244 |
<div class="bp-paypal-pending__dots"> |
| 245 |
<span></span><span></span><span></span> |
| 246 |
</div> |
| 247 |
</div> |
| 248 |
|
| 249 |
<div class="bp-paypal-pending__bar"> |
| 250 |
<div class="bp-paypal-pending__bar-inner"></div> |
| 251 |
</div> |
| 252 |
|
| 253 |
</div> |
| 254 |
</section> |
| 255 |
<?php |
| 256 |
} elseif ( $status ) { |
| 257 |
self::success_message_template( $settings, $status ); |
| 258 |
$redirection_url_success = ! empty( $settings['better_payment_form_success_page_url']['url'] ) ? esc_url( $settings['better_payment_form_success_page_url']['url'] ) : ''; |
| 259 |
|
| 260 |
if( $redirection_url_success ){ |
| 261 |
?> |
| 262 |
<script> |
| 263 |
setTimeout(function(){ |
| 264 |
window.location.replace("<?php echo esc_url( $redirection_url_success ); ?>"); |
| 265 |
}, 2000); |
| 266 |
</script> |
| 267 |
<?php |
| 268 |
} |
| 269 |
} |
| 270 |
self::remove_arg(); |
| 271 |
|
| 272 |
return $status; |
| 273 |
} |
| 274 |
|
| 275 |
/** |
| 276 |
* Paypal payment success |
| 277 |
* |
| 278 |
* The DB write happens exclusively in handle_paypal_ipn() after PayPal verifies |
| 279 |
* the IPN post-back. This method is read-only: it never writes to the DB. |
| 280 |
* |
| 281 |
* Display data priority: |
| 282 |
* 1. DB row (IPN already fired and confirmed) — authoritative. |
| 283 |
* 2. PayPal return-URL params ($_REQUEST) — for display only when IPN hasn't |
| 284 |
* fired yet (local dev, race condition). Safe because no DB write occurs here. |
| 285 |
* |
| 286 |
* @since 0.0.1 |
| 287 |
*/ |
| 288 |
public static function paypal_payment_success( $settings = [] ) { |
| 289 |
$item_number = ! empty( $_REQUEST['item_number'] ) ? sanitize_text_field( $_REQUEST['item_number'] ) : ''; |
| 290 |
|
| 291 |
if ( empty( $item_number ) ) { |
| 292 |
return false; |
| 293 |
} |
| 294 |
|
| 295 |
global $wpdb; |
| 296 |
$table = "{$wpdb->prefix}better_payment"; |
| 297 |
$row = $wpdb->get_row( |
| 298 |
$wpdb->prepare( |
| 299 |
"SELECT transaction_id, status, email, amount, currency FROM $table WHERE order_id = %s LIMIT 1", |
| 300 |
$item_number |
| 301 |
) |
| 302 |
); |
| 303 |
|
| 304 |
// No matching order — reject (prevents fake success display with forged item_number). |
| 305 |
if ( empty( $row ) ) { |
| 306 |
return false; |
| 307 |
} |
| 308 |
|
| 309 |
// IPN confirmed — return verified DB data. |
| 310 |
if ( $row->status === 'Completed' ) { |
| 311 |
return [ |
| 312 |
'amount' => floatval( $row->amount ), |
| 313 |
'email' => sanitize_email( $row->email ), |
| 314 |
'transaction_id' => sanitize_text_field( $row->transaction_id ), |
| 315 |
'currency' => sanitize_text_field( $row->currency ), |
| 316 |
'method' => 'paypal', |
| 317 |
]; |
| 318 |
} |
| 319 |
|
| 320 |
// Order exists but IPN hasn't arrived yet — signal pending so JS can poll. |
| 321 |
return [ 'pending' => true, 'order_id' => $item_number ]; |
| 322 |
} |
| 323 |
|
| 324 |
/** |
| 325 |
* AJAX: check whether a PayPal order has been confirmed by IPN. |
| 326 |
* |
| 327 |
* Called by the frontend polling loop after the user lands on the return URL |
| 328 |
* before the IPN fires. Returns {status:'pending'} or {status:'completed'}. |
| 329 |
* |
| 330 |
* Lives on Handler (not Actions) so it can be registered unconditionally — |
| 331 |
* PayPal payments flow through the block/campaign path without Elementor. |
| 332 |
*/ |
| 333 |
public static function check_paypal_status() { |
| 334 |
check_ajax_referer( 'better-payment', 'security' ); |
| 335 |
|
| 336 |
$order_id = ! empty( $_POST['order_id'] ) ? sanitize_text_field( $_POST['order_id'] ) : ''; |
| 337 |
|
| 338 |
if ( empty( $order_id ) ) { |
| 339 |
wp_send_json_error( [ 'message' => 'Missing order_id' ] ); |
| 340 |
} |
| 341 |
|
| 342 |
global $wpdb; |
| 343 |
$table = "{$wpdb->prefix}better_payment"; |
| 344 |
$row = $wpdb->get_row( |
| 345 |
$wpdb->prepare( |
| 346 |
"SELECT status FROM $table WHERE order_id = %s LIMIT 1", |
| 347 |
$order_id |
| 348 |
) |
| 349 |
); |
| 350 |
|
| 351 |
if ( empty( $row ) ) { |
| 352 |
wp_send_json_error( [ 'message' => 'Order not found' ] ); |
| 353 |
} |
| 354 |
|
| 355 |
if ( $row->status === 'Completed' ) { |
| 356 |
wp_send_json_success( [ 'status' => 'completed' ] ); |
| 357 |
} |
| 358 |
|
| 359 |
wp_send_json_success( [ 'status' => 'pending' ] ); |
| 360 |
} |
| 361 |
|
| 362 |
/** |
| 363 |
* PayPal IPN listener. |
| 364 |
* |
| 365 |
* PayPal POSTs the raw IPN body here server-to-server. We echo it back with |
| 366 |
* cmd=_notify-validate; only a VERIFIED response from PayPal's servers triggers |
| 367 |
* the DB write. The browser return URL (paypal_payment_success) never writes. |
| 368 |
* |
| 369 |
* @since 2.1.3 |
| 370 |
*/ |
| 371 |
public static function handle_paypal_ipn() { |
| 372 |
$raw_post = file_get_contents( 'php://input' ); |
| 373 |
|
| 374 |
if ( empty( $raw_post ) ) { |
| 375 |
status_header( 400 ); |
| 376 |
exit; |
| 377 |
} |
| 378 |
|
| 379 |
$data = []; |
| 380 |
wp_parse_str( $raw_post, $data ); |
| 381 |
|
| 382 |
// PayPal includes test_ipn=1 for sandbox notifications. |
| 383 |
$verify_url = ! empty( $data['test_ipn'] ) |
| 384 |
? 'https://ipnpb.sandbox.paypal.com/cgi-bin/webscr' |
| 385 |
: 'https://ipnpb.paypal.com/cgi-bin/webscr'; |
| 386 |
|
| 387 |
$response = wp_remote_post( |
| 388 |
$verify_url, |
| 389 |
[ |
| 390 |
'body' => 'cmd=_notify-validate&' . $raw_post, |
| 391 |
'timeout' => 30, |
| 392 |
'sslverify' => true, |
| 393 |
'headers' => [ 'Content-Type' => 'application/x-www-form-urlencoded' ], |
| 394 |
] |
| 395 |
); |
| 396 |
|
| 397 |
// Always respond 200 to PayPal to prevent retries, but only act on VERIFIED. |
| 398 |
if ( is_wp_error( $response ) || wp_remote_retrieve_body( $response ) !== 'VERIFIED' ) { |
| 399 |
status_header( 200 ); |
| 400 |
exit; |
| 401 |
} |
| 402 |
|
| 403 |
$data = array_map( 'sanitize_text_field', $data ); |
| 404 |
|
| 405 |
if ( empty( $data['payment_status'] ) || empty( $data['item_number'] ) || $data['payment_status'] !== 'Completed' ) { |
| 406 |
status_header( 200 ); |
| 407 |
exit; |
| 408 |
} |
| 409 |
|
| 410 |
global $wpdb; |
| 411 |
$table = "{$wpdb->prefix}better_payment"; |
| 412 |
$results = $wpdb->get_row( |
| 413 |
$wpdb->prepare( |
| 414 |
"SELECT id, amount, currency, form_fields_info, referer FROM $table WHERE order_id = %s AND status IS NULL LIMIT 1", |
| 415 |
$data['item_number'] |
| 416 |
) |
| 417 |
); |
| 418 |
|
| 419 |
if ( empty( $results->id ) ) { |
| 420 |
status_header( 200 ); |
| 421 |
exit; |
| 422 |
} |
| 423 |
|
| 424 |
// Validate receiver_email matches the merchant's configured PayPal email. |
| 425 |
$form_info = maybe_unserialize( $results->form_fields_info ); |
| 426 |
$expected_email = ! empty( $form_info['paypal_business_email'] ) ? strtolower( $form_info['paypal_business_email'] ) : ''; |
| 427 |
$receiver = ! empty( $data['receiver_email'] ) ? strtolower( $data['receiver_email'] ) : ( ! empty( $data['business'] ) ? strtolower( $data['business'] ) : '' ); |
| 428 |
|
| 429 |
if ( $expected_email && $receiver && $expected_email !== $receiver ) { |
| 430 |
status_header( 200 ); |
| 431 |
exit; |
| 432 |
} |
| 433 |
|
| 434 |
// Validate the paid amount is not less than the expected order amount. |
| 435 |
$paid_amount = ! empty( $data['mc_gross'] ) ? floatval( $data['mc_gross'] ) : 0; |
| 436 |
if ( $paid_amount < floatval( $results->amount ) ) { |
| 437 |
status_header( 200 ); |
| 438 |
exit; |
| 439 |
} |
| 440 |
|
| 441 |
// Validate currency matches. |
| 442 |
$paid_currency = ! empty( $data['mc_currency'] ) ? strtoupper( $data['mc_currency'] ) : ''; |
| 443 |
if ( $paid_currency && $results->currency && strtoupper( $results->currency ) !== $paid_currency ) { |
| 444 |
status_header( 200 ); |
| 445 |
exit; |
| 446 |
} |
| 447 |
|
| 448 |
$txn_id = ! empty( $data['txn_id'] ) ? $data['txn_id'] : ''; |
| 449 |
|
| 450 |
// Prevent txn_id replay: reject if this transaction ID was already recorded. |
| 451 |
if ( $txn_id ) { |
| 452 |
$existing = $wpdb->get_var( |
| 453 |
$wpdb->prepare( |
| 454 |
"SELECT id FROM $table WHERE transaction_id = %s LIMIT 1", |
| 455 |
$txn_id |
| 456 |
) |
| 457 |
); |
| 458 |
if ( $existing ) { |
| 459 |
status_header( 200 ); |
| 460 |
exit; |
| 461 |
} |
| 462 |
} |
| 463 |
|
| 464 |
$payer_email = ! empty( $data['payer_email'] ) ? sanitize_email( $data['payer_email'] ) : ''; |
| 465 |
|
| 466 |
$updated = $wpdb->update( |
| 467 |
$table, |
| 468 |
[ |
| 469 |
'transaction_id' => $txn_id, |
| 470 |
'status' => $data['payment_status'], |
| 471 |
'email' => $payer_email, |
| 472 |
'customer_info' => maybe_serialize( $data ), |
| 473 |
], |
| 474 |
[ 'ID' => $results->id ] |
| 475 |
); |
| 476 |
|
| 477 |
if ( false !== $updated ) { |
| 478 |
$is_elementor_form = ! empty( $results->referer ) && $results->referer === 'elementor-form' ? 1 : 0; |
| 479 |
|
| 480 |
// Rebuild the e-mail settings persisted at payment-create time. IPN runs |
| 481 |
// server-to-server with no live widget context, so without this the body |
| 482 |
// would collapse to the bare transaction id (every section flag defaults |
| 483 |
// to 0). Legacy / pending rows created before this fix fall back to []. |
| 484 |
$email_settings = ! empty( $form_info['email_settings'] ) && is_array( $form_info['email_settings'] ) |
| 485 |
? $form_info['email_settings'] |
| 486 |
: []; |
| 487 |
|
| 488 |
// Mirror the Stripe / Paystack gate: honour the form's "Send Email" toggle, |
| 489 |
// and always e-mail for Elementor Pro Form submissions. |
| 490 |
if ( |
| 491 |
( isset( $email_settings['better_payment_form_email_enable'] ) && 'yes' === $email_settings['better_payment_form_email_enable'] ) |
| 492 |
|| $is_elementor_form |
| 493 |
) { |
| 494 |
self::better_email_notification( $txn_id, $payer_email, $email_settings, 'PayPal', $results->form_fields_info, $is_elementor_form ); |
| 495 |
} |
| 496 |
} |
| 497 |
|
| 498 |
status_header( 200 ); |
| 499 |
exit; |
| 500 |
} |
| 501 |
|
| 502 |
/** |
| 503 |
* Stripe payment success |
| 504 |
* |
| 505 |
* @since 0.0.1 |
| 506 |
*/ |
| 507 |
public static function stripe_payment_success( $settings = [] ) { |
| 508 |
|
| 509 |
$data = $_REQUEST; |
| 510 |
|
| 511 |
if ( !empty( $data[ 'better_payment_stripe_id' ] ) ) { |
| 512 |
global $wpdb; |
| 513 |
$table = "{$wpdb->prefix}better_payment"; |
| 514 |
$results = $wpdb->get_row( |
| 515 |
$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' ] ) ) |
| 516 |
); |
| 517 |
|
| 518 |
if ( !empty( $results->obj_id ) && !empty( $settings[ 'better_payment_stripe_secret_key' ] ) ) { |
| 519 |
$header = array( |
| 520 |
'Authorization' => 'Basic ' . base64_encode( sanitize_text_field( $settings[ 'better_payment_stripe_secret_key' ] ) . ':' ), |
| 521 |
'Stripe-Version' => '2019-05-16', |
| 522 |
); |
| 523 |
|
| 524 |
$request = [ |
| 525 |
'expand' => [ |
| 526 |
'subscription.latest_invoice.payment_intent', |
| 527 |
'payment_intent' |
| 528 |
] |
| 529 |
]; |
| 530 |
$form_fields_info = maybe_unserialize($results->form_fields_info); |
| 531 |
$is_payment_recurring = ! empty( $form_fields_info['mode'] ) && 'subscription' === $form_fields_info['mode']; |
| 532 |
$is_payment_split_payment = ( $is_payment_recurring ) && ( ! empty( $form_fields_info['is_payment_split_payment'] ) && 1 === intval( $form_fields_info['is_payment_split_payment'] ) ); |
| 533 |
|
| 534 |
$action_data = [ |
| 535 |
'form_fields_info' => $form_fields_info, |
| 536 |
'is_payment_recurring' => $is_payment_recurring, |
| 537 |
'is_payment_split_payment' => $is_payment_split_payment, |
| 538 |
'checkout_session_id' => $results->obj_id, |
| 539 |
]; |
| 540 |
|
| 541 |
$response = wp_safe_remote_post( |
| 542 |
'https://api.stripe.com/v1/checkout/sessions/' . $results->obj_id, |
| 543 |
array( |
| 544 |
'method' => 'GET', |
| 545 |
'headers' => $header, |
| 546 |
'timeout' => 70, |
| 547 |
'body' => $request |
| 548 |
) |
| 549 |
); |
| 550 |
|
| 551 |
if ( is_wp_error( $response ) || empty( $response[ 'body' ] ) ) { |
| 552 |
return new \WP_Error( 'stripe_error', __( 'There was a problem connecting to the Stripe API endpoint.', 'better-payment' ) ); |
| 553 |
} |
| 554 |
|
| 555 |
$response = json_decode( $response[ 'body' ] ); |
| 556 |
$transaction_id = ! empty( $results->transaction_id ) ? sanitize_text_field( $results->transaction_id ) : ''; |
| 557 |
|
| 558 |
if ( $is_payment_recurring && ! empty( $response->subscription->id ) ) { |
| 559 |
$transaction_id = sanitize_text_field( $response->subscription->id ); |
| 560 |
$subscription_obj = $response->subscription; |
| 561 |
$form_fields_info['subscription_id'] = sanitize_text_field( $transaction_id ); |
| 562 |
$form_fields_info['subscription_customer_id'] = ! empty( $response->customer ) ? sanitize_text_field( $response->customer ) : ''; |
| 563 |
$form_fields_info['subscription_plan_id'] = ! empty( $subscription_obj->items->data[0]->plan->id ) ? sanitize_text_field( $subscription_obj->items->data[0]->plan->id ) : ''; |
| 564 |
$form_fields_info['subscription_interval'] = ! empty( $subscription_obj->items->data[0]->plan->interval_count ) ? intval( $subscription_obj->items->data[0]->plan->interval_count ) : ''; |
| 565 |
$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']; |
| 566 |
$form_fields_info['subscription_current_period_start'] = ! empty( $subscription_obj->current_period_start ) ? intval( $subscription_obj->current_period_start ) : 0; |
| 567 |
$form_fields_info['subscription_current_period_end'] = ! empty( $subscription_obj->current_period_end ) ? intval( $subscription_obj->current_period_end ) : 0; |
| 568 |
$form_fields_info['subscription_status'] = sanitize_text_field( $response->status ); |
| 569 |
$form_fields_info['subscription_created_date'] = sanitize_text_field( $subscription_obj->created ); |
| 570 |
} |
| 571 |
|
| 572 |
if ( isset( $response->error->message ) ) { |
| 573 |
return new \WP_Error( 'stripe_error', __( 'There was a problem connecting to the Stripe API endpoint.', 'better-payment' ) ); |
| 574 |
} |
| 575 |
|
| 576 |
$customer_email = $is_payment_recurring && ( ! empty( $response->customer_email ) ) ? sanitize_email( $response->customer_email ) : ''; |
| 577 |
$customer_email_optional = ''; |
| 578 |
if ( |
| 579 |
isset( $response->payment_intent ) && |
| 580 |
isset( $response->payment_intent->charges ) && |
| 581 |
isset( $response->payment_intent->charges->data ) && |
| 582 |
! empty( $response->payment_intent->charges->data ) |
| 583 |
) { |
| 584 |
$charge = current( $response->payment_intent->charges->data ); |
| 585 |
|
| 586 |
if ( |
| 587 |
isset( $charge->billing_details ) && |
| 588 |
isset( $charge->billing_details->email ) && |
| 589 |
! empty( $charge->billing_details->email ) |
| 590 |
) { |
| 591 |
$customer_email_optional = sanitize_email( $charge->billing_details->email ); |
| 592 |
} |
| 593 |
} |
| 594 |
|
| 595 |
$form_fields_info['is_coupon_applied'] = 0; |
| 596 |
$exact_paid_amount = ! empty( $response->amount_total ) ? floatval( $response->amount_total ) : $results->amount * 100; |
| 597 |
$exact_paid_amount = $exact_paid_amount / 100; |
| 598 |
$form_fields_info['exact_paid_amount'] = $exact_paid_amount; |
| 599 |
if( (int)$exact_paid_amount != (int)$results->amount ) { |
| 600 |
$form_fields_info['paid_amount_diff'] = $results->amount - $exact_paid_amount; |
| 601 |
$form_fields_info['is_coupon_applied'] = 1; |
| 602 |
} |
| 603 |
|
| 604 |
$updated = $wpdb->update( |
| 605 |
$table, |
| 606 |
array( |
| 607 |
'amount' => $exact_paid_amount, |
| 608 |
'status' => sanitize_text_field( $response->payment_status ), |
| 609 |
'email' => $is_payment_recurring ? $customer_email : $customer_email_optional, |
| 610 |
'customer_info' => maybe_serialize( $response ), |
| 611 |
'form_fields_info' => maybe_serialize( $form_fields_info ), |
| 612 |
'transaction_id' => $transaction_id, |
| 613 |
), |
| 614 |
array( 'ID' => $results->id ) |
| 615 |
); |
| 616 |
|
| 617 |
do_action('better_payment/stripe_payment/success', $action_data); |
| 618 |
do_action( 'better_payment/payment_confirmed', (int) $results->id ); |
| 619 |
|
| 620 |
$frontend_data = [ |
| 621 |
'amount' => $exact_paid_amount, |
| 622 |
'email' => $is_payment_recurring ? $customer_email : $customer_email_optional, |
| 623 |
'transaction_id' => $transaction_id, |
| 624 |
'currency' => ! empty( $results->currency ) ? $results->currency : __( 'USD', 'better-payment' ), |
| 625 |
'method' => 'stripe', |
| 626 |
'is_payment_recurring' => $is_payment_recurring, |
| 627 |
'is_payment_split_payment' => $is_payment_split_payment, |
| 628 |
'is_payment_mixed' => ! empty( $form_fields_info['is_payment_mixed'] ) ? intval( $form_fields_info['is_payment_mixed'] ) : 0, |
| 629 |
'mixed_payment_selected_type' => ! empty( $form_fields_info['mixed_payment_selected_type'] ) ? sanitize_text_field( $form_fields_info['mixed_payment_selected_type'] ) : '', |
| 630 |
]; |
| 631 |
|
| 632 |
if ( $is_payment_split_payment ) { |
| 633 |
$total_amount = ! empty( $form_fields_info['split_payment_total_amount'] ) |
| 634 |
? sanitize_text_field( $form_fields_info['split_payment_total_amount'] ) |
| 635 |
: 0; |
| 636 |
$total_installment = ! empty( $form_fields_info['split_payment_installment_iteration'] ) |
| 637 |
? sanitize_text_field( $form_fields_info['split_payment_installment_iteration'] ) |
| 638 |
: 1; |
| 639 |
|
| 640 |
// $frontend_data['amount'] = floatval( $total_amount / $total_installment ); |
| 641 |
$frontend_data['total_amount'] = $total_amount; |
| 642 |
} |
| 643 |
|
| 644 |
if ( false !== $updated ) { |
| 645 |
//Send email notification |
| 646 |
$better_customer_email = $is_payment_recurring ? $customer_email : $customer_email_optional; |
| 647 |
|
| 648 |
if ( |
| 649 |
(isset($settings[ 'better_payment_form_email_enable' ]) && $settings[ 'better_payment_form_email_enable' ] == 'yes' ) |
| 650 |
|| ( $results->referer === 'elementor-form' ) |
| 651 |
) { |
| 652 |
$is_elementor_form = ! empty( $results->referer ) && $results->referer === 'elementor-form' ? 1 : 0; |
| 653 |
self::better_email_notification($transaction_id, $better_customer_email, $settings, 'Stripe', $results->form_fields_info, $is_elementor_form); |
| 654 |
} |
| 655 |
|
| 656 |
return $frontend_data; |
| 657 |
} |
| 658 |
} |
| 659 |
} |
| 660 |
return false; |
| 661 |
} |
| 662 |
|
| 663 |
/** |
| 664 |
* Paystack payment success |
| 665 |
* |
| 666 |
* @since 0.0.1 |
| 667 |
*/ |
| 668 |
public static function paystack_payment_success( $settings = [] ) { |
| 669 |
$data = $_REQUEST; |
| 670 |
|
| 671 |
if ( ! empty( $data[ 'better_payment_paystack_id' ] ) ) { |
| 672 |
global $wpdb; |
| 673 |
$table = "{$wpdb->prefix}better_payment"; |
| 674 |
$results = $wpdb->get_row( |
| 675 |
$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' ] ) ) |
| 676 |
); |
| 677 |
|
| 678 |
$header_info = array( |
| 679 |
'Authorization' => 'Bearer ' . sanitize_text_field( $settings[ 'better_payment_paystack_secret_key' ] ), |
| 680 |
"Cache-Control: no-cache", |
| 681 |
); |
| 682 |
|
| 683 |
$response = wp_safe_remote_get( |
| 684 |
'https://api.paystack.co/transaction/verify/'. sanitize_text_field( $data[ 'reference' ] ), |
| 685 |
array( |
| 686 |
'headers' => $header_info, |
| 687 |
'timeout' => 70, |
| 688 |
) |
| 689 |
); |
| 690 |
|
| 691 |
$response = json_decode(wp_remote_retrieve_body($response)); |
| 692 |
|
| 693 |
if ( ! empty( $response->status ) ) { |
| 694 |
$updated = $wpdb->update( |
| 695 |
$table, |
| 696 |
array( |
| 697 |
'status' => ! empty( $response->data->status ) ? sanitize_text_field( $response->data->status ) : '', |
| 698 |
'amount' => ! empty( $response->data->amount ) ? floatval( ( $response->data->amount ) / 100 ) : 0, |
| 699 |
'obj_id' => ! empty( $response->data->id ) ? sanitize_text_field( $response->data->id ) : '', |
| 700 |
'transaction_id' => ! empty( $response->data->reference ) ? sanitize_text_field( $response->data->reference ) : '', |
| 701 |
'customer_info' => ! empty( $response->data->customer ) ? maybe_serialize( $response->data->customer ) : '', |
| 702 |
'email' => ! empty( $response->data->customer->email ) ? sanitize_email( $response->data->customer->email ) : '', |
| 703 |
), |
| 704 |
array( 'ID' => $results->id ) |
| 705 |
); |
| 706 |
do_action( 'better_payment/payment_confirmed', (int) $results->id ); |
| 707 |
} |
| 708 |
|
| 709 |
$better_customer_email = ! empty( $response->data->customer->email ) ? maybe_serialize( $response->data->customer->email ) : ''; |
| 710 |
$transaction_id = ! empty( $response->data->reference ) ? sanitize_text_field( $response->data->reference ) : ''; |
| 711 |
|
| 712 |
$frontend_data = [ |
| 713 |
'amount' => ! empty( $response->data->amount ) ? floatval( ( $response->data->amount ) / 100 ) : 0, |
| 714 |
'email' => ! empty( $better_customer_email ) ? $better_customer_email : '', |
| 715 |
'transaction_id' => $transaction_id, |
| 716 |
'currency' => ! empty( $response->data->currency ) ? sanitize_text_field( $response->data->currency ) : __( 'USD', 'better-payment' ), |
| 717 |
'method' => 'paystack', |
| 718 |
]; |
| 719 |
|
| 720 |
if ( ! empty( $updated ) && $better_customer_email ) { |
| 721 |
//Send email notification |
| 722 |
if ( |
| 723 |
(isset($settings[ 'better_payment_form_email_enable' ]) && $settings[ 'better_payment_form_email_enable' ] == 'yes' ) |
| 724 |
|| ( $results->referer === 'elementor-form' ) |
| 725 |
) { |
| 726 |
$is_elementor_form = ! empty( $results->referer ) && $results->referer === 'elementor-form' ? 1 : 0; |
| 727 |
self::better_email_notification($transaction_id, $better_customer_email, $settings, 'Paystack', $results->form_fields_info, $is_elementor_form); |
| 728 |
} |
| 729 |
|
| 730 |
do_action( 'better_payment/payment/success', sanitize_text_field( $data['better_payment_paystack_id'] ?? '' ), (int) $results->id, 'paystack' ); |
| 731 |
|
| 732 |
return $frontend_data; |
| 733 |
} |
| 734 |
} |
| 735 |
return false; |
| 736 |
} |
| 737 |
|
| 738 |
/** |
| 739 |
* Success message template |
| 740 |
* |
| 741 |
* @since 0.0.1 |
| 742 |
*/ |
| 743 |
public static function success_message_template( $settings = [], $tr_id = '' ) { |
| 744 |
if ( empty( $tr_id ) || is_wp_error($tr_id)) { |
| 745 |
return false; |
| 746 |
} |
| 747 |
wp_enqueue_script('better-payment-admin-script'); |
| 748 |
$image_url = BETTER_PAYMENT_ASSETS . '/img/success.svg'; |
| 749 |
$show_icon = 0; |
| 750 |
$default_icon = 1; |
| 751 |
$helper_obj = new Helper(); |
| 752 |
|
| 753 |
$store_name = ( isset( $settings['better_payment_form_payment_source'] ) && $settings['better_payment_form_payment_source'] === 'manual' && !empty( $settings['better_payment_form_title'] ) ) |
| 754 |
? esc_html($settings['better_payment_form_title']) |
| 755 |
: esc_html( get_bloginfo('name') ); |
| 756 |
|
| 757 |
$payment_desc_text = !empty( $settings['better_payment_form_success_message_heading'] ) |
| 758 |
? esc_html($settings['better_payment_form_success_message_heading']) |
| 759 |
: esc_html( __('You paid', 'better-payment') . ' [currency_symbol][amount] ' . __('to', 'better-payment') . ' [store_name]'); |
| 760 |
|
| 761 |
$bp__currency_symbol = esc_html( ! empty( $tr_id['currency'] ) ? $helper_obj->get_currency_symbol( $tr_id['currency'] ) : '' ); |
| 762 |
|
| 763 |
$payment_desc_text = str_replace( '[currency_symbol]', '<span class="bp-bold">' . $bp__currency_symbol . '</span>', $payment_desc_text ); |
| 764 |
|
| 765 |
$payment_desc_text = str_replace( '[amount]', '<span class="bp-bold">' . esc_html( ! empty( $tr_id['amount'] ) ? $tr_id['amount'] : 0 ) . '</span>', $payment_desc_text ); |
| 766 |
|
| 767 |
$payment_desc_text = str_replace( '[store_name]', '<span class="bp-bold">' . esc_html( $store_name ) . '</span>', $payment_desc_text ); |
| 768 |
|
| 769 |
$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]'); |
| 770 |
|
| 771 |
$payment_mail_text = str_replace( '[customer_email]', '<span class="bp-bold">' . esc_html( ! empty( $tr_id['email'] ) ? $tr_id['email'] : '' ) . '</span>', $payment_mail_text ); |
| 772 |
|
| 773 |
if ( !empty( $settings[ 'better_payment_form_success_message_icon' ][ 'library' ] ) ) { |
| 774 |
if ( $settings[ 'better_payment_form_success_message_icon' ][ 'library' ] == 'svg' ) { |
| 775 |
$image_url = $settings[ 'better_payment_form_success_message_icon' ][ 'value' ][ 'url' ]; |
| 776 |
$default_icon = 0; |
| 777 |
} else { |
| 778 |
$show_icon = 1; |
| 779 |
$image_url = $settings[ 'better_payment_form_success_message_icon' ][ 'value' ]; |
| 780 |
$default_icon = 0; |
| 781 |
} |
| 782 |
} |
| 783 |
|
| 784 |
|
| 785 |
$allowed_payment_methods = [ |
| 786 |
'paypal' => BETTER_PAYMENT_ASSETS . '/img/paypal-2.svg', |
| 787 |
'stripe' => BETTER_PAYMENT_ASSETS . '/img/stripe-2.svg', |
| 788 |
'paystack' => BETTER_PAYMENT_ASSETS . '/img/paystack-2.svg', |
| 789 |
]; |
| 790 |
$payment_method_logo = isset( $tr_id['method'] ) && isset( $allowed_payment_methods[ $tr_id['method'] ] ) ? $allowed_payment_methods[ $tr_id['method'] ] : ''; |
| 791 |
|
| 792 |
$better_payment_form_success_message_thanks = !empty( $settings['better_payment_form_success_message_thanks'] ) |
| 793 |
? esc_html( $settings['better_payment_form_success_message_thanks'] ) |
| 794 |
: esc_html__('Thank You!', 'better-payment'); |
| 795 |
$better_payment_form_success_message_transaction = !empty( $settings['better_payment_form_success_message_transaction'] ) |
| 796 |
? esc_html__( $settings['better_payment_form_success_message_transaction'], 'better-payment' ) |
| 797 |
: esc_html__('Transaction ID', 'better-payment'); |
| 798 |
$better_payment_form_success_message_amount_text = !empty( $settings['better_payment_form_success_message_amount_text'] ) |
| 799 |
? esc_html( $settings['better_payment_form_success_message_amount_text'] ) |
| 800 |
: esc_html__( 'Amount', 'better-payment' ); |
| 801 |
$better_payment_form_success_message_currency_text = !empty( $settings['better_payment_form_success_message_currency_text'] ) |
| 802 |
? esc_html( $settings['better_payment_form_success_message_currency_text'] ) |
| 803 |
: esc_html__( 'Currency', 'better-payment' ); |
| 804 |
$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' ); |
| 805 |
$better_payment_form_success_message_pay_type_text = !empty( $settings['better_payment_form_success_message_pay_type_text'] ) |
| 806 |
? esc_html( $settings['better_payment_form_success_message_pay_type_text'] ) |
| 807 |
: esc_html__( 'Payment Type', 'better-payment' ); |
| 808 |
$better_payment_form_payment_type = !empty( $settings['better_payment_form_payment_type'] ) |
| 809 |
? esc_html( $settings['better_payment_form_payment_type'] ) |
| 810 |
: ''; |
| 811 |
if ( ! empty( $better_payment_form_payment_type ) ) { |
| 812 |
if ( 'one-time' === $better_payment_form_payment_type ) { |
| 813 |
$better_payment_form_payment_type_value = esc_html__( 'One Time Payment', 'better-payment' ); |
| 814 |
} elseif ( 'recurring' === $better_payment_form_payment_type ) { |
| 815 |
$better_payment_form_payment_type_value = esc_html__( 'Recurring Payment', 'better-payment' ); |
| 816 |
} elseif ( 'mixed' === $better_payment_form_payment_type ) { |
| 817 |
$mixed_payment_selected_type = ! empty( $tr_id['mixed_payment_selected_type'] ) ? sanitize_text_field( $tr_id['mixed_payment_selected_type'] ) : ''; |
| 818 |
$is_mixed_recurring = 'recurring' === $mixed_payment_selected_type; |
| 819 |
|
| 820 |
if ( empty( $mixed_payment_selected_type ) ) { |
| 821 |
$is_mixed_recurring = ! empty( $tr_id['is_payment_recurring'] ) && empty( $tr_id['is_payment_split_payment'] ); |
| 822 |
} |
| 823 |
|
| 824 |
$better_payment_form_payment_type_value = $is_mixed_recurring |
| 825 |
? esc_html__( 'Recurring Payment', 'better-payment' ) |
| 826 |
: esc_html__( 'One Time Payment', 'better-payment' ); |
| 827 |
} else { |
| 828 |
$better_payment_form_payment_type_value = esc_html__( 'Split Payment', 'better-payment' ); |
| 829 |
} |
| 830 |
} |
| 831 |
$better_payment_form_success_message_merchant_details_text = !empty( $settings['better_payment_form_success_message_merchant_details_text'] ) |
| 832 |
? esc_html( $settings['better_payment_form_success_message_merchant_details_text'] ) |
| 833 |
: esc_html__( 'Merchant Details', 'better-payment' ); |
| 834 |
$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'] ) |
| 835 |
? esc_html($settings['better_payment_form_title']) |
| 836 |
: esc_html( get_bloginfo( 'name' ) ); |
| 837 |
$better_payment_form_success_message_paid_amount_text = !empty( $settings['better_payment_form_success_message_paid_amount_text'] ) |
| 838 |
? esc_html( $settings['better_payment_form_success_message_paid_amount_text'] ) |
| 839 |
: esc_html__( 'Paid Amount', 'better-payment' ); |
| 840 |
$better_payment_form_success_message_purchase_details_text = !empty( $settings['better_payment_form_success_message_purchase_details_text'] ) |
| 841 |
? esc_html( $settings['better_payment_form_success_message_purchase_details_text'] ) |
| 842 |
: esc_html__( 'Purchase Details', 'better-payment' ); |
| 843 |
$better_payment_form_success_message_print_text = !empty( $settings['better_payment_form_success_message_print_text'] ) |
| 844 |
? esc_html( $settings['better_payment_form_success_message_print_text'] ) |
| 845 |
: esc_html__( 'Print', 'better-payment' ); |
| 846 |
$better_payment_form_success_message_view_details_btn_text = !empty( $settings['better_payment_form_success_message_view_details_btn_text'] ) |
| 847 |
? esc_html( $settings['better_payment_form_success_message_view_details_btn_text'] ) |
| 848 |
: esc_html__( 'View Details', 'better-payment' ); |
| 849 |
$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)'; |
| 850 |
?> |
| 851 |
<section class="bp-thank_page"> |
| 852 |
<div class="bp-thank_page-wrapper"> |
| 853 |
<div class="bp-thank_page-logo"> |
| 854 |
<?php if( $default_icon ): ?> |
| 855 |
<span class="bp-thank_page-logo_wrapper"> |
| 856 |
<img src="<?php echo esc_url( BETTER_PAYMENT_ASSETS . '/img/success-2.svg' ); ?>" alt="Better Payment logo"> |
| 857 |
</span> |
| 858 |
<?php endif; ?> |
| 859 |
<?php if( ! $default_icon ): ?> |
| 860 |
<?php if( $show_icon ): ?> |
| 861 |
<?php |
| 862 |
// Add 'pf-block' class if this is a Gutenberg block (not Elementor) |
| 863 |
$success_wrapper_class = 'bp-thank_page-custom-logo_wrapper-success'; |
| 864 |
if ( ! empty( $settings['better_payment_form_source'] ) && 'block' === $settings['better_payment_form_source'] ) { |
| 865 |
$success_wrapper_class .= ' pf-block'; |
| 866 |
} |
| 867 |
?> |
| 868 |
<div class="<?php echo esc_attr( $success_wrapper_class ); ?>"> |
| 869 |
<?php |
| 870 |
// Render icon safely (handles FontAwesome, Dashicons, SVG with or without Elementor) |
| 871 |
if (!empty($settings['better_payment_form_success_message_icon'])) { |
| 872 |
self::render_icon($settings['better_payment_form_success_message_icon'], ['aria-hidden' => 'true']); |
| 873 |
} else { |
| 874 |
// Fallback to default icons |
| 875 |
echo '<i class="' . esc_attr($image_url) . '"></i>'; |
| 876 |
} |
| 877 |
?> |
| 878 |
</div> |
| 879 |
<?php endif; ?> |
| 880 |
<?php if( ! $show_icon ): ?> |
| 881 |
<span class="bp-thank_page-logo_wrapper"> |
| 882 |
<img src="<?php echo esc_url($image_url); ?>" alt="Success logo"> |
| 883 |
</span> |
| 884 |
<?php endif; ?> |
| 885 |
<?php endif; ?> |
| 886 |
</div> |
| 887 |
<div class="bp-thank_page-text"> |
| 888 |
<h2 class="bp-font_ibm bp-page_header"> |
| 889 |
<?php echo wp_kses_post( $better_payment_form_success_message_thanks ); ?> |
| 890 |
<span> 🎉</span> |
| 891 |
</h2> |
| 892 |
<p class="bp-font_ibm bp-reason_for-text"> |
| 893 |
<?php echo wp_kses_post( $payment_desc_text ); ?> |
| 894 |
</p> |
| 895 |
<?php if (isset( $settings['better_payment_form_email_enable'] ) && !empty( $tr_id['email'] )): ?> |
| 896 |
<p class="bp-font_ibm bp-payment_info"> |
| 897 |
<?php echo wp_kses_post( $payment_mail_text ); ?> |
| 898 |
</p> |
| 899 |
<?php endif; ?> |
| 900 |
|
| 901 |
<div class="bp-flex bp-transaction_info-wrapper"> |
| 902 |
<p class="bp-flex bp-font_ibm bp-transaction_info"> <span class="line-height-0"> |
| 903 |
<img src="<?php echo esc_url( BETTER_PAYMENT_ASSETS . '/img/wallet.svg' ); ?>" alt="Better Payment wallet"> |
| 904 |
</span> |
| 905 |
<span> |
| 906 |
<?php echo wp_kses_post( $better_payment_form_success_message_transaction ); ?>: |
| 907 |
</span> |
| 908 |
<span class="bp-bold bp-transaction_id"><?php echo esc_html( ! empty( $tr_id['transaction_id']) ? $tr_id['transaction_id'] : '' ); ?></span> |
| 909 |
</p> |
| 910 |
|
| 911 |
<button class="bp-transaction_data-copy_btn "> |
| 912 |
<svg width="20" height="20" viewBox="0 0 20 20" |
| 913 |
fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 914 |
<path |
| 915 |
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" |
| 916 |
stroke-width="1.152" /> |
| 917 |
</svg> |
| 918 |
</button> |
| 919 |
</div> |
| 920 |
</div> |
| 921 |
|
| 922 |
<div class="bp-thank_page-info"> |
| 923 |
<ul class="bp-page_info-list"> |
| 924 |
<li class="bp-flex bp-font_ibm bp-page_info-list_item"> |
| 925 |
<span class="bp-info_content"> |
| 926 |
<?php |
| 927 |
echo wp_kses_post( $better_payment_form_success_message_amount_text ); |
| 928 |
?> |
| 929 |
</span> |
| 930 |
<span class="bp-info_content bp-bold"><?php echo $bp__currency_symbol . esc_html( ! empty( $tr_id['amount'] ) ? $tr_id['amount'] : 0 ); ?></span> |
| 931 |
</li> |
| 932 |
<li class="bp-flex bp-font_ibm bp-page_info-list_item"> |
| 933 |
<span class=" bp-info_content"> |
| 934 |
<?php |
| 935 |
echo wp_kses_post( $better_payment_form_success_message_currency_text ); |
| 936 |
?> |
| 937 |
</span> |
| 938 |
<span class="bp-info_content bp-bold"><?php echo esc_html( ! empty( $tr_id['currency'] ) ? $tr_id['currency'] : '' ); ?></span> |
| 939 |
</li> |
| 940 |
<li class="bp-flex bp-font_ibm bp-page_info-list_item"> |
| 941 |
<span class="bp-info_content"> |
| 942 |
<?php |
| 943 |
echo wp_kses_post( $better_payment_form_success_message_pay_method_text ); |
| 944 |
?> |
| 945 |
</span> |
| 946 |
<div class="bp-payment_method-logo-wrapper"> |
| 947 |
<?php if ( !empty( $payment_method_logo ) ) : ?> |
| 948 |
<img src="<?php echo esc_url( $payment_method_logo ); ?>" alt="<?php echo esc_attr( $tr_id['method'] ); ?>" class="bp-payment_method-logo"> |
| 949 |
<?php endif; ?> |
| 950 |
</div> |
| 951 |
</li> |
| 952 |
<?php if( !empty( $better_payment_form_payment_type ) ): ?> |
| 953 |
<li class="bp-flex bp-font_ibm bp-page_info-list_item"> |
| 954 |
<span class="bp-info_content"> |
| 955 |
<?php |
| 956 |
echo wp_kses_post( $better_payment_form_success_message_pay_type_text ); |
| 957 |
?> |
| 958 |
</span> |
| 959 |
<span class="bp-info_content bp-bold"><?php echo wp_kses_post( $better_payment_form_payment_type_value ); ?></span> |
| 960 |
</li> |
| 961 |
<?php endif; ?> |
| 962 |
<li class="bp-flex bp-font_ibm bp-page_info-list_item"> |
| 963 |
<span class="bp-info_content"> |
| 964 |
<?php |
| 965 |
echo wp_kses_post( $better_payment_form_success_message_merchant_details_text ); |
| 966 |
?> |
| 967 |
</span> |
| 968 |
<span class="bp-info_content bp-bold"> |
| 969 |
<?php echo wp_kses_post( $better_payment_form_success_message_merchant_details_value ); ?> |
| 970 |
</span> |
| 971 |
</li> |
| 972 |
<?php if( isset( $tr_id['is_payment_split_payment'] ) && $tr_id['is_payment_split_payment'] ): ?> |
| 973 |
<li class="bp-flex bp-font_ibm bp-page_info-list_item"> |
| 974 |
<span class="bp-info_content"> |
| 975 |
<?php |
| 976 |
echo wp_kses_post( $better_payment_form_success_message_paid_amount_text ); |
| 977 |
?> |
| 978 |
</span> |
| 979 |
<span class="bp-info_content bp-bold"> |
| 980 |
<?php echo $bp__currency_symbol . esc_html($tr_id['amount']); ?> out of <?php echo $bp__currency_symbol . esc_html($tr_id['total_amount']); ?> |
| 981 |
</span> |
| 982 |
</li> |
| 983 |
<?php endif; ?> |
| 984 |
<?php |
| 985 |
$has_woo_products = !empty($settings['better_payment_form_woocommerce_product_id']) || !empty($settings['better_payment_form_woocommerce_product_ids']); |
| 986 |
$has_fluentcart_products = !empty($settings['better_payment_form_fluentcart_product_id']) || !empty($settings['better_payment_form_fluentcart_product_ids']); |
| 987 |
|
| 988 |
if( $has_woo_products || $has_fluentcart_products ): |
| 989 |
?> |
| 990 |
<li class="bp-flex bp-font_ibm bp-page_info-list_item"> |
| 991 |
<span class="bp-info_content"> |
| 992 |
<?php |
| 993 |
echo wp_kses_post( $better_payment_form_success_message_purchase_details_text ); |
| 994 |
?> |
| 995 |
</span> |
| 996 |
<?php |
| 997 |
$product_names = []; |
| 998 |
|
| 999 |
if( !empty( $settings['better_payment_form_woocommerce_product_id'] ) ): |
| 1000 |
$product_names[] = get_the_title( $settings['better_payment_form_woocommerce_product_id'] ); |
| 1001 |
endif; |
| 1002 |
|
| 1003 |
if( !empty( $settings['better_payment_form_woocommerce_product_ids'] ) ): |
| 1004 |
$product_ids = $settings['better_payment_form_woocommerce_product_ids']; |
| 1005 |
foreach( $product_ids as $product_id ): |
| 1006 |
$product_names[] = get_the_title( $product_id ); |
| 1007 |
endforeach; |
| 1008 |
endif; |
| 1009 |
|
| 1010 |
if( !empty( $settings['better_payment_form_fluentcart_product_id'] ) && function_exists('fluentCart') && class_exists( '\FluentCart\App\Models\Product' ) ): |
| 1011 |
try { |
| 1012 |
$fluentcart_product = \FluentCart\App\Models\Product::query()->find($settings['better_payment_form_fluentcart_product_id']); |
| 1013 |
if ($fluentcart_product) { |
| 1014 |
$product_names[] = sanitize_text_field( $fluentcart_product->post_title ); |
| 1015 |
} |
| 1016 |
} catch ( \Exception $e ) { |
| 1017 |
// |
| 1018 |
} |
| 1019 |
endif; |
| 1020 |
|
| 1021 |
if( !empty( $settings['better_payment_form_fluentcart_product_ids'] ) && function_exists('fluentCart') && class_exists( '\FluentCart\App\Models\Product' ) ): |
| 1022 |
$product_ids = $settings['better_payment_form_fluentcart_product_ids']; |
| 1023 |
foreach( $product_ids as $product_id ): |
| 1024 |
try { |
| 1025 |
$fluentcart_product = \FluentCart\App\Models\Product::query()->find($product_id); |
| 1026 |
if ($fluentcart_product) { |
| 1027 |
$product_names[] = sanitize_text_field( $fluentcart_product->post_title ); |
| 1028 |
} |
| 1029 |
} catch ( \Exception $e ) { |
| 1030 |
// |
| 1031 |
} |
| 1032 |
endforeach; |
| 1033 |
endif; |
| 1034 |
|
| 1035 |
if( !empty($product_names) ): |
| 1036 |
echo '<span class="bp-info_content bp-bold">' . implode( ', ', $product_names ) . '</span>'; |
| 1037 |
endif; |
| 1038 |
?> |
| 1039 |
</li> |
| 1040 |
<?php endif; ?> |
| 1041 |
</ul> |
| 1042 |
</div> |
| 1043 |
|
| 1044 |
<div class="bp-flex bp-button_group"> |
| 1045 |
<button class="bp-flex bp-font_ibm bp-print_btn"> |
| 1046 |
<span style="line-height: 0;"> |
| 1047 |
<img src="<?php echo esc_url( BETTER_PAYMENT_ASSETS . '/img/print.svg' ); ?>" alt="Better Payment print"> |
| 1048 |
</span> |
| 1049 |
<span class="bp-font_ibm"> |
| 1050 |
<?php echo wp_kses_post( $better_payment_form_success_message_print_text ); ?> |
| 1051 |
</span> |
| 1052 |
</button> |
| 1053 |
|
| 1054 |
<div class="bp-flex bp-btn_wrapper"> |
| 1055 |
<a href="<?php echo $better_payment_form_success_page_view_details_url; ?>" target="_blank" class="bp-font_ibm bp-details_btn"> |
| 1056 |
<?php echo wp_kses_post( $better_payment_form_success_message_view_details_btn_text ); ?> |
| 1057 |
</a> |
| 1058 |
</div> |
| 1059 |
</div> |
| 1060 |
</div> |
| 1061 |
</section> |
| 1062 |
<?php |
| 1063 |
} |
| 1064 |
|
| 1065 |
/** |
| 1066 |
* Error message template |
| 1067 |
* |
| 1068 |
* @since 0.0.1 |
| 1069 |
*/ |
| 1070 |
public static function failed_message_template( $settings = [], $transaction_data = false ) { |
| 1071 |
|
| 1072 |
$image_url = BETTER_PAYMENT_ASSETS . '/img/fail.svg'; |
| 1073 |
$show_icon = 0; |
| 1074 |
$default_icon = 1; |
| 1075 |
$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' ); |
| 1076 |
$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' ); |
| 1077 |
$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' ); |
| 1078 |
$show_details_button = !empty( $settings['better_payment_form_error_details_button_switch'] ) && $settings['better_payment_form_error_details_button_switch'] == 'yes' ? true : false; |
| 1079 |
$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' ); |
| 1080 |
$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)'; |
| 1081 |
$store_name = ( isset( $settings['better_payment_form_payment_source'] ) && $settings['better_payment_form_payment_source'] === 'manual' && !empty( $settings['better_payment_form_title'] ) ) |
| 1082 |
? esc_html($settings['better_payment_form_title']) |
| 1083 |
: esc_html( get_bloginfo('name') ); |
| 1084 |
|
| 1085 |
// Get transaction details |
| 1086 |
$transaction_amount = ''; |
| 1087 |
$transaction_id = ''; |
| 1088 |
$currency_symbol = ''; |
| 1089 |
|
| 1090 |
if ( !empty( $transaction_data ) ) { |
| 1091 |
$transaction_amount = !empty( $transaction_data['amount'] ) ? floatval( $transaction_data['amount'] ) : ''; |
| 1092 |
$currency_symbol = !empty( $transaction_data['currency_symbol'] ) ? esc_html( $transaction_data['currency_symbol'] ) : ''; |
| 1093 |
$transaction_id = !empty( $transaction_data['transaction_id'] ) ? esc_html( $transaction_data['transaction_id'] ) : ''; |
| 1094 |
} |
| 1095 |
|
| 1096 |
if ( !empty( $settings[ 'better_payment_form_error_message_icon' ][ 'library' ] ) ) { |
| 1097 |
if ( $settings[ 'better_payment_form_error_message_icon' ][ 'library' ] == 'svg' ) { |
| 1098 |
$image_url = $settings[ 'better_payment_form_error_message_icon' ][ 'value' ][ 'url' ]; |
| 1099 |
$default_icon = 0; |
| 1100 |
} else { |
| 1101 |
$show_icon = 1; |
| 1102 |
$image_url = $settings[ 'better_payment_form_error_message_icon' ][ 'value' ]; |
| 1103 |
$default_icon = 0; |
| 1104 |
} |
| 1105 |
} |
| 1106 |
?> |
| 1107 |
<section class="payment-failed-screen-section"> |
| 1108 |
<div class="bp-thank_page-wrapper"> |
| 1109 |
<div class="bp-thank_page-logo"> |
| 1110 |
<?php if( $default_icon ): ?> |
| 1111 |
<span class="bp-thank_page-logo_wrapper"> |
| 1112 |
<svg width="58" height="58" viewBox="0 0 58 58" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 1113 |
<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> |
| 1114 |
<circle cx="45.5" cy="41.5" r="6.5" fill="white"></circle> |
| 1115 |
<foreignObject x="21.4686" y="17.3701" width="47.2066" height="47.3399"> |
| 1116 |
<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%"> |
| 1117 |
</div> |
| 1118 |
</foreignObject> |
| 1119 |
<g filter="url(#filter0_d_3595_8284)" data-figma-bg-blur-radius="12.71"> |
| 1120 |
<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> |
| 1121 |
</g> |
| 1122 |
<defs> |
| 1123 |
<filter id="filter0_d_3595_8284" x="21.4686" y="17.3701" width="47.2066" height="47.3399" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB"> |
| 1124 |
<feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood> |
| 1125 |
<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> |
| 1126 |
<feOffset dx="-4"></feOffset> |
| 1127 |
<feGaussianBlur stdDeviation="2"></feGaussianBlur> |
| 1128 |
<feComposite in2="hardAlpha" operator="out"></feComposite> |
| 1129 |
<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> |
| 1130 |
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_3595_8284"></feBlend> |
| 1131 |
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_3595_8284" result="shape"></feBlend> |
| 1132 |
</filter> |
| 1133 |
<clipPath id="bgblur_0_3595_8284_clip_path" transform="translate(-21.4686 -17.3701)"> |
| 1134 |
<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> |
| 1135 |
</clipPath> |
| 1136 |
</defs> |
| 1137 |
</svg> |
| 1138 |
</span> |
| 1139 |
<?php else: ?> |
| 1140 |
<?php if( $show_icon ): ?> |
| 1141 |
<?php |
| 1142 |
// Add 'pf-block' class if this is a Gutenberg block (not Elementor) |
| 1143 |
$error_wrapper_class = 'bp-thank_page-custom-logo_wrapper-error'; |
| 1144 |
if ( ! empty( $settings['better_payment_form_source'] ) && 'block' === $settings['better_payment_form_source'] ) { |
| 1145 |
$error_wrapper_class .= ' pf-block'; |
| 1146 |
} |
| 1147 |
?> |
| 1148 |
<div class="<?php echo esc_attr( $error_wrapper_class ); ?>"> |
| 1149 |
<?php |
| 1150 |
// Render icon safely (handles FontAwesome, Dashicons, SVG with or without Elementor) |
| 1151 |
if (!empty($settings['better_payment_form_error_message_icon'])) { |
| 1152 |
self::render_icon($settings['better_payment_form_error_message_icon'], ['aria-hidden' => 'true']); |
| 1153 |
} else { |
| 1154 |
// Fallback to default icons |
| 1155 |
echo '<i class="' . esc_attr($image_url) . '"></i>'; |
| 1156 |
} |
| 1157 |
?> |
| 1158 |
</div> |
| 1159 |
<?php else: ?> |
| 1160 |
<span class="bp-thank_page-logo_wrapper"> |
| 1161 |
<img src="<?php echo esc_url($image_url); ?>" alt="Error logo"> |
| 1162 |
</span> |
| 1163 |
<?php endif; ?> |
| 1164 |
<?php endif; ?> |
| 1165 |
</div> |
| 1166 |
<div class="bp-thank_page-text"> |
| 1167 |
<h2 class="bp-font_ibm bp-page_header"><?php echo wp_kses_post( $failed_heading ); ?></h2> |
| 1168 |
<p class="bp-font_ibm bp-reason_for-text">Payment of <?php echo $currency_symbol . $transaction_amount; ?> to <?php echo $store_name; ?> failed.</p> |
| 1169 |
<p class="bp-font_ibm bp-payment_info"><?php echo wp_kses_post( $failed_sub_heading ); ?></p> |
| 1170 |
|
| 1171 |
<div class="bp-flex bp-transaction_info-wrapper"> |
| 1172 |
<p class="bp-flex bp-font_ibm bp-transaction_info"> <span> |
| 1173 |
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 1174 |
<g clip-path="url(#clip0_2914_6421)"> |
| 1175 |
<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> |
| 1176 |
</g> |
| 1177 |
<defs> |
| 1178 |
<clipPath id="clip0_2914_6421"> |
| 1179 |
<rect width="18" height="18" fill="white"></rect> |
| 1180 |
</clipPath> |
| 1181 |
</defs> |
| 1182 |
</svg> |
| 1183 |
</span> |
| 1184 |
<span><?php echo wp_kses_post( $transaction_id_text ); ?>:</span> |
| 1185 |
<span class="bp-bolt bp-transaction_id"><?php echo $transaction_id; ?></span> |
| 1186 |
</p> |
| 1187 |
|
| 1188 |
<button class="bp-transaction_data-copy_btn "> |
| 1189 |
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> |
| 1190 |
<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> |
| 1191 |
</svg> |
| 1192 |
</button> |
| 1193 |
</div> |
| 1194 |
</div> |
| 1195 |
<?php if( $show_details_button ): ?> |
| 1196 |
<div class="bp-btn_wrapper"> |
| 1197 |
<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> |
| 1198 |
</div> |
| 1199 |
<?php endif; ?> |
| 1200 |
</div> |
| 1201 |
</section> |
| 1202 |
<?php |
| 1203 |
} |
| 1204 |
|
| 1205 |
/** |
| 1206 |
* Remove args from url |
| 1207 |
* |
| 1208 |
* @since 0.0.1 |
| 1209 |
*/ |
| 1210 |
public static function remove_arg() { |
| 1211 |
?> |
| 1212 |
<script> |
| 1213 |
|
| 1214 |
if(typeof params === 'undefined'){ |
| 1215 |
let params = ''; |
| 1216 |
} |
| 1217 |
|
| 1218 |
params = new URLSearchParams(location.search); |
| 1219 |
|
| 1220 |
if (params.has('better_payment_paypal_status') || params.has('better_payment_stripe_status') || params.has('better_payment_paystack_status')) { |
| 1221 |
params.delete('better_payment_paypal_status'); |
| 1222 |
params.delete('better_payment_stripe_status'); |
| 1223 |
params.delete('better_payment_paystack_status'); |
| 1224 |
params.delete('better_payment_widget_id'); |
| 1225 |
params.delete('better_payment_stripe_id'); |
| 1226 |
params.delete('better_payment_paystack_id'); |
| 1227 |
params.delete('item_number'); |
| 1228 |
window.history.replaceState({}, '', `${location.pathname}?${params}`); |
| 1229 |
} |
| 1230 |
</script> |
| 1231 |
<?php |
| 1232 |
} |
| 1233 |
|
| 1234 |
/** |
| 1235 |
* Get failed transaction data |
| 1236 |
* |
| 1237 |
* @since 1.0.0 |
| 1238 |
*/ |
| 1239 |
public static function get_failed_transaction_data( $order_id = '' ) { |
| 1240 |
if ( empty( $order_id ) ) { |
| 1241 |
return false; |
| 1242 |
} |
| 1243 |
|
| 1244 |
global $wpdb; |
| 1245 |
$table = "{$wpdb->prefix}better_payment"; |
| 1246 |
|
| 1247 |
$result = $wpdb->get_row( |
| 1248 |
$wpdb->prepare( |
| 1249 |
"SELECT amount, currency, transaction_id, order_id, source FROM $table WHERE order_id=%s LIMIT 1", |
| 1250 |
$order_id |
| 1251 |
) |
| 1252 |
); |
| 1253 |
|
| 1254 |
if ( !empty( $result ) ) { |
| 1255 |
$helper_obj = new Helper(); |
| 1256 |
return [ |
| 1257 |
'amount' => floatval( $result->amount ), |
| 1258 |
'currency' => sanitize_text_field( $result->currency ), |
| 1259 |
'currency_symbol' => $helper_obj->get_currency_symbol( $result->currency ), |
| 1260 |
'transaction_id' => !empty( $result->transaction_id ) ? sanitize_text_field( $result->transaction_id ) : 'N/A', |
| 1261 |
'method' => sanitize_text_field( $result->source ), |
| 1262 |
]; |
| 1263 |
} |
| 1264 |
|
| 1265 |
return false; |
| 1266 |
} |
| 1267 |
|
| 1268 |
/** |
| 1269 |
* Whitelist the e-mail related settings that better_email_notification() reads. |
| 1270 |
* |
| 1271 |
* PayPal confirms payments asynchronously through the IPN listener |
| 1272 |
* (handle_paypal_ipn), where the live Elementor widget / block settings are NOT |
| 1273 |
* available. Stripe and Paystack build their e-mail synchronously on the return |
| 1274 |
* page, so they still have the full settings array in hand. To reach parity we |
| 1275 |
* persist this subset into the transaction's form_fields_info at payment-create |
| 1276 |
* time, and the IPN handler rebuilds the same $settings to produce an identical |
| 1277 |
* e-mail body (heading, From / To / Transaction Summary / footer sections, |
| 1278 |
* subjects, headers) and to honour the "Send Email" on/off toggle. |
| 1279 |
* |
| 1280 |
* @param mixed $settings Full widget / block / form settings (guarded: non-array input returns []). |
| 1281 |
* |
| 1282 |
* @return array Whitelisted e-mail settings (safe to serialize into form_fields_info). |
| 1283 |
* @since 2.2.2 |
| 1284 |
*/ |
| 1285 |
public static function extract_email_settings( $settings = [] ) { |
| 1286 |
$email_settings = []; |
| 1287 |
|
| 1288 |
if ( ! is_array( $settings ) ) { |
| 1289 |
return $email_settings; |
| 1290 |
} |
| 1291 |
|
| 1292 |
foreach ( $settings as $key => $value ) { |
| 1293 |
if ( |
| 1294 |
0 === strpos( $key, 'better_payment_email_' ) |
| 1295 |
|| 0 === strpos( $key, 'better_payment_form_email_' ) |
| 1296 |
|| 'better_payment_form_title' === $key |
| 1297 |
) { |
| 1298 |
$email_settings[ $key ] = $value; |
| 1299 |
} |
| 1300 |
} |
| 1301 |
|
| 1302 |
return $email_settings; |
| 1303 |
} |
| 1304 |
|
| 1305 |
/** |
| 1306 |
* Email template |
| 1307 |
* |
| 1308 |
* @since 0.0.1 |
| 1309 |
*/ |
| 1310 |
public static function better_email_notification($transaction_id, $customer_email, $settings, $referrer='Stripe', $form_fields_info='', $is_elementor_form = 0){ |
| 1311 |
//Send Email: customer and admin |
| 1312 |
$better_txn_id = sanitize_text_field( $transaction_id ); |
| 1313 |
$better_cus_email = sanitize_email( $customer_email ); |
| 1314 |
$default_subject = sprintf(__('Better Payment transaction on %s', 'better-payment'), esc_html(get_option('blogname'))); |
| 1315 |
$better_payment_global_settings = DB::get_settings(); |
| 1316 |
|
| 1317 |
$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' ); |
| 1318 |
|
| 1319 |
$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; |
| 1320 |
$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'; |
| 1321 |
$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'] : ''; |
| 1322 |
$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'] : ''; |
| 1323 |
$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'] : ''; |
| 1324 |
$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'] : ''; |
| 1325 |
$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'] : ''; |
| 1326 |
$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'; |
| 1327 |
|
| 1328 |
$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; |
| 1329 |
$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'; |
| 1330 |
$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'] : ''; |
| 1331 |
$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'] : ''; |
| 1332 |
$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'] : ''; |
| 1333 |
$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'] : ''; |
| 1334 |
$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'] : ''; |
| 1335 |
$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'; |
| 1336 |
$args = []; |
| 1337 |
|
| 1338 |
$args['email_form_name'] = ! empty( $settings['better_payment_form_title'] ) ? sanitize_text_field( $settings['better_payment_form_title'] ) : 'N/A'; |
| 1339 |
$args['email_content_heading_show'] = ! empty( $settings['better_payment_email_content_heading'] ) && 'yes' === $settings['better_payment_email_content_heading'] ? 1 : 0; |
| 1340 |
$args['email_content_from_section_show'] = ! empty( $settings['better_payment_email_content_from_section'] ) && 'yes' === $settings['better_payment_email_content_from_section'] ? 1 : 0; |
| 1341 |
$args['email_content_to_section_show'] = ! empty( $settings['better_payment_email_content_to_section'] ) && 'yes' === $settings['better_payment_email_content_to_section'] ? 1 : 0; |
| 1342 |
$args['email_content_transaction_summary_show'] = ! empty( $settings['better_payment_email_content_transaction_summary'] ) && 'yes' === $settings['better_payment_email_content_transaction_summary'] ? 1 : 0; |
| 1343 |
$args['email_content_footer_text_show'] = ! empty( $settings['better_payment_email_content_footer_text'] ) && 'yes' === $settings['better_payment_email_content_footer_text'] ? 1 : 0; |
| 1344 |
$args['email_content_customer'] = ! empty( $settings['better_payment_email_content_customer'] ) ? $settings['better_payment_email_content_customer'] : ''; |
| 1345 |
$args['email_content_admin'] = ! empty( $settings['better_payment_email_content'] ) ? $settings['better_payment_email_content'] : ''; |
| 1346 |
$args['is_elementor_form'] = $is_elementor_form; |
| 1347 |
|
| 1348 |
if ( ! empty( $settings['better_payment_email_content_greeting'] ) ) { |
| 1349 |
$args['email_content_greeting'] = $settings['better_payment_email_content_greeting']; |
| 1350 |
} |
| 1351 |
|
| 1352 |
if ( ! empty( $settings['better_payment_form_email_logo']['url'] ) ) { |
| 1353 |
$args['email_logo_url'] = $settings['better_payment_form_email_logo']['url']; |
| 1354 |
} |
| 1355 |
|
| 1356 |
if ( ! empty( $settings['better_payment_form_email_attachment']['id'] ) ) { |
| 1357 |
$args['email_attachment_id'] = intval( $settings['better_payment_form_email_attachment']['id'] ); |
| 1358 |
$args['email_attachment_path'] = get_attached_file( $args['email_attachment_id'] ); |
| 1359 |
} |
| 1360 |
|
| 1361 |
if ( ! empty( $settings['better_payment_form_email_attachment_pdf_show'] ) && ! empty( $settings['better_payment_form_email_attachment_pdf']['id'] ) ) { |
| 1362 |
$args['email_attachment_id'] = intval( $settings['better_payment_form_email_attachment_pdf']['id'] ); |
| 1363 |
$args['email_attachment_path'] = get_attached_file( $args['email_attachment_id'] ); |
| 1364 |
} |
| 1365 |
|
| 1366 |
if(isset($settings['better_payment_email_to'])){ |
| 1367 |
$better_payment_email_to = sanitize_email($settings['better_payment_email_to']); |
| 1368 |
} |
| 1369 |
|
| 1370 |
if(isset($settings['better_payment_email_subject'])){ |
| 1371 |
$better_payment_email_subject = sanitize_text_field($settings['better_payment_email_subject']); |
| 1372 |
} |
| 1373 |
|
| 1374 |
if(isset($settings['better_payment_email_subject_customer'])){ |
| 1375 |
$better_payment_email_subject_customer = sanitize_text_field($settings['better_payment_email_subject_customer']); |
| 1376 |
} |
| 1377 |
|
| 1378 |
if(isset($settings['better_payment_email_content_type'])){ |
| 1379 |
$better_payment_email_content_type = sanitize_text_field($settings['better_payment_email_content_type']); |
| 1380 |
} |
| 1381 |
|
| 1382 |
if(isset($settings['better_payment_email_content_type_customer'])){ |
| 1383 |
$better_payment_email_content_type_customer = sanitize_text_field($settings['better_payment_email_content_type_customer']); |
| 1384 |
} |
| 1385 |
|
| 1386 |
$args['email_content_type'] = $better_payment_email_content_type; |
| 1387 |
$args['email_content_type_customer'] = $better_payment_email_content_type_customer; |
| 1388 |
|
| 1389 |
$line_break = $better_payment_email_content_type == 'html' ? '<br>' : "\n"; |
| 1390 |
$line_break_customer = $better_payment_email_content_type_customer == 'html' ? '<br>' : "\n"; |
| 1391 |
|
| 1392 |
global $wpdb; |
| 1393 |
$table = "{$wpdb->prefix}better_payment"; |
| 1394 |
$transaction_obj = $wpdb->get_row( |
| 1395 |
$wpdb->prepare( "SELECT * FROM $table WHERE transaction_id=%s limit 1", sanitize_text_field( $transaction_id ) ) |
| 1396 |
); |
| 1397 |
|
| 1398 |
if(isset($settings['better_payment_email_content'])){ |
| 1399 |
$better_payment_email_content = sanitize_text_field($settings['better_payment_email_content']); |
| 1400 |
$better_payment_email_content = self::better_render_email_body( $better_payment_email_content, $form_fields_info, $line_break, 'admin', $transaction_obj, $args ); |
| 1401 |
} else if ( !empty($better_payment_email_content) ){ |
| 1402 |
$better_payment_email_content = self::better_render_email_body( $better_payment_email_content, $form_fields_info, $line_break, 'admin', $transaction_obj, $args ); |
| 1403 |
} |
| 1404 |
|
| 1405 |
if(isset($settings['better_payment_email_content_customer'])){ |
| 1406 |
$better_payment_email_content_customer = sanitize_text_field($settings['better_payment_email_content_customer']); |
| 1407 |
$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 ); |
| 1408 |
} else if ( !empty($better_payment_email_content_customer) ){ |
| 1409 |
$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. |
| 1410 |
} |
| 1411 |
|
| 1412 |
if(isset($settings['better_payment_email_from'])){ |
| 1413 |
$better_payment_email_from = sanitize_email($settings['better_payment_email_from']); |
| 1414 |
} |
| 1415 |
|
| 1416 |
if(isset($settings['better_payment_email_from_name'])){ |
| 1417 |
$better_payment_email_from_name = sanitize_text_field($settings['better_payment_email_from_name']); |
| 1418 |
} |
| 1419 |
|
| 1420 |
if(isset($settings['better_payment_email_reply_to'])){ |
| 1421 |
$better_payment_email_reply_to = sanitize_email($settings['better_payment_email_reply_to']); |
| 1422 |
} |
| 1423 |
|
| 1424 |
if(isset($settings['better_payment_email_cc'])){ |
| 1425 |
$better_payment_email_cc = sanitize_email($settings['better_payment_email_cc']); |
| 1426 |
} |
| 1427 |
|
| 1428 |
if(isset($settings['better_payment_email_bcc'])){ |
| 1429 |
$better_payment_email_bcc = sanitize_email($settings['better_payment_email_bcc']); |
| 1430 |
} |
| 1431 |
|
| 1432 |
//Customer Email |
| 1433 |
if(isset($settings['better_payment_email_from_customer'])){ |
| 1434 |
$better_payment_email_from_customer = sanitize_email($settings['better_payment_email_from_customer']); |
| 1435 |
} |
| 1436 |
|
| 1437 |
if(isset($settings['better_payment_email_from_name_customer'])){ |
| 1438 |
$better_payment_email_from_name_customer = sanitize_text_field($settings['better_payment_email_from_name_customer']); |
| 1439 |
} |
| 1440 |
|
| 1441 |
if(isset($settings['better_payment_email_reply_to_customer'])){ |
| 1442 |
$better_payment_email_reply_to_customer = sanitize_email($settings['better_payment_email_reply_to_customer']); |
| 1443 |
} |
| 1444 |
|
| 1445 |
if(isset($settings['better_payment_email_cc_customer'])){ |
| 1446 |
$better_payment_email_cc_customer = sanitize_email($settings['better_payment_email_cc_customer']); |
| 1447 |
} |
| 1448 |
|
| 1449 |
if(isset($settings['better_payment_email_bcc_customer'])){ |
| 1450 |
$better_payment_email_bcc_customer = sanitize_email($settings['better_payment_email_bcc_customer']); |
| 1451 |
} |
| 1452 |
|
| 1453 |
if($better_payment_email_content == ''){ |
| 1454 |
$better_payment_email_content = __('New better payment transaction! ', 'better-payment'); |
| 1455 |
} |
| 1456 |
|
| 1457 |
if($better_payment_email_content_customer == ''){ |
| 1458 |
$better_payment_email_content_customer = __('New better payment transaction! ', 'better-payment'); |
| 1459 |
} |
| 1460 |
|
| 1461 |
$better_payment_email_headers = []; |
| 1462 |
$better_payment_email_headers_customer = []; |
| 1463 |
|
| 1464 |
if($better_payment_email_content_type == 'html'){ |
| 1465 |
$better_payment_email_headers[] = 'Content-Type: text/html; charset=UTF-8'; |
| 1466 |
} |
| 1467 |
|
| 1468 |
if($better_payment_email_content_type_customer == 'html'){ |
| 1469 |
$better_payment_email_headers_customer[] = 'Content-Type: text/html; charset=UTF-8'; |
| 1470 |
} |
| 1471 |
|
| 1472 |
if($better_payment_email_from != ''){ |
| 1473 |
$better_payment_email_headers[] = "From: $better_payment_email_from_name <$better_payment_email_from>"; |
| 1474 |
} |
| 1475 |
|
| 1476 |
if($better_payment_email_cc != ''){ |
| 1477 |
$better_payment_email_headers[] = "Cc: <$better_payment_email_cc>"; |
| 1478 |
} |
| 1479 |
|
| 1480 |
if($better_payment_email_bcc != ''){ |
| 1481 |
$better_payment_email_headers[] = "BCc: $better_payment_email_bcc"; |
| 1482 |
} |
| 1483 |
|
| 1484 |
if($better_payment_email_reply_to != ''){ |
| 1485 |
$better_payment_email_headers[] = "Reply-To: $better_payment_email_reply_to"; |
| 1486 |
} |
| 1487 |
|
| 1488 |
//Customer Email |
| 1489 |
if($better_payment_email_from_customer != ''){ |
| 1490 |
$better_payment_email_headers_customer[] = "From: $better_payment_email_from_name_customer <$better_payment_email_from_customer>"; |
| 1491 |
} |
| 1492 |
|
| 1493 |
$form_fields_info_array = []; |
| 1494 |
|
| 1495 |
if( ! empty( $form_fields_info ) ){ |
| 1496 |
$form_fields_info_array = maybe_unserialize( $form_fields_info ); |
| 1497 |
} |
| 1498 |
|
| 1499 |
$form_fields_info_cus_email = ! empty( $form_fields_info_array['primary_email'] ) ? sanitize_email( $form_fields_info_array['primary_email'] ) : ''; |
| 1500 |
|
| 1501 |
if($better_payment_email_cc_customer != '' || ! empty( $form_fields_info_cus_email ) ){ |
| 1502 |
$better_payment_email_cc_customer_multiple = implode(',', [$form_fields_info_cus_email, $better_payment_email_cc_customer]); |
| 1503 |
$better_payment_email_headers_customer[] = "Cc: $better_payment_email_cc_customer_multiple"; |
| 1504 |
} |
| 1505 |
|
| 1506 |
if($better_payment_email_bcc_customer != ''){ |
| 1507 |
$better_payment_email_headers_customer[] = "BCc: $better_payment_email_bcc_customer"; |
| 1508 |
} |
| 1509 |
|
| 1510 |
if($better_payment_email_reply_to_customer != ''){ |
| 1511 |
$better_payment_email_headers_customer[] = "Reply-To: $better_payment_email_reply_to_customer"; |
| 1512 |
} |
| 1513 |
|
| 1514 |
$email_attachments = ! empty( $args['email_attachment_path'] ) ? [ $args['email_attachment_path'] ] : []; |
| 1515 |
$allowed_extensions = array('jpg', 'jpeg', 'png', 'pdf'); |
| 1516 |
|
| 1517 |
$file_info = count( $email_attachments ) ? pathinfo($email_attachments[0]) : []; |
| 1518 |
$file_extension = count( $file_info ) ? strtolower($file_info['extension']) : ''; |
| 1519 |
|
| 1520 |
if ( ! in_array( $file_extension, $allowed_extensions ) ){ |
| 1521 |
$email_attachments = []; |
| 1522 |
} |
| 1523 |
|
| 1524 |
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 |
| 1525 |
self::send_better_email($better_payment_email_to, $better_payment_email_subject, $better_payment_email_content, $better_payment_email_headers); //admin mail |
| 1526 |
} |
| 1527 |
|
| 1528 |
/** |
| 1529 |
* Sends an HTML email. |
| 1530 |
* |
| 1531 |
* @since 0.0.2 |
| 1532 |
* |
| 1533 |
* @param string $to |
| 1534 |
* @param string $subject |
| 1535 |
* @param array $message |
| 1536 |
* |
| 1537 |
* @return bool false indicates mail sending failed while true doesn't gurantee that mail sent. |
| 1538 |
* true just indicate script processed successfully without any errors. |
| 1539 |
* Ref: https://developer.wordpress.org/reference/functions/wp_mail/ |
| 1540 |
*/ |
| 1541 |
public static function send_better_email( $to, $subject, $message, $headers=[], $attachments = [] ) { |
| 1542 |
$response = false; |
| 1543 |
|
| 1544 |
$mailValidated = filter_var($to, FILTER_VALIDATE_EMAIL); |
| 1545 |
|
| 1546 |
if ($mailValidated) { |
| 1547 |
$response = wp_mail( $to, $subject, $message, $headers, $attachments ); |
| 1548 |
} |
| 1549 |
|
| 1550 |
return $response; |
| 1551 |
} |
| 1552 |
|
| 1553 |
/** |
| 1554 |
* Email body |
| 1555 |
* |
| 1556 |
* |
| 1557 |
* @return string |
| 1558 |
* @since 0.0.1 |
| 1559 |
*/ |
| 1560 |
public static function better_render_email_body( $email_body, $form_fields_info, $line_break, $type = 'admin', $transaction_obj = null, $args = [] ) { |
| 1561 |
$transaction_id = |
| 1562 |
$currency = |
| 1563 |
$payment_date = |
| 1564 |
$customer_name = |
| 1565 |
$customer_first_name = |
| 1566 |
$customer_last_name = |
| 1567 |
$amount = ''; |
| 1568 |
$helper_obj = new Helper(); |
| 1569 |
|
| 1570 |
if(null !== $transaction_obj && is_object($transaction_obj)){ |
| 1571 |
$transaction_id = $transaction_obj->transaction_id; |
| 1572 |
$amount = $transaction_obj->amount; |
| 1573 |
$status = $transaction_obj->status; |
| 1574 |
$source = $transaction_obj->source; |
| 1575 |
$currency = $transaction_obj->currency; |
| 1576 |
$currency_symbol = $helper_obj->get_currency_symbol( esc_html($currency) ); |
| 1577 |
$payment_date = wp_date(get_option('date_format').' '.get_option('time_format'), strtotime($transaction_obj->payment_date)); |
| 1578 |
} |
| 1579 |
|
| 1580 |
$is_empty_email_body = empty($email_body); |
| 1581 |
|
| 1582 |
$email_body = do_shortcode( $email_body ); |
| 1583 |
$bp_form_fields_html_content = $email_body; |
| 1584 |
|
| 1585 |
$bp_all_fields_shortcode = 'bp-all-fields'; |
| 1586 |
$referer_content_page_link = '#'; |
| 1587 |
|
| 1588 |
$field_text = __('Field', 'better-payment'); |
| 1589 |
$value_text = __('Entry', 'better-payment'); |
| 1590 |
|
| 1591 |
$form_fields_info_arr = maybe_unserialize($form_fields_info); |
| 1592 |
|
| 1593 |
$email_logo_url = ! empty( $args['email_logo_url'] ) ? $args['email_logo_url'] : ''; |
| 1594 |
$email_content_greeting = ! empty( $args['email_content_greeting'] ) ? 1 : 0; |
| 1595 |
$email_form_name = ! empty( $args['email_form_name'] ) ? $args['email_form_name'] : 'N/A'; |
| 1596 |
|
| 1597 |
$bp_form_fields_html_header = '<table style="margin-bottom: 20px; font-size: 14px; border-collapse: collapse; width: 100%;">'; |
| 1598 |
|
| 1599 |
$bp_form_fields_html_footer = "</table>"; |
| 1600 |
|
| 1601 |
$content = ''. $line_break; |
| 1602 |
|
| 1603 |
foreach ( $form_fields_info_arr as $key => $field ) { |
| 1604 |
if ( $key === 'is_payment_split_payment' ) { |
| 1605 |
$is_payment_split_payment = 1; |
| 1606 |
} |
| 1607 |
//Hide few fields |
| 1608 |
if( |
| 1609 |
$key === 'referer_page_id' || $key === 'referer_widget_id' || $key === 'source' || $key === 'el_form_fields' |
| 1610 |
|| $key === 'is_woo_layout' |
| 1611 |
|| $key === 'is_payment_split_payment' |
| 1612 |
|| $key === 'split_payment_total_amount' |
| 1613 |
|| $key === 'split_payment_total_amount_price_id' |
| 1614 |
|| $key === 'split_payment_installment_price_id' |
| 1615 |
) { |
| 1616 |
if($key === 'referer_page_id'){ |
| 1617 |
$referer_content_page_link = !empty($field) ? get_permalink( $field ) : $referer_content_page_link; |
| 1618 |
} |
| 1619 |
|
| 1620 |
continue; |
| 1621 |
} |
| 1622 |
|
| 1623 |
if($key === 'primary_first_name'){ |
| 1624 |
$key = 'first_name'; |
| 1625 |
$customer_first_name = $field; |
| 1626 |
} |
| 1627 |
if($key === 'primary_last_name'){ |
| 1628 |
$key = 'last_name'; |
| 1629 |
$customer_last_name = $field; |
| 1630 |
} |
| 1631 |
|
| 1632 |
if($key === 'primary_email'){ |
| 1633 |
$key = 'email'; |
| 1634 |
} |
| 1635 |
|
| 1636 |
if($key === 'primary_payment_amount'){ |
| 1637 |
$key = 'payment_amount'; |
| 1638 |
} |
| 1639 |
|
| 1640 |
$key_formatted = self::better_title_case($key); |
| 1641 |
if($key_formatted === 'Amount'){ |
| 1642 |
$key_formatted = __('Paid', 'better-payment'); |
| 1643 |
|
| 1644 |
if ( ! empty( $is_payment_split_payment ) ) { |
| 1645 |
$key_formatted = __('Product Price: ', 'better-payment'); |
| 1646 |
} |
| 1647 |
} |
| 1648 |
|
| 1649 |
$content .= "<tr> |
| 1650 |
<td style='padding: 7px; border: 1px solid #666;'> <strong>$key_formatted</strong> </td> |
| 1651 |
<td style='padding: 7px; border: 1px solid #666;'> $field </td> |
| 1652 |
</tr>"; |
| 1653 |
} |
| 1654 |
|
| 1655 |
if($customer_first_name) { |
| 1656 |
$customer_name = $customer_first_name . ' '; |
| 1657 |
} |
| 1658 |
if($customer_last_name) { |
| 1659 |
$customer_name .= $customer_last_name . ' '; |
| 1660 |
} |
| 1661 |
|
| 1662 |
$allowed_sources = ['paypal', 'stripe', 'paystack']; |
| 1663 |
$source_image_url = BETTER_PAYMENT_ASSETS . '/img/stripe.png'; |
| 1664 |
$source_image_alt = 'Stripe'; |
| 1665 |
|
| 1666 |
if( in_array( strtolower( $transaction_obj->source ), $allowed_sources ) ){ |
| 1667 |
$source_image_url = strtolower( $transaction_obj->source ) == 'paypal' ? BETTER_PAYMENT_ASSETS . '/img/paypal.png' : BETTER_PAYMENT_ASSETS . "/img/{$transaction_obj->source}.png"; |
| 1668 |
$source_image_alt = strtolower( $transaction_obj->source ) == 'paypal' ? 'PayPal' : ucfirst( strtolower( $transaction_obj->source ) ); |
| 1669 |
} |
| 1670 |
|
| 1671 |
$amount_quantity = ! empty( $form_fields_info_arr['amount_quantity'] ) ? intval( $form_fields_info_arr['amount_quantity'] ) : 1; |
| 1672 |
// #ToDo Product id or ids with comma |
| 1673 |
$woo_product_id = ! empty( $form_fields_info_arr['woo_product_id'] ) ? intval( $form_fields_info_arr['woo_product_id'] ) : 0; |
| 1674 |
$fluentcart_product_id = ! empty( $form_fields_info_arr['fluentcart_product_id'] ) ? intval( $form_fields_info_arr['fluentcart_product_id'] ) : 0; |
| 1675 |
$woo_product_ids = ! empty( $form_fields_info_arr['woo_product_ids'] ) ? maybe_unserialize( $form_fields_info_arr['woo_product_ids'] ) : [0]; |
| 1676 |
$fluentcart_product_ids = ! empty( $form_fields_info_arr['fluentcart_product_ids'] ) ? maybe_unserialize( $form_fields_info_arr['fluentcart_product_ids'] ) : [0]; |
| 1677 |
$product_name = ''; |
| 1678 |
$product_permalink = ''; |
| 1679 |
$product_image_src = ''; |
| 1680 |
|
| 1681 |
// Handle WooCommerce products |
| 1682 |
if (function_exists('wc_get_product') && $woo_product_id ) { |
| 1683 |
$bp_woocommerce_product = wc_get_product($woo_product_id); |
| 1684 |
$product = $bp_woocommerce_product; |
| 1685 |
|
| 1686 |
if ($product) { |
| 1687 |
$product_name = $product->get_name(); |
| 1688 |
$product_permalink = get_permalink($product->get_id()); |
| 1689 |
$product_price = $product->get_price(); |
| 1690 |
$product_image_src_array = wp_get_attachment_image_src( get_post_thumbnail_id( $product->get_id() ), 'single-post-thumbnail' ); |
| 1691 |
$product_image_src = is_array( $product_image_src_array ) && count( $product_image_src_array ) ? $product_image_src_array[0] : ''; |
| 1692 |
} |
| 1693 |
} |
| 1694 |
|
| 1695 |
if (function_exists('fluentCart') && $fluentcart_product_id ) { |
| 1696 |
try { |
| 1697 |
$fluentcart_product = \FluentCart\App\Models\Product::query() |
| 1698 |
->with(['detail', 'variants']) |
| 1699 |
->find($fluentcart_product_id); |
| 1700 |
|
| 1701 |
if ($fluentcart_product) { |
| 1702 |
$product_name = $fluentcart_product->post_title; |
| 1703 |
$product_permalink = get_permalink($fluentcart_product->ID); |
| 1704 |
|
| 1705 |
// Get price from the first variant or detail |
| 1706 |
$product_price = 0; |
| 1707 |
if (!empty($fluentcart_product->variants) && count($fluentcart_product->variants) > 0) { |
| 1708 |
$product_price = $fluentcart_product->variants[0]->item_price; |
| 1709 |
} elseif (!empty($fluentcart_product->detail)) { |
| 1710 |
$product_price = $fluentcart_product->detail->min_price; |
| 1711 |
} |
| 1712 |
|
| 1713 |
$product_image_src_array = wp_get_attachment_image_src( get_post_thumbnail_id( $fluentcart_product->ID ), 'single-post-thumbnail' ); |
| 1714 |
$product_image_src = is_array( $product_image_src_array ) && count( $product_image_src_array ) ? $product_image_src_array[0] : ''; |
| 1715 |
} |
| 1716 |
} catch ( \Exception $e ) { |
| 1717 |
// Handle error silently |
| 1718 |
} |
| 1719 |
} |
| 1720 |
|
| 1721 |
$detailed_product_info = isset( $form_fields_info_arr['detailed_product_info'] ) ? maybe_unserialize( $form_fields_info_arr['detailed_product_info'] ) : []; |
| 1722 |
|
| 1723 |
$all_data = [ |
| 1724 |
'amount' => $amount, |
| 1725 |
'amount_quantity' => $amount_quantity, |
| 1726 |
'woo_product_id' => $woo_product_id, |
| 1727 |
'woo_product_ids' => $woo_product_ids, |
| 1728 |
'fluentcart_product_id' => $fluentcart_product_id, |
| 1729 |
'fluentcart_product_ids' => $fluentcart_product_ids, |
| 1730 |
'product_name' => $product_name, |
| 1731 |
'product_permalink' => $product_permalink, |
| 1732 |
'product_image_src' => $product_image_src, |
| 1733 |
'detailed_product_info' => $detailed_product_info, |
| 1734 |
'amount_single' => $amount_quantity > 0 ? floatval( $amount / $amount_quantity ) : $amount, |
| 1735 |
'currency' => ! empty( $currency ) ? $currency : '', |
| 1736 |
'currency_symbol' => ! empty( $currency_symbol ) ? $currency_symbol : '', |
| 1737 |
'payment_date_time' => ! empty( $payment_date ) ? $payment_date : '', |
| 1738 |
'transaction_id' => ! empty( $transaction_id ) ? $transaction_id : '', |
| 1739 |
'payment_date_only' => wp_date(get_option('date_format'), strtotime($transaction_obj->payment_date)), |
| 1740 |
'status' => ucfirst( $status ), |
| 1741 |
'form_fields_info_arr' => $form_fields_info_arr, |
| 1742 |
// 'admin_name' => $admin_name, |
| 1743 |
'customer_name' => $customer_name, |
| 1744 |
'site_title' => get_bloginfo( 'name' ), |
| 1745 |
'site_admin_email' => get_bloginfo( 'admin_email' ), |
| 1746 |
'form_name' => $email_form_name, |
| 1747 |
'payment_method' => ucfirst( $source ), |
| 1748 |
'email_logo_url' => $email_logo_url, |
| 1749 |
'source_image_url' => $source_image_url, |
| 1750 |
'source_image_alt' => $source_image_alt, |
| 1751 |
'view_transaction_link' => admin_url("admin.php?page=better-payment-transactions&action=view&id={$transaction_obj->id}"), |
| 1752 |
'email_content_heading_show' => intval( $args['email_content_heading_show'] ), |
| 1753 |
'email_content_from_section_show' => intval( $args['email_content_from_section_show'] ), |
| 1754 |
'email_content_to_section_show' => intval( $args['email_content_to_section_show'] ), |
| 1755 |
'email_content_transaction_summary_show' => intval( $args['email_content_transaction_summary_show'] ), |
| 1756 |
'email_content_footer_text_show' => intval( $args['email_content_footer_text_show'] ), |
| 1757 |
'email_content_customer' => wp_kses_post( $args['email_content_customer'] ), |
| 1758 |
'email_content_admin' => wp_kses_post( $args['email_content_admin'] ), |
| 1759 |
'is_elementor_form' => intval( $args['is_elementor_form'] ), |
| 1760 |
'email_content_type' => $args['email_content_type'] ?? 'html', |
| 1761 |
'email_content_type_customer' => $args['email_content_type_customer'] ?? 'html', |
| 1762 |
]; |
| 1763 |
|
| 1764 |
$bp_form_fields_html_body = $content; |
| 1765 |
$bp_form_fields_html_content = $bp_form_fields_html_header . $bp_form_fields_html_body . $bp_form_fields_html_footer ; |
| 1766 |
|
| 1767 |
//Replace shortcode with form fields info |
| 1768 |
$email_body = str_replace( "[$bp_all_fields_shortcode]", $bp_form_fields_html_content, $email_body ); |
| 1769 |
|
| 1770 |
// Email V2 |
| 1771 |
// General content |
| 1772 |
$form_name = |
| 1773 |
|
| 1774 |
ob_start(); |
| 1775 |
|
| 1776 |
include BETTER_PAYMENT_ADMIN_VIEWS_PATH . "/template-email-notification.php"; |
| 1777 |
|
| 1778 |
$email_body = ob_get_contents(); |
| 1779 |
ob_end_clean(); |
| 1780 |
|
| 1781 |
return $email_body; |
| 1782 |
} |
| 1783 |
|
| 1784 |
/** |
| 1785 |
* String helper method |
| 1786 |
* helps to convert string to title case |
| 1787 |
* |
| 1788 |
* @return string |
| 1789 |
* @since 0.0.1 |
| 1790 |
*/ |
| 1791 |
public static function better_title_case($string){ |
| 1792 |
$string = str_replace('_',' ', $string); |
| 1793 |
$string = ucwords($string); |
| 1794 |
return $string; |
| 1795 |
} |
| 1796 |
|
| 1797 |
/** |
| 1798 |
* Safe icon rendering for payment form messages |
| 1799 |
* |
| 1800 |
* Handles multiple icon types: FontAwesome, Dashicons, SVG from media library |
| 1801 |
* Works with or without Elementor being active |
| 1802 |
* |
| 1803 |
* @param array $icon_settings Icon settings from block/widget controls |
| 1804 |
* @param array $html_attributes Optional HTML attributes for the icon element |
| 1805 |
* |
| 1806 |
* @return void (outputs HTML directly) |
| 1807 |
* @since 2.0.4 |
| 1808 |
*/ |
| 1809 |
public static function render_icon( $icon_settings = [], $html_attributes = [] ) { |
| 1810 |
// Bail if no settings provided |
| 1811 |
if ( empty( $icon_settings ) || ! is_array( $icon_settings ) ) { |
| 1812 |
return; |
| 1813 |
} |
| 1814 |
|
| 1815 |
// If value is empty, nothing to render |
| 1816 |
if ( empty( $icon_settings['value'] ) ) { |
| 1817 |
return; |
| 1818 |
} |
| 1819 |
|
| 1820 |
$library = ! empty( $icon_settings['library'] ) ? $icon_settings['library'] : ''; |
| 1821 |
$value = $icon_settings['value']; |
| 1822 |
|
| 1823 |
// Try to use Elementor's Icons_Manager if it's available and loaded |
| 1824 |
if ( did_action( 'elementor/loaded' ) && class_exists( '\Elementor\Icons_Manager' ) ) { |
| 1825 |
try { |
| 1826 |
\Elementor\Icons_Manager::render_icon( $icon_settings, $html_attributes ); |
| 1827 |
return; |
| 1828 |
} catch ( \Exception $e ) { |
| 1829 |
// If Elementor rendering fails, fall back to manual rendering |
| 1830 |
} |
| 1831 |
} |
| 1832 |
|
| 1833 |
// Handle SVG (uploaded via media library) |
| 1834 |
if ( $library === 'svg' ) { |
| 1835 |
if ( is_array( $value ) && ! empty( $value['url'] ) ) { |
| 1836 |
$svg_url = esc_url( $value['url'] ); |
| 1837 |
echo '<img src="' . $svg_url . '" alt="Icon" class="bp-icon-svg" />'; |
| 1838 |
return; |
| 1839 |
} |
| 1840 |
} |
| 1841 |
|
| 1842 |
// Handle FontAwesome icons (all variants: fa, fas, far, fab, fal, fad, etc.) |
| 1843 |
if ( in_array( $library, [ 'fa', 'fas', 'far', 'fab', 'fal', 'fad', 'fontawesome', 'font-awesome' ], true ) ) { |
| 1844 |
if ( is_string( $value ) && ! empty( $value ) ) { |
| 1845 |
// Build complete FontAwesome class |
| 1846 |
$icon_class = 'fa'; |
| 1847 |
|
| 1848 |
// Add variant if specified (fas, far, fab, fal) |
| 1849 |
if ( ! empty( $library ) && $library !== 'fa' && $library !== 'fontawesome' && $library !== 'font-awesome' ) { |
| 1850 |
$icon_class = esc_attr( $library ); |
| 1851 |
} else { |
| 1852 |
// Default to 'fas' if no variant specified |
| 1853 |
$icon_class = 'fas'; |
| 1854 |
} |
| 1855 |
|
| 1856 |
// Add the specific icon class |
| 1857 |
$icon_class .= ' ' . esc_attr( $value ); |
| 1858 |
|
| 1859 |
$html_class = ! empty( $html_attributes['class'] ) ? ' ' . $html_attributes['class'] : ''; |
| 1860 |
$aria_hidden = isset( $html_attributes['aria-hidden'] ) ? ' aria-hidden="' . esc_attr( $html_attributes['aria-hidden'] ) . '"' : ' aria-hidden="true"'; |
| 1861 |
|
| 1862 |
echo '<i class="' . $icon_class . $html_class . '"' . $aria_hidden . '></i>'; |
| 1863 |
return; |
| 1864 |
} |
| 1865 |
} |
| 1866 |
|
| 1867 |
// Handle Dashicons |
| 1868 |
if ( in_array( $library, [ 'dashicons' ], true ) ) { |
| 1869 |
if ( is_string( $value ) && ! empty( $value ) ) { |
| 1870 |
$icon_class = 'dashicons dashicons-' . esc_attr( $value ); |
| 1871 |
|
| 1872 |
$html_class = ! empty( $html_attributes['class'] ) ? ' ' . $html_attributes['class'] : ''; |
| 1873 |
$aria_hidden = isset( $html_attributes['aria-hidden'] ) ? ' aria-hidden="' . esc_attr( $html_attributes['aria-hidden'] ) . '"' : ' aria-hidden="true"'; |
| 1874 |
|
| 1875 |
echo '<span class="' . $icon_class . $html_class . '"' . $aria_hidden . '></span>'; |
| 1876 |
return; |
| 1877 |
} |
| 1878 |
} |
| 1879 |
|
| 1880 |
// Handle custom CSS classes (like 'bp-icon bp-check-circle') |
| 1881 |
// These are custom icon fonts or CSS-based icons defined by the theme/plugin |
| 1882 |
if ( 'custom' === $library ) { |
| 1883 |
if ( is_string( $value ) && ! empty( $value ) ) { |
| 1884 |
$html_class = ! empty( $html_attributes['class'] ) ? ' ' . $html_attributes['class'] : ''; |
| 1885 |
$aria_hidden = isset( $html_attributes['aria-hidden'] ) ? ' aria-hidden="' . esc_attr( $html_attributes['aria-hidden'] ) . '"' : ' aria-hidden="true"'; |
| 1886 |
|
| 1887 |
echo '<i class="' . esc_attr( $value ) . $html_class . '"' . $aria_hidden . '></i>'; |
| 1888 |
return; |
| 1889 |
} |
| 1890 |
} |
| 1891 |
|
| 1892 |
// If value is a plain string (might be a FontAwesome class without library specified) |
| 1893 |
if ( is_string( $value ) && ! empty( $value ) && empty( $library ) ) { |
| 1894 |
// Check if it looks like a FontAwesome class |
| 1895 |
if ( strpos( $value, 'fa' ) !== false || strpos( $value, 'fa-' ) !== false ) { |
| 1896 |
$icon_class = 'fas ' . esc_attr( $value ); |
| 1897 |
|
| 1898 |
$html_class = ! empty( $html_attributes['class'] ) ? ' ' . $html_attributes['class'] : ''; |
| 1899 |
$aria_hidden = isset( $html_attributes['aria-hidden'] ) ? ' aria-hidden="' . esc_attr( $html_attributes['aria-hidden'] ) . '"' : ' aria-hidden="true"'; |
| 1900 |
|
| 1901 |
echo '<i class="' . $icon_class . $html_class . '"' . $aria_hidden . '></i>'; |
| 1902 |
return; |
| 1903 |
} |
| 1904 |
|
| 1905 |
// Check if it looks like a dashicon |
| 1906 |
if ( strpos( $value, 'dashicon' ) !== false || strpos( $value, 'dashicons-' ) !== false ) { |
| 1907 |
$icon_class = 'dashicons ' . esc_attr( $value ); |
| 1908 |
|
| 1909 |
$html_class = ! empty( $html_attributes['class'] ) ? ' ' . $html_attributes['class'] : ''; |
| 1910 |
$aria_hidden = isset( $html_attributes['aria-hidden'] ) ? ' aria-hidden="' . esc_attr( $html_attributes['aria-hidden'] ) . '"' : ' aria-hidden="true"'; |
| 1911 |
|
| 1912 |
echo '<span class="' . $icon_class . $html_class . '"' . $aria_hidden . '></span>'; |
| 1913 |
return; |
| 1914 |
} |
| 1915 |
} |
| 1916 |
} |
| 1917 |
} |
| 1918 |
|