123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- import logging
- import simplejson as json
- from typing import TYPE_CHECKING, Dict
- from apps.web.common.transaction.refund import RefundNotifier, RefundPuller
- from apps.web.core.models import JDAggrePayApp
- from library.jd import JDAggrePay
- from library.jd.exceptions import JDPayException
- if TYPE_CHECKING:
- from django.core.handlers.wsgi import WSGIRequest
- from apps.web.core.payment import PaymentGatewayT
- from apps.web.common.transaction.pay import RefundRecordT, RechargeRecordT
- logger = logging.getLogger(__name__)
- class JDAggreRefundNotifier(RefundNotifier):
- def __init__(self, request, record_cls_factory):
- self.orginal = json.loads(request.body) # type: Dict
- logger.debug('received jdaggre refund notify(encrypt): {}'.format(str(self.orginal)))
- super(JDAggreRefundNotifier, self).__init__(request=request, refund_order_getter=record_cls_factory)
- def parse_request(self, request): # type:(WSGIRequest) -> dict
- app = JDAggrePayApp.objects(merchant_no = self.orginal['merchantNo']).first() # type: JDAggrePayApp
- client = JDAggrePay(app.merchant_no, app.desKey, app.saltMd5Key, app.debug) # type: JDAggrePay
- return client.decrypt_response(self.orginal)
- def verify_payload(self, payload): # type:(dict) -> bool
- """ 京东聚合的退款返回参数中,没有明确要求对于参数做篡改校验 """
- return True
- @property
- def refund_order_no(self): # type:() -> str
- return self.payload['outRefundNo']
- def handle_refund_order(self, refundOrder, post_pay): # type:(RefundRecordT, callable) -> None
- if self.payload["resultCode"] != "SUCCESS": # 接口失败
- refundOrder.fail(errorCode = self.payload["errCode"], errorDesc = self.payload["errCodeDes"])
- return
- if self.payload["payStatus"] == "FINISH": # 业务状态成功
- payFinishTime = self.payload["payFinishTime"]
- datetimeRefund = datetime.datetime.strptime(payFinishTime, "%Y%m%d%H%M%S")
- matched = refundOrder.succeed(tradeRefundNo = self.payload["tradeRefundNo"], finishedTime = datetimeRefund)
- if not matched:
- return
- return post_pay(refundOrder, datetimeRefund)
- if self.payload["payStatus"] == "CLOSE": # 退款单被关闭
- refundOrder.closed(
- tradeRefundNo = self.payload["tradeRefundNo"],
- errorCode = self.payload["errCode"],
- errorDesc = self.payload["errCodeDes"])
- return
- # 剩下的情况就是resultCode == SUCCESS 但是 payStatus != [FINISH, CLOSE] 在文档中没有描述 做个防止机制
- refundOrder.fail(errorCode = self.payload["errCode"], errorDesc = self.payload["errCodeDes"])
- @property
- def errorResponse(self): # type:() -> str
- return "error"
- @property
- def successResponse(self): # type:() -> str
- return "ok"
- class JDAggreRefundPuller(RefundPuller):
- def pull(self, payGateWay, payOrder, post_pay): # type:(PaymentGatewayT, RechargeRecordT, callable) -> None
- try:
- result = payGateWay.api_refund_query(out_refund_no = self._refundOrder.orderNo)
- except JDPayException:
- return
- if result["resultCode"] != "SUCCESS":
- self._refundOrder.fail(errorCode = result["errCode"], errorDesc = result["errCodeDes"])
- elif result["payStatus"] == "FINISH":
- payFinishTime = result["payFinishTime"]
- datetimeRefund = datetime.datetime.strptime(payFinishTime, "%Y%m%d%H%M%S")
- matched = self._refundOrder.succeed(result["payRequestPiNo"], finishedTime = datetimeRefund)
- if not matched:
- return
- post_pay(self._refundOrder, datetimeRefund)
- elif result["payStatus"] == "CLOSE":
- self._refundOrder.closed(result["payRequestPiNo"], errorCode = result["errCode"],
- errorDesc = result["errCodeDes"])
- elif result["payStatus"] == "PROCESSING":
- pass
- else:
- pass
|