Refactor payment service, fix DB session, and consolidate endpoints
- Fix critical NameError in database.py by restoring Session factory - Refactor payment_service.py and crud.py to use shared constants.py and utils.py - Deduplicate state mapping and input sanitization logic - Move transaction amount calculation logic from CRUD to Router layer - Enforce type safety in schemas using IntEnum for TransactionType/Status - Move capture endpoint from transaction.py to payment.py (now /payments/capture) - Update create_customer_profile signature for clarity
This commit is contained in:
@@ -1,26 +1,19 @@
|
||||
## File: transaction.py (New transaction router)
|
||||
"""
|
||||
Transaction Router - Endpoints for transaction lookup and capture operations.
|
||||
"""
|
||||
import logging
|
||||
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
|
||||
from app.services.payment_service import parse_authnet_response, TransactionStatus
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# 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():
|
||||
@@ -29,9 +22,6 @@ def test_transaction_router():
|
||||
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)):
|
||||
"""
|
||||
@@ -84,36 +74,4 @@ def update_transaction_auto_id(transaction_id: int, new_auto_id: int, db: Sessio
|
||||
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
|
||||
logger.info(f"POST /capture - Capturing authorized transaction {transaction.auth_net_transaction_id}")
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user