from os import access import httpx import time from app.utils.logger import logger from app.config import settings class SimbrellaIntegration: BASE_URL = settings.SIMBRELLA_BASE_URL ENDPOINT_RAC_CHECKS = settings.SIMBRELLA_ENDPOINT_RAC_CHECKS HEALTH_ENDPOINT = settings.SIMBRELLA_HEALTH AUTH_ENDPOINT = settings.BANK_CALL_AUTH_ENDPOINT _access_token = None # cache token in memory _token_expiry = 0 @staticmethod def generate_token(): """ Generate a new access token using the username and password from settings. """ url = f"{SimbrellaIntegration.BASE_URL}{SimbrellaIntegration.AUTH_ENDPOINT}" payload = { "username": settings.BANK_CALL_USERNAME, "password": settings.BANK_CALL_PASSWORD, "grant_type": "password" } headers = {"Content-Type": "application/json"} try: logger.info(f"Requesting Bank token from {url}") response = httpx.post(url, json=payload, headers=headers, timeout=10.0) response.raise_for_status() data = response.json() expires_in = data.get("expires_in", 1800) SimbrellaIntegration._access_token = data.get("access_token") SimbrellaIntegration._token_expiry = time.time() + expires_in - 60 if not SimbrellaIntegration._access_token: raise Exception("Access token not found in Bank Authorization response") logger.info("Successfully retrieved Bank access token") return SimbrellaIntegration._access_token except Exception as e: logger.error(f"Token generation failed: {str(e)}", exc_info=True) raise Exception(f"Token generation failed: {str(e)}") @staticmethod def _get_token(): """ Return a valid token, refreshing if expired or missing """ if not SimbrellaIntegration._access_token or time.time() >= SimbrellaIntegration._token_expiry: return SimbrellaIntegration.generate_token() return SimbrellaIntegration._access_token @staticmethod def rac_check(customer_id, account_id, transaction_id): """ Calls the RACCheck endpoit """ url = f"{SimbrellaIntegration.BASE_URL}/{SimbrellaIntegration.ENDPOINT_RAC_CHECKS}" logger.info(f"Contacting Rack Checks EndPoint: {str(url)}", exc_info=True) payload = { "customerId": customer_id, "accountId": account_id, "transactionId": str(transaction_id), "fbnTransactionId": str(transaction_id), "countryCode": "NG", "channel": "USSD" } try: access_token = SimbrellaIntegration._get_token() headers = { "Content-Type": "application/json", "Authorization": f"Bearer {access_token}" } response = httpx.post(url, json=payload, headers=headers, timeout=10.0) logger.info(f"This is Response: {str(response)}", exc_info=True) return response except Exception as e: logger.error(f"RACCheck API call failed: {str(e)}", exc_info=True) raise Exception(f"RACCheck API call failed: {str(e)}") @staticmethod def health_check(): """ Health check for Bank Service """ url = f"{SimbrellaIntegration.BASE_URL}/{SimbrellaIntegration.HEALTH_ENDPOINT}" logger.info(f"Bank Health Check URL: {url}") try: access_token = SimbrellaIntegration._get_token() headers = { "Content-Type": "application/json", "Authorization": f"Bearer {access_token}" } response = httpx.get(url, headers=headers, timeout=10.0) logger.info(f"Bank Health Check Response: {response.text}") return response except Exception as e: logger.error(f"Bank Health Check API call failed: {str(e)}", exc_info=True) raise Exception(f"Bank Health Check API call failed: {str(e)}")