Spaces:
Sleeping
Sleeping
Download service/RefundService.py from kltn21110/chatbot_server: direct link, hf CLI and curl.
- Browser
- Download file 7.17 kB
-
https://huggingface.co/spaces/kltn21110/chatbot_server/resolve/main/service/RefundService.py
- Command line
-
hf download hf://spaces/kltn21110/chatbot_server/service/RefundService.py
-
curl -L -o RefundService.py https://huggingface.co/spaces/kltn21110/chatbot_server/resolve/main/service/RefundService.py
7.17 kB
| from pydantic import BaseModel | |
| import uuid, hmac, hashlib, requests | |
| # --- Thông tin định danh --- | |
| PARTNER_CODE = "MOMO" | |
| ACCESS_KEY = "F8BBA842ECF85" | |
| SECRET_KEY = "K951B6PE1waDMi640xX08PD3vg6EkVlz" | |
| # --- Model yêu cầu hoàn tiền --- | |
| class RefundRequest(BaseModel): | |
| partnerCode: str | |
| orderId: str | |
| requestId: str | |
| amount: int | |
| transId: int | |
| description: str | |
| lang: str = "vi" | |
| # --- Tạo chữ ký --- | |
| def generate_refund_signature(data: dict) -> str: | |
| raw_data = ( | |
| f"accessKey={ACCESS_KEY}&amount={data['amount']}&description={data['description']}" | |
| f"&orderId={data['orderId']}&partnerCode={PARTNER_CODE}" | |
| f"&requestId={data['requestId']}&transId={data['transId']}" | |
| ) | |
| return hmac.new(SECRET_KEY.encode(), raw_data.encode(), hashlib.sha256).hexdigest() | |
| def call_momo_refund(amount: int, trans_id: int, description: str = "Hoàn tiền giao dịch"): | |
| order_id = str(uuid.uuid4()) | |
| request_id = str(uuid.uuid4()) | |
| refund = RefundRequest( | |
| partnerCode=PARTNER_CODE, | |
| orderId=order_id, | |
| requestId=request_id, | |
| amount=amount, | |
| transId=trans_id, | |
| description=description, | |
| ) | |
| payload = refund.dict() | |
| payload["signature"] = generate_refund_signature(payload) | |
| response = requests.post( | |
| "https://test-payment.momo.vn/v2/gateway/api/refund", | |
| json=payload, | |
| headers={"Content-Type": "application/json"}, | |
| timeout=90, | |
| ) | |
| return response.json() | |
| # result = call_momo_refund(amount=100000, trans_id=4506777858) | |
| # print(result) | |
| import hmac | |
| import hashlib | |
| import requests | |
| from datetime import datetime | |
| import uuid | |
| # ====== CẤU HÌNH MẶC ĐỊNH ====== | |
| VNP_URL = "https://sandbox.vnpayment.vn/merchant_webapi/api/transaction" | |
| VNP_TMN_CODE = 'MCQ3SXQ1' | |
| VNP_SECRET_KEY = '2QS3MSRVQQAFN36I5GA02DWB353KO4FD' | |
| IP_ADDR = "127.0.0.1" | |
| # ====== HÀM TẠO CHECKSUM HMAC SHA512 ====== | |
| def hmac_sha512(key: str, data: str) -> str: | |
| return hmac.new(key.encode(), data.encode(), hashlib.sha512).hexdigest() | |
| # ====== HÀM HOÀN TIỀN VNPAY ====== | |
| def call_vnpay_refund( | |
| txn_ref: str, | |
| amount: int, | |
| transaction_date: str, | |
| create_by: str, | |
| order_info: str, | |
| transaction_no: str = "", # optional | |
| transaction_type: str = "02", # "02": full refund, "03": partial | |
| vnp_url: str = VNP_URL, | |
| vnp_tmn_code: str = VNP_TMN_CODE, | |
| vnp_secret_key: str = VNP_SECRET_KEY, | |
| ip_addr: str = IP_ADDR, | |
| ): | |
| # Lấy thời gian hiện tại (vnp_CreateDate) | |
| now = datetime.now().strftime("%Y%m%d%H%M%S") | |
| # Tạo request body | |
| params = { | |
| "vnp_RequestId": str(uuid.uuid4().hex[:32]), | |
| "vnp_Version": "2.1.0", | |
| "vnp_Command": "refund", | |
| "vnp_TmnCode": vnp_tmn_code, | |
| "vnp_TransactionType": transaction_type, | |
| "vnp_TxnRef": txn_ref, | |
| "vnp_Amount": str(amount), # nhân 100 nếu VNP yêu cầu | |
| "vnp_TransactionNo": transaction_no, | |
| "vnp_TransactionDate": transaction_date, | |
| "vnp_CreateBy": create_by, | |
| "vnp_CreateDate": now, | |
| "vnp_IpAddr": ip_addr, | |
| "vnp_OrderInfo": order_info | |
| } | |
| sign_data = "|".join([ | |
| params["vnp_RequestId"], | |
| params["vnp_Version"], | |
| params["vnp_Command"], | |
| params["vnp_TmnCode"], | |
| params["vnp_TransactionType"], | |
| params["vnp_TxnRef"], | |
| params["vnp_Amount"], | |
| params["vnp_TransactionNo"], | |
| params["vnp_TransactionDate"], | |
| params["vnp_CreateBy"], | |
| params["vnp_CreateDate"], | |
| params["vnp_IpAddr"], | |
| params["vnp_OrderInfo"] | |
| ]) | |
| params["vnp_SecureHash"] = hmac_sha512(vnp_secret_key, sign_data) | |
| response = requests.post(vnp_url, json=params, headers={"Content-Type": "application/json"}) | |
| return { | |
| "status_code": response.status_code, | |
| "data": response.json() | |
| } | |
| import hmac | |
| import hashlib | |
| import requests | |
| import time | |
| from datetime import datetime | |
| import random | |
| import string | |
| # Cấu hình tài khoản ZaloPay | |
| APP_ID = "2553" | |
| KEY1 = "PcY4iZIKFCIdgZvA6ueMcMHHUbRLYjPL" | |
| QUERY_ENDPOINT = "https://sb-openapi.zalopay.vn/v2/query" | |
| REFUND_ENDPOINT = "https://sb-openapi.zalopay.vn/v2/refund" | |
| def generate_mac(data: str, key: str) -> str: | |
| return hmac.new(key.encode(), data.encode(), hashlib.sha256).hexdigest() | |
| def generate_m_refund_id(): | |
| date_part = datetime.now().strftime("%y%m%d") | |
| random_part = ''.join(random.choices(string.digits, k=10)) | |
| return f"{date_part}_{APP_ID}_{random_part}" | |
| def call_zalopay_refund(app_trans_id: str, amount: int, description: str, refund_fee_amount: int = None): | |
| """ | |
| Hàm thực hiện hoàn tiền giao dịch ZaloPay dựa trên app_trans_id. | |
| Args: | |
| app_trans_id (str): Mã giao dịch của ứng dụng. | |
| amount (int): Số tiền hoàn lại (đơn vị: VND). | |
| description (str): Mô tả lý do hoàn tiền. | |
| refund_fee_amount (int, optional): Số tiền phí hoàn (nếu có). | |
| Returns: | |
| dict: Kết quả phản hồi từ ZaloPay. | |
| """ | |
| # Bước 1: Truy vấn để lấy zp_trans_id | |
| mac_input = f"{APP_ID}|{app_trans_id}|{KEY1}" | |
| mac = generate_mac(mac_input, KEY1) | |
| query_payload = { | |
| "app_id": APP_ID, | |
| "app_trans_id": app_trans_id, | |
| "mac": mac | |
| } | |
| try: | |
| query_response = requests.post(QUERY_ENDPOINT, data=query_payload) | |
| query_result = query_response.json() | |
| zp_trans_id = query_result.get("zp_trans_id") | |
| if not zp_trans_id: | |
| print("❌ Không tìm thấy zp_trans_id từ app_trans_id.") | |
| return {"code": -1, "message": "Không tìm thấy zp_trans_id"} | |
| except Exception as e: | |
| print("❌ Lỗi khi truy vấn giao dịch:", e) | |
| return {"code": -2, "message": "Lỗi truy vấn giao dịch"} | |
| timestamp = int(time.time() * 1000) | |
| m_refund_id = generate_m_refund_id() | |
| if refund_fee_amount is not None: | |
| hmac_data = f"{APP_ID}|{zp_trans_id}|{amount}|{refund_fee_amount}|{description}|{timestamp}" | |
| else: | |
| hmac_data = f"{APP_ID}|{zp_trans_id}|{amount}|{description}|{timestamp}" | |
| refund_mac = generate_mac(hmac_data, KEY1) | |
| refund_data = { | |
| "app_id": APP_ID, | |
| "m_refund_id": m_refund_id, | |
| "zp_trans_id": zp_trans_id, | |
| "amount": amount, | |
| "timestamp": timestamp, | |
| "description": description, | |
| "mac": refund_mac | |
| } | |
| if refund_fee_amount is not None: | |
| refund_data["refund_fee_amount"] = refund_fee_amount | |
| try: | |
| headers = { | |
| "Content-Type": "application/x-www-form-urlencoded" | |
| } | |
| refund_response = requests.post(REFUND_ENDPOINT, data=refund_data, headers=headers) | |
| return refund_response.json() | |
| except Exception as e: | |
| print("❌ Lỗi khi gửi hoàn tiền:", e) | |
| return {"code": -3, "message": "Lỗi hoàn tiền"} |