<?php

/**
 * Main plugin class
 *
 * @package     bspscw
 */
namespace BSD_Split_Pay_Stripe_Connect_Woo\Inc;

use Automattic\WooCommerce\Utilities\OrderUtil;
use Exception;
if ( !defined( 'ABSPATH' ) ) {
    exit( 'Sorry!' );
}
// Exit if accessed directly
if ( !class_exists( 'BSD_Split_Pay_Stripe_Connect_Woo\\Inc\\BSD_SCSP_Main_Plugin' ) ) {
    class BSD_SCSP_Main_Plugin {
        public string $log_prefix = '[BSD Split Pay for Stripe Connect] ';

        public string $secret = '';

        /**
         * Safely log via the official WC Stripe gateway when present.
         *
         * Split Pay supports both `woocommerce-gateway-stripe` (which ships
         * WC_Stripe_Logger) and `woo-stripe-payment` (which does NOT). On sites
         * using only the latter, every WC_Stripe_Logger::log() call would fatal.
         * This helper guards against:
         *   - Class missing (woo-stripe-payment-only sites)
         *   - log() method removed in a future WC Stripe release (deprecated since 9.7.0)
         *
         * Mirrors the guarded pattern at
         * includes/Integrations/WooCommerce/WooCommerceIntegration.php:754-760.
         *
         * @param string $message  The log message to record.
         */
        private function safe_wcs_log( $message ) : void {
            if ( class_exists( '\\WC_Stripe_Logger' ) ) {
                if ( method_exists( '\\WC_Stripe_Logger', 'log' ) ) {
                    \WC_Stripe_Logger::log( $message );
                    return;
                }
                if ( method_exists( '\\WC_Stripe_Logger', 'debug' ) ) {
                    \WC_Stripe_Logger::debug( $message );
                    return;
                }
            }
            if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
                error_log( $message );
                // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
            }
        }

        public function run() {
            $wc_settings = get_option( 'woocommerce_stripe_settings' );
            $is_test = isset( $wc_settings['testmode'] ) && $wc_settings['testmode'] === 'yes';
            $secret_key = ( $is_test ? 'test_webhook_secret' : 'webhook_secret' );
            $this->secret = ( !empty( $wc_settings[$secret_key] ) ? $wc_settings[$secret_key] : '' );
            add_action( 'woocommerce_api_wc_stripe', array($this, 'check_for_webhook'), 9 );
            if ( function_exists( 'BSD_Split_Pay_Stripe_Connect_Woo\\bsdwcscsp_fs' ) ) {
                // Add account link to plugin links
                add_filter( 'plugin_action_links_' . SPP_PLUGIN_BASE_NAME, array($this, 'bsd_scsp_plugin_links') );
            }
            // Add Documentation link to plugin row meta
            add_filter(
                'plugin_row_meta',
                array($this, 'plugin_row_meta'),
                10,
                2
            );
            // Add custom tab to Product Data metabox
            add_filter(
                'woocommerce_product_data_tabs',
                array($this, 'bsd_product_data_tab'),
                10,
                1
            );
            // Add fields to the custom data tab
            add_action( 'woocommerce_product_data_panels', array($this, 'bsd_product_data_fields') );
            // 3.7.5: the legacy main plugin is the canonical owner of the
            // product-editor Split Pay UI (tab + panel partial + meta save) for full
            // backwards compatibility across every 3.x install. Mark that we have
            // bound those hooks so the namespaced WooCommerceIntegration::registerAdminUI()
            // (plugins_loaded:30, runs later) does NOT re-bind the SAME callbacks/partial
            // and double-render the panel / double-fire the save. Same tab key
            // (stripe-connect-split-pay-tab), same target, same partial, same meta keys —
            // so skipping the new bindings is lossless.
            if ( !defined( 'SPP_LEGACY_PRODUCT_UI_BOUND' ) ) {
                define( 'SPP_LEGACY_PRODUCT_UI_BOUND', true );
            }
            if ( function_exists( 'BSD_Split_Pay_Stripe_Connect_Woo\\bsdwcscsp_fs' ) ) {
            }
            add_action(
                'woocommerce_product_after_variable_attributes',
                array($this, 'bsd_variable_product_fields'),
                10,
                3
            );
            if ( function_exists( 'BSD_Split_Pay_Stripe_Connect_Woo\\bsdwcscsp_fs' ) ) {
            }
            add_action( 'init', array($this, 'bsd_background_actions') );
            add_action( 'bsd_migrate_existing_split_type_values', array($this, 'bsd_migrate_existing_split_type_values_cb') );
            add_action( 'before_woocommerce_init', array($this, 'spp_hpos_declare_compatibility') );
            /** Product add-on meta boxes (Product Add-Ons Ultimate / pewc) */
            if ( is_plugin_active( 'product-extras-for-woocommerce/product-extras-for-woocommerce.php' ) ) {
                add_action( 'add_meta_boxes', array($this, 'add_meta_box_for_pewc') );
                add_action( 'save_post', array($this, 'save_metabox_data_for_pewc') );
            }
            // Refund reversal and retry now handled by WooCommerceIntegration::handleRefund/retryTransfers
        }

        public function spp_hpos_declare_compatibility() {
            if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
                \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', SPP_PLUGIN_MAIN_FILE_PATH, true );
            }
        }

        public function add_meta_box_for_pewc() {
            add_meta_box(
                'custom_html_for_spp',
                __( 'Split pay plugin', 'bsd-split-pay-stripe-connect-woo' ),
                array($this, "spp_pewc_custom_html_callback"),
                array('pewc_group'),
                'normal',
                'default'
            );
        }

        public function spp_pewc_custom_html_callback( $post ) {
            wp_nonce_field( 'save_metabox_data', 'pewc_metabox_nonce' );
            $value = get_post_meta( $post->ID, "spp_connected_accounts", true );
            global $bsd_sca;
            // 3.7.5: filter vendor accounts to the store's active Stripe mode.
            $spp_active_mode = ( !empty( $bsd_sca ) ? $bsd_sca->active_stripe_mode() : '' );
            if ( empty( $bsd_sca ) ) {
                $get_accounts = [];
            } else {
                $get_accounts = $bsd_sca->get_stored_accounts( $spp_active_mode );
            }
            $level = 'global';
            $get_accounts = apply_filters( "spp_get_stored_accounts", $get_accounts, $level );
            ?>

			<div class="pewc-metafield ">
				<label for="spp_connected_accounts"><?php 
            esc_html_e( 'Connected Stripe Account ID', 'bsd-split-pay-stripe-connect-woo' );
            ?></label>
				<div class="bsd_stripe_select_wrapper" style="max-width: 470px;min-width: 470px;">
					<select name="spp_connected_accounts"
						id="spp_connected_accounts" class="sspscwsca_select" style="width: 420px;">
						<?php 
            // 3.7.5: keep a saved wrong-mode/unsynced account visible + labelled.
            $spp_pewc_saved = ( is_string( $value ) ? trim( $value ) : '' );
            $spp_pewc_in_list = false;
            if ( $spp_pewc_saved !== '' && !empty( $get_accounts ) ) {
                foreach ( $get_accounts as $spp_pewc_acc ) {
                    if ( isset( $spp_pewc_acc['bsd_account_id'] ) && trim( (string) $spp_pewc_acc['bsd_account_id'] ) === $spp_pewc_saved ) {
                        $spp_pewc_in_list = true;
                        break;
                    }
                }
            }
            if ( !$spp_pewc_in_list && $spp_pewc_saved !== '' && !empty( $bsd_sca ) ) {
                printf( "<option value=\"%s\" selected='selected'>%s</option>", esc_attr( $spp_pewc_saved ), esc_html( $bsd_sca->unavailable_account_label( $spp_pewc_saved, $spp_active_mode ) ) );
            }
            if ( !empty( $get_accounts ) ) {
                ?>
							<option value=""><?php 
                esc_html_e( "Select", 'bsd-split-pay-stripe-connect-woo' );
                ?></option>
							<?php 
                foreach ( $get_accounts as $gak ) {
                    $display_option = "";
                    if ( !empty( $gak["bsd_account_name"] ) && isset( $gak["bsd_account_email"] ) && !empty( $gak["bsd_account_email"] ) ) {
                        $display_option .= $gak["bsd_account_name"] . " - " . $gak["bsd_account_email"];
                    } elseif ( !empty( $gak["bsd_account_name"] ) ) {
                        $display_option .= $gak["bsd_account_name"];
                    } else {
                        $display_option .= trim( $gak["bsd_account_id"] );
                    }
                    ?>
								<option value="<?php 
                    echo esc_attr( trim( $gak["bsd_account_id"] ) );
                    ?>" <?php 
                    echo ( $value == trim( $gak["bsd_account_id"] ) ? 'selected' : '' );
                    ?>><?php 
                    echo esc_html( $display_option );
                    ?></option>
						<?php 
                }
            }
            ?>

					</select>

				</div>
			</div>
<?php 
        }

        public function save_metabox_data_for_pewc( $post_id ) {
            // Check the nonce is set
            if ( !isset( $_POST['pewc_metabox_nonce'] ) ) {
                return;
            }
            // Verify the nonce
            if ( !wp_verify_nonce( $_POST['pewc_metabox_nonce'], 'save_metabox_data' ) ) {
                return;
            }
            /* if( get_post_type( $post_id ) == 'pewc_group' ) {
            				// Do groups separately
            				return;
            			}  */
            // If this is an autosave, our form has not been submitted, so we don't want to do anything.
            /* if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
            				return;
            			} */
            // Check the user's permissions.
            /* if( ! current_user_can( 'edit_post', $post_id ) ) {
            				return;
            			} */
            $data = sanitize_text_field( wp_unslash( $_POST["spp_connected_accounts"] ) );
            update_post_meta( $post_id, "spp_connected_accounts", $data );
        }

        public function fee( $atts ) {
            $atts = shortcode_atts( array(
                'percent'       => '',
                'min_fee'       => '',
                'max_fee'       => '',
                'product_price' => '',
            ), $atts, 'fee' );
            $calculated_fee = 0;
            if ( $atts['percent'] ) {
                $calculated_fee = $atts['product_price'] * (floatval( $atts['percent'] ) / 100);
            }
            if ( $atts['min_fee'] && $calculated_fee < $atts['min_fee'] ) {
                $calculated_fee = $atts['min_fee'];
            }
            if ( $atts['max_fee'] && $calculated_fee > $atts['max_fee'] ) {
                $calculated_fee = $atts['max_fee'];
            }
            return $calculated_fee;
        }

        public function get_chosen_shipping_methods( $calculated_shipping_packages = array() ) {
            $chosen_methods = array();
            // Get chosen methods for each package to get our totals.
            foreach ( $calculated_shipping_packages as $key => $package ) {
                $chosen_method = wc_get_chosen_shipping_method_for_package( $key, $package );
                if ( $chosen_method ) {
                    $chosen_methods[$key] = $package['rates'][$chosen_method];
                }
            }
            return $chosen_methods;
        }

        public function bsd_get_all_shipping_zones() {
            $data_store = \WC_Data_Store::load( 'shipping-zone' );
            $raw_zones = $data_store->get_zones();
            $zones = array();
            foreach ( $raw_zones as $raw_zone ) {
                $zones[] = new \WC_Shipping_Zone($raw_zone);
            }
            return $zones;
        }

        public function bsd_background_actions() {
            if ( class_exists( 'WooCommerce' ) ) {
                include_once WC_ABSPATH . 'packages/action-scheduler/action-scheduler.php';
                $bsd_migration = get_option( 'bsd_migration', false );
                if ( empty( $bsd_migration ) && false === as_has_scheduled_action( 'bsd_migrate_existing_split_type_values' ) ) {
                    as_schedule_single_action(
                        strtotime( 'now' ),
                        'bsd_migrate_existing_split_type_values',
                        array(),
                        '',
                        true
                    );
                }
            }
        }

        public function bsd_migrate_existing_split_type_values_cb() {
            $bsd_migration = get_option( 'bsd_migration', false );
            // $bsd_migration = 0;
            if ( empty( $bsd_migration ) ) {
                global $wpdb;
                $table_prefix = $wpdb->prefix;
                $table_name = $table_prefix . SPP_CONNECTED_ID_TABLE;
                $connected_account_query = 'select * from ' . $table_name . ' order by bsd_connected_id asc limit 1 ';
                // $table_name is a constant identifier ($table_prefix . SPP_CONNECTED_ID_TABLE); this fixed SELECT has no bindable user input.
                $connected_account_results = $wpdb->get_results( $connected_account_query, ARRAY_A );
                // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- constant table identifier, no user input.
                $first_connected_acc_id = '';
                if ( !empty( $connected_account_results ) && isset( $connected_account_results[0]['bsd_connected_account_id'] ) ) {
                    $first_connected_acc_id = $connected_account_results[0]['bsd_connected_account_id'];
                }
                $bsd_last_page = get_option( 'bsd_last_page', false );
                // update_option("bsd_last_page", 0);
                $page = ( empty( $bsd_last_page ) ? 1 : $bsd_last_page );
                $args = array(
                    'post_type'      => array('product', 'product_variation'),
                    'post_status'    => 'publish',
                    'fields'         => 'ids',
                    'posts_per_page' => 50,
                    'paged'          => $page,
                    'meta_query'     => array(array(
                        'key'     => '_bsd_spscwt_product_type',
                        'compare' => 'EXISTS',
                    )),
                );
                $query = new \WP_Query($args);
                if ( !empty( $query->posts ) ) {
                    foreach ( $query->posts as $prod_id ) {
                        // $product = new \WC_product($prod_id);
                        $_bsd_spscwt_product_connected_account = get_post_meta( $prod_id, '_bsd_spscwt_product_connected_account', true );
                        if ( !empty( $_bsd_spscwt_product_connected_account ) ) {
                            continue;
                        }
                        $_bsd_spscwt_product_type = get_post_meta( $prod_id, '_bsd_spscwt_product_type', true );
                        if ( !empty( $_bsd_spscwt_product_type ) ) {
                            if ( $_bsd_spscwt_product_type == 'percentage' ) {
                                $_stripe_connect_split_pay_transfer_percentage = get_post_meta( $prod_id, '_stripe_connect_split_pay_transfer_percentage', true );
                                update_post_meta( $prod_id, '_bsd_spscwt_product_type_ko', $_bsd_spscwt_product_type );
                                update_post_meta( $prod_id, '_stripe_connect_split_pay_transfer_percentage_ko', $_stripe_connect_split_pay_transfer_percentage );
                                update_post_meta( $prod_id, '_bsd_spscwt_product_connected_account', array(
                                    0 => $first_connected_acc_id,
                                ) );
                                update_post_meta( $prod_id, '_bsd_spscwt_product_type', array(
                                    0 => $_bsd_spscwt_product_type,
                                ) );
                                update_post_meta( $prod_id, '_stripe_connect_split_pay_transfer_percentage', array(
                                    0 => $_stripe_connect_split_pay_transfer_percentage,
                                ) );
                            } elseif ( $_bsd_spscwt_product_type == 'amount' ) {
                                $_bsd_spscwt_product_amount = get_post_meta( $prod_id, '_bsd_spscwt_product_amount', true );
                                update_post_meta( $prod_id, '_bsd_spscwt_product_type_ko', $_bsd_spscwt_product_type );
                                update_post_meta( $prod_id, '_bsd_spscwt_product_amount_ko', $_bsd_spscwt_product_amount );
                                update_post_meta( $prod_id, '_bsd_spscwt_product_connected_account', array(
                                    0 => $first_connected_acc_id,
                                ) );
                                update_post_meta( $prod_id, '_bsd_spscwt_product_type', array(
                                    0 => $_bsd_spscwt_product_type,
                                ) );
                                update_post_meta( $prod_id, '_bsd_spscwt_product_amount', array(
                                    0 => $_bsd_spscwt_product_amount,
                                ) );
                            }
                        }
                    }
                    $next_page = (int) $page + 1;
                    update_option( 'bsd_last_page', $next_page );
                } else {
                    update_option( 'bsd_migration', '1' );
                }
            }
        }

        /*
         * Add account link to plugin links
         *
         */
        public function bsd_scsp_plugin_links( $links ) {
            $plugin_links = array('<a href="' . admin_url( 'admin.php?page=bsd-split-pay-stripe-connect-woo-account' ) . '">' . __( 'Account', 'bsd-split-pay-stripe-connect-woo' ) . '</a>');
            return array_merge( $plugin_links, $links );
        }

        /*
         * Add Documentation link to plugin row meta
         *
         */
        public function plugin_row_meta( $plugin_meta, $plugin_file ) {
            if ( SPP_PLUGIN_BASE_NAME === $plugin_file ) {
                $row_meta = array(
                    'docs' => '<a href="https://docs.splitpayplugin.com" aria-label="' . esc_attr( __( 'View Documentation', 'bsd-split-pay-stripe-connect-woo' ) ) . '" target="_blank" rel="noopener noreferrer">' . __( 'Documentation', 'bsd-split-pay-stripe-connect-woo' ) . '</a>',
                );
                $plugin_meta = array_merge( $plugin_meta, $row_meta );
            }
            return $plugin_meta;
        }

        /*
         * Add custom tab to Product Data metabox
         *
         */
        public function bsd_product_data_tab( $product_data_tabs ) {
            global $post;
            $product = wc_get_product( $post->ID );
            $product_types = wc_get_product_types();
            /** This filter is documented in includes/Integrations/WooCommerce/WooCommerceIntegration.php */
            $classes = apply_filters( 'spp_product_data_tab_classes', array('show_if_simple'), $this );
            $product_data_tabs['stripe-connect-split-pay-tab'] = array(
                'label'  => __( 'Split Pay Plugin', 'bsd-split-pay-stripe-connect-woo' ),
                'target' => 'stripe_connect_split_pay_product_data',
                'class'  => ( is_array( $classes ) ? array_values( $classes ) : array('show_if_simple') ),
            );
            /*
            			}else{
            				return $product_data_tabs;
            			} */
            return $product_data_tabs;
        }

        /*
         * Add fields to the custom data tab
         *
         */
        public function bsd_product_data_fields( $product_data_tabs ) {
            ob_start();
            require SPP_PLUGIN_DIR . '/includes/admin/partials/bsd-simple-product-table.php';
            $variable_product_data_html = ob_get_clean();
            // The partial is trusted markup (form fields) whose dynamic values are
            // individually escaped at the point of output inside the template; it
            // contains <select>/<option>/<input> that wp_kses_post() would strip,
            // which would break the product editor. Output is therefore already safe.
            echo $variable_product_data_html;
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        }

        /*
         * Save fields of the custom data tab
         *
         */
        public function bsd_product_data_fields_save( $post_id ) {
            /*
             * 3.7.4 form-presence gate (sc-7216 — product-save erasure regression).
             *
             * Pre-3.7.4 this handler unconditionally overwrote / deleted every SPP
             * product-level meta key based purely on whether the corresponding
             * $_POST entry was present. That worked when the SPP product-tab
             * partial actually rendered and POSTed its fields. It silently
             * destroyed data whenever the partial DIDN'T render its fields:
             *
             *   - variable products' parent save (the simple-product partial's
             *     inputs aren't on the form)
             *   - max_input_vars truncation on large products (PHP silently
             *     drops fields past the configured cap, default 1000)
             *   - JS render failure mid-tab (account dropdown never populated,
             *     so the inputs aren't in the DOM at submit time)
             *   - WC REST API / wp_update_post / programmatic third-party saves
             *   - any plugin that hooks woocommerce_process_product_meta and
             *     does its own save without our fields in scope
             *
             * The fix: the SPP simple-product partial now renders a hidden
             * input `bsd_spp_product_tab_rendered=1` (see
             * includes/admin/partials/bsd-simple-product-table.php). If that
             * marker is missing from $_POST, the SPP tab wasn't on this form
             * submission and we MUST leave every SPP meta key untouched.
             *
             * The intentional "user trashed every row and clicked Update" flow
             * still works: the marker is present, the SPP arrays come through
             * as empty, and the handler clears the meta exactly as before.
             *
             * Backfill for already-erased data ships separately in
             * migration-374.php, which reconstructs lost product->vendor
             * mappings from the transfer log.
             */
            // PT-fix-3.7.5 (security #16): defense-in-depth against the
            // WCFMCompat::maybeSaveOnShutdown auth-bypass. The shutdown
            // handler re-emits `spp_compat_save_product_meta` and re-enters
            // this method from request-shutdown context (i.e. without WP's
            // usual edit-screen nonce + cap chain). Without these checks an
            // unauthenticated POST to /wp-cron.php or any other shutdown-firing
            // endpoint with body `bsd_spp_product_tab_rendered=1&post_ID=42`
            // could overwrite product 42's connected-account meta, redirecting
            // future transfers to the attacker's Stripe account. Verifying
            // edit_post cap + product post-type here closes that window
            // regardless of which dispatch path got us here.
            $post_id = (int) $post_id;
            if ( $post_id <= 0 || get_post_type( $post_id ) !== 'product' ) {
                return;
            }
            if ( !function_exists( 'current_user_can' ) || !current_user_can( 'edit_post', $post_id ) ) {
                return;
            }
            // phpcs:disable WordPress.Security.NonceVerification.Missing
            if ( empty( $_POST['bsd_spp_product_tab_rendered'] ) ) {
                return;
            }
            // phpcs:enable WordPress.Security.NonceVerification.Missing
            $_bsd_spscwt_product_connected_account = ( isset( $_POST['_bsd_spscwt_product_connected_account'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['_bsd_spscwt_product_connected_account'] ) ) : null );
            $_bsd_spscwt_product_type = ( isset( $_POST['_bsd_spscwt_product_type'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['_bsd_spscwt_product_type'] ) ) : null );
            $transfer_percentage = ( isset( $_POST['_stripe_connect_split_pay_transfer_percentage'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['_stripe_connect_split_pay_transfer_percentage'] ) ) : null );
            $_bsd_spscwt_product_amount = ( isset( $_POST['_bsd_spscwt_product_amount'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['_bsd_spscwt_product_amount'] ) ) : null );
            /* Shipping */
            $_bsd_spscwt_shipping_type = ( isset( $_POST['bsd_spscwt_shipping_type'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['bsd_spscwt_shipping_type'] ) ) : null );
            $transfer_shipping_percentage = ( isset( $_POST['bsd_prod_shipping_percentage'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['bsd_prod_shipping_percentage'] ) ) : null );
            $_bsd_spscwt_shipping_amount = ( isset( $_POST['bsd_prod_shipping_amount'] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['bsd_prod_shipping_amount'] ) ) : null );
            /*
             * 3.7.3 fix (Carlos Lozano / sc-7171 vendor-save regression):
             *
             * Pre-fix this block applied a "validation gate" that dropped any
             * connected_account row whose paired percent/amount input was empty.
             * When a user selected a vendor in the dropdown and saved WITHOUT
             * filling in the percent or amount field (a very common first-time
             * workflow), the gate produced an empty array and update_post_meta
             * erased the selection. On reload the dropdown returned to blank,
             * leaving the user thinking the save was broken.
             *
             * Symptom reported by Carlos Lozano on May 19 2026: "If I go to a
             * product and try to add a vendor to it, it lets me do it, but once
             * I save, the page refreshes and shows no selected vendor."
             *
             * Fix: persist the connected account selection unconditionally —
             * matches the new namespaced WCProductAdapter::saveProductSplitPaySettings
             * which never gated on percent/amount. Validation of percent/amount
             * is the user's responsibility (we surface a dismissible admin
             * notice via spp-validation-notices.php when totals look wrong, but
             * we never silently lose data).
             */
            /*
             * 3.7.4 hotfix (Vanessa Provs / profplaza.nl): only touch vendor meta
             * when the account dropdown was on the form. The tab marker is always
             * present (hidden WC panel), but new products ship a placeholder row
             * without name= attributes until JS adds a row — and saves that omit
             * _bsd_spscwt_product_connected_account must not wipe stored vendors.
             * Matches WCProductAdapter::saveProductSplitPaySettings (null = skip).
             */
            if ( isset( $_POST['_bsd_spscwt_product_connected_account'] ) ) {
                $prod_valid_connected_account = array();
                if ( !empty( $_bsd_spscwt_product_connected_account ) ) {
                    foreach ( $_bsd_spscwt_product_connected_account as $bspcak => $bspcav ) {
                        if ( !empty( $bspcav ) ) {
                            $prod_valid_connected_account[$bspcak] = $bspcav;
                        }
                    }
                }
                $prod_valid_connected_account = apply_filters( 'spp_before_save_product_accounts', $prod_valid_connected_account, $post_id );
                update_post_meta( $post_id, '_bsd_spscwt_product_connected_account', $prod_valid_connected_account );
            }
            $_bsd_spscwt_product_type = apply_filters( 'spp_before_save_product_types', $_bsd_spscwt_product_type, $post_id );
            if ( empty( $_bsd_spscwt_product_type ) ) {
                delete_post_meta( $post_id, '_bsd_spscwt_product_type' );
                delete_post_meta( $post_id, '_stripe_connect_split_pay_transfer_percentage' );
                delete_post_meta( $post_id, '_bsd_spscwt_product_amount' );
            } else {
                update_post_meta( $post_id, '_bsd_spscwt_product_type', $_bsd_spscwt_product_type );
            }
            $transfer_percentage = apply_filters( 'spp_before_save_product_transfer_percentage', $transfer_percentage, $post_id );
            if ( $transfer_percentage === null ) {
                delete_post_meta( $post_id, '_stripe_connect_split_pay_transfer_percentage' );
            } else {
                update_post_meta( $post_id, '_stripe_connect_split_pay_transfer_percentage', $transfer_percentage );
            }
            $_bsd_spscwt_product_amount = apply_filters( 'spp_before_save_product_transfer_amount', $_bsd_spscwt_product_amount, $post_id );
            if ( empty( $_bsd_spscwt_product_amount ) ) {
                delete_post_meta( $post_id, '_bsd_spscwt_product_amount' );
            } else {
                update_post_meta( $post_id, '_bsd_spscwt_product_amount', $_bsd_spscwt_product_amount );
            }
            $_bsd_spscwt_shipping_type = apply_filters( 'spp_before_save_product_shipping_transfer_type', $_bsd_spscwt_shipping_type, $post_id );
            /* Shipping */
            if ( empty( $_bsd_spscwt_shipping_type ) ) {
                delete_post_meta( $post_id, '_bsd_spscwt_shipping_type' );
                delete_post_meta( $post_id, '_bsd_prod_shipping_percentage' );
                delete_post_meta( $post_id, '_bsd_spscwt_shipping_amount' );
            } else {
                update_post_meta( $post_id, '_bsd_spscwt_shipping_type', $_bsd_spscwt_shipping_type );
            }
            $transfer_shipping_percentage = apply_filters( 'spp_before_save_product_shipping_transfer_percentage', $transfer_shipping_percentage, $post_id );
            if ( $transfer_shipping_percentage === null ) {
                delete_post_meta( $post_id, '_bsd_prod_shipping_percentage' );
            } else {
                update_post_meta( $post_id, '_bsd_prod_shipping_percentage', $transfer_shipping_percentage );
            }
            $_bsd_spscwt_shipping_amount = apply_filters( 'spp_before_save_product_shipping_transfer_amount', $_bsd_spscwt_shipping_amount, $post_id );
            if ( empty( $_bsd_spscwt_shipping_amount ) ) {
                delete_post_meta( $post_id, '_bsd_spscwt_shipping_amount' );
            } else {
                update_post_meta( $post_id, '_bsd_spscwt_shipping_amount', $_bsd_spscwt_shipping_amount );
            }
        }

        /***************************************
         * BEGIN Modified WooCommerce Functions
         ***************************************/
        /**
         * Check incoming requests for Stripe Webhook data and process them.
         * WooCommerce version 4.0.0
         *
         * @version 2.0.0
         */
        public function check_for_webhook() {
            if ( 'POST' !== $_SERVER['REQUEST_METHOD'] || !isset( $_GET['wc-api'] ) || 'wc_stripe' !== $_GET['wc-api'] ) {
                return;
            }
            $wc_stripe_webhook_handler = new \WC_Stripe_Webhook_Handler();
            // BSD Instantiate WC Stripe class
            $request_body = file_get_contents( 'php://input' );
            $request_headers = array_change_key_case( $wc_stripe_webhook_handler->get_request_headers(), CASE_UPPER );
            // New function call:
            // 3.7.5 (sc-ACCT-DEAUTH): account-lifecycle events
            // (account.application.{authorized,deauthorized}) don't carry
            // an order source_id; they refer to the platform's connected
            // account. Skip the for-this-site check for those — signature
            // verification already proves they're from our Stripe app.
            $preflight_event_type = $this->get_event_type( $request_body );
            $is_account_lifecycle = in_array( $preflight_event_type, \SplitPay\Integrations\WooCommerce\AccountLifecycleHandler::handledEventTypes(), true );
            if ( !$is_account_lifecycle && !$this->webhook_for_this_site( $request_body ) ) {
                status_header( 200 );
                exit;
            }
            // Validate it to make sure it is legit.
            if ( $this->is_valid_request( $request_headers, $request_body ) ) {
                // 3.7.5 (sc-DUP-XFER companion): dedupe duplicate Stripe deliveries of
                // the SAME event. Stripe retries an event (same event.id) on any
                // non-2xx or timeout, and at-least-once delivery means even a 200 can
                // be re-sent. Without this, a redelivered payment_intent.succeeded ran
                // transfer_controller a second time. We record each processed event.id
                // for 24h and short-circuit a repeat with a 200 (so Stripe stops
                // retrying). The per-order lock + idempotent keys are the money-safety
                // backstops; this avoids the wasted reprocessing and any window where
                // they don't fully overlap. Signature verification already passed, so
                // the event.id is trustworthy.
                $spp_event_id = $this->get_event_id( $request_body );
                if ( $spp_event_id !== '' ) {
                    $spp_dedupe_key = 'spp_evt_' . md5( $spp_event_id );
                    if ( false !== get_transient( $spp_dedupe_key ) ) {
                        $this->safe_wcs_log( $this->log_prefix . ': duplicate Stripe event ' . $spp_event_id . ' already processed — skipping (idempotent webhook dedup).' );
                        status_header( 200 );
                        exit;
                    }
                    $spp_dedupe_ttl = ( defined( 'DAY_IN_SECONDS' ) ? DAY_IN_SECONDS : 86400 );
                    set_transient( $spp_dedupe_key, time(), $spp_dedupe_ttl );
                }
                $wc_stripe_webhook_handler->process_webhook( $request_body );
                $this->safe_wcs_log( $this->log_prefix . ': after process webhooks ' . wp_json_encode( $request_body ) );
                // 3.7.5 payments-grade hardening (2026-05-24): route dispute
                // events to the dedicated DisputeHandler. For every other event
                // (charge.succeeded, payment_intent.succeeded, source.chargeable),
                // transfer_controller handles vendor payouts as before.
                $event_type = $this->get_event_type( $request_body );
                if ( in_array( $event_type, \SplitPay\Integrations\WooCommerce\DisputeHandler::handledEventTypes(), true ) ) {
                    $decoded = json_decode( $request_body );
                    $result = \SplitPay\Integrations\WooCommerce\DisputeHandler::handle( $event_type, $decoded );
                    $this->safe_wcs_log( $this->log_prefix . ': dispute event ' . $event_type . ' result ' . wp_json_encode( $result ) );
                } elseif ( in_array( $event_type, \SplitPay\Integrations\WooCommerce\ChargeFailedHandler::handledEventTypes(), true ) ) {
                    // 3.7.5 (sc-ASYNC-FAIL): an async payment (ACH/SEPA/Bacs) used as
                    // the transfer's source_transaction failed AFTER the vendor was
                    // already paid from the platform balance. Stripe does NOT
                    // auto-reverse those transfers for separate-charges-and-transfers,
                    // so reverse them here to recover the platform's funds. Idempotent
                    // (deterministic spp_rev_ keys + event-id meta marker).
                    $decoded = json_decode( $request_body );
                    $result = \SplitPay\Integrations\WooCommerce\ChargeFailedHandler::handle( $event_type, $decoded );
                    $this->safe_wcs_log( $this->log_prefix . ': async-failure event ' . $event_type . ' result ' . wp_json_encode( $result ) );
                } elseif ( in_array( $event_type, \SplitPay\Integrations\WooCommerce\AccountLifecycleHandler::handledEventTypes(), true ) ) {
                    // 3.7.5 (sc-ACCT-DEAUTH): account.application.authorized /
                    // .deauthorized → mark/unmark in the deauthorized-accounts
                    // option so TransferEngine skips revoked destinations.
                    $decoded = json_decode( $request_body );
                    $result = \SplitPay\Integrations\WooCommerce\AccountLifecycleHandler::handle( $event_type, $decoded );
                    $this->safe_wcs_log( $this->log_prefix . ': account-lifecycle event ' . $event_type . ' result ' . wp_json_encode( $result ) );
                } else {
                    $this->transfer_controller( $request_body );
                }
                status_header( 200 );
                exit;
            } else {
                $this->safe_wcs_log( 'Incoming webhook failed validation: ' . wp_json_encode( $request_body ) );
                status_header( 400 );
                exit;
            }
        }

        /**
         * Verify the incoming webhook notification to make sure it is legit.
         *
         * @since   4.0.0
         * WooCommerce @param string $request_headers The request headers from Stripe.
         *
         * @param string $request_body The request body from Stripe.
         *
         * @return bool
         *
         * @version 4.0.0
         * @version 1.0.0
         */
        public function is_valid_request( $request_headers = null, $request_body = null ) {
            if ( null === $request_headers || null === $request_body ) {
                return false;
            }
            if ( !empty( $request_headers['USER-AGENT'] ) && !preg_match( '/Stripe/', $request_headers['USER-AGENT'] ) ) {
                return false;
            }
            // PT-fix-3.7.5 (security #17): legacy path mirror of WebhookHandler::isValidRequest.
            // MUST reject when secret is unset — never short-circuit to "accept anything".
            if ( empty( $this->secret ) ) {
                $this->safe_wcs_log( $this->log_prefix . ': Webhook rejected: no webhook_secret configured. Configure it in WooCommerce → Stripe → Webhook secret to enable webhook processing. Endpoint will reject all events until then.' );
                return false;
            }
            if ( empty( $request_headers['STRIPE-SIGNATURE'] ) ) {
                return false;
            }
            try {
                \Stripe\Webhook::constructEvent( $request_body, $request_headers['STRIPE-SIGNATURE'], $this->secret );
            } catch ( \Stripe\Exception\SignatureVerificationException $e ) {
                $this->safe_wcs_log( $this->log_prefix . ': Webhook signature verification failed: ' . $e->getMessage() );
                return false;
            } catch ( \Exception $e ) {
                $this->safe_wcs_log( $this->log_prefix . ': Webhook verification exception: ' . $e->getMessage() );
                return false;
            }
            return true;
        }

        /***************************************
         * END Modified WooCommerce Functions
         ***************************************/
        private function calculate_transfer_amount( $order_id, $default_percentage, $data_keys ) {
            global $wpdb;
            $table_prefix = $wpdb->prefix;
            $table_name = $table_prefix . SPP_CONNECTED_ID_TABLE;
            $total_transfer_amount = 0;
            $order = wc_get_order( $order_id );
            $ordered_items = $order->get_items();
            /** tax starts */
            $tax = new \WC_Tax();
            $product_wise_rates = array();
            $tax_transfer_type = get_option( 'tax_transfer_type', false );
            /** tax ends */
            /* shipping */
            $shipping_total = $order->get_shipping_total();
            $global_shipping_amount = $shipping_total;
            $this->safe_wcs_log( $this->log_prefix . ': shipping_total ' . wp_json_encode( $shipping_total ) );
            $selected_shipping_method_id = '';
            foreach ( $order->get_shipping_methods() as $shipping_method ) {
                $selected_shipping_method_id = $shipping_method->get_method_id();
            }
            $this->safe_wcs_log( $this->log_prefix . ': selected_shipping_method_id ' . wp_json_encode( $selected_shipping_method_id ) );
            $shipping_data = array();
            foreach ( $this->bsd_get_all_shipping_zones() as $zone ) {
                $zone_shipping_methods = $zone->get_shipping_methods();
                foreach ( $zone_shipping_methods as $index => $method ) {
                    if ( $method->id == $selected_shipping_method_id ) {
                        $shipping_data[$index] = $method;
                    }
                }
            }
            $this->safe_wcs_log( $this->log_prefix . ': shipping_data ' . wp_json_encode( $shipping_data ) );
            $applied_coupon_arry = array();
            $fixed_cart_discounted_amount = 0;
            $fixed_cart_percentage_discounted_amount = 0;
            $this->safe_wcs_log( $this->log_prefix . ': get_coupons obj ' . wp_json_encode( $order->get_coupons() ) );
            foreach ( $order->get_coupons() as $coupon ) {
                $code = $coupon->get_code();
                $original_coupon_details = new \WC_Coupon($code);
                $product_ids = $original_coupon_details->get_product_ids();
                $discount_type = $original_coupon_details->get_discount_type();
                $coupon_amount = $original_coupon_details->get_amount();
                $order_discount = $coupon->get_discount();
                $applied_coupon_arry[] = array(
                    'code'            => $code,
                    'discount_type'   => $discount_type,
                    'discount'        => $order_discount,
                    'discount_amount' => $coupon_amount,
                    'product_ids'     => $product_ids,
                );
            }
            $this->safe_wcs_log( $this->log_prefix . ': applied_coupon_arry ' . wp_json_encode( $applied_coupon_arry ) );
            $coupon_adjust = get_option( 'coupon_adjust_transfers', '0' );
            if ( $coupon_adjust !== '1' ) {
                $applied_coupon_arry = array();
            }
            if ( !empty( $applied_coupon_arry ) ) {
                foreach ( $applied_coupon_arry as $acak ) {
                    if ( empty( $acak['product_ids'] ) && $acak['discount_type'] == 'fixed_cart' ) {
                        $fixed_cart_discounted_amount = $fixed_cart_discounted_amount + $acak['discount'];
                    } elseif ( empty( $acak['product_ids'] ) && $acak['discount_type'] == 'percent' ) {
                        $fixed_cart_percentage_discounted_amount = $acak['discount_amount'];
                    } elseif ( $acak['discount_type'] == 'fixed_product' ) {
                        // fixed_product discount is per-unit; handled per-product below, not aggregated globally.
                    }
                }
            }
            $this->safe_wcs_log( $this->log_prefix . ': fixed_cart_discounted_amount ' . wp_json_encode( $fixed_cart_discounted_amount ) );
            $customer_id = $order->get_customer_id();
            $customer = null;
            try {
                $customer = new \WC_Customer($customer_id);
            } catch ( \Throwable $e ) {
                $this->safe_wcs_log( $this->log_prefix . ': Could not instantiate WC_Customer (admin context): ' . $e->getMessage() );
            }
            $data_array = array();
            /** tax starts */
            $all_taxes_array = array();
            foreach ( $order->get_items( 'tax' ) as $tx_item_id => $tx_item ) {
                $tax_rate_id = $tx_item->get_rate_id();
                // Tax rate ID
                $all_taxes_array[$tax_rate_id]['tax_total'] = $tx_item->get_tax_total();
                $all_taxes_array[$tax_rate_id]['tax_ship_total'] = $tx_item->get_shipping_tax_total();
            }
            /** tax ends */
            $this->safe_wcs_log( $this->log_prefix . ': all_taxes_array ' . wp_json_encode( $all_taxes_array ) );
            $product_wise_taxes = array();
            foreach ( $ordered_items as $order_item_id => $item ) {
                if ( function_exists( 'wc_pb_is_bundled_order_item' ) ) {
                    $is_bundle = wc_pb_is_bundled_order_item( $item );
                    if ( $is_bundle ) {
                        continue;
                    }
                }
                $product = $item->get_product();
                $get_taxes = $item->get_taxes();
                $this->safe_wcs_log( $this->log_prefix . ': get_taxes ' . wp_json_encode( $get_taxes ) );
                $tax_subtotal = ( is_array( $get_taxes ) && isset( $get_taxes['subtotal'] ) && is_array( $get_taxes['subtotal'] ) ? $get_taxes['subtotal'] : array() );
                foreach ( $tax_subtotal as $rt_id => $rt_tax ) {
                    $product_wise_taxes[$product->get_id()][] = $rt_tax;
                }
                $this->safe_wcs_log( $this->log_prefix . ': product_wise_taxes ' . wp_json_encode( $product_wise_taxes ) );
                /** tax starts */
                $taxes = array();
                try {
                    if ( $customer !== null ) {
                        $taxes = $tax->get_rates( $item->get_tax_class(), $customer );
                    }
                } catch ( \Throwable $e ) {
                    $this->safe_wcs_log( $this->log_prefix . ': Tax rate lookup failed (likely admin context): ' . $e->getMessage() );
                }
                $this->safe_wcs_log( $this->log_prefix . ': get_tax_class ' . wp_json_encode( $item->get_tax_class() ) );
                foreach ( $taxes as $txk => $txv ) {
                    $product_wise_rates[$product->get_id()]['tax_rate_id'] = $txk;
                }
                /** tax ends */
                $this->safe_wcs_log( $this->log_prefix . ': product_wise_rates ' . wp_json_encode( $product_wise_rates ) );
                $shipping_class_id = '';
                $variation_id = $product_wise_shipping_cost = 0;
                $product_id = $item->get_product_id();
                if ( $product->is_type( 'variation' ) ) {
                    $variation_id = $product->get_id();
                    $product_id = $product->get_id();
                }
                $quantity = $item->get_quantity();
                /*
                 * 3.7.3 fix (Carlos Lozano / sc-7170 / Name Your Price compatibility):
                 * Use the order line item subtotal as the source of truth, not
                 * $product->get_price(). The product's get_price() returns the BASE
                 * default price ($1 for WPC Name Your Price products), not what the
                 * customer actually paid. Percentage transfers were computed against
                 * the $1 base instead of the customer-chosen price, so 80% of a
                 * $100 chosen-price order moved only $0.80 instead of $80.
                 * Mirrors the same fix in Core\WCOrderAdapter::getItems().
                 */
                $line_subtotal = (float) $item->get_subtotal();
                $product_price = ( $quantity > 0 ? $line_subtotal / $quantity : (float) $product->get_price() );
                /* shipping */
                $shipping_class_id = $product->get_shipping_class_id();
                $this->safe_wcs_log( $this->log_prefix . ': shipping_class_id ' . wp_json_encode( $shipping_class_id ) );
                if ( isset( $shipping_class_id ) && !empty( $shipping_class_id ) ) {
                    foreach ( $shipping_data as $data ) {
                        if ( isset( $data->instance_settings['class_cost_' . $shipping_class_id] ) ) {
                            $class_cost = $data->instance_settings['class_cost_' . $shipping_class_id];
                            $class_cost_type = $data->instance_settings['type'];
                            $this->safe_wcs_log( $this->log_prefix . ': class_cost ' . wp_json_encode( $class_cost ) );
                            $this->safe_wcs_log( $this->log_prefix . ': class_cost_type ' . wp_json_encode( $class_cost_type ) );
                            if ( $class_cost_type == 'class' ) {
                                $qty_post = strpos( $class_cost, '[qty]' );
                                $fee_post = strpos( $class_cost, '[fee' );
                                if ( $qty_post !== false ) {
                                    $rate = substr( $class_cost, 0, 2 );
                                    $product_wise_shipping_cost = $rate * $quantity;
                                } elseif ( $fee_post !== false ) {
                                    add_shortcode( 'fee', array($this, 'fee') );
                                    $product_price = $product_price * $quantity;
                                    $rate = do_shortcode( str_replace( ']', ' product_price="' . $product_price . '" ]', $class_cost ) );
                                    remove_shortcode( 'fee', array($this, 'fee') );
                                    $product_wise_shipping_cost = $rate;
                                } elseif ( ctype_digit( $class_cost ) ) {
                                    $product_wise_shipping_cost = $class_cost;
                                }
                                $product_wise_shipping_cost = $product_wise_shipping_cost;
                            }
                        }
                    }
                }
                // WC_Order does not have get_item_shipping_amount() in WooCommerce core; use it only if provided by a custom implementation.
                if ( method_exists( $order, 'get_item_shipping_amount' ) ) {
                    $product_wise_shipping_cost = $order->get_item_shipping_amount( $item );
                }
                $this->safe_wcs_log( $this->log_prefix . ': product_wise_shipping_cost ' . wp_json_encode( $product_wise_shipping_cost ) );
                $data_array[$order_item_id]['product_id'] = $product_id;
                $data_array[$order_item_id]['single_product_original_price'] = $product_price;
                $data_array[$order_item_id]['product_quantity'] = $quantity;
                $data_array[$order_item_id]['global_tax'] = 0;
                /* shipping */
                $data_array[$order_item_id]['product_shipping_cost'] = $product_wise_shipping_cost;
                $data_array[$order_item_id]['product_original_shipping_cost'] = $product_wise_shipping_cost;
                $global_shipping_amount = $global_shipping_amount - $product_wise_shipping_cost;
                $product_discount = 0;
                if ( !empty( $applied_coupon_arry ) ) {
                    foreach ( $applied_coupon_arry as $acak ) {
                        if ( !empty( $acak['product_ids'] ) && in_array( $product_id, $acak['product_ids'] ) ) {
                            $product_discount = $acak['discount'];
                            break;
                        }
                        if ( !empty( $acak['product_ids'] ) && in_array( $variation_id, $acak['product_ids'] ) ) {
                            $product_discount = $acak['discount'];
                            break;
                        }
                    }
                }
                $data_array[$order_item_id]['product_discount'] = $product_discount;
                $data_array[$order_item_id]['product_price_wo_qty'] = $product_price;
                $product_price = $product_price * $quantity;
                $data_array[$order_item_id]['product_price_x_qty'] = $product_price;
                $data_array[$order_item_id]['product_discounted_price_x_qty'] = $product_price - $product_discount;
                if ( $product->is_type( 'simple' ) ) {
                    $_bsd_spscwt_product_connected_account = get_post_meta( $product_id, '_bsd_spscwt_product_connected_account', true );
                    $_bsd_spscwt_product_type = get_post_meta( $product_id, '_bsd_spscwt_product_type', true );
                    $product_transfer_percentage = get_post_meta( $product_id, '_stripe_connect_split_pay_transfer_percentage', true );
                    $_bsd_spscwt_product_amount = get_post_meta( $product_id, '_bsd_spscwt_product_amount', true );
                    /* shipping */
                    $_bsd_spscwt_shipping_type = get_post_meta( $product_id, '_bsd_spscwt_shipping_type', true );
                    $transfer_shipping_percentage = get_post_meta( $product_id, '_bsd_prod_shipping_percentage', true );
                    $_bsd_spscwt_shipping_amount = get_post_meta( $product_id, '_bsd_spscwt_shipping_amount', true );
                } elseif ( $product->is_type( 'variation' ) || $product->is_type( 'subscription_variation' ) ) {
                    $variation_id = $product->get_id();
                    $_bsd_spscwt_product_connected_account = get_post_meta( $variation_id, '_bsd_spscwt_product_connected_account', true );
                    $_bsd_spscwt_product_type = get_post_meta( $variation_id, '_bsd_spscwt_product_type', true );
                    $product_transfer_percentage = get_post_meta( $variation_id, '_stripe_connect_split_pay_transfer_percentage', true );
                    $_bsd_spscwt_product_amount = get_post_meta( $variation_id, '_bsd_spscwt_product_amount', true );
                    $this->safe_wcs_log( $this->log_prefix . ': variable product id ' . wp_json_encode( $variation_id ) );
                    /* shipping */
                    $_bsd_spscwt_shipping_type = get_post_meta( $variation_id, '_bsd_spscwt_shipping_type', true );
                    $transfer_shipping_percentage = get_post_meta( $variation_id, '_bsd_prod_shipping_percentage', true );
                    $_bsd_spscwt_shipping_amount = get_post_meta( $variation_id, '_bsd_prod_shipping_amount', true );
                } else {
                    $_bsd_spscwt_product_connected_account = get_post_meta( $product_id, '_bsd_spscwt_product_connected_account', true );
                    $_bsd_spscwt_product_type = get_post_meta( $product_id, '_bsd_spscwt_product_type', true );
                    $product_transfer_percentage = get_post_meta( $product_id, '_stripe_connect_split_pay_transfer_percentage', true );
                    $_bsd_spscwt_product_amount = get_post_meta( $product_id, '_bsd_spscwt_product_amount', true );
                    /* shipping */
                    $_bsd_spscwt_shipping_type = get_post_meta( $product_id, '_bsd_spscwt_shipping_type', true );
                    $transfer_shipping_percentage = get_post_meta( $product_id, '_bsd_prod_shipping_percentage', true );
                    $_bsd_spscwt_shipping_amount = get_post_meta( $product_id, '_bsd_spscwt_shipping_amount', true );
                }
                $data_array[$order_item_id]['product_type'] = $product->get_type();
                if ( !$product_price ) {
                    continue;
                }
                if ( empty( $_bsd_spscwt_product_connected_account ) ) {
                    $data_array[$order_item_id]['transfer_level'] = 'global';
                    if ( isset( $product_wise_taxes[$product_id][0] ) ) {
                        $data_array[$order_item_id]['global_tax'] = $data_array[$order_item_id]['global_tax'] + $product_wise_taxes[$product_id][0];
                        /** tax starts */
                    }
                } else {
                    $data_array[$order_item_id]['transfer_level'] = 'product';
                    // if($data_array[$product_id]["product_type"] == "simple"){
                    $data_array[$order_item_id]['transfer_accounts'] = $_bsd_spscwt_product_connected_account;
                    $data_array[$order_item_id]['transfer_type'] = $_bsd_spscwt_product_type;
                    $data_array[$order_item_id]['transfer_percentage'] = $product_transfer_percentage;
                    $data_array[$order_item_id]['transfer_amount'] = $_bsd_spscwt_product_amount;
                    /* shipping */
                    $data_array[$order_item_id]['transfer_shipping_type'] = $_bsd_spscwt_shipping_type;
                    $data_array[$order_item_id]['transfer_shipping_percentage'] = $transfer_shipping_percentage;
                    $data_array[$order_item_id]['transfer_shipping_amount'] = $_bsd_spscwt_shipping_amount;
                    $data_array[$order_item_id]['product_tax'] = $product_wise_taxes[$product_id] ?? array();
                    /** tax starts */
                }
            }
            $this->safe_wcs_log( $this->log_prefix . ': data_array before calculation ' . wp_json_encode( $data_array ) );
            $total_global_transfer_amount = 0;
            $global_product_discounted_price_x_qty_total = 0;
            $global_product_price_x_qty = 0;
            $product_discounted_price_x_qty_total = 0;
            $global_product_qty_total = 0;
            $store_acc_wise_array = array();
            $store_acc_wise_shipping_array = array();
            $global_tax = 0;
            if ( !empty( $data_array ) ) {
                foreach ( $data_array as $dak => $dav ) {
                    if ( $dav['transfer_level'] == 'global' ) {
                        if ( !empty( $fixed_cart_percentage_discounted_amount ) ) {
                            $fcpdam = $fixed_cart_percentage_discounted_amount / 100;
                            $data_array[$dak]['fxd_crt_prcntg_dscunt_amt'] = $dav['product_price_x_qty'] * $fcpdam;
                            $data_array[$dak]['product_discounted_price_x_qty'] = $dav['product_discounted_price_x_qty'] - $data_array[$dak]['fxd_crt_prcntg_dscunt_amt'];
                            $global_product_discounted_price_x_qty_total += $data_array[$dak]['product_discounted_price_x_qty'];
                        } else {
                            $global_product_discounted_price_x_qty_total += $dav['product_discounted_price_x_qty'];
                        }
                        $global_product_price_x_qty += $dav['product_price_x_qty'];
                        $global_product_qty_total += $dav['product_quantity'];
                        // shipping
                        $global_shipping_amount = $global_shipping_amount + $data_array[$dak]['product_shipping_cost'];
                        /** tax start */
                        if ( !empty( $data_array[$dak]['global_tax'] ) ) {
                            $this->safe_wcs_log( $this->log_prefix . ': data_array global_tax ' . wp_json_encode( $data_array[$dak]['global_tax'] ) );
                            $global_tax = $global_tax + $data_array[$dak]['global_tax'];
                        }
                        $data_array['global_tax_total'] = $global_tax;
                        /** tax end */
                    } else {
                        if ( !empty( $fixed_cart_percentage_discounted_amount ) ) {
                            $fcpdam = $fixed_cart_percentage_discounted_amount / 100;
                            $data_array[$dak]['fxd_crt_prcntg_dscunt_amt'] = $dav['product_price_x_qty'] * $fcpdam;
                            $data_array[$dak]['product_discounted_price_x_qty'] = $dav['product_discounted_price_x_qty'] - $data_array[$dak]['fxd_crt_prcntg_dscunt_amt'];
                            $dav['product_discounted_price_x_qty'] = $data_array[$dak]['product_discounted_price_x_qty'];
                        }
                        /** tax start */
                        $tax = 0;
                        if ( !empty( $data_array[$dak]['product_tax'] ) ) {
                            $this->safe_wcs_log( $this->log_prefix . ': data_array product_tax ' . wp_json_encode( $data_array[$dak]['product_tax'] ) );
                            foreach ( $data_array[$dak]['product_tax'] as $gtk ) {
                                $tax = $tax + $gtk;
                            }
                        }
                        $data_array[$dak]['tax_total'] = $tax;
                        /** tax end */
                        // @phpstan-ignore-next-line — defensive: 3rd-party filters on $data_array may strip 'transfer_accounts' even when transfer_level=='product'.
                        if ( isset( $dav['transfer_accounts'] ) && !empty( $dav['transfer_accounts'] ) ) {
                            foreach ( $dav['transfer_accounts'] as $dtak => $dtav ) {
                                $account_wise_tax = 0;
                                if ( isset( $dav['transfer_type'][$dtak] ) ) {
                                    if ( $dav['transfer_type'][$dtak] == 'percentage' ) {
                                        $percentage_amount = $dav['transfer_percentage'][$dtak] / 100;
                                        $product_discounted_price_x_qty_total = $dav['product_discounted_price_x_qty'] * $percentage_amount;
                                        /** tax start */
                                        if ( $tax_transfer_type == 'partial' ) {
                                            $account_wise_tax = $data_array[$dak]['tax_total'] * $percentage_amount;
                                        }
                                        /** tax end */
                                        $data_array[$dak]['transfer_amount_account_wise'][$dtak] = array(
                                            'product_id'                           => $dav['product_id'],
                                            'connected_acc_id'                     => $dtav,
                                            'product_discounted_price_x_qty'       => $dav['product_discounted_price_x_qty'],
                                            'product_discounted_price_x_qty_total' => $product_discounted_price_x_qty_total,
                                            'transfer_type'                        => $dav['transfer_type'][$dtak],
                                            'transfer_percentage_or_amount'        => $dav['transfer_percentage'][$dtak],
                                            'product_type'                         => $dav['product_type'],
                                            'account_wise_tax'                     => $account_wise_tax,
                                            'tax_total'                            => $data_array[$dak]['tax_total'],
                                        );
                                        // $dav["product_discounted_price_x_qty"] = $dav["product_discounted_price_x_qty"] - $product_discounted_price_x_qty_total;
                                    } elseif ( $dav['transfer_type'][$dtak] == 'amount' ) {
                                        // $dav["product_discounted_price_x_qty"] = 0; // case-1 product amount is 0;
                                        // $dav["transfer_amount"][$dtak] = 100; // case-2 product amount is left to less transfer amount
                                        if ( $dav['product_discounted_price_x_qty'] > 0 ) {
                                            $transfer_amount_x_qty = $dav['transfer_amount'][$dtak] * $dav['product_quantity'];
                                            if ( $transfer_amount_x_qty > $dav['product_discounted_price_x_qty'] ) {
                                                $product_discounted_price_x_qty_total = $dav['product_discounted_price_x_qty'];
                                            } else {
                                                $product_discounted_price_x_qty_total = $transfer_amount_x_qty;
                                            }
                                            /** tax start */
                                            if ( $tax_transfer_type == 'partial' ) {
                                                $account_wise_tax = $dav['transfer_amount'][$dtak] / $dav['product_price_wo_qty'] * $data_array[$dak]['tax_total'];
                                            }
                                            /** tax end */
                                            $data_array[$dak]['transfer_amount_account_wise'][$dtak] = array(
                                                'product_id'                           => $dav['product_id'],
                                                'connected_acc_id'                     => $dtav,
                                                'product_discounted_price_x_qty'       => $dav['product_discounted_price_x_qty'],
                                                'product_discounted_price_x_qty_total' => $product_discounted_price_x_qty_total,
                                                'transfer_type'                        => $dav['transfer_type'][$dtak],
                                                'transfer_percentage_or_amount'        => $transfer_amount_x_qty,
                                                'product_type'                         => $dav['product_type'],
                                                'account_wise_tax'                     => $account_wise_tax,
                                                'tax_total'                            => $data_array[$dak]['tax_total'],
                                            );
                                        }
                                        // $dav["product_discounted_price_x_qty"] = $dav["product_discounted_price_x_qty"] - $product_discounted_price_x_qty_total;
                                    }
                                }
                                /* shipping */
                                if ( isset( $dav['transfer_shipping_type'][$dtak] ) && $data_array[$dak]['product_shipping_cost'] > 0 ) {
                                    if ( $dav['transfer_shipping_type'][$dtak] == 'percentage' && !empty( $dav['transfer_shipping_percentage'][$dtak] ) ) {
                                        $percentage_shipping_amount = $dav['transfer_shipping_percentage'][$dtak] / 100;
                                        $transfer_product_shipping_cost = $percentage_shipping_amount * $data_array[$dak]['product_original_shipping_cost'];
                                        if ( !empty( $transfer_product_shipping_cost ) && $transfer_product_shipping_cost <= $data_array[$dak]['product_shipping_cost'] ) {
                                            $data_array[$dak]['transfer_shipping_amount_account_wise'][$dtak] = array(
                                                'product_id'                     => $dav['product_id'],
                                                'connected_acc_id'               => $dtav,
                                                'product_original_shipping_cost' => $data_array[$dak]['product_original_shipping_cost'],
                                                'transfer_type'                  => $dav['transfer_shipping_type'][$dtak],
                                                'transfer_percentage_or_amount'  => $dav['transfer_shipping_percentage'][$dtak],
                                                'transfer_calculate_amount'      => (float) number_format(
                                                    $transfer_product_shipping_cost,
                                                    2,
                                                    '.',
                                                    ''
                                                ),
                                            );
                                        } elseif ( !empty( $transfer_product_shipping_cost ) && $transfer_product_shipping_cost > $data_array[$dak]['product_shipping_cost'] ) {
                                            $transfer_product_shipping_cost = $data_array[$dak]['product_shipping_cost'];
                                            $data_array[$dak]['transfer_shipping_amount_account_wise'][$dtak] = array(
                                                'product_id'                     => $dav['product_id'],
                                                'connected_acc_id'               => $dtav,
                                                'product_original_shipping_cost' => $data_array[$dak]['product_original_shipping_cost'],
                                                'transfer_type'                  => $dav['transfer_shipping_type'][$dtak],
                                                'transfer_percentage_or_amount'  => $dav['transfer_shipping_percentage'][$dtak],
                                                'transfer_calculate_amount'      => $transfer_product_shipping_cost,
                                            );
                                        }
                                        $data_array[$dak]['product_shipping_cost'] = $data_array[$dak]['product_shipping_cost'] - $transfer_product_shipping_cost;
                                    } elseif ( $dav['transfer_shipping_type'][$dtak] == 'amount' ) {
                                        if ( isset( $dav['transfer_shipping_amount'][$dtak] ) ) {
                                            $transfer_product_shipping_cost = $dav['transfer_shipping_amount'][$dtak];
                                            if ( !empty( $transfer_product_shipping_cost ) && $transfer_product_shipping_cost < $data_array[$dak]['product_shipping_cost'] ) {
                                                $data_array[$dak]['transfer_shipping_amount_account_wise'][$dtak] = array(
                                                    'product_id'                     => $dav['product_id'],
                                                    'connected_acc_id'               => $dtav,
                                                    'product_original_shipping_cost' => $data_array[$dak]['product_original_shipping_cost'],
                                                    'transfer_type'                  => $dav['transfer_shipping_type'][$dtak],
                                                    'transfer_percentage_or_amount'  => $dav['transfer_shipping_amount'][$dtak],
                                                    'transfer_calculate_amount'      => $transfer_product_shipping_cost,
                                                );
                                            } elseif ( !empty( $transfer_product_shipping_cost ) && $transfer_product_shipping_cost > $data_array[$dak]['product_shipping_cost'] ) {
                                                $transfer_product_shipping_cost = $data_array[$dak]['product_shipping_cost'];
                                                $data_array[$dak]['transfer_shipping_amount_account_wise'][$dtak] = array(
                                                    'product_id'                     => $dav['product_id'],
                                                    'connected_acc_id'               => $dtav,
                                                    'product_original_shipping_cost' => $data_array[$dak]['product_original_shipping_cost'],
                                                    'transfer_type'                  => $dav['transfer_shipping_type'][$dtak],
                                                    'transfer_percentage_or_amount'  => $dav['transfer_shipping_amount'][$dtak],
                                                    'transfer_calculate_amount'      => $transfer_product_shipping_cost,
                                                );
                                            }
                                            $data_array[$dak]['product_shipping_cost'] = $data_array[$dak]['product_shipping_cost'] - $transfer_product_shipping_cost;
                                        }
                                    }
                                }
                            }
                            $store_acc_wise_array[$dak] = $data_array[$dak]['transfer_amount_account_wise'];
                            if ( $tax_transfer_type == 'all' ) {
                                $total_transfer_amount_per_product = 0;
                                foreach ( $store_acc_wise_array[$dak] as $sawadpik ) {
                                    $total_transfer_amount_per_product = $total_transfer_amount_per_product + $sawadpik['product_discounted_price_x_qty_total'];
                                    $this->safe_wcs_log( $this->log_prefix . ': sawadpik ' . wp_json_encode( $sawadpik ) );
                                }
                                $this->safe_wcs_log( $this->log_prefix . ': total_transfer_amount_per_product ' . wp_json_encode( $total_transfer_amount_per_product ) );
                                foreach ( $store_acc_wise_array[$dak] as $sawadpik => $sawadpiv ) {
                                    $partial_transfer_percentage = $sawadpiv['product_discounted_price_x_qty_total'] / $total_transfer_amount_per_product * 100;
                                    $divided_amount = $sawadpiv['tax_total'] / 100;
                                    $account_wise_tax = $divided_amount * $partial_transfer_percentage;
                                    $store_acc_wise_array[$dak][$sawadpik]['partial_transfer_percentage'] = $partial_transfer_percentage;
                                    $store_acc_wise_array[$dak][$sawadpik]['account_wise_tax'] = $account_wise_tax;
                                }
                            }
                            $this->safe_wcs_log( $this->log_prefix . ': transfer_amount_account_wise ' . wp_json_encode( $store_acc_wise_array[$dak] ) );
                            // shipping
                            // $global_shipping_amount = $global_shipping_amount + $data_array[$dak]["product_shipping_cost"];
                            $store_acc_wise_shipping_array[$dak] = ( isset( $data_array[$dak]['transfer_shipping_amount_account_wise'] ) ? $data_array[$dak]['transfer_shipping_amount_account_wise'] : array() );
                        }
                    }
                }
            }
            $this->safe_wcs_log( $this->log_prefix . ': data_array after calculation ' . wp_json_encode( $data_array ) );
            $this->safe_wcs_log( $this->log_prefix . ': global_product_discounted_price_x_qty_total ' . wp_json_encode( $global_product_discounted_price_x_qty_total ) );
            if ( !empty( $fixed_cart_discounted_amount ) ) {
                $total_global_transfer_amount = $global_product_discounted_price_x_qty_total - $fixed_cart_discounted_amount;
                $this->safe_wcs_log( $this->log_prefix . ': fixed_cart_discounted_amount ' . wp_json_encode( $fixed_cart_discounted_amount ) );
            } else {
                $total_global_transfer_amount = $global_product_discounted_price_x_qty_total;
            }
            $this->safe_wcs_log( $this->log_prefix . ': total_global_transfer_amount ' . wp_json_encode( $total_global_transfer_amount ) );
            $this->safe_wcs_log( $this->log_prefix . ': data_keys["bsd_spscwt_type"] ' . wp_json_encode( $data_keys['bsd_spscwt_type'] ) );
            $this->safe_wcs_log( $this->log_prefix . ': default_percentage ' . wp_json_encode( $default_percentage ) );
            $total_transfer_amount = $total_global_transfer_amount;
            $this->safe_wcs_log( $this->log_prefix . ': total_transfer_amount before subtotal ' . wp_json_encode( $total_transfer_amount ) );
            $subtotal = $order->get_subtotal();
            if ( $total_transfer_amount > $subtotal ) {
                $total_transfer_amount = $subtotal;
            }
            $this->safe_wcs_log( $this->log_prefix . ': total_transfer_amount after subtotal ' . wp_json_encode( $total_transfer_amount ) );
            $this->safe_wcs_log( $this->log_prefix . ': store_acc_wise_array after subtotal ' . wp_json_encode( $store_acc_wise_array ) );
            $this->safe_wcs_log( $this->log_prefix . ': global_shipping_amount ' . wp_json_encode( $global_shipping_amount ) );
            $this->safe_wcs_log( $this->log_prefix . ': store_acc_wise_shipping_array ' . wp_json_encode( $store_acc_wise_shipping_array ) );
            $data = array();
            $data['total_global_transfer_amount'] = $total_transfer_amount;
            $data['total_product_transfer_amount'] = $store_acc_wise_array;
            $data['total_transfer_global_shipping_amount'] = $global_shipping_amount;
            $data['total_transfer_product_shipping_amount'] = $store_acc_wise_shipping_array;
            $data['all_taxes_array'] = $all_taxes_array;
            /** tax start */
            $data['data_array'] = $data_array;
            return $data;
        }

        /**
         * Get event meta data (payment_intent.succeeded)
         */
        private function get_event_meta( $request_body ) {
            $data = null;
            $event = json_decode( $request_body );
            $charge_description = '';
            $total_amount = '';
            $source_charge_id = '';
            $source_transaction = '';
            $wc_order_id = '';
            try {
                if ( $event->object == 'event' ) {
                    if ( $event->data->object->id ) {
                        $event = $this->get_payment_intent_object( $event->data->object->id );
                    }
                }
                $this->safe_wcs_log( $this->log_prefix . ': event_data ' . wp_json_encode( $event ) );
                if ( $event->object == 'payment_intent' ) {
                    $charge_created = $event->created;
                    // Intentionally date() (server timezone), not gmdate(): this value is stored as charge_date in the transfer-log ledger; switching to UTC would retroactively shift recorded financial timestamps. Behavior-preserving by design.
                    $charge_created = date( 'Y-m-d H:i:s', $charge_created );
                    // phpcs:ignore WordPress.DateTime.RestrictedFunctions.date_date -- preserves existing local-time charge_date semantics in the money ledger; changing to gmdate() would alter stored values.
                    if ( $event->amount ) {
                        $order_amount = $event->amount;
                        $order_amount = $order_amount / 100;
                    } else {
                        $this->safe_wcs_log( $this->log_prefix . ': get_event_meta amount not found ' );
                        return null;
                    }
                    $charge_description = $event->description;
                    $total_amount = $event->amount;
                    $source_charge_id = $event->latest_charge;
                    $source_transaction = $event->source;
                    $wc_order_id = $event->metadata->order_id;
                } else {
                    $this->safe_wcs_log( $this->log_prefix . ': get_event_meta unsupported event object type: ' . $event->object );
                    return null;
                }
                if ( $event->livemode ) {
                    $stripe_mode = 'live';
                } else {
                    $stripe_mode = 'test';
                }
                $data = array(
                    'charge_amount'      => $order_amount,
                    'charge_created'     => $charge_created,
                    'charge_description' => $charge_description,
                    'total_amount'       => $total_amount,
                    'source_charge_id'   => $source_charge_id,
                    'source_transaction' => $source_transaction,
                    'stripe_mode'        => $stripe_mode,
                    'wc_order_id'        => $wc_order_id,
                );
            } catch ( Exception $e ) {
                $this->safe_wcs_log( $this->log_prefix . ': Exception in get_event_meta ' . wp_json_encode( $e ) );
            }
            return $data;
        }

        private function get_payment_intent_object( $id ) {
            $data_keys = $this->stp_retrieve_keys();
            if ( !$data_keys ) {
                $result_message = 'Missing WooCommerce Stripe settings';
                $this->safe_wcs_log( $this->log_prefix . ': keys not found ' . wp_json_encode( $result_message ) );
                return null;
            }
            try {
                $stripe_test_mode = $data_keys['stripeInTestMode'] == 'yes';
                if ( $stripe_test_mode ) {
                    $stripe = new \Stripe\StripeClient($data_keys['secretTestKey']);
                } else {
                    $stripe = new \Stripe\StripeClient($data_keys['secretLiveKey']);
                }
                return $stripe->paymentIntents->retrieve( $id, array() );
            } catch ( Exception $e ) {
                $this->safe_wcs_log( $this->log_prefix . ': get_payment_intent_object exception ' . wp_json_encode( $e ) );
            }
        }

        /**
         * Gets the Stripe event type
         */
        private function get_event_type( $request_body ) {
            $request_body = json_decode( $request_body );
            $event_type = ( $request_body->type ? strtolower( $request_body->type ) : null );
            return $event_type;
        }

        /**
         * Extract the Stripe event id (evt_…) from a raw webhook body. Used by the
         * 3.7.5 idempotent-webhook dedup in check_for_webhook(). Returns '' when the
         * body is not decodable or carries no id.
         *
         * @since 3.7.5
         * @param string $request_body Raw JSON webhook body.
         * @return string Event id, or '' if absent.
         */
        private function get_event_id( $request_body ) {
            $decoded = json_decode( $request_body );
            if ( !is_object( $decoded ) || empty( $decoded->id ) || !is_string( $decoded->id ) ) {
                return '';
            }
            return $decoded->id;
        }

        /**
         * Gets the Stripe source ID
         */
        private function get_source_id( $request_body ) {
            $event_type = $this->get_event_type( $request_body );
            $source_id = null;
            if ( !$event_type ) {
                return null;
            }
            $request_body = json_decode( $request_body );
            switch ( $event_type ) {
                case 'charge.succeeded':
                    $source_id = ( isset( $request_body->data->object->source->id ) ? $request_body->data->object->source->id : '' );
                    break;
                case 'payment_intent.succeeded':
                    $source_id = ( isset( $request_body->data->object->source ) ? $request_body->data->object->source : '' );
                    if ( empty( $source_id ) ) {
                        $this->safe_wcs_log( $this->log_prefix . ' payment_method : ' . wp_json_encode( $request_body->data->object->payment_method ) );
                        $source_id = ( isset( $request_body->data->object->payment_method ) ? $request_body->data->object->payment_method : '' );
                    }
                    break;
                case 'source.chargeable':
                    $source_id = ( isset( $request_body->data->object->id ) ? $request_body->data->object->id : '' );
                    break;
                // 3.7.5 payments-grade hardening (2026-05-24): dispute events
                // carry the original charge ID in `data.object.charge`. Same
                // value WC stores as _stripe_source_id meta, so the existing
                // webhook_for_this_site() check matches the right order.
                case 'charge.dispute.created':
                case 'charge.dispute.won':
                case 'charge.dispute.lost':
                case 'charge.dispute.closed':
                case 'charge.dispute.funds_withdrawn':
                case 'charge.dispute.funds_reinstated':
                    $source_id = ( isset( $request_body->data->object->charge ) ? $request_body->data->object->charge : '' );
                    break;
                // 3.7.5 (sc-ASYNC-FAIL): async-payment failure events. A
                // charge.failed object IS the charge, so its `id` is the value WC
                // stored as _stripe_source_id. A payment_intent.payment_failed
                // object is the PaymentIntent — prefer its latest_charge, fall back
                // to charges.data[0].id, then to the PI id itself — so
                // webhook_for_this_site() resolves the right order.
                case 'charge.failed':
                    $source_id = ( isset( $request_body->data->object->id ) ? $request_body->data->object->id : '' );
                    break;
                case 'payment_intent.payment_failed':
                    if ( isset( $request_body->data->object->latest_charge ) && !empty( $request_body->data->object->latest_charge ) ) {
                        $source_id = $request_body->data->object->latest_charge;
                    } elseif ( isset( $request_body->data->object->charges->data[0]->id ) ) {
                        $source_id = $request_body->data->object->charges->data[0]->id;
                    } else {
                        $source_id = ( isset( $request_body->data->object->id ) ? $request_body->data->object->id : '' );
                    }
                    break;
            }
            return $source_id;
        }

        /**
         * Get data from the transfer request
         */
        private function get_transfer_meta( $transfer ) {
            try {
                $data = null;
                // Populate variables from objects. If any required value is null, exit
                if ( isset( $transfer['amount'] ) && $transfer->amount ) {
                    $transfer_amount = $transfer->amount;
                    $transfer_amount = $transfer_amount / 100;
                } else {
                    return null;
                }
                if ( isset( $transfer['id'] ) && $transfer->id ) {
                    $transfer_id = $transfer->id;
                } else {
                    return null;
                }
                if ( isset( $transfer['destination'] ) && $transfer->destination ) {
                    $transfer_destination = $transfer->destination;
                } else {
                    return null;
                }
                if ( isset( $transfer['source_transaction'] ) && $transfer->source_transaction ) {
                    $transfer_source_transaction = $transfer->source_transaction;
                } else {
                    return null;
                }
                $data = array(
                    'transfer_amount'             => $transfer_amount,
                    'transfer_id'                 => $transfer_id,
                    'transfer_destination'        => $transfer_destination,
                    'transfer_source_transaction' => $transfer_source_transaction,
                );
                return $data;
            } catch ( Exception $e ) {
                return null;
            }
        }

        /**
         * Add an order note with transfer details and a link to the Stripe Dashboard.
         */
        private function add_transfer_order_note(
            $order,
            $transfer_obj,
            $destination,
            $label,
            $is_test_mode,
            $platform_account_id = '',
            $status = 'success',
            $error_msg = ''
        ) {
            $dashboard_base = 'https://dashboard.stripe.com';
            $acct_segment = ( !empty( $platform_account_id ) ? '/' . $platform_account_id : '' );
            $mode_segment = ( $is_test_mode ? '/test' : '' );
            if ( $status === 'success' && $transfer_obj ) {
                $transfer_id = $transfer_obj->id;
                $amount_cents = $transfer_obj->amount;
                $currency = strtoupper( $transfer_obj->currency );
                $amount = number_format( $amount_cents / 100, 2 );
                $link = $dashboard_base . $acct_segment . $mode_segment . '/connect/transfers/' . $transfer_id;
                $note = sprintf(
                    'Split Pay %s: %s %s to %s — <a href="%s" target="_blank" rel="noopener noreferrer">%s</a>',
                    $label,
                    $currency,
                    $amount,
                    $destination,
                    esc_url( $link ),
                    $transfer_id
                );
            } else {
                $note = sprintf(
                    'Split Pay %s FAILED for %s: %s',
                    $label,
                    $destination,
                    $error_msg
                );
            }
            $order->add_order_note( $note );
        }

        /**
         * Retrieve keys and options
         */
        private function stp_retrieve_keys() {
            // Get settings from WooCommerce Stripe Gateway plugin
            $data = null;
            $woocommerce_stripe_settings = get_option( 'woocommerce_stripe_settings' );
            if ( !$woocommerce_stripe_settings ) {
                return false;
            }
            $wc_stripe_test_mode = ( isset( $woocommerce_stripe_settings['testmode'] ) ? $woocommerce_stripe_settings['testmode'] : null );
            $stripe_test_api_secret_key = get_option( 'stripe_test_api_secret_key', false );
            $stripe_api_secret_key = get_option( 'stripe_api_secret_key', false );
            // Get our settings and theirs
            $data = array(
                'connectedKey'      => get_option( 'bsd_split_pay_stripe_connect_woo_stripe_connected_account' ),
                'bsd_spscwt_type'   => get_option( 'bsd_spscwt_type' ),
                'percentage'        => get_option( 'bsd_split_pay_stripe_connect_woo_transfer_percentage' ),
                'bsd_spscwt_amount' => get_option( 'bsd_spscwt_amount' ),
                'secretTestKey'     => $stripe_test_api_secret_key,
                'secretLiveKey'     => $stripe_api_secret_key,
                'stripeInTestMode'  => $wc_stripe_test_mode,
            );
            return $data;
        }

        /**
         * Determine whether or not to initiate a transfer
         */
        private function transfer_controller( $request_body ) {
            require_once __DIR__ . '/vendor/autoload.php';
            $event_type = $this->get_event_type( $request_body );
            $this->safe_wcs_log( $this->log_prefix . ': transfer_controller event_type ' . wp_json_encode( $event_type ) );
            if ( $event_type == 'payment_intent.succeeded' ) {
                [
                    $success,
                    $result_message,
                    $transfer,
                    $shipping_transfer,
                    $other_transfer_info,
                    $product_extras_transfer_log_info_array
                ] = $this->transfer_to_account( $request_body );
                $this->safe_wcs_log( $this->log_prefix . ': after success transfer_to_account ' . wp_json_encode( $success ) );
                if ( $success ) {
                    $this->log_transfer_request(
                        $request_body,
                        $transfer,
                        $shipping_transfer,
                        $other_transfer_info,
                        $product_extras_transfer_log_info_array
                    );
                    // audit P2-1 — idempotency observability for the suite's
                    // idempotency-replay spec. Fires only on the SUCCESSFUL
                    // processing path; if the order's transfer-processed
                    // flag was already set, transfer_to_account() returns
                    // $success=false (or no-op) and this counter doesn't
                    // fire — which is the dedup the spec asserts.
                    if ( function_exists( 'do_action' ) ) {
                        do_action( 'pts_increment_counter', 'payment_succeeded' );
                    }
                } else {
                    // TODO: Notify administrator. For now, error_log it
                    $this->safe_wcs_log( $this->log_prefix . ': ' . wp_json_encode( $result_message ) );
                }
            }
        }

        /**
         * Transfer to connected account
         */
        private function transfer_to_account( $request_body ) {
            global $wpdb;
            $table_prefix = $wpdb->prefix;
            $table_name = $table_prefix . SPP_CONNECTED_ID_TABLE;
            $result_message = null;
            $success = false;
            $any_transfer_failed = false;
            $transfer = $paymentIntent = array();
            $shipping_transfer = array();
            $other_transfer_info = array();
            $meta_data = array();
            $product_extras_transfer_log_info_array = array();
            $transfer_description = $cus_first_name = $cus_last_name = '';
            $sending_meta = get_option( 'sending_meta', false );
            $transfer_taxes = get_option( 'transfer_taxes', false );
            $tax_transfer_type = get_option( 'tax_transfer_type', false );
            $data_keys = $this->stp_retrieve_keys();
            if ( !$data_keys ) {
                $result_message = 'Missing WooCommerce Stripe settings';
                return array(
                    $success,
                    $result_message,
                    $transfer,
                    $shipping_transfer,
                    $other_transfer_info,
                    $product_extras_transfer_log_info_array
                );
            }
            $event_data = $this->get_event_meta( $request_body );
            $this->safe_wcs_log( $this->log_prefix . ': tax_transfer_type ==> ' . wp_json_encode( $tax_transfer_type ) );
            if ( $event_data ) {
                try {
                    $stripe_test_mode = $data_keys['stripeInTestMode'] == 'yes';
                    // $exclude_shipping = $data_keys['excludeShipping'] == '1' ? true : false;
                    // $exclude_tax = $data_keys['excludeTax'] == '1' ? true : false;
                    $default_percentage = $data_keys['percentage'] / 100;
                    // Order details
                    $order_id = $event_data['wc_order_id'];
                    $order = wc_get_order( $order_id );
                    $source_transaction = $event_data['source_charge_id'];
                    $total_amount = $event_data['charge_amount'];
                    $this->safe_wcs_log( $this->log_prefix . ': order_id ' . wp_json_encode( $order_id ) );
                    $this->safe_wcs_log( $this->log_prefix . ': source_transaction ' . wp_json_encode( $source_transaction ) );
                    // 3.7.6 hardening (sc-WEBHOOK-ORDER-RES companion): guard BEFORE touching $order.
                    // A payment_intent.succeeded that passed signature + webhook_for_this_site can still
                    // carry an EMPTY metadata.order_id (get_event_meta reads $event->metadata->order_id),
                    // so wc_get_order('') returns false; calling $order->get_billing_email() on it threw an
                    // uncaught Error -> HTTP 500 -> Stripe retried the delivery indefinitely. Money is
                    // already safe (per-order done-flag + spp_evt_ dedup); return the graceful result instead.
                    if ( !$order_id || !$source_transaction || !$order ) {
                        $result_message = 'Missing order data.';
                        return array(
                            $success,
                            $result_message,
                            $transfer,
                            $shipping_transfer,
                            $other_transfer_info,
                            $product_extras_transfer_log_info_array
                        );
                    }
                    /* Order Billing */
                    $cus_email = $order->get_billing_email();
                    // Customer billing information details
                    $cus_first_name = $order->get_billing_first_name();
                    $cus_last_name = $order->get_billing_last_name();
                    $transfer_description = $cus_first_name . ' ' . $cus_last_name . ' - Order ' . $order_id;
                    if ( $sending_meta == '1' ) {
                        $meta_data = array(
                            'Site Name'      => get_bloginfo( 'name' ),
                            'Site Url'       => get_bloginfo( 'url' ),
                            'Order Id'       => $order_id,
                            'Customer Name'  => $cus_first_name . ' ' . $cus_last_name,
                            'Customer Email' => $cus_email,
                        );
                    }
                    if ( class_exists( '\\Automattic\\WooCommerce\\Utilities\\OrderUtil' ) ) {
                        if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
                            $is_transfer_process_done = $order->get_meta( 'is_transfer_process_done', true );
                        } else {
                            $is_transfer_process_done = get_post_meta( $order_id, 'is_transfer_process_done', true );
                        }
                    } else {
                        $is_transfer_process_done = get_post_meta( $order_id, 'is_transfer_process_done', true );
                    }
                    if ( !empty( $is_transfer_process_done ) ) {
                        $result_message = 'Transfer already done of this order ==> ' . $order_id;
                        $this->safe_wcs_log( $this->log_prefix . ': Transfer already done of this order ==> ' . wp_json_encode( $order_id ) );
                        return array(
                            $success,
                            $result_message,
                            $transfer,
                            $shipping_transfer,
                            $other_transfer_info,
                            $product_extras_transfer_log_info_array
                        );
                    }
                    // 3.7.5 (sc-YA8): bump the per-order Stripe-idempotency
                    // attempt counter at the top of each fresh batch so retries
                    // after a previous-attempt failure don't collide with the
                    // prior request's cached Stripe fingerprint. See the
                    // docblock on spp_bump_idem_attempt() in the main file.
                    $idem_attempt = \BSD_Split_Pay_Stripe_Connect_Woo\spp_bump_idem_attempt( $order_id );
                    $transfer_amount = $this->calculate_transfer_amount( $order_id, $default_percentage, $data_keys );
                    $this->safe_wcs_log( $this->log_prefix . ': returned transfer_amount ' . wp_json_encode( $transfer_amount ) );
                    if ( empty( $transfer_amount['total_global_transfer_amount'] ) && empty( $transfer_amount['total_product_transfer_amount'] ) ) {
                        $result_message = 'Error calculating transfer amount.';
                        return array(
                            $success,
                            $result_message,
                            $transfer,
                            $shipping_transfer,
                            $other_transfer_info,
                            $product_extras_transfer_log_info_array
                        );
                    }
                    $api_key = ( $stripe_test_mode ? $data_keys['secretTestKey'] : $data_keys['secretLiveKey'] );
                    $stripe = new \Stripe\StripeClient($api_key);
                    $platform_account_id = '';
                    try {
                        $platform_account = $stripe->accounts->retrieve( 'self', array() );
                        $platform_account_id = $platform_account->id;
                    } catch ( Exception $e ) {
                        $this->safe_wcs_log( $this->log_prefix . ': could not retrieve platform account ID: ' . $e->getMessage() );
                    }
                    $woo_currency = get_woocommerce_currency();
                    $currency = ( $woo_currency ? $woo_currency : 'usd' );
                    // $table_name is a constant identifier ($table_prefix . SPP_CONNECTED_ID_TABLE); this fixed SELECT has no bindable user input.
                    $connected_accounts = $wpdb->get_results( 'select * from ' . $table_name . ' ', ARRAY_A );
                    // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared,PluginCheck.Security.DirectDB.UnescapedDBParameter -- constant table identifier, no user input.
                    $store_global_transfer_amount = $transfer_amount['total_global_transfer_amount'];
                    $global_tax_total = $transfer_amount['data_array']['global_tax_total'] ?? 0;
                    /** tax start */
                    $this->safe_wcs_log( $this->log_prefix . ': store_global_transfer_amount ' . wp_json_encode( $store_global_transfer_amount ) );
                    $this->safe_wcs_log( $this->log_prefix . ': global_tax_total ' . wp_json_encode( $global_tax_total ) );
                    /** tax start */
                    $all_taxes_array = $transfer_amount['all_taxes_array'];
                    /** tax start */
                    try {
                        $charge_obj = $stripe->charges->retrieve( $source_transaction, array() );
                        $payment_method = $charge_obj->payment_method_details->type ?? 'unknown';
                        $this->safe_wcs_log( $this->log_prefix . ': payment_method_type ' . $payment_method . ' for order ' . $order_id );
                        if ( $charge_obj->status !== 'succeeded' ) {
                            $result_message = 'Charge not yet succeeded (status: ' . $charge_obj->status . '). Payment method: ' . $payment_method . '. Transfers deferred.';
                            $this->safe_wcs_log( $this->log_prefix . ': ' . $result_message );
                            $order->add_order_note( sprintf( 
                                /* translators: %1$s = Stripe charge status, %2$s = payment method label. */
                                __( 'Split Pay: Charge status is "%1$s" (payment method: %2$s). Transfers will be attempted when the charge succeeds.', 'bsd-split-pay-stripe-connect-woo' ),
                                $charge_obj->status,
                                $payment_method
                             ) );
                            return array(
                                $success,
                                $result_message,
                                $transfer,
                                $shipping_transfer,
                                $other_transfer_info,
                                $product_extras_transfer_log_info_array
                            );
                        }
                    } catch ( \Exception $e ) {
                        $this->safe_wcs_log( $this->log_prefix . ': Could not verify charge status: ' . $e->getMessage() );
                    }
                    $this->safe_wcs_log( $this->log_prefix . ': transfer started for order ==================> ' . wp_json_encode( $order_id ) );
                    $email_log_global_transfer = array();
                    /** global transfers */
                    $store_total_transffered_amount = 0;
                    $index = 0;
                    if ( !empty( $connected_accounts ) && !empty( $store_global_transfer_amount ) ) {
                        $total_global_connected_accounts = count( $connected_accounts );
                        foreach ( $connected_accounts as $cak ) {
                            if ( $cak['bsd_spscwt_type'] == 'percentage' ) {
                                $percentage_divided = $cak['bsd_spscwt_percentage_amount'] / 100;
                                $actual_transfer_amount = $transfer_amount['total_global_transfer_amount'] * $percentage_divided;
                                $store_total_transffered_amount = $store_total_transffered_amount + $actual_transfer_amount;
                            } else {
                                $store_total_transffered_amount = $store_total_transffered_amount + $cak['bsd_spscwt_percentage_amount'];
                            }
                        }
                        $this->safe_wcs_log( $this->log_prefix . ': store_total_transffered_amount ' . wp_json_encode( $store_total_transffered_amount ) );
                        foreach ( $connected_accounts as $cak ) {
                            if ( !empty( $store_global_transfer_amount ) ) {
                                $account_wise_tax = 0;
                                if ( $cak['bsd_spscwt_type'] == 'percentage' ) {
                                    $percentage_divided = $cak['bsd_spscwt_percentage_amount'] / 100;
                                    $actual_transfer_amount = $transfer_amount['total_global_transfer_amount'] * $percentage_divided;
                                    /** tax start */
                                    if ( !empty( $global_tax_total ) && $transfer_taxes == '1' && $tax_transfer_type == 'partial' ) {
                                        $account_wise_tax = $global_tax_total * $percentage_divided;
                                        $meta_data['account_wise_tax'] = $account_wise_tax;
                                    } elseif ( !empty( $global_tax_total ) && $transfer_taxes == '1' && $tax_transfer_type == 'all' ) {
                                        if ( $total_global_connected_accounts == 1 ) {
                                            $this->safe_wcs_log( $this->log_prefix . ': total_global_connected_accounts ' . wp_json_encode( $total_global_connected_accounts ) );
                                            $this->safe_wcs_log( $this->log_prefix . ': total_global_connected_accounts global_tax_total ' . wp_json_encode( $global_tax_total ) );
                                            $account_wise_tax = $global_tax_total;
                                            $meta_data['account_wise_tax'] = $account_wise_tax;
                                        } else {
                                            $partial_transfer_percentage = $actual_transfer_amount / $store_total_transffered_amount * 100;
                                            $this->safe_wcs_log( $this->log_prefix . ': global partial_transfer_percentage ' . wp_json_encode( $partial_transfer_percentage ) );
                                            $divided_amount = $global_tax_total / 100;
                                            $account_wise_tax = $divided_amount * $partial_transfer_percentage;
                                            $meta_data['account_wise_tax'] = $account_wise_tax;
                                        }
                                    }
                                    /** tax end */
                                    $this->safe_wcs_log( $this->log_prefix . ': global account_wise_tax ' . wp_json_encode( $account_wise_tax ) );
                                    $this->safe_wcs_log( $this->log_prefix . ': actual_transfer_amount ' . wp_json_encode( $actual_transfer_amount ) );
                                    if ( !empty( $actual_transfer_amount ) ) {
                                        if ( $transfer_taxes == '1' ) {
                                            $actual_transfer_amount_into_hundred = bsd_wcsc_get_amount( $actual_transfer_amount + $account_wise_tax );
                                        } else {
                                            $actual_transfer_amount_into_hundred = bsd_wcsc_get_amount( $actual_transfer_amount );
                                        }
                                        $this->safe_wcs_log( $this->log_prefix . ': actual_transfer_amount_into_hundred ' . wp_json_encode( $actual_transfer_amount_into_hundred ) );
                                        if ( $actual_transfer_amount < $store_global_transfer_amount ) {
                                            if ( $index == 0 ) {
                                                // $actual_transfer_amount_into_hundred = $actual_transfer_amount_into_hundred + bsd_wcsc_get_amount($store_product_transfer_amount);
                                                $actual_transfer_amount_into_hundred = $actual_transfer_amount_into_hundred;
                                            }
                                            try {
                                                $meta_data = apply_filters(
                                                    'spp_global_account_wise_meta_data',
                                                    $meta_data,
                                                    $order_id,
                                                    $cak['bsd_connected_account_id']
                                                );
                                                $transfer_params = array(
                                                    'amount'             => $actual_transfer_amount_into_hundred,
                                                    'currency'           => $currency,
                                                    'source_transaction' => $source_transaction,
                                                    'destination'        => $cak['bsd_connected_account_id'],
                                                    'description'        => $transfer_description,
                                                );
                                                if ( !empty( $meta_data ) && is_array( $meta_data ) ) {
                                                    $transfer_params['metadata'] = $meta_data;
                                                }
                                                $transfer[$index] = $stripe->transfers->create( $transfer_params, array(
                                                    'idempotency_key' => 'spp_' . $order_id . '_' . $cak['bsd_connected_account_id'] . '_gp_' . $index . '_' . $idem_attempt,
                                                ) );
                                                $email_log_global_transfer[$index] = array(
                                                    'account_id'                   => $cak['bsd_connected_account_id'],
                                                    'transfer_type'                => $cak['bsd_spscwt_type'],
                                                    'transfer_percentage_or_fixed' => $cak['bsd_spscwt_percentage_amount'],
                                                    'transfer_value'               => $actual_transfer_amount,
                                                    'status'                       => 'success',
                                                    'transfer'                     => $transfer[$index],
                                                    'account_wise_tax'             => $account_wise_tax,
                                                );
                                                if ( !empty( $meta_data ) ) {
                                                    $destination_payment = $transfer[$index]->destination_payment;
                                                    $paymentIntent[$index] = $stripe->charges->update( $destination_payment, array(
                                                        'metadata' => $meta_data,
                                                    ), array(
                                                        'stripe_account' => $cak['bsd_connected_account_id'],
                                                    ) );
                                                }
                                                $other_transfer_info[$index]['transfer_type'] = '1';
                                                // 1 stands for global percentage transfer
                                                $other_transfer_info[$index]['entered_transfer_value'] = $cak['bsd_spscwt_percentage_amount'];
                                                $other_transfer_info[$index]['total_global_transfer_amount'] = $transfer_amount['total_global_transfer_amount'];
                                                $other_transfer_info[$index]['global_tax_total'] = $global_tax_total;
                                                if ( $transfer_taxes == '1' ) {
                                                    $other_transfer_info[$index]['account_wise_tax'] = $account_wise_tax;
                                                    $other_transfer_info[$index]['tax_transfer_type'] = $tax_transfer_type;
                                                } else {
                                                    $other_transfer_info[$index]['account_wise_tax'] = 0;
                                                }
                                                $this->safe_wcs_log( $this->log_prefix . ': transfer ' . wp_json_encode( $transfer[$index] ) );
                                                // $this->safe_wcs_log($this->log_prefix . ': PaymentIntent Log ' . print_r($paymentIntent[$index], true));
                                                $store_global_transfer_amount = $store_global_transfer_amount - $actual_transfer_amount;
                                                $this->add_transfer_order_note(
                                                    $order,
                                                    $transfer[$index],
                                                    $cak['bsd_connected_account_id'],
                                                    'Global Transfer (' . $cak['bsd_spscwt_percentage_amount'] . '%)',
                                                    $stripe_test_mode,
                                                    $platform_account_id
                                                );
                                            } catch ( Exception $e ) {
                                                $any_transfer_failed = true;
                                                $this->safe_wcs_log( $this->log_prefix . ': transfer didnt happend ' . wp_json_encode( $e ) );
                                                $email_log_global_transfer[$index] = array(
                                                    'account_id'                   => $cak['bsd_connected_account_id'],
                                                    'transfer_type'                => $cak['bsd_spscwt_type'],
                                                    'transfer_percentage_or_fixed' => $cak['bsd_spscwt_percentage_amount'],
                                                    'transfer_value'               => $actual_transfer_amount,
                                                    'status'                       => 'failed',
                                                    'transfer'                     => array(),
                                                );
                                                $this->add_transfer_order_note(
                                                    $order,
                                                    null,
                                                    $cak['bsd_connected_account_id'],
                                                    'Global Transfer (' . $cak['bsd_spscwt_percentage_amount'] . '%)',
                                                    $stripe_test_mode,
                                                    $platform_account_id,
                                                    'failed',
                                                    $e->getMessage()
                                                );
                                            }
                                            ++$index;
                                        } else {
                                            break;
                                        }
                                    }
                                } else {
                                    /** tax start */
                                    if ( !empty( $global_tax_total ) && $transfer_taxes == '1' && $tax_transfer_type == 'partial' ) {
                                        $account_wise_tax = $cak['bsd_spscwt_percentage_amount'] / $store_global_transfer_amount * $global_tax_total;
                                        $meta_data['account_wise_tax'] = $account_wise_tax;
                                    } elseif ( !empty( $global_tax_total ) && $transfer_taxes == '1' && $tax_transfer_type == 'all' ) {
                                        $partial_transfer_percentage = $cak['bsd_spscwt_percentage_amount'] / $store_total_transffered_amount * 100;
                                        $this->safe_wcs_log( $this->log_prefix . ': global fixed partial_transfer_percentage ' . wp_json_encode( $partial_transfer_percentage ) );
                                        $divided_amount = $global_tax_total / 100;
                                        $account_wise_tax = $divided_amount * $partial_transfer_percentage;
                                        $meta_data['account_wise_tax'] = $account_wise_tax;
                                    }
                                    /** tax end */
                                    if ( $transfer_taxes == '1' ) {
                                        $actual_transfer_amount_into_hundred = bsd_wcsc_get_amount( $cak['bsd_spscwt_percentage_amount'] + $account_wise_tax );
                                    } else {
                                        $actual_transfer_amount_into_hundred = bsd_wcsc_get_amount( $cak['bsd_spscwt_percentage_amount'] );
                                    }
                                    $this->safe_wcs_log( $this->log_prefix . ': cak["bsd_spscwt_percentage_amount"] ' . wp_json_encode( $cak['bsd_spscwt_percentage_amount'] ) );
                                    $this->safe_wcs_log( $this->log_prefix . ': fixed account_wise_tax ' . wp_json_encode( $account_wise_tax ) );
                                    $this->safe_wcs_log( $this->log_prefix . ': actual_transfer_amount_into_hundred ' . wp_json_encode( $actual_transfer_amount_into_hundred ) );
                                    if ( !empty( $actual_transfer_amount_into_hundred ) ) {
                                        if ( $cak['bsd_spscwt_percentage_amount'] < $store_global_transfer_amount ) {
                                            if ( $index == 0 ) {
                                                // $actual_transfer_amount_into_hundred = $actual_transfer_amount_into_hundred + bsd_wcsc_get_amount($store_product_transfer_amount);
                                                $actual_transfer_amount_into_hundred = $actual_transfer_amount_into_hundred;
                                            }
                                            try {
                                                $meta_data = apply_filters(
                                                    'spp_global_account_wise_meta_data',
                                                    $meta_data,
                                                    $order_id,
                                                    $cak['bsd_connected_account_id']
                                                );
                                                $transfer_params = array(
                                                    'amount'             => $actual_transfer_amount_into_hundred,
                                                    'currency'           => $currency,
                                                    'source_transaction' => $source_transaction,
                                                    'destination'        => $cak['bsd_connected_account_id'],
                                                    'description'        => $transfer_description,
                                                );
                                                if ( !empty( $meta_data ) && is_array( $meta_data ) ) {
                                                    $transfer_params['metadata'] = $meta_data;
                                                }
                                                $transfer[$index] = $stripe->transfers->create( $transfer_params, array(
                                                    'idempotency_key' => 'spp_' . $order_id . '_' . $cak['bsd_connected_account_id'] . '_ga_' . $index . '_' . $idem_attempt,
                                                ) );
                                                $email_log_global_transfer[$index] = array(
                                                    'account_id'                   => $cak['bsd_connected_account_id'],
                                                    'transfer_type'                => $cak['bsd_spscwt_type'],
                                                    'transfer_percentage_or_fixed' => $cak['bsd_spscwt_percentage_amount'],
                                                    'transfer_value'               => $cak['bsd_spscwt_percentage_amount'],
                                                    'status'                       => 'success',
                                                    'transfer'                     => $transfer[$index],
                                                    'account_wise_tax'             => $account_wise_tax,
                                                );
                                                if ( !empty( $meta_data ) ) {
                                                    $destination_payment = $transfer[$index]->destination_payment;
                                                    $paymentIntent[$index] = $stripe->charges->update( $destination_payment, array(
                                                        'metadata' => $meta_data,
                                                    ), array(
                                                        'stripe_account' => $cak['bsd_connected_account_id'],
                                                    ) );
                                                }
                                                $other_transfer_info[$index]['transfer_type'] = '2';
                                                // 2 stands for global fixed transfer
                                                $other_transfer_info[$index]['entered_transfer_value'] = $cak['bsd_spscwt_percentage_amount'];
                                                $other_transfer_info[$index]['total_global_transfer_amount'] = $transfer_amount['total_global_transfer_amount'];
                                                $other_transfer_info[$index]['global_tax_total'] = $global_tax_total;
                                                if ( $transfer_taxes == '1' ) {
                                                    $other_transfer_info[$index]['account_wise_tax'] = $account_wise_tax;
                                                    $other_transfer_info[$index]['tax_transfer_type'] = $tax_transfer_type;
                                                } else {
                                                    $other_transfer_info[$index]['account_wise_tax'] = 0;
                                                }
                                                $this->safe_wcs_log( $this->log_prefix . ': transfer ' . wp_json_encode( $transfer[$index] ) );
                                                // $this->safe_wcs_log($this->log_prefix . ': PaymentIntent ' . print_r($paymentIntent[$index], true));
                                                $store_global_transfer_amount = $store_global_transfer_amount - $cak['bsd_spscwt_percentage_amount'];
                                                $this->add_transfer_order_note(
                                                    $order,
                                                    $transfer[$index],
                                                    $cak['bsd_connected_account_id'],
                                                    'Global Transfer ($' . $cak['bsd_spscwt_percentage_amount'] . ' fixed)',
                                                    $stripe_test_mode,
                                                    $platform_account_id
                                                );
                                            } catch ( Exception $e ) {
                                                $any_transfer_failed = true;
                                                $email_log_global_transfer[$index] = array(
                                                    'account_id'                   => $cak['bsd_connected_account_id'],
                                                    'transfer_type'                => $cak['bsd_spscwt_type'],
                                                    'transfer_percentage_or_fixed' => $cak['bsd_spscwt_percentage_amount'],
                                                    'transfer_value'               => $cak['bsd_spscwt_percentage_amount'],
                                                    'status'                       => 'failed',
                                                    'transfer'                     => array(),
                                                );
                                                $this->safe_wcs_log( $this->log_prefix . ': transfer didn\'t happend ' . wp_json_encode( $e ) );
                                                $this->add_transfer_order_note(
                                                    $order,
                                                    null,
                                                    $cak['bsd_connected_account_id'],
                                                    'Global Transfer ($' . $cak['bsd_spscwt_percentage_amount'] . ' fixed)',
                                                    $stripe_test_mode,
                                                    $platform_account_id,
                                                    'failed',
                                                    $e->getMessage()
                                                );
                                            }
                                            ++$index;
                                        } else {
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    /** product wise transfer product amount */
                    $email_log_product_transfer = array();
                    $store_product_transfer_amount = $transfer_amount['total_product_transfer_amount'];
                    $this->safe_wcs_log( $this->log_prefix . ': acc_wise - store_product_transfer_amount ' . wp_json_encode( $store_product_transfer_amount ) );
                    if ( !empty( $store_product_transfer_amount ) ) {
                        foreach ( $store_product_transfer_amount as $sptak => $sptav ) {
                            $this->safe_wcs_log( $this->log_prefix . ': acc_wise - sptak ' . wp_json_encode( $sptak ) );
                            $this->safe_wcs_log( $this->log_prefix . ': acc_wise - sptav ' . wp_json_encode( $sptav ) );
                            foreach ( $sptav as $sptavk => $sptavv ) {
                                $this->safe_wcs_log( $this->log_prefix . ': acc_wise - sptak ' . wp_json_encode( $sptak ) );
                                $this->safe_wcs_log( $this->log_prefix . ': acc_wise - sptav ' . wp_json_encode( $sptav ) );
                                $this->safe_wcs_log( $this->log_prefix . ': acc_wise - account_wise_tax ' . wp_json_encode( $sptavv['account_wise_tax'] ) );
                                $this->safe_wcs_log( $this->log_prefix . ': acc_wise - actual_transfer_amount ' . wp_json_encode( $sptavv['product_discounted_price_x_qty_total'] ) );
                                if ( $transfer_taxes == '1' ) {
                                    $actual_transfer_amount_into_hundred = bsd_wcsc_get_amount( $sptavv['product_discounted_price_x_qty_total'] + $sptavv['account_wise_tax'] );
                                } else {
                                    $actual_transfer_amount_into_hundred = bsd_wcsc_get_amount( $sptavv['product_discounted_price_x_qty_total'] );
                                }
                                $this->safe_wcs_log( $this->log_prefix . ': acc_wise - actual_transfer_amount_into_hundred ' . wp_json_encode( $actual_transfer_amount_into_hundred ) );
                                if ( !empty( $actual_transfer_amount_into_hundred ) ) {
                                    try {
                                        if ( !empty( $meta_data ) ) {
                                            $transfer_meta = array(
                                                'Site Name'                     => get_bloginfo( 'name' ),
                                                'Site Url'                      => get_bloginfo( 'url' ),
                                                'product_id'                    => $sptavv['product_id'],
                                                'transfer_type'                 => $sptavv['transfer_type'],
                                                'transfer_percentage_or_amount' => $sptavv['transfer_percentage_or_amount'],
                                                'Order Id'                      => $order_id,
                                                'Customer Name'                 => $cus_first_name . ' ' . $cus_last_name,
                                                'Customer Email'                => $cus_email,
                                                'account_wise_tax'              => $sptavv['account_wise_tax'],
                                            );
                                            $transfer_meta = apply_filters(
                                                'spp_product_wise_meta_data',
                                                $transfer_meta,
                                                $order_id,
                                                $sptavv['connected_acc_id']
                                            );
                                        }
                                        $transfer_params = array(
                                            'amount'             => $actual_transfer_amount_into_hundred,
                                            'currency'           => $currency,
                                            'source_transaction' => $source_transaction,
                                            'destination'        => $sptavv['connected_acc_id'],
                                            'description'        => $transfer_description,
                                        );
                                        if ( !empty( $transfer_meta ) && is_array( $transfer_meta ) ) {
                                            $transfer_params['metadata'] = $transfer_meta;
                                        }
                                        $transfer[$index] = $stripe->transfers->create( $transfer_params, array(
                                            'idempotency_key' => 'spp_' . $order_id . '_' . $sptavv['connected_acc_id'] . '_pp_' . $index . '_' . $idem_attempt,
                                        ) );
                                        $email_log_product_transfer[$index] = array(
                                            'product_id'                   => $sptavv['product_id'],
                                            'account_id'                   => $sptavv['connected_acc_id'],
                                            'transfer_type'                => $sptavv['transfer_type'],
                                            'transfer_percentage_or_fixed' => $sptavv['transfer_percentage_or_amount'],
                                            'transfer_value'               => $sptavv['product_discounted_price_x_qty_total'],
                                            'status'                       => 'success',
                                            'transfer'                     => $transfer[$index],
                                            'account_wise_tax'             => $sptavv['account_wise_tax'],
                                        );
                                        if ( !empty( $meta_data ) ) {
                                            $destination_payment = $transfer[$index]->destination_payment;
                                            $paymentIntent[$index] = $stripe->charges->update( $destination_payment, array(
                                                'metadata' => $meta_data,
                                            ), array(
                                                'stripe_account' => $sptavv['connected_acc_id'],
                                            ) );
                                        }
                                        if ( $sptavv['product_type'] == 'simple' || $sptavv['product_type'] == 'bundle' ) {
                                            if ( $sptavv['transfer_type'] == 'percentage' ) {
                                                $other_transfer_info[$index]['transfer_type'] = '8';
                                                // 8 stands for simple product percentage transfer
                                            } else {
                                                $other_transfer_info[$index]['transfer_type'] = '9';
                                                // 9 stands for simple product fixed transfer
                                            }
                                        } elseif ( $sptavv['product_type'] == 'variation' || $sptavv['product_type'] == 'subscription_variation' ) {
                                            if ( $sptavv['transfer_type'] == 'percentage' ) {
                                                $other_transfer_info[$index]['transfer_type'] = '10';
                                                // 10 stands for variable product percentage transfer
                                            } else {
                                                $other_transfer_info[$index]['transfer_type'] = '11';
                                                // 11 stands for variable product fixed transfer
                                            }
                                        }
                                        $other_transfer_info[$index]['entered_transfer_value'] = $sptavv['transfer_percentage_or_amount'];
                                        $other_transfer_info[$index]['product_price'] = $sptavv['product_discounted_price_x_qty'];
                                        if ( $transfer_taxes == '1' ) {
                                            $other_transfer_info[$index]['account_wise_tax'] = $sptavv['account_wise_tax'];
                                            $other_transfer_info[$index]['tax_transfer_type'] = $tax_transfer_type;
                                            $other_transfer_info[$index]['product_tax_total'] = $sptavv['tax_total'];
                                        } else {
                                            $other_transfer_info[$index]['account_wise_tax'] = 0;
                                        }
                                        $this->safe_wcs_log( $this->log_prefix . ': acc_wise - transfer ' . wp_json_encode( $transfer[$index] ) );
                                        // $this->safe_wcs_log($this->log_prefix . ': acc_wise - PaymentIntent ' . print_r($paymentIntent[$index], true));
                                        $product_label = 'Product #' . $sptavv['product_id'] . ' Transfer (' . $sptavv['transfer_percentage_or_amount'] . (( $sptavv['transfer_type'] === 'percentage' ? '%' : ' fixed' )) . ')';
                                        $this->add_transfer_order_note(
                                            $order,
                                            $transfer[$index],
                                            $sptavv['connected_acc_id'],
                                            $product_label,
                                            $stripe_test_mode,
                                            $platform_account_id
                                        );
                                    } catch ( Exception $e ) {
                                        $any_transfer_failed = true;
                                        $email_log_product_transfer[$index] = array(
                                            'product_id'                   => $sptavv['product_id'],
                                            'account_id'                   => $sptavv['connected_acc_id'],
                                            'transfer_type'                => $sptavv['transfer_type'],
                                            'transfer_percentage_or_fixed' => $sptavv['transfer_percentage_or_amount'],
                                            'transfer_value'               => $sptavv['product_discounted_price_x_qty_total'],
                                            'status'                       => 'failed',
                                            'transfer'                     => array(),
                                        );
                                        $product_label = 'Product #' . $sptavv['product_id'] . ' Transfer (' . $sptavv['transfer_percentage_or_amount'] . (( $sptavv['transfer_type'] === 'percentage' ? '%' : ' fixed' )) . ')';
                                        $this->add_transfer_order_note(
                                            $order,
                                            null,
                                            $sptavv['connected_acc_id'],
                                            $product_label,
                                            $stripe_test_mode,
                                            $platform_account_id,
                                            'failed',
                                            $e->getMessage()
                                        );
                                        $this->safe_wcs_log( $this->log_prefix . ': acc_wise - transfer didn\'t happend ' . wp_json_encode( $e ) );
                                    }
                                    ++$index;
                                }
                            }
                        }
                    }
                    /** global shipping variables */
                    $email_log_global_shipping_transfer = array();
                    $total_transfer_global_shipping_amount = $transfer_amount['total_transfer_global_shipping_amount'];
                    $adjustable_transfer_global_shipping_amount = $transfer_amount['total_transfer_global_shipping_amount'];
                    $this->safe_wcs_log( $this->log_prefix . ': total_transfer_global_shipping_amount ' . wp_json_encode( $total_transfer_global_shipping_amount ) );
                    /** global shipping transfer */
                    $store_total_transffered_amount = 0;
                    // $all_taxes_array
                    $total_shipping_tax = 0;
                    if ( !empty( $all_taxes_array ) ) {
                        foreach ( $all_taxes_array as $atak ) {
                            $this->safe_wcs_log( $this->log_prefix . ': atak ' . wp_json_encode( $atak ) );
                            $total_shipping_tax = $total_shipping_tax + $atak['tax_ship_total'];
                        }
                    }
                    $this->safe_wcs_log( $this->log_prefix . ': all_taxes_array ' . wp_json_encode( $all_taxes_array ) );
                    $this->safe_wcs_log( $this->log_prefix . ': total_shipping_tax ' . wp_json_encode( $total_shipping_tax ) );
                    if ( !empty( $connected_accounts ) && !empty( $total_transfer_global_shipping_amount ) ) {
                        $shipping_index = $index;
                        $total_global_connected_accounts = count( $connected_accounts );
                        foreach ( $connected_accounts as $cak ) {
                            if ( $cak['bsd_global_shipping_type'] == 'percentage' ) {
                                $percentage_divided = $cak['bsd_global_shipping_percentage_amount'] / 100;
                                $actual_transfer_amount = $total_transfer_global_shipping_amount * $percentage_divided;
                                $store_total_transffered_amount = $store_total_transffered_amount + $actual_transfer_amount;
                            } else {
                                $store_total_transffered_amount = $store_total_transffered_amount + $cak['bsd_global_shipping_percentage_amount'];
                            }
                        }
                        foreach ( $connected_accounts as $cak ) {
                            if ( !empty( $adjustable_transfer_global_shipping_amount ) ) {
                                if ( isset( $cak['bsd_global_shipping_type'] ) && !empty( $cak['bsd_global_shipping_type'] ) && isset( $cak['bsd_global_shipping_percentage_amount'] ) && !empty( $cak['bsd_global_shipping_percentage_amount'] ) ) {
                                    $this->safe_wcs_log( $this->log_prefix . ': shipping adjustable_transfer_global_shipping_amount ' . wp_json_encode( $adjustable_transfer_global_shipping_amount ) );
                                    $account_wise_tax = 0;
                                    if ( $cak['bsd_global_shipping_type'] == 'percentage' ) {
                                        $percentage_divided = $cak['bsd_global_shipping_percentage_amount'] / 100;
                                        $actual_transfer_amount = $total_transfer_global_shipping_amount * $percentage_divided;
                                        $this->safe_wcs_log( $this->log_prefix . ': shipping actual_transfer_amount ' . wp_json_encode( $actual_transfer_amount ) );
                                        /** tax start */
                                        if ( !empty( $total_shipping_tax ) && $transfer_taxes == '1' && $tax_transfer_type == 'partial' ) {
                                            $account_wise_tax = $total_shipping_tax * $percentage_divided;
                                            $meta_data['account_wise_tax'] = $account_wise_tax;
                                        } elseif ( !empty( $total_shipping_tax ) && $transfer_taxes == '1' && $tax_transfer_type == 'all' ) {
                                            if ( $total_global_connected_accounts == 1 ) {
                                                $this->safe_wcs_log( $this->log_prefix . ': total_global_connected_accounts ' . wp_json_encode( $total_global_connected_accounts ) );
                                                $this->safe_wcs_log( $this->log_prefix . ': total_global_connected_accounts total_shipping_tax ' . wp_json_encode( $total_shipping_tax ) );
                                                $account_wise_tax = $total_shipping_tax;
                                                $meta_data['account_wise_tax'] = $account_wise_tax;
                                            } else {
                                                $partial_transfer_percentage = $actual_transfer_amount / $store_total_transffered_amount * 100;
                                                $this->safe_wcs_log( $this->log_prefix . ': global partial_transfer_percentage ' . wp_json_encode( $partial_transfer_percentage ) );
                                                $divided_amount = $total_shipping_tax / 100;
                                                $account_wise_tax = $divided_amount * $partial_transfer_percentage;
                                                $meta_data['account_wise_tax'] = $account_wise_tax;
                                            }
                                        }
                                        $this->safe_wcs_log( $this->log_prefix . ': shipping percentage account_wise_tax ' . wp_json_encode( $account_wise_tax ) );
                                        /** tax end */
                                        if ( !empty( $actual_transfer_amount ) ) {
                                            if ( $transfer_taxes == '1' ) {
                                                $actual_transfer_amount_into_hundred = bsd_wcsc_get_amount( $actual_transfer_amount + $account_wise_tax );
                                            } else {
                                                $actual_transfer_amount_into_hundred = bsd_wcsc_get_amount( $actual_transfer_amount );
                                            }
                                            $this->safe_wcs_log( $this->log_prefix . ': shipping actual_transfer_amount_into_hundred ' . wp_json_encode( $actual_transfer_amount_into_hundred ) );
                                            if ( $actual_transfer_amount <= $adjustable_transfer_global_shipping_amount ) {
                                                try {
                                                    $meta_data = apply_filters(
                                                        'spp_shipping_transfer_meta_data',
                                                        $meta_data,
                                                        $order_id,
                                                        $cak['bsd_connected_account_id']
                                                    );
                                                    $shipping_transfer_params = array(
                                                        'amount'             => $actual_transfer_amount_into_hundred,
                                                        'currency'           => $currency,
                                                        'source_transaction' => $source_transaction,
                                                        'destination'        => $cak['bsd_connected_account_id'],
                                                        'description'        => $transfer_description,
                                                    );
                                                    if ( !empty( $meta_data ) && is_array( $meta_data ) ) {
                                                        $shipping_transfer_params['metadata'] = $meta_data;
                                                    }
                                                    $shipping_transfer[$shipping_index] = $stripe->transfers->create( $shipping_transfer_params, array(
                                                        'idempotency_key' => 'spp_' . $order_id . '_' . $cak['bsd_connected_account_id'] . '_gsp_' . $shipping_index . '_' . $idem_attempt,
                                                    ) );
                                                    $email_log_global_shipping_transfer[$shipping_index] = array(
                                                        'account_id'                   => $cak['bsd_connected_account_id'],
                                                        'transfer_type'                => $cak['bsd_global_shipping_type'],
                                                        'transfer_percentage_or_fixed' => $cak['bsd_global_shipping_percentage_amount'],
                                                        'transfer_value'               => $actual_transfer_amount,
                                                        'status'                       => 'success',
                                                        'transfer'                     => $shipping_transfer[$shipping_index],
                                                        'account_wise_tax'             => $account_wise_tax,
                                                    );
                                                    if ( !empty( $meta_data ) ) {
                                                        $destination_payment = $shipping_transfer[$shipping_index]->destination_payment;
                                                        $paymentIntent[$shipping_index] = $stripe->charges->update( $destination_payment, array(
                                                            'metadata' => $meta_data,
                                                        ), array(
                                                            'stripe_account' => $cak['bsd_connected_account_id'],
                                                        ) );
                                                    }
                                                    $other_transfer_info[$shipping_index]['shipping_transfer_type'] = '3';
                                                    // 3 stands for global shipping percentage transfer
                                                    $other_transfer_info[$shipping_index]['entered_transfer_value'] = $cak['bsd_global_shipping_percentage_amount'];
                                                    $other_transfer_info[$shipping_index]['account_wise_tax'] = $account_wise_tax;
                                                    $other_transfer_info[$shipping_index]['total_transfer_global_shipping_amount'] = $total_transfer_global_shipping_amount;
                                                    $other_transfer_info[$shipping_index]['tax_transfer_type'] = $tax_transfer_type;
                                                    $other_transfer_info[$shipping_index]['total_shipping_tax'] = $total_shipping_tax;
                                                    $this->safe_wcs_log( $this->log_prefix . ': shipping transfer ' . wp_json_encode( $shipping_transfer[$shipping_index] ) );
                                                    // $this->safe_wcs_log($this->log_prefix . ': shipping transfer PaymentIntent' . print_r($paymentIntent[$shipping_index], true));
                                                    $adjustable_transfer_global_shipping_amount = $adjustable_transfer_global_shipping_amount - $actual_transfer_amount;
                                                    $this->add_transfer_order_note(
                                                        $order,
                                                        $shipping_transfer[$shipping_index],
                                                        $cak['bsd_connected_account_id'],
                                                        'Global Shipping Transfer (' . $cak['bsd_global_shipping_percentage_amount'] . '%)',
                                                        $stripe_test_mode,
                                                        $platform_account_id
                                                    );
                                                } catch ( Exception $e ) {
                                                    $any_transfer_failed = true;
                                                    $email_log_global_shipping_transfer[$shipping_index] = array(
                                                        'account_id'                   => $cak['bsd_connected_account_id'],
                                                        'transfer_type'                => $cak['bsd_global_shipping_type'],
                                                        'transfer_percentage_or_fixed' => $cak['bsd_global_shipping_percentage_amount'],
                                                        'transfer_value'               => $actual_transfer_amount,
                                                        'status'                       => 'failed',
                                                        'transfer'                     => array(),
                                                    );
                                                    $this->safe_wcs_log( $this->log_prefix . ': shipping didn\'t happend ' . wp_json_encode( $e ) );
                                                    $this->add_transfer_order_note(
                                                        $order,
                                                        null,
                                                        $cak['bsd_connected_account_id'],
                                                        'Global Shipping Transfer (' . $cak['bsd_global_shipping_percentage_amount'] . '%)',
                                                        $stripe_test_mode,
                                                        $platform_account_id,
                                                        'failed',
                                                        $e->getMessage()
                                                    );
                                                }
                                            }
                                        }
                                    } else {
                                        /** tax start */
                                        if ( !empty( $total_shipping_tax ) && $transfer_taxes == '1' && $tax_transfer_type == 'partial' ) {
                                            $account_wise_tax = $cak['bsd_global_shipping_percentage_amount'] / $store_total_transffered_amount * $total_shipping_tax;
                                            $meta_data['account_wise_tax'] = $account_wise_tax;
                                        } elseif ( !empty( $total_shipping_tax ) && $transfer_taxes == '1' && $tax_transfer_type == 'all' ) {
                                            $partial_transfer_percentage = $cak['bsd_global_shipping_percentage_amount'] / $store_total_transffered_amount * 100;
                                            $this->safe_wcs_log( $this->log_prefix . ': global shipping fixed partial_transfer_percentage ' . wp_json_encode( $partial_transfer_percentage ) );
                                            $divided_amount = $total_shipping_tax / 100;
                                            $account_wise_tax = $divided_amount * $partial_transfer_percentage;
                                            $meta_data['account_wise_tax'] = $account_wise_tax;
                                        }
                                        $this->safe_wcs_log( $this->log_prefix . ': shipping fixed account_wise_tax ' . wp_json_encode( $account_wise_tax ) );
                                        /** tax end */
                                        if ( $transfer_taxes == '1' ) {
                                            $actual_transfer_amount_into_hundred = bsd_wcsc_get_amount( $cak['bsd_global_shipping_percentage_amount'] + $account_wise_tax );
                                        } else {
                                            $actual_transfer_amount_into_hundred = bsd_wcsc_get_amount( $cak['bsd_global_shipping_percentage_amount'] );
                                        }
                                        $this->safe_wcs_log( $this->log_prefix . ': cak["bsd_global_shipping_percentage_amount"] ' . wp_json_encode( $cak['bsd_global_shipping_percentage_amount'] ) );
                                        $this->safe_wcs_log( $this->log_prefix . ': actual_transfer_amount_into_hundred ' . wp_json_encode( $actual_transfer_amount_into_hundred ) );
                                        if ( !empty( $actual_transfer_amount_into_hundred ) ) {
                                            $this->safe_wcs_log( $this->log_prefix . ': actual_transfer_amount_into_hundred inner if ' . wp_json_encode( $actual_transfer_amount_into_hundred ) );
                                            if ( $cak['bsd_global_shipping_percentage_amount'] < $adjustable_transfer_global_shipping_amount ) {
                                                $this->safe_wcs_log( $this->log_prefix . ': adjustable_transfer_global_shipping_amount inner if ' . wp_json_encode( $adjustable_transfer_global_shipping_amount ) );
                                                try {
                                                    $meta_data = apply_filters(
                                                        'spp_global_shipping_transfer_meta_data',
                                                        $meta_data,
                                                        $order_id,
                                                        $cak['bsd_connected_account_id']
                                                    );
                                                    $shipping_transfer_params = array(
                                                        'amount'             => $actual_transfer_amount_into_hundred,
                                                        'currency'           => $currency,
                                                        'source_transaction' => $source_transaction,
                                                        'destination'        => $cak['bsd_connected_account_id'],
                                                        'description'        => $transfer_description,
                                                    );
                                                    if ( !empty( $meta_data ) && is_array( $meta_data ) ) {
                                                        $shipping_transfer_params['metadata'] = $meta_data;
                                                    }
                                                    $shipping_transfer[$shipping_index] = $stripe->transfers->create( $shipping_transfer_params, array(
                                                        'idempotency_key' => 'spp_' . $order_id . '_' . $cak['bsd_connected_account_id'] . '_gsa_' . $shipping_index . '_' . $idem_attempt,
                                                    ) );
                                                    $email_log_global_shipping_transfer[$shipping_index] = array(
                                                        'account_id'                   => $cak['bsd_connected_account_id'],
                                                        'transfer_type'                => $cak['bsd_global_shipping_type'],
                                                        'transfer_percentage_or_fixed' => $cak['bsd_global_shipping_percentage_amount'],
                                                        'transfer_value'               => $cak['bsd_global_shipping_percentage_amount'],
                                                        'status'                       => 'success',
                                                        'transfer'                     => $shipping_transfer[$shipping_index],
                                                        'account_wise_tax'             => $account_wise_tax,
                                                    );
                                                    if ( !empty( $meta_data ) ) {
                                                        $destination_payment = $shipping_transfer[$shipping_index]->destination_payment;
                                                        $paymentIntent[$shipping_index] = $stripe->charges->update( $destination_payment, array(
                                                            'metadata' => $meta_data,
                                                        ), array(
                                                            'stripe_account' => $cak['bsd_connected_account_id'],
                                                        ) );
                                                    }
                                                    $other_transfer_info[$shipping_index]['shipping_transfer_type'] = '4';
                                                    // 4 stands for global shipping fixed transfer
                                                    $other_transfer_info[$shipping_index]['entered_transfer_value'] = $cak['bsd_global_shipping_percentage_amount'];
                                                    $other_transfer_info[$shipping_index]['account_wise_tax'] = $account_wise_tax;
                                                    $other_transfer_info[$shipping_index]['total_transfer_global_shipping_amount'] = $total_transfer_global_shipping_amount;
                                                    $other_transfer_info[$shipping_index]['tax_transfer_type'] = $tax_transfer_type;
                                                    $other_transfer_info[$shipping_index]['total_shipping_tax'] = $total_shipping_tax;
                                                    $this->safe_wcs_log( $this->log_prefix . ': shipping transfer ' . wp_json_encode( $shipping_transfer[$shipping_index] ) );
                                                    // $this->safe_wcs_log($this->log_prefix . ': shipping transfer PaymentIntent' . print_r($paymentIntent[$shipping_index], true));
                                                    $adjustable_transfer_global_shipping_amount = $adjustable_transfer_global_shipping_amount - $cak['bsd_global_shipping_percentage_amount'];
                                                    $this->add_transfer_order_note(
                                                        $order,
                                                        $shipping_transfer[$shipping_index],
                                                        $cak['bsd_connected_account_id'],
                                                        'Global Shipping Transfer ($' . $cak['bsd_global_shipping_percentage_amount'] . ' fixed)',
                                                        $stripe_test_mode,
                                                        $platform_account_id
                                                    );
                                                } catch ( Exception $e ) {
                                                    $any_transfer_failed = true;
                                                    $email_log_global_shipping_transfer[$shipping_index] = array(
                                                        'account_id'                   => $cak['bsd_connected_account_id'],
                                                        'transfer_type'                => $cak['bsd_global_shipping_type'],
                                                        'transfer_percentage_or_fixed' => $cak['bsd_global_shipping_percentage_amount'],
                                                        'transfer_value'               => $cak['bsd_global_shipping_percentage_amount'],
                                                        'status'                       => 'failed',
                                                        'transfer'                     => array(),
                                                    );
                                                    $this->safe_wcs_log( $this->log_prefix . ': shipping transfer didn\'t happend ' . wp_json_encode( $e ) );
                                                    $this->add_transfer_order_note(
                                                        $order,
                                                        null,
                                                        $cak['bsd_connected_account_id'],
                                                        'Global Shipping Transfer ($' . $cak['bsd_global_shipping_percentage_amount'] . ' fixed)',
                                                        $stripe_test_mode,
                                                        $platform_account_id,
                                                        'failed',
                                                        $e->getMessage()
                                                    );
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                            ++$shipping_index;
                        }
                    }
                    /** product shipping variables */
                    $email_log_product_shipping_transfer = array();
                    $total_transfer_product_shipping_amount = $transfer_amount['total_transfer_product_shipping_amount'];
                    $this->safe_wcs_log( $this->log_prefix . ': acc_wise - total_transfer_product_shipping_amount ' . wp_json_encode( $total_transfer_product_shipping_amount ) );
                    /** product shipping variables */
                    if ( !empty( $total_transfer_product_shipping_amount ) ) {
                        // audit P1.4 — initialize $shipping_index defensively.
                        // In rare code paths (no global accounts → skipped the
                        // `$shipping_index = $index` assignment at line 2112),
                        // this foreach was reading $shipping_index undefined.
                        // PHP 8.x emits a warning that may become a fatal.
                        $shipping_index = ( isset( $shipping_index ) ? (int) $shipping_index : 0 );
                        foreach ( $total_transfer_product_shipping_amount as $sptak => $sptav ) {
                            $this->safe_wcs_log( $this->log_prefix . ': shipping acc_wise - sptak ' . wp_json_encode( $sptak ) );
                            $this->safe_wcs_log( $this->log_prefix . ': shipping acc_wise - sptav ' . wp_json_encode( $sptav ) );
                            foreach ( $sptav as $sptavk => $sptavv ) {
                                $this->safe_wcs_log( $this->log_prefix . ': shipping acc_wise - sptak ' . wp_json_encode( $sptak ) );
                                $this->safe_wcs_log( $this->log_prefix . ': shipping acc_wise - sptav ' . wp_json_encode( $sptav ) );
                                $this->safe_wcs_log( $this->log_prefix . ': shipping acc_wise - actual_transfer_amount ' . wp_json_encode( $sptavv['transfer_calculate_amount'] ) );
                                $actual_transfer_amount_into_hundred = bsd_wcsc_get_amount( $sptavv['transfer_calculate_amount'] );
                                $this->safe_wcs_log( $this->log_prefix . ': shipping acc_wise - actual_transfer_amount_into_hundred ' . wp_json_encode( $actual_transfer_amount_into_hundred ) );
                                if ( !empty( $actual_transfer_amount_into_hundred ) ) {
                                    try {
                                        if ( !empty( $meta_data ) ) {
                                            $transfer_meta = array(
                                                'Site Name'                     => get_bloginfo( 'name' ),
                                                'Site Url'                      => get_bloginfo( 'url' ),
                                                'product_id'                    => $sptavv['product_id'],
                                                'transfer_type'                 => $sptavv['transfer_type'],
                                                'transfer_percentage_or_amount' => $sptavv['transfer_percentage_or_amount'],
                                                'Order Id'                      => $order_id,
                                                'Customer Name'                 => $cus_first_name . ' ' . $cus_last_name,
                                                'Customer Email'                => $cus_email,
                                            );
                                            $transfer_meta = apply_filters(
                                                'spp_product_wise_shipping_transfer_meta_data',
                                                $transfer_meta,
                                                $order_id,
                                                $sptavv['connected_acc_id']
                                            );
                                        }
                                        $shipping_transfer_params = array(
                                            'amount'             => $actual_transfer_amount_into_hundred,
                                            'currency'           => $currency,
                                            'source_transaction' => $source_transaction,
                                            'destination'        => $sptavv['connected_acc_id'],
                                            'description'        => $transfer_description,
                                        );
                                        if ( !empty( $transfer_meta ) && is_array( $transfer_meta ) ) {
                                            $shipping_transfer_params['metadata'] = $transfer_meta;
                                        }
                                        $shipping_transfer[$shipping_index] = $stripe->transfers->create( $shipping_transfer_params, array(
                                            'idempotency_key' => 'spp_' . $order_id . '_' . $sptavv['connected_acc_id'] . '_psp_' . $shipping_index . '_' . $idem_attempt,
                                        ) );
                                        $email_log_product_shipping_transfer[$shipping_index] = array(
                                            'product_id'                   => $sptavv['product_id'],
                                            'account_id'                   => $sptavv['connected_acc_id'],
                                            'transfer_type'                => $sptavv['transfer_type'],
                                            'transfer_percentage_or_fixed' => $sptavv['transfer_percentage_or_amount'],
                                            'transfer_value'               => $sptavv['transfer_calculate_amount'],
                                            'status'                       => 'success',
                                            'transfer'                     => $shipping_transfer[$shipping_index],
                                        );
                                        if ( !empty( $meta_data ) ) {
                                            $destination_payment = $shipping_transfer[$shipping_index]->destination_payment;
                                            $paymentIntent[$shipping_index] = $stripe->charges->update( $destination_payment, array(
                                                'metadata' => $meta_data,
                                            ), array(
                                                'stripe_account' => $sptavv['connected_acc_id'],
                                            ) );
                                        }
                                        if ( $sptavv['transfer_type'] == 'percentage' ) {
                                            $other_transfer_info[$shipping_index]['shipping_transfer_type'] = '6';
                                            // 6 stands for product shiping percentage transfer
                                        } else {
                                            $other_transfer_info[$shipping_index]['shipping_transfer_type'] = '7';
                                            // 7 stands for product shiping fixed transfer
                                        }
                                        $other_transfer_info[$shipping_index]['entered_transfer_value'] = $sptavv['transfer_percentage_or_amount'];
                                        $other_transfer_info[$shipping_index]['account_wise_tax'] = 0;
                                        $other_transfer_info[$shipping_index]['total_shipping_cost'] = $sptavv['product_original_shipping_cost'];
                                        $this->safe_wcs_log( $this->log_prefix . ': shipping acc_wise - transfer ' . wp_json_encode( $shipping_transfer[$shipping_index] ) );
                                        // $this->safe_wcs_log($this->log_prefix . ': shipping acc_wise - transfer PaymentIntent ' . print_r($paymentIntent[$shipping_index], true));
                                        $ship_label = 'Product #' . $sptavv['product_id'] . ' Shipping Transfer (' . $sptavv['transfer_percentage_or_amount'] . (( $sptavv['transfer_type'] === 'percentage' ? '%' : ' fixed' )) . ')';
                                        $this->add_transfer_order_note(
                                            $order,
                                            $shipping_transfer[$shipping_index],
                                            $sptavv['connected_acc_id'],
                                            $ship_label,
                                            $stripe_test_mode,
                                            $platform_account_id
                                        );
                                    } catch ( Exception $e ) {
                                        $any_transfer_failed = true;
                                        $email_log_product_shipping_transfer[$shipping_index] = array(
                                            'product_id'                   => $sptavv['product_id'],
                                            'account_id'                   => $sptavv['connected_acc_id'],
                                            'transfer_type'                => $sptavv['transfer_type'],
                                            'transfer_percentage_or_fixed' => $sptavv['transfer_percentage_or_amount'],
                                            'transfer_value'               => $sptavv['transfer_calculate_amount'],
                                            'status'                       => 'failed',
                                            'transfer'                     => array(),
                                        );
                                        $ship_label = 'Product #' . $sptavv['product_id'] . ' Shipping Transfer (' . $sptavv['transfer_percentage_or_amount'] . (( $sptavv['transfer_type'] === 'percentage' ? '%' : ' fixed' )) . ')';
                                        $this->add_transfer_order_note(
                                            $order,
                                            null,
                                            $sptavv['connected_acc_id'],
                                            $ship_label,
                                            $stripe_test_mode,
                                            $platform_account_id,
                                            'failed',
                                            $e->getMessage()
                                        );
                                        $this->safe_wcs_log( $this->log_prefix . ': shipping transfer didn\'t happend ' . wp_json_encode( $e ) );
                                    }
                                    ++$shipping_index;
                                }
                            }
                        }
                    }
                    /** Product extras tansfer start */
                    $product_extras_transfer = array();
                    $product_extras_transfer_index = 0;
                    if ( is_plugin_active( "product-extras-for-woocommerce/product-extras-for-woocommerce.php" ) ) {
                        foreach ( $order->get_items() as $item_id => $item ) {
                            $this->safe_wcs_log( $this->log_prefix . ': get_items_item ' . wp_json_encode( $item ) );
                            if ( isset( $item['product_extras']['groups'] ) ) {
                                foreach ( $item['product_extras']['groups'] as $group_id => $group ) {
                                    if ( $group ) {
                                        $this->safe_wcs_log( $this->log_prefix . ': group ' . wp_json_encode( $group ) );
                                        foreach ( $group as $field_id => $field ) {
                                            $group_id = $field['group_id'];
                                            $price = $field['price'];
                                            $value = $field['value'];
                                            $spp_connected_accounts = get_post_meta( $group_id, "spp_connected_accounts", true );
                                            $group_details = get_post( $group_id );
                                            $group_title = $group_details->post_title;
                                            $this->safe_wcs_log( $this->log_prefix . ': group_id ' . wp_json_encode( $group_id ) );
                                            $this->safe_wcs_log( $this->log_prefix . ': price ' . wp_json_encode( $price ) );
                                            $this->safe_wcs_log( $this->log_prefix . ': value ' . wp_json_encode( $value ) );
                                            $this->safe_wcs_log( $this->log_prefix . ': spp_connected_accounts ' . wp_json_encode( $spp_connected_accounts ) );
                                            if ( !empty( $spp_connected_accounts ) && !empty( $price ) && $price > 0 ) {
                                                $price_into_hundred = bsd_wcsc_get_amount( $price );
                                                $field_label = pewc_get_field_label_order_meta( $field, $item );
                                                $check_meta = esc_html( $item->get_meta( $field_label, true ) );
                                                $check_meta = wp_strip_all_tags( html_entity_decode( $check_meta ) );
                                                $transfer_description = $group_title . "  Transfer for Order #" . $order_id;
                                                $extras_transfer_params = array(
                                                    'amount'             => $price_into_hundred,
                                                    'currency'           => $currency,
                                                    'source_transaction' => $source_transaction,
                                                    'destination'        => $spp_connected_accounts,
                                                    'description'        => $transfer_description,
                                                );
                                                if ( !empty( $meta_data ) && is_array( $meta_data ) ) {
                                                    $extras_transfer_params['metadata'] = $meta_data;
                                                }
                                                $product_extras_transfer[$product_extras_transfer_index] = $stripe->transfers->create( $extras_transfer_params );
                                                $this->safe_wcs_log( $this->log_prefix . ': product_extras_transfer ' . wp_json_encode( $product_extras_transfer[$product_extras_transfer_index] ) );
                                                $product_extras_transfer_log_info_array[$product_extras_transfer_index]['product_extras_transfer'] = $product_extras_transfer[$product_extras_transfer_index];
                                                $product_extras_transfer_log_info_array[$product_extras_transfer_index]['transfer_type'] = '12';
                                                $product_extras_transfer_log_info_array[$product_extras_transfer_index]['product_id'] = $item->get_product_id();
                                                $product_extras_transfer_log_info_array[$product_extras_transfer_index]['variation_id'] = $item->get_variation_id();
                                                $product_extras_transfer_log_info_array[$product_extras_transfer_index]['group_title'] = $group_title;
                                                $product_extras_transfer_log_info_array[$product_extras_transfer_index]['label'] = $value;
                                                $product_extras_transfer_log_info_array[$product_extras_transfer_index]['account_id'] = $spp_connected_accounts;
                                                $product_extras_transfer_log_info_array[$product_extras_transfer_index]['entered_transfer_value'] = $price;
                                                $product_extras_transfer_log_info_array[$product_extras_transfer_index]['total_global_transfer_amount'] = 0;
                                                $product_extras_transfer_log_info_array[$product_extras_transfer_index]['global_tax_total'] = "";
                                                $product_extras_transfer_log_info_array[$product_extras_transfer_index]['account_wise_tax'] = "";
                                                $product_extras_transfer_index++;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        $this->safe_wcs_log( $this->log_prefix . ': product_extras_transfer_log_info_array ' . wp_json_encode( $product_extras_transfer_log_info_array ) );
                    }
                    /** Product extras tansfer end */
                    $this->safe_wcs_log( $this->log_prefix . ': transfer ended for order ==================> ' . wp_json_encode( $order_id ) );
                    if ( !$any_transfer_failed ) {
                        if ( class_exists( '\\Automattic\\WooCommerce\\Utilities\\OrderUtil' ) ) {
                            if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
                                $order->update_meta_data( 'is_transfer_process_done', 1 );
                                $order->save();
                            } else {
                                update_post_meta( $order_id, 'is_transfer_process_done', 1 );
                            }
                        } else {
                            update_post_meta( $order_id, 'is_transfer_process_done', 1 );
                        }
                        $success = true;
                        $result_message = 'Transfer successful';
                    } else {
                        $result_message = 'Some transfers failed for order ' . $order_id;
                        $this->safe_wcs_log( $this->log_prefix . ': ' . $result_message );
                        if ( class_exists( '\\Automattic\\WooCommerce\\Utilities\\OrderUtil' ) && OrderUtil::custom_orders_table_usage_is_enabled() ) {
                            $order->update_meta_data( 'spp_has_failed_transfers', '1' );
                            $order->save();
                        } else {
                            update_post_meta( $order_id, 'spp_has_failed_transfers', '1' );
                        }
                    }
                    $transfer_email = get_option( 'transfer_email', false );
                    if ( $transfer_email == '1' ) {
                        $data_email = array(
                            'global_transfer'           => $email_log_global_transfer,
                            'global_shippint_transfer'  => $email_log_global_shipping_transfer,
                            'product_transfer'          => $email_log_product_transfer,
                            'product_shipping_transfer' => $email_log_product_shipping_transfer,
                        );
                        if ( is_plugin_active( 'product-extras-for-woocommerce/product-extras-for-woocommerce.php' ) ) {
                            $data_email['product_extras_transfer'] = $product_extras_transfer_log_info_array;
                        }
                        $this->safe_wcs_log( $this->log_prefix . ': data_email ' . wp_json_encode( $data_email ) );
                        WC()->mailer()->emails['WC_Transfer_Order_Email']->trigger( $order_id, $data_email );
                    }
                    $this->safe_wcs_log( $this->log_prefix . ': transfer array for log ' . wp_json_encode( $transfer ) );
                    $this->safe_wcs_log( $this->log_prefix . ': shipping_transfer array for log ' . wp_json_encode( $shipping_transfer ) );
                    $this->safe_wcs_log( $this->log_prefix . ': other_transfer_info array for log ' . wp_json_encode( $other_transfer_info ) );
                    return array(
                        $success,
                        $result_message,
                        $transfer,
                        $shipping_transfer,
                        $other_transfer_info,
                        $product_extras_transfer_log_info_array
                    );
                } catch ( \InvalidRequestException $e ) {
                    // Invalid request
                    $result_message = "Invalid request: {$e}";
                    $this->safe_wcs_log( $this->log_prefix . ': transfer Invalid request' . wp_json_encode( $result_message ) );
                    return array(
                        $success,
                        $result_message,
                        $transfer,
                        $shipping_transfer,
                        $other_transfer_info,
                        $product_extras_transfer_log_info_array
                    );
                } catch ( Exception $e ) {
                    if ( stristr( $e, 'no such destination' ) ) {
                        $account_number = substr( $e, strpos( $e, 'acct_' ) );
                        $account_number = explode( ' ', trim( $account_number ) );
                        $account_number = $account_number[0];
                        $result_message = "Ignored; cannot find account number: {$account_number}. Stripe replied 'No such destination.'";
                        $this->safe_wcs_log( $this->log_prefix . ': ' . wp_json_encode( $result_message ) );
                        return array(
                            $success,
                            $result_message,
                            $transfer,
                            $shipping_transfer,
                            $other_transfer_info,
                            $product_extras_transfer_log_info_array
                        );
                    } else {
                        $result_message = "Exception: {$e}";
                        $this->safe_wcs_log( $this->log_prefix . ': ' . wp_json_encode( $result_message ) );
                        return array(
                            $success,
                            $result_message,
                            $transfer,
                            $shipping_transfer,
                            $other_transfer_info,
                            $product_extras_transfer_log_info_array
                        );
                    }
                }
            } else {
                $result_message = 'Could not retreive order meta data.';
                $this->safe_wcs_log( $this->log_prefix . ': ' . wp_json_encode( $result_message ) );
                return array(
                    $success,
                    $result_message,
                    $transfer,
                    $shipping_transfer,
                    $other_transfer_info,
                    $product_extras_transfer_log_info_array
                );
            }
        }

        /**
         * Add "Retry Transfers" to WooCommerce order actions dropdown for orders
         * where transfers have not completed.
         */
        public function spp_add_retry_order_action( $actions, $order = null ) {
            if ( !$order ) {
                return $actions;
            }
            $is_done = $order->get_meta( 'is_transfer_process_done', true );
            $has_failed = $order->get_meta( 'spp_has_failed_transfers', true );
            if ( empty( $is_done ) || !empty( $has_failed ) ) {
                if ( $order->get_status() === 'processing' || $order->get_status() === 'completed' ) {
                    $actions['spp_retry_transfers'] = __( 'Retry Split Pay Transfers', 'bsd-split-pay-stripe-connect-woo' );
                }
            }
            return $actions;
        }

        /**
         * Handle the retry transfers order action.
         * Clears the existing transfer meta so the webhook handler will re-process.
         */
        public function spp_retry_transfers( $order ) {
            $order_id = $order->get_id();
            $order->delete_meta_data( 'is_transfer_process_done' );
            $order->delete_meta_data( 'spp_has_failed_transfers' );
            $order->save();
            $order->add_order_note( __( 'Split Pay: Transfer retry initiated. The plugin will re-attempt transfers for this order.', 'bsd-split-pay-stripe-connect-woo' ) );
            $data_keys = $this->stp_retrieve_keys();
            if ( !$data_keys ) {
                $order->add_order_note( __( 'Split Pay: Cannot retry transfers -- API keys not configured.', 'bsd-split-pay-stripe-connect-woo' ) );
                return;
            }
            $stripe_test_mode = isset( $data_keys['stripeInTestMode'] ) && $data_keys['stripeInTestMode'] === 'yes';
            $api_key = ( $stripe_test_mode ? $data_keys['secretTestKey'] ?? '' : $data_keys['secretLiveKey'] ?? '' );
            if ( empty( $api_key ) ) {
                $order->add_order_note( __( 'Split Pay: Cannot retry transfers -- API key not configured.', 'bsd-split-pay-stripe-connect-woo' ) );
                return;
            }
            try {
                require_once __DIR__ . '/vendor/autoload.php';
                $stripe = new \Stripe\StripeClient($api_key);
                $payment_intent_id = $order->get_meta( '_stripe_intent_id', true );
                if ( empty( $payment_intent_id ) ) {
                    $payment_intent_id = $order->get_transaction_id();
                }
                if ( !empty( $payment_intent_id ) ) {
                    $pi = $stripe->paymentIntents->retrieve( $payment_intent_id, array() );
                    $event = array(
                        'type'   => 'payment_intent.succeeded',
                        'object' => 'event',
                        'data'   => array(
                            'object' => json_decode( json_encode( $pi ), false ),
                        ),
                    );
                    $this->transfer_controller( wp_json_encode( $event ) );
                    $order->add_order_note( __( 'Split Pay: Transfer retry completed. Check order notes above for individual transfer results.', 'bsd-split-pay-stripe-connect-woo' ) );
                } else {
                    $order->add_order_note( __( 'Split Pay: Could not retry -- no Stripe payment intent found for this order.', 'bsd-split-pay-stripe-connect-woo' ) );
                }
            } catch ( \Exception $e ) {
                $order->add_order_note( sprintf( 
                    /* translators: %s = error message from the failed transfer retry. */
                    __( 'Split Pay: Transfer retry failed: %s', 'bsd-split-pay-stripe-connect-woo' ),
                    $e->getMessage()
                 ) );
                $this->safe_wcs_log( $this->log_prefix . ': Transfer retry failed for order ' . $order_id . ': ' . $e->getMessage() );
            }
        }

        /**
         * Handle WooCommerce refund by reversing associated Stripe transfers.
         *
         * @param int $order_id The order being refunded.
         * @param int $refund_id The refund ID.
         */
        public function spp_handle_refund( $order_id, $refund_id ) {
            global $wpdb;
            $order = wc_get_order( $order_id );
            $refund = wc_get_order( $refund_id );
            if ( !$order || !$refund ) {
                return;
            }
            $refund_total = abs( $refund->get_total() );
            $order_total = abs( $order->get_total() );
            if ( $refund_total <= 0 || $order_total <= 0 ) {
                return;
            }
            $refund_ratio = $refund_total / $order_total;
            $table_name = $wpdb->prefix . 'bsd_scsp_transfer_log';
            $transfers = $wpdb->get_results( $wpdb->prepare( "SELECT transfer_id, transfer_amount, transfer_destination FROM {$table_name} WHERE wc_order_id = %d AND transfer_id IS NOT NULL AND transfer_id != ''", $order_id ), ARRAY_A );
            if ( empty( $transfers ) ) {
                $order->add_order_note( __( 'Split Pay: No transfers found for this order to reverse.', 'bsd-split-pay-stripe-connect-woo' ) );
                return;
            }
            $data_keys = $this->stp_retrieve_keys();
            if ( !$data_keys ) {
                $order->add_order_note( __( 'Split Pay: Could not reverse transfers -- API keys not configured.', 'bsd-split-pay-stripe-connect-woo' ) );
                return;
            }
            $stripe_test_mode = isset( $data_keys['stripeInTestMode'] ) && $data_keys['stripeInTestMode'] === 'yes';
            $api_key = ( $stripe_test_mode ? $data_keys['secretTestKey'] ?? '' : $data_keys['secretLiveKey'] ?? '' );
            if ( empty( $api_key ) ) {
                $order->add_order_note( __( 'Split Pay: Could not reverse transfers -- API key not configured.', 'bsd-split-pay-stripe-connect-woo' ) );
                return;
            }
            require_once __DIR__ . '/vendor/autoload.php';
            $stripe = new \Stripe\StripeClient($api_key);
            $is_full_refund = $refund_total >= $order_total;
            $reversed_count = 0;
            $failed_count = 0;
            foreach ( $transfers as $tr ) {
                $transfer_id = $tr['transfer_id'];
                if ( empty( $transfer_id ) || strpos( $transfer_id, 'tr_' ) !== 0 ) {
                    continue;
                }
                try {
                    if ( $is_full_refund ) {
                        $stripe->transfers->createReversal( $transfer_id, array() );
                    } else {
                        $reversal_amount = round( $tr['transfer_amount'] * $refund_ratio * 100 );
                        if ( $reversal_amount < 1 ) {
                            continue;
                        }
                        $stripe->transfers->createReversal( $transfer_id, array(
                            'amount' => (int) $reversal_amount,
                        ) );
                    }
                    $reversed_count++;
                    $order->add_order_note( sprintf( 
                        /* translators: %1$s = Stripe transfer ID, %2$s = destination connected account ID. */
                        __( 'Split Pay: Transfer %1$s to %2$s reversed successfully.', 'bsd-split-pay-stripe-connect-woo' ),
                        $transfer_id,
                        $tr['transfer_destination']
                     ) );
                } catch ( \Exception $e ) {
                    $failed_count++;
                    $order->add_order_note( sprintf(
                        /* translators: %1$s = Stripe transfer ID, %2$s = destination connected account ID, %3$s = error message. */
                        __( 'Split Pay: Failed to reverse transfer %1$s to %2$s: %3$s', 'bsd-split-pay-stripe-connect-woo' ),
                        $transfer_id,
                        $tr['transfer_destination'],
                        $e->getMessage()
                    ) );
                    $this->safe_wcs_log( $this->log_prefix . ': Transfer reversal failed for ' . $transfer_id . ': ' . $e->getMessage() );
                }
            }
            if ( $reversed_count > 0 || $failed_count > 0 ) {
                $order->add_order_note( sprintf(
                    /* translators: %1$d = number of transfers reversed, %2$d = number of transfers that failed, %3$s = refund ratio percentage. */
                    __( 'Split Pay Refund Summary: %1$d transfer(s) reversed, %2$d failed. Refund ratio: %3$s%%', 'bsd-split-pay-stripe-connect-woo' ),
                    $reversed_count,
                    $failed_count,
                    round( $refund_ratio * 100, 2 )
                ) );
            }
        }

        /**
         * Log the transfer request
         */
        private function log_transfer_request(
            $event,
            $transfer,
            $shipping_transfer,
            $other_transfer_info,
            $product_extras_transfer_log_info_array
        ) {
            $event_info = $this->get_event_meta( $event );
            global $wpdb;
            if ( !empty( $transfer ) ) {
                foreach ( $transfer as $trk => $trv ) {
                    $this->safe_wcs_log( $this->log_prefix . '$trk --- : ' . wp_json_encode( $trk ) );
                    $this->safe_wcs_log( $this->log_prefix . '$trv --- : ' . wp_json_encode( $trv ) );
                    $this->safe_wcs_log( $this->log_prefix . '$other_transfer_info --- : ' . wp_json_encode( $other_transfer_info ) );
                    $transfer_info = $this->get_transfer_meta( $trv );
                    $transfer_type = 0;
                    $entered_transfer_value = 0;
                    $account_wise_tax = 0;
                    $item_total = 0;
                    $item_tax_total = 0;
                    $tax_transfer_type = '';
                    if ( isset( $other_transfer_info[$trk]['transfer_type'] ) && !empty( $other_transfer_info[$trk]['transfer_type'] ) ) {
                        $transfer_type = $other_transfer_info[$trk]['transfer_type'];
                    }
                    if ( isset( $other_transfer_info[$trk]['entered_transfer_value'] ) && !empty( $other_transfer_info[$trk]['entered_transfer_value'] ) ) {
                        $entered_transfer_value = $other_transfer_info[$trk]['entered_transfer_value'];
                    }
                    if ( isset( $other_transfer_info[$trk]['account_wise_tax'] ) && !empty( $other_transfer_info[$trk]['account_wise_tax'] ) ) {
                        $account_wise_tax = $other_transfer_info[$trk]['account_wise_tax'];
                    }
                    if ( isset( $other_transfer_info[$trk]['total_global_transfer_amount'] ) && !empty( $other_transfer_info[$trk]['total_global_transfer_amount'] ) ) {
                        $item_total = $other_transfer_info[$trk]['total_global_transfer_amount'];
                    }
                    if ( isset( $other_transfer_info[$trk]['product_price'] ) && !empty( $other_transfer_info[$trk]['product_price'] ) ) {
                        $item_total = $other_transfer_info[$trk]['product_price'];
                    }
                    if ( isset( $other_transfer_info[$trk]['global_tax_total'] ) && !empty( $other_transfer_info[$trk]['global_tax_total'] ) ) {
                        $item_tax_total = $other_transfer_info[$trk]['global_tax_total'];
                    }
                    if ( isset( $other_transfer_info[$trk]['tax_transfer_type'] ) && !empty( $other_transfer_info[$trk]['tax_transfer_type'] ) ) {
                        $tax_transfer_type = $other_transfer_info[$trk]['tax_transfer_type'];
                    }
                    if ( isset( $other_transfer_info[$trk]['product_tax_total'] ) && !empty( $other_transfer_info[$trk]['product_tax_total'] ) ) {
                        $item_tax_total = $other_transfer_info[$trk]['product_tax_total'];
                    }
                    if ( !$event_info || !$transfer_info ) {
                        return;
                    }
                    // If the transfer isn't related to this charge, exit
                    if ( $event_info['source_charge_id'] != $transfer_info['transfer_source_transaction'] ) {
                        return;
                    }
                    $table_prefix = $wpdb->prefix;
                    $table = $table_prefix . SPP_TRANSFER_LOG_TABLE;
                    if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) == $table ) {
                        $data = array(
                            'wc_order_id'            => $event_info['wc_order_id'],
                            'charge_amount'          => $event_info['charge_amount'],
                            'transfer_amount'        => $transfer_info['transfer_amount'],
                            'transfer_entered_value' => $entered_transfer_value,
                            'charge_id'              => $event_info['source_charge_id'],
                            'charge_date'            => $event_info['charge_created'],
                            'charge_description'     => $event_info['charge_description'],
                            'transfer_id'            => $transfer_info['transfer_id'],
                            'transfer_destination'   => $transfer_info['transfer_destination'],
                            'stripe_mode'            => $event_info['stripe_mode'],
                            'transfer_type'          => $transfer_type,
                            'transfer_tax_value'     => $account_wise_tax,
                            'item_total'             => $item_total,
                            'item_tax_total'         => $item_tax_total,
                            'tax_transfer_type'      => $tax_transfer_type,
                            'date_created'           => current_time( 'mysql', true ),
                            'date_modified'          => current_time( 'mysql', true ),
                        );
                        $wpdb->insert( $table, $data );
                    }
                }
            }
            if ( !empty( $shipping_transfer ) ) {
                $this->safe_wcs_log( $this->log_prefix . '$shipping_transfer --- : ' . wp_json_encode( $shipping_transfer ) );
                foreach ( $shipping_transfer as $trk => $trv ) {
                    $this->safe_wcs_log( $this->log_prefix . '$trv --- : ' . wp_json_encode( $trv ) );
                    $this->safe_wcs_log( $this->log_prefix . '$other_transfer_info --- : ' . wp_json_encode( $other_transfer_info ) );
                    $transfer_info = $this->get_transfer_meta( $trv );
                    $transfer_type = 0;
                    $entered_transfer_value = 0;
                    $account_wise_tax = 0;
                    $item_total = 0;
                    $item_tax_total = 0;
                    $tax_transfer_type = '';
                    if ( isset( $other_transfer_info[$trk]['shipping_transfer_type'] ) && !empty( $other_transfer_info[$trk]['shipping_transfer_type'] ) ) {
                        $transfer_type = $other_transfer_info[$trk]['shipping_transfer_type'];
                    }
                    if ( isset( $other_transfer_info[$trk]['entered_transfer_value'] ) && !empty( $other_transfer_info[$trk]['entered_transfer_value'] ) ) {
                        $entered_transfer_value = $other_transfer_info[$trk]['entered_transfer_value'];
                    }
                    if ( isset( $other_transfer_info[$trk]['account_wise_tax'] ) && !empty( $other_transfer_info[$trk]['account_wise_tax'] ) ) {
                        $account_wise_tax = $other_transfer_info[$trk]['account_wise_tax'];
                    }
                    if ( isset( $other_transfer_info[$trk]['total_transfer_global_shipping_amount'] ) && !empty( $other_transfer_info[$trk]['total_transfer_global_shipping_amount'] ) ) {
                        $item_total = $other_transfer_info[$trk]['total_transfer_global_shipping_amount'];
                    }
                    if ( isset( $other_transfer_info[$trk]['total_shipping_cost'] ) && !empty( $other_transfer_info[$trk]['total_shipping_cost'] ) ) {
                        $item_total = $other_transfer_info[$trk]['total_shipping_cost'];
                    }
                    if ( isset( $other_transfer_info[$trk]['total_shipping_tax'] ) && !empty( $other_transfer_info[$trk]['total_shipping_tax'] ) ) {
                        $item_tax_total = $other_transfer_info[$trk]['total_shipping_tax'];
                    }
                    if ( isset( $other_transfer_info[$trk]['tax_transfer_type'] ) && !empty( $other_transfer_info[$trk]['tax_transfer_type'] ) ) {
                        $tax_transfer_type = $other_transfer_info[$trk]['tax_transfer_type'];
                    }
                    if ( !$event_info || !$transfer_info ) {
                        return;
                    }
                    // If the transfer isn't related to this charge, exit
                    if ( $event_info['source_charge_id'] != $transfer_info['transfer_source_transaction'] ) {
                        return;
                    }
                    $table_prefix = $wpdb->prefix;
                    $table = $table_prefix . SPP_TRANSFER_LOG_TABLE;
                    if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) == $table ) {
                        $data = array(
                            'wc_order_id'            => $event_info['wc_order_id'],
                            'charge_amount'          => $event_info['charge_amount'],
                            'transfer_amount'        => $transfer_info['transfer_amount'],
                            'transfer_entered_value' => $entered_transfer_value,
                            'charge_id'              => $event_info['source_charge_id'],
                            'charge_date'            => $event_info['charge_created'],
                            'charge_description'     => $event_info['charge_description'],
                            'transfer_id'            => $transfer_info['transfer_id'],
                            'transfer_destination'   => $transfer_info['transfer_destination'],
                            'stripe_mode'            => $event_info['stripe_mode'],
                            'transfer_type'          => $transfer_type,
                            'transfer_tax_value'     => $account_wise_tax,
                            'item_total'             => $item_total,
                            'item_tax_total'         => $item_tax_total,
                            'tax_transfer_type'      => $tax_transfer_type,
                            'date_created'           => current_time( 'mysql', true ),
                            'date_modified'          => current_time( 'mysql', true ),
                        );
                        $wpdb->insert( $table, $data );
                    }
                }
            }
            if ( is_plugin_active( "product-extras-for-woocommerce/product-extras-for-woocommerce.php" ) ) {
                if ( !empty( $product_extras_transfer_log_info_array ) ) {
                    $this->safe_wcs_log( $this->log_prefix . ': product_extras_transfer_log_info_array ' . wp_json_encode( $product_extras_transfer_log_info_array ) );
                    foreach ( $product_extras_transfer_log_info_array as $petlki => $petlkv ) {
                        $product_extras_transfer = new \stdClass();
                        $transfer_type = 0;
                        $entered_transfer_value = 0;
                        // audit P1.4 — $account_wise_tax was inherited from the
                        // previous outer-foreach iteration; defensive init.
                        $account_wise_tax = 0;
                        if ( isset( $petlkv['product_extras_transfer'] ) && !empty( $petlkv['product_extras_transfer'] ) ) {
                            $product_extras_transfer = $petlkv['product_extras_transfer'];
                        }
                        if ( isset( $petlkv['transfer_type'] ) && !empty( $petlkv['transfer_type'] ) ) {
                            $transfer_type = $petlkv['transfer_type'];
                        }
                        if ( isset( $petlkv['entered_transfer_value'] ) && !empty( $petlkv['entered_transfer_value'] ) ) {
                            $entered_transfer_value = $petlkv['entered_transfer_value'];
                        }
                        $table_prefix = $wpdb->prefix;
                        $table = $table_prefix . 'bsd_scsp_transfer_log';
                        if ( $wpdb->get_var( "SHOW TABLES LIKE '{$table}'" ) == $table ) {
                            $data = array(
                                'wc_order_id'            => $event_info['wc_order_id'],
                                'charge_amount'          => $event_info['charge_amount'],
                                'transfer_amount'        => $entered_transfer_value,
                                'transfer_entered_value' => $entered_transfer_value,
                                'charge_id'              => $event_info['source_charge_id'],
                                'charge_date'            => $event_info['charge_created'],
                                'charge_description'     => $event_info['charge_description'],
                                'transfer_id'            => $product_extras_transfer->id,
                                'transfer_destination'   => $product_extras_transfer->destination,
                                'stripe_mode'            => $event_info['stripe_mode'],
                                'transfer_type'          => $transfer_type,
                                'transfer_tax_value'     => $account_wise_tax,
                                'item_total'             => 0,
                                'item_tax_total'         => 0,
                                'tax_transfer_type'      => "",
                                'date_created'           => current_time( 'mysql', true ),
                                'date_modified'          => current_time( 'mysql', true ),
                            );
                            $is_inserted = $wpdb->insert( $table, $data );
                            $this->safe_wcs_log( $this->log_prefix . ': is_inserted ' . wp_json_encode( $is_inserted ) );
                            $this->safe_wcs_log( $this->log_prefix . ': last_id ' . wp_json_encode( $wpdb->insert_id ) );
                        }
                    }
                }
            }
        }

        /**
         * Check if the webhook is for this site.
         *
         * The webhook is "for this site" iff it resolves to an order in the LOCAL
         * WooCommerce database — that is what keeps a multi-tenant Stripe app
         * (the same connected platform receiving events for many stores) from
         * processing another store's event. Every lookup below queries the local
         * WC DB only, so a foreign-site event still correctly returns false.
         *
         * 3.7.6 (sc-WEBHOOK-ORDER-RES): for `payment_intent.*` events, resolve the
         * order by what WC Stripe actually stores on the order AT CHECKOUT, before
         * the legacy source-id lookup. On a fresh Pending order WC Stripe has NOT
         * yet written `_stripe_source_id` (it does that on completion), but it HAS
         * written `_stripe_intent_id` at order creation — and get_source_id()
         * returns the PaymentIntent's `payment_method` (pm_…) for these events,
         * which never matches `_stripe_source_id`. The pre-3.7.6 single source-id
         * lookup therefore missed the order, this method returned false, and
         * check_for_webhook() exited 200 BEFORE WC Stripe's own prio-10 handler ran
         * — leaving the order stuck Pending (the order never completes when SPP is
         * active). We now try, in order, the intent id, then the latest charge,
         * then fall back to the original source-id lookup (legacy source/charge and
         * dispute/async-fail flows). First hit wins; only all-miss returns false.
         */
        private function webhook_for_this_site( $request_body ) {
            // 3.7.6 (sc-WEBHOOK-ORDER-RES): intent-id / charge-id resolution for
            // payment_intent.* events — matches the Pending order WC Stripe created
            // at checkout. Defensive about field presence and helper availability.
            $event_type = $this->get_event_type( $request_body );
            if ( is_string( $event_type ) && 0 === strpos( $event_type, 'payment_intent.' ) ) {
                $decoded = json_decode( $request_body );
                $object = ( is_object( $decoded ) && isset( $decoded->data->object ) && is_object( $decoded->data->object ) ? $decoded->data->object : null );
                if ( null !== $object ) {
                    // 1) PaymentIntent id (pi_…) -> _stripe_intent_id (set at order creation).
                    $intent_id = ( isset( $object->id ) && is_string( $object->id ) ? $object->id : '' );
                    if ( '' !== $intent_id && is_callable( array('\\WC_Stripe_Helper', 'get_order_by_intent_id') ) ) {
                        $order = \WC_Stripe_Helper::get_order_by_intent_id( $intent_id );
                        if ( $order ) {
                            $this->safe_wcs_log( $this->log_prefix . ' resolved order by intent_id : ' . wp_json_encode( $intent_id ) );
                            return true;
                        }
                    }
                    // 2) Latest charge (ch_…) -> _stripe_charge_id / _transaction_id (fallback).
                    $charge_id = ( isset( $object->latest_charge ) && is_string( $object->latest_charge ) ? $object->latest_charge : '' );
                    if ( '' !== $charge_id && is_callable( array('\\WC_Stripe_Helper', 'get_order_by_charge_id') ) ) {
                        $order = \WC_Stripe_Helper::get_order_by_charge_id( $charge_id );
                        if ( $order ) {
                            $this->safe_wcs_log( $this->log_prefix . ' resolved order by charge_id : ' . wp_json_encode( $charge_id ) );
                            return true;
                        }
                    }
                }
            }
            // 3) Legacy last resort: the original source-id lookup. Covers
            // charge.succeeded / source.chargeable, dispute events (charge id) and
            // async-failure events, and any payment_intent.* whose order WC Stripe
            // has already stamped with a matching _stripe_source_id.
            // Look for source id
            $source_id = $this->get_source_id( $request_body );
            if ( empty( $source_id ) ) {
                $this->safe_wcs_log( $this->log_prefix . ' source_id not found: ' . wp_json_encode( $source_id ) );
                return false;
            }
            $this->safe_wcs_log( $this->log_prefix . ' source_id : ' . wp_json_encode( $source_id ) );
            // Check with Woo to see if it's a valid order
            $order = \WC_Stripe_Helper::get_order_by_source_id( $source_id );
            // If yes return true
            if ( $order ) {
                return true;
            }
            $this->safe_wcs_log( $this->log_prefix . ' get_order_by_source_id not found: ' . wp_json_encode( $source_id ) );
            // If no return false
            return false;
        }

        public function bsd_variable_product_fields( $loop, $variation_data, $variation ) {
            ob_start();
            require SPP_PLUGIN_DIR . '/includes/admin/partials/bsd-variable-product-table.php';
            $variable_product_data_html = ob_get_clean();
            // The partial is trusted markup (form fields) whose dynamic values are
            // individually escaped at the point of output inside the template; it
            // contains <select>/<option>/<input> that wp_kses_post() would strip,
            // which would break the product editor. Output is therefore already safe.
            echo $variable_product_data_html;
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        }

        public function bsd_variable_product_fields_save( $variation_id, $i ) {
            /*
             * 3.7.4 form-presence + vendor-save gates (sc-7216 + sc-7201 backport
             * to variations).
             *
             * The variation save handler had two compounding bugs in 3.7.3 and
             * earlier:
             *
             *   (a) sc-7216 erasure: every variation save unconditionally wrote
             *       _bsd_spscwt_product_connected_account = [] and delete_post_meta()'d
             *       six other SPP variation meta keys whenever the corresponding
             *       $_POST[<key>][<variation_id>] entries were missing (which
             *       happens on every variation save where the SPP variation panel
             *       wasn't expanded, on AJAX variation saves that don't include
             *       the per-variation panel, on bulk-edit variation saves, and on
             *       max_input_vars truncation across all variations).
             *
             *   (b) sc-7201 vendor-erasure: even when the panel WAS rendered, the
             *       inner percent/amount gate (`empty($transfer_percentage[$bspcak])`)
             *       silently dropped any vendor selection saved without a
             *       percentage / amount value. The 3.7.3 fix removed this gate
             *       from the simple-product handler but never touched the
             *       variation handler. Variations have been silently losing
             *       data on every save with empty value fields since well before
             *       3.7.0.
             *
             * 3.7.4 fixes both. The form-presence marker
             * bsd_spp_variation_tab_rendered[<variation_id>] is emitted by
             * bsd-variable-product-table.php (see partial), and the marker gate
             * here short-circuits the handler when the SPP variation panel
             * wasn't on the form for THIS variation. The inner percent/amount
             * gate is removed in the collection loop below (matches the
             * sc-7201 fix in bsd_product_data_fields_save).
             *
             * Recovery for already-erased variation data is handled by the
             * sc-7216 migration in migration-374.php — the transfer log query
             * joins back to order line items via wc_get_order(), which returns
             * variation IDs for variable-product line items, so variations are
             * recovered through the same code path as simple products.
             */
            // phpcs:disable WordPress.Security.NonceVerification.Missing
            if ( empty( $_POST['bsd_spp_variation_tab_rendered'][$variation_id] ) ) {
                return;
            }
            // phpcs:enable WordPress.Security.NonceVerification.Missing
            $_bsd_spscwt_product_connected_account = ( isset( $_POST['_bsd_spscwt_product_connected_account'][$variation_id] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['_bsd_spscwt_product_connected_account'][$variation_id] ) ) : null );
            $_bsd_spscwt_product_type = ( isset( $_POST['_bsd_spscwt_product_type'][$variation_id] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['_bsd_spscwt_product_type'][$variation_id] ) ) : null );
            $transfer_percentage = ( isset( $_POST['_stripe_connect_split_pay_transfer_percentage'][$variation_id] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['_stripe_connect_split_pay_transfer_percentage'][$variation_id] ) ) : null );
            $_bsd_spscwt_product_amount = ( isset( $_POST['_bsd_spscwt_product_amount'][$variation_id] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['_bsd_spscwt_product_amount'][$variation_id] ) ) : null );
            /* shipping */
            $_bsd_spscwt_shipping_type = ( isset( $_POST['bsd_spscwt_shipping_type'][$variation_id] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['bsd_spscwt_shipping_type'][$variation_id] ) ) : null );
            $_bsd_prod_shipping_percentage = ( isset( $_POST['bsd_prod_shipping_percentage'][$variation_id] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['bsd_prod_shipping_percentage'][$variation_id] ) ) : null );
            $_bsd_prod_shipping_amount = ( isset( $_POST['bsd_prod_shipping_amount'][$variation_id] ) ? array_map( 'sanitize_text_field', wp_unslash( $_POST['bsd_prod_shipping_amount'][$variation_id] ) ) : null );
            // 3.7.4 sc-7201 backport to variations: persist the vendor
            // selection unconditionally. The pre-fix inner gate erased the
            // vendor when the percent / amount field was left empty.
            if ( isset( $_POST['_bsd_spscwt_product_connected_account'][$variation_id] ) ) {
                $prod_valid_connected_account = array();
                if ( !empty( $_bsd_spscwt_product_connected_account ) ) {
                    foreach ( $_bsd_spscwt_product_connected_account as $bspcak => $bspcav ) {
                        if ( !empty( $bspcav ) ) {
                            $prod_valid_connected_account[$bspcak] = $bspcav;
                        }
                    }
                }
                $prod_valid_connected_account = apply_filters( 'spp_before_save_variable_product_accounts', $prod_valid_connected_account, $variation_id );
                update_post_meta( $variation_id, '_bsd_spscwt_product_connected_account', $prod_valid_connected_account );
            }
            $_bsd_spscwt_product_type = apply_filters( 'spp_before_save_variable_product_types', $_bsd_spscwt_product_type, $variation_id );
            if ( empty( $_bsd_spscwt_product_type ) ) {
                delete_post_meta( $variation_id, '_bsd_spscwt_product_type' );
                delete_post_meta( $variation_id, '_stripe_connect_split_pay_transfer_percentage' );
                delete_post_meta( $variation_id, '_bsd_spscwt_product_amount' );
            } else {
                update_post_meta( $variation_id, '_bsd_spscwt_product_type', $_bsd_spscwt_product_type );
            }
            $transfer_percentage = apply_filters( 'spp_before_save_variable_product_transfer_percentage', $transfer_percentage, $variation_id );
            if ( $transfer_percentage === null ) {
                delete_post_meta( $variation_id, '_stripe_connect_split_pay_transfer_percentage' );
            } else {
                update_post_meta( $variation_id, '_stripe_connect_split_pay_transfer_percentage', $transfer_percentage );
            }
            $_bsd_spscwt_product_amount = apply_filters( 'spp_before_save_variable_product_transfer_amount', $_bsd_spscwt_product_amount, $variation_id );
            if ( empty( $_bsd_spscwt_product_amount ) ) {
                delete_post_meta( $variation_id, '_bsd_spscwt_product_amount' );
            } else {
                update_post_meta( $variation_id, '_bsd_spscwt_product_amount', $_bsd_spscwt_product_amount );
            }
            $_bsd_spscwt_shipping_type = apply_filters( 'spp_before_save_variable_product_shipping_transfer_type', $_bsd_spscwt_shipping_type, $variation_id );
            /* shipping */
            if ( empty( $_bsd_spscwt_shipping_type ) ) {
                delete_post_meta( $variation_id, '_bsd_spscwt_shipping_type' );
                delete_post_meta( $variation_id, '_bsd_prod_shipping_percentage' );
                delete_post_meta( $variation_id, '_bsd_prod_shipping_amount' );
            } else {
                update_post_meta( $variation_id, '_bsd_spscwt_shipping_type', $_bsd_spscwt_shipping_type );
            }
            $_bsd_prod_shipping_percentage = apply_filters( 'spp_before_save_variable_product_shipping_transfer_percentage', $_bsd_prod_shipping_percentage, $variation_id );
            if ( $_bsd_prod_shipping_percentage === null ) {
                delete_post_meta( $variation_id, '_bsd_prod_shipping_percentage' );
            } else {
                update_post_meta( $variation_id, '_bsd_prod_shipping_percentage', $_bsd_prod_shipping_percentage );
            }
            $_bsd_prod_shipping_amount = apply_filters( 'spp_before_save_variable_product_shipping_transfer_amount', $_bsd_prod_shipping_amount, $variation_id );
            if ( empty( $_bsd_prod_shipping_amount ) ) {
                delete_post_meta( $variation_id, '_bsd_prod_shipping_amount' );
            } else {
                update_post_meta( $variation_id, '_bsd_prod_shipping_amount', $_bsd_prod_shipping_amount );
            }
        }

        public function is_stripe_enabled_and_configured() {
            $enabled_configured = false;
            $stripe_test_api_secret_key = get_option( 'stripe_test_api_secret_key', false );
            $stripe_api_secret_key = get_option( 'stripe_api_secret_key', false );
            if ( !empty( $stripe_test_api_secret_key ) || !empty( $stripe_api_secret_key ) ) {
                $enabled_configured = true;
            }
            $woocommerce_stripe_settings = get_option( 'woocommerce_stripe_settings' );
            if ( !empty( $woocommerce_stripe_settings['enabled'] ) && $woocommerce_stripe_settings['enabled'] === 'yes' ) {
                $enabled_configured = true;
            }
            if ( function_exists( 'stripe_wc' ) ) {
                $pp_settings = get_option( 'woocommerce_stripe_api_settings' );
                if ( !empty( $pp_settings['secret_key_test'] ) || !empty( $pp_settings['secret_key_live'] ) ) {
                    $enabled_configured = true;
                }
            }
            if ( class_exists( 'FluentCart\\App\\Modules\\PaymentMethods\\StripeGateway\\StripeSettingsBase' ) ) {
                try {
                    $ssb = new \FluentCart\App\Modules\PaymentMethods\StripeGateway\StripeSettingsBase();
                    if ( $ssb->isActive() ) {
                        $enabled_configured = true;
                    }
                } catch ( \Throwable $e ) {
                    // FC not configured
                }
            }
            return $enabled_configured;
        }

    }

}
// class_exists check
function bsd_wcsc_get_amount(  $total, $currency = ''  ) {
    $zero_decimals = array(
        'BIF',
        'CLP',
        'DJF',
        'GNF',
        'JPY',
        'KMF',
        'KRW',
        'MGA',
        'PYG',
        'RWF',
        'VND',
        'VUV',
        'XAF',
        'XOF',
        'XPF'
    );
    $three_decimals = array('BHD', 'KWD', 'OMR');
    if ( empty( $currency ) ) {
        $currency = get_woocommerce_currency();
    }
    $currency = strtoupper( $currency );
    if ( in_array( $currency, $zero_decimals ) ) {
        // Zero-decimal currencies: amount is already in the smallest unit.
    } elseif ( in_array( $currency, $three_decimals ) ) {
        $total *= 1000;
    } else {
        $total *= 100;
    }
    return round( $total );
}
