Spaces:
Sleeping
Sleeping
| 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 | |
| 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 | |
| ) | |
| 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 | |
| ) |