112 lines
4.5 KiB
Python
112 lines
4.5 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, models
|
|
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.put("/transaction/delivery/{delivery_id}/update/{new_delivery_id}", summary="Update delivery_id for transaction")
|
|
def update_transaction_delivery(delivery_id: int, new_delivery_id: int, db: Session = Depends(database.get_db)):
|
|
"""
|
|
Update the delivery_id of a transaction based on the current delivery_id.
|
|
Used to change transaction from auto_delivery.id to auto_ticket.id
|
|
"""
|
|
transaction = crud.get_transaction_by_delivery_id(db, delivery_id=delivery_id)
|
|
if not transaction:
|
|
raise HTTPException(status_code=404, detail="No transaction found for this delivery")
|
|
|
|
transaction.delivery_id = new_delivery_id
|
|
db.commit()
|
|
return {"message": "Transaction delivery_id updated"}
|
|
|
|
|
|
@transaction_router.put("/transaction/{transaction_id}/update_auto_id/{new_auto_id}", summary="Update auto_id for transaction")
|
|
def update_transaction_auto_id(transaction_id: int, new_auto_id: int, db: Session = Depends(database.get_db)):
|
|
"""
|
|
Update the auto_id of a transaction by its ID.
|
|
Used to set auto_id to auto_ticket.id after ticket creation.
|
|
"""
|
|
transaction = db.query(models.Transaction).filter(models.Transaction.id == transaction_id).first()
|
|
if not transaction:
|
|
raise HTTPException(status_code=404, detail="Transaction not found")
|
|
|
|
transaction.auto_id = new_auto_id
|
|
db.commit()
|
|
return {"message": "Transaction auto_id updated"}
|
|
|
|
|
|
@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.messages.resultCode == "Ok":
|
|
status = TransactionStatus.APPROVED
|
|
rejection_reason = None
|
|
else:
|
|
status = TransactionStatus.DECLINED
|
|
rejection_reason = "Payment declined by gateway."
|
|
return status, None, rejection_reason
|