feat: add payment method toggles and new pricing vars

This commit is contained in:
Machka Pasla
2025-06-24 01:18:30 +03:00
parent c7294ddaba
commit 6e8f810cbd
5 changed files with 60 additions and 36 deletions
+20 -10
View File
@@ -31,20 +31,30 @@ YOOKASSA_PAYMENT_SUBJECT=payment
# If unset, bot will use polling while YooKassa uses webhooks.
TELEGRAM_WEBHOOK_BASE_URL=https://webhooks.yourdomain.tld
# Subscription Prices (integer values)
PRICE_1_MONTH=150
PRICE_3_MONTHS=300
PRICE_6_MONTHS=500
PRICE_12_MONTHS=900
# Telegram Stars Prices (integer values)
# Payment Methods
YOOKASSA_ENABLED=True
STARS_ENABLED=True
TRIBUTE_ENABLED=True
# Subscription Options
1_MONTH_ENABLED=True
RUB_PRICE_1_MONTH=150
STARS_PRICE_1_MONTH=0
STARS_PRICE_3_MONTHS=0
STARS_PRICE_6_MONTHS=0
STARS_PRICE_12_MONTHS=0
# Tribute Payment Links
TRIBUTE_LINK_1_MONTH=
3_MONTHS_ENABLED=True
RUB_PRICE_3_MONTHS=300
STARS_PRICE_3_MONTHS=0
TRIBUTE_LINK_3_MONTHS=
6_MONTHS_ENABLED=True
RUB_PRICE_6_MONTHS=500
STARS_PRICE_6_MONTHS=0
TRIBUTE_LINK_6_MONTHS=
12_MONTHS_ENABLED=True
RUB_PRICE_12_MONTHS=900
STARS_PRICE_12_MONTHS=0
TRIBUTE_LINK_12_MONTHS=
# API key for verifying Tribute webhook signatures
TRIBUTE_API_KEY=
+4 -1
View File
@@ -93,7 +93,10 @@ This Telegram bot is designed to automate the sale and management of subscriptio
* `YOOKASSA_PAYMENT_MODE`: e.g., `full_prepayment`.
* `YOOKASSA_PAYMENT_SUBJECT`: e.g., `service`.
* `TELEGRAM_WEBHOOK_BASE_URL`: (Optional) If you want Telegram updates via webhook. Can be the same as `YOOKASSA_WEBHOOK_BASE_URL`. If not set, the bot will use polling for Telegram updates.
* `PRICE_X_MONTH`: Prices for different subscription durations.
* **Payment Method Toggles:** `YOOKASSA_ENABLED`, `STARS_ENABLED`, `TRIBUTE_ENABLED`.
* **Subscription Options:** For each duration you can use variables like
`1_MONTH_ENABLED`, `RUB_PRICE_1_MONTH`, `STARS_PRICE_1_MONTH`, `TRIBUTE_LINK_1_MONTH`
(and corresponding variables for `3_MONTHS`, `6_MONTHS`, `12_MONTHS`).
* **Panel API Settings:**
* `PANEL_API_URL`: Full URL to your Remnawave panel's API (e.g., `http://localhost:3000/api` or `https://panel.yourdomain.com/api`).
* `PANEL_API_KEY`: API Key for authenticating with the Remnawave panel.
+1
View File
@@ -111,6 +111,7 @@ async def select_subscription_period_callback_handler(
currency_symbol_val,
current_lang,
i18n,
settings,
)
try:
+6 -5
View File
@@ -112,16 +112,17 @@ def get_payment_method_keyboard(months: int, price: float,
tribute_url: Optional[str],
stars_price: Optional[int],
currency_symbol_val: str, lang: str,
i18n_instance) -> InlineKeyboardMarkup:
i18n_instance, settings: Settings) -> InlineKeyboardMarkup:
_ = lambda key, **kwargs: i18n_instance.gettext(lang, key, **kwargs)
builder = InlineKeyboardBuilder()
if stars_price is not None:
if settings.STARS_ENABLED and stars_price is not None:
builder.button(text=_("pay_with_stars_button"),
callback_data=f"pay_stars:{months}:{stars_price}")
if tribute_url:
if settings.TRIBUTE_ENABLED and tribute_url:
builder.button(text=_("pay_with_tribute_button"), url=tribute_url)
builder.button(text=_("pay_with_yookassa_button"),
callback_data=f"pay_yk:{months}:{price}")
if settings.YOOKASSA_ENABLED:
builder.button(text=_("pay_with_yookassa_button"),
callback_data=f"pay_yk:{months}:{price}")
builder.button(text=_(key="cancel_button"),
callback_data="main_action:subscribe")
builder.adjust(1)
+29 -20
View File
@@ -36,10 +36,19 @@ class Settings(BaseSettings):
TELEGRAM_WEBHOOK_BASE_URL: Optional[str] = None
PRICE_1_MONTH: Optional[int] = Field(default=None)
PRICE_3_MONTHS: Optional[int] = Field(default=None)
PRICE_6_MONTHS: Optional[int] = Field(default=None)
PRICE_12_MONTHS: Optional[int] = Field(default=None)
YOOKASSA_ENABLED: bool = Field(default=True)
STARS_ENABLED: bool = Field(default=True)
TRIBUTE_ENABLED: bool = Field(default=True)
MONTH_1_ENABLED: bool = Field(default=True, alias="1_MONTH_ENABLED")
MONTH_3_ENABLED: bool = Field(default=True, alias="3_MONTHS_ENABLED")
MONTH_6_ENABLED: bool = Field(default=True, alias="6_MONTHS_ENABLED")
MONTH_12_ENABLED: bool = Field(default=True, alias="12_MONTHS_ENABLED")
RUB_PRICE_1_MONTH: Optional[int] = Field(default=None)
RUB_PRICE_3_MONTHS: Optional[int] = Field(default=None)
RUB_PRICE_6_MONTHS: Optional[int] = Field(default=None)
RUB_PRICE_12_MONTHS: Optional[int] = Field(default=None)
STARS_PRICE_1_MONTH: Optional[int] = Field(default=None)
STARS_PRICE_3_MONTHS: Optional[int] = Field(default=None)
@@ -170,27 +179,27 @@ class Settings(BaseSettings):
def subscription_options(self) -> Dict[int, float]:
options: Dict[int, float] = {}
if self.PRICE_1_MONTH is not None:
options[1] = float(self.PRICE_1_MONTH)
if self.PRICE_3_MONTHS is not None:
options[3] = float(self.PRICE_3_MONTHS)
if self.PRICE_6_MONTHS is not None:
options[6] = float(self.PRICE_6_MONTHS)
if self.PRICE_12_MONTHS is not None:
options[12] = float(self.PRICE_12_MONTHS)
if self.MONTH_1_ENABLED and self.RUB_PRICE_1_MONTH is not None:
options[1] = float(self.RUB_PRICE_1_MONTH)
if self.MONTH_3_ENABLED and self.RUB_PRICE_3_MONTHS is not None:
options[3] = float(self.RUB_PRICE_3_MONTHS)
if self.MONTH_6_ENABLED and self.RUB_PRICE_6_MONTHS is not None:
options[6] = float(self.RUB_PRICE_6_MONTHS)
if self.MONTH_12_ENABLED and self.RUB_PRICE_12_MONTHS is not None:
options[12] = float(self.RUB_PRICE_12_MONTHS)
return options
@computed_field
@property
def stars_subscription_options(self) -> Dict[int, int]:
options: Dict[int, int] = {}
if self.STARS_PRICE_1_MONTH is not None:
if self.STARS_ENABLED and self.MONTH_1_ENABLED and self.STARS_PRICE_1_MONTH is not None:
options[1] = self.STARS_PRICE_1_MONTH
if self.STARS_PRICE_3_MONTHS is not None:
if self.STARS_ENABLED and self.MONTH_3_ENABLED and self.STARS_PRICE_3_MONTHS is not None:
options[3] = self.STARS_PRICE_3_MONTHS
if self.STARS_PRICE_6_MONTHS is not None:
if self.STARS_ENABLED and self.MONTH_6_ENABLED and self.STARS_PRICE_6_MONTHS is not None:
options[6] = self.STARS_PRICE_6_MONTHS
if self.STARS_PRICE_12_MONTHS is not None:
if self.STARS_ENABLED and self.MONTH_12_ENABLED and self.STARS_PRICE_12_MONTHS is not None:
options[12] = self.STARS_PRICE_12_MONTHS
return options
@@ -198,13 +207,13 @@ class Settings(BaseSettings):
@property
def tribute_payment_links(self) -> Dict[int, str]:
links: Dict[int, str] = {}
if self.TRIBUTE_LINK_1_MONTH:
if self.TRIBUTE_ENABLED and self.MONTH_1_ENABLED and self.TRIBUTE_LINK_1_MONTH:
links[1] = self.TRIBUTE_LINK_1_MONTH
if self.TRIBUTE_LINK_3_MONTHS:
if self.TRIBUTE_ENABLED and self.MONTH_3_ENABLED and self.TRIBUTE_LINK_3_MONTHS:
links[3] = self.TRIBUTE_LINK_3_MONTHS
if self.TRIBUTE_LINK_6_MONTHS:
if self.TRIBUTE_ENABLED and self.MONTH_6_ENABLED and self.TRIBUTE_LINK_6_MONTHS:
links[6] = self.TRIBUTE_LINK_6_MONTHS
if self.TRIBUTE_LINK_12_MONTHS:
if self.TRIBUTE_ENABLED and self.MONTH_12_ENABLED and self.TRIBUTE_LINK_12_MONTHS:
links[12] = self.TRIBUTE_LINK_12_MONTHS
return links