# better-payment/2.4.0/includes/Classes/Actions.php

Better Payment – Instant Payments, Donations, Fundraising with Subscriptions &amp; More, version 2.4.0. 795 lines.

- Page: https://pluginprobe.com/plugins/better-payment/2.4.0/code/includes/Classes/Actions.php
- Raw: https://pluginprobe.com/plugins/better-payment/2.4.0/raw/includes/Classes/Actions.php
- Modified: 2026-09-24T10:14:42+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/better-payment/2.4.0/code/includes/Classes/Actions.php#L10-L20`.

```php
<?php

namespace Better_Payment\Lite\Classes;
use Better_Payment\Lite\Traits\Helper as TraitsHelper;

/**
 * Exit if accessed directly
 */
if (!defined('ABSPATH')) {
    exit;
}

/**
 * The plugin action class
 * 
 * @since 0.0.1
 */
class Actions {
    use TraitsHelper;
    /**
     * Constructor
     * 
     * @since 0.0.1
     */
    public function __construct() {
        add_action( 'admin_post_paypal_form_handle', [ $this, 'paypal_form_handle' ] );
        add_action( 'admin_post_nopriv_paypal_form_handle', [ $this, 'paypal_form_handle' ] );

        add_action( 'wp_ajax_better_payment_stripe_get_token', [ $this, 'better_payment_stripe_get_token' ] );
        add_action( 'wp_ajax_nopriv_better_payment_stripe_get_token', [ $this, 'better_payment_stripe_get_token' ] );

        add_action( 'wp_ajax_better_payment_paystack_get_token', [ $this, 'better_payment_paystack_get_token' ] );
        add_action( 'wp_ajax_nopriv_better_payment_paystack_get_token', [ $this, 'better_payment_paystack_get_token' ] );

        // NOTE: PayPal IPN + verification-poll hooks are registered unconditionally
        // in better-payment.php (init_plugin), not here — they must run even when
        // Elementor is inactive (block/campaign payment flow).
    }


    /**
     * Handle the paypal form
     * 
     * @since 0.0.1
     */
    public function paypal_form_handle() {

        check_admin_referer( 'better-payment-paypal', 'security' );

        $page_id = ! empty( $_POST[ 'better_payment_page_id' ] ) ? intval( $_POST[ 'better_payment_page_id' ], 10 ) : 0;

        if ( ! $page_id ) {
            $this->redirect_previous_page();
        }

        if ( !empty( $_POST[ 'better_payment_widget_id' ] ) ) {
            $widget_id = sanitize_text_field( $_POST[ 'better_payment_widget_id' ] );
        } else {
            $this->redirect_previous_page();
        }

        $el_settings = $this->better_payment_widget_settings( $page_id, $widget_id );

        if ( empty( $el_settings ) ) {
            $this->redirect_previous_page();
        }

        if ( empty( $el_settings[ 'better_payment_paypal_business_email' ] ) ) {
            $this->redirect_previous_page();
        }

        if ( $el_settings[ 'better_payment_paypal_live_mode' ] == 'yes' ) {
            $path = "paypal";
        } else {
            $path = "sandbox.paypal";
        }

        $el_settings_currency = $el_settings[ 'better_payment_form_currency' ];
        $woo_product_id = !empty($el_settings["better_payment_form_woocommerce_product_id"]) ? intval($el_settings["better_payment_form_woocommerce_product_id"]) : 0;
        $woo_product_ids = !empty($el_settings["better_payment_form_woocommerce_product_ids"]) ? $el_settings["better_payment_form_woocommerce_product_ids"] : [0];
        $fluentcart_product_id = !empty($el_settings["better_payment_form_fluentcart_product_id"]) ? intval($el_settings["better_payment_form_fluentcart_product_id"]) : 0;
        $fluentcart_product_ids = !empty($el_settings["better_payment_form_fluentcart_product_ids"]) ? $el_settings["better_payment_form_fluentcart_product_ids"] : [0];

        // Amount, quantity, currency and campaign come from the stored settings, never
        // from the request — see PaymentRequestGuard.
        $guarded = ( new PaymentRequestGuard() )->resolve_form_payment(
            $el_settings,
            wp_unslash( $_POST ),
            [
                'page_id' => $page_id,
                'gateway' => 'paypal',
            ]
        );

        if ( is_wp_error( $guarded ) ) {
            PaymentRequestGuard::reject_form_post( $guarded );
            return;
        }

        $el_settings_currency        = $guarded['currency'];
        $el_settings_currency_symbol = $this->get_currency_symbol( esc_html($el_settings_currency) );

        $primary_payment_amount          = $guarded['amount'];
        $primary_payment_amount_quantity = $guarded['quantity'];

        $order_id     = Handler::new_order_id( 'paypal' );
        $request_data = [
            'business'      => $el_settings[ 'better_payment_paypal_business_email' ],
            'currency_code' => $el_settings_currency,
            'rm'            => '2',
            'return'        => esc_url_raw( $_POST[ 'return' ] ),
            'cancel_return' => add_query_arg( 'better_payment_paypal_id', $order_id, esc_url_raw( $_POST[ 'cancel_return' ] ) ),
            'item_number'   => $order_id,
            'item_name'     => ! empty( $el_settings['better_payment_form_title'] ) ? esc_html__( $el_settings['better_payment_form_title'], 'better-payment' ) : esc_html__('Better Payment', 'better-payment'),
            'amount'        => $primary_payment_amount,
            'cmd'           => $el_settings[ 'better_payment_paypal_button_type' ],
            'notify_url'    => admin_url( 'admin-post.php?action=better_payment_paypal_ipn' ),
        ];

        $product_ids = [
            'woo_product_ids' => $woo_product_ids,
            'fluentcart_product_ids' => $fluentcart_product_ids,
        ];

        $detailed_product_info = $this->get_detailed_product_info( $product_ids );

        //Form fields data to send via email
        $better_form_fields = [
            'amount' => sanitize_text_field($el_settings_currency_symbol) . $primary_payment_amount,
            'referer_page_id' => $page_id,
            'referer_widget_id' => $widget_id,
            'woo_product_id' => $woo_product_id,
            'woo_product_ids' => maybe_serialize( $woo_product_ids ),
            'fluentcart_product_id' => $fluentcart_product_id,
            'fluentcart_product_ids' => maybe_serialize( $fluentcart_product_ids ),
            'source' => 'paypal',
            'amount_quantity' => ! empty( $primary_payment_amount_quantity ) ? intval( $primary_payment_amount_quantity ) : '',
            'detailed_product_info' => maybe_serialize( $detailed_product_info ),
            'paypal_business_email' => sanitize_email( $el_settings['better_payment_paypal_business_email'] ),
            // Persisted so the async PayPal IPN can rebuild the e-mail body + on/off toggle.
            'email_settings'        => Handler::extract_email_settings( $el_settings ),
        ];

        // Fields only Pro's forms store (layout 6's platform flags) — see PaymentEntitlement.
        $better_form_fields = PaymentEntitlement::transaction_fields( $better_form_fields, $el_settings );

        $better_form_fields = array_merge( $better_form_fields, $this->fetch_better_form_fields($el_settings, $_POST) );

        if ( !empty( $better_form_fields[ 'primary_first_name' ] ) ) {
            $request_data[ 'primary_first_name' ] = sanitize_text_field( $better_form_fields[ 'primary_first_name' ] );
        }

        if ( !empty( $better_form_fields[ 'primary_last_name' ] ) ) {
            $request_data[ 'primary_last_name' ] = sanitize_text_field( $better_form_fields[ 'primary_last_name' ] );
        }

        if ( !empty( $better_form_fields[ 'primary_email' ] ) ) {
            $request_data[ 'primary_email' ] = sanitize_email( $better_form_fields[ 'primary_email' ] );
        }

        if ( !empty( $better_form_fields[ 'primary_reference_number' ] ) ) {
            $request_data[ 'invoice' ] = sanitize_text_field( $better_form_fields[ 'primary_reference_number' ] );
        }
        
        $campaign_id = $guarded['campaign_id'];

        Handler::payment_create(
            [
                'amount'       => floatval( $primary_payment_amount ),
                'order_id'     => $order_id,
                'payment_date' => date( 'Y-m-d H:i:s' ),
                'source'       => 'paypal',
                'form_fields_info'     => maybe_serialize( $better_form_fields ),
                'currency'     => sanitize_text_field($el_settings_currency),
                'referer'      => "widget",
                'campaign_id'  => $campaign_id,
            ]
        );
        $paypal_url = "https://www.$path.com/cgi-bin/webscr?";
        $paypal_url .= http_build_query( $request_data );
        wp_redirect( esc_url_raw($paypal_url) );
    }

    /**
     * Get the stripe token
     * 
     * @since 0.0.1
     */
    public function better_payment_stripe_get_token() {
        if ( !check_admin_referer( 'better-payment', 'security' ) ) {
            wp_send_json_error();
        }

        $setting_data_page_id = isset($_POST[ 'setting_data' ]['page_id']) ? intval( $_POST[ 'setting_data' ]['page_id'] ) : 0;
        $setting_data_widget_id = isset($_POST[ 'setting_data' ]['widget_id']) ? sanitize_text_field( $_POST[ 'setting_data' ]['widget_id'] ) : 0;

        if ( !empty( $setting_data_page_id ) ) {
            $page_id = $setting_data_page_id;
        } else {
            $err_msg = __( 'Page ID is missing', 'better-payment' );
            wp_send_json_error( esc_html($err_msg) );
        }

        if ( !empty( $setting_data_widget_id ) ) {
            $widget_id = sanitize_text_field( $setting_data_widget_id );
        } else {
            $err_msg = __( 'Widget ID is missing', 'better-payment' );
            wp_send_json_error( esc_html($err_msg) );
        }

        $el_settings = $this->better_payment_widget_settings( $page_id, $widget_id );

        // Before any setting is read: an unknown, or unpublished, form has none.
        if ( empty( $el_settings ) ) {
            wp_send_json_error( esc_html(__( 'Setting Data is missing', 'better-payment' )) );
        }

        $better_payment_keys = [
            'public_key' => 'yes' === sanitize_text_field( $el_settings[ 'better_payment_stripe_live_mode' ] ) ? sanitize_text_field( $el_settings[ 'better_payment_stripe_public_key_live' ] ) : sanitize_text_field( $el_settings[ 'better_payment_stripe_public_key' ] ),
            'secret_key' => 'yes' === sanitize_text_field( $el_settings[ 'better_payment_stripe_live_mode' ] ) ? sanitize_text_field( $el_settings[ 'better_payment_stripe_secret_key_live' ] ) : sanitize_text_field( $el_settings[ 'better_payment_stripe_secret_key' ] ),
        ];

        // Amount, quantity, currency, price ids, coupon and campaign come from the stored
        // settings, never from the request — see PaymentRequestGuard.
        $guard   = new PaymentRequestGuard();
        $guarded = $guard->resolve_form_payment(
            $el_settings,
            isset( $_POST['fields'] ) && is_array( $_POST['fields'] ) ? wp_unslash( $_POST['fields'] ) : [],
            [
                'page_id' => $page_id,
                'gateway' => 'stripe',
            ]
        );

        if ( is_wp_error( $guarded ) ) {
            wp_send_json_error( esc_html( $guarded->get_error_message() ) );
        }

        $amount             = $guarded['amount'];
        $amount_quantity    = $guarded['quantity'];
        $product_quantities = $guarded['product_quantities'];

        if ( empty( $better_payment_keys['public_key'] ) || empty( $better_payment_keys['secret_key'] ) ) {
            wp_send_json_error( esc_html(__( 'Stripe Key missing', 'better-payment' )) );
        }

        $header_info = array(
            'Authorization'  => 'Basic ' . base64_encode( sanitize_text_field( $better_payment_keys['secret_key'] ) . ':' ),
            'Stripe-Version' => '2019-05-16'
        );

        $order_id = Handler::new_order_id( 'stripe' );

        $el_settings_currency = $el_settings[ 'better_payment_form_currency' ];
        $woo_product_id = !empty($el_settings["better_payment_form_woocommerce_product_id"]) ? intval($el_settings["better_payment_form_woocommerce_product_id"]) : 0;
        $woo_product_ids = !empty($el_settings["better_payment_form_woocommerce_product_ids"]) ? $el_settings["better_payment_form_woocommerce_product_ids"] : [0];
        $fluentcart_product_id = !empty($el_settings["better_payment_form_fluentcart_product_id"]) ? intval($el_settings["better_payment_form_fluentcart_product_id"]) : 0;
        $fluentcart_product_ids = !empty($el_settings["better_payment_form_fluentcart_product_ids"]) ? $el_settings["better_payment_form_fluentcart_product_ids"] : [0];

        $el_settings_currency = $guarded['currency'];

        $el_settings_currency_symbol = $this->get_currency_symbol( esc_html($el_settings_currency) );

        $request  = [
            'success_url'                => add_query_arg( [
                'better_payment_stripe_status' => 'success',
                'better_payment_stripe_id'     => $order_id,
                'better_payment_widget_id'     => $widget_id
            ], get_permalink( $setting_data_page_id )  ),
            'cancel_url'                 => add_query_arg( [
                'better_payment_error_status' => 'error',
                'better_payment_stripe_id'    => $order_id,
                'better_payment_widget_id'    => $widget_id
            ], get_permalink( $setting_data_page_id )  ),
            'locale'                     => 'auto',
            'payment_method_types'       => [ 'card' ],
            'client_reference_id'        => time(),
            'billing_address_collection' => 'required',
            'metadata'                   => [
                'order_id' => $order_id
            ],
            'line_items'                 => [
                [
                    'amount'   => (int) round( $amount * 100 ),
                    'currency' => $el_settings_currency,
                    'name'     => ! empty( $el_settings['better_payment_form_title'] ) ? esc_html__( $el_settings['better_payment_form_title'], 'better-payment' ) : esc_html__('Better Payment', 'better-payment'),
                    'quantity' => 1
                ]
            ],
            'payment_intent_data'        => [
                'capture_method' => 'automatic',
                'description'    => ! empty( $el_settings['better_payment_form_title'] ) ? esc_html__( $el_settings['better_payment_form_title'], 'better-payment' ) : esc_html__('Better Payment', 'better-payment'),
                'metadata'       => [
                    'order_id' => $order_id
                ]
            ]
        ];

        // The typed code is kept for the receipt; what Stripe applies is decided by the guard —
        // an active promotion code, or a coupon the merchant tagged public. A bare coupon id
        // no longer works, because every coupon in the account (internal 100%-off ones
        // included) would be one guess away.
        $coupon_code = $guarded['coupon_code'];
        $discount    = $guard->resolve_stripe_discount( $coupon_code, $better_payment_keys['secret_key'] );

        if ( is_wp_error( $discount ) ) {
            wp_send_json_error( esc_html( $discount->get_error_message() ) );
        }

        if ( ! empty( $discount ) ) {
            $request['discounts'] = [ $discount ];
        }

        $product_ids = [
            'woo_product_ids' => $woo_product_ids,
            'fluentcart_product_ids' => $fluentcart_product_ids,
        ];

        $detailed_product_info = $this->get_detailed_product_info( $product_ids, $product_quantities );

        //Form fields data to send via email
        $better_form_fields = [
            'amount' => $el_settings_currency_symbol . $amount,
            'referer_page_id' => $page_id,
            'referer_widget_id' => $widget_id,
            'woo_product_id' => $woo_product_id,
            'woo_product_ids' => maybe_serialize( $woo_product_ids ),
            'fluentcart_product_id' => $fluentcart_product_id,
            'fluentcart_product_ids' => maybe_serialize( $fluentcart_product_ids ),
            'source' => 'stripe',
            'amount_quantity' => ! empty( $amount_quantity ) ? $amount_quantity : '',
            'stripe_coupon_code' => $coupon_code,
            'detailed_product_info' => maybe_serialize( $detailed_product_info ),
        ];

        // Fields only Pro's forms store (layout 6's platform flags) — see PaymentEntitlement.
        $better_form_fields = PaymentEntitlement::transaction_fields( $better_form_fields, $el_settings );

        $better_form_fields = array_merge( $better_form_fields, $this->fetch_better_form_fields($el_settings, $_POST['fields']) );

        if ( !empty( $better_form_fields['primary_first_name'] ) ) {
            $request[ 'customer_name' ] = $better_form_fields['primary_first_name'];
        }

        if ( !empty( $better_form_fields['primary_last_name'] ) ) {
            $request[ 'customer_name' ] = !empty( $request[ 'customer_name' ] ) ? $request[ 'customer_name' ] . ' ' . $better_form_fields['primary_last_name'] : $better_form_fields['primary_last_name'];
        }

        if ( !empty( $request[ 'customer_name' ] ) ) {
            $request[ 'metadata' ][ 'customer_name' ]                          = $request[ 'customer_name' ];
            $request[ 'payment_intent_data' ][ 'metadata' ][ 'customer_name' ] = $request[ 'customer_name' ];
            unset( $request[ 'customer_name' ] );
        }

        if ( !empty( $better_form_fields['primary_email'] ) ) {
            $request[ 'customer_email' ]                                        = $better_form_fields['primary_email'];
            $request[ 'metadata' ][ 'customer_email' ]                          = $request[ 'customer_email' ];
            $request[ 'payment_intent_data' ][ 'metadata' ][ 'customer_email' ] = $request[ 'customer_email' ];

        }

        // Recurring, split-payment and mixed checkouts are Pro's: refused without Pro, built by
        // Pro (or, for an older Pro, by Lite's transitional copy) — see PaymentEntitlement.
        if ( PaymentEntitlement::is_pro_form( $el_settings ) ) {
            $checkout = PaymentEntitlement::stripe_checkout(
                [
                    'request'     => $request,
                    'form_fields' => $better_form_fields,
                ],
                [
                    'settings'    => $el_settings,
                    'fields'      => isset( $_POST['fields'] ) && is_array( $_POST['fields'] ) ? wp_unslash( $_POST['fields'] ) : [],
                    'guarded'     => $guarded,
                    'order_id'    => $order_id,
                    'widget_id'   => $widget_id,
                    'header_info' => $header_info,
                ]
            );

            if ( is_wp_error( $checkout ) ) {
                wp_send_json_error( esc_html( $checkout->get_error_message() ) );
            }

            $request            = $checkout['request'];
            $better_form_fields = $checkout['form_fields'];
        }

        #ToDo: Need to prefill name field on stripe checkout
        $response = wp_safe_remote_post(
            'https://api.stripe.com/v1/checkout/sessions',
            array(
                'method'  => 'POST',
                'headers' => $header_info,
                'body'    => $request,
                'timeout' => 70,
            )
        );

        $response_ar = json_decode( $response[ 'body' ] );

        if ( ! empty( $response_ar->payment_intent ) || ( ! empty( $response_ar->mode ) && 'subscription' === $response_ar->mode ) ) {
            $campaign_id = $guarded['campaign_id'];

            Handler::payment_create(
                [
                    'amount'         => $amount,
                    'order_id'       => $order_id,
                    'payment_date'   => date( 'Y-m-d H:i:s' ),
                    'source'         => 'stripe',
                    'transaction_id' => sanitize_text_field($response_ar->payment_intent),
                    'customer_info'  => maybe_serialize( $response_ar ),
                    'form_fields_info'  => maybe_serialize( $better_form_fields ),
                    'obj_id'         => sanitize_text_field($response_ar->id),
                    'status'         => sanitize_text_field($response_ar->payment_status),
                    'currency'       => $el_settings_currency,
                    'referer'        => "widget",
                    'campaign_id'    => $campaign_id,
                ]
            );
            wp_send_json_success(
                [
                    'stripe_data'       => sanitize_text_field($response_ar->id),
                    'stripe_public_key' => sanitize_text_field( $better_payment_keys['public_key'] )
                ]
            );
        } else {
            $error_message = 'Something went wrong!';

            if (isset($response_ar->error)){
                $error_message = sanitize_text_field($response_ar->error->message);
            }

            wp_send_json_error( $error_message );
        }
    }

    /**
     * Get the paystack token
     * 
     * @since 0.0.1
     */
    public function better_payment_paystack_get_token() {
        if ( !check_admin_referer( 'better-payment', 'security' ) ) {
            wp_send_json_error();
        }

        $error_message = '';

        if( empty( $_POST[ 'setting_data' ]['page_id'] ) ){
           $error_message = __( 'Page ID is missing', 'better-payment' );
        }

        if( empty( $_POST[ 'setting_data' ]['widget_id'] ) ){
            $error_message = __( 'Widget ID is missing', 'better-payment' );
        }

        if( ! empty( $error_message ) ){
            wp_send_json_error( esc_html( $error_message ) );
        }

        $page_id = intval( $_POST[ 'setting_data' ]['page_id'] );
        $widget_id = sanitize_text_field( $_POST[ 'setting_data' ]['widget_id'] );
        $el_settings = $this->better_payment_widget_settings( $page_id, $widget_id );

        if ( empty( $el_settings ) ) {
            wp_send_json_error( esc_html(__( 'Setting Data is missing', 'better-payment' )) );
        }

        if ( empty( $el_settings[ 'better_payment_paystack_public_key' ] ) || empty( $el_settings[ 'better_payment_paystack_secret_key' ] ) ) {
            wp_send_json_error( esc_html(__( 'Paystack Key missing', 'better-payment' )) );
        }

        // Amount, quantity, currency and campaign come from the stored settings, never
        // from the request — see PaymentRequestGuard.
        $guarded = ( new PaymentRequestGuard() )->resolve_form_payment(
            $el_settings,
            isset( $_POST['fields'] ) && is_array( $_POST['fields'] ) ? wp_unslash( $_POST['fields'] ) : [],
            [
                'page_id' => $page_id,
                'gateway' => 'paystack',
            ]
        );

        if ( is_wp_error( $guarded ) ) {
            wp_send_json_error( esc_html( $guarded->get_error_message() ) );
        }

        $amount          = $guarded['amount'];
        $amount_quantity = $guarded['quantity'];

        $header_info = array(
            'Authorization'  => 'Bearer ' . sanitize_text_field( $el_settings[ 'better_payment_paystack_secret_key' ] ),
            "Cache-Control: no-cache",
        );

        $order_id = Handler::new_order_id( 'paystack' );

        $el_settings_currency = $el_settings[ 'better_payment_form_currency' ];
        $woo_product_id = !empty($el_settings["better_payment_form_woocommerce_product_id"]) ? intval($el_settings["better_payment_form_woocommerce_product_id"]) : 0;
        $woo_product_ids = !empty($el_settings["better_payment_form_woocommerce_product_ids"]) ? $el_settings["better_payment_form_woocommerce_product_ids"] : [0];
        $fluentcart_product_id = !empty($el_settings["better_payment_form_fluentcart_product_id"]) ? intval($el_settings["better_payment_form_fluentcart_product_id"]) : 0;
        $fluentcart_product_ids = !empty($el_settings["better_payment_form_fluentcart_product_ids"]) ? $el_settings["better_payment_form_fluentcart_product_ids"] : [0];

        $el_settings_currency = $guarded['currency'];

        $el_settings_currency_symbol = $this->get_currency_symbol( esc_html($el_settings_currency) );

        $redirection_url_success    = get_permalink( $page_id );
        $redirection_url_error      = get_permalink( $page_id );

        $request  = [
            'amount'   => ( $amount * 100 ),
            'currency' => $el_settings_currency,
            'cart_id'  => $order_id,
            'callback_url'  => add_query_arg( [
                'better_payment_paystack_status' => 'success',
                'better_payment_paystack_id'     => $order_id,
                'better_payment_widget_id'     => $widget_id
            ], $redirection_url_success ),
            'metadata' => [
                'cancel_action' => add_query_arg( [
                    'better_payment_error_status' => 'error',
                    'better_payment_paystack_id'  => $order_id,
                    'better_payment_widget_id'    => $widget_id
                ], $redirection_url_error )
            ]
        ];

        $product_ids = [
            'woo_product_ids' => $woo_product_ids,
            'fluentcart_product_ids' => $fluentcart_product_ids,
        ];

        $detailed_product_info = $this->get_detailed_product_info( $product_ids );

        //Form fields data to send via email
        $better_form_fields = [
            'amount' => $el_settings_currency_symbol . $amount,
            'referer_page_id' => $page_id,
            'referer_widget_id' => $widget_id,
            'woo_product_id' => $woo_product_id,
            'woo_product_ids' => maybe_serialize( $woo_product_ids ),
            'fluentcart_product_id' => $fluentcart_product_id,
            'fluentcart_product_ids' => maybe_serialize( $fluentcart_product_ids ),
            'source' => 'paystack',
            'amount_quantity' => ! empty( $amount_quantity ) ? $amount_quantity : '',
            'detailed_product_info' => maybe_serialize( $detailed_product_info ),
        ];

        // Fields only Pro's forms store (layout 6's platform flags) — see PaymentEntitlement.
        $better_form_fields = PaymentEntitlement::transaction_fields( $better_form_fields, $el_settings );

        $better_form_fields = array_merge( $better_form_fields, $this->fetch_better_form_fields($el_settings, $_POST['fields']) );

        if ( !empty( $better_form_fields['primary_email'] ) ) {
            $request[ 'email' ] = $better_form_fields['primary_email'];
        }

        if ( !empty( $better_form_fields['primary_first_name'] ) ) {
            $request[ 'customer_name' ] = $better_form_fields['primary_first_name'];
        }

        if ( !empty( $better_form_fields['primary_last_name'] ) ) {
            $request[ 'customer_name' ] = !empty( $request[ 'customer_name' ] ) ? $request[ 'customer_name' ] . ' ' . $better_form_fields['primary_last_name'] : $better_form_fields['primary_last_name'];
        }

        if ( !empty( $request[ 'customer_name' ] ) ) {
            $request[ 'metadata' ][ 'customer_name' ]   = $request[ 'customer_name' ];
            unset( $request[ 'customer_name' ] );
        }

        $response = wp_safe_remote_post(
            'https://api.paystack.co/transaction/initialize',
            array(
                'method'  => 'POST',
                'headers' => $header_info,
                'body'    => $request,
                'timeout' => 70,
            )
        );

        $response_ar = json_decode( $response[ 'body' ] );

        if( empty( $response_ar->status ) || empty( $response_ar->data ) ){
            $error_message = $response_ar->message ? sanitize_text_field($response_ar->message) : 'Something went wrong!';

            if (isset($response_ar->error)){
                $error_message = sanitize_text_field($response_ar->error->message);
            }

            wp_send_json_error( $error_message );
        }

        $campaign_id = $guarded['campaign_id'];

        Handler::payment_create(
            [
                'amount'         => $amount,
                'order_id'       => $order_id,
                'payment_date'   => date( 'Y-m-d H:i:s' ),
                'source'         => 'paystack',
                // Paystack's reference, so verification can bind it to this order.
                'transaction_id' => ! empty( $response_ar->data->reference ) ? sanitize_text_field( $response_ar->data->reference ) : '',
                'customer_info'  => maybe_serialize( $response_ar ),
                'form_fields_info'  => maybe_serialize( $better_form_fields ),
                'status'         => 'unpaid',
                'currency'       => $el_settings_currency,
                'referer'        => "widget",
                'campaign_id'    => $campaign_id,
            ]
        );

        $authorization_url = ! empty( $response_ar->data->authorization_url ) ? esc_url_raw( $response_ar->data->authorization_url ) : '';

        wp_send_json_success(
            [
                'authorization_url' => $authorization_url,
            ]
        );
    }

    /**
     * Get detailed product information
     * @param array $product_ids Array of woo_product_ids and fluentcart_product_ids
     * 
     * @since 1.4.5
     */
    public function get_detailed_product_info( $product_ids, $product_quantities = [] ) {
        $detailed_product_info = [];

        if (function_exists('wc_get_product') && !empty($product_ids['woo_product_ids'])) {
            foreach ($product_ids['woo_product_ids'] as $key => $product_id) {
                if (empty($product_id)) continue;

                $product = wc_get_product($product_id);
                if ($product) {
                    $product_image_src_array = wp_get_attachment_image_src( get_post_thumbnail_id( $product->get_id() ), 'single-post-thumbnail' );
                    $product_image_src = is_array( $product_image_src_array ) && count( $product_image_src_array ) ? $product_image_src_array[0] : '';

                    $quantity = !empty($product_quantities[$key]) ? intval($product_quantities[$key]) : 1;
                    $price = floatval( $product->get_price() );
                    $total_price = floatval( $price * $quantity );

                    $detailed_product_info['woo_products'][$product_id] = [
                        'name' => $product->get_name(),
                        'product_id' => intval( $product_id ),
                        'permalink' => esc_url( get_permalink($product->get_id()) ),
                        'image_src' => esc_url( $product_image_src ),
                        'price' => $price,
                        'quantity' => $quantity,
                        'total_price' => $total_price,
                    ];
                }
            }
        }

        if (function_exists('fluentCart') && class_exists('\FluentCart\App\Models\Product') && !empty($product_ids['fluentcart_product_ids'])) {
            foreach ($product_ids['fluentcart_product_ids'] as $key => $product_id) {
                if (empty($product_id)) continue;

                try {
                    $fluentcart_product = \FluentCart\App\Models\Product::query()
                        ->with(['detail', 'variants'])
                        ->find($product_id);

                    if ($fluentcart_product) {
                        $product_price = 0;
                        if (!empty($fluentcart_product->variants) && count($fluentcart_product->variants) > 0) {
                            $product_price = $fluentcart_product->variants[0]->item_price;
                        } elseif (!empty($fluentcart_product->detail)) {
                            $product_price = $fluentcart_product->detail->min_price;
                        }

                        if ( ! empty( $product_price ) ) {
                            $product_price = floatval( $product_price / 100 );
                        }

                        $product_image_src_array = wp_get_attachment_image_src( get_post_thumbnail_id( $fluentcart_product->ID ), 'single-post-thumbnail' );
                        $product_image_src = is_array( $product_image_src_array ) && count( $product_image_src_array ) ? $product_image_src_array[0] : '';

                        $quantity = !empty($product_quantities[$key]) ? intval($product_quantities[$key]) : 1;
                        $total_price = floatval( $product_price * $quantity );

                        $detailed_product_info['fluentcart_products'][$product_id] = [
                            'name' => sanitize_text_field( $fluentcart_product->post_title ),
                            'product_id' => intval( $product_id ),
                            'permalink' => esc_url( get_permalink($fluentcart_product->ID) ),
                            'image_src' => esc_url( $product_image_src ),
                            'price' => $product_price,
                            'quantity' => $quantity,
                            'total_price' => $total_price,
                        ];
                    }
                } catch (\Exception $e) {
                    //
                }
            }
        }

        return $detailed_product_info;
    }

    /**
     * Widget settings
     * 
     * @since 1.0.0
     */
    public function better_payment_widget_settings( $page_id, $widget_id ) {
        // page_id is the visitor's to choose. A form on a page they cannot see — draft,
        // private, scheduled, password-protected — must be neither payable nor probeable.
        if ( ! $this->is_payable_form_page( $page_id ) ) {
            return [];
        }

        $settings = $this->get_elementor_widget_settings( $page_id, $widget_id );

        return $settings;
    }

    /**
     * Redirect to referer page
     * 
     * @since 1.0.0
     */
    public function redirect_previous_page() {
        $location = $_SERVER[ 'HTTP_REFERER' ];
        wp_safe_redirect( $location );
        exit();
    }

    /**
     * Fetch form fields
     * 
     * @since 0.0.4
     */

    public function fetch_better_form_fields($el_settings, $post_data_form_fields) {
        $better_form_fields = array();

        $better_payment_helper_obj = new Helper();
        $post_data_primary_first_name = '';
        $post_data_primary_last_name = '';
        $post_data_primary_email = '';

        $post_fields = $post_data_form_fields;

        // The fields repeater a Pro form renders is Pro's to name — see PaymentEntitlement.
        $el_settings['better_payment_form_fields'] = PaymentEntitlement::form_fields( is_array( $el_settings ) ? $el_settings : [] );

        //in case of duplicate post name using the first one
        if(isset($el_settings['better_payment_form_fields']) && count($el_settings['better_payment_form_fields'])){
            foreach ($el_settings['better_payment_form_fields'] as $item) {

                $item_field_name = $better_payment_helper_obj->titleToSnake($item["better_payment_field_name_heading"]);
                if(!empty($item['better_payment_primary_field_type']) ){
                    $item_primary_field_type = $item['better_payment_primary_field_type'];

                    if( isset($post_fields[$item_primary_field_type]) ) {
                        $post_fields[$item_primary_field_type] =  is_array($post_fields[$item_primary_field_type]) ? $post_fields[$item_primary_field_type][0] : $post_fields[$item_primary_field_type];
                    }

                    if( isset($post_fields[$item_field_name]) ) {
                        $post_fields[$item_field_name] =  is_array($post_fields[$item_field_name]) ? $post_fields[$item_field_name][0] : $post_fields[$item_field_name];
                    }

                    if ( 'primary_first_name' == $item_primary_field_type && isset($post_fields[$item_primary_field_type])){
                        $better_form_fields[$item_primary_field_type] =  sanitize_text_field($post_fields[$item_primary_field_type]);
                        $post_data_primary_first_name = sanitize_text_field($post_fields[$item_primary_field_type]);

                    }else if ( 'primary_last_name' == $item_primary_field_type && isset($post_fields[$item_primary_field_type])){
                        $better_form_fields[$item_primary_field_type] = sanitize_text_field($post_fields[$item_primary_field_type]);
                        $post_data_primary_last_name = sanitize_text_field($post_fields[$item_primary_field_type]);

                    }else if( 'primary_email' == $item_primary_field_type && isset($post_fields[$item_primary_field_type])){
                        $better_form_fields[$item_primary_field_type] = sanitize_email($post_fields[$item_primary_field_type]);
                        $post_data_primary_email = sanitize_email($post_fields[$item_primary_field_type]);

                    }else if ( 'primary_payment_amount' == $item_primary_field_type && isset($post_fields[$item_primary_field_type]) ){
                        $better_form_fields[$item_primary_field_type] = floatval($post_fields[$item_primary_field_type]);

                    }else if ( 'primary_reference_number' == $item_primary_field_type && isset($post_fields[$item_primary_field_type]) ){
                        $better_form_fields[$item_primary_field_type] = sanitize_text_field($post_fields[$item_primary_field_type]);

                    } else {
                        $better_form_fields[$item_field_name] = !empty($post_fields[$item_field_name]) ? sanitize_text_field($post_fields[$item_field_name]) : '';
                    }

                }
            }
        }

        return $better_form_fields;
    }
}

```
