fix: bind HWID top-ups to subscription periods
This commit is contained in:
+35
-9
@@ -66,6 +66,17 @@ JSON-каталог может содержать несколько тариф
|
||||
"rub": [{ "gb": 10, "price": 99 }],
|
||||
"stars": [{ "gb": 10, "price": 2500 }]
|
||||
},
|
||||
"hwid_device_packages": {
|
||||
"rub": [
|
||||
{
|
||||
"count": 1,
|
||||
"price": 99,
|
||||
"prices": { "1": 99, "3": 249 },
|
||||
"min_price": 20
|
||||
}
|
||||
],
|
||||
"stars": [{ "count": 1, "price": 50, "prices": { "1": 50, "3": 130 } }]
|
||||
},
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
@@ -88,7 +99,7 @@ JSON-каталог может содержать несколько тариф
|
||||
| `tariffs[].premium_topup_packages` | Пакеты докупки premium-трафика в формате `{ "rub": [{ "gb": 10, "price": 99 }], "stars": [...] }`. Требуют `premium_squad_uuids`. |
|
||||
| `tariffs[].billing_model` | Модель тарифа: `period` или `traffic`. |
|
||||
| `tariffs[].hwid_device_limit` | Базовый лимит HWID-устройств. `0` означает безлимит, отсутствие поля использует `USER_HWID_DEVICE_LIMIT`. |
|
||||
| `tariffs[].hwid_device_packages` | Пакеты докупки устройств: `{ "count": 1, "price": 99 }`. |
|
||||
| `tariffs[].hwid_device_packages` | Пакеты докупки устройств. `price` — legacy/monthly fallback, `prices` задаёт полную цену пакета для периодов тарифа (`"1"`, `"3"`, `"6"`, `"12"`), `min_price` задаёт минимальную цену prorate-докупки. |
|
||||
|
||||
Для `period`-тарифа также используются:
|
||||
|
||||
@@ -210,8 +221,15 @@ limit_after = current_used + balance_after
|
||||
{
|
||||
"hwid_device_limit": 5,
|
||||
"hwid_device_packages": {
|
||||
"rub": [{ "count": 1, "price": 99 }],
|
||||
"stars": [{ "count": 1, "price": 2500 }]
|
||||
"rub": [
|
||||
{
|
||||
"count": 1,
|
||||
"price": 99,
|
||||
"prices": { "1": 99, "3": 249, "6": 449, "12": 799 },
|
||||
"min_price": 20
|
||||
}
|
||||
],
|
||||
"stars": [{ "count": 1, "price": 50, "prices": { "1": 50, "3": 130 } }]
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -219,11 +237,17 @@ limit_after = current_used + balance_after
|
||||
Правила:
|
||||
|
||||
- `hwid_device_limit` хранит базовый лимит тарифа;
|
||||
- `extra_hwid_devices` хранит количество докупленных устройств;
|
||||
- эффективный лимит равен `hwid_device_limit + extra_hwid_devices`;
|
||||
- `extra_hwid_devices` хранит только текущую активную сумму докупленных устройств;
|
||||
- срок действия каждой докупки хранится в `hwid_device_purchases.valid_from` / `valid_until`;
|
||||
- эффективный лимит равен `hwid_device_limit + active extra_hwid_devices`;
|
||||
- базовый лимит `0` означает безлимит, в Remnawave отправляется `hwidDeviceLimit = 0`;
|
||||
- при безлимитном базовом лимите докупка устройств не применяется;
|
||||
- при смене тарифа базовый лимит берется из целевого тарифа, а докупленные устройства сохраняются;
|
||||
- полная цена HWID-пакета берется из `prices[duration_months]`; если периода нет, используется fallback `price * duration_months`;
|
||||
- фактическая цена докупки считается пропорционально оплачиваемому окну `valid_from -> valid_until` относительно периода подписки и фиксируется в платежe;
|
||||
- для Telegram Stars цена округляется вверх до целого Stars, для RUB — вверх до копеек; `min_price` защищает от микроплатежей в конце периода;
|
||||
- при продлении подписки докупленные устройства не продлеваются автоматически: старая докупка действует до прежнего `end_date`, а для нового срока создается отдельная `hwid_devices_renewal`-покупка;
|
||||
- `traffic`-тарифы не показывают и не принимают докупку HWID-устройств, потому что у них нет срока подписки;
|
||||
- при смене тарифа базовый лимит берется из целевого тарифа, а неиспользованная RUB-стоимость HWID-докупок конвертируется в дни нового period-тарифа или GB traffic-тарифа; XTR/Stars-докупки не конвертируются без явного курса и продолжают жить по своему `valid_until`;
|
||||
- история докупок пишется в `hwid_device_purchases`;
|
||||
- платеж хранит количество устройств в `payments.purchased_hwid_devices`.
|
||||
|
||||
@@ -237,9 +261,9 @@ limit_after = current_used + balance_after
|
||||
|
||||
| Переход | Поведение |
|
||||
| --- | --- |
|
||||
| `period -> period` | Остаток оплаченных дней оценивается по `effective_monthly_price_rub`, затем пересчитывается в дни целевого тарифа через месячную цену целевого тарифа. Количество дней округляется вниз. |
|
||||
| `period -> period` с доплатой | Если целевой тариф дороже, может быть создан платеж `tariff_upgrade`; после оплаты применяется целевой тариф. |
|
||||
| `period -> traffic` | Остаток оплаченных дней конвертируется в GB по `conversion_rate_rub_per_gb` или минимальной RUB-цене GB из пакетов целевого тарифа. |
|
||||
| `period -> period` | Остаток оплаченных дней оценивается по `effective_monthly_price_rub`, затем пересчитывается в дни целевого тарифа через месячную цену целевого тарифа. Неиспользованная RUB-стоимость HWID-докупок добавляется к этому расчету как дополнительные дни. Количество дней округляется вниз. |
|
||||
| `period -> period` с доплатой | Если целевой тариф дороже, может быть создан платеж `tariff_upgrade`; неиспользованная RUB-стоимость HWID-докупок уменьшает сумму доплаты. После оплаты применяется целевой тариф, а конвертированные HWID-окна закрываются. |
|
||||
| `period -> traffic` | Остаток оплаченных дней и неиспользованная RUB-стоимость HWID-докупок конвертируются в GB по `conversion_rate_rub_per_gb` или минимальной RUB-цене GB из пакетов целевого тарифа. |
|
||||
| `traffic -> period` | Пользователь выбирает и оплачивает период целевого тарифа; остаток GB сохраняется как `topup_balance_bytes` поверх лимита period-тарифа. |
|
||||
|
||||
При смене тарифа бот меняет:
|
||||
@@ -262,6 +286,8 @@ limit_after = current_used + balance_after
|
||||
| `tariff_key` | Ключ тарифа, к которому относится платеж. |
|
||||
| `purchased_gb` | Купленный объем GB для traffic-пакетов и докупки трафика. |
|
||||
| `purchased_hwid_devices` | Количество устройств при докупке HWID. |
|
||||
| `hwid_valid_from`, `hwid_valid_until` | Зафиксированное окно действия HWID-докупки на момент создания платежа. |
|
||||
| `hwid_pricing_period_months`, `hwid_proration_ratio`, `hwid_full_price` | Метаданные расчета цены HWID-докупки: период тарифа, коэффициент prorate и полная цена пакета для периода. |
|
||||
| `subscription_duration_months` | Количество месяцев для подписки на срок; также используется платежными обработчиками как числовое поле покупки. |
|
||||
|
||||
В callback и metadata платежных провайдеров `sale_mode` может передаваться с суффиксом тарифа, например `subscription@standard` или `topup@standard`. При активации платежа тариф сохраняется отдельно в `tariff_key`.
|
||||
|
||||
Reference in New Issue
Block a user