Compare commits

...

4 Commits

Author SHA1 Message Date
Fringg 29d3e8984b fix(smtp): use implicit TLS (SMTPS) for port 465 registration emails
The cabinet email service called smtplib.SMTP() and conditionally ran
starttls() regardless of port, which is wrong for port 465. Port 465
is SMTPS (implicit TLS, RFC 8314): the TLS handshake must happen on
connect, before any EHLO. With the old code, switching to 465
produced a corrupted handshake — sometimes one garbled message went
through, then the server dropped the source.

Now SMTP_SSL is used when SMTP_USE_SSL is true OR when SMTP_PORT is
465 (auto-detect). The new SMTP_USE_SSL setting defaults to false
to keep existing 587/25 deployments unchanged.
2026-05-10 10:02:46 +03:00
Fringg b5a066628f fix(cabinet): return original_price_per_device_kopeks for device addon
Endpoint /cabinet/subscription/devices/price did not include
original_price_per_device_kopeks when a promo group discount applied,
causing the cabinet UI to render a strikethrough 'Бесплатно' next to
the per-device price line.
2026-05-10 09:59:52 +03:00
Egor d6442b87df Merge pull request #2926 from BEDOLAGA-DEV/dev
docs: add Antilopay/Etoplatezhi/Jupiter/Donut/Lava + Apple IAP to pro…
2026-05-04 21:22:17 +03:00
Fringg 31e3ccd24c docs: add Antilopay/Etoplatezhi/Jupiter/Donut/Lava + Apple IAP to provider list
- Bump provider counter 18 → 24+ in Features and Documentation sections
- Add 7 new rows to providers table:
  - Antilopay (RSA signing)
  - Etoplatezhi
  - Jupiter (FPGate P2P) — partner via @k_juppiter
  - Donut (Donut P2P) — partner via @donut_payment
  - Lava Business
  - Apple In-App Purchase
- Add 2 partner cards (Jupiter, Donut) following the Platega/PayPear pattern
2026-05-04 21:20:44 +03:00
5 changed files with 56 additions and 8 deletions
+4 -1
View File
@@ -72,8 +72,11 @@ SMTP_PASSWORD=
# Email отправителя (если не указан, используется SMTP_USER)
SMTP_FROM_EMAIL=
SMTP_FROM_NAME=VPN Service
# Использовать TLS шифрование
# Использовать STARTTLS (порт 587 / 25). Не путать с SMTP_USE_SSL.
SMTP_USE_TLS=true
# Использовать implicit TLS (SMTPS). Автоматически включается при SMTP_PORT=465.
# Для портов 25/587 оставить false.
SMTP_USE_SSL=false
# Уведомления администраторов
ADMIN_NOTIFICATIONS_ENABLED=true
+34 -2
View File
@@ -55,7 +55,7 @@ Bedolaga — полнофункциональная платформа для п
### 💳 Платежи
- 🏦 **18 платёжных провайдеров** одновременно
- 🏦 **24+ платёжных провайдера** одновременно
- 💰 Единый баланс: пополнение любым способом → покупка с баланса
- ⚡ Автопокупка подписки после пополнения
- 💾 Рекуррентные платежи (сохранённые карты)
@@ -127,6 +127,12 @@ Bedolaga — полнофункциональная платформа для п
| 🤝 | **[RollyPay](https://rollypay.io/?utm_source=bedolaga&utm_medium=community&utm_campaign=integration)** 🔸 | СБП, карты, крипто | RUB → USDT |
| 🤝 | **[AuraPay](https://aurapay.tech/)** 🔸 | Карты, СБП | RUB |
| 🤝 | **[Overpay](https://overpay.pro/)** 🔸 | Карты, СБП | RUB |
| 🦌 | **Antilopay** | Карты, СБП, SberPay (RSA подпись) | RUB |
| 💳 | **Etoplatezhi** | Карты, СБП | RUB |
| 🪐 | **[Jupiter](https://t.me/k_juppiter)** 🔸 | СБП через QR (FPGate P2P v2.1) | RUB |
| 🍩 | **[Donut](https://t.me/donut_payment)** 🔸 | Карты, СБП по телефону, СБП QR (P2P) | RUB |
| 🌋 | **Lava Business** | Карты, СБП (gate.lava.ru) | RUB |
| 🍎 | **Apple In-App Purchase** | Покупки через iOS App Store | USD |
| 📲 | **Tribute** | Telegram-платежи | RUB |
</div>
@@ -210,6 +216,32 @@ Bedolaga — официальный партнёр платёжного шлюз
📩 Менеджер: [@A_OverPay](https://t.me/A_OverPay) | 🌐 [overpay.pro](https://overpay.pro/)
</td>
</tr>
<tr>
<td align="center">
**🤝 Официальный партнёр Jupiter (FPGate P2P)**
Bedolaga — официальный партнёр платёжного шлюза **Jupiter** (FPGate P2P v2.1).<br>
Эквайринг СБП через QR-код банковского приложения, HMAC-SHA256 подпись.<br>
Высокая проходимость, callback-driven архитектура, защита от replay-атак.<br>
Подключение по кодовому слову **`БЕДОЛАГА`** — **спец. условия**
📩 Менеджер: [@k_juppiter](https://t.me/k_juppiter)
</td>
<td align="center">
**🤝 Официальный партнёр Donut**
Bedolaga — официальный партнёр платёжной системы **Donut** (Donut P2P).<br>
P2P-оплата картой, СБП по номеру телефона и СБП QR — три метода через единый API.<br>
HMAC-SHA256 подпись, sticky terminal-status guard, защита от amount tampering.<br>
Подключение по кодовому слову **`БЕДОЛАГА`** — **спец. условия**
📩 Менеджер: [@donut_payment](https://t.me/donut_payment)
</td>
</tr>
</table>
@@ -275,7 +307,7 @@ docker compose up -d
| | Раздел | Описание |
|:---:|:---|:---|
| 🚀 | [Быстрый старт](https://docs.bedolagam.ru/getting-started/quickstart) | Развёртывание за 5 минут |
| 💳 | [Настройка платежей](https://docs.bedolagam.ru/bot/payments) | 18 провайдеров, webhook, фискализация |
| 💳 | [Настройка платежей](https://docs.bedolagam.ru/bot/payments) | 24+ провайдера, webhook, фискализация, Apple IAP |
| 📦 | [Подписки и тарифы](https://docs.bedolagam.ru/bot/subscriptions) | Конфигурация планов и трафика |
| 👥 | [Реферальная программа](https://docs.bedolagam.ru/bot/referral-program) | Партнёрка и вывод средств |
| 🖥 | [Cabinet](https://docs.bedolagam.ru/cabinet/overview) | Настройка веб-кабинета |
@@ -828,6 +828,9 @@ async def get_device_price(
response['discount_percent'] = devices_discount_percent
response['discount_kopeks'] = discount_value
response['base_total_price_kopeks'] = base_total_price
response['original_price_per_device_kopeks'] = (
base_total_price // devices if devices > 0 else 0
)
return response
+13 -5
View File
@@ -45,18 +45,26 @@ class EmailService:
def use_tls(self) -> bool:
return settings.SMTP_USE_TLS
@property
def use_ssl(self) -> bool:
# Port 465 always implies implicit TLS (SMTPS, RFC 8314).
return settings.SMTP_USE_SSL or self.port == 465
def is_configured(self) -> bool:
"""Check if SMTP is properly configured."""
return settings.is_smtp_configured()
def _get_smtp_connection(self) -> smtplib.SMTP:
"""Create and return SMTP connection."""
smtp = smtplib.SMTP(self.host, self.port, timeout=30)
smtp.ehlo()
if self.use_tls:
smtp.starttls()
if self.use_ssl:
smtp: smtplib.SMTP = smtplib.SMTP_SSL(self.host, self.port, timeout=30)
smtp.ehlo()
else:
smtp = smtplib.SMTP(self.host, self.port, timeout=30)
smtp.ehlo()
if self.use_tls:
smtp.starttls()
smtp.ehlo()
# Only attempt login if credentials are provided AND server supports AUTH
if self.user and self.password:
+2
View File
@@ -1014,6 +1014,8 @@ class Settings(BaseSettings):
SMTP_FROM_EMAIL: str | None = None
SMTP_FROM_NAME: str = 'VPN Service'
SMTP_USE_TLS: bool = True
# Implicit TLS (SMTPS) — required for port 465. Auto-enabled when SMTP_PORT == 465.
SMTP_USE_SSL: bool = False
# Ban System Integration (BedolagaBan monitoring)
BAN_SYSTEM_ENABLED: bool = False