chatbot_server / controller /RefundController.py
kltn21110's picture
Upload 239 files
325b400 verified
from fastapi import APIRouter, Request, Depends, HTTPException
from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials
from fastapi.requests import Request
from fastapi.responses import JSONResponse
import asyncio
router = APIRouter()
import asyncio
class JWTBearer(HTTPBearer):
def __init__(self, auto_error: bool = True):
super(JWTBearer, self).__init__(auto_error=auto_error)
async def __call__(self, request: Request):
credentials: HTTPAuthorizationCredentials = await super(JWTBearer, self).__call__(request)
if credentials:
if credentials.scheme != "Bearer":
raise HTTPException(status_code=401, detail="Invalid authentication scheme.")
return credentials.credentials
else:
raise HTTPException(status_code=401, detail="Invalid authorization code.")
import sys,os
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
jwt_bearer = JWTBearer()
import decode_token
from models.Database_Entity import StopSignal
from models.Database_Entity import ChatHistory,PaymentCallbackLog
from service.RefundService import *
from models.Database_Entity import PaymentCallbackLog
from bson import ObjectId
from mongoengine import connect
from dotenv import load_dotenv
load_dotenv()
MONGO_URI = os.getenv("MONGO_URI", "")
connect("chatbot_hmdrinks", host=MONGO_URI)
async def refund_by_type_and_code(type: str, code: str):
if type.lower() == "zalopay":
log = PaymentCallbackLog.objects(type="zalopay", app_trans_id=code).first()
if not log:
return {"code": -3, "message": "Không tìm thấy giao dịch ZaloPay"}
data = call_zalopay_refund(
app_trans_id=code,
amount=log.raw_data.get("amount", 0),
description="Hoàn tiền ZaloPay"
)
return_code = data.get("return_code")
if return_code == 3:
log.is_refund = True
log.save()
return {"code": 0 , "message": f"Hoàn tiền thành công", "data": data}
else:
log.is_refund = False
log.save()
return {"code": -1 , "message": f"Hoàn tiền thất bại", "data": data}
elif type.lower() == "vnpay":
log = PaymentCallbackLog.objects(type="vnpay", txn_ref=code).first()
if not log:
return {"code": -2, "message": "Không tìm thấy giao dịch VNPay"}
raw = log.raw_data
data = call_vnpay_refund(
txn_ref=code,
amount=int(raw.get("vnp_Amount", 0)), # VNPAY trả về x100
transaction_date=raw.get("vnp_PayDate"),
transaction_no=raw.get("vnp_TransactionNo"),
create_by="system_refund",
order_info=raw.get("vnp_OrderInfo", "Hoàn tiền VNPay")
)
resultCode = data.get("data").get("vnp_ResponseCode")
message = data.get("data").get("vnp_Message")
if resultCode == "00":
log.is_refund = True
log.save()
return {"code": 0 , "message": f"Hoàn tiền thành công {message}", "data": data}
else:
log.is_refund = False
log.save()
return {"code": -1 , "message": f"Hoàn tiền thất bại {message}", "data": data}
elif type.lower() == "momo":
log = PaymentCallbackLog.objects(type="momo", order_id=code).first()
if not log:
return {"code": -3, "message": "Không tìm thấy giao dịch MoMo"}
if log.raw_data.get("payType", "") != "qr":
return {"code": -2 , "message": f"Payment không thể hoàn tiền với ", "data": data}
data = call_momo_refund(
trans_id=log.raw_data.get("transId", 0),
amount=log.raw_data.get("amount", 0),
description=f"Hoàn tiền MoMo cho giao dịch {code}"
)
resultCode = data.get("resultCode")
if resultCode == 0:
log.is_refund = True
log.save()
return {"code": 0 , "message": f"Hoàn tiền thành công", "data": data}
else:
log.is_refund = False
log.save()
return {"code": -1 , "message": f"Hoàn tiền thất bại", "data": data}
else:
return {"code": -4, "message": f"Không hỗ trợ cổng thanh toán '{type}'"}
from fastapi import HTTPException
from pydantic import BaseModel
class Refund(BaseModel):
type: str
code: str
@router.post("/refund")
async def refund_endpoint(request: Refund,token: str = Depends(jwt_bearer)):
type = request.type
code = request.code
user_role = decode_token.JwtService.extract_user_role(token)
if user_role != "ADMIN":
return JSONResponse(content={"message": "Not allow"}, status_code=404)
data = asyncio.run(refund_by_type_and_code(type = type,code=code))
if data.get("code") != 0 :
return JSONResponse(content={"message": f"Not allow type {type}","status": -1, "data":data}, status_code=404)
else:
return JSONResponse(
content={
"status": 0,
"data": data
},
status_code=200
)
@router.post("/refund-schedule")
async def refund_endpoint_schedule(request: Refund):
type = request.type
code = request.code
data = asyncio.run(refund_by_type_and_code(type = type,code=code))
if data.get("code") != 0 :
return JSONResponse(content={"message": f"Not allow type {type}","status": -1, "data":data}, status_code=404)
else:
return JSONResponse(
content={
"status": 0,
"data": data
},
status_code=200
)