import time from sqlalchemy.orm import Session from app.services.transaction_service import ( get_transaction_by_payme_id, create_transaction, update_transaction_state, ) from app.services.shopify_service import mark_order_paid, get_shopify_order from app.core.constants import ( STATE_CREATED, STATE_COMPLETED, STATE_CANCELLED, ERROR_TRANSACTION_NOT_FOUND, ) async def check_perform_transaction(params: dict) -> dict: order_id = params["account"]["order"] payme_amount = params["amount"] # tiyin order = await get_shopify_order(order_id) if not order: return {"allow": False} # Draft orders use "total_price", completed orders too — same field name shopify_amount = int(float(order["total_price"]) * 100) if shopify_amount != payme_amount: return {"allow": False} # Draft: status field is "status" not "financial_status" if order.get("_is_draft"): already_paid = order.get("status") == "completed" else: already_paid = order.get("financial_status") == "paid" if already_paid: return {"allow": False} return {"allow": True} async def create_transaction_handler(db: Session, params: dict) -> dict: payme_id = params["id"] order_id = params["account"]["order"] amount = params["amount"] existing = get_transaction_by_payme_id(db, payme_id) if existing: return { "create_time": int(time.time() * 1000), "transaction": payme_id, "state": existing.state, } create_transaction(db, order_id, payme_id, amount) return { "create_time": int(time.time() * 1000), "transaction": payme_id, "state": STATE_CREATED, } async def perform_transaction_handler(db: Session, params: dict) -> dict | None: payme_id = params["id"] transaction = get_transaction_by_payme_id(db, payme_id) if not transaction: return None if transaction.state == STATE_COMPLETED: return { "perform_time": int(time.time() * 1000), "transaction": payme_id, "state": STATE_COMPLETED, } update_transaction_state(db, transaction, STATE_COMPLETED) # Fetch order to know if it's a draft order = await get_shopify_order(transaction.order_id) is_draft = order.get("_is_draft", False) if order else False amount_uzs = str(transaction.amount / 100) await mark_order_paid(transaction.order_id, amount_uzs, is_draft=is_draft) return { "perform_time": int(time.time() * 1000), "transaction": payme_id, "state": STATE_COMPLETED, } async def cancel_transaction_handler(db: Session, params: dict) -> dict | None: payme_id = params["id"] transaction = get_transaction_by_payme_id(db, payme_id) if not transaction: return None update_transaction_state(db, transaction, STATE_CANCELLED) return { "cancel_time": int(time.time() * 1000), "transaction": payme_id, "state": STATE_CANCELLED, }