feat: update recipit

This commit is contained in:
2026-05-09 10:30:27 +03:00
parent be8aee7b73
commit b6e4f8165f
5 changed files with 32 additions and 45 deletions

View File

@@ -46,24 +46,15 @@ class CreatePaymentCloudkassirCommand:
user = await self._unit_of_work.user_repository.get(user_id) user = await self._unit_of_work.user_repository.get(user_id)
if user is None: if user is None:
raise ApplicationException(status_code=404, message='User not found') raise ApplicationException(status_code=404, message='User not found')
email_meta = metadata.get('customer_email') email = str(user.email or '').strip()
if email_meta is None:
email_meta = metadata.get('email')
email = str(email_meta or user.email or '').strip()
if not email: if not email:
raise ApplicationException(status_code=400, message='User email missing') raise ApplicationException(status_code=400, message='User email missing')
phone_raw = str(metadata.get('phone') or '').strip()
if not phone_raw:
phone_raw = str(user.phone or '').strip()
phone = phone_raw if phone_raw else None
customer_inn_meta = metadata.get('customer_inn')
if customer_inn_meta is None:
customer_inn_meta = metadata.get('customerInn')
customer_inn = str(customer_inn_meta or user.inn or '').strip()
paid_total = _parse_money(payment.amount) paid_total = _parse_money(payment.amount)
if paid_total is None: if paid_total is None:
paid_total = _parse_money(metadata.get('amount')) paid_total = _parse_money(metadata.get('amount'))
if paid_total is None:
paid_total = _parse_money(metadata.get('total_amount'))
meta_principal = _parse_money(metadata.get('principal_amount')) meta_principal = _parse_money(metadata.get('principal_amount'))
meta_agent = _parse_money(metadata.get('agent_fee')) meta_agent = _parse_money(metadata.get('agent_fee'))
@@ -109,7 +100,5 @@ class CreatePaymentCloudkassirCommand:
total_amount=total_amount, total_amount=total_amount,
principal_amount=principal_amount, principal_amount=principal_amount,
service_fee=service_fee, service_fee=service_fee,
phone=phone,
customer_inn=customer_inn,
request_id=str(ULID()), request_id=str(ULID()),
) )

View File

@@ -49,8 +49,9 @@ class ClaudeKassirClient(IReceipt):
total = total_amount.quantize(Decimal('0.01')) total = total_amount.quantize(Decimal('0.01'))
principal = principal_amount.quantize(Decimal('0.01')) principal = principal_amount.quantize(Decimal('0.01'))
fee = service_fee.quantize(Decimal('0.01')) fee = service_fee.quantize(Decimal('0.01'))
description = f'Исполнение поручения принципала по заявке №{order_id}' description = f'Оплата по заявке №{order_id}'
fee_description = f'Агентское вознаграждение за исполнение поручения по заявке №{order_id}' principal_description = f'Исполнение поручения принципала по заявке №{order_id}'
fee_description = f'Агентское вознаграждение по заявке №{order_id}'
payload: dict[str, Any] = { payload: dict[str, Any] = {
'Inn': self._inn, 'Inn': self._inn,
'Type': 'Income', 'Type': 'Income',
@@ -58,29 +59,30 @@ class ClaudeKassirClient(IReceipt):
'AccountId': user_id, 'AccountId': user_id,
'Description': description, 'Description': description,
'CustomerReceipt': { 'CustomerReceipt': {
'TaxationSystem': 2,
'Items': [ 'Items': [
{ {
'label': description, 'label': principal_description,
'price': float(principal), 'price': float(principal),
'quantity': 1.00, 'quantity': 1,
'amount': float(principal), 'amount': float(principal),
'vat': 0, 'vat': 0,
'method': 4, 'method': 4,
'object': 4, 'object': 4,
'measurement_unit': 'шт', 'measurement_unit': 'шт',
'agent_info': { 'agent_info': {
'type': 2, 'type': 4,
}, },
'supplier_info': { 'supplier_info': {
'name': 'Принципал (физическое лицо)', 'name': 'Принципал',
'inn': '',
'phones': [], 'phones': [],
'inn': self._inn,
}, },
}, },
{ {
'label': fee_description, 'label': fee_description,
'price': float(fee), 'price': float(fee),
'quantity': 1.00, 'quantity': 1,
'amount': float(fee), 'amount': float(fee),
'vat': 0, 'vat': 0,
'method': 4, 'method': 4,
@@ -88,17 +90,14 @@ class ClaudeKassirClient(IReceipt):
'measurement_unit': 'шт', 'measurement_unit': 'шт',
}, },
], ],
'taxationSystem': 2,
'email': email,
'phone': phone,
'customerInn': customer_inn,
'agentSign': 2,
'amounts': { 'amounts': {
'electronic': float(total), 'electronic': float(total),
'advancePayment': 0.00, 'advancePayment': 0,
'credit': 0.00, 'credit': 0,
'provision': 0.00, 'provision': 0,
}, },
'email': email,
'phone': phone,
}, },
'Email': email, 'Email': email,
'SuccessUrl': success_url or self._success_url, 'SuccessUrl': success_url or self._success_url,

View File

@@ -272,20 +272,16 @@ class Settings(BaseSettings):
data['CLOUD_KASSIR_PUBLIC_ID'] = str(ck_public).strip() data['CLOUD_KASSIR_PUBLIC_ID'] = str(ck_public).strip()
data['CLOUD_KASSIR_API_SECRET'] = str(ck_secret).strip() data['CLOUD_KASSIR_API_SECRET'] = str(ck_secret).strip()
else: else:
cloudkassir = read_secret('cloudkassir') cloudkassir = read_secret_optional('cloudkassir')
if cloudkassir:
ck_ci = {str(k).lower(): v for k, v in cloudkassir.items()} ck_ci = {str(k).lower(): v for k, v in cloudkassir.items()}
public_id_ck = ck_ci.get('public_id') public_id_ck = ck_ci.get('public_id')
api_secret_ck = ck_ci.get('api_secret') api_secret_ck = ck_ci.get('api_secret')
if api_secret_ck is None: if api_secret_ck is None:
api_secret_ck = ck_ci.get('secret') api_secret_ck = ck_ci.get('secret')
missing_ck = [] if public_id_ck is not None and str(public_id_ck).strip():
if public_id_ck is None or not str(public_id_ck).strip():
missing_ck.append('public_id')
if api_secret_ck is None or not str(api_secret_ck).strip():
missing_ck.append('api_secret')
if missing_ck:
raise RuntimeError(f'Vault secret cloudkassir missing non-empty keys: {missing_ck} (mount={mount},path=cloudkassir)')
data['CLOUD_KASSIR_PUBLIC_ID'] = str(public_id_ck).strip() data['CLOUD_KASSIR_PUBLIC_ID'] = str(public_id_ck).strip()
if api_secret_ck is not None and str(api_secret_ck).strip():
data['CLOUD_KASSIR_API_SECRET'] = str(api_secret_ck).strip() data['CLOUD_KASSIR_API_SECRET'] = str(api_secret_ck).strip()
return data return data

View File

@@ -37,7 +37,9 @@ class ItPayClient(IItPayService):
'usdt_exchange_rate': str(order.usdt_exchange_rate) if order.usdt_exchange_rate is not None else None, 'usdt_exchange_rate': str(order.usdt_exchange_rate) if order.usdt_exchange_rate is not None else None,
'gas_fee': str(order.gas_fee) if order.gas_fee is not None else None, 'gas_fee': str(order.gas_fee) if order.gas_fee is not None else None,
'service_fee': str(order.service_fee) if order.service_fee is not None else None, 'service_fee': str(order.service_fee) if order.service_fee is not None else None,
'agent_fee': str(order.service_fee) if order.service_fee is not None else None,
'amount': amount_str, 'amount': amount_str,
'total_amount': amount_str,
} }
if order.total_price is not None and order.service_fee is not None: if order.total_price is not None and order.service_fee is not None:
principal = (Decimal(str(order.total_price)) - Decimal(str(order.service_fee))).quantize(Decimal('0.01')) principal = (Decimal(str(order.total_price)) - Decimal(str(order.service_fee))).quantize(Decimal('0.01'))

View File

@@ -95,6 +95,7 @@ async def itpay_webhook(
'payment_id': data.get('id'), 'payment_id': data.get('id'),
'client_payment_id': data.get('client_payment_id'), 'client_payment_id': data.get('client_payment_id'),
'payment_status': status, 'payment_status': status,
'itpay_metadata': data.get('metadata'),
} }
logger.info(orjson.dumps(log_payload, default=str).decode()) logger.info(orjson.dumps(log_payload, default=str).decode())
if status == 'completed': if status == 'completed':