Добавлено логирование операций оплаты в классе OracleDatabase и обновлены обработчики в main.py для сохранения информации о платежах. Реализована логика логирования успешных и неудачных операций для услуг DecodeVin, CheckSalvage и GetPhotos. Эти изменения улучшают отслеживание платежей и помогают в отладке.

This commit is contained in:
Vlad 2025-06-03 00:38:29 +03:00
parent f43580e1b0
commit a25c39e9cd
2 changed files with 205 additions and 1 deletions

68
db.py
View File

@ -404,3 +404,71 @@ class OracleDatabase:
return result[0] if result else 0 return result[0] if result else 0
import asyncio import asyncio
return await asyncio.to_thread(_query) return await asyncio.to_thread(_query)
async def save_payment_log(self, user: User, service_type: str, vin: str, payment_data: dict, service_result: dict = None) -> bool:
"""
Логирует операцию оплаты с полной информацией о пользователе, услуге и результате
Args:
user: Объект пользователя Telegram
service_type: Тип услуги ('decode_vin', 'check_salvage', 'get_photos')
vin: VIN номер автомобиля
payment_data: Данные о платеже (сумма, transaction_id, статус)
service_result: Результат предоставления услуги (количество данных, статус)
"""
def _save_log():
with self._pool.acquire() as conn:
with conn.cursor() as cur:
insert_query = """
INSERT INTO payment_logs (
log_id, user_id, user_first_name, user_last_name, user_username,
user_language_code, user_is_premium, service_type, vin_number,
payment_amount, transaction_id, payment_status, payment_currency,
service_status, data_found_count, refund_status, refund_reason,
vehicle_make, vehicle_model, vehicle_year, error_message,
created_date, ip_address
) VALUES (
payment_logs_seq.NEXTVAL, :user_id, :user_first_name, :user_last_name, :user_username,
:user_language_code, :user_is_premium, :service_type, :vin_number,
:payment_amount, :transaction_id, :payment_status, :payment_currency,
:service_status, :data_found_count, :refund_status, :refund_reason,
:vehicle_make, :vehicle_model, :vehicle_year, :error_message,
SYSDATE, :ip_address
)
"""
params = {
"user_id": user.id,
"user_first_name": user.first_name,
"user_last_name": user.last_name,
"user_username": user.username,
"user_language_code": user.language_code,
"user_is_premium": 1 if user.is_premium else 0,
"service_type": service_type,
"vin_number": vin,
"payment_amount": payment_data.get('amount', 0),
"transaction_id": payment_data.get('transaction_id'),
"payment_status": payment_data.get('status', 'completed'),
"payment_currency": payment_data.get('currency', 'XTR'),
"service_status": service_result.get('status', 'success') if service_result else 'pending',
"data_found_count": service_result.get('data_count', 0) if service_result else 0,
"refund_status": payment_data.get('refund_status', 'no_refund'),
"refund_reason": payment_data.get('refund_reason'),
"vehicle_make": service_result.get('vehicle_make') if service_result else None,
"vehicle_model": service_result.get('vehicle_model') if service_result else None,
"vehicle_year": service_result.get('vehicle_year') if service_result else None,
"error_message": service_result.get('error') if service_result else None,
"ip_address": None # Telegram не предоставляет IP адреса
}
cur.execute(insert_query, params)
conn.commit()
return True
try:
import asyncio
loop = asyncio.get_event_loop()
return await loop.run_in_executor(None, _save_log)
except Exception as e:
print(f"Error saving payment log for user {user.id}: {e}")
return False

138
main.py
View File

@ -785,6 +785,15 @@ async def successful_payment_handler(message: Message, db: OracleDatabase = None
await database.update_user_payment(message.from_user.id, payment_amount) await database.update_user_payment(message.from_user.id, payment_amount)
# Подготавливаем базовые данные платежа для логирования
payment_data = {
'amount': payment_amount,
'transaction_id': message.successful_payment.telegram_payment_charge_id,
'status': 'completed',
'currency': 'XTR',
'refund_status': 'no_refund'
}
if payload.startswith("detailed_vin_info:"): if payload.startswith("detailed_vin_info:"):
vin = payload.split(":")[1] vin = payload.split(":")[1]
@ -911,6 +920,17 @@ async def successful_payment_handler(message: Message, db: OracleDatabase = None
await message.answer(plain_report, reply_markup=builder.as_markup()) await message.answer(plain_report, reply_markup=builder.as_markup())
logging.info("Plain text message sent successfully!") logging.info("Plain text message sent successfully!")
# Логируем успешную операцию DecodeVin
service_result = {
'status': 'success',
'data_count': len(detailed_info['all_params']),
'vehicle_make': params.get('make', 'N/A'),
'vehicle_model': params.get('model', 'N/A'),
'vehicle_year': params.get('model_year', 'N/A')
}
await database.save_payment_log(message.from_user, "decode_vin", vin, payment_data, service_result)
logging.info(f"Payment logged successfully for DecodeVin service - User: {message.from_user.id}, VIN: {vin}")
# Проверяем, является ли пользователь администратором и возвращаем звезды # Проверяем, является ли пользователь администратором и возвращаем звезды
if message.from_user.id == ADMIN_USER_ID: if message.from_user.id == ADMIN_USER_ID:
try: try:
@ -918,6 +938,7 @@ async def successful_payment_handler(message: Message, db: OracleDatabase = None
user_id=message.from_user.id, user_id=message.from_user.id,
telegram_payment_charge_id=message.successful_payment.telegram_payment_charge_id telegram_payment_charge_id=message.successful_payment.telegram_payment_charge_id
) )
payment_data['refund_status'] = 'admin_refund'
await message.answer( await message.answer(
"🔧 **Admin Refund**\n\n" "🔧 **Admin Refund**\n\n"
f"💰 Payment automatically refunded for admin user.\n" f"💰 Payment automatically refunded for admin user.\n"
@ -936,6 +957,16 @@ async def successful_payment_handler(message: Message, db: OracleDatabase = None
) )
else: else:
# No detailed information found - refund the payment # No detailed information found - refund the payment
service_result = {
'status': 'no_data',
'data_count': 0,
'error': 'No detailed information found for VIN'
}
payment_data['refund_status'] = 'auto_refund'
payment_data['refund_reason'] = 'No detailed information found'
await database.save_payment_log(message.from_user, "decode_vin", vin, payment_data, service_result)
logging.info(f"Payment logged for DecodeVin no data case - User: {message.from_user.id}, VIN: {vin}")
try: try:
await message.bot.refund_star_payment( await message.bot.refund_star_payment(
user_id=message.from_user.id, user_id=message.from_user.id,
@ -954,10 +985,20 @@ async def successful_payment_handler(message: Message, db: OracleDatabase = None
"⚠️ Please contact support with this transaction ID for a refund:\n" "⚠️ Please contact support with this transaction ID for a refund:\n"
f"🆔 {message.successful_payment.telegram_payment_charge_id}" f"🆔 {message.successful_payment.telegram_payment_charge_id}"
) )
except Exception as e: except Exception as e:
logging.error(f"Error getting detailed VIN info for {vin}: {e}") logging.error(f"Error getting detailed VIN info for {vin}: {e}")
# Логируем ошибку
service_result = {
'status': 'error',
'data_count': 0,
'error': str(e)
}
payment_data['refund_status'] = 'auto_refund'
payment_data['refund_reason'] = 'Service error'
await database.save_payment_log(message.from_user, "decode_vin", vin, payment_data, service_result)
logging.info(f"Payment logged for DecodeVin error case - User: {message.from_user.id}, VIN: {vin}")
# Attempt to refund the payment due to service error # Attempt to refund the payment due to service error
try: try:
await message.bot.refund_star_payment( await message.bot.refund_star_payment(
@ -1092,6 +1133,17 @@ async def successful_payment_handler(message: Message, db: OracleDatabase = None
await message.answer(plain_report, reply_markup=builder.as_markup()) await message.answer(plain_report, reply_markup=builder.as_markup())
logging.info("Plain text message sent successfully!") logging.info("Plain text message sent successfully!")
# Логируем успешную операцию CheckSalvage
service_result = {
'status': 'success',
'data_count': len(salvage_records),
'vehicle_make': make,
'vehicle_model': model,
'vehicle_year': year
}
await database.save_payment_log(message.from_user, "check_salvage", vin, payment_data, service_result)
logging.info(f"Payment logged successfully for CheckSalvage service - User: {message.from_user.id}, VIN: {vin}")
# Отправляем отдельное сообщение о фотографиях # Отправляем отдельное сообщение о фотографиях
if salvage_records and salvage_records[0]['img_count'] > 0: if salvage_records and salvage_records[0]['img_count'] > 0:
img_count = salvage_records[0]['img_count'] img_count = salvage_records[0]['img_count']
@ -1109,6 +1161,7 @@ async def successful_payment_handler(message: Message, db: OracleDatabase = None
user_id=message.from_user.id, user_id=message.from_user.id,
telegram_payment_charge_id=message.successful_payment.telegram_payment_charge_id telegram_payment_charge_id=message.successful_payment.telegram_payment_charge_id
) )
payment_data['refund_status'] = 'admin_refund'
await message.answer( await message.answer(
"🔧 **Admin Refund**\n\n" "🔧 **Admin Refund**\n\n"
f"💰 Payment automatically refunded for admin user.\n" f"💰 Payment automatically refunded for admin user.\n"
@ -1127,6 +1180,16 @@ async def successful_payment_handler(message: Message, db: OracleDatabase = None
) )
else: else:
# Нет записей - возвращаем деньги # Нет записей - возвращаем деньги
service_result = {
'status': 'no_data',
'data_count': 0,
'error': 'No salvage records found for VIN'
}
payment_data['refund_status'] = 'auto_refund'
payment_data['refund_reason'] = 'No salvage records found'
await database.save_payment_log(message.from_user, "check_salvage", vin, payment_data, service_result)
logging.info(f"Payment logged for CheckSalvage no data case - User: {message.from_user.id}, VIN: {vin}")
try: try:
await message.bot.refund_star_payment( await message.bot.refund_star_payment(
user_id=message.from_user.id, user_id=message.from_user.id,
@ -1149,6 +1212,17 @@ async def successful_payment_handler(message: Message, db: OracleDatabase = None
except Exception as e: except Exception as e:
logging.error(f"Error getting salvage info for {vin}: {e}") logging.error(f"Error getting salvage info for {vin}: {e}")
# Логируем ошибку
service_result = {
'status': 'error',
'data_count': 0,
'error': str(e)
}
payment_data['refund_status'] = 'auto_refund'
payment_data['refund_reason'] = 'Service error'
await database.save_payment_log(message.from_user, "check_salvage", vin, payment_data, service_result)
logging.info(f"Payment logged for CheckSalvage error case - User: {message.from_user.id}, VIN: {vin}")
# Возвращаем деньги при ошибке # Возвращаем деньги при ошибке
try: try:
await message.bot.refund_star_payment( await message.bot.refund_star_payment(
@ -1215,12 +1289,32 @@ async def successful_payment_handler(message: Message, db: OracleDatabase = None
# Отправляем фотографии # Отправляем фотографии
await send_vehicle_photos(message, vin, full_photo_paths, make, model, year) await send_vehicle_photos(message, vin, full_photo_paths, make, model, year)
# Логируем успешную операцию GetPhotos
service_result = {
'status': 'success',
'data_count': len(full_photo_paths),
'vehicle_make': make,
'vehicle_model': model,
'vehicle_year': year
}
await database.save_payment_log(message.from_user, "get_photos", vin, payment_data, service_result)
logging.info(f"Payment logged successfully for GetPhotos service - User: {message.from_user.id}, VIN: {vin}")
else: else:
await message.answer( await message.answer(
"⚠️ **Warning:** No photo paths found in database despite photo count > 0.\n" "⚠️ **Warning:** No photo paths found in database despite photo count > 0.\n"
"Please contact support with your transaction details." "Please contact support with your transaction details."
) )
logging.warning(f"No photo paths found for VIN {vin} despite photo_count = {photo_count}") logging.warning(f"No photo paths found for VIN {vin} despite photo_count = {photo_count}")
# Логируем проблему с путями к фотографиям
service_result = {
'status': 'error',
'data_count': 0,
'error': 'Photo paths not found despite photo count > 0'
}
await database.save_payment_log(message.from_user, "get_photos", vin, payment_data, service_result)
logging.info(f"Payment logged for GetPhotos path error case - User: {message.from_user.id}, VIN: {vin}")
except Exception as markdown_error: except Exception as markdown_error:
logging.error(f"Markdown parsing failed for photos payment: {markdown_error}") logging.error(f"Markdown parsing failed for photos payment: {markdown_error}")
@ -1240,12 +1334,32 @@ async def successful_payment_handler(message: Message, db: OracleDatabase = None
# Отправляем фотографии # Отправляем фотографии
await send_vehicle_photos(message, vin, full_photo_paths, make, model, year) await send_vehicle_photos(message, vin, full_photo_paths, make, model, year)
# Логируем успешную операцию GetPhotos (fallback)
service_result = {
'status': 'success',
'data_count': len(full_photo_paths),
'vehicle_make': make,
'vehicle_model': model,
'vehicle_year': year
}
await database.save_payment_log(message.from_user, "get_photos", vin, payment_data, service_result)
logging.info(f"Payment logged successfully for GetPhotos service (fallback) - User: {message.from_user.id}, VIN: {vin}")
else: else:
await message.answer( await message.answer(
"Warning: No photo paths found in database despite photo count > 0. " "Warning: No photo paths found in database despite photo count > 0. "
"Please contact support with your transaction details." "Please contact support with your transaction details."
) )
logging.warning(f"No photo paths found for VIN {vin} despite photo_count = {photo_count} (fallback)") logging.warning(f"No photo paths found for VIN {vin} despite photo_count = {photo_count} (fallback)")
# Логируем проблему с путями к фотографиям (fallback)
service_result = {
'status': 'error',
'data_count': 0,
'error': 'Photo paths not found despite photo count > 0 (fallback)'
}
await database.save_payment_log(message.from_user, "get_photos", vin, payment_data, service_result)
logging.info(f"Payment logged for GetPhotos fallback path error case - User: {message.from_user.id}, VIN: {vin}")
# Проверяем, является ли пользователь администратором и возвращаем звезды # Проверяем, является ли пользователь администратором и возвращаем звезды
if message.from_user.id == ADMIN_USER_ID: if message.from_user.id == ADMIN_USER_ID:
@ -1254,6 +1368,7 @@ async def successful_payment_handler(message: Message, db: OracleDatabase = None
user_id=message.from_user.id, user_id=message.from_user.id,
telegram_payment_charge_id=message.successful_payment.telegram_payment_charge_id telegram_payment_charge_id=message.successful_payment.telegram_payment_charge_id
) )
payment_data['refund_status'] = 'admin_refund'
await message.answer( await message.answer(
"🔧 **Admin Refund**\n\n" "🔧 **Admin Refund**\n\n"
f"💰 Payment automatically refunded for admin user.\n" f"💰 Payment automatically refunded for admin user.\n"
@ -1272,6 +1387,16 @@ async def successful_payment_handler(message: Message, db: OracleDatabase = None
) )
else: else:
# Нет фотографий - возвращаем деньги # Нет фотографий - возвращаем деньги
service_result = {
'status': 'no_data',
'data_count': 0,
'error': 'No photos found for VIN'
}
payment_data['refund_status'] = 'auto_refund'
payment_data['refund_reason'] = 'No photos found'
await database.save_payment_log(message.from_user, "get_photos", vin, payment_data, service_result)
logging.info(f"Payment logged for GetPhotos no data case - User: {message.from_user.id}, VIN: {vin}")
try: try:
await message.bot.refund_star_payment( await message.bot.refund_star_payment(
user_id=message.from_user.id, user_id=message.from_user.id,
@ -1294,6 +1419,17 @@ async def successful_payment_handler(message: Message, db: OracleDatabase = None
except Exception as e: except Exception as e:
logging.error(f"Error getting photos info for {vin}: {e}") logging.error(f"Error getting photos info for {vin}: {e}")
# Логируем ошибку
service_result = {
'status': 'error',
'data_count': 0,
'error': str(e)
}
payment_data['refund_status'] = 'auto_refund'
payment_data['refund_reason'] = 'Service error'
await database.save_payment_log(message.from_user, "get_photos", vin, payment_data, service_result)
logging.info(f"Payment logged for GetPhotos error case - User: {message.from_user.id}, VIN: {vin}")
# Возвращаем деньги при ошибке # Возвращаем деньги при ошибке
try: try:
await message.bot.refund_star_payment( await message.bot.refund_star_payment(