<?php
/**
 * PeachPay ConvesioPay Unified Gateway
 * Handles all payment methods (Card, Apple Pay, Google Pay, BTCPay) through a single ConvesioPay option
 *
 * @package PeachPay
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

require_once PEACHPAY_ABSPATH . 'core/abstract/class-peachpay-payment-gateway.php';

/**
 * ConvesioPay Unified Gateway
 */
class PeachPay_ConvesioPay_Unified_Gateway extends PeachPay_Payment_Gateway {
	/**
	 * Track whether the renewal hook has been registered.
	 *
	 * @var bool
	 */
	private static $renewal_hook_registered = false;

	/**
	 * Track if gateway was properly initialized
	 */
	private $initialized = false;
	
	/**
	 * Gateway settings
	 */
	public $settings = array();
	
	/**
	 * Gateway properties
	 */
	public $id;
	public $title;
	public $description;
	public $method_title;
	public $method_description;
	public $icon;
	public $has_fields;
	public $supports;
	public $enabled;
	
	/**
	 * Constructor.
	 */
	public function __construct() {
		$this->id                    = 'peachpay_convesiopay_unified';
		// Get customizable label from option, default to 'Credit Card'
		$this->title                 = get_option( 'peachpay_convesiopay_unified_gateway_label', 'Credit Card' );
		// $this->description           = 'Pay with card, crypto, or digital wallets via ConvesioPay.';
		$this->method_title          = sprintf( __( '%s (PeachPay)', 'peachpay-for-woocommerce' ), 'ConvesioPay' );
		$this->method_description    = 'Accept all payment methods through ConvesioPay unified checkout. Note: ConvesioPay only supports USD currency';
		$this->has_fields            = true;
		$this->supports              = array(
			'products',
			'refunds',
			'blocks',
			'tokenization',
			'subscriptions',
			'multiple_subscriptions',
			'subscription_cancellation',
			'subscription_suspension',
			'subscription_reactivation',
			'subscription_amount_changes',
			'subscription_date_changes',
			'subscription_payment_method_change_customer',
		);

		// Set up basic icon - icons are handled via get_icon() method on frontend checkout
		$this->icon = '';
		$this->icons = array();

		// Set payment provider info
		$this->payment_provider = 'ConvesioPay';

		// Restrict to USD currency only
		$this->currencies = array( 'USD' );

		// Call parent constructor (this loads all other settings via init_settings())
		parent::__construct();

		// After parent loads settings, check if title is empty and restore default if needed
		if ( empty( $this->title ) ) {
			$this->title = get_option( 'peachpay_convesiopay_unified_gateway_label', 'Credit Card' );
		}
		
		// Add hooks
		add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
		add_action( 'woocommerce_thankyou', array( $this, 'hide_order_actions_on_thankyou' ), 5 );

		add_filter( 'woocommerce_gateway_title', array( $this, 'override_test_mode_title' ), 10, 2 );
		
		// Additional CSS hiding method
		add_action( 'admin_head', array( $this, 'hide_gateway_with_css' ) );
		
		// Subscription renewal support - route to Card Gateway.
		$this->register_subscription_renewal_hook();

		// Hook into checkout update to read selected method from POST
		add_action( 'woocommerce_checkout_update_order_review', array( $this, 'store_selected_convesiopay_method' ) );
		// Also sync method on final checkout submit to avoid fee/method race conditions.
		add_action( 'woocommerce_checkout_process', array( $this, 'sync_selected_convesiopay_method_on_checkout_process' ) );

		// Enable gateway by default if not set and ConvesioPay is connected
		if ( PeachPay_ConvesioPay_Integration::connected() ) {
			if ( !isset( $this->settings['enabled'] ) || $this->settings['enabled'] !== 'yes' ) {
				$this->enabled = 'yes';

				// Also update the database setting to ensure admin interface shows it as enabled
				$this->settings['enabled'] = 'yes';
				$option_name = 'woocommerce_' . $this->id . '_settings';
				update_option( $option_name, $this->settings );
			}
		}
		
		$this->init_form_fields();
		// Mark as initialized
		$this->initialized = true;
	}

	/**
	 * Register subscription renewal hook once per request.
	 */
	private function register_subscription_renewal_hook() {
		if ( self::$renewal_hook_registered ) {
			return;
		}
		add_action(
			'woocommerce_scheduled_subscription_payment_' . $this->id,
			array( $this, 'handle_subscription_renewal_payment' ),
			10,
			2
		);
		self::$renewal_hook_registered = true;
	}

	/**
	 * Handle scheduled subscription payment for unified ConvesioPay gateway.
	 *
	 * @param float    $renewal_total Renewal amount.
	 * @param WC_Order $renewal_order Renewal order.
	 */
	public function handle_subscription_renewal_payment( $renewal_total, $renewal_order ) {
		if ( ! function_exists( 'wcs_get_subscriptions_for_renewal_order' ) ) {
			peachpay_log(
				'error',
				'ConvesioPay Unified Subscription renewal failed - wcs_get_subscriptions_for_renewal_order() unavailable.',
				array(
					'event'     => 'payments.convesiopay_gateway.subscription.renewal.failed',
					'component' => 'payments',
					'feature'   => 'convesiopay_gateway',
					'operation' => 'subscription.renewal',
					'outcome'   => 'failed',
					'line'     => __LINE__,
					'function' => __FUNCTION__,
					'file'     => __FILE__,
					'class'    => __CLASS__,
					'method'   => __METHOD__,
					'data'     => array(
						'renewal_total' => $renewal_total,
					),
				)
			);
			return;
		}

		$gateways = WC()->payment_gateways->payment_gateways();
		if ( ! isset( $gateways['peachpay_convesiopay_card'] ) ) {
			$renewal_order->update_status( 'failed', __( 'ConvesioPay Card gateway not found.', 'peachpay-for-woocommerce' ) );
			return;
		}

		$subscriptions = wcs_get_subscriptions_for_renewal_order( $renewal_order );
		$subscription  = array_pop( $subscriptions );
		if ( ! $subscription ) {
			peachpay_log(
				'error',
				'ConvesioPay Unified Subscription renewal failed - no subscription found for renewal order.',
				array(
					'event'     => 'payments.convesiopay_gateway.subscription.renewal.failed',
					'component' => 'payments',
					'feature'   => 'convesiopay_gateway',
					'operation' => 'subscription.renewal',
					'outcome'   => 'failed',
					'line'     => __LINE__,
					'function' => __FUNCTION__,
					'file'     => __FILE__,
					'class'    => __CLASS__,
					'method'   => __METHOD__,
					'data'     => array(
						'renewal_total' => $renewal_total,
					),
				)
			);
			return;
		}

		$parent_order = wc_get_order( $subscription->get_parent_id() );
		if ( ! $parent_order ) {
			peachpay_log(
				'error',
				'ConvesioPay Unified Subscription renewal failed - parent order not found.',
				array(
					'event'     => 'payments.convesiopay_gateway.subscription.renewal.failed',
					'component' => 'payments',
					'feature'   => 'convesiopay_gateway',
					'operation' => 'subscription.renewal',
					'outcome'   => 'failed',
					'line'     => __LINE__,
					'function' => __FUNCTION__,
					'file'     => __FILE__,
					'class'    => __CLASS__,
					'method'   => __METHOD__,
				)
			);
			return;
		}

		peachpay_log(
			'debug',
			'ConvesioPay Unified Subscription renewal debug - delegating to card gateway.',
			array(
				'event'     => 'payments.convesiopay_gateway.subscription.renewal.debug',
				'component' => 'payments',
				'feature'   => 'convesiopay_gateway',
				'operation' => 'subscription.renewal',
				'outcome'   => 'debug',
				'line'     => __LINE__,
				'function' => __FUNCTION__,
				'file'     => __FILE__,
				'class'    => __CLASS__,
				'method'   => __METHOD__,
				'data'     => array(
					'renewal_total' => $renewal_total,
				),
			)
		);
		$gateways['peachpay_convesiopay_card']->process_subscription_renewal( $parent_order, $renewal_order, $renewal_total, $subscription );
		peachpay_log(
			'debug',
			'ConvesioPay Unified Subscription renewal debug - card gateway delegation completed.',
			array(
				'event'     => 'payments.convesiopay_gateway.subscription.renewal.debug',
				'component' => 'payments',
				'feature'   => 'convesiopay_gateway',
				'operation' => 'subscription.renewal',
				'outcome'   => 'debug',
				'line'     => __LINE__,
				'function' => __FUNCTION__,
				'file'     => __FILE__,
				'class'    => __CLASS__,
				'method'   => __METHOD__,
			)
		);
	}

	/**
	 * Initialize gateway form fields.
	 */
	public function init_form_fields() {
		// Call parent method to get standard fields
		parent::init_form_fields();

		// Remove fee settings from unified gateway - fees are configured on individual gateways
		// (Card, Apple Pay, BTCPay) and will be read from them dynamically
		unset( $this->form_fields['fees_enabled'] );
		unset( $this->form_fields['fee_type'] );
		unset( $this->form_fields['fee_amount'] );
		unset( $this->form_fields['fee_reason'] );
		unset( $this->form_fields['fee_threshold_min'] );
		unset( $this->form_fields['fee_threshold_max'] );
	}

	/**
	 * Override should_refresh_checkout to check if any individual gateway has fees enabled.
	 *
	 * @return string 'true' or 'false'
	 */
	protected function should_refresh_checkout() {
		// Check if any of the individual ConvesioPay gateways have fees enabled
		$card_gateway     = $this->get_individual_gateway( 'card' );
		$applepay_gateway = $this->get_individual_gateway( 'applepay' );
		$googlepay_gateway = $this->get_individual_gateway( 'googlepay' );
		$btcpay_gateway   = $this->get_individual_gateway( 'btcpay' );

		if ( ( $card_gateway && $card_gateway->get_option( 'fees_enabled' ) === 'yes' ) ||
			 ( $applepay_gateway && $applepay_gateway->get_option( 'fees_enabled' ) === 'yes' ) ||
			 ( $googlepay_gateway && $googlepay_gateway->get_option( 'fees_enabled' ) === 'yes' ) ||
			 ( $btcpay_gateway && $btcpay_gateway->get_option( 'fees_enabled' ) === 'yes' ) ) {
			return 'true';
		}
		return 'false';
	}

	/**
	 * Get an individual ConvesioPay gateway instance.
	 *
	 * @param string $method Payment method type (card, applepay, googlepay, btcpay).
	 * @return WC_Payment_Gateway|null Gateway instance or null.
	 */
	protected function get_individual_gateway( $method ) {
		$gateway_ids = array(
			'card'     => 'peachpay_convesiopay_card',
			'applepay' => 'peachpay_convesiopay_applepay',
			'googlepay' => 'peachpay_convesiopay_googlepay',
			'btcpay'   => 'peachpay_convesiopay_btcpay',
		);

		$gateway_id = isset( $gateway_ids[ $method ] ) ? $gateway_ids[ $method ] : null;
		if ( ! $gateway_id ) {
			return null;
		}

		return peachpay_get_payment_gateway( $gateway_id );
	}

	/**
	 * Check whether an individual ConvesioPay gateway is enabled.
	 *
	 * @param WC_Payment_Gateway|null $gateway Gateway instance.
	 * @return bool
	 */
	protected function is_individual_gateway_enabled( $gateway ) {
		if ( ! $gateway ) {
			return false;
		}

		$enabled_option   = $gateway->get_option( 'enabled', 'no' );
		$enabled_property = $gateway->enabled ?? 'no';

		return 'yes' === $enabled_option || 'yes' === $enabled_property;
	}

	/**
	 * Check whether an individual ConvesioPay gateway should show in native checkout.
	 *
	 * @param WC_Payment_Gateway|null $gateway Gateway instance.
	 * @return bool
	 */
	protected function is_individual_gateway_visible_in_native_checkout( $gateway ) {
		if ( ! $gateway ) {
			return false;
		}

		return 'express_checkout_only' !== $gateway->get_option( 'active_locations', 'default' );
	}

	/**
	 * Check whether an individual ConvesioPay gateway is active for native checkout.
	 *
	 * @param WC_Payment_Gateway|null $gateway Gateway instance.
	 * @return bool
	 */
	protected function is_individual_gateway_active_for_native_checkout( $gateway ) {
		return $this->is_individual_gateway_enabled( $gateway ) && $this->is_individual_gateway_visible_in_native_checkout( $gateway );
	}

	/**
	 * Check whether an individual ConvesioPay gateway should show in PeachPay Express Checkout.
	 *
	 * @param WC_Payment_Gateway|null $gateway Gateway instance.
	 * @return bool
	 */
	protected function is_individual_gateway_active_for_peachpay_express_checkout( $gateway ) {
		if ( ! $gateway ) {
			return false;
		}

		return $this->is_individual_gateway_enabled( $gateway ) && 'checkout_page_only' !== $gateway->get_option( 'active_locations', 'default' );
	}

	/**
	 * Get ConvesioPay SDK disabled payment method flags for native checkout.
	 *
	 * @return array
	 */
	protected function get_disabled_payment_methods() {
		return array(
			'cards'     => ! $this->is_individual_gateway_active_for_native_checkout( $this->get_individual_gateway( 'card' ) ),
			'applePay'  => ! $this->is_individual_gateway_active_for_native_checkout( $this->get_individual_gateway( 'applepay' ) ),
			'googlePay' => ! $this->is_individual_gateway_active_for_native_checkout( $this->get_individual_gateway( 'googlepay' ) ),
		);
	}

	/**
	 * Get the selected payment method type from session or request.
	 *
	 * @return string Payment method type (card, applepay, googlepay, btcpay) or empty string.
	 */
	protected function get_selected_convesiopay_method() {
		$method = null;
		$source = 'default';

		// Check POST data first (from checkout update / Classic checkout)
		// phpcs:ignore WordPress.Security.NonceVerification.Missing
		if ( isset( $_POST['convesiopay_selected_method'] ) && ! empty( $_POST['convesiopay_selected_method'] ) ) {
			// phpcs:ignore WordPress.Security.NonceVerification.Missing
			$method = $this->normalize_convesiopay_method( wp_unslash( $_POST['convesiopay_selected_method'] ) );
			$source = 'POST';
		}

		// Check for Blocks checkout - look in extensions data
		// phpcs:ignore WordPress.Security.NonceVerification.Missing
		if ( ! $method && isset( $_POST['extensions']['peachpay_convesiopay_unified']['selected_method'] ) ) {
			// phpcs:ignore WordPress.Security.NonceVerification.Missing
			$method = $this->normalize_convesiopay_method( wp_unslash( $_POST['extensions']['peachpay_convesiopay_unified']['selected_method'] ) );
			$source = 'POST extensions';
		}

		// Check WooCommerce session
		if ( ! $method && WC()->session ) {
			$session_method = WC()->session->get( 'convesiopay_selected_method' );
			if ( $session_method ) {
				$method = $this->normalize_convesiopay_method( $session_method );
				$source = 'session';
			}
		}

		// Default to 'card' if nothing selected
		if ( ! $method ) {
			$method = 'card';
			$source = 'default';
		}

		return $method;
	}

	/**
	 * Store selected ConvesioPay method in session during checkout update.
	 *
	 * @param string $posted_data Checkout posted data string.
	 */
	public function store_selected_convesiopay_method( $posted_data ) {
		// Parse the posted data string
		$parsed_data = array();
		if ( is_string( $posted_data ) ) {
			parse_str( $posted_data, $parsed_data );
		}

		// Store the selected method in session
		if ( isset( $parsed_data['convesiopay_selected_method'] ) && WC()->session ) {
			$method = sanitize_text_field( $parsed_data['convesiopay_selected_method'] );
			WC()->session->set( 'convesiopay_selected_method', $method );

		}
	}

	/**
	 * Sync selected ConvesioPay method during final checkout submission.
	 *
	 * Some checkout flows can skip update-order-review timing, so we also
	 * persist the method at checkout process time to keep fee calculation
	 * and payment routing in sync.
	 */
	public function sync_selected_convesiopay_method_on_checkout_process() {
		if ( ! WC()->session ) {
			return;
		}

		$payment_method = isset( $_POST['payment_method'] ) ? sanitize_text_field( wp_unslash( $_POST['payment_method'] ) ) : '';
		if ( 'peachpay_convesiopay_unified' !== $payment_method ) {
			return;
		}

		$selected_method = '';

		if ( isset( $_POST['convesiopay_selected_method'] ) && ! empty( $_POST['convesiopay_selected_method'] ) ) {
			$selected_method = $this->normalize_convesiopay_method( wp_unslash( $_POST['convesiopay_selected_method'] ) );
		}

		if ( empty( $selected_method ) && isset( $_POST['payment_method_data'] ) ) {
			$payment_method_data = is_string( $_POST['payment_method_data'] )
				? json_decode( stripslashes( $_POST['payment_method_data'] ), true )
				: $_POST['payment_method_data'];

			if ( is_array( $payment_method_data ) ) {
				$selected_method = $this->normalize_convesiopay_method(
					$payment_method_data['convesiopay_selected_method']
					?? $payment_method_data['selected_method']
					?? $payment_method_data['selectedMethod']
					?? $payment_method_data['method']
					?? $payment_method_data['payment_method']
					?? $payment_method_data['paymentMethodType']
					?? $payment_method_data['payment_method_type']
					?? $payment_method_data['paymentMethod']
					?? $payment_method_data['paymentmethod']
					?? ''
				);
			}
		}

		if ( in_array( $selected_method, array( 'card', 'applepay', 'googlepay', 'btcpay' ), true ) ) {
			$previous_method = WC()->session->get( 'convesiopay_selected_method' );
			WC()->session->set( 'convesiopay_selected_method', $selected_method );
			if ( $previous_method !== $selected_method ) {
				peachpay_log(
					'debug',
					'Payments: Checkout method sync debug.',
					array(
						'event'     => 'payments.convesiopay_gateway.checkout.method_sync.debug',
						'component' => 'payments',
						'feature'   => 'convesiopay_gateway',
						'operation' => 'checkout.method_sync',
						'outcome'   => 'debug',
						'method'    => __METHOD__,
						'line'      => __LINE__,
						'data'      => array(
							'selected_method' => $selected_method,
							'previous_method' => $previous_method,
						),
					)
				);
			}
		}
	}

	/**
	 * Returns whether unified gateway is currently selected for fee calculation.
	 *
	 * @return bool
	 */
	protected function is_unified_gateway_selected_for_fee() {
		$selected_gateway = '';
		if ( isset( $_POST['payment_method'] ) ) {
			$selected_gateway = sanitize_text_field( wp_unslash( $_POST['payment_method'] ) );
		}

		if ( empty( $selected_gateway ) && WC()->session ) {
			$selected_gateway = WC()->session->get( 'chosen_payment_method' );
		}

		return 'peachpay_convesiopay_unified' === $selected_gateway;
	}

	/**
	 * Override calculate_payment_method_fee to read fees from individual gateways.
	 *
	 * @param WC_Cart $cart Current cart.
	 */
	public function calculate_payment_method_fee( $cart ) {
		if ( ! $this->is_unified_gateway_selected_for_fee() ) {
			if ( WC()->session ) {
				WC()->session->set( 'convesiopay_selected_method', '' );
			}
			return;
		}

		$selected_method = $this->get_selected_convesiopay_method();
		// Get the individual gateway based on selected method
		$individual_gateway = $this->get_individual_gateway( $selected_method );
		if ( ! $individual_gateway ) {
			// Fallback to card gateway
			$individual_gateway = $this->get_individual_gateway( 'card' );
		}

		if ( ! $individual_gateway ) {
			return;
		}

		// Use the individual gateway's fee calculation
		$individual_gateway->calculate_payment_method_fee( $cart );
	}

	/**
	 * Get ConvesioPay configuration
	 *
	 * @return array
	 */
	protected function get_convesiopay_config() {
		return PeachPay_ConvesioPay_Integration::config();
	}

	/**
	 * Check if gateway is available at checkout.
	 *
	 * @param bool $skip_cart_check Skip cart check.
	 */
	public function is_available( $skip_cart_check = false ) {
		// Basic enabled check
		if ( ! $this->enabled || 'no' === $this->enabled ) {
			return false;
		}

		// Check if ConvesioPay is connected
		if ( ! PeachPay_ConvesioPay_Integration::connected() ) {
			$availability_details        = new stdClass();
			$availability_details->setup = array(
				'explanation' => sprintf(
					__( '<b>%s</b> requires ConvesioPay to be connected. Please connect ConvesioPay in the PeachPay settings.', 'peachpay-for-woocommerce' ),
					$this->get_title()
				),
			);
			$this->availability_details  = $availability_details;
			return false;
		}

		// Check if ConvesioPay is properly configured
		$config = $this->get_convesiopay_config();
		if ( empty( $config ) ) {
			$availability_details        = new stdClass();
			$availability_details->setup = array(
				'explanation' => sprintf(
					__( '<b>%s</b> is not properly configured. Please check your ConvesioPay settings.', 'peachpay-for-woocommerce' ),
					$this->get_title()
				),
			);
			$this->availability_details  = $availability_details;
			return false;
		}

		// Check for required configuration keys
		$has_api_key     = ! empty( $config['api_key'] );
		$has_integration = ! empty( $config['integration_name'] );

		if ( ! $has_api_key || ! $has_integration ) {
			$availability_details        = new stdClass();
			$availability_details->setup = array(
				'explanation' => sprintf(
					__( '<b>%s</b> requires API key and integration name to be configured.', 'peachpay-for-woocommerce' ),
					$this->get_title()
				),
			);
			$this->availability_details  = $availability_details;
			return false;
		}

		// Check if at least one payment method is active for the current checkout context.
		$active_methods = defined( 'PEACHPAY_CHECKOUT' ) ? $this->get_peachpay_express_checkout_payment_methods() : $this->get_active_payment_methods();
		if ( empty( $active_methods ) ) {
			return false; // Hide gateway if no payment methods are active
		}

		// Call parent to check currency (USD only), location (Express vs Checkout), min/max, countries, test mode, etc.
		// Parent will also set $this->availability_details with detailed explanations
		$parent_result = parent::is_available( $skip_cart_check );


		return $parent_result;
	}

	/**
	 * Ensure transaction id is present before base validation runs.
	 *
	 * @return bool
	 */
	public function validate_fields() {
		$transaction_id = $this->get_transaction_id_from_request();

		if ( empty( $transaction_id ) ) {
			$transaction_id = $this->create_fallback_transaction_id();
		}

		if ( ! empty( $transaction_id ) ) {
			$transaction_id = sanitize_text_field( $transaction_id );
			$this->persist_transaction_id( $transaction_id );
			// phpcs:ignore WordPress.Security.NonceVerification.Missing
			$_POST['peachpay_transaction_id'] = $transaction_id;
			$this->inject_transaction_id_into_payment_method_data( $transaction_id );
		}

		return parent::validate_fields();
	}

	/**
	 * Inject transaction id into payment_method_data for Blocks checkout.
	 * Ensures downstream code (e.g. extract_unified_payment_data) sees the id.
	 *
	 * @param string $transaction_id The transaction id.
	 */
	private function inject_transaction_id_into_payment_method_data( $transaction_id ) {
		if ( empty( $transaction_id ) ) {
			return;
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Missing
		if ( ! isset( $_POST['payment_method_data'] ) ) {
			return;
		}
		// phpcs:ignore WordPress.Security.NonceVerification.Missing
		$raw = $_POST['payment_method_data'];
		$data = is_string( $raw ) ? json_decode( stripslashes( $raw ), true ) : $raw;
		if ( ! is_array( $data ) ) {
			return;
		}
		$data['peachpay_transaction_id'] = $transaction_id;
		// phpcs:ignore WordPress.Security.NonceVerification.Missing
		$_POST['payment_method_data'] = wp_json_encode( $data );
	}

	/**
	 * Persist transaction id in both PHP and WooCommerce sessions.
	 *
	 * @param string $transaction_id The transaction id.
	 */
	private function persist_transaction_id( $transaction_id ) {
		if ( empty( $transaction_id ) ) {
			return;
		}

		if ( session_status() === PHP_SESSION_ACTIVE ) {
			// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
			$_SESSION['peachpay_transaction_id'] = $transaction_id;
		}

		if ( function_exists( 'WC' ) && WC()->session ) {
			WC()->session->set( 'peachpay_transaction_id', $transaction_id );
		}
	}

	/**
	 * Process payment.
	 *
	 * @param int $order_id Order ID.
	 * @return array
	 */
	public function process_payment( $order_id ) {
		$order = wc_get_order( $order_id );

		if ( ! $order ) {
			wc_add_notice( __( 'Order not found.', 'peachpay-for-woocommerce' ), 'error' );
			return array(
				'result'   => 'failure',
				'messages' => 'Order not found.',
			);
		}

		// Check if this order has already been processed to prevent reuse
		if ( ! $order->needs_payment() ) {
			wc_add_notice( __( 'Order has already been processed.', 'peachpay-for-woocommerce' ), 'error' );
			return array(
				'result'   => 'failure',
				'messages' => 'Order has already been processed.',
			);
		}

		// Check if order already has any transaction attempts
		$transaction_id = $order->get_transaction_id();

		// Check if order has any payment-related meta data indicating previous processing
		// Note: _peachpay_transaction_id is set during transaction creation, not completion, so we don't check it
		$payment_meta_keys = array(
			'_convesiopay_payment_id',
			'_convesiopay_payment_method',
			'_convesiopay_payment_status'
		);

		foreach ( $payment_meta_keys as $meta_key ) {
			$meta_value = $order->get_meta( $meta_key );
		}

		// Check if order already has a payment method assigned (except our unified method)
		$existing_payment_method = $order->get_payment_method();
		if ( $existing_payment_method && $existing_payment_method !== 'peachpay_convesiopay_unified' ) {
			wc_add_notice(
				sprintf(
					/* translators: %s: payment method ID */
					__( 'Order is already assigned to payment method: %s', 'peachpay-for-woocommerce' ),
					$existing_payment_method
				),
				'error'
			);
			return array(
				'result'   => 'failure',
				'messages' => 'Order is already assigned to payment method: ' . $existing_payment_method,
			);
		}
		
		try {

			// Unified payment data extraction for both blocks and classic checkout (DO THIS FIRST)
			$payment_data = $this->extract_unified_payment_data();

			if ( empty( $payment_data ) ) {
				peachpay_log( 'error', 'ConvesioPay Unified: Empty payment data in process_payment for order ' . $order->get_order_number() );
				throw new Exception( 'Payment data not provided' );
			}

			peachpay_log(
				'info',
				'ConvesioPay Unified: Extracted payment data for order ' . $order->get_order_number() . ' | ' . wp_json_encode(
					array(
						'payment_method_type' => $payment_data['payment_method_type'] ?? '',
						'paymentMethod'       => $payment_data['paymentMethod'] ?? $payment_data['paymentmethod'] ?? '',
						'status'              => $payment_data['status'] ?? '',
						'amount'              => $payment_data['amount'] ?? '',
						'currency'            => $payment_data['currency'] ?? '',
						'has_token'           => ! empty( $payment_data['convesiopay_payment_token'] ),
						'token_length'        => isset( $payment_data['convesiopay_payment_token'] ) ? strlen( (string) $payment_data['convesiopay_payment_token'] ) : 0,
						'token_prefix'        => isset( $payment_data['convesiopay_payment_token'] ) ? substr( (string) $payment_data['convesiopay_payment_token'], 0, 8 ) : '',
					)
				)
			);

			// Enhanced payment method detection based on ConvesioPay events (must be done EARLY)
			$detected_method = $this->detect_payment_method( $payment_data );
			peachpay_log( 'info', 'ConvesioPay Unified: Detected payment method for order ' . $order->get_order_number() . ' => ' . $detected_method );

			// This guard enforces native checkout visibility only. Accelerated Checkout
			// and PeachPay Express Checkout have separate availability semantics.
			$is_accelerated_checkout = isset( $_POST['convesiopay_checkout_context'] ) && 'accelerated' === sanitize_key( wp_unslash( $_POST['convesiopay_checkout_context'] ) );
			$is_peachpay_express_checkout = defined( 'PEACHPAY_CHECKOUT' );
			if ( ! $is_accelerated_checkout && ! $is_peachpay_express_checkout ) {
				$active_methods    = $this->get_active_payment_methods();
				$active_method_key = 'btcpay' === $detected_method ? 'crypto' : $detected_method;
				if ( ! in_array( $active_method_key, $active_methods, true ) ) {
					throw new Exception( __( 'The selected ConvesioPay payment method is not available on this checkout.', 'peachpay-for-woocommerce' ) );
				}
			}

			if ( 'card' === $detected_method ) {
				$this->log_card_retry_after_token_invalidation( $order, $payment_data, $detected_method );
			}

			// For BTCPay payments, skip parent API call entirely and go straight to BTCPay gateway
			// This prevents unnecessary API calls that cause 503 errors
			if ( $detected_method === 'btcpay' ) {
				// Directly redirect to BTCPay gateway without calling parent API
				return $this->redirect_to_btcpay_gateway( $order, $payment_data );
			}

			// For non-BTCPay payments, continue with normal processing
			// Get PeachPay session and transaction data (following card gateway pattern)
			$session_id = PeachPay_Payment::get_session();
			$transaction_id = $this->get_transaction_id_from_request();
			
			// Check if we have the required transaction ID
			if ( empty( $transaction_id ) ) {
				// Try to create a transaction ID as a fallback
				$transaction_id = $this->create_fallback_transaction_id();
				
				if ( empty( $transaction_id ) ) {
					wc_add_notice( __( 'Missing required field "peachpay_transaction_id". Please refresh the page and try again.', 'peachpay-for-woocommerce' ), 'error' );
					return array(
						'result'   => 'failure',
						'redirect' => '',
					);
				}
			}
			
			// Call parent process_payment to handle PeachPay transaction creation (following card gateway pattern)
			try {
				$parent_result = parent::process_payment( $order_id );
				
				// The parent may return a WC_Order object or an array, handle both cases
				if ( is_object( $parent_result ) ) {
					// Parent returned WC_Order object, continue with our processing
					$order = $parent_result;
				} elseif ( is_array( $parent_result ) && isset( $parent_result['result'] ) && $parent_result['result'] !== 'success' ) {
					// Parent returned failure array
					if ( isset( $parent_result['messages'] ) && is_string( $parent_result['messages'] ) && ! empty( $parent_result['messages'] ) ) {
						wc_add_notice( $parent_result['messages'], 'error' );
					} else {
						wc_add_notice( __( 'Payment processing failed. Please try again.', 'peachpay-for-woocommerce' ), 'error' );
					}
					return $parent_result;
				}
				// If parent returned success array or order object, continue
			} catch ( Exception $parent_exception ) {
				// Continue without parent processing if it fails
			}
			
			// Get session and transaction data before using them
			$session_id = PeachPay_Payment::get_session();
			$transaction_id = $this->get_transaction_id_from_request();

			// Set PeachPay details on the order (following card gateway pattern)
			$this->set_peachpay_order_details( $order, $session_id, $transaction_id );

			// Extract common payment information (handle both camelCase and lowercase)
			$payment_id = $payment_data['paymentId'] ?? $payment_data['paymentid'] ?? '';
			$payment_method = $payment_data['paymentMethod'] ?? $payment_data['paymentmethod'] ?? 'unknown';
			$status = $payment_data['status'] ?? '';
			$amount = $payment_data['amount'] ?? '';
			$currency = $payment_data['currency'] ?? '';

			// For express checkout with token-based payments, we don't have payment_id yet
			// The token will be processed by the card gateway
			if ( empty( $payment_id ) && ! isset( $payment_data['convesiopay_payment_token'] ) ) {
				throw new Exception( 'Payment ID or token not provided' );
			}

			// Handle different payment methods based on detection
			// Act as interface/router - redirect to appropriate existing gateway
			switch ( $detected_method ) {
				case 'card':
					return $this->redirect_to_card_gateway( $order, $payment_data );

				case 'applepay':
					return $this->redirect_to_applepay_gateway( $order, $payment_data );

				case 'googlepay':
					return $this->redirect_to_googlepay_gateway( $order, $payment_data );

				default:
					return $this->process_generic_payment( $order, $payment_data );
			}
			
		} catch ( Exception $e ) {
			peachpay_log(
				'error',
				'Payments: Unified process payment failed.',
				array(
					'event'     => 'payments.convesiopay_gateway.process_payment.failed',
					'component' => 'payments',
					'feature'   => 'convesiopay_gateway',
					'operation' => 'process_payment',
					'outcome'   => 'failed',
					'method'    => __METHOD__,
					'line'      => __LINE__,
					'data'      => array(
						'order_id' => $order_id,
						'order_number' => ( $order && is_a( $order, 'WC_Order' ) ) ? $order->get_order_number() : $order_id,
						'error_message' => $e->getMessage(),
					),
				)
			);
			wc_add_notice(
				sprintf(
					/* translators: %s: payment error message */
					__( 'Payment processing failed: %s', 'peachpay-for-woocommerce' ),
					$e->getMessage()
				),
				'error'
			);
			return array(
				'result'   => 'failure',
				'messages' => 'Payment processing failed: ' . $e->getMessage(),
			);
		}
	}
	
	/**
	 * Detect payment method based on ConvesioPay events and validation data
	 *
	 * @param array $payment_data Payment data from frontend
	 * @return string Detected payment method (card, btcpay, applepay, googlepay, etc.)
	 */
	private function detect_payment_method( $payment_data ) {
		// Method 1: Check explicit payment method in data
		$explicit_method = $this->normalize_convesiopay_method(
			$payment_data['paymentMethod']
			?? $payment_data['paymentmethod']
			?? $payment_data['payment_method_type']
			?? $payment_data['convesiopay_selected_method']
			?? $payment_data['selected_method']
			?? ''
		);

		if ( ! empty( $explicit_method ) ) {
			return $explicit_method;
		}

		// Method 1.5: Check for payment token (express checkout)
		if ( isset( $payment_data['convesiopay_payment_token'] ) && ! empty( $payment_data['convesiopay_payment_token'] ) ) {
			$token = $payment_data['convesiopay_payment_token'];
			
			// Check if it's a BTCPay token
			if ( strpos( $token, 'btc-session-' ) === 0 ) {
				return 'btcpay';
			}
			
			// Check if it's an ApplePay token (typically starts with specific prefix or check payment method type)
			// ApplePay tokens might not have a specific prefix, so check payment_method_type or payment data
			if ( isset( $payment_data['payment_method_type'] ) && $payment_data['payment_method_type'] === 'applepay' ) {
				return 'applepay';
			}

			if ( isset( $payment_data['payment_method_type'] ) && $payment_data['payment_method_type'] === 'googlepay' ) {
				return 'googlepay';
			}
			
			// Check if we have ApplePay payment ID in POST data
			if ( isset( $_POST['applepay_payment_id'] ) && ! empty( $_POST['applepay_payment_id'] ) ) {
				return 'applepay';
			}
			
			return 'card';
		}
		
		// Method 2: Check for ConvesioPay event type indicators
		$event_type = $payment_data['eventType'] ?? $payment_data['eventtype'] ?? '';
		$event_data = $payment_data['eventData'] ?? $payment_data['eventdata'] ?? array();
		
		// Card payment indicators
		if ( $event_type === 'card' || 
		     isset( $event_data['card'] ) || 
		     isset( $payment_data['cardData'] ) || isset( $payment_data['carddata'] ) ||
		     strpos( $payment_data['paymentId'] ?? $payment_data['paymentid'] ?? '', 'card_' ) === 0 ) {
			return 'card';
		}
		
		// BTCPay/crypto payment indicators
		if ( $event_type === 'btcpay' || 
		     $event_type === 'crypto' ||
		     isset( $event_data['btcpay'] ) || 
		     isset( $event_data['crypto'] ) ||
		     isset( $payment_data['btcpayData'] ) || isset( $payment_data['btcpaydata'] ) ||
		     isset( $payment_data['cryptoData'] ) || isset( $payment_data['cryptodata'] ) ||
		     strpos( $payment_data['paymentId'] ?? $payment_data['paymentid'] ?? '', 'btc_' ) === 0 ||
		     strpos( $payment_data['paymentId'] ?? $payment_data['paymentid'] ?? '', 'crypto_' ) === 0 ) {
			return 'btcpay';
		}
		
		// Apple Pay indicators
		if ( $event_type === 'applepay' || 
		     isset( $event_data['applepay'] ) || 
		     isset( $payment_data['applepayData'] ) || isset( $payment_data['applepaydata'] ) ||
		     strpos( $payment_data['paymentId'] ?? $payment_data['paymentid'] ?? '', 'apple_' ) === 0 ) {
			return 'applepay';
		}

		// Google Pay indicators
		if ( $event_type === 'googlepay' ||
		     isset( $event_data['googlepay'] ) ||
		     isset( $payment_data['googlepayData'] ) || isset( $payment_data['googlepaydata'] ) ||
		     strpos( $payment_data['paymentId'] ?? $payment_data['paymentid'] ?? '', 'google_' ) === 0 ||
		     strpos( $payment_data['paymentId'] ?? $payment_data['paymentid'] ?? '', 'gpay_' ) === 0 ) {
			return 'googlepay';
		}
		
		// Method 3: Check status patterns
		$status = $payment_data['status'] ?? '';

		if ( $status === 'Processing' && ( isset( $payment_data['invoiceId'] ) || isset( $payment_data['invoiceid'] ) ) ) {
			return 'btcpay'; // BTCPay typically has Processing status with invoiceId
		}

		if ( $status === 'succeeded' && ! isset( $payment_data['invoiceId'] ) && ! isset( $payment_data['invoiceid'] ) ) {
			return 'card'; // Card payments typically succeed without invoiceId
		}


		if ( isset( $payment_data['qrCodeData'] ) || isset( $payment_data['qrcodedata'] ) || isset( $payment_data['paymentUri'] ) || isset( $payment_data['paymenturi'] ) ) {
			return 'btcpay'; // BTCPay typically has QR code data
		}

		if ( isset( $payment_data['token'] ) && ! isset( $payment_data['qrCodeData'] ) && ! isset( $payment_data['qrcodedata'] ) ) {
			return 'card'; // Card payments typically have tokens but no QR codes
		}

		// Method 4: Use selected method from request/session after token/data heuristics.
		$selected_method = $this->normalize_convesiopay_method( $this->get_selected_convesiopay_method() );
		if ( in_array( $selected_method, array( 'card', 'applepay', 'googlepay', 'btcpay' ), true ) ) {
			return $selected_method;
		}

		// Default fallback
		return 'unknown';
	}

	/**
	 * Normalize method aliases to canonical unified values.
	 *
	 * @param string $method Raw method value.
	 * @return string Canonical method or empty string.
	 */
	private function normalize_convesiopay_method( $method ) {
		$normalized = strtolower( sanitize_text_field( (string) $method ) );
		if ( empty( $normalized ) ) {
			return '';
		}
		if ( in_array( $normalized, array( 'applepay', 'apple_pay', 'apple-pay' ), true ) ) {
			return 'applepay';
		}
		if ( in_array( $normalized, array( 'googlepay', 'google_pay', 'google-pay' ), true ) ) {
			return 'googlepay';
		}
		if ( in_array( $normalized, array( 'btcpay', 'crypto', 'btc_pay', 'btc-pay' ), true ) ) {
			return 'btcpay';
		}
		if ( 'card' === $normalized ) {
			return 'card';
		}
		return '';
	}
	
	/**
	 * Redirect to card gateway for processing.
	 *
	 * @param WC_Order $order Order object.
	 * @param array    $payment_data Payment data.
	 * @return array
	 */
	private function redirect_to_card_gateway( $order, $payment_data ) {

		$wc = function_exists( 'WC' ) ? WC() : null;
		if ( ! $wc || ! $wc->payment_gateways ) {
			throw new Exception( 'WooCommerce payment gateways unavailable' );
		}
		$gateways = $wc->payment_gateways->payment_gateways();
		if ( ! isset( $gateways['peachpay_convesiopay_card'] ) ) {
			throw new Exception( 'ConvesioPay card gateway not available' );
		}

		$card_gateway = $gateways['peachpay_convesiopay_card'];

		// Store original payment method before redirecting
		$order->update_meta_data( '_original_payment_method', 'peachpay_convesiopay_unified' );

		// Change the order's payment method to the card gateway
		$order->set_payment_method( 'peachpay_convesiopay_card' );
		$order->set_payment_method_title( $card_gateway ? $card_gateway->get_title() : 'ConvesioPay' );
		$order->save();

		// Prepare POST data in the format expected by the card gateway
		$_POST['payment_method'] = 'peachpay_convesiopay_card';
		$_POST['convesiopay_payment_token'] = $payment_data['convesiopay_payment_token'] ?? '';
		$_POST['peachpay_transaction_id'] = $_POST['peachpay_transaction_id'] ?? $this->get_transaction_id_from_request();

		// Also prepare payment method data for blocks
		if ( isset( $_POST['payment_method_data'] ) ) {
			$payment_method_data = is_string( $_POST['payment_method_data'] )
				? json_decode( stripslashes( $_POST['payment_method_data'] ), true )
				: $_POST['payment_method_data'];

			if ( is_array( $payment_method_data ) ) {
				$payment_method_data['convesiopay_payment_token'] = $payment_data['convesiopay_payment_token'] ?? '';
				$_POST['payment_method_data'] = wp_json_encode( $payment_method_data );
			}
		}

		// Call the card gateway's process_payment method directly
		$result = $card_gateway->process_payment( $order->get_id() );

		// Handle case where parent class returns WC_Order object instead of array
		if ( is_a( $result, 'WC_Order' ) ) {
			// Convert order object to expected array format
			$result = array(
				'result'   => 'success',
				'redirect' => $this->get_return_url( $result ),
			);
		}

		// If payment was successful, ensure cart and session are cleared to prevent order reuse
		if ( isset( $result['result'] ) && $result['result'] === 'success' ) {
			// Clear cart
			WC()->cart->empty_cart();

			// Clear WooCommerce session data
			if ( WC()->session ) {
				WC()->session->destroy_session();
				WC()->session->init();
			}

			// Force regenerate order ID for next checkout
			if ( isset( WC()->session ) ) {
				WC()->session->set( 'order_awaiting_payment', null );
				WC()->session->set( 'reload_checkout', true );
			}
		}

		return $result;
	}

	/**
	 * Log the first card retry after Classic checkout invalidated a stale token.
	 *
	 * @param WC_Order $order Order object.
	 * @param array    $payment_data Payment data from frontend.
	 * @param string   $detected_method Detected payment method.
	 */
	private function log_card_retry_after_token_invalidation( $order, $payment_data, $detected_method ) {
		$invalidated_reason = $payment_data['convesiopay_token_invalidated_reason'] ?? ( $_POST['convesiopay_token_invalidated_reason'] ?? '' );
		$invalidated_reason = $this->sanitize_log_scalar( $invalidated_reason );

		if ( '' === $invalidated_reason ) {
			return;
		}

		$invalidated_at = $payment_data['convesiopay_token_invalidated_at'] ?? ( $_POST['convesiopay_token_invalidated_at'] ?? '' );
		$previous_token_prefix = $payment_data['convesiopay_previous_token_prefix'] ?? ( $_POST['convesiopay_previous_token_prefix'] ?? '' );
		$current_token = isset( $payment_data['convesiopay_payment_token'] ) ? (string) $payment_data['convesiopay_payment_token'] : '';
		$current_token_prefix = substr( $this->sanitize_log_scalar( $current_token ), 0, 8 );
		$selected_method = $payment_data['payment_method_type'] ?? ( $payment_data['paymentMethod'] ?? $detected_method );

		peachpay_log(
			'info',
			'ConvesioPay Card retry after frontend token invalidation for order ' . $order->get_order_number(),
			array(
				'event'     => 'payments.convesiopay_gateway.card.payment.retry_after_token_invalidation',
				'component' => 'payments',
				'feature'   => 'convesiopay_gateway',
				'operation' => 'card.payment',
				'outcome'   => 'retry_after_token_invalidation',
				'method'    => __METHOD__,
				'line'      => __LINE__,
				'data'      => array(
					'order_id'              => $order->get_id(),
					'order_number'          => $order->get_order_number(),
					'invalidated_reason'    => $invalidated_reason,
					'invalidated_at'        => $this->sanitize_log_scalar( $invalidated_at ),
					'previous_token_prefix' => substr( $this->sanitize_log_scalar( $previous_token_prefix ), 0, 8 ),
					'current_token_prefix'  => $current_token_prefix,
					'current_token_length'  => strlen( $current_token ),
					'selected_method'       => $this->sanitize_log_scalar( $selected_method ),
					'payment_method_type'   => $this->sanitize_log_scalar( $payment_data['payment_method_type'] ?? '' ),
				),
			)
		);
	}

	/**
	 * Sanitize scalar values received from checkout POST data for logging.
	 *
	 * @param mixed $value Raw value.
	 * @return string
	 */
	private function sanitize_log_scalar( $value ) {
		if ( is_array( $value ) || is_object( $value ) ) {
			return '';
		}

		return sanitize_text_field( wp_unslash( (string) $value ) );
	}

	/**
	 * Redirect to BTCPay gateway for processing.
	 *
	 * @param WC_Order $order Order object.
	 * @param array    $payment_data Payment data.
	 * @return array
	 */
	private function redirect_to_btcpay_gateway( $order, $payment_data ) {
		$wc = function_exists( 'WC' ) ? WC() : null;
		if ( ! $wc || ! $wc->payment_gateways ) {
			throw new Exception( 'WooCommerce payment gateways unavailable' );
		}
		$gateways = $wc->payment_gateways->payment_gateways();
		if ( ! isset( $gateways['peachpay_convesiopay_btcpay'] ) ) {
			throw new Exception( 'ConvesioPay BTCPay gateway not available' );
		}

		$btcpay_gateway = $gateways['peachpay_convesiopay_btcpay'];

		if ( ! PeachPay_ConvesioPay_Integration::is_btcpay_enabled() ) {
			throw new Exception( 'ConvesioPay BTCPay payment method is disabled' );
		}

		// Store original payment method before redirecting
		$order->update_meta_data( '_original_payment_method', 'peachpay_convesiopay_unified' );

		// Change the order's payment method to the BTCPay gateway
		$order->set_payment_method( 'peachpay_convesiopay_btcpay' );
		$order->set_payment_method_title( $btcpay_gateway ? $btcpay_gateway->get_title() : 'ConvesioPay' );
		$order->save();

		// Prepare POST data in the format expected by the BTCPay gateway
		$_POST['payment_method'] = 'peachpay_convesiopay_btcpay';
		$_POST['peachpay_transaction_id'] = $_POST['peachpay_transaction_id'] ?? $this->get_transaction_id_from_request();

		// Set placeholder transaction/token to ensure BTCPay gateway handles it (not parent API)
		// This ensures the BTCPay gateway processes locally instead of calling parent API
		// The BTCPay gateway checks: if transaction_id === 'btc-transaction-id-placeholder' OR 
		// payment_token === 'btc-pay-token-placeholder' OR btcpay_session_id is set, it processes locally
		// We want to use placeholders to avoid calling parent API for BTCPay payments
		$_POST['peachpay_transaction_id'] = 'btc-transaction-id-placeholder';
		$_POST['convesiopay_payment_token'] = 'btc-pay-token-placeholder';

		// Add payment-specific data
		if ( isset( $payment_data['paymentId'] ) && ! empty( $payment_data['paymentId'] ) ) {
			$_POST['convesiopay_payment_id'] = sanitize_text_field( $payment_data['paymentId'] );
		}
		if ( isset( $payment_data['invoiceId'] ) && ! empty( $payment_data['invoiceId'] ) ) {
			$_POST['convesiopay_invoice_id'] = sanitize_text_field( $payment_data['invoiceId'] );
		}
		if ( isset( $payment_data['status'] ) && ! empty( $payment_data['status'] ) ) {
			$_POST['convesiopay_status'] = sanitize_text_field( $payment_data['status'] );
		}

		// IMPORTANT: Add BTCPay-specific fields that the BTCPay gateway expects
		// These are critical for the gateway to recognize payment confirmation
		if ( isset( $payment_data['paymentId'] ) && ! empty( $payment_data['paymentId'] ) ) {
			$_POST['btcpay_payment_id'] = sanitize_text_field( $payment_data['paymentId'] );
		}
		if ( isset( $payment_data['invoiceId'] ) && ! empty( $payment_data['invoiceId'] ) ) {
			$_POST['btcpay_invoice_id'] = sanitize_text_field( $payment_data['invoiceId'] );
		}
		if ( isset( $payment_data['status'] ) && ! empty( $payment_data['status'] ) ) {
			$_POST['btcpay_status'] = sanitize_text_field( $payment_data['status'] );
		} else {
			// Default to Processing if status not provided but payment ID exists
			if ( isset( $payment_data['paymentId'] ) && ! empty( $payment_data['paymentId'] ) ) {
				$_POST['btcpay_status'] = 'Processing';
			}
		}
				if ( isset( $payment_data['btcpaySessionId'] ) || isset( $payment_data['btcpay_session_id'] ) ) {
					$session_id = $payment_data['btcpaySessionId'] ?? $payment_data['btcpay_session_id'];
					if ( ! empty( $session_id ) ) {
						$_POST['btcpay_session_id'] = sanitize_text_field( $session_id );
					}
				}

		// Also prepare payment method data for blocks and extract BTCPay fields
		if ( isset( $_POST['payment_method_data'] ) ) {
			$payment_method_data = is_string( $_POST['payment_method_data'] )
				? json_decode( stripslashes( $_POST['payment_method_data'] ), true )
				: $_POST['payment_method_data'];

			if ( is_array( $payment_method_data ) ) {
				// Extract BTCPay-specific fields from blocks checkout payment data
				if ( isset( $payment_method_data['btcpay_payment_id'] ) ) {
					$_POST['btcpay_payment_id'] = $payment_method_data['btcpay_payment_id'];
					$payment_data['paymentId'] = $payment_method_data['btcpay_payment_id'];
				}
				if ( isset( $payment_method_data['btcpay_invoice_id'] ) ) {
					$_POST['btcpay_invoice_id'] = $payment_method_data['btcpay_invoice_id'];
					$payment_data['invoiceId'] = $payment_method_data['btcpay_invoice_id'];
				}
				if ( isset( $payment_method_data['btcpay_status'] ) ) {
					$_POST['btcpay_status'] = $payment_method_data['btcpay_status'];
					$payment_data['status'] = $payment_method_data['btcpay_status'];
				}
				if ( isset( $payment_method_data['btcpay_session_id'] ) ) {
					$_POST['btcpay_session_id'] = $payment_method_data['btcpay_session_id'];
				}

				$payment_method_data = array_merge( $payment_method_data, array(
					'convesiopay_payment_id' => $payment_data['paymentId'] ?? '',
					'convesiopay_invoice_id' => $payment_data['invoiceId'] ?? '',
					'convesiopay_status' => $payment_data['status'] ?? '',
				) );
				$_POST['payment_method_data'] = wp_json_encode( $payment_method_data );
			}
		}

		// Call the BTCPay gateway's process_payment method directly
		$result = $btcpay_gateway->process_payment( $order->get_id() );

		// Check if result is an object (Order) or array (payment result)
		if ( is_object( $result ) ) {
			// BTCPay gateway returned an Order object, which means success
			// Create a standard success response
			$order_object = $result; // Store the order object
			$result = array(
				'result'   => 'success',
				'redirect' => $this->get_return_url( $order_object ),
			);
		}

		// If payment was successful, ensure cart and session are cleared to prevent order reuse
		if ( is_array( $result ) && isset( $result['result'] ) && $result['result'] === 'success' ) {
			// Clear cart
			WC()->cart->empty_cart();

			// Clear WooCommerce session data
			if ( WC()->session ) {
				WC()->session->destroy_session();
				WC()->session->init();
			}

			// Force regenerate order ID for next checkout
			if ( isset( WC()->session ) ) {
				WC()->session->set( 'order_awaiting_payment', null );
				WC()->session->set( 'reload_checkout', true );
			}
		}

		return $result;
	}
	
	/**
	 * Redirect to Apple Pay gateway for processing.
	 *
	 * @param WC_Order $order Order object.
	 * @param array    $payment_data Payment data.
	 * @return array
	 */
	private function redirect_to_applepay_gateway( $order, $payment_data ) {

		$wc = function_exists( 'WC' ) ? WC() : null;
		if ( ! $wc || ! $wc->payment_gateways ) {
			throw new Exception( 'WooCommerce payment gateways unavailable' );
		}
		$gateways = $wc->payment_gateways->payment_gateways();
		if ( ! isset( $gateways['peachpay_convesiopay_applepay'] ) ) {
			throw new Exception( 'ConvesioPay Apple Pay gateway not available' );
		}

		$applepay_gateway = $gateways['peachpay_convesiopay_applepay'];

		// Store original payment method before redirecting
		$order->update_meta_data( '_original_payment_method', 'peachpay_convesiopay_unified' );

		// Change the order's payment method to the Apple Pay gateway
		$order->set_payment_method( 'peachpay_convesiopay_applepay' );
		$order->set_payment_method_title( $applepay_gateway ? $applepay_gateway->get_title() : 'ConvesioPay' );
		$order->save();

		// Prepare POST data in the format expected by the Apple Pay gateway
		$_POST['payment_method'] = 'peachpay_convesiopay_applepay';
		$_POST['peachpay_transaction_id'] = $_POST['peachpay_transaction_id'] ?? $this->get_transaction_id_from_request();

		// NEW TOKEN-BASED FLOW: Add payment token (required for creating payment with secret key)
		if ( isset( $payment_data['convesiopay_payment_token'] ) && ! empty( $payment_data['convesiopay_payment_token'] ) ) {
			$token_to_pass = $payment_data['convesiopay_payment_token'];
			
			// Validate token format before passing to Apple Pay gateway
			if ( strpos( $token_to_pass, ' ' ) !== false || strlen( trim( $token_to_pass ) ) < 20 ) {
				throw new Exception( __( 'Invalid Apple Pay payment token format. Please try again.', 'peachpay-for-woocommerce' ) );
			}
			
			$_POST['convesiopay_payment_token'] = $token_to_pass;
		} else {
			throw new Exception( __( 'Apple Pay payment token is missing. Please try again.', 'peachpay-for-woocommerce' ) );
		}

		// Add payment-specific data (legacy fields, may not be present in new token-based flow)
		if ( isset( $payment_data['paymentId'] ) ) {
			$_POST['convesiopay_payment_id'] = $payment_data['paymentId'];
		}
		if ( isset( $payment_data['status'] ) ) {
			$_POST['convesiopay_status'] = $payment_data['status'];
		}

		// Also prepare payment method data for blocks
		if ( isset( $_POST['payment_method_data'] ) ) {
			$payment_method_data = is_string( $_POST['payment_method_data'] )
				? json_decode( stripslashes( $_POST['payment_method_data'] ), true )
				: $_POST['payment_method_data'];

			if ( is_array( $payment_method_data ) ) {
				$payment_method_data = array_merge( $payment_method_data, array(
					'convesiopay_payment_token' => $payment_data['convesiopay_payment_token'] ?? '',
					'convesiopay_payment_id' => $payment_data['paymentId'] ?? '',
					'convesiopay_status' => $payment_data['status'] ?? '',
				) );
				$_POST['payment_method_data'] = wp_json_encode( $payment_method_data );
			}
		}

		// Call the Apple Pay gateway's process_payment method directly
		$result = $applepay_gateway->process_payment( $order->get_id() );

		// Handle case where parent class returns WC_Order object instead of array
		if ( is_a( $result, 'WC_Order' ) ) {
			// Convert order object to expected array format
			$result = array(
				'result'   => 'success',
				'redirect' => $this->get_return_url( $result ),
			);
		}

		// If payment was successful, ensure cart and session are cleared to prevent order reuse
		if ( isset( $result['result'] ) && $result['result'] === 'success' ) {
			// Clear cart
			WC()->cart->empty_cart();

			// Clear WooCommerce session data
			if ( WC()->session ) {
				WC()->session->destroy_session();
				WC()->session->init();
			}

			// Force regenerate order ID for next checkout
			if ( isset( WC()->session ) ) {
				WC()->session->set( 'order_awaiting_payment', null );
				WC()->session->set( 'reload_checkout', true );
			}
		}

		return $result;
	}

	/**
	 * Redirect to Google Pay gateway for processing.
	 *
	 * @param WC_Order $order Order object.
	 * @param array    $payment_data Payment data.
	 * @return array
	 */
	private function redirect_to_googlepay_gateway( $order, $payment_data ) {

		$gateways = WC()->payment_gateways->payment_gateways();
		if ( ! isset( $gateways['peachpay_convesiopay_googlepay'] ) ) {
			throw new Exception( 'ConvesioPay Google Pay gateway not available' );
		}

		$googlepay_gateway = $gateways['peachpay_convesiopay_googlepay'];

		peachpay_log(
			'info',
			'ConvesioPay Unified: Redirecting order ' . $order->get_order_number() . ' to Google Pay gateway | ' . wp_json_encode(
				array(
					'status'       => $payment_data['status'] ?? '',
					'amount'       => $payment_data['amount'] ?? '',
					'currency'     => $payment_data['currency'] ?? '',
					'has_token'    => ! empty( $payment_data['convesiopay_payment_token'] ),
					'token_length' => isset( $payment_data['convesiopay_payment_token'] ) ? strlen( (string) $payment_data['convesiopay_payment_token'] ) : 0,
					'token_prefix' => isset( $payment_data['convesiopay_payment_token'] ) ? substr( (string) $payment_data['convesiopay_payment_token'], 0, 8 ) : '',
				)
			)
		);

		$order->update_meta_data( '_original_payment_method', 'peachpay_convesiopay_unified' );
		$order->set_payment_method( 'peachpay_convesiopay_googlepay' );
		$order->set_payment_method_title( 'ConvesioPay - Google Pay' );
		$order->save();

		$_POST['payment_method'] = 'peachpay_convesiopay_googlepay';
		$_POST['peachpay_transaction_id'] = $_POST['peachpay_transaction_id'] ?? $this->get_transaction_id_from_request();

		if ( isset( $payment_data['convesiopay_payment_token'] ) && ! empty( $payment_data['convesiopay_payment_token'] ) ) {
			$token_to_pass = $payment_data['convesiopay_payment_token'];
			if ( strpos( $token_to_pass, ' ' ) !== false || strlen( trim( $token_to_pass ) ) < 20 ) {
				throw new Exception( __( 'Invalid Google Pay payment token format. Please try again.', 'peachpay-for-woocommerce' ) );
			}

			$_POST['convesiopay_payment_token'] = $token_to_pass;
		} else {
			throw new Exception( __( 'Google Pay payment token is missing. Please try again.', 'peachpay-for-woocommerce' ) );
		}

		if ( isset( $payment_data['paymentId'] ) ) {
			$_POST['convesiopay_payment_id'] = $payment_data['paymentId'];
		}
		if ( isset( $payment_data['status'] ) ) {
			$_POST['convesiopay_status'] = $payment_data['status'];
		}
		if ( isset( $payment_data['amount'] ) ) {
			$_POST['googlepay_amount'] = $payment_data['amount'];
		}
		if ( isset( $payment_data['currency'] ) ) {
			$_POST['googlepay_currency'] = $payment_data['currency'];
		}

		if ( isset( $_POST['payment_method_data'] ) ) {
			$payment_method_data = is_string( $_POST['payment_method_data'] )
				? json_decode( stripslashes( $_POST['payment_method_data'] ), true )
				: $_POST['payment_method_data'];

			if ( is_array( $payment_method_data ) ) {
				$payment_method_data = array_merge( $payment_method_data, array(
					'convesiopay_payment_token' => $payment_data['convesiopay_payment_token'] ?? '',
					'convesiopay_payment_id' => $payment_data['paymentId'] ?? '',
					'convesiopay_status' => $payment_data['status'] ?? '',
					'payment_method_type' => 'googlepay',
					'googlepay_amount' => $payment_data['amount'] ?? '',
					'googlepay_currency' => $payment_data['currency'] ?? '',
				) );
				$_POST['payment_method_data'] = wp_json_encode( $payment_method_data );
			}
		}

		$result = $googlepay_gateway->process_payment( $order->get_id() );

		peachpay_log(
			'info',
			'ConvesioPay Unified: Google Pay gateway returned for order ' . $order->get_order_number() . ' | ' . wp_json_encode( $result )
		);

		if ( is_a( $result, 'WC_Order' ) ) {
			$result = array(
				'result'   => 'success',
				'redirect' => $this->get_return_url( $result ),
			);
		}

		if ( isset( $result['result'] ) && $result['result'] === 'success' ) {
			WC()->cart->empty_cart();

			if ( WC()->session ) {
				WC()->session->destroy_session();
				WC()->session->init();
			}

			if ( isset( WC()->session ) ) {
				WC()->session->set( 'order_awaiting_payment', null );
				WC()->session->set( 'reload_checkout', true );
			}
		}

		return $result;
	}
	
	/**
	 * Process generic payment (fallback).
	 *
	 * @param WC_Order $order Order object.
	 * @param array    $payment_data Payment data.
	 * @return array
	 */
	private function process_generic_payment( $order, $payment_data ) {
		$payment_id = $payment_data['paymentId'] ?? $payment_data['paymentid'] ?? '';
		$payment_method = $payment_data['paymentMethod'] ?? $payment_data['paymentmethod'] ?? 'unknown';
		$status = $payment_data['status'];

		peachpay_log(
			'info',
			'Payments: Generic payment received.',
			array(
				'event'     => 'payments.convesiopay_gateway.generic_payment.received',
				'component' => 'payments',
				'feature'   => 'convesiopay_gateway',
				'operation' => 'generic_payment.received',
				'outcome'   => 'success',
				'method'    => __METHOD__,
				'line'      => __LINE__,
				'data'      => array(
					'order_id' => $order->get_id(),
					'order_number' => $order->get_order_number(),
					'payment_id' => $payment_id,
					'payment_method' => $payment_method,
					'status' => $status,
				),
			)
		);

		// Set order transaction ID
		$order->set_transaction_id( $payment_id );
		
		// Add payment method meta
		$order->update_meta_data( '_convesiopay_payment_method', $payment_method );
		$order->update_meta_data( '_convesiopay_payment_id', $payment_id );

		// Store manual capture mode from API (manualPaymentCapture in POST /payments response).
		// Required for reconciliation to skip auto-updating manual-capture orders.
		$manual_capture = $payment_data['manualPaymentCapture'] ?? $payment_data['manualpaymentcapture'] ?? false;
		$order->update_meta_data( '_convesiopay_manual_capture_mode', $manual_capture ? 'yes' : 'no' );
		
		// Update order status based on payment status
		if ( in_array( $status, array( 'succeeded', 'Processing' ), true ) ) {
			$order->update_status( 'processing', sprintf( __( 'ConvesioPay payment completed via %s. Payment ID: %s', 'peachpay-for-woocommerce' ), $payment_method, $payment_id ) );
			$payment_url = peachpay_convesiopay_dashboard_url() . '/payments/' . $payment_id;
			$order->add_order_note( sprintf( __( 'ConvesioPay payment successful via %s. Payment ID: %s | <a href="%s" target="_blank">View Payment</a>', 'peachpay-for-woocommerce' ), $payment_method, $payment_id, $payment_url ) );
		} else {
			$order->update_status( 'pending', sprintf( __( 'ConvesioPay payment pending via %s. Payment ID: %s, Status: %s', 'peachpay-for-woocommerce' ), $payment_method, $payment_id, $status ) );
		}
		
		$order->save();

		peachpay_log(
			'info',
			'Payments: Generic payment completed.',
			array(
				'event'     => 'payments.convesiopay_gateway.generic_payment.completed',
				'component' => 'payments',
				'feature'   => 'convesiopay_gateway',
				'operation' => 'generic_payment.completed',
				'outcome'   => 'success',
				'method'    => __METHOD__,
				'line'      => __LINE__,
				'data'      => array(
					'order_id' => $order->get_id(),
					'order_number' => $order->get_order_number(),
					'payment_id' => $payment_id,
					'payment_method' => $payment_method,
					'status' => $status,
				),
			)
		);
		return array(
			'result'   => 'success',
			'redirect' => $this->get_return_url( $order ),
		);
	}

	/**
	 * Get transaction URL for viewing payment in ConvesioPay dashboard
	 *
	 * @param WC_Order $order Order object.
	 * @return string Transaction URL.
	 */
	public function get_transaction_url( $order ) {
		$payment_id = $order->get_meta( '_convesiopay_payment_id' );
		if ( empty( $payment_id ) ) {
			$payment_id = $order->get_transaction_id();
		}

		if ( ! empty( $payment_id ) ) {
			$this->view_transaction_url = peachpay_convesiopay_dashboard_url() . '/payments/%s';
			return parent::get_transaction_url( $order );
		}

		return '';
	}

	/**
	 * Enqueue scripts for unified payment.
	 */
	public function enqueue_scripts() {
		// Don't restrict to checkout/cart only - Express Checkout can open from any page
		// if ( ! is_checkout() && ! is_cart() ) {
		// 	return;
		// }
		
		if ( ! $this->is_available() ) {
			return;
		}

		// Enqueue ConvesioPay SDK
		wp_enqueue_script(
			'convesiopay-sdk',
			'https://js.convesiopay.com/v1/index.js',
			array(),
			'1.0',
			true
		);

		// Enqueue classic checkout script for traditional checkout
		wp_enqueue_script(
			'peachpay-convesiopay-unified-classic',
			plugins_url( 'core/payments/convesiopay/assets/js/convesiopay-unified-classic-v2.js', PEACHPAY_PLUGIN_FILE ),
			array( 'jquery', 'convesiopay-sdk' ),
			'1.2.2',
			true
		);

		// Pass settings to JavaScript
		// Note: the accelerated-checkout script is enqueued by
		// PeachPay_ConvesioPay_Accelerated_Checkout_Element — not here.
		$config = PeachPay_ConvesioPay_Integration::config();

		// IMPORTANT: Get theme from separate option (not from gateway settings)
		// WooCommerce gateways only save keys defined in form_fields during settings save,
		// so we store the theme in a dedicated option to avoid it being stripped out
		$checkout_theme = get_option( 'peachpay_convesiopay_checkout_theme', 'light' );

		// Get active payment methods
		$active_methods = $this->get_active_payment_methods();

		// Get fee configuration from individual gateways
		$card_gateway = $this->get_individual_gateway( 'card' );
		$applepay_gateway = $this->get_individual_gateway( 'applepay' );
		$googlepay_gateway = $this->get_individual_gateway( 'googlepay' );
		$btcpay_gateway = $this->get_individual_gateway( 'btcpay' );

		$fee_config = array(
			'card' => array(
				'enabled' => $card_gateway ? $card_gateway->get_option( 'fees_enabled' ) === 'yes' : false,
				'type' => $card_gateway ? $card_gateway->get_option( 'fee_type' ) : 'fixed',
				'amount' => $card_gateway ? floatval( $card_gateway->get_option( 'fee_amount' ) ) : 0,
				'label' => $card_gateway ? $card_gateway->get_option( 'fee_reason' ) : '',
			),
			'applepay' => array(
				'enabled' => $applepay_gateway ? $applepay_gateway->get_option( 'fees_enabled' ) === 'yes' : false,
				'type' => $applepay_gateway ? $applepay_gateway->get_option( 'fee_type' ) : 'fixed',
				'amount' => $applepay_gateway ? floatval( $applepay_gateway->get_option( 'fee_amount' ) ) : 0,
				'label' => $applepay_gateway ? $applepay_gateway->get_option( 'fee_reason' ) : '',
			),
			'googlepay' => array(
				'enabled' => $googlepay_gateway ? $googlepay_gateway->get_option( 'fees_enabled' ) === 'yes' : false,
				'type' => $googlepay_gateway ? $googlepay_gateway->get_option( 'fee_type' ) : 'fixed',
				'amount' => $googlepay_gateway ? floatval( $googlepay_gateway->get_option( 'fee_amount' ) ) : 0,
				'label' => $googlepay_gateway ? $googlepay_gateway->get_option( 'fee_reason' ) : '',
			),
			'btcpay' => array(
				'enabled' => $btcpay_gateway ? $btcpay_gateway->get_option( 'fees_enabled' ) === 'yes' : false,
				'type' => $btcpay_gateway ? $btcpay_gateway->get_option( 'fee_type' ) : 'fixed',
				'amount' => $btcpay_gateway ? floatval( $btcpay_gateway->get_option( 'fee_amount' ) ) : 0,
				'label' => $btcpay_gateway ? $btcpay_gateway->get_option( 'fee_reason' ) : '',
			),
		);

		// Get cart total for percentage calculations (subtotal - discount + shipping + tax, WITHOUT gateway fee)
		$cart_total = 0;
		if ( WC()->cart ) {
			$cart_total = WC()->cart->get_subtotal() - WC()->cart->get_discount_total() + WC()->cart->get_shipping_total() + WC()->cart->get_total_tax();
		}

		// Detect order-pay context and pass existing order details to frontend.
		$is_order_pay = false;
		$order_pay_data = array();
		if ( is_wc_endpoint_url( 'order-pay' ) ) {
			$order_id  = absint( get_query_var( 'order-pay' ) );
			$pay_order = wc_get_order( $order_id );
			if ( $pay_order instanceof WC_Order ) {
				$is_order_pay = true;
				$order_pay_data = array(
					'order_id'      => $pay_order->get_id(),
					'order_number'  => $pay_order->get_order_number(),
					'order_key'     => $pay_order->get_order_key(),
					'total'         => floatval( $pay_order->get_total() ),
					'currency'      => $pay_order->get_currency(),
					'billing_email' => $pay_order->get_billing_email(),
					'billing_first_name' => $pay_order->get_billing_first_name(),
					'billing_last_name'  => $pay_order->get_billing_last_name(),
					'billing_address'    => array(
						'street'     => trim( $pay_order->get_billing_address_1() . ' ' . $pay_order->get_billing_address_2() ),
						'city'       => $pay_order->get_billing_city(),
						'state'      => $pay_order->get_billing_state(),
						'postalCode' => $pay_order->get_billing_postcode(),
						'country'    => $pay_order->get_billing_country(),
					),
					'shipping_address'   => array(
						'street'     => trim( $pay_order->get_shipping_address_1() . ' ' . $pay_order->get_shipping_address_2() ),
						'city'       => $pay_order->get_shipping_city(),
						'state'      => $pay_order->get_shipping_state(),
						'postalCode' => $pay_order->get_shipping_postcode(),
						'country'    => $pay_order->get_shipping_country(),
					),
				);
			}
		}

		$script_data = array(
			'enabled' => $this->enabled,
			'title' => $this->title,
			'description' => $this->description,
			'supports' => $this->supports,
			'currency' => get_woocommerce_currency(),
			'integration_name' => $config['integration_name'] ?? '',
			// Store identity fields for wallet payment sheet merchant labels.
			// Primary: WP store name (Settings > General > Site Title).
			// Fallback: hostname so the sheet always shows something meaningful.
			'store_name' => get_bloginfo( 'name' ),
			'store_url'  => (string) wp_parse_url( get_site_url(), PHP_URL_HOST ) ?: get_site_url(),
			'checkout_theme' => $checkout_theme,
			'active_methods' => $active_methods,
			'disabled_payment_methods' => $this->get_disabled_payment_methods(),
			'ajax_url' => admin_url( 'admin-ajax.php' ),
			'nonce' => wp_create_nonce( 'peachpay_convesiopay_nonce' ),
			'convesiopay_config' => array(
				'apiKey' => $config['api_key'] ?? '', // Use publicKey as apiKey for frontend
				'clientKey' => $config['client_key'] ?? '', // Use publicKey as clientKey for frontend
				'api_url' => $config['api_url'] ?? '',
			),
			'fee_config' => $fee_config,
			'cart_total' => floatval( $cart_total ),
			'is_order_pay' => $is_order_pay,
			'order_pay' => $order_pay_data,
			'peachpay_is_advanced_logging_enabled' => peachpay_is_advanced_logging_enabled(),
			'accelerated_checkout' => array_merge(
				array(
					'applepay_enabled' => 'yes',
					'googlepay_enabled' => 'yes',
					'checkout_enabled' => 'yes',
					'cart_enabled' => 'no',
					'product_enabled' => 'no',
				),
				(array) get_option( 'peachpay_convesiopay_accelerated_checkout_settings', array() ),
				array(
					// Derive the list of countries the wallet button should be shown in
					// from the WooCommerce shipping zones so stores outside US/CA/GB work.
					'allowed_countries' => array_values( array_unique( array_filter( array_map(
						'strtoupper',
						array_keys( WC()->countries ? WC()->countries->get_shipping_countries() : array() )
					) ) ) ),
				)
			),
			'accelerated_checkout_route' => rest_url( 'peachpay/v1/convesiopay/accelerated-checkout/create-order' ),
			'accelerated_recalculate_route' => rest_url( 'peachpay/v1/convesiopay/accelerated-checkout/recalculate' ),
			'rest_nonce' => wp_create_nonce( 'wp_rest' ),
		);

		// Localize for blocks and classic scripts.
		// The accelerated-checkout script is localised by
		// PeachPay_ConvesioPay_Accelerated_Checkout_Element::enqueue_scripts().
		wp_localize_script( 'peachpay-convesiopay-unified-blocks', 'peachpay_convesiopay_unified_data', $script_data );
		wp_localize_script( 'peachpay-convesiopay-unified-classic', 'peachpay_convesiopay_unified_data', $script_data );

		// CRITICAL: Set data as global inline script in the footer so it's available for all contexts
		// This ensures Express Checkout, Blocks, and Classic all have access to the configuration
		$script_data_json = wp_json_encode( $script_data );
		$inline_script = "window.peachpay_convesiopay_unified_data = {$script_data_json};";

		// Add to footer with high priority so it runs before any checkout scripts
		add_action(
			'wp_footer',
			function() use ( $inline_script ) {
				echo '<script type="text/javascript">' . $inline_script . '</script>';
			},
			1
		);

		// Also add inline script for WooCommerce Blocks compatibility
		// This registers the settings so getSetting('peachpay_convesiopay_unified_data') works
		$blocks_inline_script = "
		(function() {
			if (typeof window.wc !== 'undefined' && window.wc.wcSettings) {
				// Register settings for WooCommerce Blocks getSetting() function
				if (typeof window.wc.wcSettings.registerPaymentMethodData === 'function') {
					window.wc.wcSettings.registerPaymentMethodData('peachpay_convesiopay_unified', {
						peachpay_convesiopay_unified_data: {$script_data_json}
					});
				}
				// Also set in allSettings as fallback
				window.wc.wcSettings.allSettings = window.wc.wcSettings.allSettings || {};
				window.wc.wcSettings.allSettings['peachpay_convesiopay_unified_data'] = {$script_data_json};

				// Set in getSetting cache
				if (typeof window.wc.wcSettings.getSetting === 'function') {
					try {
						// Force set the setting by modifying the internal cache
						if (!window.wc.wcSettings.__internalCache) {
							window.wc.wcSettings.__internalCache = {};
						}
						window.wc.wcSettings.__internalCache['peachpay_convesiopay_unified_data'] = {$script_data_json};
					} catch(e) {
						console.error('Failed to set WC settings cache:', e);
					}
				}
			}
		})();
		";
		wp_add_inline_script( 'peachpay-convesiopay-unified-blocks', $blocks_inline_script, 'before' );
	}

	/**
	 * Process refund.
	 *
	 * @param int    $order_id Order ID.
	 * @param float  $amount Refund amount.
	 * @param string $reason Refund reason.
	 * @return bool|WP_Error
	 */
	public function process_refund( $order_id, $amount = null, $reason = '' ) {
		$order = wc_get_order( $order_id );

		if ( ! $order ) {
			return new WP_Error( 'convesiopay_refund_error', __( 'Order not found.', 'peachpay-for-woocommerce' ) );
		}

		// Get ConvesioPay configuration
		$config = $this->get_convesiopay_config();

		if ( empty( $config ) ) {
			return new WP_Error( 'convesiopay_refund_error', __( 'ConvesioPay is not properly configured.', 'peachpay-for-woocommerce' ) );
		}

		// Validate currency - ConvesioPay only supports USD
		if ( $order->get_currency() !== 'USD' ) {
			return new WP_Error( 'convesiopay_refund_error', sprintf(
				__( 'ConvesioPay only supports USD currency. Order currency is %s.', 'peachpay-for-woocommerce' ),
				$order->get_currency()
			) );
		}

		// Check payment method - only allow refunds for card and Apple Pay payments (not BTCPay/crypto)
		$payment_method = $order->get_meta( '_convesiopay_payment_method' );
		if ( $payment_method === 'btcpay' ) {
			return new WP_Error( 'refund_not_supported', __( 'Refunds are not supported for cryptocurrency payments.', 'peachpay-for-woocommerce' ) );
		}

		try {
			// Prefer original payment ID for refunds (Adyen requires original PID, not updated lifecycle PID)
			$payment_id = $order->get_meta( '_convesiopay_original_payment_id' );
			if ( empty( $payment_id ) ) {
				$payment_id = $order->get_meta( '_convesiopay_payment_id' );
			}

			// If not found in meta, try to find payment ID by order number using ConvesioPay API
			if ( empty( $payment_id ) ) {
				$payment_id = $this->find_payment_by_order_number( $order->get_order_number(), $config );
			}

			if ( ! $payment_id ) {
				peachpay_log(
					'error',
					'Payments: Refund failed.',
					array(
						'event'     => 'payments.convesiopay_gateway.refund.failed',
						'component' => 'payments',
						'feature'   => 'convesiopay_gateway',
						'operation' => 'refund',
						'outcome'   => 'failed',
						'method'    => __METHOD__,
						'line'      => __LINE__,
						'data'      => array(
							'details' => 'ConvesioPay: Refund - payment ID not found for order ' . $order->get_order_number()
				)));
				return new WP_Error( 'convesiopay_refund_error', __( 'Payment ID not found for this order.', 'peachpay-for-woocommerce' ) );
			}

			// If no amount specified, refund the full order total
			if ( is_null( $amount ) || $amount <= 0 ) {
				$amount = $order->get_total();
			}

			// Prepare refund data in ConvesioPay format
			$refund_data = array(
				'currency' => strtoupper( $order->get_currency() ), // Ensure uppercase 3-character ISO code
				'amount' => (int) round( $amount * 100 ), // Convert to minor units (cents) and ensure integer
			);

			// Validate minimum amount (50 cents as per ConvesioPay docs)
			if ( $refund_data['amount'] < 50 ) {
				return new WP_Error( 'convesiopay_refund_error', __( 'Refund amount must be at least 50 cents.', 'peachpay-for-woocommerce' ) );
			}

			// Build refund endpoint URL
			$refund_endpoint = $config['api_url'] . '/payments/' . $payment_id . '/refund';
			peachpay_log(
				'debug',
				'Payments: Refund debug.',
				array(
					'event'     => 'payments.convesiopay_gateway.refund.debug',
					'component' => 'payments',
					'feature'   => 'convesiopay_gateway',
					'operation' => 'refund',
					'outcome'   => 'debug',
					'method'    => __METHOD__,
					'line'      => __LINE__,
					'data'      => array(
						'details' => 'ConvesioPay: Refund API request for order ' . $order->get_order_number() . ', payment ' . $payment_id . ', amount ' . $refund_data['amount'] . ' ' . $refund_data['currency']
			)));

			// Add order note for refund request
			$order->add_order_note( sprintf(
				__( 'ConvesioPay refund request: Endpoint: %s | Payment ID: %s | Amount: %s | Currency: %s', 'peachpay-for-woocommerce' ),
				$refund_endpoint,
				$payment_id,
				$refund_data['amount'],
				$refund_data['currency']
			) );

			// Make API call to ConvesioPay refund endpoint
			$response = wp_remote_post( $refund_endpoint, array(
				'headers' => array(
					'Authorization' => $config['secret_key'],
					'Content-Type' => 'application/json',
				),
				'body' => json_encode( $refund_data ),
				'timeout' => 30,
			) );

			if ( is_wp_error( $response ) ) {
				peachpay_log(
					'error',
					'Payments: Refund failed.',
					array(
						'event'     => 'payments.convesiopay_gateway.refund.failed',
						'component' => 'payments',
						'feature'   => 'convesiopay_gateway',
						'operation' => 'refund',
						'outcome'   => 'failed',
						'method'    => __METHOD__,
						'line'      => __LINE__,
						'data'      => array(
							'details' => 'ConvesioPay: Refund network error - ' . $response->get_error_message() . ' (order ' . $order->get_order_number() . ', payment ' . $payment_id . ')'
				)));
				$order->add_order_note( sprintf(
					__( 'ConvesioPay refund response: Network error - %s', 'peachpay-for-woocommerce' ),
					$response->get_error_message()
				) );
				return new WP_Error( 'convesiopay_refund_error', 'Network error: ' . $response->get_error_message() );
			}

			$response_code = wp_remote_retrieve_response_code( $response );
			$response_body = wp_remote_retrieve_body( $response );
			$response_data = json_decode( $response_body, true );

			if ( $response_code !== 200 ) {
				$error_message = isset( $response_data['message'] ) ? $response_data['message'] : 'Refund failed (HTTP ' . $response_code . ')';
				peachpay_log(
					'error',
					'Payments: Refund failed.',
					array(
						'event'     => 'payments.convesiopay_gateway.refund.failed',
						'component' => 'payments',
						'feature'   => 'convesiopay_gateway',
						'operation' => 'refund',
						'outcome'   => 'failed',
						'method'    => __METHOD__,
						'line'      => __LINE__,
						'data'      => array(
							'details' => 'ConvesioPay: Refund API error - ' . $error_message . ' (order ' . $order->get_order_number() . ', payment ' . $payment_id . ')'
				)));
				return new WP_Error( 'convesiopay_refund_error', $error_message );
			}

			// Refund successful - extract refund details from response
			$refund_id = isset( $response_data['id'] ) ? $response_data['id'] : '';
			peachpay_log(
				'info',
				'Payments: Refund success.',
				array(
					'event'     => 'payments.convesiopay_gateway.refund.success',
					'component' => 'payments',
					'feature'   => 'convesiopay_gateway',
					'operation' => 'refund',
					'outcome'   => 'success',
					'method'    => __METHOD__,
					'line'      => __LINE__,
					'data'      => array(
						'details' => 'ConvesioPay: Refund success - order ' . $order->get_order_number() . ', refund_id ' . $refund_id
			)));

			// Add detailed order note
			$note = sprintf(
				__( 'ConvesioPay refund processed. Amount: %s', 'peachpay-for-woocommerce' ),
				wc_price( $amount )
			);

			if ( $refund_id ) {
				$note .= sprintf( __( '. Refund ID: %s', 'peachpay-for-woocommerce' ), $refund_id );
			}

			if ( $reason ) {
				$note .= sprintf( __( '. Reason: %s', 'peachpay-for-woocommerce' ), $reason );
			}

			$order->add_order_note( $note );

			// Store refund ID as order meta for future reference and update payment ID
			if ( $refund_id ) {
				// Check if payment ID has changed and add note
				$existing_payment_id = $order->get_meta( '_convesiopay_payment_id' );
				if ( ! empty( $existing_payment_id ) && $existing_payment_id !== $refund_id ) {
					$order->add_order_note( sprintf( __( 'ConvesioPay Payment ID updated from %s to %s (refunded)', 'peachpay-for-woocommerce' ), $existing_payment_id, $refund_id ) );
				}

				// Update payment ID meta and transaction ID
				$order->update_meta_data( '_convesiopay_last_refund_id', $refund_id );
				$order->update_meta_data( '_convesiopay_refund_id', $refund_id );
				$order->update_meta_data( '_convesiopay_payment_id', $refund_id );
				$order->set_transaction_id( $refund_id );
				$order->save();
			}

			return true;

		} catch ( Exception $e ) {
			peachpay_log(
				'error',
				'Payments: Refund failed.',
				array(
					'event'     => 'payments.convesiopay_gateway.refund.failed',
					'component' => 'payments',
					'feature'   => 'convesiopay_gateway',
					'operation' => 'refund',
					'outcome'   => 'failed',
					'method'    => __METHOD__,
					'line'      => __LINE__,
					'data'      => array(
						'details' => 'ConvesioPay: Refund exception - ' . $e->getMessage() . ' (order ' . $order->get_order_number() . ')'
			)));
			return new WP_Error( 'convesiopay_refund_error', $e->getMessage() );
		}
	}

	/**
	 * Find payment ID by order number using ConvesioPay API.
	 *
	 * @param string $order_number Order number.
	 * @param array  $config       ConvesioPay configuration.
	 * @return string|false Payment ID or false if not found.
	 */
	private function find_payment_by_order_number( $order_number, $config ) {
		peachpay_log(
			'debug',
			'Payments: Find payment by order number debug.',
			array(
				'event'     => 'payments.convesiopay_gateway.find_payment_by_order_number.debug',
				'component' => 'payments',
				'feature'   => 'convesiopay_gateway',
				'operation' => 'find_payment_by_order_number',
				'outcome'   => 'debug',
				'method'    => __METHOD__,
				'line'      => __LINE__,
				'data'      => array(
					'order_number' => $order_number,
					'api_url' => $config['api_url'] . '/payments/list',
				),
			)
		);

		// Make API call to ConvesioPay to find payment by order number
		$response = wp_remote_get( $config['api_url'] . '/payments/list?orderNumber=' . urlencode( $order_number ), array(
			'headers' => array(
				'Authorization' => $config['secret_key'],
				'Content-Type' => 'application/json',
			),
			'timeout' => 30,
		) );

		if ( is_wp_error( $response ) ) {
			peachpay_log(
				'error',
				'Payments: Find payment by order number failed.',
				array(
					'event'     => 'payments.convesiopay_gateway.find_payment_by_order_number.failed',
					'component' => 'payments',
					'feature'   => 'convesiopay_gateway',
					'operation' => 'find_payment_by_order_number',
					'outcome'   => 'failed',
					'method'    => __METHOD__,
					'line'      => __LINE__,
					'data'      => array(
						'order_number' => $order_number,
						'error_message' => $response->get_error_message(),
					),
				)
			);
			return false;
		}

		$response_code = wp_remote_retrieve_response_code( $response );
		$response_body = wp_remote_retrieve_body( $response );
		$response_data = json_decode( $response_body, true );

		if ( $response_code !== 200 || empty( $response_data['payments'] ) ) {
			peachpay_log(
				'warning',
				'Payments: Find payment by order number warning.',
				array(
					'event'     => 'payments.convesiopay_gateway.find_payment_by_order_number.warning',
					'component' => 'payments',
					'feature'   => 'convesiopay_gateway',
					'operation' => 'find_payment_by_order_number',
					'outcome'   => 'warning',
					'method'    => __METHOD__,
					'line'      => __LINE__,
					'data'      => array(
						'order_number' => $order_number,
						'response_code' => $response_code,
						'payments_count' => isset( $response_data['payments'] ) && is_array( $response_data['payments'] ) ? count( $response_data['payments'] ) : 0,
					),
				)
			);
			return false;
		}

		$payment_id = $response_data['payments'][0]['id'] ?? false;
		if ( $payment_id ) {
			peachpay_log(
				'info',
				'Payments: Find payment by order number success.',
				array(
					'event'     => 'payments.convesiopay_gateway.find_payment_by_order_number.success',
					'component' => 'payments',
					'feature'   => 'convesiopay_gateway',
					'operation' => 'find_payment_by_order_number',
					'outcome'   => 'success',
					'method'    => __METHOD__,
					'line'      => __LINE__,
					'data'      => array(
						'order_number' => $order_number,
						'payment_id' => $payment_id,
					),
				)
			);
		}
		return $payment_id;
	}

	/**
	 * Get transaction ID from request (following card gateway pattern)
	 */
	private function get_transaction_id_from_request() {
		
		// Method 1: Classic checkout - check POST data
		if ( isset( $_POST['peachpay_transaction_id'] ) && !empty( $_POST['peachpay_transaction_id'] ) ) {
			$transaction_id = sanitize_text_field( $_POST['peachpay_transaction_id'] );
			return $transaction_id;
		}
		
		// Method 2: WooCommerce Blocks - check for blocks payment method data
		$payment_method = $_POST['payment_method'] ?? '';
		if ( $payment_method === 'peachpay_convesiopay_unified' ) {
			
			// Check all possible locations where blocks might send the transaction ID
			$possible_locations = [
				'payment_method_data',
				'wc-peachpay_convesiopay_unified-transaction-id',
				'peachpay_convesiopay_unified_transaction_id',
				'meta',
				'paymentMethodData'
			];
			
			foreach ( $possible_locations as $location ) {
				if ( isset( $_POST[$location] ) ) {
					$data = $_POST[$location];
					
					if ( is_string( $data ) ) {
						// Try to decode if it's JSON
						$decoded = json_decode( stripslashes( $data ), true );
						if ( $decoded && isset( $decoded['peachpay_transaction_id'] ) ) {
							$transaction_id = sanitize_text_field( $decoded['peachpay_transaction_id'] );
							return $transaction_id;
						}
					}
					
					if ( is_array( $data ) && isset( $data['peachpay_transaction_id'] ) ) {
						$transaction_id = sanitize_text_field( $data['peachpay_transaction_id'] );
						return $transaction_id;
					}
				}
			}
		}

		// Method 3: Fallback to PHP/WooCommerce session.
		if ( session_status() === PHP_SESSION_ACTIVE ) {
			// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
			$session_transaction_id = $_SESSION['peachpay_transaction_id'] ?? '';
			if ( ! empty( $session_transaction_id ) ) {
				return sanitize_text_field( $session_transaction_id );
			}
		}

		if ( function_exists( 'WC' ) && WC()->session ) {
			$wc_transaction_id = WC()->session->get( 'peachpay_transaction_id' );
			if ( ! empty( $wc_transaction_id ) ) {
				return sanitize_text_field( $wc_transaction_id );
			}
		}
		
		return '';
	}

	/**
	 * Create fallback transaction ID (following card gateway pattern)
	 */
	private function create_fallback_transaction_id() {
		// Generate a transaction ID based on current time and random number
		$timestamp = time();
		$random = wp_rand( 1000, 9999 );
		$transaction_id = 'cvp_tx_' . $timestamp . '_' . $random;
		
		return $transaction_id;
	}

	/**
	 * Set PeachPay order details (following card gateway pattern)
	 */
	private function set_peachpay_order_details( $order, $session_id, $transaction_id ) {
		// Set order meta data
		$order->update_meta_data( '_peachpay_session_id', $session_id );
		$order->update_meta_data( '_peachpay_transaction_id', $transaction_id );
		$order->save();
	}

	/**
	 * Hide order actions on thank you/order received page for ConvesioPay orders
	 *
	 * @param int $order_id Order ID
	 */
	public function hide_order_actions_on_thankyou( $order_id ) {
		$order = wc_get_order( $order_id );
		if ( ! $order ) {
			return;
		}

		// Check if this order was processed through ConvesioPay
		$original_payment_method = $order->get_meta( '_original_payment_method' );
		$current_payment_method = $order->get_payment_method();

		if ( $original_payment_method === 'peachpay_convesiopay_unified' ||
		     in_array( $current_payment_method, array(
		     	'peachpay_convesiopay_unified',
		     	'peachpay_convesiopay_card',
		     	'peachpay_convesiopay_btcpay',
		     	'peachpay_convesiopay_applepay',
		     	'peachpay_convesiopay_googlepay'
		     ), true ) ) {

			// Hide order actions with CSS
			echo '<style>
				.woocommerce-order-details .order-actions,
				.woocommerce-order-details .order-actions--heading,
				.woocommerce-order .order-actions,
				.woocommerce-order .order-actions--heading,
				.order-actions,
				.order-actions-button,
				.woocommerce-button.pay,
				.woocommerce-button.cancel,
				a[aria-label*="Pay for order"],
				a[aria-label*="Cancel order"],
				a.button.pay,
				a.button.cancel {
					display: none !important;
				}
			</style>';
		}
	}

	/**
	 * Override test mode title to show normal title instead of test mode message
	 *
	 * @param string $title Gateway title
	 * @param string $gateway_id Gateway ID
	 * @return string
	 */
	public function override_test_mode_title( $title, $gateway_id ) {
		if ( $gateway_id === $this->id && is_checkout() ) {
			// Return the normal title instead of test mode message
			return $this->title;
		}
		return $title;
	}

	/**
	 * Override get_title to prevent test mode message
	 *
	 * @return string
	 */
	public function get_title() {
		if ( is_checkout() ) {
			return $this->title;
		}
		return parent::get_title();
	}

	/**
	 * Build card icons HTML string
	 *
	 * @return string HTML for card brand icons
	 */
	private function build_card_icons_html() {
		$icons_html = '';
		
		// Get individual card icon settings
		$card_icons_settings = get_option( 'peachpay_convesiopay_card_icons', array(
			'visa'       => 'no',
			'mastercard' => 'no',
			'amex'       => 'no',
			'discover'   => 'no',
		) );
		
		// Define all available card icons with their URLs
		$all_card_icons = array(
			'visa'       => PeachPay::get_asset_url( '/img/marks/visa.svg' ),
			'mastercard' => PeachPay::get_asset_url( '/img/marks/mastercard.svg' ),
			'amex'       => PeachPay::get_asset_url( '/img/marks/amex.svg' ),
			'discover'   => PeachPay::get_asset_url( '/img/marks/discover.svg' ),
		);

		// Only include icons that are enabled
		foreach ( $all_card_icons as $card_name => $icon_url ) {
			if ( isset( $card_icons_settings[ $card_name ] ) && $card_icons_settings[ $card_name ] === 'yes' ) {
				$icons_html .= sprintf(
					'<img src="%s" alt="%s" style="width: 40px; margin: 0px 1px; height: 25px;" />',
					esc_url( $icon_url ),
					esc_attr( ucfirst( $card_name ) )
				);
			}
		}

		return $icons_html;
	}

	/**
	 * Get the gateway icon - shows card brand icons if enabled
	 *
	 * @param bool   $flex       Whether to use flex layout.
	 * @param string $size       Icon size ('full' or 'small').
	 * @param string $background Icon background style.
	 * @return string HTML for the icon(s)
	 */
	public function get_icon( $flex = false, $size = 'full', $background = 'color' ) {
		// Don't show icons in admin - they're handled via JavaScript injection in card gateway
		if ( is_admin() ) {
			return '';
		}

		// Check if any card icons should be shown (using legacy option for backward compatibility)
		$show_card_icons = get_option( 'peachpay_convesiopay_show_card_icons', 'no' );
		
		if ( $show_card_icons !== 'yes' ) {
			return ''; // Return empty if icons are disabled
		}

		$icons_html = $this->build_card_icons_html();
		
		// Return empty if no icons are enabled
		if ( empty( $icons_html ) ) {
			return '';
		}

		return apply_filters( 'woocommerce_gateway_icon', $icons_html, $this->id );
	}

	/**
	 * Override payment_fields to prevent test mode notice
	 */
	public function payment_fields() {
		// Hidden div for checkout refresh - required for fee recalculation when payment method changes
		?>
		<div
			style="display:none"
			data-should-refresh-checkout="<?php echo esc_attr( $this->should_refresh_checkout() ); ?>"
			data-service-fee="<?php echo esc_attr( peachpay_gateway_has_service_fee( $this->id ) ? 'true' : 'false' ); ?>"
		></div>
		<?php

		// Hidden field to track selected payment method within ConvesioPay
		$selected_method = $this->get_selected_convesiopay_method();
		?>
		<input type="hidden" id="convesiopay_selected_method" name="convesiopay_selected_method" value="<?php echo esc_attr( $selected_method ); ?>" />
		
		<?php
		// Pass fee configuration for each payment method to frontend
		$card_gateway = $this->get_individual_gateway( 'card' );
		$applepay_gateway = $this->get_individual_gateway( 'applepay' );
		$googlepay_gateway = $this->get_individual_gateway( 'googlepay' );
		$btcpay_gateway = $this->get_individual_gateway( 'btcpay' );
		
		$fee_config = array(
			'card' => array(
				'enabled' => $card_gateway ? $card_gateway->get_option( 'fees_enabled' ) === 'yes' : false,
				'type' => $card_gateway ? $card_gateway->get_option( 'fee_type' ) : 'fixed',
				'amount' => $card_gateway ? floatval( $card_gateway->get_option( 'fee_amount' ) ) : 0,
				'label' => $card_gateway ? $card_gateway->get_option( 'fee_reason' ) : '',
			),
			'applepay' => array(
				'enabled' => $applepay_gateway ? $applepay_gateway->get_option( 'fees_enabled' ) === 'yes' : false,
				'type' => $applepay_gateway ? $applepay_gateway->get_option( 'fee_type' ) : 'fixed',
				'amount' => $applepay_gateway ? floatval( $applepay_gateway->get_option( 'fee_amount' ) ) : 0,
				'label' => $applepay_gateway ? $applepay_gateway->get_option( 'fee_reason' ) : '',
			),
			'googlepay' => array(
				'enabled' => $googlepay_gateway ? $googlepay_gateway->get_option( 'fees_enabled' ) === 'yes' : false,
				'type' => $googlepay_gateway ? $googlepay_gateway->get_option( 'fee_type' ) : 'fixed',
				'amount' => $googlepay_gateway ? floatval( $googlepay_gateway->get_option( 'fee_amount' ) ) : 0,
				'label' => $googlepay_gateway ? $googlepay_gateway->get_option( 'fee_reason' ) : '',
			),
			'btcpay' => array(
				'enabled' => $btcpay_gateway ? $btcpay_gateway->get_option( 'fees_enabled' ) === 'yes' : false,
				'type' => $btcpay_gateway ? $btcpay_gateway->get_option( 'fee_type' ) : 'fixed',
				'amount' => $btcpay_gateway ? floatval( $btcpay_gateway->get_option( 'fee_amount' ) ) : 0,
				'label' => $btcpay_gateway ? $btcpay_gateway->get_option( 'fee_reason' ) : '',
			),
		);
		
		// Get cart total for percentage calculations (subtotal - discount + shipping + tax, WITHOUT gateway fee)
		$cart_total = 0;
		if ( WC()->cart ) {
			$cart_total = WC()->cart->get_subtotal() - WC()->cart->get_discount_total() + WC()->cart->get_shipping_total() + WC()->cart->get_total_tax();
		}
		?>
		<script type="text/javascript">
			window.convesiopayFeeConfig = <?php echo wp_json_encode( $fee_config ); ?>;
			window.convesiopayCartTotal = <?php echo floatval( $cart_total ); ?>;
		</script>
		<?php

		if ( $this->description ) {
			echo wpautop( wptexturize( $this->description ) );
		}

		// Add ConvesioPay component container (min-height/min-width prevent layout shift during Adyen load)
		echo '<div id="convesiopay-unified-payment-container"></div>';

		// Skip parent payment_fields to avoid test mode notice
	}

	/**
	 * Extract unified payment data from both blocks and classic checkout
	 *
	 * @return array Payment data in consistent format
	 */
	private function extract_unified_payment_data() {

		if ( isset( $_POST['payment_method_data'] ) && is_string( $_POST['payment_method_data'] ) ) {
			$json_string = stripslashes( $_POST['payment_method_data'] );
			$decoded_data = json_decode( $json_string, true );

			if ( is_array( $decoded_data ) && ! empty( $decoded_data ) ) {
				return $decoded_data;
			}
		}

		// Method 3: Try direct $_POST access (fallback)
		if ( isset( $_POST['payment_method_data'] ) ) {
			$raw_data = $_POST['payment_method_data'];

			if ( is_array( $raw_data ) ) {
				return $raw_data;
			}
		}

		$payment_data_raw = $this->get_post_data( 'payment_method_data' );

		if ( is_array( $payment_data_raw ) && ! empty( $payment_data_raw ) ) {
			return $payment_data_raw;
		}

		// Express checkout: If we have convesiopay_payment_token directly, create payment data structure
		// This allows express checkout to work with unified gateway
		if ( isset( $_POST['convesiopay_payment_token'] ) && ! empty( $_POST['convesiopay_payment_token'] ) ) {
			// Check payment method type from POST data (express checkout sets this)
			$payment_method_type = isset( $_POST['payment_method_type'] ) ? sanitize_text_field( $_POST['payment_method_type'] ) : 'card';
			
			// Get raw token value - don't sanitize yet, we need to validate it first
			$payment_token_raw = $_POST['convesiopay_payment_token'];
			
			// Validate token format - Apple Pay tokens should be long strings without spaces
			// If it contains spaces or is too short, it's likely the wrong field
			if ( strpos( $payment_token_raw, ' ' ) !== false || strlen( trim( $payment_token_raw ) ) < 20 ) {
				// This might be the wrong field - check if it's actually a token
				// Apple Pay tokens are typically long alphanumeric strings
				if ( in_array( $payment_method_type, array( 'applepay', 'googlepay' ), true ) ) {
					// For Apple Pay, reject tokens with spaces or that are too short
					// Don't return empty - let it fall through to other extraction methods
				}
			}
			
			// Sanitize the token (but preserve the full value)
			$payment_token_sanitized = sanitize_text_field( $payment_token_raw );
			
			$payment_data = array(
				'convesiopay_payment_token' => $payment_token_sanitized,
				'payment_method_type' => $payment_method_type,
			);

			// Check if this is a BTCPay payment (token format: btc-session-{invoiceId})
			// Use the already sanitized token from payment_data
			$payment_token = $payment_data['convesiopay_payment_token'];
			
			if ( strpos( $payment_token, 'btc-session-' ) === 0 ) {
				// This is a BTCPay payment
				$payment_data['payment_method_type'] = 'btcpay';
				
				// Extract invoice ID from token if needed
				$invoice_id = str_replace( 'btc-session-', '', $payment_token );
				if ( ! empty( $invoice_id ) ) {
					$payment_data['invoiceId'] = $invoice_id;
					$payment_data['paymentId'] = $invoice_id;
				}

				// Extract BTCPay-specific fields from POST data
				if ( isset( $_POST['btcpay_invoice_id'] ) && ! empty( $_POST['btcpay_invoice_id'] ) ) {
					$payment_data['invoiceId'] = sanitize_text_field( $_POST['btcpay_invoice_id'] );
					$payment_data['paymentId'] = sanitize_text_field( $_POST['btcpay_invoice_id'] );
				}
				if ( isset( $_POST['btcpay_payment_id'] ) && ! empty( $_POST['btcpay_payment_id'] ) ) {
					$payment_data['paymentId'] = sanitize_text_field( $_POST['btcpay_payment_id'] );
				}
				if ( isset( $_POST['btcpay_status'] ) && ! empty( $_POST['btcpay_status'] ) ) {
					$payment_data['status'] = sanitize_text_field( $_POST['btcpay_status'] );
				}
				if ( isset( $_POST['btcpay_session_id'] ) && ! empty( $_POST['btcpay_session_id'] ) ) {
					$payment_data['btcpaySessionId'] = sanitize_text_field( $_POST['btcpay_session_id'] );
					$payment_data['btcpay_session_id'] = sanitize_text_field( $_POST['btcpay_session_id'] );
				}

				// Set default status if not provided
				if ( ! isset( $payment_data['status'] ) ) {
					$payment_data['status'] = 'Processing';
				}
			} elseif ( in_array( $payment_method_type, array( 'applepay', 'googlepay' ), true ) ) {
				$payment_data['payment_method_type'] = $payment_method_type;
				$payment_data['paymentMethod'] = $payment_method_type;

				$wallet_token = $payment_data['convesiopay_payment_token'];
				if ( strpos( $wallet_token, ' ' ) !== false || strlen( trim( $wallet_token ) ) < 20 ) {
					return array();
				}

				$amount_field = $payment_method_type === 'googlepay' ? 'googlepay_amount' : 'applepay_amount';
				$currency_field = $payment_method_type === 'googlepay' ? 'googlepay_currency' : 'applepay_currency';

				if ( isset( $_POST[ $amount_field ] ) && ! empty( $_POST[ $amount_field ] ) ) {
					$payment_data['amount'] = sanitize_text_field( $_POST[ $amount_field ] );
				}
				if ( isset( $_POST[ $currency_field ] ) && ! empty( $_POST[ $currency_field ] ) ) {
					$payment_data['currency'] = sanitize_text_field( $_POST[ $currency_field ] );
				}
				if ( isset( $_POST['convesiopay_status'] ) && ! empty( $_POST['convesiopay_status'] ) ) {
					$payment_data['status'] = sanitize_text_field( $_POST['convesiopay_status'] );
				} elseif ( isset( $_POST['status'] ) && ! empty( $_POST['status'] ) ) {
					$payment_data['status'] = sanitize_text_field( $_POST['status'] );
				} else {
					$payment_data['status'] = 'authorized';
				}
			}

			return $payment_data;
		}

		return array();
	}

	/**
	 * Get payment method type from request data
	 *
	 * @return string Payment method type (card, btcpay, applepay, etc.)
	 */
	private function get_payment_method_type_from_request() {
		// Check for payment_method_type in POST data (from JavaScript)
		if ( isset( $_POST['payment_method_data'] ) ) {
			$payment_method_data = is_string( $_POST['payment_method_data'] )
				? json_decode( stripslashes( $_POST['payment_method_data'] ), true )
				: $_POST['payment_method_data'];

			if ( is_array( $payment_method_data ) && isset( $payment_method_data['payment_method_type'] ) ) {
				$method_type = sanitize_text_field( $payment_method_data['payment_method_type'] );
				return $method_type;
			}
		}

		// Check direct POST parameter
		if ( isset( $_POST['payment_method_type'] ) ) {
			$method_type = sanitize_text_field( $_POST['payment_method_type'] );
			return $method_type;
		}

		// Check for payment token (indicates card payment)
		if ( isset( $_POST['convesiopay_payment_token'] ) && ! empty( $_POST['convesiopay_payment_token'] ) ) {
			return 'card';
		}

		// Default fallback
		return 'btcpay';
	}


	/**
	 * Hide gateway using CSS in admin head
	 */
	public function hide_gateway_with_css() {
		$screen = get_current_screen();
		if ( $screen && 'woocommerce_page_wc-settings' === $screen->id && isset($_GET['tab']) && $_GET['tab'] === 'checkout' ) {
			echo '<style>
				tr[data-gateway_id="' . $this->id . '"] { 
					display:none !important; 
				}
				#' . esc_attr( $this->id ) . '.woocommerce-item__payment-gateway {
					display: none !important;
				}
				
			</style>';
		}
	}

	/**
	 * Get list of active payment methods
	 * 
	 * @return array Array of active payment method keys ('card', 'applepay', 'googlepay', 'crypto')
	 */
	private function get_active_payment_methods() {
		$active_methods = array();
		
		// Check Card
		if ( PeachPay_ConvesioPay_Integration::is_capable( 'card' ) ) {
			$card_gateway = $this->get_individual_gateway( 'card' );
			if ( $this->is_individual_gateway_active_for_native_checkout( $card_gateway ) ) {
				$active_methods[] = 'card';
			}
		}
		
		// Check ApplePay
		if ( PeachPay_ConvesioPay_Integration::is_capable( 'applepay' ) ) {
			$applepay_gateway = $this->get_individual_gateway( 'applepay' );
			if ( $this->is_individual_gateway_active_for_native_checkout( $applepay_gateway ) ) {
				$active_methods[] = 'applepay';
			}
		}

		// Check Google Pay
		if ( PeachPay_ConvesioPay_Integration::is_capable( 'googlepay' ) ) {
			$googlepay_gateway = $this->get_individual_gateway( 'googlepay' );
			if ( $this->is_individual_gateway_active_for_native_checkout( $googlepay_gateway ) ) {
				$active_methods[] = 'googlepay';
			}
		}
		
		// Check Crypto/BTCPay
		if ( PeachPay_ConvesioPay_Integration::is_capable( 'btcpay' ) ) {
			$btcpay_gateway = $this->get_individual_gateway( 'btcpay' );
			if ( $this->is_individual_gateway_active_for_native_checkout( $btcpay_gateway ) ) {
				$active_methods[] = 'crypto';
			}
		}
		
		return $active_methods;
	}

	/**
	 * Get list of payment methods active in PeachPay Express Checkout.
	 *
	 * @return array Array of active payment method keys ('card', 'applepay', 'googlepay', 'crypto')
	 */
	private function get_peachpay_express_checkout_payment_methods() {
		$active_methods = array();

		// Check Card
		if ( PeachPay_ConvesioPay_Integration::is_capable( 'card' ) ) {
			$card_gateway = $this->get_individual_gateway( 'card' );
			if ( $this->is_individual_gateway_active_for_peachpay_express_checkout( $card_gateway ) ) {
				$active_methods[] = 'card';
			}
		}

		// Check ApplePay
		if ( PeachPay_ConvesioPay_Integration::is_capable( 'applepay' ) ) {
			$applepay_gateway = $this->get_individual_gateway( 'applepay' );
			if ( $this->is_individual_gateway_active_for_peachpay_express_checkout( $applepay_gateway ) ) {
				$active_methods[] = 'applepay';
			}
		}

		// Check Google Pay
		if ( PeachPay_ConvesioPay_Integration::is_capable( 'googlepay' ) ) {
			$googlepay_gateway = $this->get_individual_gateway( 'googlepay' );
			if ( $this->is_individual_gateway_active_for_peachpay_express_checkout( $googlepay_gateway ) ) {
				$active_methods[] = 'googlepay';
			}
		}

		// Check Crypto/BTCPay
		if ( PeachPay_ConvesioPay_Integration::is_capable( 'btcpay' ) ) {
			$btcpay_gateway = $this->get_individual_gateway( 'btcpay' );
			if ( $this->is_individual_gateway_active_for_peachpay_express_checkout( $btcpay_gateway ) ) {
				$active_methods[] = 'crypto';
			}
		}

		return $active_methods;
	}

}
