я пишу бот автопродаж на aiogram 2, в частности версия 2.25.1

есть проблема: я нашел проблему она была в функции process_category_selection в строке:
button = InlineKeyboardButton(product['name'], callback_data=f"product_{product['id']}")

тут добавлялся префикс product_ к id, я убрал, но проблема почти та же, только теперь бот никак не реагирует на кнопку с товаром

структура products.json:
{
    "categories": [
      {
        "name": "Тиктокерши",
        "products": [
        ]
      },
      {
        "name": "Стримерши",
        "products": [
            {
                "id": "dilara_1",
                "name": "Дилара",
                "description": "дилара описание", 
                "preview_image": "dilara_preview.png", 
                "old_price": 3999,
                "current_price": 790
              }
        ]
      },
      {
        "name": "Ютуберши/Блогерши",
        "products": []
      }
    ]
  }

Полный код проекта с понятной структурой:
Код файла D:/python projects/!MIREL\bot.py:
from aiogram import Bot, Dispatcher, executor
from aiogram.contrib.middlewares.logging import LoggingMiddleware
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from configparser import ConfigParser
from middleware.subscription_middleware import SubscriptionMiddleware
import handlers
import states

# Загружаем конфигурацию
config = ConfigParser()
config.read('settings.cfg')
API_TOKEN = config['Bot']['token']

bot = Bot(token=API_TOKEN)
storage = MemoryStorage()
dp = Dispatcher(bot, storage=storage)

# Подключаем миддлвары
dp.middleware.setup(SubscriptionMiddleware(bot))
dp.middleware.setup(LoggingMiddleware())

# Регистрация обработчиков
handlers.register_handlers(dp, bot)
states.register_states(dp)

if __name__ == '__main__':
    executor.start_polling(dp, skip_updates=True)
Код файла D:/python projects/!MIREL\handlers.py:
from aiogram import types
from aiogram.dispatcher import Dispatcher, FSMContext
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton, InlineKeyboardMarkup, InlineKeyboardButton
import database.db_module as db_module
from states import UserState
import logging
import random
import json
import os
import re

logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")

# Глобальная переменная для хранения file_id
photo_file_id = None

# Загрузка данных о товарах
with open('products.json', 'r', encoding='utf-8') as file:
    products_data = json.load(file)

def escape_markdown_v2(text):
    escape_chars = r'_*[]()~`>#+-=|{}.!'
    return ''.join(f'\\{c}' if c in escape_chars else c for c in str(text))

# Функция для отправки главного меню с кнопками
async def send_main_menu(message: types.Message):
    keyboard = ReplyKeyboardMarkup(resize_keyboard=True)
    personal_account_button = KeyboardButton("🏠 Личный кабинет")
    products_button = KeyboardButton("🛒 Товары")
    support_button = KeyboardButton("💬 Техподдержка")
    
    keyboard.add(personal_account_button, products_button)
    keyboard.add(support_button)
    
    await message.answer("Добро пожаловать! Выберите опцию:", reply_markup=keyboard)

# Новый обработчик для кнопки "Главное меню"
async def main_menu(callback_query: types.CallbackQuery, state: FSMContext):
    await send_main_menu(callback_query.message)
    await UserState.waiting_for_choice.set()
    await callback_query.answer()

# Функция для отправки сообщения о подписке
async def send_subscription_message(message: types.Message):
    keyboard = InlineKeyboardMarkup()
    subscribe_button = InlineKeyboardButton("ПОДПИСАТЬСЯ", url="https://t.me/mirel_porn")
    confirm_button = InlineKeyboardButton("Я ПОДПИСАЛСЯ", callback_data="confirm_subscription")
    keyboard.add(subscribe_button, confirm_button)
    
    await message.answer(
        "Чтобы использовать бота, подпишитесь на канал и нажмите \"Я ПОДПИСАЛСЯ.\"",
        reply_markup=keyboard
    )

# Обработчик команды /start
async def start_command(message: types.Message, state: FSMContext):
    db_module.add_user(message.from_user.id)
    
    if db_module.check_subscription(message.from_user.id):
        await send_main_menu(message)
        await UserState.waiting_for_choice.set()
    else:
        await send_subscription_message(message)
        await UserState.waiting_for_subscription.set()

# Обработчик выбора кнопок меню
async def handle_user_choice(message: types.Message, state: FSMContext):
    current_state = await state.get_state()
    if current_state not in [UserState.waiting_for_choice.state, UserState.selecting_category.state]:
        await message.answer("Пожалуйста, начните с команды /start")
        return

    if message.text == "🏠 Личный кабинет":
        await handle_personal_account(message, state)
    elif message.text == "🛒 Товары":
        await show_products(message, state)
    elif message.text == "💬 Техподдержка":
        await handle_tech_support(message, state)
    elif message.text == "🔙 Главное меню":
        await send_main_menu(message)
        await UserState.waiting_for_choice.set()
    else:
        await message.answer("Неизвестный выбор. Попробуйте снова.")

async def handle_tech_support(message: types.Message, state: FSMContext):
    message_text = """
🛒 *MIREL* \- лучшие сливы селебрити\\!

🆘 *Поддержка* \- @mirel\_support

Мы ценим каждого клиента и стремимся предоставить наилучшее обслуживание и помощь в любых вопросах\.

🕑 *Отвечаем с 10:00 \- 20:00 по МСК*
📅 *Без выходных\!*
    """
    await message.answer(message_text, parse_mode=types.ParseMode.MARKDOWN_V2)

# Обработчик подтверждения подписки
async def process_confirmation(callback_query: types.CallbackQuery, state: FSMContext):
    user_id = callback_query.from_user.id
    try:
        member = await callback_query.bot.get_chat_member(chat_id="@mirel_porn", user_id=user_id)
        if member.status in ['member', 'administrator', 'creator']:
            db_module.set_subscription_status(user_id, 1)
            await callback_query.message.answer("Спасибо за подписку! Теперь вы можете использовать бота.")
            await send_main_menu(callback_query.message)
            await UserState.waiting_for_choice.set()
        else:
            await callback_query.message.answer("Пожалуйста, сначала подпишитесь на канал.")
            await send_subscription_message(callback_query.message)
            await UserState.waiting_for_subscription.set()
    except Exception as e:
        await callback_query.message.answer("Не удалось проверить подписку.")
    finally:
        await callback_query.answer()

async def handle_personal_account(message: types.Message, state: FSMContext):
    user_id = message.from_user.id
    user_data = db_module.get_user_data(user_id)

    balance = user_data['balance']
    purchase_history = user_data['purchase_history']
    
    # Форматируем историю покупок
    history = '\n'.join(escape_markdown_v2(item) for item in purchase_history) if purchase_history else 'Нет покупок'

    keyboard = InlineKeyboardMarkup()
    top_up_button = InlineKeyboardButton("💳 Пополнить баланс", callback_data="top_up_balance")
    keyboard.add(top_up_button)

    message_text = f"""
👤 *Личный кабинет*

💰 *Ваш баланс:* {escape_markdown_v2(balance)} руб\.

*История покупок:*
{history}
    """
    
    try:
        await message.answer(message_text, reply_markup=keyboard, parse_mode=types.ParseMode.MARKDOWN_V2)
    except Exception as e:
        print(f"Ошибка при отправке сообщения: {e}")
        # Если возникла ошибка, попробуем отправить сообщение без форматирования
        await message.answer("Произошла ошибка при форматировании сообщения. Пожалуйста, обратитесь в поддержку.")

    await UserState.waiting_for_choice.set()

# Обработчик для кнопки "Пополнить баланс"
async def handle_top_up_balance(callback_query: types.CallbackQuery):
    await callback_query.answer("Функция пополнения баланса временно недоступна. Попробуйте позже.", show_alert=True)

# Обновленная функция show_products
async def show_products(message: types.Message, state: FSMContext):
    global photo_file_id
    
    keyboard = InlineKeyboardMarkup(row_width=1)
    for category in products_data['categories']:
        button = InlineKeyboardButton(category['name'], callback_data=f"category_{category['name']}")
        keyboard.add(button)
    
    # Добавляем inline кнопку "Главное меню"
    main_menu_button = InlineKeyboardButton("🔙 Главное меню", callback_data="main_menu")
    keyboard.add(main_menu_button)

    captions = [
        "🔥 УВИДЕТЬ СЛИВЫ! 🔥",
        "🔞 ОНИ ХОТЕЛИ СКРЫТЬ ЭТО! 🔞",
        "🤫 ТЫ НЕ ГОТОВ... ИЛИ ГОТОВ? 😉",
        "🚀 ЭКСКЛЮЗИВНЫЙ КОНТЕНТ ЗДЕСЬ! 🚀",
        "🔞 🔞 🔞",
        "Ты не готов к этому... Но можешь попробовать 😉"
    ]

    if not photo_file_id:
        photo_path = os.path.join('RESOURSES', 'SHOP_PREVIEW.png')
        with open(photo_path, 'rb') as photo:
            sent_photo = await message.answer_photo(
                photo,
                caption=random.choice(captions),
                reply_markup=keyboard
            )
            photo_file_id = sent_photo.photo[-1].file_id
    else:
        await message.answer_photo(
            photo_file_id,
            caption=random.choice(captions),
            reply_markup=keyboard
        )

    await UserState.selecting_category.set()

# Обновленный обработчик выбора категории
async def process_category_selection(callback_query: types.CallbackQuery, state: FSMContext):
    category_name = callback_query.data.split('_')[1]
    
    # Находим выбранную категорию
    category = next((cat for cat in products_data['categories'] if cat['name'] == category_name), None)
    
    if category and category['products']:
        keyboard = InlineKeyboardMarkup(row_width=2)
        for product in category['products']:
            button = InlineKeyboardButton(product['name'], callback_data=f"{product['id']}")
            keyboard.add(button)
        
        back_button = InlineKeyboardButton("🔙 Назад", callback_data="back_to_categories")
        keyboard.add(back_button)
        
        # Используем edit_caption вместо edit_text
        await callback_query.message.edit_caption(
            caption=f"Товары в категории {category_name}:",
            reply_markup=keyboard
        )
        await UserState.selecting_product.set()
    else:
        # Если в категории нет товаров, просто отвечаем на callback
        await callback_query.answer("В этой категории пока нет товаров.")
    
    # Отвечаем на callback, чтобы убрать "часики" у кнопки
    await callback_query.answer()

# Обновленный обработчик для кнопки "Назад"
async def back_to_categories(callback_query: types.CallbackQuery, state: FSMContext):
    keyboard = InlineKeyboardMarkup(row_width=1)
    for category in products_data['categories']:
        button = InlineKeyboardButton(category['name'], callback_data=f"category_{category['name']}")
        keyboard.add(button)
    
    main_menu_button = InlineKeyboardButton("🔙 Главное меню", callback_data="main_menu")
    keyboard.add(main_menu_button)

    caption = "Выберите категорию:"
    
    # Используем edit_caption для редактирования подписи к фото
    await callback_query.message.edit_caption(
        caption=caption,
        reply_markup=keyboard
    )
    
    await UserState.selecting_category.set()
    await callback_query.answer()

# Обновленный обработчик выбора товара
async def process_product_selection(callback_query: types.CallbackQuery, state: FSMContext):
    product_id = callback_query.data.split('_')[1]
    
    # Находим выбранный товар
    product = None
    for category in products_data['categories']:
        for prod in category['products']:
            if prod['id'] == product_id:
                product = prod
                break
        if product:
            break
    
    if product:
        # Формируем сообщение с информацией о товаре
        message_text = f"""
*{escape_markdown_v2(product['name'])}*

{escape_markdown_v2(product['description'])}

💰 Старая цена: {escape_markdown_v2(str(product['old_price']))} руб\.
🔥 Новая цена: {escape_markdown_v2(str(product['current_price']))} руб\.
        """
        
        keyboard = InlineKeyboardMarkup()
        buy_button = InlineKeyboardButton("💳 Купить", callback_data=f"buy_{product_id}")
        back_button = InlineKeyboardButton("🔙 Назад", callback_data="back_to_products")
        keyboard.add(buy_button, back_button)
        
        # Отправляем фото товара с описанием
        with open(os.path.join('RESOURSES', product['preview_image']), 'rb') as photo:
            await callback_query.message.answer_photo(
                photo,
                caption=message_text,
                reply_markup=keyboard,
                parse_mode=types.ParseMode.MARKDOWN_V2
            )
        
        # Удаляем предыдущее сообщение со списком товаров
        await callback_query.message.delete()
    else:
        await callback_query.answer("Товар не найден.")
    
    await callback_query.answer()

# Обработчик для кнопки "Назад к товарам"
async def back_to_products(callback_query: types.CallbackQuery, state: FSMContext):
    async with state.proxy() as data:
        category_name = data.get('selected_category')
    
    if category_name:
        await process_category_selection(callback_query, state)
    else:
        await show_products(callback_query.message, state)
    
    await callback_query.answer()



def register_handlers(dp: Dispatcher, bot):
    dp.register_message_handler(start_command, commands=["start"], state="*")
    dp.register_message_handler(handle_user_choice, lambda message: message.text in ["🏠 Личный кабинет", "🛒 Товары", "💬 Техподдержка", "🔙 Главное меню"], state="*")
    dp.register_callback_query_handler(process_confirmation, lambda c: c.data == "confirm_subscription", state="*")
    dp.register_callback_query_handler(handle_top_up_balance, lambda c: c.data == "top_up_balance", state="*")
    dp.register_callback_query_handler(process_category_selection, lambda c: c.data.startswith("category_"), state=UserState.selecting_category)
    dp.register_callback_query_handler(back_to_categories, lambda c: c.data == "back_to_categories", state=UserState.selecting_product)
    dp.register_callback_query_handler(process_product_selection, lambda c: c.data.startswith("product_"), state=UserState.selecting_product)
    dp.register_callback_query_handler(back_to_products, lambda c: c.data == "back_to_products", state="*")
    dp.register_callback_query_handler(main_menu, lambda c: c.data == "main_menu", state="*")
Код файла D:/python projects/!MIREL\states.py:
from aiogram.dispatcher.filters.state import StatesGroup, State

class UserState(StatesGroup):
    waiting_for_subscription = State()
    waiting_for_choice = State()
    personal_account = State()
    viewing_products = State()
    selecting_category = State()
    selecting_product = State()

def register_states(dp):
    pass
Код файла D:/python projects/!MIREL\database\db_module.py:
import sqlite3
import os

def get_db_path():
    return os.path.join(os.path.dirname(__file__), 'users.db')

def add_user(user_id):
    conn = sqlite3.connect(get_db_path())
    cursor = conn.cursor()
    cursor.execute('''
        INSERT OR IGNORE INTO users (user_id) VALUES (?)
    ''', (user_id,))
    conn.commit()
    conn.close()

def set_subscription_status(user_id, is_subscribed):
    conn = sqlite3.connect(get_db_path())
    cursor = conn.cursor()
    cursor.execute('''
        UPDATE users SET is_subscribed = ? WHERE user_id = ?
    ''', (is_subscribed, user_id))
    conn.commit()
    conn.close()

def check_subscription(user_id):
    conn = sqlite3.connect(get_db_path())
    cursor = conn.cursor()
    cursor.execute('SELECT is_subscribed FROM users WHERE user_id = ?', (user_id,))
    result = cursor.fetchone()
    conn.close()
    return result and result[0] == 1

def get_user_data(user_id):
    conn = sqlite3.connect(get_db_path())
    cursor = conn.cursor()
    cursor.execute('SELECT balance, purchase_history FROM users WHERE user_id = ?', (user_id,))
    result = cursor.fetchone()
    conn.close()

    return {
        'balance': result[0],
        'purchase_history': eval(result[1]) if result[1] else []
    }

Код файла D:/python projects/!MIREL\database\edit_db.py:
import sqlite3
import os

# Определяем путь к базе данных
db_path = os.path.join(os.path.dirname(__file__), 'users.db')

# Функция для добавления новых столбцов в существующую таблицу
def add_columns_to_users():
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()

    # Добавление новых столбцов, если они не существуют
    try:
        cursor.execute('ALTER TABLE users ADD COLUMN balance REAL DEFAULT 0')
        cursor.execute('ALTER TABLE users ADD COLUMN purchase_history TEXT DEFAULT "[]"')
    except sqlite3.OperationalError as e:
        print(f"Ошибка: {e}")

    conn.commit()
    conn.close()

if __name__ == '__main__':
    # Добавление новых столбцов при запуске скрипта
    add_columns_to_users()
    print(f"База данных обновлена по пути: {db_path}")
Код файла D:/python projects/!MIREL\middleware\subscription_middleware.py:
from aiogram import types
from aiogram.dispatcher.middlewares import BaseMiddleware
from aiogram.dispatcher import FSMContext
import database.db_module as db_module
from states import UserState

class SubscriptionMiddleware(BaseMiddleware):
    def __init__(self, bot):
        super(SubscriptionMiddleware, self).__init__()
        self.bot = bot

    async def on_process_message(self, message: types.Message, data: dict):
        if message.text == '/start':
            return

        # Получаем state из data
        state: FSMContext = data.get('state')
        if state is None:
            return False

        current_state = await state.get_state()
        user_id = message.from_user.id

        if not db_module.check_subscription(user_id) and current_state != UserState.waiting_for_subscription.state:
            await message.answer("Пожалуйста, подпишитесь на канал, чтобы использовать бота.")
            await state.set_state(UserState.waiting_for_subscription)
            return False
        return True

    async def on_process_callback_query(self, callback_query: types.CallbackQuery, data: dict):
        # Разрешаем все callback запросы
        return True