diff --git a/README.md b/README.md index 4025fbf..b52e6ae 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,10 @@ Then, open the `.env` file and add the following: ```ini # Environment Variables -VALID_API_KEY=testtest-api-key-12345 -VALID_APP_ID=app1 +BASIC_AUTH_USERNAME=admin +BASIC_AUTH_PASSWORD=password +SWAGGER_URL="/documentation" +API_URL="/swagger.json" ``` This ensures that the application uses secure API keys and app IDs. @@ -46,14 +48,14 @@ Once you have the repository cloned, you can easily set up and run the applicati docker-compose up --build ``` -This command will build the Docker image and start the Flask application in a container. By default, the application will be accessible at `http://localhost:5000`. +This command will build the Docker image and start the Flask application in a container. By default, the application will be accessible at `http://localhost:4500`. ### 4. Health Check You can check if the Flask application is running by accessing the `/health` endpoint. To perform a health check, run the following command: ```bash -curl http://localhost:7200/health +curl http://localhost:4500/health ``` If the application is running properly, you should receive a response similar to this: @@ -64,7 +66,17 @@ If the application is running properly, you should receive a response similar to } ``` -### 5. Stop the Application + +### 5. Documentation + +You can check the Swagger Doc by accessing the `/documentation` endpoint. Run the following command: + +```bash +curl http://localhost:4500/documentation +``` + + +### 6. Stop the Application To stop the application, use: diff --git a/app/__init__.py b/app/__init__.py index be3109d..e7b7836 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -1,8 +1,10 @@ from flask import Flask +import os +from flask_swagger_ui import get_swaggerui_blueprint from flask_cors import CORS from app.config import Config -from app.routes import api -from app.errors import method_not_allowed, unsupported_media_type +from app.api.routes import api +from app.errors import register_error_handlers def create_app(): """ Factory function to create a Flask app instance """ @@ -14,11 +16,22 @@ def create_app(): CORS(app) + # Swagger Doc + SWAGGER_URL = app.config.get("SWAGGER_URL") + API_URL = app.config.get("API_URL") + + # Register blueprints app.register_blueprint(api) - # Error Handlers - app.register_error_handler(405, method_not_allowed) - app.register_error_handler(415, unsupported_media_type) + swagger_ui_blueprint = get_swaggerui_blueprint(SWAGGER_URL, API_URL) + app.register_blueprint(swagger_ui_blueprint, url_prefix=SWAGGER_URL) + + + # Error Handlers + register_error_handlers(app) + + + return app diff --git a/app/helpers/response_helper.py b/app/api/helpers/response_helper.py similarity index 100% rename from app/helpers/response_helper.py rename to app/api/helpers/response_helper.py diff --git a/app/middlewares/__init__.py b/app/api/middlewares/__init__.py similarity index 56% rename from app/middlewares/__init__.py rename to app/api/middlewares/__init__.py index c439164..ecf8fb2 100644 --- a/app/middlewares/__init__.py +++ b/app/api/middlewares/__init__.py @@ -1,3 +1,4 @@ from .verify_api_key import require_api_key from .app_id_checker import require_app_id -from .cors import enforce_json \ No newline at end of file +from .cors import enforce_json +from .basic_auth import require_auth \ No newline at end of file diff --git a/app/middlewares/app_id_checker.py b/app/api/middlewares/app_id_checker.py similarity index 77% rename from app/middlewares/app_id_checker.py rename to app/api/middlewares/app_id_checker.py index 18797b0..b674aa9 100644 --- a/app/middlewares/app_id_checker.py +++ b/app/api/middlewares/app_id_checker.py @@ -1,10 +1,11 @@ from functools import wraps from flask import request, jsonify from app.utils.logger import logger -import os +from app.config import Config -# Load valid App-IDs from environment variables (comma-separated list) -VALID_APP_ID = os.getenv("VALID_APP_ID", "app1,app2,app3").split(",") + + +VALID_APP_ID = Config.VALID_APP_ID def require_app_id(f): """Decorator to enforce App-ID validation.""" @@ -17,7 +18,7 @@ def require_app_id(f): return jsonify({"message": "Invalid request parameters"}), 400 - if app_id not in VALID_APP_ID: + if app_id != VALID_APP_ID: logger.error(f"Unauthorized access: Invalid App-ID {app_id}.") return jsonify({"message": "Invalid request parameters"}), 400 diff --git a/app/api/middlewares/basic_auth.py b/app/api/middlewares/basic_auth.py new file mode 100644 index 0000000..00a8771 --- /dev/null +++ b/app/api/middlewares/basic_auth.py @@ -0,0 +1,30 @@ +from functools import wraps +from flask import request, jsonify +import base64 +from app.config import Config + +USERNAME = Config.BASIC_AUTH_USERNAME +PASSWORD = Config.BASIC_AUTH_PASSWORD + +def require_auth(f): + @wraps(f) + def decorated(*args, **kwargs): + auth = request.headers.get('Authorization') + if not auth or not check_auth(auth): + return jsonify({"message": "Invalid request parameters"}), 401 + return f(*args, **kwargs) + return decorated + +def check_auth(auth_header): + if not auth_header: + return False + try: + auth_type, credentials = auth_header.split() + if auth_type.lower() != "basic": + return False + + decoded_credentials = base64.b64decode(credentials).decode("utf-8") + user, pwd = decoded_credentials.split(":", 1) + return user == USERNAME and pwd == PASSWORD + except Exception: + return False \ No newline at end of file diff --git a/app/middlewares/cors.py b/app/api/middlewares/cors.py similarity index 100% rename from app/middlewares/cors.py rename to app/api/middlewares/cors.py diff --git a/app/middlewares/verify_api_key.py b/app/api/middlewares/verify_api_key.py similarity index 91% rename from app/middlewares/verify_api_key.py rename to app/api/middlewares/verify_api_key.py index 81644b1..b395fc4 100644 --- a/app/middlewares/verify_api_key.py +++ b/app/api/middlewares/verify_api_key.py @@ -1,10 +1,10 @@ from functools import wraps from flask import request, jsonify from app.utils.logger import logger -import os +from app.config import Config # Load valid API key from environment variables (fallback for testing) -VALID_API_KEY = os.getenv("VALID_API_KEY", "test-api-key-12345") +VALID_API_KEY = Config.VALID_API_KEY def require_api_key(f): """Decorator to enforce API key authentication.""" diff --git a/app/routes/__init__.py b/app/api/routes/__init__.py similarity index 100% rename from app/routes/__init__.py rename to app/api/routes/__init__.py diff --git a/app/api/routes/routes.py b/app/api/routes/routes.py new file mode 100644 index 0000000..4586f56 --- /dev/null +++ b/app/api/routes/routes.py @@ -0,0 +1,111 @@ +from flask import Blueprint, request, jsonify, send_from_directory +from app.api.services import ( + EligibilityCheckService, + SelectOfferService, + ProvideLoanService, + LoanInformationService, + RepaymentService, + CustomerConsentService, + NotificationCallbackService +) +from app.utils.logger import logger +from app.api.middlewares import enforce_json, require_auth +import os + + +api = Blueprint("api", __name__) + + +@api.before_request +def cors_middleware(): + """Middleware applied globally to all API routes in this blueprint""" + return enforce_json() + + +# Swagger JSON file +@api.route("/swagger.json", methods=['GET']) +def swagger_json(): + swagger_dir = os.path.join("swagger") + return send_from_directory(swagger_dir, "digifi_swagger.json") + + + +@api.route('/swagger/') +def serve_paths(filename): + swagger_dir = os.path.join("swagger") + return send_from_directory(swagger_dir, filename) + + +# EligibilityCheck Endpoint +@api.route('/EligibilityCheck', methods=['POST']) +@require_auth +def eligibility_check(): + data = request.get_json() + # logger.info(f"EligibilityCheck request received: {data}") + response = EligibilityCheckService.process_request(data) + return response + +# SelectOffer Endpoint +@api.route('/SelectOffer', methods=['POST']) +@require_auth +def select_offer(): + data = request.get_json() + # logger.info(f"SelectOffer request received: {data}") + response = SelectOfferService.process_request(data) + return response + + +# ProvideLoan Endpoint +@api.route('/ProvideLoan', methods=['POST']) +@require_auth +def provide_loan(): + data = request.get_json() + # logger.info(f"ProvideLoan request received: {data}") + response = ProvideLoanService.process_request(data) + return response + + +# LoanInformation Endpoint +@api.route('/LoanInformation', methods=['GET']) +@require_auth +def loan_information(): + data = request.args.to_dict() + # logger.info(f"LoanInformation request received: {data}") + response = LoanInformationService.process_request(data) + return response + + +# Repayment Endpoint +@api.route('/Repayment', methods=['POST']) +@require_auth +def repayment(): + data = request.get_json() + # logger.info(f"Repayment request received: {data}") + response = RepaymentService.process_request(data) + return response + + +# CustomerConsent Endpoint +@api.route('/CustomerConsent', methods=['POST']) +@require_auth +def customer_consent(): + data = request.get_json() + # logger.info(f"CustomerConsent request received: {data}") + response = CustomerConsentService.process_request(data) + return response + + +# NotificationCallback Endpoint +@api.route('/NotificationCallback', methods=['POST']) +@require_auth +def notification_callback(): + data = request.get_json() + # logger.info(f"NotificationCallback request received: {data}") + response = NotificationCallbackService.process_request(data) + return response + + +# Health Check Endpoint +@api.route('/health', methods=['GET']) +def health_check(): + return {"status": "ok"} , 200 \ No newline at end of file diff --git a/app/schemas/__init__.py b/app/api/schemas/__init__.py similarity index 100% rename from app/schemas/__init__.py rename to app/api/schemas/__init__.py diff --git a/app/schemas/customer_consent.py b/app/api/schemas/customer_consent.py similarity index 100% rename from app/schemas/customer_consent.py rename to app/api/schemas/customer_consent.py diff --git a/app/schemas/eligibility_check.py b/app/api/schemas/eligibility_check.py similarity index 91% rename from app/schemas/eligibility_check.py rename to app/api/schemas/eligibility_check.py index 016168c..80434e7 100644 --- a/app/schemas/eligibility_check.py +++ b/app/api/schemas/eligibility_check.py @@ -1,7 +1,6 @@ from marshmallow import Schema, fields class EligibilityCheckSchema(Schema): - type = fields.Str(required=True) transactionId = fields.Str(required=True) countryCode = fields.Str(required=True) customerId = fields.Str(required=True) diff --git a/app/schemas/loan_information.py b/app/api/schemas/loan_information.py similarity index 100% rename from app/schemas/loan_information.py rename to app/api/schemas/loan_information.py diff --git a/app/schemas/notification_callback.py b/app/api/schemas/notification_callback.py similarity index 100% rename from app/schemas/notification_callback.py rename to app/api/schemas/notification_callback.py diff --git a/app/schemas/provide_loan.py b/app/api/schemas/provide_loan.py similarity index 100% rename from app/schemas/provide_loan.py rename to app/api/schemas/provide_loan.py diff --git a/app/schemas/repayment.py b/app/api/schemas/repayment.py similarity index 100% rename from app/schemas/repayment.py rename to app/api/schemas/repayment.py diff --git a/app/schemas/select_offer.py b/app/api/schemas/select_offer.py similarity index 100% rename from app/schemas/select_offer.py rename to app/api/schemas/select_offer.py diff --git a/app/api/services/__init__.py b/app/api/services/__init__.py new file mode 100644 index 0000000..911e4d1 --- /dev/null +++ b/app/api/services/__init__.py @@ -0,0 +1,7 @@ +from app.api.services.eligibility_check import EligibilityCheckService +from app.api.services.select_offer import SelectOfferService +from app.api.services.provide_loan import ProvideLoanService +from app.api.services.loan_information import LoanInformationService +from app.api.services.repayment import RepaymentService +from app.api.services.customer_consent import CustomerConsentService +from app.api.services.notification_callback import NotificationCallbackService \ No newline at end of file diff --git a/app/services/customer_consent.py b/app/api/services/customer_consent.py similarity index 95% rename from app/services/customer_consent.py rename to app/api/services/customer_consent.py index f37aa47..cd76120 100644 --- a/app/services/customer_consent.py +++ b/app/api/services/customer_consent.py @@ -1,7 +1,7 @@ from flask import request, jsonify from marshmallow import ValidationError from app.utils.logger import logger -from app.schemas.customer_consent import CustomerConsentSchema +from app.api.schemas.customer_consent import CustomerConsentSchema class CustomerConsentService: diff --git a/app/services/eligibility_check.py b/app/api/services/eligibility_check.py similarity index 86% rename from app/services/eligibility_check.py rename to app/api/services/eligibility_check.py index a450607..4cd5106 100644 --- a/app/services/eligibility_check.py +++ b/app/api/services/eligibility_check.py @@ -1,7 +1,6 @@ from flask import session, jsonify from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.eligibility_check import EligibilityCheckSchema +from app.api.schemas.eligibility_check import EligibilityCheckSchema from marshmallow import ValidationError class EligibilityCheckService: @@ -23,10 +22,6 @@ class EligibilityCheckService: schema = EligibilityCheckSchema() validated_data = schema.load(data) # Raises an error if invalid - # Example: Validate data, perform calculations, etc. - if not data: - return ResponseHelper.error("Invalid input data", status_code=400) - # Simulate processing response_data = { "customerId": "CN621868", diff --git a/app/services/loan_information.py b/app/api/services/loan_information.py similarity index 94% rename from app/services/loan_information.py rename to app/api/services/loan_information.py index 6136cd1..d2e49a1 100644 --- a/app/services/loan_information.py +++ b/app/api/services/loan_information.py @@ -1,8 +1,7 @@ from flask import request, jsonify from marshmallow import ValidationError from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.loan_information import LoanInformationSchema +from app.api.schemas.loan_information import LoanInformationSchema class LoanInformationService: @staticmethod diff --git a/app/services/notification_callback.py b/app/api/services/notification_callback.py similarity index 91% rename from app/services/notification_callback.py rename to app/api/services/notification_callback.py index c587a9c..2c876db 100644 --- a/app/services/notification_callback.py +++ b/app/api/services/notification_callback.py @@ -1,8 +1,7 @@ from flask import request, jsonify from marshmallow import ValidationError from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.notification_callback import NotificationCallbackSchema +from app.api.schemas.notification_callback import NotificationCallbackSchema class NotificationCallbackService: @staticmethod diff --git a/app/services/provide_loan.py b/app/api/services/provide_loan.py similarity index 93% rename from app/services/provide_loan.py rename to app/api/services/provide_loan.py index b5b5396..d55e79b 100644 --- a/app/services/provide_loan.py +++ b/app/api/services/provide_loan.py @@ -1,8 +1,7 @@ from flask import request, jsonify from marshmallow import ValidationError from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.provide_loan import ProvideLoanSchema +from app.api.schemas.provide_loan import ProvideLoanSchema class ProvideLoanService: @staticmethod diff --git a/app/services/repayment.py b/app/api/services/repayment.py similarity index 93% rename from app/services/repayment.py rename to app/api/services/repayment.py index 472890d..a8d5738 100644 --- a/app/services/repayment.py +++ b/app/api/services/repayment.py @@ -1,8 +1,7 @@ from flask import request, jsonify from marshmallow import ValidationError from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.repayment import RepaymentSchema +from app.api.schemas.repayment import RepaymentSchema class RepaymentService: @staticmethod diff --git a/app/services/select_offer.py b/app/api/services/select_offer.py similarity index 90% rename from app/services/select_offer.py rename to app/api/services/select_offer.py index c0e12e0..8c82157 100644 --- a/app/services/select_offer.py +++ b/app/api/services/select_offer.py @@ -1,8 +1,7 @@ from flask import request, jsonify from marshmallow import ValidationError from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.select_offer import SelectOfferSchema +from app.api.schemas.select_offer import SelectOfferSchema class SelectOfferService: @staticmethod @@ -34,8 +33,8 @@ class SelectOfferService: "managementFee": 1.0, "insuranceRate": 1.0, "insuranceFee": 100.0, - "vatRate": 7.5, - "vatAmount": 100.0, + "VATRate": 7.5, + "VATAmount": 100.0, "recommendedRepaymentDates": ["2022-11-30"], "installmentAmount": 11000.0, "totalRepaymentAmount": 11000.0 @@ -50,8 +49,8 @@ class SelectOfferService: "managementFee": 1.0, "insuranceRate": 1.0, "insuranceFee": 100.0, - "vatRate": 7.5, - "vatAmount": 100.0, + "VATRate": 7.5, + "VATAmount": 100.0, "recommendedRepaymentDates": ["2022-11-30", "2023-12-30"], "installmentAmount": 5761.9, "totalRepaymentAmount": 11523.8 @@ -66,8 +65,8 @@ class SelectOfferService: "managementFee": 1.0, "insuranceRate": 1.0, "insuranceFee": 100.0, - "vatRate": 7.5, - "vatAmount": 100.0, + "VATRate": 7.5, + "VATAmount": 100.0, "recommendedRepaymentDates": ["2022-11-30", "2022-12-30", "2023-01-29"], "installmentAmount": 4021.15, "totalRepaymentAmount": 12063.45 @@ -81,7 +80,7 @@ class SelectOfferService: "transactionId": "1231231321232", "customerId": "1256907", "accountId": "5948306019", - "offers": offers, + "loan": offers, "resultCode": "00", "resultDescription": "Successful" } diff --git a/app/config.py b/app/config.py index 5e16347..a1f4794 100644 --- a/app/config.py +++ b/app/config.py @@ -7,4 +7,11 @@ class Config: # SQLALCHEMY_TRACK_MODIFICATIONS = False # SECRET_KEY = os.environ.get("SECRET_KEY", "your_secret_key") - DEBUG = True \ No newline at end of file + SWAGGER_URL = os.getenv("SWAGGER_URL", "/documentation") + API_URL = os.getenv("API_URL", "/swagger.json") + + DEBUG = True + VALID_APP_ID = os.getenv("VALID_APP_ID", "app1") + VALID_API_KEY = os.getenv("VALID_API_KEY", "test-api-key-12345") + BASIC_AUTH_USERNAME = os.environ.get("BASIC_AUTH_USERNAME", "admin") + BASIC_AUTH_PASSWORD = os.environ.get("BASIC_AUTH_PASSWORD", "password") \ No newline at end of file diff --git a/app/errors/__init__.py b/app/errors/__init__.py index 15c380c..77d4fe1 100644 --- a/app/errors/__init__.py +++ b/app/errors/__init__.py @@ -1 +1 @@ -from .handlers import method_not_allowed, unsupported_media_type \ No newline at end of file +from .handlers import register_error_handlers \ No newline at end of file diff --git a/app/errors/handlers.py b/app/errors/handlers.py index 0b4cbdf..02b665f 100644 --- a/app/errors/handlers.py +++ b/app/errors/handlers.py @@ -1,14 +1,24 @@ +from werkzeug.exceptions import HTTPException from flask import jsonify -from app.helpers.response_helper import ResponseHelper +from app.api.helpers.response_helper import ResponseHelper -def method_not_allowed(error): - return jsonify({"message": "Method Not Allowed"}), 405 +def register_error_handlers(app): + @app.errorhandler(HTTPException) + def handle_http_exception(e): + return jsonify({'error': e.description}), e.code + + @app.errorhandler(405) + def method_not_allowed(error): + return jsonify({"message": "Method Not Allowed"}), 405 -def not_found(error): - return jsonify({"message": "Resource not found"}), 404 + @app.errorhandler(404) + def not_found(error): + return jsonify({"message": "Resource not found"}), 404 -def bad_request(error): - return jsonify({"message": "Bad Request"}), 400 + @app.errorhandler(400) + def bad_request(error): + return jsonify({"message": "Bad Request"}), 400 -def unsupported_media_type(error): - return jsonify({"message": "Unsupported Media Type"}), 415 + @app.errorhandler(415) + def unsupported_media_type(error): + return jsonify({"message": "Unsupported Media Type"}), 415 diff --git a/app/routes/routes.py b/app/routes/routes.py deleted file mode 100644 index 2c75412..0000000 --- a/app/routes/routes.py +++ /dev/null @@ -1,211 +0,0 @@ -from flask import Blueprint, request, jsonify -from app.services import ( - EligibilityCheckService, - SelectOfferService, - ProvideLoanService, - LoanInformationService, - RepaymentService, - CustomerConsentService, - NotificationCallbackService, - RACCheckService, - DisbursementService, - CollectLoanService, - TransactionVerifyService, - PenalChargeService, - RevokeEnableConsentService, - TokenValidationService, - LienCheckService, - NewTransactionCheckService -) -from app.utils.logger import logger -from app.middlewares import require_api_key, require_app_id, enforce_json - - -api = Blueprint("api", __name__) - - -@api.before_request -def cors_middleware(): - """Middleware applied globally to all API routes in this blueprint""" - return enforce_json() - - -# EligibilityCheck Endpoint -@api.route('/EligibilityCheck', methods=['POST']) -@require_api_key -@require_app_id -def eligibility_check(): - data = request.get_json() - # logger.info(f"EligibilityCheck request received: {data}") - response = EligibilityCheckService.process_request(data) - return response - -# SelectOffer Endpoint -@api.route('/SelectOffer', methods=['POST']) -@require_api_key -@require_app_id -def select_offer(): - data = request.get_json() - # logger.info(f"SelectOffer request received: {data}") - response = SelectOfferService.process_request(data) - return response - - -# ProvideLoan Endpoint -@api.route('/ProvideLoan', methods=['POST']) -@require_api_key -@require_app_id -def provide_loan(): - data = request.get_json() - # logger.info(f"ProvideLoan request received: {data}") - response = ProvideLoanService.process_request(data) - return response - - -# LoanInformation Endpoint -@api.route('/LoanInformation', methods=['GET']) -@require_api_key -@require_app_id -def loan_information(): - data = request.args.to_dict() - # logger.info(f"LoanInformation request received: {data}") - response = LoanInformationService.process_request(data) - return response - - -# Repayment Endpoint -@api.route('/Repayment', methods=['POST']) -@require_api_key -@require_app_id -def repayment(): - data = request.get_json() - # logger.info(f"Repayment request received: {data}") - response = RepaymentService.process_request(data) - return response - - -# CustomerConsent Endpoint -@api.route('/CustomerConsent', methods=['POST']) -@require_api_key -@require_app_id -def customer_consent(): - data = request.get_json() - # logger.info(f"CustomerConsent request received: {data}") - response = CustomerConsentService.process_request(data) - return response - - -# NotificationCallback Endpoint -@api.route('/NotificationCallback', methods=['POST']) -@require_api_key -@require_app_id -def notification_callback(): - data = request.get_json() - # logger.info(f"NotificationCallback request received: {data}") - response = NotificationCallbackService.process_request(data) - return response - - -# RACCheck Endpoint -@api.route('/RACCheck', methods=['POST']) -@require_api_key -@require_app_id -def rac_check(): - data = request.get_json() - # logger.info(f"RACCheck request received: {data}") - response = RACCheckService.process_request(data) - return response - - -# Disbursement Endpoint -@api.route('/Disbursement', methods=['POST']) -@require_api_key -@require_app_id -def disbursement(): - data = request.get_json() - # logger.info(f"Disbursement request received: {data}") - response = DisbursementService.process_request(data) - return response - - -# CollectLoan Endpoint -@api.route('/CollectLoan', methods=['POST']) -@require_api_key -@require_app_id -def collect_loan(): - data = request.get_json() - # logger.info(f"CollectLoan request received: {data}") - response = CollectLoanService.process_request(data) - return response - - -# TransactionVerify Endpoint -@api.route('/TransactionVerify', methods=['POST']) -@require_api_key -@require_app_id -def transaction_verify(): - data = request.get_json() - # logger.info(f"TransactionVerify request received: {data}") - response = TransactionVerifyService.process_request(data) - return response - - -# PenalCharge Endpoint -@api.route('/PenalCharge', methods=['POST']) -@require_api_key -@require_app_id -def penal_charge(): - data = request.get_json() - # logger.info(f"PenalCharge request received: {data}") - response = PenalChargeService.process_request(data) - return response - - -# RevokeEnableConsent Endpoint -@api.route('/RevokeEnableConsent', methods=['POST']) -@require_api_key -@require_app_id -def revoke_enable_consent(): - data = request.get_json() - # logger.info(f"RevokeEnableConsent request received: {data}") - response = RevokeEnableConsentService.process_request(data) - return response - - -# TokenValidation Endpoint -@api.route('/TokenValidation', methods=['POST']) -@require_api_key -@require_app_id -def token_validation(): - data = request.get_json() - # logger.info(f"TokenValidation request received: {data}") - response = TokenValidationService.process_request(data) - return response - - -# LienCheck Endpoint -@api.route('/LienCheck', methods=['POST']) -@require_api_key -@require_app_id -def lien_check(): - data = request.get_json() - # logger.info(f"LienCheck request received: {data}") - response = LienCheckService.process_request(data) - return response - - -# NewTransactionCheck Endpoint -@api.route('/NewTransactionCheck', methods=['POST']) -@require_api_key -@require_app_id -def new_transaction_check(): - data = request.get_json() - # logger.info(f"NewTransactionCheck request received: {data}") - response = NewTransactionCheckService.process_request(data) - return response - - -# Health Check Endpoint -@api.route('/health', methods=['GET']) -def health_check(): - return {"status": "ok"} , 200 \ No newline at end of file diff --git a/app/schemas/bulk_sms.py b/app/schemas/bulk_sms.py deleted file mode 100644 index 40c2465..0000000 --- a/app/schemas/bulk_sms.py +++ /dev/null @@ -1,6 +0,0 @@ -from marshmallow import Schema, fields -from .sms import SMSSchema - -# Bulk SMS Schema -class BulkSMSSchema(Schema): - requests = fields.List(fields.Nested(SMSSchema), required=True) \ No newline at end of file diff --git a/app/schemas/collect_loan.py b/app/schemas/collect_loan.py deleted file mode 100644 index fb5bc76..0000000 --- a/app/schemas/collect_loan.py +++ /dev/null @@ -1,16 +0,0 @@ -from marshmallow import Schema, fields - -# Collect Loan Schema -class CollectLoanSchema(Schema): - transactionId = fields.Str(required=True) - fbnTransactionId = fields.Str(required=True) - debtId = fields.Str(required=True) - customerId = fields.Str(required=True) - accountId = fields.Str(required=True) - productId = fields.Str(required=True) - collectAmount = fields.Float(required=True) - penalCharge = fields.Float(required=False) # Optional - collectionMethod = fields.Int(required=True) - lienAmount = fields.Float(required=True) - countryId = fields.Str(required=True) - comment = fields.Str(required=False) # Optional \ No newline at end of file diff --git a/app/schemas/disbursement.py b/app/schemas/disbursement.py deleted file mode 100644 index 5f4bead..0000000 --- a/app/schemas/disbursement.py +++ /dev/null @@ -1,18 +0,0 @@ -from marshmallow import Schema, fields - -# Disbursement Schema -class DisbursementSchema(Schema): - requestId = fields.Str(required=True) - debtId = fields.Str(required=True) - transactionId = fields.Str(required=True) - customerId = fields.Str(required=True) - accountId = fields.Str(required=True) - productId = fields.Str(required=True) - provideAmount = fields.Float(required=True) - collectAmountInterest = fields.Float(required=False) # Optional - collectAmountMgtFee = fields.Float(required=True) - collectAmountInsurance = fields.Float(required=True) - collectAmountVAT = fields.Float(required=True) - countryId = fields.Str(required=True) - comment = fields.Str(required=False) # Optional - \ No newline at end of file diff --git a/app/schemas/lien_check.py b/app/schemas/lien_check.py deleted file mode 100644 index 7a0912a..0000000 --- a/app/schemas/lien_check.py +++ /dev/null @@ -1,8 +0,0 @@ -from marshmallow import Schema, fields - -# Lien Check Schema -class LienCheckSchema(Schema): - transactionId = fields.Str(required=True) - customerId = fields.Str(required=True) - accountId = fields.Str(required=True) - countryId = fields.Str(required=True) \ No newline at end of file diff --git a/app/schemas/new_transaction_check.py b/app/schemas/new_transaction_check.py deleted file mode 100644 index 9e79864..0000000 --- a/app/schemas/new_transaction_check.py +++ /dev/null @@ -1,12 +0,0 @@ -from marshmallow import Schema, fields - -# New Transaction Check Schema -class NewTransactionCheckSchema(Schema): - transactionId = fields.Str(required=True) - debtId = fields.Str(required=True) - transactionType = fields.Str(required=True, metadata={ - "allowed_values": ["Disbursement", "Collection", "PenalCharge"] - }) - fbnTransactionId = fields.Str(required=True) - origTransactionId = fields.Str(required=True) - customerId = fields.Str(required=True) \ No newline at end of file diff --git a/app/schemas/penal_charge.py b/app/schemas/penal_charge.py deleted file mode 100644 index 40d6d0a..0000000 --- a/app/schemas/penal_charge.py +++ /dev/null @@ -1,14 +0,0 @@ -from marshmallow import Schema, fields - - -# Penal Charge Schema -class PenalChargeSchema(Schema): - transactionId = fields.Str(required=True) - fbnTransactionId = fields.Str(required=True) - debtId = fields.Str(required=True) - customerId = fields.Str(required=True) - accountId = fields.Str(required=True) - penalCharge = fields.Decimal(required=True) - lienAmount = fields.Decimal(required=True) - countryId = fields.Str(required=True) - comment = fields.Str(required=False) diff --git a/app/schemas/rac_check.py b/app/schemas/rac_check.py deleted file mode 100644 index 3b858d2..0000000 --- a/app/schemas/rac_check.py +++ /dev/null @@ -1,23 +0,0 @@ -from marshmallow import Schema, fields - -class RACItemSchema(Schema): - salaryAccount = fields.Bool(required=True) - bvn = fields.Str(required=True) - crc = fields.Bool(required=True) - crms = fields.Bool(required=True) - accountStatus = fields.Str(required=True) - lien = fields.Bool(required=True) - noBouncedCheck = fields.Bool(required=True) - existingLoan = fields.Bool(required=True) - whitelist = fields.Bool(required=True) - noPastDueSalaryLoan = fields.Bool(required=True) - noPastDueOtherLoans = fields.Bool(required=True) - - -# RAC Check Schema -class RACCheckSchema(Schema): - transactionId = fields.Str(required=True) - fbnTransactionId = fields.Str(required=True) - customerId = fields.Str(required=True) - accountId = fields.Str(required=True) - RAC_Array = fields.List(fields.Nested(RACItemSchema), required=True) \ No newline at end of file diff --git a/app/schemas/revoke_enable_consent.py b/app/schemas/revoke_enable_consent.py deleted file mode 100644 index ce1a5f5..0000000 --- a/app/schemas/revoke_enable_consent.py +++ /dev/null @@ -1,13 +0,0 @@ -from marshmallow import Schema, fields - - -# Revoke Enable Consent Schema -class RevokeEnableConsentSchema(Schema): - transactionId = fields.Str(required=True) - fbnTransactionId = fields.Str(required=True) - customerId = fields.Str(required=True) - accountId = fields.Str(required=True) - processTime = fields.DateTime(required=True) - consentType = fields.Str(required=True) - countryId = fields.Str(required=True) - comment = fields.Str(required=False) diff --git a/app/schemas/sms.py b/app/schemas/sms.py deleted file mode 100644 index e8209c4..0000000 --- a/app/schemas/sms.py +++ /dev/null @@ -1,7 +0,0 @@ -from marshmallow import Schema, fields - -# SMS Schema -class SMSSchema(Schema): - text = fields.Str(required=True) - dest = fields.Str(required=True) - unicode = fields.Bool(required=True) \ No newline at end of file diff --git a/app/schemas/token_validation.py b/app/schemas/token_validation.py deleted file mode 100644 index c8e067b..0000000 --- a/app/schemas/token_validation.py +++ /dev/null @@ -1,8 +0,0 @@ -from marshmallow import Schema, fields - -# Token Validation Schema -class TokenValidationSchema(Schema): - RequestId = fields.Str(required=True) - UserId = fields.Str(required=True) - CountryId = fields.Str(required=True) - TokenCode = fields.Str(required=True) \ No newline at end of file diff --git a/app/schemas/transaction_verify.py b/app/schemas/transaction_verify.py deleted file mode 100644 index 021ded4..0000000 --- a/app/schemas/transaction_verify.py +++ /dev/null @@ -1,12 +0,0 @@ -from marshmallow import Schema, fields - - -# Transaction Verify Schema -class TransactionVerifySchema(Schema): - counter = fields.Str(required=True) - TransactionId = fields.Str(required=True) - requestID = fields.Str(required=True) - customerId = fields.Str(required=True) - accountId = fields.Str(required=True) - countryId = fields.Str(required=True) # Static value “01” - transactionType = fields.Str(required=True) \ No newline at end of file diff --git a/app/services/__init__.py b/app/services/__init__.py deleted file mode 100644 index 9a1af9f..0000000 --- a/app/services/__init__.py +++ /dev/null @@ -1,16 +0,0 @@ -from app.services.eligibility_check import EligibilityCheckService -from app.services.select_offer import SelectOfferService -from app.services.provide_loan import ProvideLoanService -from app.services.loan_information import LoanInformationService -from app.services.repayment import RepaymentService -from app.services.customer_consent import CustomerConsentService -from app.services.notification_callback import NotificationCallbackService -from app.services.rac_check import RACCheckService -from app.services.disbursement import DisbursementService -from app.services.collect_loan import CollectLoanService -from app.services.transaction_verify import TransactionVerifyService -from app.services.penal_charge import PenalChargeService -from app.services.revoke_enable_consent import RevokeEnableConsentService -from app.services.token_validation import TokenValidationService -from app.services.lien_check import LienCheckService -from app.services.new_transaction_check import NewTransactionCheckService \ No newline at end of file diff --git a/app/services/collect_loan.py b/app/services/collect_loan.py deleted file mode 100644 index ec65b5a..0000000 --- a/app/services/collect_loan.py +++ /dev/null @@ -1,59 +0,0 @@ -from flask import request, jsonify -from marshmallow import ValidationError -from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.collect_loan import CollectLoanSchema - -class CollectLoanService: - @staticmethod - def process_request(data): - """ - Process the CollectLoan request. - - Args: - data (dict): The request data. - - Returns: - dict: A standardized response. - """ - try: - logger.info("Processing CollectLoan request") - - # Validate input data using CollectLoanSchema - schema = CollectLoanSchema() - validated_data = schema.load(data) # Raises ValidationError if invalid - - # Simulated processing logic - response_data = { - "transactionId": "T002", - "debtId": "273194670", - "customerId": "CN621868", - "accountId": "2017821799", - "productId": "101", - "collectAmount": 60000.00, - "penalCharge": 0, - "lienAmount": 20000, - "countryId": "01", - "comment": "Testing CollectionLoanRequest", - "resultCode": "00", - "resultDescription": "Loan Collection Successful" - } - - - # return ResponseHelper.success( - # data=response_data, - # message="Loan collection completed successfully" - # ) - return jsonify(response_data), 200 - - except ValidationError as err: - logger.error(f"Validation Error: {err.messages}") - return jsonify({ - "message": "Validation exception" - }) , 422 - - except Exception as e: - logger.error(f"An error occurred: {str(e)}", exc_info=True) - return jsonify({ - "message": "Internal Server Error" - }) , 500 diff --git a/app/services/disbursement.py b/app/services/disbursement.py deleted file mode 100644 index 4005077..0000000 --- a/app/services/disbursement.py +++ /dev/null @@ -1,62 +0,0 @@ -from flask import request, jsonify -from marshmallow import ValidationError -from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.disbursement import DisbursementSchema - -class DisbursementService: - @staticmethod - def process_request(data): - """ - Process the Disbursement request. - - Args: - data (dict): The request data. - - Returns: - dict: A standardized response. - """ - try: - logger.info("Processing Disbursement request") - - # Validate input data using DisbursementSchema - schema = DisbursementSchema() - validated_data = schema.load(data) # Raises ValidationError if invalid - - # Simulated processing logic - response_data = { - "transactionId": "T001", - "TransactionId": "Tr201712RK9232P115", - "debtId": "273194670", - "customerId": "CN621868", - "accountId": "2017821799", - "productId": "101", - "provideAmount": 100000.0, - "collectAmountInterest": 5000, - "collectAmountMgtFee": 1000, - "collectAmountInsurance": 1000, - "collectAmountVAT": 75, - "countryId": "01", - "resultCode": "00", - "resultDescription": "Loan Request Completed Successfully!" - } - - - # return ResponseHelper.success( - # data=response_data, - # message="Disbursement completed successfully" - # ) - - return response_data - - except ValidationError as err: - logger.error(f"Validation Error: {err.messages}") - return jsonify({ - "message": "Validation exception" - }) , 422 - - except Exception as e: - logger.error(f"An error occurred: {str(e)}", exc_info=True) - return jsonify({ - "message": "Internal Server Error" - }) , 500 diff --git a/app/services/lien_check.py b/app/services/lien_check.py deleted file mode 100644 index 0fbcd5d..0000000 --- a/app/services/lien_check.py +++ /dev/null @@ -1,51 +0,0 @@ -from flask import request, jsonify -from marshmallow import ValidationError -from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.lien_check import LienCheckSchema - -class LienCheckService: - @staticmethod - def process_request(data): - """ - Process the LienCheck request. - - Args: - data (dict): The request data. - - Returns: - dict: A standardized response. - """ - try: - logger.info("Processing LienCheck request") - - # Validate input data using LienCheckSchema - schema = LienCheckSchema() - validated_data = schema.load(data) # Raises ValidationError if invalid - - # Simulated lien check logic - response_data = { - "lienAmount": 20000.0, - "resultCode": "00", - "resultDescription": "Successful" - } - - - # return ResponseHelper.success( - # data=response_data, - # message="Lien check completed successfully" - # ) - - return response_data - - except ValidationError as err: - logger.error(f"Validation Error: {err.messages}") - return jsonify({ - "message": "Validation exception" - }) , 422 - - except Exception as e: - logger.error(f"An error occurred: {str(e)}", exc_info=True) - return jsonify({ - "message": "Internal Server Error" - }) , 500 diff --git a/app/services/new_transaction_check.py b/app/services/new_transaction_check.py deleted file mode 100644 index 0eeac65..0000000 --- a/app/services/new_transaction_check.py +++ /dev/null @@ -1,58 +0,0 @@ -from flask import request, jsonify -from marshmallow import ValidationError -from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.new_transaction_check import NewTransactionCheckSchema - -class NewTransactionCheckService: - @staticmethod - def process_request(data): - """ - Process the NewTransactionCheck request. - - Args: - data (dict): The request data. - - Returns: - dict: A standardized response. - """ - try: - logger.info("Processing NewTransactionCheck request") - - # Validate input data using NewTransactionCheckSchema - schema = NewTransactionCheckSchema() - validated_data = schema.load(data) # Raises ValidationError if invalid - - # Simulated transaction check logic - response_data = { - "transactionId": "24110114545374721", - "data": { - "transactionId": "241101", - "providedAmount": 1000.00, - "collectedAmount": 0.00, - "resultCode": "00", - "resultDescription": "Loan Provision is successful" - }, - "resultCode": "00", - "resultDescription": "SUCCESS" - } - - - # return ResponseHelper.success( - # data=response_data, - # message="New transaction check completed successfully" - # ) - - return response_data - - except ValidationError as err: - logger.error(f"Validation Error: {err.messages}") - return jsonify({ - "message": "Validation exception" - }) , 422 - - except Exception as e: - logger.error(f"An error occurred: {str(e)}", exc_info=True) - return jsonify({ - "message": "Internal Server Error" - }) , 500 diff --git a/app/services/penal_charge.py b/app/services/penal_charge.py deleted file mode 100644 index 7b1d1ad..0000000 --- a/app/services/penal_charge.py +++ /dev/null @@ -1,51 +0,0 @@ -from flask import request, jsonify -from marshmallow import ValidationError -from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.penal_charge import PenalChargeSchema - - -class PenalChargeService: - @staticmethod - def process_request(data): - """ - Process the PenalCharge request. - - Args: - data (dict): The request data. - - Returns: - dict: A standardized response. - """ - try: - logger.info("Processing PenalCharge request") - - # Validate input data using PenalChargeSchema - schema = PenalChargeSchema() - validated_data = schema.load(data) # Raises ValidationError if invalid - - # Simulated processing logic - response_data = { - "resultCode": "00", - "resultDescription": "Penal charge debited successfully" - } - - - # return ResponseHelper.success( - # data=response_data, - # message="Penal charge applied successfully" - # ) - - return response_data - - except ValidationError as err: - logger.error(f"Validation Error: {err.messages}") - return jsonify({ - "message": "Validation exception" - }) , 422 - - except Exception as e: - logger.error(f"An error occurred: {str(e)}", exc_info=True) - return jsonify({ - "message": "Internal Server Error" - }) , 500 diff --git a/app/services/rac_check.py b/app/services/rac_check.py deleted file mode 100644 index ea7eaa3..0000000 --- a/app/services/rac_check.py +++ /dev/null @@ -1,63 +0,0 @@ -from flask import request, jsonify -from marshmallow import ValidationError -from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.rac_check import RACCheckSchema - -class RACCheckService: - @staticmethod - def process_request(data): - """ - Process the RACCheck request. - - Args: - data (dict): The request data. - - Returns: - dict: A standardized response. - """ - try: - logger.info("Processing RACCheck request") - - # Validate input data using RACCheckSchema - schema = RACCheckSchema() - validated_data = schema.load(data) # Raises ValidationError if invalid - - # Simulated processing logic - response_data = { - "resultCode": "00", - "RACResponse": { - "SalaryAccount": "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 ResponseHelper.success( - # data=response_data, - # message="RAC check completed successfully" - # ) - - return response_data - - except ValidationError as err: - logger.error(f"Validation Error: {err.messages}") - return jsonify({ - "message": "Validation exception" - }) , 422 - - except Exception as e: - logger.error(f"An error occurred: {str(e)}", exc_info=True) - return jsonify({ - "message": "Internal Server Error" - }) , 500 diff --git a/app/services/revoke_enable_consent.py b/app/services/revoke_enable_consent.py deleted file mode 100644 index fffb5af..0000000 --- a/app/services/revoke_enable_consent.py +++ /dev/null @@ -1,54 +0,0 @@ -from flask import request, jsonify -from marshmallow import ValidationError -from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.revoke_enable_consent import RevokeEnableConsentSchema - - -class RevokeEnableConsentService: - @staticmethod - def process_request(data): - """ - Process the RevokeEnableConsent request. - - Args: - data (dict): The request data. - - Returns: - dict: A standardized response. - """ - try: - logger.info("Processing RevokeEnableConsent request") - - # Validate input data using RevokeEnableConsentSchema - schema = RevokeEnableConsentSchema() - validated_data = schema.load(data) # Raises ValidationError if invalid - - # Simulated processing logic - response_data = { - "type": "RevokeEnableConsentResponse", - "customerId": "CN621868", - "accountId": "2017821799", - "resultCode": "00", - "resultDescription": "Success" - } - - - # return ResponseHelper.success( - # data=response_data, - # message="Consent revocation processed successfully" - # ) - - return response_data - - except ValidationError as err: - logger.error(f"Validation Error: {err.messages}") - return jsonify({ - "message": "Validation exception" - }) , 422 - - except Exception as e: - logger.error(f"An error occurred: {str(e)}", exc_info=True) - return jsonify({ - "message": "Internal Server Error" - }) , 500 diff --git a/app/services/token_validation.py b/app/services/token_validation.py deleted file mode 100644 index 3226f23..0000000 --- a/app/services/token_validation.py +++ /dev/null @@ -1,54 +0,0 @@ -from flask import request, jsonify -from marshmallow import ValidationError -from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.token_validation import TokenValidationSchema - - -class TokenValidationService: - @staticmethod - def process_request(data): - """ - Process the TokenValidation request. - - Args: - data (dict): The request data. - - Returns: - dict: A standardized response. - """ - try: - logger.info("Processing TokenValidation request") - - # Validate input data using TokenValidationSchema - schema = TokenValidationSchema() - validated_data = schema.load(data) # Raises ValidationError if invalid - - # Simulated token validation logic - response_data = { - "Authenticated": True, - "AuthenticatedMessage": "The user Oluwole Olusoga has successfully authenticated!", - "ResponseCode": "00", - "ResponseMessage": "Successful", - "RequestId": "SMB1234567" - } - - - # return ResponseHelper.success( - # data=response_data, - # message="Token validation completed successfully" - # ) - - return response_data - - except ValidationError as err: - logger.error(f"Validation Error: {err.messages}") - return jsonify({ - "message": "Validation exception" - }) , 422 - - except Exception as e: - logger.error(f"An error occurred: {str(e)}", exc_info=True) - return jsonify({ - "message": "Internal Server Error" - }) , 500 diff --git a/app/services/transaction_verify.py b/app/services/transaction_verify.py deleted file mode 100644 index 2232835..0000000 --- a/app/services/transaction_verify.py +++ /dev/null @@ -1,57 +0,0 @@ -from flask import request, jsonify -from marshmallow import ValidationError -from app.utils.logger import logger -from app.helpers.response_helper import ResponseHelper -from app.schemas.transaction_verify import TransactionVerifySchema - - -class TransactionVerifyService: - @staticmethod - def process_request(data): - """ - Process the TransactionVerify request. - - Args: - data (dict): The request data. - - Returns: - dict: A standardized response. - """ - try: - logger.info("Processing TransactionVerify request") - - # Validate input data using TransactionVerifySchema - schema = TransactionVerifySchema() - validated_data = schema.load(data) # Raises ValidationError if invalid - - # Simulated processing logic - response_data = { - "type": "TransactionCheckResponse", - "nativeId": "FBN20191031104405CN621868", - "customerId": "CN621868", - "accountId": "2017821799", - "providedAmount": 0.0, - "collectedAmount": 7.50, - "resultCode": "00", - "resultDescription": "Collect Status retrieved successfully." - } - - - # return ResponseHelper.success( - # data=response_data, - # message="Transaction verification completed successfully" - # ) - - return response_data - - except ValidationError as err: - logger.error(f"Validation Error: {err.messages}") - return jsonify({ - "message": "Validation exception" - }) , 422 - - except Exception as e: - logger.error(f"An error occurred: {str(e)}", exc_info=True) - return jsonify({ - "message": "Internal Server Error" - }) , 500 diff --git a/app/static/css/main.css b/app/static/css/main.css deleted file mode 100644 index e69de29..0000000 diff --git a/app/static/js/main.js b/app/static/js/main.js deleted file mode 100644 index e69de29..0000000 diff --git a/app/swagger/digifi_swagger.json b/app/swagger/digifi_swagger.json new file mode 100644 index 0000000..42b5d06 --- /dev/null +++ b/app/swagger/digifi_swagger.json @@ -0,0 +1,156 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Swagger Simbrella FirstAdvance - OpenAPI 3.0", + "description": "This is a Simbrella FirstAdvance Backend Server with the OpenAPI 3.0 specification. \n\n\nSome useful links:\n- [Web Simulated Demo Page](https://digifi-salaryloan.chiefsoft.net/)\n- [Web Management Support Portal](https://digifi-office.chiefsoft.net/auth/login)", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "email": "support@chiefsoft.com" + }, + "license": { + "name": "Apache 2.0", + "url": "http://www.apache.org/licenses/LICENSE-2.0.html" + }, + "version": "1.0.11" + }, + "servers": [ + { + "url": "http://localhost:4500" + } + ], + "tags": [ + { + "name": "EligibilityCheck", + "description": "Eligibility Check Request", + "externalDocs": { + "description": "Find out more", + "url": "https://www.simbrellang.net" + } + }, + { + "name": "SelectOffer", + "description": "This method is used the send the offer the customer selected to Simbrella.", + "externalDocs": { + "description": "Find out more", + "url": "https://www.simbrellang.net" + } + }, + { + "name": "ProvideLoan", + "description": "Provide Loan Request.", + "externalDocs": { + "description": "Find out more", + "url": "https://www.simbrellang.net" + } + }, + { + "name": "LoanInformation", + "description": "Loan Information Request.", + "externalDocs": { + "description": "Find out more", + "url": "https://www.simbrellang.net" + } + }, + { + "name": "Repayment", + "description": "Repayment Request.", + "externalDocs": { + "description": "Find out more", + "url": "https://www.simbrellang.net" + } + }, + { + "name": "CustomerConsent", + "description": "CustomerConsent Request.", + "externalDocs": { + "description": "Find out more", + "url": "https://www.simbrellang.net" + } + }, + { + "name": "NotificationCallback", + "description": "This new feature will be used for informing Simbrella about status of the transactions that FBN have processed.", + "externalDocs": { + "description": "Find out more", + "url": "https://www.simbrellang.net" + } + } + ], + "paths": { + "/EligibilityCheck": { + "$ref": "swagger/paths/EligibilityCheck.json" + }, + "/SelectOffer": { + "$ref": "swagger/paths/SelectOffer.json" + }, + "/ProvideLoan": { + "$ref": "swagger/paths/ProvideLoan.json" + }, + "/LoanInformation": { + "$ref": "swagger/paths/LoanInformation.json" + }, + "/Repayment": { + "$ref": "swagger/paths/Repayment.json" + }, + "/CustomerConsent": { + "$ref": "swagger/paths/CustomerConsent.json" + }, + "/NotificationCallback": { + "$ref": "swagger/paths/NotificationCallback.json" + } + }, + "components": { + "schemas": { + "EligibilityCheckRequest": { + "$ref": "swagger/schemas/EligibilityCheckRequest.json" + }, + "EligibilityCheckResponse": { + "$ref": "swagger/schemas/EligibilityCheckResponse.json" + }, + "SelectOfferRequest": { + "$ref": "swagger/schemas/SelectOfferRequest.json" + }, + "SelectOfferResponse": { + "$ref": "swagger/schemas/SelectOfferResponse.json" + }, + "LoanInformationRequest": { + "$ref": "swagger/schemas/LoanInformationRequest.json" + }, + "LoanInformationResponse": { + "$ref": "swagger/schemas/LoanInformationResponse.json" + }, + "RepaymentRequest": { + "$ref": "swagger/schemas/RepaymentRequest.json" + }, + "RepaymentResponse": { + "$ref": "swagger/schemas/RepaymentResponse.json" + }, + "CustomerConsentRequest": { + "$ref": "swagger/schemas/CustomerConsentRequest.json" + }, + "CustomerConsentResponse": { + "$ref": "swagger/schemas/CustomerConsentResponse.json" + }, + "NotificationCallbackRequest": { + "$ref": "swagger/schemas/NotificationCallbackRequest.json" + }, + "NotificationCallbackResponse": { + "$ref": "swagger/schemas/NotificationCallbackResponse.json" + }, + "ApiResponse": { + "$ref": "swagger/schemas/ApiResponse.json" + } + }, + "securitySchemes": { + "basicAuth": { + "type": "http", + "scheme": "basic" + } + } + }, + "security": [ + { + "basicAuth": [] + } + ] +} \ No newline at end of file diff --git a/app/swagger/paths/CustomerConsent.json b/app/swagger/paths/CustomerConsent.json new file mode 100644 index 0000000..dafbf04 --- /dev/null +++ b/app/swagger/paths/CustomerConsent.json @@ -0,0 +1,53 @@ +{ + "post": { + "tags": [ + "CustomerConsent" + ], + "summary": "Customer Consent Request", + "description": "Customer Consent Request", + "operationId": "CustomerConsent", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "../schemas/CustomerConsentRequest.json" + } + }, + "application/xml": { + "schema": { + "$ref": "../schemas/CustomerConsentRequest.json" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "../schemas/CustomerConsentRequest.json" + } + } + } + }, + "responses": { + "200": { + "description": "Successful", + "content": { + "application/json": { + "schema": { + "$ref": "../schemas/CustomerConsentResponse.json" + } + }, + "application/xml": { + "schema": { + "$ref": "../schemas/CustomerConsentResponse.json" + } + } + } + }, + "400": { + "description": "Invalid request" + }, + "500": { + "description": "Internal server error" + } + } + } + } \ No newline at end of file diff --git a/app/swagger/paths/EligibilityCheck.json b/app/swagger/paths/EligibilityCheck.json new file mode 100644 index 0000000..a6231d7 --- /dev/null +++ b/app/swagger/paths/EligibilityCheck.json @@ -0,0 +1,65 @@ +{ + "post": { + "tags": [ + "EligibilityCheck" + ], + "summary": "Start the process - initiate steps to eligibility RAC Checks ", + "description": "Initiate Eligibility Check Request", + "operationId": "startEligibilityCheck", + "requestBody": { + "description": "Post JSON to conduct eligibility tests", + "content": { + "application/json": { + "schema": { + "$ref": "../schemas/EligibilityCheckRequest.json" + } + }, + "application/xml": { + "schema": { + "$ref": "../schemas/EligibilityCheckRequest.json" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "../schemas/EligibilityCheckRequest.json" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "../schemas/EligibilityCheckResponse.json" + } + }, + "application/xml": { + "schema": { + "$ref": "../schemas/EligibilityCheckResponse.json" + } + } + } + }, + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Pet not found" + }, + "422": { + "description": "Validation exception" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } +} \ No newline at end of file diff --git a/app/swagger/paths/LoanInformation.json b/app/swagger/paths/LoanInformation.json new file mode 100644 index 0000000..ded3156 --- /dev/null +++ b/app/swagger/paths/LoanInformation.json @@ -0,0 +1,65 @@ +{ + "get": { + "tags": [ + "LoanInformation" + ], + "summary": "Loan Information Request ", + "description": "Loan Information Request", + "operationId": "startEligibilityCheck", + "requestBody": { + "description": "Post JSON to conduct eligibility tests", + "content": { + "application/json": { + "schema": { + "$ref": "../schemas/LoanInformationRequest.json" + } + }, + "application/xml": { + "schema": { + "$ref": "../schemas/LoanInformationRequest.json" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "../schemas/LoanInformationRequest.json" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "../schemas/LoanInformationResponse.json" + } + }, + "application/xml": { + "schema": { + "$ref": "../schemas/LoanInformationResponse.json" + } + } + } + }, + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Loan not found" + }, + "422": { + "description": "Validation exception" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } + } \ No newline at end of file diff --git a/app/swagger/paths/NotificationCallback.json b/app/swagger/paths/NotificationCallback.json new file mode 100644 index 0000000..b7d8e7c --- /dev/null +++ b/app/swagger/paths/NotificationCallback.json @@ -0,0 +1,65 @@ +{ + "post": { + "tags": [ + "NotificationCallback" + ], + "summary": "Loan Information Request ", + "description": "Loan Information Request", + "operationId": "startEligibilityCheck", + "requestBody": { + "description": "Post JSON to conduct eligibility tests", + "content": { + "application/json": { + "schema": { + "$ref": "../schemas/LoanInformationRequest.json" + } + }, + "application/xml": { + "schema": { + "$ref": "../schemas/LoanInformationRequest.json" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "../schemas/LoanInformationRequest.json" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "../schemas/LoanInformationResponse.json" + } + }, + "application/xml": { + "schema": { + "$ref": "../schemas/LoanInformationResponse.json" + } + } + } + }, + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Loan not found" + }, + "422": { + "description": "Validation exception" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } + } \ No newline at end of file diff --git a/app/swagger/paths/ProvideLoan.json b/app/swagger/paths/ProvideLoan.json new file mode 100644 index 0000000..d919c2d --- /dev/null +++ b/app/swagger/paths/ProvideLoan.json @@ -0,0 +1,65 @@ +{ + "post": { + "tags": [ + "ProvideLoan" + ], + "summary": "Provide Loan Request ", + "description": "Provide Loan Request", + "operationId": "startEligibilityCheck", + "requestBody": { + "description": "Post JSON to conduct eligibility tests", + "content": { + "application/json": { + "schema": { + "$ref": "../schemas/EligibilityCheckRequest.json" + } + }, + "application/xml": { + "schema": { + "$ref": "../schemas/EligibilityCheckRequest.json" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "../schemas/EligibilityCheckRequest.json" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "../schemas/EligibilityCheckResponse.json" + } + }, + "application/xml": { + "schema": { + "$ref": "../schemas/EligibilityCheckResponse.json" + } + } + } + }, + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Pet not found" + }, + "422": { + "description": "Validation exception" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } + } \ No newline at end of file diff --git a/app/swagger/paths/Repayment.json b/app/swagger/paths/Repayment.json new file mode 100644 index 0000000..e0c0878 --- /dev/null +++ b/app/swagger/paths/Repayment.json @@ -0,0 +1,53 @@ +{ + "post": { + "tags": [ + "Repayment" + ], + "summary": "Repayment Request", + "description": "Repayment Request", + "operationId": "Repayment", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "../schemas/RepaymentRequest.json" + } + }, + "application/xml": { + "schema": { + "$ref": "../schemas/RepaymentRequest.json" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "../schemas/RepaymentRequest.json" + } + } + } + }, + "responses": { + "200": { + "description": "Repayment Successful", + "content": { + "application/json": { + "schema": { + "$ref": "../schemas/RepaymentResponse.json" + } + }, + "application/xml": { + "schema": { + "$ref": "../schemas/RepaymentResponse.json" + } + } + } + }, + "400": { + "description": "Invalid request" + }, + "500": { + "description": "Internal server error" + } + } + } +} \ No newline at end of file diff --git a/app/swagger/paths/SelectOffer.json b/app/swagger/paths/SelectOffer.json new file mode 100644 index 0000000..14c6234 --- /dev/null +++ b/app/swagger/paths/SelectOffer.json @@ -0,0 +1,65 @@ +{ + "post": { + "tags": [ + "SelectOffer" + ], + "summary": "This method is used the send the offer the customer selected to Simbrella ", + "description": "This method is used the send the offer the customer selected to Simbrella", + "operationId": "startEligibilityCheck", + "requestBody": { + "description": "Post JSON to conduct eligibility tests", + "content": { + "application/json": { + "schema": { + "$ref": "../schemas/SelectOfferRequest.json" + } + }, + "application/xml": { + "schema": { + "$ref": "../schemas/SelectOfferRequest.json" + } + }, + "application/x-www-form-urlencoded": { + "schema": { + "$ref": "../schemas/SelectOfferRequest.json" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful operation", + "content": { + "application/json": { + "schema": { + "$ref": "../schemas/SelectOfferResponse.json" + } + }, + "application/xml": { + "schema": { + "$ref": "../schemas/SelectOfferResponse.json" + } + } + } + }, + "400": { + "description": "Invalid ID supplied" + }, + "404": { + "description": "Offers not found" + }, + "422": { + "description": "Validation exception" + } + }, + "security": [ + { + "petstore_auth": [ + "write:pets", + "read:pets" + ] + } + ] + } +} \ No newline at end of file diff --git a/app/swagger/schemas/ApiResponse.json b/app/swagger/schemas/ApiResponse.json new file mode 100644 index 0000000..2cd2bdd --- /dev/null +++ b/app/swagger/schemas/ApiResponse.json @@ -0,0 +1,18 @@ +{ + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "type": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "xml": { + "name": "##default" + } +} \ No newline at end of file diff --git a/app/swagger/schemas/CustomerConsentRequest.json b/app/swagger/schemas/CustomerConsentRequest.json new file mode 100644 index 0000000..c8c9e70 --- /dev/null +++ b/app/swagger/schemas/CustomerConsentRequest.json @@ -0,0 +1,37 @@ +{ + "type": "object", + "properties": { + "$type": { + "type": "string", + "example": "CustomerConsentRequest" + }, + "transactionId": { + "type": "string", + "example": "20171209232177" + }, + "customerId": { + "type": "string", + "example": "CN621868" + }, + "accountId": { + "type": "string", + "example": "ACN8263457" + }, + "requestTime": { + "type": "string", + "format": "date-time", + "example": "2019-10-18 14:26:21.063" + }, + "consentType": { + "type": "string", + "example": "Revoke" + }, + "channel": { + "type": "string", + "example": "USSD" + } + }, + "xml": { + "name": "CustomerConsentRequest" + } +} \ No newline at end of file diff --git a/app/swagger/schemas/CustomerConsentResponse.json b/app/swagger/schemas/CustomerConsentResponse.json new file mode 100644 index 0000000..fb46f6a --- /dev/null +++ b/app/swagger/schemas/CustomerConsentResponse.json @@ -0,0 +1,16 @@ +{ + "type": "object", + "properties": { + "resultCode": { + "type": "string", + "example": "00" + }, + "resultDescription": { + "type": "string", + "example": "Request is received" + } + }, + "xml": { + "name": "CustomerConsentResponse" + } +} \ No newline at end of file diff --git a/app/swagger/schemas/EligibilityCheckRequest.json b/app/swagger/schemas/EligibilityCheckRequest.json new file mode 100644 index 0000000..8bb14de --- /dev/null +++ b/app/swagger/schemas/EligibilityCheckRequest.json @@ -0,0 +1,32 @@ +{ + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "example": "Tr201712RK9232P115" + }, + "countryCode": { + "type": "string", + "example": "NGR" + }, + "customerId": { + "type": "string", + "example": "CN621868" + }, + "msisdn": { + "type": "string", + "example": "8093451342" + }, + "channel": { + "type": "string", + "example": "100" + }, + "accountId": { + "type": "string", + "example": "ACN8263457" + } + }, + "xml": { + "name": "EligibilityCheckRequest" + } +} \ No newline at end of file diff --git a/app/swagger/schemas/EligibilityCheckResponse.json b/app/swagger/schemas/EligibilityCheckResponse.json new file mode 100644 index 0000000..1f91239 --- /dev/null +++ b/app/swagger/schemas/EligibilityCheckResponse.json @@ -0,0 +1,82 @@ +{ + "type": "object", + "properties": { + "customerId": { + "type": "string", + "example": "CN621868" + }, + "transactionId": { + "type": "string", + "example": "TX12345" + }, + "countryCode": { + "type": "string", + "example": "NG" + }, + "msisdn": { + "type": "string", + "example": "3451342" + }, + "eligibleOffers": { + "type": "array", + "items": { + "type": "object", + "properties": { + "offerId": { + "type": "string", + "example": "Offer1" + }, + "productId": { + "type": "string", + "example": "Product1" + }, + "minAamount": { + "type": "number", + "format": "decimal", + "example": 100.00 + }, + "maxAamount": { + "type": "number", + "format": "decimal", + "example": 1000.00 + }, + "tenor": { + "type": "integer", + "example": 12 + } + } + }, + "example": [ + { + "offerId": "Offer1", + "productId": "Product1", + "minAamount": 100.00, + "maxAamount": 1000.00, + "tenor": 12 + }, + { + "offerId": "Offer2", + "productId": "Product2", + "minAamount": 200.00, + "maxAamount": 2000.00, + "tenor": 24 + } + ] + }, + "resultDescription": { + "type": "string", + "example": "Successful" + }, + "resultCode": { + "type": "string", + "example": "00" + }, + "accountId": { + "type": "string", + "example": "ACN8263457" + } + }, + "xml": { + "name": "EligibilityCheckResponse" + } +} \ No newline at end of file diff --git a/app/swagger/schemas/LoanInformationRequest.json b/app/swagger/schemas/LoanInformationRequest.json new file mode 100644 index 0000000..70d753c --- /dev/null +++ b/app/swagger/schemas/LoanInformationRequest.json @@ -0,0 +1,28 @@ +{ + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "example": "Tr201712RK9232P115" + }, + "resultDescription": { + "type": "string", + "example": "Successful" + }, + "customerId": { + "type": "string", + "example": "CN621868" + }, + "msisdn": { + "type": "string", + "example": "3451342" + }, + "channel": { + "type": "string", + "example": "USSD" + } + }, + "xml": { + "name": "LoanInformationRequest" + } +} \ No newline at end of file diff --git a/app/swagger/schemas/LoanInformationResponse.json b/app/swagger/schemas/LoanInformationResponse.json new file mode 100644 index 0000000..528abd9 --- /dev/null +++ b/app/swagger/schemas/LoanInformationResponse.json @@ -0,0 +1,28 @@ +{ + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "example": "Tr201712RK9232P115" + }, + "resultDescription": { + "type": "string", + "example": "Successful" + }, + "resultCode": { + "type": "string", + "example": "00" + }, + "customerId": { + "type": "string", + "example": "CN621868" + }, + "loan": { + "type": "string", + "example": "Arrray of loans" + } + }, + "xml": { + "name": "LoanInformationResponse" + } +} \ No newline at end of file diff --git a/app/swagger/schemas/NotificationCallbackRequest.json b/app/swagger/schemas/NotificationCallbackRequest.json new file mode 100644 index 0000000..d5457fb --- /dev/null +++ b/app/swagger/schemas/NotificationCallbackRequest.json @@ -0,0 +1,50 @@ +{ + "type": "object", + "properties": { + "fbnTransactionId": { + "type": "string", + "example": "123456789" + }, + "transactionId": { + "type": "string", + "example": "123456789" + }, + "customerId": { + "type": "string", + "example": "CN621868" + }, + "accountId": { + "type": "string", + "example": "ACN8263457" + }, + "debtId": { + "type": "string", + "example": "987654321" + }, + "transactionType": { + "type": "string", + "example": "Disbursement" + }, + "amountProvided": { + "type": "number", + "format": "float", + "example": 1000.00 + }, + "amountCollected": { + "type": "number", + "format": "float", + "example": 0.00 + }, + "responseCode": { + "type": "string", + "example": "00" + }, + "responseDescription": { + "type": "string", + "example": "Successful" + } + }, + "xml": { + "name": "NotificationCallbackRequest" + } +} \ No newline at end of file diff --git a/app/swagger/schemas/NotificationCallbackResponse.json b/app/swagger/schemas/NotificationCallbackResponse.json new file mode 100644 index 0000000..c4a6a78 --- /dev/null +++ b/app/swagger/schemas/NotificationCallbackResponse.json @@ -0,0 +1,16 @@ +{ + "type": "object", + "properties": { + "resultCode": { + "type": "string", + "example": "00" + }, + "resultDescription": { + "type": "string", + "example": "Successful" + } + }, + "xml": { + "name": "NotificationCallbackResponse" + } +} \ No newline at end of file diff --git a/app/swagger/schemas/ProvideLoanRequest.json b/app/swagger/schemas/ProvideLoanRequest.json new file mode 100644 index 0000000..8d20f34 --- /dev/null +++ b/app/swagger/schemas/ProvideLoanRequest.json @@ -0,0 +1,45 @@ +{ + "type": "object", + "properties": { + "transactionId": { + "type": "string", + "example": "202111170001371256908" + }, + "accountId": { + "type": "string", + "example": "ACN8263457" + }, + "customerId": { + "type": "string", + "example": "CN621868" + }, + "msisdn": { + "type": "string", + "example": "9012345678" + }, + "productId": { + "type": "string", + "example": "101" + }, + "requestedAmount": { + "type": "number", + "format": "decimal", + "example": 900 + }, + "collectionType": { + "type": "integer", + "example": 1 + }, + "offerID": { + "type": "integer", + "example": 0 + }, + "channel": { + "type": "string", + "example": "100" + } + }, + "xml": { + "name": "ProvideLoanRequest" + } +} \ No newline at end of file diff --git a/app/swagger/schemas/ProvideLoanResponse.json b/app/swagger/schemas/ProvideLoanResponse.json new file mode 100644 index 0000000..d7ddb3c --- /dev/null +++ b/app/swagger/schemas/ProvideLoanResponse.json @@ -0,0 +1,36 @@ +{ + "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" + }, + "resultCode": { + "type": "string", + "example": "00" + }, + "resultDescription": { + "type": "string", + "example": "Successful" + } + }, + "xml": { + "name": "ProvideLoanResponse" + } +} \ No newline at end of file diff --git a/app/swagger/schemas/RepaymentRequest.json b/app/swagger/schemas/RepaymentRequest.json new file mode 100644 index 0000000..c463d70 --- /dev/null +++ b/app/swagger/schemas/RepaymentRequest.json @@ -0,0 +1,36 @@ +{ + "type": "object", + "properties": { + "$type": { + "type": "string", + "example": "RepaymentRequest" + }, + "msisdn": { + "type": "string", + "example": "3451342" + }, + "debtId": { + "type": "string", + "example": "273194670" + }, + "productId": { + "type": "string", + "example": "101" + }, + "transactionId": { + "type": "string", + "example": "20171209232115" + }, + "customerId": { + "type": "string", + "example": "CN621868" + }, + "channel": { + "type": "string", + "example": "USSD" + } + }, + "xml": { + "name": "RepaymentRequest" + } +} \ No newline at end of file diff --git a/app/swagger/schemas/RepaymentResponse.json b/app/swagger/schemas/RepaymentResponse.json new file mode 100644 index 0000000..06e4666 --- /dev/null +++ b/app/swagger/schemas/RepaymentResponse.json @@ -0,0 +1,28 @@ +{ + "type": "object", + "properties": { + "customerId": { + "type": "string", + "example": "CN621868" + }, + "productId": { + "type": "string", + "example": "101" + }, + "debtId": { + "type": "string", + "example": "273194670" + }, + "resultCode": { + "type": "string", + "example": "00" + }, + "resultDescription": { + "type": "string", + "example": "Successful" + } + }, + "xml": { + "name": "RepaymentResponse" + } +} \ No newline at end of file diff --git a/app/swagger/schemas/SelectOfferRequest.json b/app/swagger/schemas/SelectOfferRequest.json new file mode 100644 index 0000000..2ce7d62 --- /dev/null +++ b/app/swagger/schemas/SelectOfferRequest.json @@ -0,0 +1,41 @@ +{ + "type": "object", + "properties": { + "requestId": { + "type": "string", + "example": "202111170001371256908" + }, + "transactionId": { + "type": "string", + "example": "1231231321232" + }, + "customerId": { + "type": "string", + "example": "CN621868" + }, + "msisdn": { + "type": "string", + "example": "123456789" + }, + "requestedAmount": { + "type": "number", + "format": "double", + "example": 10000.55 + }, + "accountId": { + "type": "string", + "example": "ACN8263457" + }, + "productid": { + "type": "string", + "example": "101" + }, + "channel": { + "type": "string", + "example": "" + } + }, + "xml": { + "name": "SelectOffersRequest" + } +} \ No newline at end of file diff --git a/app/swagger/schemas/SelectOfferResponse.json b/app/swagger/schemas/SelectOfferResponse.json new file mode 100644 index 0000000..1d0ebdf --- /dev/null +++ b/app/swagger/schemas/SelectOfferResponse.json @@ -0,0 +1,112 @@ +{ + "type": "object", + "properties": { + "requestId": { + "type": "string", + "example": "202111170001371256908" + }, + "transactionId": { + "type": "string", + "example": "1231231321232" + }, + "customerId": { + "type": "string", + "example": "1256907" + }, + "accountId": { + "type": "string", + "example": "5948306019" + }, + "loan": { + "type": "array", + "items": { + "type": "object", + "properties": { + "offerId": { + "type": "string", + "example": "14451" + }, + "productId": { + "type": "string", + "example": "2030" + }, + "amount": { + "type": "number", + "format": "float", + "example": 10000.0 + }, + "upfrontPayment": { + "type": "number", + "format": "float", + "example": 1000.0 + }, + "interestRate": { + "type": "number", + "format": "float", + "example": 3.0 + }, + "ManagementRate": { + "type": "number", + "format": "float", + "example": 1.0 + }, + "ManagementFee": { + "type": "number", + "format": "float", + "example": 1.0 + }, + "InsuranceRate": { + "type": "number", + "format": "float", + "example": 1.0 + }, + "InsuranceFee": { + "type": "number", + "format": "float", + "example": 100.0 + }, + "VATRate": { + "type": "number", + "format": "float", + "example": 7.5 + }, + "VATamount": { + "type": "number", + "format": "float", + "example": 100.0 + }, + "recommendedRepaymentDates": { + "type": "array", + "items": { + "type": "string" + }, + "example": [ + "2022-11-30" + ] + }, + "installmentAmount": { + "type": "number", + "format": "float", + "example": 11000.0 + }, + "totalRepaymentAmount": { + "type": "number", + "format": "float", + "example": 11000.0 + } + } + } + }, + "resultCode": { + "type": "string", + "example": "00" + }, + "resultDescription": { + "type": "string", + "example": "Successful" + } + }, + "xml": { + "name": "SelectOffersResponse" + } +} \ No newline at end of file diff --git a/app/templates/index.html b/app/templates/index.html deleted file mode 100644 index f29a4e2..0000000 --- a/app/templates/index.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index b4d292a..e3765f2 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,7 +2,7 @@ services: digifi-flaska002: build: . ports: - - "7200:5000" + - "4500:5000" environment: - FLASK_APP=app.py - FLASK_RUN_HOST=0.0.0.0 diff --git a/requirements.txt b/requirements.txt index 737f663..d5cb30f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,6 +4,7 @@ Flask-Marshmallow==0.15.0 marshmallow==3.19.0 Flask-Cors==3.0.10 gunicorn +flask-swagger-ui