# -*- coding: utf-8 -*- # !/usr/bin/env python import datetime import logging from typing import TYPE_CHECKING, Dict from apps.web.common.transaction.refund import RefundNotifier, RefundPuller if TYPE_CHECKING: from django.core.handlers.wsgi import WSGIRequest from apps.web.core.payment import PaymentGatewayT from apps.web.common.transaction.pay import RechargeRecordT, RefundRecordT logger = logging.getLogger(__name__) class AliRefundNotifier(RefundNotifier): def parse_request(self, request): # type:(WSGIRequest) -> Dict return request.POST.dict() # type: Dict @property def refund_order_no(self): # type:() -> str return self.payload['out_biz_no'] def handle_refund_order(self, refundOrder, post_pay): # type:(RefundRecordT, callable) -> None """ 只有成功的退款 才会走异步的回调 """ refundTime = self.payload["gmt_refund"] datetimeRefund = datetime.datetime.strptime(refundTime[: 19], "%Y-%m-%d %H:%M:%S") matched = refundOrder.succeed(tradeRefundNo = None, finishedTime = datetimeRefund) if not matched: return return post_pay(refundOrder, datetimeRefund) @property def errorResponse(self): # type:() -> str return "error" @property def successResponse(self): # type:() -> str return "success" def verify_payload(self, payload): # type:(dict) -> bool return True class AliRefundPuller(RefundPuller): def pull(self, payGateWay, payOrder, post_pay): # type:(PaymentGatewayT, RechargeRecordT, callable) -> None result = payGateWay.api_refund_query( trade_no = payOrder.wxOrderNo, out_trade_no = payOrder.orderNo, out_request_no = self._refundOrder.orderNo) if result["code"] != "10000" or result["msg"] != "Success" or result["refund_status"] != "REFUND_SUCCESS": logger.info( "RefundPuller {} pull refund order {}, result code = {}, msg = {}".format( self.__class__.__name__, self._refundOrder, result["code"], result["msg"])) return # 对于支付宝来说, 查询的时候通知的时间并没有显示出来, 就用查询的时间代理 gmt_refund_pay = result["gmt_refund_pay"] datetimeRefund = datetime.datetime.strptime(gmt_refund_pay, "%Y-%m-%d %H:%M:%S") matched = self._refundOrder.succeed(tradeRefundNo = None, finishedTime = datetimeRefund) if not matched: return post_pay(self._refundOrder, datetimeRefund)