Private
Public Access
forked from FOSS/AutoShop-Djimbo-Simple
feat: add Lolzteam payment integration
This commit is contained in:
+1
-20
@@ -168,23 +168,4 @@ def validate_bot_config() -> None:
|
|||||||
def get_text_desc() -> str:
|
def get_text_desc() -> str:
|
||||||
from tgbot.utils.const_functions import ded
|
from tgbot.utils.const_functions import ded
|
||||||
|
|
||||||
return ded(f"""
|
return ded(f"""<b>♻️ Версия бота: <code>{BOT_VERSION}</code>""").strip()
|
||||||
<b>♻️ Версия бота: <code>{BOT_VERSION}</code>
|
|
||||||
👑 Разработчик бота - @djimbox
|
|
||||||
🍩 Донат разработчику: <a href='https://t.me/send?start=IV8bjPKhYkYJ'>Click me</a>
|
|
||||||
🤖 Новости и обновления: <a href='https://t.me/DJIMBO_SHOP'>Click me</a>
|
|
||||||
🔗 Тема с ботом [LOLZ]: <a href='https://lolz.guru/threads/1888814'>Click me</a></b>
|
|
||||||
""").strip()
|
|
||||||
|
|
||||||
|
|
||||||
# Получение варнинг-текста
|
|
||||||
def get_text_warning() -> str:
|
|
||||||
from tgbot.utils.const_functions import ded
|
|
||||||
|
|
||||||
return ded(f"""
|
|
||||||
❗️ Если вы видите данное сообщение, значит <u>Администратор</u> бота не изменил текст установленный
|
|
||||||
по умолчанию. Скорее всего данный бот занимается <u>скамом, обманом</u> или другими схожими действиями.
|
|
||||||
|
|
||||||
❗️ Если вас обманули, не надо писать <b><u>РАЗРАБОТЧИКУ</u></b> бота, он ничем не сможет помочь. Бот является
|
|
||||||
открытым и распространяется публично. Абсолютно любой желающий мог его запустить.
|
|
||||||
""")
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ from typing import Any, Dict, Optional
|
|||||||
|
|
||||||
from sqlalchemy import Integer, String, Float
|
from sqlalchemy import Integer, String, Float
|
||||||
from sqlalchemy.orm import Mapped, mapped_column
|
from sqlalchemy.orm import Mapped, mapped_column
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncConnection
|
||||||
|
|
||||||
from tgbot.database.core import Base
|
from tgbot.database.core import Base
|
||||||
from tgbot.database.entities import Payments
|
from tgbot.database.entities import Payments
|
||||||
@@ -22,11 +23,81 @@ class PaymentsModel(Base):
|
|||||||
String(16), nullable=False, default="False"
|
String(16), nullable=False, default="False"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Оплата через Lolzteam
|
||||||
|
lolzteam_token: Mapped[str] = mapped_column(String, nullable=False, default="None")
|
||||||
|
lolzteam_merchant_id: Mapped[Optional[int]] = mapped_column(
|
||||||
|
Integer, nullable=True, default=None
|
||||||
|
)
|
||||||
|
status_lolzteam: Mapped[str] = mapped_column(
|
||||||
|
String(16), nullable=False, default="False"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
ModelBase = Payments
|
ModelBase = Payments
|
||||||
BaseModel = Payments
|
BaseModel = Payments
|
||||||
|
|
||||||
|
|
||||||
|
async def ensure_payments_schema(conn: AsyncConnection) -> None:
|
||||||
|
columns = (
|
||||||
|
await conn.exec_driver_sql("PRAGMA table_info(storage_payments)")
|
||||||
|
).mappings().all()
|
||||||
|
|
||||||
|
if not columns:
|
||||||
|
return
|
||||||
|
|
||||||
|
merchant_column = next(
|
||||||
|
(column for column in columns if column["name"] == "lolzteam_merchant_id"),
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
|
||||||
|
if merchant_column is None or merchant_column["notnull"] == 0:
|
||||||
|
return
|
||||||
|
|
||||||
|
await conn.exec_driver_sql(
|
||||||
|
"ALTER TABLE storage_payments RENAME TO storage_payments__legacy"
|
||||||
|
)
|
||||||
|
await conn.exec_driver_sql(
|
||||||
|
"""
|
||||||
|
CREATE TABLE storage_payments (
|
||||||
|
id INTEGER NOT NULL,
|
||||||
|
cryptobot_token VARCHAR NOT NULL,
|
||||||
|
stars_course FLOAT NOT NULL,
|
||||||
|
status_cryptobot VARCHAR(16) NOT NULL,
|
||||||
|
status_stars VARCHAR(16) NOT NULL,
|
||||||
|
lolzteam_token VARCHAR NOT NULL,
|
||||||
|
lolzteam_merchant_id INTEGER,
|
||||||
|
status_lolzteam VARCHAR(16) NOT NULL,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
)
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
await conn.exec_driver_sql(
|
||||||
|
"""
|
||||||
|
INSERT INTO storage_payments (
|
||||||
|
id,
|
||||||
|
cryptobot_token,
|
||||||
|
stars_course,
|
||||||
|
status_cryptobot,
|
||||||
|
status_stars,
|
||||||
|
lolzteam_token,
|
||||||
|
lolzteam_merchant_id,
|
||||||
|
status_lolzteam
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
cryptobot_token,
|
||||||
|
stars_course,
|
||||||
|
status_cryptobot,
|
||||||
|
status_stars,
|
||||||
|
lolzteam_token,
|
||||||
|
lolzteam_merchant_id,
|
||||||
|
status_lolzteam
|
||||||
|
FROM storage_payments__legacy
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
await conn.exec_driver_sql("DROP TABLE storage_payments__legacy")
|
||||||
|
|
||||||
|
|
||||||
class Paymentsx(BaseRepository[PaymentsModel, Payments]):
|
class Paymentsx(BaseRepository[PaymentsModel, Payments]):
|
||||||
# Подключение модели платежных настроек
|
# Подключение модели платежных настроек
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
# - *- coding: utf- 8 - *-
|
# - *- coding: utf- 8 - *-
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -40,6 +41,12 @@ class Payments:
|
|||||||
status_cryptobot: str
|
status_cryptobot: str
|
||||||
status_stars: str
|
status_stars: str
|
||||||
|
|
||||||
|
# Оплата через Lolzteam
|
||||||
|
lolzteam_token: str
|
||||||
|
lolzteam_merchant_id: Optional[int]
|
||||||
|
|
||||||
|
status_lolzteam: str
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class Purchase:
|
class Purchase:
|
||||||
|
|||||||
@@ -162,6 +162,10 @@ async def prepare_database() -> None:
|
|||||||
import tgbot.database.db_users # noqa: F401
|
import tgbot.database.db_users # noqa: F401
|
||||||
|
|
||||||
async with engine.begin() as conn:
|
async with engine.begin() as conn:
|
||||||
|
from tgbot.database.db_payments import ensure_payments_schema
|
||||||
|
|
||||||
|
await ensure_payments_schema(conn)
|
||||||
|
|
||||||
await conn.run_sync(Base.metadata.create_all)
|
await conn.run_sync(Base.metadata.create_all)
|
||||||
|
|
||||||
from tgbot.database.db_payments import Paymentsx
|
from tgbot.database.db_payments import Paymentsx
|
||||||
|
|||||||
@@ -98,6 +98,43 @@ async def payment_cryptobot_finl() -> InlineKeyboardMarkup:
|
|||||||
return keyboard.as_markup()
|
return keyboard.as_markup()
|
||||||
|
|
||||||
|
|
||||||
|
# Управление - Lolzteam
|
||||||
|
async def payment_lolzteam_finl() -> InlineKeyboardMarkup:
|
||||||
|
keyboard = InlineKeyboardBuilder()
|
||||||
|
|
||||||
|
get_payments = await Paymentsx().get()
|
||||||
|
|
||||||
|
if get_payments.lolzteam_token == "None":
|
||||||
|
assets_symbol = "➖"
|
||||||
|
else:
|
||||||
|
assets_symbol = "➕"
|
||||||
|
|
||||||
|
if get_payments.status_lolzteam == "True":
|
||||||
|
status_kb = ikb(
|
||||||
|
f"{assets_symbol} | Статус: Включено ✅",
|
||||||
|
data="payment_lolzteam_status:False",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
status_kb = ikb(
|
||||||
|
f"{assets_symbol} | Статус: Выключено ❌",
|
||||||
|
data="payment_lolzteam_status:True",
|
||||||
|
)
|
||||||
|
|
||||||
|
keyboard.row(
|
||||||
|
ikb("Информация ♻️", data="payment_lolzteam_check"),
|
||||||
|
).row(
|
||||||
|
ikb("Баланс 💰", data="payment_lolzteam_balance"),
|
||||||
|
).row(
|
||||||
|
ikb("Изменить 🖍", data="payment_lolzteam_edit"),
|
||||||
|
).row(
|
||||||
|
ikb("", data="..."),
|
||||||
|
).row(
|
||||||
|
status_kb,
|
||||||
|
)
|
||||||
|
|
||||||
|
return keyboard.as_markup()
|
||||||
|
|
||||||
|
|
||||||
# Управление - Звёзды
|
# Управление - Звёзды
|
||||||
async def payment_stars_finl() -> InlineKeyboardMarkup:
|
async def payment_stars_finl() -> InlineKeyboardMarkup:
|
||||||
keyboard = InlineKeyboardBuilder()
|
keyboard = InlineKeyboardBuilder()
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ async def category_edit_open_finl(
|
|||||||
).row(
|
).row(
|
||||||
ikb(
|
ikb(
|
||||||
"▪️ Скопировать ссылку",
|
"▪️ Скопировать ссылку",
|
||||||
copy=f"t.me/{get_bot.username}?start=c_{category_id}",
|
copy=f"telegram.me/{get_bot.username}?start=c_{category_id}",
|
||||||
),
|
),
|
||||||
ikb("▪️ Удалить", data=f"category_edit_delete:{category_id}:{remover}"),
|
ikb("▪️ Удалить", data=f"category_edit_delete:{category_id}:{remover}"),
|
||||||
).row(
|
).row(
|
||||||
@@ -85,7 +85,7 @@ async def position_edit_open_finl(
|
|||||||
).row(
|
).row(
|
||||||
ikb(
|
ikb(
|
||||||
"▪️ Скопировать ссылку",
|
"▪️ Скопировать ссылку",
|
||||||
copy=f"t.me/{get_bot.username}?start=p_{position_id}",
|
copy=f"telegram.me/{get_bot.username}?start=p_{position_id}",
|
||||||
),
|
),
|
||||||
ikb("▪️ Удалить Позицию", data=f"position_edit_delete:{position_id}:{remover}"),
|
ikb("▪️ Удалить Позицию", data=f"position_edit_delete:{position_id}:{remover}"),
|
||||||
).row(
|
).row(
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ def user_support_finl(support_login: str) -> InlineKeyboardMarkup:
|
|||||||
keyboard = InlineKeyboardBuilder()
|
keyboard = InlineKeyboardBuilder()
|
||||||
|
|
||||||
keyboard.row(
|
keyboard.row(
|
||||||
ikb("💌 Написать в поддержку", url=f"https://t.me/{support_login}"),
|
ikb("💌 Написать в поддержку", url=f"https://telegram.me/{support_login}"),
|
||||||
)
|
)
|
||||||
|
|
||||||
return keyboard.as_markup()
|
return keyboard.as_markup()
|
||||||
@@ -43,6 +43,8 @@ async def refill_method_finl() -> InlineKeyboardMarkup:
|
|||||||
|
|
||||||
if get_payments.status_cryptobot == "True":
|
if get_payments.status_cryptobot == "True":
|
||||||
keyboard.row(ikb("🔷 CryptoBot", data="user_refill_method:Cryptobot"))
|
keyboard.row(ikb("🔷 CryptoBot", data="user_refill_method:Cryptobot"))
|
||||||
|
if get_payments.status_lolzteam == "True":
|
||||||
|
keyboard.row(ikb("🟢 Lolzteam", data="user_refill_method:Lolzteam"))
|
||||||
if get_payments.status_stars == "True":
|
if get_payments.status_stars == "True":
|
||||||
keyboard.row(ikb("⭐️ Звёзды", data="user_refill_method:Stars"))
|
keyboard.row(ikb("⭐️ Звёзды", data="user_refill_method:Stars"))
|
||||||
|
|
||||||
@@ -74,6 +76,8 @@ async def refill_method_buy_finl() -> InlineKeyboardMarkup:
|
|||||||
|
|
||||||
if get_payments.status_cryptobot == "True":
|
if get_payments.status_cryptobot == "True":
|
||||||
keyboard.row(ikb("🔷 CryptoBot", data="user_refill_method:Cryptobot"))
|
keyboard.row(ikb("🔷 CryptoBot", data="user_refill_method:Cryptobot"))
|
||||||
|
if get_payments.status_lolzteam == "True":
|
||||||
|
keyboard.row(ikb("🟢 Lolzteam", data="user_refill_method:Lolzteam"))
|
||||||
if get_payments.status_stars == "True":
|
if get_payments.status_stars == "True":
|
||||||
keyboard.row(ikb("⭐️ Звёзды", data="user_refill_method:Stars"))
|
keyboard.row(ikb("⭐️ Звёзды", data="user_refill_method:Stars"))
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ def payments_frep() -> ReplyKeyboardMarkup:
|
|||||||
|
|
||||||
keyboard.row(
|
keyboard.row(
|
||||||
rkb("🔷 CryptoBot"),
|
rkb("🔷 CryptoBot"),
|
||||||
|
rkb("🟢 Lolzteam"),
|
||||||
rkb("⭐️ Звёзды"),
|
rkb("⭐️ Звёзды"),
|
||||||
).row(
|
).row(
|
||||||
rkb("🔙 Главное меню"),
|
rkb("🔙 Главное меню"),
|
||||||
|
|||||||
@@ -7,9 +7,11 @@ from tgbot.database import Paymentsx
|
|||||||
from tgbot.keyboards.inline_admin import (
|
from tgbot.keyboards.inline_admin import (
|
||||||
close_finl,
|
close_finl,
|
||||||
payment_cryptobot_finl,
|
payment_cryptobot_finl,
|
||||||
|
payment_lolzteam_finl,
|
||||||
payment_stars_finl,
|
payment_stars_finl,
|
||||||
)
|
)
|
||||||
from tgbot.services.api_cryptobot import CryptobotAPI
|
from tgbot.services.api_cryptobot import CryptobotAPI
|
||||||
|
from tgbot.services.api_lolzteam import LolzteamAPI
|
||||||
from tgbot.services.api_stars import StarsAPI
|
from tgbot.services.api_stars import StarsAPI
|
||||||
from tgbot.utils.const_functions import ded, is_number, to_number
|
from tgbot.utils.const_functions import ded, is_number, to_number
|
||||||
from tgbot.utils.misc.bot_models import FSM, ARS
|
from tgbot.utils.misc.bot_models import FSM, ARS
|
||||||
@@ -30,6 +32,19 @@ async def payments_cryptobot_open(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Управление - Lolzteam
|
||||||
|
@router.message(F.text == "🟢 Lolzteam")
|
||||||
|
async def payments_cryptobot_open(
|
||||||
|
message: Message, bot: Bot, state: FSM, arSession: ARS
|
||||||
|
):
|
||||||
|
await state.clear()
|
||||||
|
|
||||||
|
await message.answer(
|
||||||
|
"<b>🟢 Управление - Lolzteam</b>",
|
||||||
|
reply_markup=await payment_lolzteam_finl(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Управление - Звёзды
|
# Управление - Звёзды
|
||||||
@router.message(F.text == "⭐️ Звёзды")
|
@router.message(F.text == "⭐️ Звёзды")
|
||||||
async def payments_stars_open(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
async def payments_stars_open(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||||
@@ -161,6 +176,163 @@ async def payments_cryptobot_get(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
################################### LOLZTEAM ##################################
|
||||||
|
# Баланс - Lolzteam
|
||||||
|
@router.callback_query(F.data == "payment_lolzteam_balance")
|
||||||
|
async def payments_lolzteam_balance(
|
||||||
|
call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS
|
||||||
|
):
|
||||||
|
response = await (
|
||||||
|
await LolzteamAPI.connect(
|
||||||
|
bot=bot,
|
||||||
|
arSession=arSession,
|
||||||
|
update=call,
|
||||||
|
skipping_error=True,
|
||||||
|
)
|
||||||
|
).balance()
|
||||||
|
|
||||||
|
await call.message.answer(
|
||||||
|
response,
|
||||||
|
reply_markup=close_finl(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Информация - Lolzteam
|
||||||
|
@router.callback_query(F.data == "payment_lolzteam_check")
|
||||||
|
async def payment_lolzteam_check(
|
||||||
|
call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS
|
||||||
|
):
|
||||||
|
status, response = await (
|
||||||
|
await LolzteamAPI.connect(
|
||||||
|
bot=bot,
|
||||||
|
arSession=arSession,
|
||||||
|
update=call,
|
||||||
|
skipping_error=True,
|
||||||
|
)
|
||||||
|
).check()
|
||||||
|
|
||||||
|
await call.message.answer(
|
||||||
|
response,
|
||||||
|
reply_markup=close_finl(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Изменение - Lolzteam
|
||||||
|
@router.callback_query(F.data == "payment_lolzteam_edit")
|
||||||
|
async def payment_lolzteam_edit(
|
||||||
|
call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS
|
||||||
|
):
|
||||||
|
await state.set_state("here_lolzteam_token")
|
||||||
|
await call.message.edit_text(
|
||||||
|
ded(f"""
|
||||||
|
<b>🟢 Изменение Lolzteam - <a href='https://lolz.live/account/api'>API</a></b>
|
||||||
|
➖➖➖➖➖➖➖➖➖➖
|
||||||
|
▪️ Создайте Приложение в "Lolzteam", сгенерируйте токен (basic, invoice, market) и отправьте
|
||||||
|
"""),
|
||||||
|
disable_web_page_preview=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Выключатель - Lolzteam
|
||||||
|
@router.callback_query(F.data.startswith("payment_lolzteam_status:"))
|
||||||
|
async def payment_lolzteam_status(
|
||||||
|
call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS
|
||||||
|
):
|
||||||
|
get_status = call.data.split(":")[1]
|
||||||
|
get_payments = await Paymentsx().get()
|
||||||
|
|
||||||
|
if get_status == "True" and get_payments.lolzteam_token == "None":
|
||||||
|
return await call.answer(
|
||||||
|
"❌ Токен данной платежной системы не был добавлен", True
|
||||||
|
)
|
||||||
|
|
||||||
|
await Paymentsx().update(status_lolzteam=get_status)
|
||||||
|
|
||||||
|
await call.message.edit_text(
|
||||||
|
"<b>🟢 Управление - Lolzteam</b>",
|
||||||
|
reply_markup=await payment_lolzteam_finl(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
############################## ПРИНЯТИЕ LOLZTEAM ##############################
|
||||||
|
# Принятие токена Lolzteam
|
||||||
|
@router.message(StateFilter("here_lolzteam_token"))
|
||||||
|
async def payments_lolzteam_get(message: Message, bot: Bot, state: FSM, arSession: ARS):
|
||||||
|
get_token = message.text
|
||||||
|
|
||||||
|
cache_message = await message.answer(
|
||||||
|
"<b>🟢 Проверка введённых Lolzteam данных... 🔄</b>"
|
||||||
|
)
|
||||||
|
|
||||||
|
status, response = await (
|
||||||
|
await LolzteamAPI.connect(
|
||||||
|
bot=bot,
|
||||||
|
arSession=arSession,
|
||||||
|
update=message,
|
||||||
|
skipping_error=True,
|
||||||
|
token=get_token,
|
||||||
|
)
|
||||||
|
).check()
|
||||||
|
|
||||||
|
if status:
|
||||||
|
await Paymentsx().update(lolzteam_token=get_token)
|
||||||
|
|
||||||
|
await state.set_state("here_lolzteam_merchant_id")
|
||||||
|
await cache_message.edit_text(
|
||||||
|
ded(f"""
|
||||||
|
<b>🟢 Изменение Lolzteam - <a href='https://lzt.market/merchants'>Мерчанты</a></b>
|
||||||
|
➖➖➖➖➖➖➖➖➖➖
|
||||||
|
▪️ Создайте мерчант в "Lolzteam Market" и отправьте его ID
|
||||||
|
"""),
|
||||||
|
disable_web_page_preview=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
else:
|
||||||
|
await cache_message.edit_text(
|
||||||
|
"<b>🟢 Не удалось изменить Lolzteam кошелёк ❌</b>"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Принятие айди мерчанта Lolzteam
|
||||||
|
@router.message(StateFilter("here_lolzteam_merchant_id"))
|
||||||
|
async def payments_lolzteam_merchant_id_get(
|
||||||
|
message: Message, bot: Bot, state: FSM, arSession: ARS
|
||||||
|
):
|
||||||
|
get_payments = await Paymentsx().get()
|
||||||
|
get_token = get_payments.lolzteam_token
|
||||||
|
|
||||||
|
get_merchant_id = message.text
|
||||||
|
|
||||||
|
await state.clear()
|
||||||
|
|
||||||
|
cache_message = await message.answer(
|
||||||
|
"<b>🟢 Проверка введённых Lolzteam данных... 🔄</b>"
|
||||||
|
)
|
||||||
|
|
||||||
|
status, response = await (
|
||||||
|
await LolzteamAPI.connect(
|
||||||
|
bot=bot,
|
||||||
|
arSession=arSession,
|
||||||
|
update=message,
|
||||||
|
skipping_error=True,
|
||||||
|
token=get_token,
|
||||||
|
merchant_id=get_merchant_id,
|
||||||
|
)
|
||||||
|
).check()
|
||||||
|
|
||||||
|
if status:
|
||||||
|
await Paymentsx().update(lolzteam_merchant_id=get_merchant_id)
|
||||||
|
await cache_message.edit_text("<b>🟢 Lolzteam был успешно изменён ✅</b>")
|
||||||
|
else:
|
||||||
|
await cache_message.edit_text("<b>🟢 Не удалось изменить Lolzteam ❌</b>")
|
||||||
|
|
||||||
|
await message.answer(
|
||||||
|
"<b>🟢 Управление - Lolzteam</b>",
|
||||||
|
reply_markup=await payment_lolzteam_finl(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
#################################### ЗВЁЗДЫ ####################################
|
#################################### ЗВЁЗДЫ ####################################
|
||||||
# Баланс - Звёзды
|
# Баланс - Звёзды
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ from aiogram.types import CallbackQuery, Message, PreCheckoutQuery
|
|||||||
from tgbot.database import Paymentsx, Refillx, Userx, Settingsx
|
from tgbot.database import Paymentsx, Refillx, Userx, Settingsx
|
||||||
from tgbot.keyboards.inline_user import refill_bill_finl, refill_method_finl
|
from tgbot.keyboards.inline_user import refill_bill_finl, refill_method_finl
|
||||||
from tgbot.services.api_cryptobot import CryptobotAPI
|
from tgbot.services.api_cryptobot import CryptobotAPI
|
||||||
|
from tgbot.services.api_lolzteam import LolzteamAPI
|
||||||
from tgbot.services.api_stars import StarsAPI
|
from tgbot.services.api_stars import StarsAPI
|
||||||
from tgbot.utils.const_functions import is_number, to_number, gen_id, ded
|
from tgbot.utils.const_functions import is_number, to_number, gen_id, ded
|
||||||
from tgbot.utils.misc.bot_logging import bot_logger
|
from tgbot.utils.misc.bot_logging import bot_logger
|
||||||
@@ -26,6 +27,7 @@ async def refill_method_list(call: CallbackQuery, bot: Bot, state: FSM, arSessio
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
get_payments.status_cryptobot == "False"
|
get_payments.status_cryptobot == "False"
|
||||||
|
and get_payments.status_lolzteam == "False"
|
||||||
and get_payments.status_stars == "False"
|
and get_payments.status_stars == "False"
|
||||||
):
|
):
|
||||||
return await call.answer("❗️ Пополнения временно недоступны", True)
|
return await call.answer("❗️ Пополнения временно недоступны", True)
|
||||||
@@ -49,6 +51,10 @@ async def refill_method_select(
|
|||||||
return await call.answer(
|
return await call.answer(
|
||||||
"❌ Пополнение данным способом временно недоступно", True
|
"❌ Пополнение данным способом временно недоступно", True
|
||||||
)
|
)
|
||||||
|
elif refill_method == "Lolzteam" and get_payments.status_lolzteam == "False":
|
||||||
|
return await call.answer(
|
||||||
|
"❌ Пополнение данным способом временно недоступно", True
|
||||||
|
)
|
||||||
elif refill_method == "Stars" and get_payments.status_stars == "False":
|
elif refill_method == "Stars" and get_payments.status_stars == "False":
|
||||||
return await call.answer(
|
return await call.answer(
|
||||||
"❌ Пополнение данным способом временно недоступно", True
|
"❌ Пополнение данным способом временно недоступно", True
|
||||||
@@ -98,6 +104,15 @@ async def refill_amount_get(message: Message, bot: Bot, state: FSM, arSession: A
|
|||||||
)
|
)
|
||||||
).bill(refill_amount)
|
).bill(refill_amount)
|
||||||
|
|
||||||
|
elif refill_method == "Lolzteam":
|
||||||
|
bill_message, bill_link, bill_receipt = await (
|
||||||
|
await LolzteamAPI.connect(
|
||||||
|
bot=bot,
|
||||||
|
arSession=arSession,
|
||||||
|
update=cache_message,
|
||||||
|
)
|
||||||
|
).bill(refill_amount)
|
||||||
|
|
||||||
elif refill_method == "Stars":
|
elif refill_method == "Stars":
|
||||||
bill_message, bill_link, bill_receipt = await (
|
bill_message, bill_link, bill_receipt = await (
|
||||||
await StarsAPI.connect(
|
await StarsAPI.connect(
|
||||||
@@ -106,6 +121,7 @@ async def refill_amount_get(message: Message, bot: Bot, state: FSM, arSession: A
|
|||||||
update=cache_message,
|
update=cache_message,
|
||||||
)
|
)
|
||||||
).bill(refill_amount)
|
).bill(refill_amount)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return await cache_message.edit_text(
|
return await cache_message.edit_text(
|
||||||
f"<b>❌ Данный способ пополнения не найден. Попробуйте позже: {refill_method}</b>"
|
f"<b>❌ Данный способ пополнения не найден. Попробуйте позже: {refill_method}</b>"
|
||||||
@@ -180,6 +196,59 @@ async def refill_check_cryptobot(
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Проверка оплаты - Lolzteam
|
||||||
|
@router.callback_query(F.data.startswith("Pay:Lolzteam"))
|
||||||
|
async def refill_check_lolzteam(
|
||||||
|
call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS
|
||||||
|
):
|
||||||
|
pay_method = call.data.split(":")[1]
|
||||||
|
pay_comment = call.data.split(":")[2]
|
||||||
|
|
||||||
|
pay_status, pay_amount = await (
|
||||||
|
await LolzteamAPI.connect(
|
||||||
|
bot=bot,
|
||||||
|
arSession=arSession,
|
||||||
|
update=call,
|
||||||
|
)
|
||||||
|
).bill_check(pay_comment)
|
||||||
|
|
||||||
|
if pay_status == 0:
|
||||||
|
refill_status = await refill_success(
|
||||||
|
bot=bot,
|
||||||
|
call=call,
|
||||||
|
pay_method=pay_method,
|
||||||
|
pay_amount=pay_amount,
|
||||||
|
pay_comment=pay_comment,
|
||||||
|
)
|
||||||
|
|
||||||
|
if refill_status == "ALREADY":
|
||||||
|
await call.answer("❗ Ваше пополнение уже зачислено.", True, cache_time=60)
|
||||||
|
await delete_refill_message(
|
||||||
|
bot, call.message.chat.id, call.message.message_id
|
||||||
|
)
|
||||||
|
elif refill_status == "USER_NOT_FOUND":
|
||||||
|
await call.answer(
|
||||||
|
"❗ Пользователь не найден. Напишите в поддержку.", True, cache_time=30
|
||||||
|
)
|
||||||
|
elif pay_status == 1:
|
||||||
|
await call.answer(
|
||||||
|
"❗️ Не удалось проверить платёж. Попробуйте позже", True, cache_time=30
|
||||||
|
)
|
||||||
|
elif pay_status == 2:
|
||||||
|
await call.answer(
|
||||||
|
"❗️ Оплата не была найдена. Попробуйте позже", True, cache_time=5
|
||||||
|
)
|
||||||
|
elif pay_status == 3:
|
||||||
|
await call.answer("❗️ Вы не успели оплатить счёт", True, cache_time=5)
|
||||||
|
await call.message.edit_reply_markup()
|
||||||
|
else:
|
||||||
|
await call.answer(
|
||||||
|
f"❗ Неизвестная ошибка {pay_status}. Обратитесь в поддержку.",
|
||||||
|
True,
|
||||||
|
cache_time=5,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Проверка оплаты - Звёзды
|
# Проверка оплаты - Звёзды
|
||||||
@router.callback_query(F.data.startswith("Pay:Stars"))
|
@router.callback_query(F.data.startswith("Pay:Stars"))
|
||||||
async def refill_check_stars(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
async def refill_check_stars(call: CallbackQuery, bot: Bot, state: FSM, arSession: ARS):
|
||||||
@@ -357,6 +426,8 @@ async def save_refill_success(
|
|||||||
) -> Tuple[str, int]:
|
) -> Tuple[str, int]:
|
||||||
if pay_method == "Cryptobot":
|
if pay_method == "Cryptobot":
|
||||||
text_method = "CryptoBot"
|
text_method = "CryptoBot"
|
||||||
|
elif pay_method == "Lolzteam":
|
||||||
|
text_method = "Lolzteam"
|
||||||
elif pay_method == "Stars":
|
elif pay_method == "Stars":
|
||||||
text_method = "Telegram Stars"
|
text_method = "Telegram Stars"
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -13,20 +13,31 @@ from tgbot.utils.misc.bot_models import ARS
|
|||||||
from tgbot.utils.misc_functions import send_admins
|
from tgbot.utils.misc_functions import send_admins
|
||||||
|
|
||||||
# Список поддерживаемых валют
|
# Список поддерживаемых валют
|
||||||
ALLOW_CURRENCIES = ['BTC', 'ETH', 'LTC', 'USDT', 'USDC', 'TRX', 'TON', 'BNB', 'SOL', 'DOGE']
|
ALLOW_CURRENCIES = [
|
||||||
|
"BTC",
|
||||||
|
"ETH",
|
||||||
|
"LTC",
|
||||||
|
"USDT",
|
||||||
|
"USDC",
|
||||||
|
"TRX",
|
||||||
|
"TON",
|
||||||
|
"BNB",
|
||||||
|
"SOL",
|
||||||
|
"DOGE",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
# АПИ для работы с CryptoBot
|
# АПИ для работы с CryptoBot
|
||||||
class CryptobotAPI:
|
class CryptobotAPI:
|
||||||
# Настройка клиента CryptoBot
|
# Настройка клиента CryptoBot
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
bot: Bot,
|
bot: Bot,
|
||||||
arSession: ARS,
|
arSession: ARS,
|
||||||
update: Optional[Union[Message, CallbackQuery]] = None,
|
update: Optional[Union[Message, CallbackQuery]] = None,
|
||||||
token: str = "None",
|
token: str = "None",
|
||||||
adding: bool = False,
|
adding: bool = False,
|
||||||
skipping_error: bool = False,
|
skipping_error: bool = False,
|
||||||
):
|
):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
self.arSession = arSession
|
self.arSession = arSession
|
||||||
@@ -38,12 +49,12 @@ class CryptobotAPI:
|
|||||||
# Инициализация данных
|
# Инициализация данных
|
||||||
@classmethod
|
@classmethod
|
||||||
async def connect(
|
async def connect(
|
||||||
cls,
|
cls,
|
||||||
bot: Bot,
|
bot: Bot,
|
||||||
arSession: ARS,
|
arSession: ARS,
|
||||||
update: Optional[Union[Message, CallbackQuery]] = None,
|
update: Optional[Union[Message, CallbackQuery]] = None,
|
||||||
token: Optional[str] = None,
|
token: Optional[str] = None,
|
||||||
skipping_error: bool = False,
|
skipping_error: bool = False,
|
||||||
) -> "CryptobotAPI":
|
) -> "CryptobotAPI":
|
||||||
adding = token is not None
|
adding = token is not None
|
||||||
|
|
||||||
@@ -75,21 +86,23 @@ class CryptobotAPI:
|
|||||||
await send_admins(
|
await send_admins(
|
||||||
self.bot,
|
self.bot,
|
||||||
f"<b>🔷 CryptoBot недоступен. Как можно быстрее его замените</b>\n"
|
f"<b>🔷 CryptoBot недоступен. Как можно быстрее его замените</b>\n"
|
||||||
f"❗️ Ошибка: <code>{error_code}</code>"
|
f"❗️ Ошибка: <code>{error_code}</code>",
|
||||||
)
|
)
|
||||||
|
|
||||||
# Проверка кассы/кошелька
|
# Проверка кассы/кошелька
|
||||||
async def check(self) -> Tuple[bool, str]:
|
async def check(self) -> Tuple[bool, str]:
|
||||||
status, response = await self._request("getMe")
|
status, response = await self._request("getMe")
|
||||||
|
|
||||||
if status and response['ok']:
|
if status and response["ok"]:
|
||||||
return True, ded(f"""
|
return True, ded(
|
||||||
|
f"""
|
||||||
<b>🔷 CryptoBot кошелёк полностью функционирует ✅</b>
|
<b>🔷 CryptoBot кошелёк полностью функционирует ✅</b>
|
||||||
➖➖➖➖➖➖➖➖➖➖
|
➖➖➖➖➖➖➖➖➖➖
|
||||||
▪️ Токен: <code>{self.token}</code>
|
▪️ Токен: <code>{self.token}</code>
|
||||||
▪️ Айди: <code>{response['result']['app_id']}</code>
|
▪️ Айди: <code>{response['result']['app_id']}</code>
|
||||||
▪️ Имя: <code>{response['result']['name']}</code>
|
▪️ Имя: <code>{response['result']['name']}</code>
|
||||||
""")
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
return False, "<b>🔷 Не удалось проверить CryptoBot кошелёк ❌</b>"
|
return False, "<b>🔷 Не удалось проверить CryptoBot кошелёк ❌</b>"
|
||||||
|
|
||||||
@@ -97,17 +110,17 @@ class CryptobotAPI:
|
|||||||
async def balance(self) -> str:
|
async def balance(self) -> str:
|
||||||
status, response = await self._request("getBalance")
|
status, response = await self._request("getBalance")
|
||||||
|
|
||||||
if status and response['ok']:
|
if status and response["ok"]:
|
||||||
save_currencies = []
|
save_currencies = []
|
||||||
|
|
||||||
response_balances = sorted(
|
response_balances = sorted(
|
||||||
response['result'],
|
response["result"],
|
||||||
reverse=True,
|
reverse=True,
|
||||||
key=lambda balance: to_number(balance['available']),
|
key=lambda balance: to_number(balance["available"]),
|
||||||
)
|
)
|
||||||
|
|
||||||
for currency in response_balances:
|
for currency in response_balances:
|
||||||
if currency['currency_code'] in ALLOW_CURRENCIES:
|
if currency["currency_code"] in ALLOW_CURRENCIES:
|
||||||
save_currencies.append(
|
save_currencies.append(
|
||||||
f"▪️ {currency['currency_code']}: <code>{currency['available']}</code>"
|
f"▪️ {currency['currency_code']}: <code>{currency['available']}</code>"
|
||||||
)
|
)
|
||||||
@@ -123,24 +136,26 @@ class CryptobotAPI:
|
|||||||
return "<b>🔷 Не удалось получить баланс CryptoBot кошелька ❌</b>"
|
return "<b>🔷 Не удалось получить баланс CryptoBot кошелька ❌</b>"
|
||||||
|
|
||||||
# Создание счета на оплату
|
# Создание счета на оплату
|
||||||
async def bill(self, pay_amount: Union[float, int]) -> Tuple[Union[str, bool], str, str]:
|
async def bill(
|
||||||
|
self, pay_amount: Union[float, int]
|
||||||
|
) -> Tuple[Union[str, bool], str, str]:
|
||||||
assets_currencies = ",".join(ALLOW_CURRENCIES)
|
assets_currencies = ",".join(ALLOW_CURRENCIES)
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
'currency_type': 'fiat',
|
"currency_type": "fiat",
|
||||||
'fiat': 'RUB',
|
"fiat": "RUB",
|
||||||
'amount': str(pay_amount),
|
"amount": str(pay_amount),
|
||||||
'expires_in': 10800,
|
"expires_in": 10800,
|
||||||
'accepted_assets': assets_currencies
|
"accepted_assets": assets_currencies,
|
||||||
}
|
}
|
||||||
|
|
||||||
status, response = await self._request("createInvoice", payload)
|
status, response = await self._request("createInvoice", payload)
|
||||||
|
|
||||||
if status and response['ok']:
|
if status and response["ok"]:
|
||||||
bill_message = ded(f"""
|
bill_message = ded(f"""
|
||||||
<b>💰 Пополнение баланса</b>
|
<b>💰 Пополнение баланса</b>
|
||||||
➖➖➖➖➖➖➖➖➖➖
|
➖➖➖➖➖➖➖➖➖➖
|
||||||
▪️ Для пополнения баланса, нажмите на кнопку ниже
|
▪️ Для пополнения баланса, нажмите на кнопку ниже
|
||||||
<code>Перейти к оплате</code> и оплатите выставленный вам счёт
|
<code>Перейти к оплате</code> и оплатите выставленный вам счёт
|
||||||
▪️ У вас имеется 3 часа на оплату счета
|
▪️ У вас имеется 3 часа на оплату счета
|
||||||
▪️ Сумма пополнения: <code>{pay_amount}₽</code>
|
▪️ Сумма пополнения: <code>{pay_amount}₽</code>
|
||||||
@@ -148,46 +163,52 @@ class CryptobotAPI:
|
|||||||
❗️ После оплаты, нажмите на <code>Проверить оплату</code>
|
❗️ После оплаты, нажмите на <code>Проверить оплату</code>
|
||||||
""")
|
""")
|
||||||
|
|
||||||
return bill_message, response['result']['mini_app_invoice_url'], response['result']['invoice_id']
|
return (
|
||||||
|
bill_message,
|
||||||
|
response["result"]["mini_app_invoice_url"],
|
||||||
|
response["result"]["invoice_id"],
|
||||||
|
)
|
||||||
|
|
||||||
return False, "", ""
|
return False, "", ""
|
||||||
|
|
||||||
# Проверка счета на оплату
|
# Проверка счета на оплату
|
||||||
async def bill_check(self, bill_receipt: Optional[Union[str, int]] = None, records: int = 1) -> Tuple[int, float]:
|
async def bill_check(
|
||||||
|
self, bill_receipt: Optional[Union[str, int]] = None, records: int = 1
|
||||||
|
) -> Tuple[int, float]:
|
||||||
payload = {
|
payload = {
|
||||||
'invoice_ids': f'{bill_receipt}',
|
"invoice_ids": f"{bill_receipt}",
|
||||||
'fiat': 'RUB',
|
"fiat": "RUB",
|
||||||
}
|
}
|
||||||
|
|
||||||
status, response = await self._request("getInvoices", payload)
|
status, response = await self._request("getInvoices", payload)
|
||||||
|
|
||||||
pay_status, pay_amount = 1, 0
|
pay_status, pay_amount = 1, 0
|
||||||
|
|
||||||
if status and response['ok']:
|
if status and response["ok"]:
|
||||||
get_invoice = response['result']['items'][0]
|
get_invoice = response["result"]["items"][0]
|
||||||
|
|
||||||
if get_invoice['status'] == "active":
|
if get_invoice["status"] == "active":
|
||||||
pay_status = 2
|
pay_status = 2
|
||||||
elif get_invoice['status'] == "expired":
|
elif get_invoice["status"] == "expired":
|
||||||
pay_status = 3
|
pay_status = 3
|
||||||
else:
|
else:
|
||||||
pay_status = 0
|
pay_status = 0
|
||||||
pay_amount = to_number(get_invoice['amount'])
|
pay_amount = to_number(get_invoice["amount"])
|
||||||
|
|
||||||
return pay_status, pay_amount
|
return pay_status, pay_amount
|
||||||
|
|
||||||
# Генерация запроса
|
# Генерация запроса
|
||||||
async def _request(
|
async def _request(
|
||||||
self,
|
self,
|
||||||
method: str,
|
method: str,
|
||||||
data: Optional[Dict[str, Any]] = None,
|
data: Optional[Dict[str, Any]] = None,
|
||||||
) -> Tuple[bool, Any]:
|
) -> Tuple[bool, Any]:
|
||||||
session = await self.arSession.get_session()
|
session = await self.arSession.get_session()
|
||||||
|
|
||||||
base_url = 'https://pay.crypt.bot/api/'
|
base_url = "https://pay.crypt.bot/api/"
|
||||||
headers = {
|
headers = {
|
||||||
'Crypto-Pay-API-Token': self.token,
|
"Crypto-Pay-API-Token": self.token,
|
||||||
'Content-Type': 'application/x-www-form-urlencoded',
|
"Content-Type": "application/x-www-form-urlencoded",
|
||||||
}
|
}
|
||||||
|
|
||||||
url = base_url + method
|
url = base_url + method
|
||||||
@@ -204,7 +225,9 @@ class CryptobotAPI:
|
|||||||
if response.status == 200:
|
if response.status == 200:
|
||||||
return True, response_data
|
return True, response_data
|
||||||
else:
|
else:
|
||||||
await self.error_notification(f"{response.status} - {str(response_data)}")
|
await self.error_notification(
|
||||||
|
f"{response.status} - {str(response_data)}"
|
||||||
|
)
|
||||||
|
|
||||||
return False, response_data
|
return False, response_data
|
||||||
except ClientConnectorCertificateError:
|
except ClientConnectorCertificateError:
|
||||||
|
|||||||
@@ -0,0 +1,294 @@
|
|||||||
|
# - *- coding: utf- 8 - *-
|
||||||
|
import json
|
||||||
|
from typing import Any, Dict, Optional, Tuple, Union
|
||||||
|
|
||||||
|
from aiogram import Bot
|
||||||
|
from aiogram.types import CallbackQuery, Message
|
||||||
|
from aiohttp import ClientConnectorCertificateError
|
||||||
|
|
||||||
|
from tgbot.database import Paymentsx
|
||||||
|
from tgbot.utils.const_functions import ded, to_number, get_unix, gen_id
|
||||||
|
from tgbot.utils.misc.bot_logging import bot_logger
|
||||||
|
from tgbot.utils.misc.bot_models import ARS
|
||||||
|
from tgbot.utils.misc_functions import send_admins
|
||||||
|
|
||||||
|
# Список поддерживаемых валют
|
||||||
|
ALLOW_CURRENCIES = [
|
||||||
|
"rub",
|
||||||
|
"uah",
|
||||||
|
"kzt",
|
||||||
|
"byn",
|
||||||
|
"usd",
|
||||||
|
"eur",
|
||||||
|
"gbp",
|
||||||
|
"cny",
|
||||||
|
"try",
|
||||||
|
"jpy",
|
||||||
|
"brl",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# АПИ для работы с Lolzteam
|
||||||
|
class LolzteamAPI:
|
||||||
|
# Настройка клиента Lolzteam
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
bot: Bot,
|
||||||
|
arSession: ARS,
|
||||||
|
update: Optional[Union[Message, CallbackQuery]] = None,
|
||||||
|
token: str = "None",
|
||||||
|
merchant_id: int = "None",
|
||||||
|
adding: bool = False,
|
||||||
|
skipping_error: bool = False,
|
||||||
|
):
|
||||||
|
self.bot = bot
|
||||||
|
self.arSession = arSession
|
||||||
|
self.update = update
|
||||||
|
self.token = token
|
||||||
|
self.merchant_id = merchant_id
|
||||||
|
self.adding = adding
|
||||||
|
self.skipping_error = skipping_error
|
||||||
|
|
||||||
|
# Инициализация данных
|
||||||
|
@classmethod
|
||||||
|
async def connect(
|
||||||
|
cls,
|
||||||
|
bot: Bot,
|
||||||
|
arSession: ARS,
|
||||||
|
update: Optional[Union[Message, CallbackQuery]] = None,
|
||||||
|
token: Optional[str] = None,
|
||||||
|
merchant_id: Optional[int] = None,
|
||||||
|
skipping_error: bool = False,
|
||||||
|
) -> "LolzteamAPI":
|
||||||
|
adding = token is not None
|
||||||
|
|
||||||
|
if token is None or merchant_id is None:
|
||||||
|
payments = await Paymentsx().get()
|
||||||
|
adding = False
|
||||||
|
|
||||||
|
if token is None:
|
||||||
|
token = payments.lolzteam_token
|
||||||
|
|
||||||
|
if merchant_id is None:
|
||||||
|
merchant_id = payments.lolzteam_merchant_id
|
||||||
|
|
||||||
|
return cls(
|
||||||
|
bot=bot,
|
||||||
|
arSession=arSession,
|
||||||
|
update=update,
|
||||||
|
token=token,
|
||||||
|
merchant_id=merchant_id,
|
||||||
|
adding=adding,
|
||||||
|
skipping_error=skipping_error,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Уведомления о неработоспособности кассы/кошелька
|
||||||
|
async def error_notification(self, error_code: str = "Unknown"):
|
||||||
|
bot_logger.warning("Lolzteam недоступен: %s", error_code)
|
||||||
|
|
||||||
|
if not self.skipping_error:
|
||||||
|
if self.adding and self.update is not None:
|
||||||
|
await self.update.edit_text(
|
||||||
|
f"<b>🟢 Не удалось добавить Lolzteam кассу ❌</b>\n"
|
||||||
|
f"❗️ Ошибка: <code>{error_code}</code>"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await send_admins(
|
||||||
|
self.bot,
|
||||||
|
f"<b>🟢 Lolzteam недоступен. Как можно быстрее его замените</b>\n"
|
||||||
|
f"❗️ Ошибка: <code>{error_code}</code>",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Проверка кассы/кошелька
|
||||||
|
async def check(self) -> Tuple[bool, str]:
|
||||||
|
status, response = await self._request("me", method="GET")
|
||||||
|
merchant_valid = False
|
||||||
|
|
||||||
|
if status and "errors" not in response and self.merchant_id:
|
||||||
|
balances = response["user"]["balances"]
|
||||||
|
|
||||||
|
for balance in balances:
|
||||||
|
if int(self.merchant_id) == balance["merchant_id"]:
|
||||||
|
merchant_valid = True
|
||||||
|
|
||||||
|
if merchant_valid:
|
||||||
|
return True, ded(
|
||||||
|
f"""
|
||||||
|
<b>🟢 Lolzteam полностью функционирует ✅</b>
|
||||||
|
➖➖➖➖➖➖➖➖➖➖
|
||||||
|
▪️ Токен: <code>{self.token}</code>
|
||||||
|
▪️ Айди: <code>{response['user']['user_id']}</code>
|
||||||
|
▪️ Айди Мерчанта: <code>{self.merchant_id}</code>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
elif status and "errors" not in response and not self.merchant_id:
|
||||||
|
return True, ded(
|
||||||
|
f"""
|
||||||
|
<b>🟢 Lolzteam полностью функционирует ✅</b>
|
||||||
|
➖➖➖➖➖➖➖➖➖➖
|
||||||
|
▪️ Токен: <code>{self.token}</code>
|
||||||
|
▪️ Айди: <code>{response['user']['user_id']}</code>
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
|
||||||
|
return False, "<b>🟢 Не удалось проверить Lolzteam ❌</b>"
|
||||||
|
|
||||||
|
# Получение баланса
|
||||||
|
async def balance(self) -> str:
|
||||||
|
status, response = await self._request("me", method="GET")
|
||||||
|
|
||||||
|
if status and "errors" not in response:
|
||||||
|
merchants = []
|
||||||
|
|
||||||
|
response_balances = sorted(
|
||||||
|
response["user"]["balances"],
|
||||||
|
reverse=True,
|
||||||
|
key=lambda balance: to_number(balance["balance"]),
|
||||||
|
)
|
||||||
|
|
||||||
|
for balance in response_balances:
|
||||||
|
if balance["merchant_id"] == self.merchant_id:
|
||||||
|
title = balance["title"]
|
||||||
|
custom_title = balance["custom_title"]
|
||||||
|
|
||||||
|
merchants.append(
|
||||||
|
f"▪️ {title if not custom_title else custom_title}: <code>{balance['balance']} ₽</code>"
|
||||||
|
)
|
||||||
|
|
||||||
|
merchants = "\n".join(merchants)
|
||||||
|
|
||||||
|
return ded(f"""
|
||||||
|
<b>🟢 Баланс Lolzteam составляет</b>
|
||||||
|
➖➖➖➖➖➖➖➖➖➖
|
||||||
|
{merchants}
|
||||||
|
""")
|
||||||
|
|
||||||
|
return "<b>🟢 Не удалось получить баланс Lolzteam ❌</b>"
|
||||||
|
|
||||||
|
# Создание счета на оплату
|
||||||
|
async def bill(
|
||||||
|
self, pay_amount: Union[float, int]
|
||||||
|
) -> Tuple[Union[str, bool], str, str]:
|
||||||
|
|
||||||
|
pro_payment_id = get_unix()
|
||||||
|
eu_payment_id = gen_id(12)
|
||||||
|
|
||||||
|
payment_id = str(pro_payment_id) + str(eu_payment_id)
|
||||||
|
|
||||||
|
bot_data = await self.bot.get_me()
|
||||||
|
bot_username = bot_data.username
|
||||||
|
bot_url = f"https://telegram.me/{bot_username}"
|
||||||
|
|
||||||
|
payload = {
|
||||||
|
"currency": "rub",
|
||||||
|
"amount": pay_amount,
|
||||||
|
"payment_id": payment_id,
|
||||||
|
"comment": f"Пополнение #{payment_id}",
|
||||||
|
"url_success": bot_url,
|
||||||
|
"merchant_id": self.merchant_id,
|
||||||
|
"lifetime": 10800,
|
||||||
|
"is_test": True, # Тестовый режим для отладки
|
||||||
|
}
|
||||||
|
|
||||||
|
status, response = await self._request("invoice", payload)
|
||||||
|
|
||||||
|
if status and "errors" not in response:
|
||||||
|
bill_message = ded(f"""
|
||||||
|
<b>💰 Пополнение баланса</b>
|
||||||
|
➖➖➖➖➖➖➖➖➖➖
|
||||||
|
▪️ Для пополнения баланса, нажмите на кнопку ниже
|
||||||
|
<code>Перейти к оплате</code> и оплатите выставленный вам счёт
|
||||||
|
▪️ У вас имеется 3 часа на оплату счета
|
||||||
|
▪️ Сумма пополнения: <code>{pay_amount}₽</code>
|
||||||
|
➖➖➖➖➖➖➖➖➖➖
|
||||||
|
❗️ После оплаты, нажмите на <code>Проверить оплату</code>
|
||||||
|
""")
|
||||||
|
|
||||||
|
return (
|
||||||
|
bill_message,
|
||||||
|
response["invoice"]["url"],
|
||||||
|
response["invoice"]["invoice_id"],
|
||||||
|
)
|
||||||
|
|
||||||
|
return False, "", ""
|
||||||
|
|
||||||
|
# Проверка счета на оплату
|
||||||
|
async def bill_check(
|
||||||
|
self, bill_receipt: Optional[Union[str, int]] = None, records: int = 1
|
||||||
|
) -> Tuple[int, float]:
|
||||||
|
payload = {"invoice_id": int(bill_receipt)}
|
||||||
|
|
||||||
|
status, response = await self._request("invoice", payload, method="GET")
|
||||||
|
|
||||||
|
pay_status, pay_amount = 1, 0
|
||||||
|
|
||||||
|
if status and "errors" not in response:
|
||||||
|
get_invoice = response["invoice"]
|
||||||
|
status = get_invoice["status"]
|
||||||
|
|
||||||
|
time = response["system_info"]["time"]
|
||||||
|
expires_at = get_invoice["expires_at"]
|
||||||
|
|
||||||
|
# not_paid + time < expires_at
|
||||||
|
if (status == "not_paid") and (time < expires_at):
|
||||||
|
pay_status = 2
|
||||||
|
|
||||||
|
# not_paid + time > expires_at
|
||||||
|
elif (status == "expired") and (time > expires_at):
|
||||||
|
pay_status = 3
|
||||||
|
|
||||||
|
# paid
|
||||||
|
else:
|
||||||
|
pay_status = 0
|
||||||
|
pay_amount = to_number(get_invoice["amount"])
|
||||||
|
|
||||||
|
return pay_status, pay_amount
|
||||||
|
|
||||||
|
# Генерация запроса
|
||||||
|
async def _request(
|
||||||
|
self,
|
||||||
|
path: str,
|
||||||
|
data: Optional[Dict[str, Any]] = None,
|
||||||
|
method: str = "POST",
|
||||||
|
) -> Tuple[bool, Any]:
|
||||||
|
session = await self.arSession.get_session()
|
||||||
|
method = method.upper()
|
||||||
|
|
||||||
|
base_url = "https://prod-api.lzt.market/"
|
||||||
|
headers = {
|
||||||
|
"Authorization": f"Bearer {self.token}",
|
||||||
|
"Accept": "application/json",
|
||||||
|
}
|
||||||
|
|
||||||
|
url = base_url + path
|
||||||
|
|
||||||
|
try:
|
||||||
|
if method == "POST":
|
||||||
|
response = await session.post(url=url, headers=headers, data=data)
|
||||||
|
|
||||||
|
elif method == "GET":
|
||||||
|
response = await session.get(url=url, headers=headers, params=data)
|
||||||
|
|
||||||
|
response_data = json.loads((await response.read()).decode())
|
||||||
|
|
||||||
|
if response.status == 200:
|
||||||
|
return True, response_data
|
||||||
|
else:
|
||||||
|
await self.error_notification(
|
||||||
|
f"{response.status} - {str(response_data)}"
|
||||||
|
)
|
||||||
|
|
||||||
|
return False, response_data
|
||||||
|
|
||||||
|
except ClientConnectorCertificateError:
|
||||||
|
bot_logger.warning("Ошибка SSL при запросе Lolzteam", exc_info=True)
|
||||||
|
await self.error_notification("CERTIFICATE_VERIFY_FAILED")
|
||||||
|
|
||||||
|
return False, "CERTIFICATE_VERIFY_FAILED"
|
||||||
|
|
||||||
|
except Exception as ex:
|
||||||
|
bot_logger.warning("Ошибка запроса Lolzteam", exc_info=True)
|
||||||
|
await self.error_notification(str(ex))
|
||||||
|
|
||||||
|
return False, str(ex)
|
||||||
@@ -48,7 +48,7 @@ def ikb(
|
|||||||
if copy is not None:
|
if copy is not None:
|
||||||
return InlineKeyboardButton(text=text, copy_text=CopyTextButton(text=copy))
|
return InlineKeyboardButton(text=text, copy_text=CopyTextButton(text=copy))
|
||||||
if login is not None:
|
if login is not None:
|
||||||
return InlineKeyboardButton(text=text, url=f"https://t.me/{login}")
|
return InlineKeyboardButton(text=text, url=f"https://telegram.me/{login}")
|
||||||
|
|
||||||
raise ValueError("Не указано действие для inline-кнопки")
|
raise ValueError("Не указано действие для inline-кнопки")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user