ORDER ID added to SUccess info
This commit is contained in:
+7
-7
@@ -24,6 +24,13 @@ DISABLE_WELCOME_MESSAGE= #
|
||||
# Webhook Base URL (used for Telegram and payment providers)
|
||||
WEBHOOK_BASE_URL=https://webhooks.yourdomain.tld
|
||||
|
||||
# Payment Method Toggles
|
||||
YOOKASSA_ENABLED=True # Turn on YOOKASSA
|
||||
FREEKASSA_ENABLED=True # Turn on FreeKassa
|
||||
STARS_ENABLED=True # Turn on STARS
|
||||
TRIBUTE_ENABLED=True # Turn on TRIBUTE
|
||||
CRYPTOPAY_ENABLED=True # Turn on CRYPTOPAY
|
||||
|
||||
# YooKassa Payment Gateway Configuration
|
||||
YOOKASSA_SHOP_ID=your_shop_id # Your store ID in YooKassa
|
||||
YOOKASSA_SECRET_KEY=your_secret_key # Your secret key for YooKassa
|
||||
@@ -33,7 +40,6 @@ YOOKASSA_VAT_CODE=1 #
|
||||
YOOKASSA_AUTOPAYMENTS_ENABLED=False # Auto-renew toggle
|
||||
|
||||
# FreeKassa Payment Gateway Configuration
|
||||
FREEKASSA_ENABLED=True # Turn on FreeKassa
|
||||
FREEKASSA_MERCHANT_ID=your_shop_id # Your shop ID in FreeKassa
|
||||
FREEKASSA_API_KEY=your_api_key # API key for REST requests
|
||||
FREEKASSA_SECOND_SECRET=your_second_secret # Secret word #2 (used to verify notifications)
|
||||
@@ -50,12 +56,6 @@ TRIBUTE_API_KEY= #
|
||||
TRIBUTE_SKIP_NOTIFICATIONS=True # Skip renewal notifications for Tribute payments
|
||||
TRIBUTE_SKIP_CANCELLATION_NOTIFICATIONS=False # Skip cancellation notifications for Tribute payments
|
||||
|
||||
# Payment Method Toggles
|
||||
YOOKASSA_ENABLED=True # Turn on YOOKASSA
|
||||
STARS_ENABLED=True # Turn on STARS
|
||||
TRIBUTE_ENABLED=True # Turn on TRIBUTE
|
||||
CRYPTOPAY_ENABLED=True # Turn on CRYPTOPAY
|
||||
|
||||
# Subscription Options. Specify cost parameters or payment links here.
|
||||
1_MONTH_ENABLED=True
|
||||
RUB_PRICE_1_MONTH=150
|
||||
|
||||
@@ -280,7 +280,7 @@ async def process_successful_payment(session: AsyncSession, bot: Bot,
|
||||
details_message = _("payment_successful_error_details")
|
||||
|
||||
details_markup = get_connect_and_main_keyboard(
|
||||
user_lang, i18n, settings, config_link
|
||||
user_lang, i18n, settings, config_link, preserve_message=True
|
||||
)
|
||||
try:
|
||||
await bot.send_message(
|
||||
|
||||
@@ -427,6 +427,13 @@ async def main_action_callback_handler(
|
||||
subscription_service,
|
||||
session,
|
||||
is_edit=True)
|
||||
elif action == "back_to_main_keep":
|
||||
await send_main_menu(callback,
|
||||
settings,
|
||||
i18n_data,
|
||||
subscription_service,
|
||||
session,
|
||||
is_edit=False)
|
||||
else:
|
||||
i18n: Optional[JsonI18n] = i18n_data.get("i18n_instance")
|
||||
_ = lambda key, **kwargs: i18n.gettext(
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from aiogram import Router, F, types
|
||||
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
|
||||
from typing import Optional
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
@@ -238,7 +240,13 @@ async def pay_yk_callback_handler(callback: types.CallbackQuery, settings: Setti
|
||||
|
||||
await callback.message.edit_text(
|
||||
get_text(key="payment_link_message", months=months),
|
||||
reply_markup=get_payment_url_keyboard(payment_response_yk["confirmation_url"], current_lang, i18n),
|
||||
reply_markup=get_payment_url_keyboard(
|
||||
payment_response_yk["confirmation_url"],
|
||||
current_lang,
|
||||
i18n,
|
||||
back_callback=f"subscribe_period:{months}",
|
||||
back_text_key="back_to_payment_methods_button",
|
||||
),
|
||||
disable_web_page_preview=False,
|
||||
)
|
||||
else:
|
||||
@@ -354,7 +362,9 @@ async def pay_fk_callback_handler(
|
||||
|
||||
if success:
|
||||
location = response_data.get("location")
|
||||
provider_identifier = response_data.get("orderHash") or response_data.get("orderId")
|
||||
order_hash = response_data.get("orderHash")
|
||||
order_id_api = response_data.get("orderId")
|
||||
provider_identifier = order_hash or order_id_api
|
||||
|
||||
if provider_identifier:
|
||||
try:
|
||||
@@ -373,18 +383,36 @@ async def pay_fk_callback_handler(
|
||||
)
|
||||
|
||||
if location:
|
||||
order_identifier_display = str(order_id_api or provider_identifier or payment_record.payment_id)
|
||||
order_info_text = get_text(
|
||||
"free_kassa_order_info",
|
||||
order_id=order_identifier_display,
|
||||
date=datetime.now().strftime("%Y-%m-%d"),
|
||||
)
|
||||
try:
|
||||
await callback.message.edit_text(
|
||||
get_text(key="payment_link_message", months=months),
|
||||
reply_markup=get_payment_url_keyboard(location, current_lang, i18n),
|
||||
f"{order_info_text}\n\n" + get_text(key="payment_link_message", months=months),
|
||||
reply_markup=get_payment_url_keyboard(
|
||||
location,
|
||||
current_lang,
|
||||
i18n,
|
||||
back_callback=f"subscribe_period:{months}",
|
||||
back_text_key="back_to_payment_methods_button",
|
||||
),
|
||||
disable_web_page_preview=False,
|
||||
)
|
||||
except Exception as e_edit:
|
||||
logging.warning(f"FreeKassa: failed to display payment link ({e_edit}), sending new message.")
|
||||
try:
|
||||
await callback.message.answer(
|
||||
get_text(key="payment_link_message", months=months),
|
||||
reply_markup=get_payment_url_keyboard(location, current_lang, i18n),
|
||||
f"{order_info_text}\n\n" + get_text(key="payment_link_message", months=months),
|
||||
reply_markup=get_payment_url_keyboard(
|
||||
location,
|
||||
current_lang,
|
||||
i18n,
|
||||
back_callback=f"subscribe_period:{months}",
|
||||
back_text_key="back_to_payment_methods_button",
|
||||
),
|
||||
disable_web_page_preview=False,
|
||||
)
|
||||
except Exception:
|
||||
@@ -481,14 +509,26 @@ async def pay_crypto_callback_handler(
|
||||
try:
|
||||
await callback.message.edit_text(
|
||||
get_text(key="payment_link_message", months=months),
|
||||
reply_markup=get_payment_url_keyboard(invoice_url, current_lang, i18n),
|
||||
reply_markup=get_payment_url_keyboard(
|
||||
invoice_url,
|
||||
current_lang,
|
||||
i18n,
|
||||
back_callback=f"subscribe_period:{months}",
|
||||
back_text_key="back_to_payment_methods_button",
|
||||
),
|
||||
disable_web_page_preview=False,
|
||||
)
|
||||
except Exception:
|
||||
try:
|
||||
await callback.message.answer(
|
||||
get_text(key="payment_link_message", months=months),
|
||||
reply_markup=get_payment_url_keyboard(invoice_url, current_lang, i18n),
|
||||
reply_markup=get_payment_url_keyboard(
|
||||
invoice_url,
|
||||
current_lang,
|
||||
i18n,
|
||||
back_callback=f"subscribe_period:{months}",
|
||||
back_text_key="back_to_payment_methods_button",
|
||||
),
|
||||
disable_web_page_preview=False,
|
||||
)
|
||||
except Exception:
|
||||
@@ -555,6 +595,18 @@ async def pay_stars_callback_handler(
|
||||
)
|
||||
|
||||
if payment_db_id:
|
||||
try:
|
||||
await callback.message.edit_text(
|
||||
get_text("payment_invoice_sent_message", months=months),
|
||||
reply_markup=InlineKeyboardMarkup(inline_keyboard=[
|
||||
[InlineKeyboardButton(
|
||||
text=get_text("back_to_payment_methods_button"),
|
||||
callback_data=f"subscribe_period:{months}",
|
||||
)]
|
||||
]),
|
||||
)
|
||||
except Exception as e_edit:
|
||||
logging.warning(f"Stars payment: failed to show invoice info message ({e_edit})")
|
||||
try:
|
||||
await callback.answer()
|
||||
except Exception:
|
||||
|
||||
@@ -138,13 +138,20 @@ def get_payment_method_keyboard(months: int, price: float,
|
||||
return builder.as_markup()
|
||||
|
||||
|
||||
def get_payment_url_keyboard(payment_url: str, lang: str,
|
||||
i18n_instance) -> InlineKeyboardMarkup:
|
||||
def get_payment_url_keyboard(payment_url: str,
|
||||
lang: str,
|
||||
i18n_instance,
|
||||
back_callback: Optional[str] = None,
|
||||
back_text_key: str = "back_to_main_menu_button"
|
||||
) -> InlineKeyboardMarkup:
|
||||
_ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs)
|
||||
builder = InlineKeyboardBuilder()
|
||||
builder.button(text=_(key="pay_button"), url=payment_url)
|
||||
builder.button(text=_(key="back_to_main_menu_button"),
|
||||
callback_data="main_action:back_to_main")
|
||||
if back_callback:
|
||||
builder.button(text=_(key=back_text_key), callback_data=back_callback)
|
||||
else:
|
||||
builder.button(text=_(key="back_to_main_menu_button"),
|
||||
callback_data="main_action:back_to_main")
|
||||
builder.adjust(1)
|
||||
return builder.as_markup()
|
||||
|
||||
@@ -192,7 +199,8 @@ def get_connect_and_main_keyboard(
|
||||
lang: str,
|
||||
i18n_instance,
|
||||
settings: Settings,
|
||||
config_link: Optional[str]) -> InlineKeyboardMarkup:
|
||||
config_link: Optional[str],
|
||||
preserve_message: bool = False) -> InlineKeyboardMarkup:
|
||||
"""Keyboard with a connect button and a back to main menu button."""
|
||||
_ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs)
|
||||
builder = InlineKeyboardBuilder()
|
||||
@@ -216,10 +224,11 @@ def get_connect_and_main_keyboard(
|
||||
)
|
||||
)
|
||||
|
||||
back_callback = "main_action:back_to_main_keep" if preserve_message else "main_action:back_to_main"
|
||||
builder.row(
|
||||
InlineKeyboardButton(
|
||||
text=_("back_to_main_menu_button"),
|
||||
callback_data="main_action:back_to_main",
|
||||
callback_data=back_callback,
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -209,7 +209,9 @@ class CryptoPayService:
|
||||
end_date=final_end.strftime('%Y-%m-%d'),
|
||||
config_link=config_link)
|
||||
|
||||
markup = get_connect_and_main_keyboard(lang, i18n, settings, config_link)
|
||||
markup = get_connect_and_main_keyboard(
|
||||
lang, i18n, settings, config_link, preserve_message=True
|
||||
)
|
||||
try:
|
||||
await bot.send_message(
|
||||
user_id,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import asyncio
|
||||
from datetime import datetime
|
||||
import hashlib
|
||||
import hmac
|
||||
import json
|
||||
@@ -358,8 +359,21 @@ class FreeKassaService:
|
||||
end_date=end_date_str,
|
||||
config_link=config_link,
|
||||
)
|
||||
if provider_payment_id:
|
||||
order_info_text = _(
|
||||
"free_kassa_order_full",
|
||||
order_id=provider_payment_id,
|
||||
date=datetime.now().strftime("%Y-%m-%d"),
|
||||
)
|
||||
text = f"{order_info_text}\n{text}"
|
||||
|
||||
markup = get_connect_and_main_keyboard(lang, self.i18n, self.settings, config_link)
|
||||
markup = get_connect_and_main_keyboard(
|
||||
lang,
|
||||
self.i18n,
|
||||
self.settings,
|
||||
config_link,
|
||||
preserve_message=True,
|
||||
)
|
||||
try:
|
||||
await self.bot.send_message(
|
||||
payment.user_id,
|
||||
|
||||
@@ -148,7 +148,7 @@ class StarsService:
|
||||
config_link=config_link,
|
||||
)
|
||||
markup = get_connect_and_main_keyboard(
|
||||
current_lang, i18n, self.settings, config_link
|
||||
current_lang, i18n, self.settings, config_link, preserve_message=True
|
||||
)
|
||||
try:
|
||||
await self.bot.send_message(
|
||||
|
||||
@@ -208,7 +208,11 @@ class TributeService:
|
||||
config_link=config_link,
|
||||
)
|
||||
markup = get_connect_and_main_keyboard(
|
||||
lang, i18n, settings, config_link
|
||||
lang,
|
||||
i18n,
|
||||
settings,
|
||||
config_link,
|
||||
preserve_message=True,
|
||||
)
|
||||
|
||||
try:
|
||||
|
||||
+6
-11
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"welcome": "Welcome, {user_name}!",
|
||||
"main_menu_greeting": "Hi, {user_name}! 👋\nWhat would you like to do?",
|
||||
|
||||
"menu_activate_trial_button": "🆓 Free Trial",
|
||||
"menu_subscribe_inline": "🚀 Purchase",
|
||||
"menu_my_subscription_inline": "🔐 My Subscription",
|
||||
@@ -13,24 +12,20 @@
|
||||
"menu_server_status_button": "📊 Status",
|
||||
"menu_support_button": "💬 Support",
|
||||
"menu_terms_button": "📄 Terms of Service",
|
||||
|
||||
"back_to_main_menu_button": "⬅️ Back",
|
||||
|
||||
"choose_language": "Choose language:",
|
||||
"language_set_alert": "Language changed!",
|
||||
|
||||
"error_occurred_try_again": "An error occurred, please try again.",
|
||||
"error_try_again": "Please try again.",
|
||||
"error_displaying_menu": "Error displaying menu.",
|
||||
"main_menu_unknown_action": "Unknown action.",
|
||||
|
||||
"select_subscription_period": "Select subscription period:",
|
||||
"subscribe_for_months_button": "{months} mo. - {price} {currency_symbol}",
|
||||
|
||||
"choose_payment_method": "Choose payment method:",
|
||||
"pay_button": "💳 Pay",
|
||||
"pay_with_yookassa_button": "💳 YooKassa",
|
||||
"pay_with_sbp_button": "📱 SBP",
|
||||
"back_to_payment_methods_button": "⬅️ Back to payment methods",
|
||||
"pay_with_cryptopay_button": "💎 CryptoBot",
|
||||
"pay_with_tribute_button": "❤️ Tribute",
|
||||
"pay_with_stars_button": "🌟 Telegram Stars",
|
||||
@@ -38,13 +33,14 @@
|
||||
"cancel_button": "❌ Cancel",
|
||||
"payment_description_subscription": "Subscription payment for {months} mo.",
|
||||
"payment_link_message": "To pay for {months} mo. subscription, click the button below:",
|
||||
"free_kassa_order_info": "Order #{order_id} from {date}",
|
||||
"payment_invoice_sent_message": "Telegram has sent the invoice above. Complete the payment or pick another method below.",
|
||||
"payment_successful_error_details": "✅ Payment succeeded, but an error occurred displaying details. Your subscription is active. Contact support if anything is wrong.",
|
||||
"payment_successful_full": "✅ Payment successful!\nYour {months}-month subscription is active until {end_date}.\n\nConnection key:\n<code>{config_link}</code>\n\nTo connect, open the link and follow the instructions 👇",
|
||||
"payment_successful_with_referral_bonus_full": "✅ Payment successful!\nYour {months}-month subscription (base end date: {base_end_date}) has been extended by {bonus_days} bonus days for referral from {inviter_name} and is now active until {final_end_date}.\n\nConnection key:\n<code>{config_link}</code>\n\nTo connect, open the link and follow the instructions 👇",
|
||||
"payment_failed": "❌ Payment failed or was cancelled. Please try again or contact support.",
|
||||
"config_link_not_available": "not available, contact support",
|
||||
"traffic_unlimited": "Unlimited",
|
||||
|
||||
"promo_code_prompt": "Please enter your promo code:",
|
||||
"promo_code_not_found": "Promo code <code>{code}</code> not found, expired, or already used the maximum number of times.",
|
||||
"promo_code_already_used_by_user": "You have already used promo code <code>{code}</code>.",
|
||||
@@ -66,7 +62,6 @@
|
||||
"referral_bonus_inviter_notification_extended": "🎉 Congrats! Your friend {referee_name} paid for a subscription. You received {days} bonus days! Your subscription is now active until {new_end_date}.",
|
||||
"referral_bonus_inviter_notification_new_sub": "🎉 Congrats! Your friend {referee_name} paid for a subscription. You received a {days}-day bonus subscription! It is active until {new_end_date}.",
|
||||
"user_is_banned": "🚫 Your account is banned. Please contact support.",
|
||||
|
||||
"admin_panel_title": "Admin Panel",
|
||||
"admin_stats_button": "📊 Statistics",
|
||||
"admin_broadcast_button": "📢 Broadcast",
|
||||
@@ -323,7 +318,6 @@
|
||||
"admin_user_subscription_active_until": "⏰ <b>Active until:</b>",
|
||||
"admin_user_subscription_error": "Loading error",
|
||||
"admin_promo_management_button": "🎟 Promo Management",
|
||||
|
||||
"admin_promo_management_title": "🎟 <b>Promo Code Management</b>\n\nSelect a promo code for detailed view:",
|
||||
"admin_promo_management_empty": "📭 No promo codes available",
|
||||
"admin_promo_card_title": "🎟 <b>Promo Code: {code}</b>",
|
||||
@@ -436,5 +430,6 @@
|
||||
"admin_ads_delete_button": "🗑 Delete campaign",
|
||||
"admin_ads_delete_confirm": "Are you sure you want to delete campaign #{id}? This action is irreversible.",
|
||||
"admin_ads_deleted_success": "Campaign deleted.",
|
||||
"admin_ads_not_found": "Campaign not found."
|
||||
}
|
||||
"admin_ads_not_found": "Campaign not found.",
|
||||
"free_kassa_order_full": "Order #{order_id} from {date}\n\n"
|
||||
}
|
||||
+6
-11
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"welcome": "Добро пожаловать, {user_name}!",
|
||||
"main_menu_greeting": "Привет, {user_name}! 👋\nЧто бы вы хотели сделать?",
|
||||
|
||||
"menu_activate_trial_button": "🆓 Пробный период",
|
||||
"menu_subscribe_inline": "🚀 Купить",
|
||||
"menu_my_subscription_inline": "🔐 Моя подписка",
|
||||
@@ -13,24 +12,20 @@
|
||||
"menu_server_status_button": "📊 Статус",
|
||||
"menu_support_button": "💬 Поддержка",
|
||||
"menu_terms_button": "📄 Условия сервиса",
|
||||
|
||||
"back_to_main_menu_button": "⬅️ Назад",
|
||||
|
||||
"choose_language": "Выберите язык / Select language:",
|
||||
"language_set_alert": "Язык изменен!",
|
||||
|
||||
"error_occurred_try_again": "Произошла ошибка, попробуйте снова.",
|
||||
"error_try_again": "Попробуйте еще раз.",
|
||||
"error_displaying_menu": "Ошибка отображения меню.",
|
||||
"main_menu_unknown_action": "Неизвестное действие.",
|
||||
|
||||
"select_subscription_period": "Выберите срок подписки:",
|
||||
"subscribe_for_months_button": "{months} мес. - {price} {currency_symbol}",
|
||||
|
||||
"choose_payment_method": "Выберите способ оплаты:",
|
||||
"pay_button": "💳 Оплатить",
|
||||
"pay_with_yookassa_button": "💳 ЮKassa",
|
||||
"pay_with_sbp_button": "📱 СБП",
|
||||
"back_to_payment_methods_button": "⬅️ Назад к выбору оплаты",
|
||||
"pay_with_cryptopay_button": "💎 CryptoBot",
|
||||
"pay_with_tribute_button": "❤️ Tribute",
|
||||
"pay_with_stars_button": "🌟 Звезды Telegram",
|
||||
@@ -38,13 +33,14 @@
|
||||
"cancel_button": "❌ Отмена",
|
||||
"payment_description_subscription": "Оплата подписки на {months} мес.",
|
||||
"payment_link_message": "Для оплаты подписки на {months} мес., нажмите кнопку ниже:",
|
||||
"free_kassa_order_info": "Заказ №{order_id} от {date}",
|
||||
"payment_invoice_sent_message": "Счёт Telegram Stars отправлен выше. Нажмите «Оплатить» или вернитесь к выбору способа ниже.",
|
||||
"payment_successful_error_details": "✅ Оплата прошла успешно, но возникла ошибка при отображении деталей. Ваша подписка активна. Свяжитесь с поддержкой, если что-то не так.",
|
||||
"payment_successful_full": "✅ Оплата прошла успешно!\nВаша подписка на {months} мес. активна до {end_date}.\n\nКлюч подключения:\n<code>{config_link}</code>\n\nЧтобы подключиться, перейдите по ссылке и следуйте инструкции 👇",
|
||||
"payment_successful_with_referral_bonus_full": "✅ Оплата прошла успешно!\nВаша подписка на {months} мес. (базовая дата окончания: {base_end_date}) продлена на {bonus_days} бонусных дней за приглашение от {inviter_name} и теперь активна до {final_end_date}.\n\nКлюч подключения:\n<code>{config_link}</code>\n\nЧтобы подключиться, перейдите по ссылке и следуйте инструкции 👇",
|
||||
"payment_failed": "❌ Оплата не удалась или была отменена. Пожалуйста, попробуйте еще раз или свяжитесь с поддержкой.",
|
||||
"config_link_not_available": "недоступна, обратитесь в поддержку",
|
||||
"traffic_unlimited": "Безлимитный",
|
||||
|
||||
"promo_code_prompt": "Пожалуйста, введите ваш промокод:",
|
||||
"promo_code_not_found": "Промокод <code>{code}</code> не найден, истек или уже использован максимальное количество раз.",
|
||||
"promo_code_already_used_by_user": "Вы уже активировали промокод <code>{code}</code>.",
|
||||
@@ -66,7 +62,6 @@
|
||||
"referral_bonus_inviter_notification_extended": "🎉 Поздравляем! Ваш друг {referee_name} оплатил подписку. Вам начислено {days} бонусных дней! Ваша подписка теперь активна до {new_end_date}.",
|
||||
"referral_bonus_inviter_notification_new_sub": "🎉 Поздравляем! Ваш друг {referee_name} оплатил подписку. Вам начислена бонусная подписка на {days} дней! Она активна до {new_end_date}.",
|
||||
"user_is_banned": "🚫 Ваш аккаунт заблокирован. Пожалуйста, свяжитесь со службой поддержки.",
|
||||
|
||||
"admin_panel_title": "Панель администратора",
|
||||
"admin_stats_button": "📊 Статистика",
|
||||
"admin_broadcast_button": "📢 Рассылка",
|
||||
@@ -322,7 +317,6 @@
|
||||
"admin_user_subscription_active_until": "⏰ <b>Действует до:</b>",
|
||||
"admin_user_subscription_error": "Ошибка загрузки",
|
||||
"admin_promo_management_button": "🎟 Управление промокодами",
|
||||
|
||||
"admin_promo_management_title": "🎟 <b>Управление промокодами</b>\n\nВыберите промокод для детального просмотра:",
|
||||
"admin_promo_management_empty": "📭 Промокоды отсутствуют",
|
||||
"admin_promo_card_title": "🎟 <b>Промокод: {code}</b>",
|
||||
@@ -435,5 +429,6 @@
|
||||
"admin_ads_delete_button": "🗑 Удалить кампанию",
|
||||
"admin_ads_delete_confirm": "Вы уверены, что хотите удалить кампанию #{id}? Это действие необратимо.",
|
||||
"admin_ads_deleted_success": "Кампания удалена.",
|
||||
"admin_ads_not_found": "Кампания не найдена."
|
||||
}
|
||||
"admin_ads_not_found": "Кампания не найдена.",
|
||||
"free_kassa_order_full": "Заказ №{order_id} от {date}\n\n"
|
||||
}
|
||||
Binary file not shown.
Reference in New Issue
Block a user