## File: transaction.py (New transaction router) from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session import enum # Import locally to avoid circular imports import sys import os sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(__file__)))) from app import crud, database, schemas from app.services import payment_service # Create a router for transaction endpoints transaction_router = APIRouter() class TransactionStatus(enum.IntEnum): APPROVED = 0 DECLINED = 1 # Test endpoint to verify router is working @transaction_router.get("/test/", summary="Test transaction router") def test_transaction_router(): """Test endpoint to verify transaction router is loaded""" return {"test": "transaction router is working"} @transaction_router.get("/transaction/delivery/{delivery_id}", summary="Get pre-authorization transaction for a delivery") def get_delivery_transaction(delivery_id: int, db: Session = Depends(database.get_db)): """ Get the pre-authorization transaction for a specific delivery. This endpoint is used to retrieve transaction details for delivery finalization. """ transaction = crud.get_transaction_by_delivery_id(db, delivery_id=delivery_id) if not transaction: raise HTTPException(status_code=404, detail="No pre-authorization transaction found for this delivery") return { "id": transaction.id, "transaction_type": transaction.transaction_type, "status": transaction.status, "auth_net_transaction_id": transaction.auth_net_transaction_id, "preauthorize_amount": transaction.preauthorize_amount } @transaction_router.post("/capture/", response_model=schemas.Transaction, summary="Capture a previously authorized amount") def capture_authorized_amount(transaction: schemas.TransactionCapture, db: Session = Depends(database.get_db)): # This endpoint captures a previously authorized transaction # It finds the original transaction by its ID and captures the funds auth_transaction = crud.get_transaction_by_auth_id(db, auth_net_transaction_id=transaction.auth_net_transaction_id) if not auth_transaction: raise HTTPException(status_code=404, detail="Authorization transaction not found") # Call the capture service function auth_net_response = payment_service.capture_authorized_transaction(transaction) status, _, rejection_reason = _parse_authnet_response(auth_net_response) # Use the existing CRUD function to update the transaction return crud.update_transaction_for_capture( db=db, auth_net_transaction_id=transaction.auth_net_transaction_id, charge_amount=transaction.charge_amount, status=status, rejection_reason=rejection_reason ) def _parse_authnet_response(response): """ Parse Authorize.Net response for transaction status """ if response is not None and hasattr(response, 'messages') and response.messages.resultCode == "Ok": status = TransactionStatus.APPROVED rejection_reason = None else: status = TransactionStatus.DECLINED rejection_reason = "Payment declined by gateway." return status, None, rejection_reason