77 lines
3.2 KiB
Python
77 lines
3.2 KiB
Python
## 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
|