File size: 5,423 Bytes
a65f83d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
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
MONGO_URI = "mongodb+srv://kltn20133118:XEYSVzYvEwsp5Cvo@cluster0.nnsw9.mongodb.net/?retryWrites=true&w=majority&appName=Cluster0"
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,is_refund = False).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, is_refund = False).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,is_refund = False).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
    )