-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
reorganization of mojaloop and mpesa.
- Loading branch information
1 parent
7205e82
commit 8be04c7
Showing
21 changed files
with
391 additions
and
1,098 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,3 @@ | ||
# G2P Payments Bridge: Mojaloop SDK Scheme Adapter Payment Backend. | ||
[![Pre-commit Status](https://github.com/OpenG2P/g2p-payments-bridge/actions/workflows/pre-commit.yml/badge.svg?branch=develop)](https://github.com/OpenG2P/g2p-payments-bridge/actions/workflows/pre-commit.yml?query=branch%3Adevelop) | ||
[![Build Status](https://github.com/OpenG2P/g2p-payments-bridge/actions/workflows/test.yml/badge.svg?branch=develop)](https://github.com/OpenG2P/g2p-payments-bridge/actions/workflows/test.yml?query=branch%3Adevelop) | ||
[![codecov](https://codecov.io/gh/OpenG2P/g2p-payments-bridge/branch/develop/graph/badge.svg)](https://codecov.io/gh/OpenG2P/g2p-payments-bridge) | ||
[![openapi](https://img.shields.io/badge/open--API-swagger-brightgreen)](https://validator.swagger.io/?url=https://raw.githubusercontent.com/OpenG2P/g2p-payments-bridge/develop/api-docs/generated/openapi.json) | ||
![PyPI](https://img.shields.io/pypi/v/gpb-mojaloop-sdk-payment-backend?label=pypi%20package) | ||
![PyPI - Downloads](https://img.shields.io/pypi/dm/gpb-mojaloop-sdk-payment-backend) | ||
|
||
Mojaloop SDK Scheme Adapter backend for G2P Payments Bridge. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,186 @@ | ||
#!/usr/bin/env python3 | ||
# ruff: noqa: E402 | ||
|
||
import asyncio | ||
import logging | ||
from contextlib import asynccontextmanager | ||
from datetime import datetime | ||
from typing import List | ||
|
||
import httpx | ||
from fastapi import FastAPI | ||
from g2p_payments_bridge_core.models.disburse import ( | ||
SingleDisburseStatusEnum, | ||
) | ||
from g2p_payments_bridge_core.models.msg_header import MsgStatusEnum | ||
from g2p_payments_bridge_core.models.orm.payment_list import PaymentListItem | ||
from openg2p_fastapi_common.config import Settings as BaseSettings | ||
from openg2p_fastapi_common.context import dbengine | ||
from openg2p_fastapi_common.service import BaseService | ||
from pydantic import BaseModel | ||
from pydantic_settings import SettingsConfigDict | ||
from sqlalchemy import and_, select | ||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker | ||
|
||
|
||
class Settings(BaseSettings): | ||
model_config = SettingsConfigDict( | ||
env_prefix="gpb_mojaloop_sdk_", env_file=".env", extra="allow" | ||
) | ||
openapi_title: str = "GPB Mojaloop SDK Adapter Payment Backend" | ||
openapi_description: str = """ | ||
Payment Backend for Mojaloop SDK Adapter of G2P Payments Bridge. | ||
*********************************** | ||
Further details goes here | ||
*********************************** | ||
""" | ||
openapi_version: str = "0.1.0" | ||
|
||
payment_backend_name: str = "mojaloop" | ||
db_dbname: str = "gpbdb" | ||
|
||
api_timeout: int = 10 | ||
transfers_url: str = "" | ||
payer_id_type: str = "" | ||
payer_id_value: str = "" | ||
payee_id_type: str = "" | ||
transfer_note: str = "GPB benefit transfer" | ||
|
||
|
||
_config = Settings.get_config() | ||
_logger = logging.getLogger("openg2p_fastapi_common.app") | ||
|
||
|
||
class ReferenceIdStatus(BaseModel): | ||
txn_id: str | ||
ref_id: str | ||
status: MsgStatusEnum | ||
|
||
|
||
class MojaloopSdkPaymentBackendService(BaseService): | ||
def __init__(self, name="", **kwargs): | ||
super().__init__(name if name else _config.payment_backend_name, **kwargs) | ||
|
||
def post_init(self): | ||
asyncio.create_task(self.disburse_loop()) | ||
|
||
async def disburse_loop(self): | ||
while True: | ||
db_response = [] | ||
async_session_maker = async_sessionmaker(dbengine.get()) | ||
async with async_session_maker() as session: | ||
stmt = select(PaymentListItem) | ||
if ( | ||
_config.dsbmt_loop_filter_backend_name | ||
and _config.dsbmt_loop_filter_status | ||
): | ||
stmt = stmt.where( | ||
and_( | ||
PaymentListItem.backend_name | ||
== _config.payment_backend_name, | ||
PaymentListItem.status.in_( | ||
[ | ||
MsgStatusEnum[status] | ||
for status in _config.dsbmt_loop_filter_status | ||
] | ||
), | ||
) | ||
) | ||
elif _config.dsbmt_loop_filter_backend_name: | ||
stmt = stmt.where( | ||
PaymentListItem.backend_name == _config.payment_backend_name | ||
) | ||
elif _config.dsbmt_loop_filter_status: | ||
stmt = stmt.where( | ||
PaymentListItem.status.in_( | ||
[ | ||
MsgStatusEnum[status] | ||
for status in _config.dsbmt_loop_filter_status | ||
] | ||
) | ||
) | ||
stmt = stmt.order_by(PaymentListItem.id.asc()) | ||
result = await session.execute(stmt) | ||
|
||
db_response = list(result.scalars()) | ||
if db_response: | ||
_logger.info("GPB Mojaloop - processing payment from payment list.") | ||
await self.disburse(db_response, session) | ||
else: | ||
_logger.info( | ||
"GPB Mojaloop - no records found in payment list table." | ||
) | ||
|
||
await asyncio.sleep(_config.dsbmt_loop_interval_secs) | ||
|
||
async def disburse(self, payments: List[PaymentListItem], session: AsyncSession): | ||
for payment in payments: | ||
data = { | ||
"homeTransactionId": payment.request_id, | ||
"from": { | ||
"idType": _config.payer_id_type, | ||
"idValue": _config.payer_id_value, | ||
}, | ||
"to": { | ||
"idType": _config.payee_id_type, | ||
"idValue": await self.get_payee_id_value_from_payee_fa( | ||
payment.to_fa | ||
), | ||
}, | ||
"currency": payment.currency, | ||
"amount": float(payment.amount), | ||
"note": _config.transfer_note, | ||
"transactionType": "TRANSFER", | ||
"amountType": "SEND", | ||
} | ||
try: | ||
response = httpx.post( | ||
_config.transfers_url, | ||
json=data, | ||
timeout=_config.api_timeout, | ||
) | ||
_logger.info( | ||
"Mojaloop SDK Payment Transfer response: %s", response.content | ||
) | ||
response.raise_for_status() | ||
|
||
# TODO: Do Status check rather than hardcoding | ||
payment.updated_at = datetime.utcnow() | ||
payment.status = MsgStatusEnum.succ | ||
except Exception: | ||
_logger.exception("Mojaloop Payment Failed with unknown reason") | ||
payment.updated_at = datetime.utcnow() | ||
payment.status = MsgStatusEnum.rjct | ||
payment.error_code = SingleDisburseStatusEnum.rjct_payment_failed | ||
payment.error_msg = "Mojaloop Payment Failed with unknown reason" | ||
|
||
await session.commit() | ||
|
||
async def get_payee_id_value_from_payee_fa(self, fa: str) -> str: | ||
return fa[fa.find(":") + 1 : fa.rfind("@")] | ||
|
||
|
||
from gpb_translate_id_fa.app import Initializer as TranslateIdInitializer | ||
from openg2p_common_g2pconnect_id_mapper.app import ( | ||
Initializer as G2pConnectMapperInitializer, | ||
) | ||
from openg2p_fastapi_common.app import Initializer | ||
|
||
|
||
class PaymentBackendInitializer(Initializer): | ||
def initialize(self, **kwargs): | ||
MojaloopSdkPaymentBackendService() | ||
|
||
@asynccontextmanager | ||
async def fastapi_app_lifespan(self, app: FastAPI): | ||
self.payment_backend.post_init() | ||
yield | ||
await dbengine.get().dispose() | ||
|
||
|
||
if __name__ == "__main__": | ||
main_init = PaymentBackendInitializer() | ||
G2pConnectMapperInitializer() | ||
TranslateIdInitializer() | ||
main_init.main() |
This file was deleted.
Oops, something went wrong.
Empty file removed
0
gpb-mojaloop-sdk-payment-backend/src/gpb_mojaloop_sdk_payment_backend/__init__.py
Empty file.
15 changes: 0 additions & 15 deletions
15
gpb-mojaloop-sdk-payment-backend/src/gpb_mojaloop_sdk_payment_backend/app.py
This file was deleted.
Oops, something went wrong.
16 changes: 0 additions & 16 deletions
16
gpb-mojaloop-sdk-payment-backend/src/gpb_mojaloop_sdk_payment_backend/config.py
This file was deleted.
Oops, something went wrong.
Empty file.
88 changes: 0 additions & 88 deletions
88
...loop-sdk-payment-backend/src/gpb_mojaloop_sdk_payment_backend/services/payment_backend.py
This file was deleted.
Oops, something went wrong.
Empty file.
Oops, something went wrong.