Merge branch 'oluyemi' of DigiFi/digifi-EventManager into master

This commit is contained in:
2025-04-14 14:50:44 +00:00
committed by Gogs
9 changed files with 132 additions and 754 deletions
-2
View File
@@ -14,8 +14,6 @@ class Config:
KAFKA_PAYMENT_TOPIC = "PROCESS_PAYMENT"
KAFKA_TIMEOUT = float( os.getenv("KAFKA_TIMEOUT", 1000.0) )
JWT_SECRET_KEY = os.getenv("JWT_SECRET_KEY", "secret-key")
JWT_ACCESS_TOKEN_EXPIRES = os.getenv("JWT_ACCESS_TOKEN_EXPIRES", timedelta(hours=1))
JWT_REFRESH_TOKEN_EXPIRES = os.getenv(
"JWT_REFRESH_TOKEN_EXPIRES", timedelta(days=30)
+22 -8
View File
@@ -59,7 +59,7 @@ class KafkaIntegration:
logger.info(
f"Waiting for messages from topic {topic} with this timeout: {timeout}..."
)
message =[]
message = []
try:
msg = consumer.poll(timeout=timeout)
@@ -100,10 +100,10 @@ class KafkaIntegration:
current_topic = msg.topic()
if current_topic=="PROCESS_PAYMENT":
KafkaIntegration._call_disbursement_endpoint(message)
KafkaIntegration._call_disbursement_service(message)
if current_topic=="LOAN_REPAYMENT":
# Do loan repayment call here
KafkaIntegration._call_collect_loan_service(message)
logger.info(
f"Loan Repayment message from {msg.topic()} [{msg.partition()}] @ offset {msg.offset()}: {message}"
)
@@ -124,15 +124,29 @@ class KafkaIntegration:
logger.info("Kafka consumer closed")
@staticmethod
def _call_disbursement_endpoint(message):
"""Call the disbursement endpoint with the received message"""
logger.info(f"Calling disbursement endpoint with message: {message}")
def _call_disbursement_service(message):
"""Call the disbursement service with the received message"""
logger.info(f"Calling disbursement service with message: {message}")
try:
response = SimbrellaClient.disbursement(message)
logger.info(
f"Successfully sent message to disbursement endpoint: {response.status_code}"
f"Successfully sent message to disbursement service: {response.status_code}"
)
except Exception as e:
logger.info(f"Failed to call disbursement endpoint: {e}")
logger.info(f"Failed to call disbursement service: {e}")
#raise
@staticmethod
def _call_collect_loan_service(message):
"""Call the collect loan service with the received message"""
logger.info(f"Calling collect_loan service with message: {message}")
try:
response = SimbrellaClient.collect_loan(message)
logger.info(
f"Successfully sent message to collect_loan service: {response.status_code}"
)
except Exception as e:
logger.info(f"Failed to call collect_loan service: {e}")
# raise
+92 -7
View File
@@ -6,15 +6,13 @@ from flask import jsonify
class SimbrellaClient:
BASE_URL = settings.BANK_CALL_BASE_URL
BANK_CALL_BASE_URL = settings.BANK_CALL_BASE_URL
@staticmethod
def disbursement(data):
BANK_CALL_BASE_URL = "https://bank-emulator.dev.simbrellang.net"
api_url = f"{BANK_CALL_BASE_URL}/Disbursement"
logger.info(f"BANK_CALL_BASE_URL = {BANK_CALL_BASE_URL}")
logger.info(f"Calling disbursement endpoint with data: {data}")
api_url = f"{SimbrellaClient.BANK_CALL_BASE_URL}/Disbursement"
logger.info(f"BANK_CALL_BASE_URL = {SimbrellaClient.BANK_CALL_BASE_URL}")
logger.info(f"Calling Disbursement endpoint with data: {data}")
data={
"requestId": "RQID1743987402764",
@@ -47,9 +45,96 @@ class SimbrellaClient:
logger.info(f"Disbursement response: {response.json()}")
except Exception as e:
logger.info(f"Failed to call disbursement endpoint: {e}")
logger.info(f"Failed to call Disbursement endpoint: {e}")
#raise
return 0
# return jsonify(response.json()), response.status_code
return 1
return 1
@staticmethod
def collect_loan(data):
api_url = f"{SimbrellaClient.BANK_CALL_BASE_URL}/CollectLoan"
logger.info(f"BANK_CALL_BASE_URL = {SimbrellaClient.BANK_CALL_BASE_URL}")
logger.info(f"Calling CollectLoan endpoint with data: {data}")
collect_loan_data = {
"transactionId": "T002",
"fbnTransactionId": "FBN20231123",
"debtId": "273194670",
"customerId": "CN621868",
"accountId": "2017821799",
"productId": "101",
"collectAmount": 80000,
"penalCharge": 0,
"collectionMethod": 1,
"lienAmount": 80000,
"countryId": "01",
"comment": "Testing CollectionLoanRequest"
}
try:
logger.info(f"Here is your CollectLoan Request data ***** : {collect_loan_data}")
response = requests.post(api_url, json=collect_loan_data, headers=get_headers())
logger.info(f"CollectLoan response: {response.json()}")
except Exception as e:
logger.info(f"Failed to call CollectLoan endpoint: {e}")
return 0
return 1
@staticmethod
def verify_transaction(data):
api_url = f"{SimbrellaClient.BANK_CALL_BASE_URL}/TransactionVerify"
logger.info(f"BANK_CALL_BASE_URL = {SimbrellaClient.BANK_CALL_BASE_URL}")
logger.info(f"Calling TransactionVerify endpoint with data: {data}")
try:
logger.info(f"Here is your TransactionVerify Request data ***** : {data}")
response = requests.post(api_url, json=data, headers=get_headers())
logger.info(f"TransactionVerify response: {response.json()}")
return response.json()
except Exception as e:
logger.info(f"Failed to call TransactionVerify endpoint: {e}")
raise
@staticmethod
def refresh_disbursement(data):
api_url = f"{SimbrellaClient.BANK_CALL_BASE_URL}/Disbursement"
logger.info(f"BANK_CALL_BASE_URL = {SimbrellaClient.BANK_CALL_BASE_URL}")
logger.info(f"Calling Disbursement endpoint with data: {data}")
try:
logger.info(f"Here is your Disbursement Request data ***** : {data}")
# response = requests.post(api_url, json=data, headers=get_headers())
# logger.info(f"Disbursement response: {response.json()}")
# return response.json()
return data
except Exception as e:
logger.info(f"Failed to call Disbursement endpoint: {e}")
raise
@staticmethod
def payment_callback(data):
api_url = f"{SimbrellaClient.BANK_CALL_BASE_URL}/Payment"
logger.info(f"BANK_CALL_BASE_URL = {SimbrellaClient.BANK_CALL_BASE_URL}")
logger.info(f"Calling Payment Callback endpoint with data: {data}")
try:
logger.info(f"Here is your Payment Callback Request data ***** : {data}")
# response = requests.post(api_url, json=data, headers=get_headers())
# logger.info(f"Payment Callback response: {response.json()}")
# return response.json()
return data
except Exception as e:
logger.info(f"Failed to call Payment Callback endpoint: {e}")
raise
-2
View File
@@ -1,4 +1,2 @@
from .authentication import auth_bp
from .eligibility import eligibility_bp
from .loan import loan_bp
from .autocall import autocall_bp
+14 -4
View File
@@ -3,24 +3,34 @@ import requests
from app.config import settings
from app.utils.auth import get_headers
from app.utils.logger import logger
from app.integrations.simbrella import SimbrellaClient
autocall_bp = Blueprint("autocall", __name__)
@autocall_bp.route("/refresh-verify-disbursement", methods=["GET"])
def verify_transaction():
data = request.json()
logger.info(f"Calling Verify Components")
return jsonify(data), 200
logger.info(f"Calling VerifyTransaction Components")
response = SimbrellaClient.verify_transaction(data)
return jsonify(response), 200
@autocall_bp.route("/refresh-disbursement", methods=["GET"])
def disbursement():
data = request.json()
logger.info(f"Calling Disbursement Components")
return jsonify(data), 200
response = SimbrellaClient.verify_transaction(data)
return jsonify(response), 200
@autocall_bp.route("/payment-callback", methods=["POST"])
def payment_callback():
data = request.json()
logger.info(f"Calling Callback Components")
return jsonify(data), 200
response = SimbrellaClient.payment_callback(data)
return jsonify(response), 200
-43
View File
@@ -1,43 +0,0 @@
from flask import Blueprint, request, jsonify, current_app
from app.config import settings
import requests
from app.utils.auth import get_headers
eligibility_bp = Blueprint("eligibility", __name__)
BASE_URL = settings.BANK_CALL_BASE_URL
@eligibility_bp.route("/check", methods=["POST"])
def eligibility_check():
data = request.json
api_url = f"{BASE_URL}/EligibilityCheck"
# response = requests.post(api_url, json=data, headers=get_headers())
# return jsonify(response.json()), response.status_code
response = {
"customerId": "CN621868",
"transactionId": "Tr201712RK9232P115",
"countryCode": "NGR",
"msisdn": "2348012345678",
"eligibleOffers": [
{
"offerId": 101,
"minAmount": 5000,
"maxAmount": 20000,
"productId": 2030,
"tenor": 30,
},
{
"offerId": 102,
"minAmount": 20000,
"maxAmount": 50000,
"productId": 2090,
"tenor": 90,
},
],
"resultCode": "00",
"resultDescription": "Successful",
}
return jsonify(response), 200
-253
View File
@@ -1,253 +0,0 @@
from flask import Blueprint, request, jsonify, current_app
import requests
from app.config import settings
from app.utils.auth import get_headers
from app.utils.logger import logger
loan_bp = Blueprint("loan", __name__)
BASE_URL = settings.BANK_CALL_BASE_URL
@loan_bp.route("/select-offer", methods=["POST"])
def select_offer():
data = request.json
api_url = f"{BASE_URL}/SelectOffer"
# response = requests.post(api_url, json=data, headers=get_headers())
# return jsonify(response.json()), response.status_code
response = {
"transactionId": "1231231321232",
"customerId": "1256907",
"accountId": "5948306019",
"outstandingDebtAmount": 0,
"loan": [
{
"offerId": "14451",
"productId": "2030",
"amount": 10000,
"upfrontPayment": 1000,
"interestRate": 3,
"Interest": 300,
"ManagementRate": 1,
"ManagementFee": 100,
"InsuranceRate": 1,
"InsuranceFee": 100,
"VATRate": 7.5,
"VATamount": 100,
"recommendedRepaymentDates": ["2022-11-30"],
"installmentAmount": 11000,
"totalRepaymentAmount": 11000,
}
],
"resultCode": "00",
"resultDescription": "Successful",
}
return jsonify(response), 200
@loan_bp.route("/provide-loan", methods=["POST"])
def provide_loan():
data = request.json
api_url = f"{BASE_URL}/ProvideLoan"
# response = requests.post(api_url, json=data, headers=get_headers())
# return jsonify(response.json()), response.status_code
response = {
"requestId": "202111170001371256908",
"transactionId": "Tr201712RK9232P115",
"customerId": "CN621868",
"accountId": "ACN8263457",
"msisdn": "3451342",
"resultCode": "00",
"resultDescription": "Successful",
}
return jsonify(response), 200
@loan_bp.route("/status", methods=["POST"])
def status():
data = request.json
api_url = f"{BASE_URL}/LoanStatus"
# response = requests.post(api_url, json=data, headers=get_headers())
# return jsonify(response.json()), response.status_code
response = {
"customerId": "CN621868",
"transactionId": "Tr201712RK9232P115",
"loans": [
{
"debtId": "123456789",
"loanDate": "2019-10-18 14:26:21.063",
"dueDate": "2019-11-20 14:26:21.063",
"currentLoanAmount": 8500,
"initialLoanAmount": 10000,
"defaultPenaltyFee": 0,
"continuousFee": 0,
"productId": "101",
}
],
"totalDebtAmount": 8500,
"resultCode": "00",
"resultDescription": "Successful",
}
return jsonify(response), 200
@loan_bp.route("/repayment", methods=["POST"])
def repayment():
data = request.json
api_url = f"{BASE_URL}/Repayment"
# response = requests.post(api_url, json=data, headers=get_headers())
# return jsonify(response.json()), response.status_code
response = {
"requestId": "R02802",
"countryCode": "NGR",
"transactionId": "Tr201712RK9232P115",
"debtId": "273194670",
"customerId": "CN621868",
"accountId": "2017821799",
"productId": "101",
"collectedAmount": 60000,
"penalCharge": 0,
"lienAmount": 20000,
"comment": "Testing CollectionLoanRequest",
"resultCode": "00",
"resultDescription": "Loan Collection Successful",
}
return jsonify(response), 200
# @loan_bp.route("/rac-check", methods=["POST"])
# def rac_check():
# data = request.json
# api_url = f"{BASE_URL}/RACCheck"
#
# # response = requests.post(api_url, json=data, headers=get_headers())
# # return jsonify(response.json()), response.status_code
# response = {
# "transactionId": "T001",
# "customerId": "CN621868",
# "accountId": "2017821799",
# "RACResponse": {
# "Salary account": "1",
# "BVN": "1",
# "BVNAttachedToAccount": "1",
# "CRMS": "1",
# "CRC": "1",
# "AccountStatus": "1",
# "Lien": "1",
# "NoBouncedCheck": "1",
# "Whitelist": "1",
# "NoPastDueSalaryLoan": "1",
# "NoPastDueOtherLoan": "1",
# },
# "resultDescription": "RAC Check Successful",
# }
#
# return jsonify(response), 200
#
@loan_bp.route("/refresh-disbursement", methods=["GET"])
def disbursement():
data = request.json()
api_url = f"{BASE_URL}/Disbursement"
logger.info(f"Calling disbursement endpoint with data: {data}")
return jsonify(data), 200
#
# response = requests.post(
# api_url,
# json=data,
# headers=get_headers(),
# )
#
# logger.info(f"Disbursement response: {response.json()}")
# return jsonify(response.json()), response.status_code
# @loan_bp.route("/collect-loan", methods=["POST"])
# def collect_loan():
# data = request.json
# api_url = f"{BASE_URL}/CollectLoan"
#
# # response = requests.post(api_url, json=data, headers=get_headers())
# # return jsonify(response.json()), response.status_code
# response = {
# "transactionId": "T002",
# "debtId": "273194670",
# "customerId": "CN621868",
# "accountId": "2017821799",
# "productId": "101",
# "collectAmount": 60000,
# "penalCharge": 0,
# "lienAmount": 20000,
# "countryId": "01",
# "comment": "Testing CollectionLoanRequest",
# "resultCode": "00",
# "resultDescription": "Loan Collection Successful",
# }
#
# return jsonify(response), 200
# @loan_bp.route("/verify-transactions", methods=["GET"])
# def transaction_verify():
# data = request.json
# api_url = f"{BASE_URL}/TransactionVerify"
#
# # response = requests.post(api_url, json=data, headers=get_headers())
# # return jsonify(response.json()), response.status_code
# response = {
# "requestId": "R02802",
# "countryCode": "NGR",
# "transactionId": "Tr201712RK9232P115",
# "transactionType": "Disbursement",
# "customerId": "CN621868",
# "accountId": "2017821799",
# "providedAmount": 100,
# "collectedAmount": 7.5,
# "resultCode": "00",
# "resultDescription": "Collect Status retrieved successfully.",
# }
#
# return jsonify(response), 200
# @loan_bp.route("/penal-charge", methods=["POST"])
# def penal_charge():
# data = request.json
# api_url = f"{BASE_URL}/PenalCharge"
#
# # response = requests.post(api_url, json=data, headers=get_headers())
# # return jsonify(response.json()), response.status_code
# response = {
# "resultCode": "00",
# "resultDescription": "Penal charge debited successfully",
# }
#
# return jsonify(response), 200
# @loan_bp.route("/lien-check", methods=["POST"])
# def lien_check():
# data = request.json
# api_url = f"{BASE_URL}/LienCheck"
#
# # response = requests.post(api_url, json=data, headers=get_headers())
# # return jsonify(response.json()), response.status_code
# response = {
# "lienAmount": 20000,
# "resultCode": "00",
# "resultDescription": "Successful",
# }
#
# return jsonify(response), 200
+1 -1
View File
@@ -17,7 +17,7 @@ services:
- digital
swagger:
image: swaggerapi/swagger-ui
image: swaggerapi/swagger-ui:v5.1.0
ports:
- "9000:8080"
volumes:
+3 -434
View File
@@ -1,7 +1,7 @@
openapi: 3.0.3
info:
title: Sample Flask API
description: A simple Flask API with Swagger documentation running in Docker
title: Event Manager API
description: The documentation for Event Manager API
version: 1.0.0
contact:
name: API Support
@@ -97,435 +97,4 @@ paths:
example: true
responses:
200:
description: A successful response
/eligibility/check:
post:
summary: Performs eligibility check on a user
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
transactionId:
type: string
description: The transaction ID
example: Tr201712RK9232P115
customerId:
type: string
description: The customer ID
example: CN621868
countryCode:
type: string
description: The country code
example: NGR
accountId:
type: string
description: The account ID
example: ACN8263457
msisdn:
type: string
description: The MSISDN
example: 8012345678
channel:
type: string
description: The channel
example: 100
responses:
200:
description: A successful response
/loans/select-offer:
post:
summary: Selects an offer for a loan
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
requestId:
type: string
example: "202111170001371256908"
transactionId:
type: string
example: "1231231321232"
customerId:
type: string
example: "1256907"
accountId:
type: string
example: "5948306019"
msisdn:
type: string
example: "123456789"
requestedAmount:
type: integer
example: 10000
productId:
type: string
example: "101"
channel:
type: string
example: "USSD"
responses:
200:
description: A successful response
/loans/provide-loan:
post:
summary: Provides a loan
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
requestId:
type: string
example: "202111170001371256908"
transactionId:
type: string
example: "Tr201712RK9232P115"
customerId:
type: string
example: "CN621868"
accountId:
type: string
example: "ACN8263457"
msisdn:
type: string
example: "3451342"
productId:
type: string
example: "101"
requestedAmount:
type: integer
example: 900
collectionType:
type: integer
example: 1
offerId:
type: integer
example: 1127
channel:
type: string
example: "100"
responses:
200:
description: A successful response
/loans/status:
post:
summary: Returns the status of a loan
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
transactionId:
type: string
example: "Tr201712RK9232P115"
customerId:
type: string
example: "CN621868"
msisdn:
type: string
example: "3451342"
channel:
type: string
example: "100"
responses:
200:
description: A successful response
/loans/repayment:
post:
summary: Repays a loan
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
requestId:
type: string
example: "R02802"
countryCode:
type: string
example: "NGR"
transactionId:
type: string
example: "Tr201712RK9232P115"
debtId:
type: string
example: "273194670"
customerId:
type: string
example: "CN621868"
accountId:
type: string
example: "2017821799"
productId:
type: string
example: "101"
collectedAmount:
type: integer
example: 80000
penalCharge:
type: integer
example: 0
collectionMethod:
type: integer
example: 1
lienAmount:
type: integer
example: 80000
comment:
type: string
example: "Testing CollectionLoanRequest"
responses:
200:
description: A successful response
/loans/raccheck:
post:
summary: Performs RAC check on a user
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
transactionId:
type: string
example: "T001"
fbnTransactionId:
type: string
example: "Tr201712RK9232P115"
customerId:
type: string
example: "CN621868"
accountId:
type: string
example: "2017821799"
RAC_Array:
type: array
items:
type: string
example:
- "SalaryAccount"
- "BVN"
- "BVNAttachedtoAccount"
- "CRC"
- "CRMS"
- "AccountStatus"
- "Lien"
- "NoBouncedCheck"
- "Whitelist"
- "NoPastDueSalaryLoan"
- "NoPastDueOtherLoan"
responses:
200:
description: A successful response
/loans/refresh-disbursement:
get:
summary: Refresh disburse of a loan
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
requestId:
type: string
example: "R02802"
countryCode:
type: string
example: "NGR"
transactionId:
type: string
example: "Tr201712RK9232P115"
debtId:
type: string
example: "273194670"
customerId:
type: string
example: "CN621868"
accountId:
type: string
example: "2017821799"
productId:
type: string
example: "101"
provideAmount:
type: integer
example: 100000
totalFees:
type: integer
example: 7075
feesDetails:
type: object
properties:
collectAmountInterest:
type: integer
example: 5000
collectAmountMgtFee:
type: integer
example: 1000
collectAmountInsurance:
type: integer
example: 1000
collectAmountVAT:
type: integer
example: 75
responses:
200:
description: A successful response
/loans/collect-loan:
post:
summary: Collect loan from a customer
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
transactionId:
type: string
example: "T002"
fbnTransactionId:
type: string
example: "Tr201712RK9232P115"
debtId:
type: string
example: "273194670"
customerId:
type: string
example: "CN621868"
accountId:
type: string
example: "2017821799"
productId:
type: string
example: "101"
collectAmount:
type: integer
example: 80000
penalCharge:
type: integer
example: 0
collectionMethod:
type: integer
example: 1
lienAmount:
type: integer
example: 80000
countryId:
type: string
example: "01"
comment:
type: string
example: "Testing CollectionLoanRequest"
responses:
200:
description: A successful response
/loans/verify-transactions:
get:
summary: Verify a transaction
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
requestId:
type: string
example: "R02802"
countryCode:
type: string
example: "NGR"
counter:
type: string
example: "2"
transactionId:
type: string
example: "Tr201712RK9232P115"
customerId:
type: string
example: "CN621868"
accountId:
type: string
example: "2017821799"
transactionType:
type: string
example: "Disbursement"
responses:
200:
description: A successful response
/loans/penal-charge:
post:
summary: A penalty charge on a customer
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
transactionId:
type: string
example: "T004"
fbnTransactionId:
type: string
example: "Tr201712RK9232P115"
debtId:
type: string
example: "273194670"
customerId:
type: string
example: "CN621868"
accountId:
type: string
example: "2017821799"
penalCharge:
type: number
format: float
example: 101.2
lienAmount:
type: number
format: float
example: 101.2
comment:
type: string
example: "Testing PenalChargeRequest"
responses:
200:
description: A successful response
/loans/lien-check:
post:
summary: Perform a lien check
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
transactionId:
type: string
example: "SMB1234567"
customerId:
type: string
example: "123456"
accountId:
type: string
example: "E9F77222920BAAB1C5ACF2253C6D6113"
responses:
200:
description: A successful response
description: A successful response