133 lines
4.2 KiB
Python
133 lines
4.2 KiB
Python
import logging
|
|
import sys
|
|
from fastapi import FastAPI
|
|
from .database import engine
|
|
from . import models
|
|
from .routers import payment
|
|
from .routers.transaction import transaction_router
|
|
from .routers.auto import auto_router
|
|
from .routers.user_check import user_check_router
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
from config import load_config
|
|
from authorizenet import apicontractsv1
|
|
from authorizenet.apicontrollers import getCustomerProfileIdsController
|
|
from authorizenet.constants import constants
|
|
|
|
|
|
ApplicationConfig = load_config()
|
|
|
|
# Configure logging
|
|
def setup_logging():
|
|
"""Configure structured logging for the application."""
|
|
log_level = logging.DEBUG if ApplicationConfig.CURRENT_SETTINGS != 'PRODUCTION' else logging.INFO
|
|
|
|
formatter = logging.Formatter(
|
|
'%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
|
datefmt='%Y-%m-%d %H:%M:%S'
|
|
)
|
|
|
|
root_logger = logging.getLogger()
|
|
root_logger.setLevel(log_level)
|
|
root_logger.handlers.clear()
|
|
|
|
console_handler = logging.StreamHandler(sys.stdout)
|
|
console_handler.setLevel(log_level)
|
|
console_handler.setFormatter(formatter)
|
|
root_logger.addHandler(console_handler)
|
|
|
|
# Reduce noise from uvicorn and other libs
|
|
logging.getLogger('uvicorn.access').setLevel(logging.WARNING)
|
|
|
|
return logging.getLogger('eamco_authorize')
|
|
|
|
logger = setup_logging()
|
|
|
|
|
|
models.Base.metadata.create_all(bind=engine)
|
|
|
|
app = FastAPI()
|
|
|
|
|
|
# print(ApplicationConfig.origins)
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=ApplicationConfig.origins,
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
|
|
|
|
app.include_router(payment.router, prefix="/api", tags=["payment"])
|
|
app.include_router(transaction_router, prefix="/api", tags=["transactions"])
|
|
app.include_router(auto_router, prefix="/api", tags=["auto"])
|
|
app.include_router(user_check_router, prefix="/user", tags=["usercheck"])
|
|
|
|
|
|
|
|
@app.get("/")
|
|
def read_root():
|
|
return {"message": "Welcome to the HVAC Payment API"}
|
|
|
|
|
|
def validate_authorize_credentials():
|
|
"""
|
|
Validates Authorize.net credentials at startup.
|
|
Returns True if credentials are valid, raises exception if not.
|
|
"""
|
|
api_login_id = ApplicationConfig.API_LOGIN_ID
|
|
transaction_key = ApplicationConfig.TRANSACTION_KEY
|
|
|
|
# Check if credentials are present
|
|
if not api_login_id or not api_login_id.strip():
|
|
raise ValueError("AUTHORIZE_API_LOGIN_ID is not configured")
|
|
if not transaction_key or not transaction_key.strip():
|
|
raise ValueError("AUTHORIZE_TRANSACTION_KEY is not configured")
|
|
|
|
# Test the credentials by making a simple API call
|
|
merchantAuth = apicontractsv1.merchantAuthenticationType(
|
|
name=api_login_id,
|
|
transactionKey=transaction_key
|
|
)
|
|
|
|
request = apicontractsv1.getCustomerProfileIdsRequest(
|
|
merchantAuthentication=merchantAuth
|
|
)
|
|
|
|
controller = getCustomerProfileIdsController(request)
|
|
|
|
# Set environment based on config
|
|
if ApplicationConfig.CURRENT_SETTINGS in ['PRODUCTION', 'LOCAL']:
|
|
controller.setenvironment(constants.PRODUCTION)
|
|
else:
|
|
controller.setenvironment(constants.SANDBOX)
|
|
|
|
controller.execute()
|
|
response = controller.getresponse()
|
|
|
|
if response is None:
|
|
raise ValueError("Could not connect to Authorize.net - check network connectivity")
|
|
|
|
if response.messages.resultCode != "Ok":
|
|
error_code = response.messages.message[0].code if response.messages.message else "Unknown"
|
|
error_text = response.messages.message[0].text if response.messages.message else "Unknown error"
|
|
raise ValueError(f"Authorize.net credential validation failed: {error_code} - {error_text}")
|
|
|
|
return True
|
|
|
|
|
|
@app.on_event("startup")
|
|
async def startup_event():
|
|
"""Application startup - validate payment credentials."""
|
|
logger.info("Starting eamco_authorize service...")
|
|
logger.info(f"Mode: {ApplicationConfig.CURRENT_SETTINGS}")
|
|
|
|
try:
|
|
validate_authorize_credentials()
|
|
logger.info("Authorize.net credentials: VALID")
|
|
except ValueError as e:
|
|
logger.critical(f"PAYMENT CREDENTIALS INVALID: {e}")
|
|
logger.critical("Service will start but ALL PAYMENT OPERATIONS WILL FAIL")
|
|
# In production, you might want to sys.exit(1) here instead
|