File size: 5,838 Bytes
325b400
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
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
    )