jdaggre.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. # -*- coding: utf-8 -*-
  2. # !/usr/bin/env python
  3. import datetime
  4. import logging
  5. import simplejson as json
  6. from typing import TYPE_CHECKING, Dict
  7. from apps.web.common.transaction.refund import RefundNotifier, RefundPuller
  8. from apps.web.core.models import JDAggrePayApp
  9. from library.jd import JDAggrePay
  10. from library.jd.exceptions import JDPayException
  11. if TYPE_CHECKING:
  12. from django.core.handlers.wsgi import WSGIRequest
  13. from apps.web.core.payment import PaymentGatewayT
  14. from apps.web.common.transaction.pay import RefundRecordT, RechargeRecordT
  15. logger = logging.getLogger(__name__)
  16. class JDAggreRefundNotifier(RefundNotifier):
  17. def __init__(self, request, record_cls_factory):
  18. self.orginal = json.loads(request.body) # type: Dict
  19. logger.debug('received jdaggre refund notify(encrypt): {}'.format(str(self.orginal)))
  20. super(JDAggreRefundNotifier, self).__init__(request=request, refund_order_getter=record_cls_factory)
  21. def parse_request(self, request): # type:(WSGIRequest) -> dict
  22. app = JDAggrePayApp.objects(merchant_no = self.orginal['merchantNo']).first() # type: JDAggrePayApp
  23. client = JDAggrePay(app.merchant_no, app.desKey, app.saltMd5Key, app.debug) # type: JDAggrePay
  24. return client.decrypt_response(self.orginal)
  25. def verify_payload(self, payload): # type:(dict) -> bool
  26. """ 京东聚合的退款返回参数中,没有明确要求对于参数做篡改校验 """
  27. return True
  28. @property
  29. def refund_order_no(self): # type:() -> str
  30. return self.payload['outRefundNo']
  31. def handle_refund_order(self, refundOrder, post_pay): # type:(RefundRecordT, callable) -> None
  32. if self.payload["resultCode"] != "SUCCESS": # 接口失败
  33. refundOrder.fail(errorCode = self.payload["errCode"], errorDesc = self.payload["errCodeDes"])
  34. return
  35. if self.payload["payStatus"] == "FINISH": # 业务状态成功
  36. payFinishTime = self.payload["payFinishTime"]
  37. datetimeRefund = datetime.datetime.strptime(payFinishTime, "%Y%m%d%H%M%S")
  38. matched = refundOrder.succeed(tradeRefundNo = self.payload["tradeRefundNo"], finishedTime = datetimeRefund)
  39. if not matched:
  40. return
  41. return post_pay(refundOrder, datetimeRefund)
  42. if self.payload["payStatus"] == "CLOSE": # 退款单被关闭
  43. refundOrder.closed(
  44. tradeRefundNo = self.payload["tradeRefundNo"],
  45. errorCode = self.payload["errCode"],
  46. errorDesc = self.payload["errCodeDes"])
  47. return
  48. # 剩下的情况就是resultCode == SUCCESS 但是 payStatus != [FINISH, CLOSE] 在文档中没有描述 做个防止机制
  49. refundOrder.fail(errorCode = self.payload["errCode"], errorDesc = self.payload["errCodeDes"])
  50. @property
  51. def errorResponse(self): # type:() -> str
  52. return "error"
  53. @property
  54. def successResponse(self): # type:() -> str
  55. return "ok"
  56. class JDAggreRefundPuller(RefundPuller):
  57. def pull(self, payGateWay, payOrder, post_pay): # type:(PaymentGatewayT, RechargeRecordT, callable) -> None
  58. try:
  59. result = payGateWay.api_refund_query(out_refund_no = self._refundOrder.orderNo)
  60. except JDPayException:
  61. return
  62. if result["resultCode"] != "SUCCESS":
  63. self._refundOrder.fail(errorCode = result["errCode"], errorDesc = result["errCodeDes"])
  64. elif result["payStatus"] == "FINISH":
  65. payFinishTime = result["payFinishTime"]
  66. datetimeRefund = datetime.datetime.strptime(payFinishTime, "%Y%m%d%H%M%S")
  67. matched = self._refundOrder.succeed(result["payRequestPiNo"], finishedTime = datetimeRefund)
  68. if not matched:
  69. return
  70. post_pay(self._refundOrder, datetimeRefund)
  71. elif result["payStatus"] == "CLOSE":
  72. self._refundOrder.closed(result["payRequestPiNo"], errorCode = result["errCode"],
  73. errorDesc = result["errCodeDes"])
  74. elif result["payStatus"] == "PROCESSING":
  75. pass
  76. else:
  77. pass