110 lines
3.0 KiB
Python
110 lines
3.0 KiB
Python
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,
|
|
} |