feat: добавлена поддержка RioPay для лендингов и подарков

- Добавлен RioPay в create_guest_payment (landing/gift покупки)
- user_id в RioPayPayment теперь nullable (для гостевых платежей)
- Добавлен guest purchase flow в _finalize_riopay_payment
- Миграция 0039: riopay_payments.user_id nullable
This commit is contained in:
Fringg
2026-03-18 00:10:51 +03:00
parent 3d1fbc70f8
commit 04f4e6bf6e
4 changed files with 66 additions and 2 deletions
+1 -1
View File
@@ -15,7 +15,7 @@ logger = structlog.get_logger(__name__)
async def create_riopay_payment(
db: AsyncSession,
*,
user_id: int,
user_id: int | None,
order_id: str,
amount_kopeks: int,
currency: str = 'RUB',
+15 -1
View File
@@ -42,7 +42,7 @@ class RioPayPaymentMixin:
self,
db: AsyncSession,
*,
user_id: int,
user_id: int | None,
amount_kopeks: int,
description: str = 'Пополнение баланса',
email: str | None = None,
@@ -277,6 +277,20 @@ class RioPayPaymentMixin:
logger.info('RioPay платеж уже привязан к транзакции', order_id=payment.order_id, trigger=trigger)
return True
# --- Guest purchase flow (landing page / gift) ---
riopay_metadata = dict(getattr(payment, 'metadata_json', {}) or {})
from app.services.payment.common import try_fulfill_guest_purchase
guest_result = await try_fulfill_guest_purchase(
db,
metadata=riopay_metadata,
payment_amount_kopeks=payment.amount_kopeks,
provider_payment_id=str(riopay_order_id) if riopay_order_id else payment.order_id,
provider_name='riopay',
)
if guest_result is not None:
return True
# Получаем пользователя
user = await get_user_by_id(db, payment.user_id)
if not user:
+23
View File
@@ -692,6 +692,29 @@ class PaymentService(
}
return None
# --- RioPay -----------------------------------------------------------
if payment_method == 'riopay':
if not settings.is_riopay_enabled():
logger.warning('RioPay is not enabled, cannot create guest payment')
return None
result = await self.create_riopay_payment(
db=db,
user_id=None,
amount_kopeks=amount_kopeks,
description=description,
success_url=return_url,
fail_url=return_url,
)
if result:
await _patch_guest_metadata(result['local_payment_id'], 'riopay')
return {
'payment_url': result.get('payment_url'),
'payment_id': result.get('riopay_order_id') or result.get('order_id'),
'provider': 'riopay',
}
return None
# --- Telegram Stars ---------------------------------------------------
if payment_method == 'telegram_stars':
if not settings.TELEGRAM_STARS_ENABLED:
@@ -0,0 +1,27 @@
"""make riopay_payments.user_id nullable for guest purchases
Revision ID: 0039
Revises: 0038
Create Date: 2026-03-18
"""
from typing import Sequence, Union
import sqlalchemy as sa
from alembic import op
revision: str = '0039'
down_revision: Union[str, None] = '0038'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None
def upgrade() -> None:
with op.batch_alter_table('riopay_payments') as batch_op:
batch_op.alter_column('user_id', existing_type=sa.Integer(), nullable=True)
def downgrade() -> None:
with op.batch_alter_table('riopay_payments') as batch_op:
batch_op.alter_column('user_id', existing_type=sa.Integer(), nullable=False)