Files
2025-03-22 17:11:46 +01:00

169 lines
6.2 KiB
Python

"""
Controller for transaction check endpoints.
"""
from flask import Blueprint, request, jsonify
from flask.typing import ResponseReturnValue
from app.middleware import api_key_required
from app.models import (
TransactionCheckRequest, TransactionCheckResponse,
NewTransactionCheckRequest, NewTransactionCheckResponse,
TransactionData
)
import logging
from typing import Dict, Any
# Configure logger
logger = logging.getLogger(__name__)
# Create blueprint
transaction_bp = Blueprint('transaction', __name__)
@transaction_bp.route('/TransactionCheck', methods=['POST'])
@api_key_required
def transaction_check() -> ResponseReturnValue:
"""
Endpoint to check transaction status.
This method is used to double-check the response received from DisburseLoan
and CollectLoan Synchronous APIs. It verifies transaction results on FirstBank.
Returns:
JSON response with transaction status details
"""
try:
# Parse and validate request
data = request.get_json()
if not data:
logger.warning("Invalid JSON payload received")
return jsonify({
'resultCode': '400',
'resultDescription': 'Invalid JSON payload'
}), 400
# Validate required fields
required_fields = ['counter', 'TransactionId', 'requestID', 'customerId',
'accountId', 'countryId', 'transactionType']
missing_fields = [field for field in required_fields if field not in data]
if missing_fields:
logger.warning(f"Missing required fields: {', '.join(missing_fields)}")
return jsonify({
'resultCode': '422',
'resultDescription': f'Missing required fields: {", ".join(missing_fields)}'
}), 422
# Create request model
req = TransactionCheckRequest.from_dict(data)
# Process transaction check (this would connect to your business logic)
# For demonstration, we'll return a mock response
# Create response based on transaction type
provided_amount = 0.0
collected_amount = 0.0
if req.transactionType == "Disbursement":
provided_amount = 10000.0
elif req.transactionType == "Collection" or req.transactionType == "Penalty":
collected_amount = 7.50
# Create response
response = TransactionCheckResponse(
type_field="TransactionCheckResponse", # This will be converted to $type in JSON
nativeId=f"FBN20191031104405{req.customerId}",
customerId=req.customerId,
accountId=req.accountId,
providedAmount=provided_amount,
collectedAmount=collected_amount,
resultCode="00",
resultDescription=f"{req.transactionType} Status retrieved successfully."
)
logger.info(f"Processed transaction check for {req.transactionType}, ID {req.TransactionId}")
return jsonify(response.to_dict())
except Exception as e:
logger.exception(f"Error processing transaction check: {str(e)}")
return jsonify({
'resultCode': '500',
'resultDescription': f'Internal server error: {str(e)}'
}), 500
@transaction_bp.route('/NewTransactionCheck', methods=['POST'])
@api_key_required
def new_transaction_check() -> ResponseReturnValue:
"""
Endpoint to check status of transactions in asynchronous requests.
This method is used for checking the status of transactions when Simbrella
doesn't receive a callback notification within 5 minutes of the initial request.
Returns:
JSON response with detailed transaction status
"""
try:
# Parse and validate request
data = request.get_json()
if not data:
logger.warning("Invalid JSON payload received")
return jsonify({
'resultCode': '400',
'resultDescription': 'Invalid JSON payload'
}), 400
# Validate required fields
required_fields = ['transactionId', 'debtId', 'transactionType',
'fbnTransactionId', 'origTransactionId', 'customerId']
missing_fields = [field for field in required_fields if field not in data]
if missing_fields:
logger.warning(f"Missing required fields: {', '.join(missing_fields)}")
return jsonify({
'resultCode': '422',
'resultDescription': f'Missing required fields: {", ".join(missing_fields)}'
}), 422
# Create request model
req = NewTransactionCheckRequest.from_dict(data)
# Process new transaction check (this would connect to your business logic)
# For demonstration, we'll return a mock response
# Create transaction data based on transaction type
provided_amount = 0.0
collected_amount = 0.0
if req.transactionType == "Disbursement":
provided_amount = 1000.0
result_description = "Loan Provision is successful"
elif req.transactionType == "Collection":
collected_amount = 500.0
result_description = "Loan Collection is successful"
else: # PenalCharge
collected_amount = 50.0
result_description = "Penal Charge is successful"
# Create transaction data
transaction_data = TransactionData(
transactionId=req.origTransactionId,
providedAmount=provided_amount,
collectedAmount=collected_amount,
resultCode="00",
resultDescription=result_description
)
# Create response
response = NewTransactionCheckResponse(
transactionId=req.transactionId,
data=transaction_data.to_dict(),
resultCode="00",
resultDescription="SUCCESS"
)
logger.info(f"Processed new transaction check for {req.transactionType}, ID {req.transactionId}")
return jsonify(response.to_dict())
except Exception as e:
logger.exception(f"Error processing new transaction check: {str(e)}")
return jsonify({
'resultCode': '500',
'resultDescription': f'Internal server error: {str(e)}'
}), 500