123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- # -*- coding: utf-8 -*-
- # !/usr/bin/env python
- import datetime
- import logging
- import simplejson as json
- from django.conf import settings
- 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 RefundRecordT, RechargeRecordT
- logger = logging.getLogger(__name__)
- class JDOpenRefundNotifier(RefundNotifier):
- def parse_request(self, request): # type:(WSGIRequest) -> dict
- _head = {
- 'accessKey': request.META['HTTP_ACCESSKEY'],
- 'version': request.META['HTTP_VERSION'],
- 'timestamp': request.META['HTTP_TIMESTAMP'],
- 'token': request.META['HTTP_TOKEN']
- }
- _body = json.loads(request.body) # type: Dict
- logger.debug('received jdopen refund notify: body = {}; heads = {}'.format(_body, _head))
- return {
- 'body': _body,
- 'head': _head
- }
- def verify_payload(self, payload): # type:(dict) -> bool
- return True
- def handle_refund_order(self, refundOrder, post_pay): # type:(RefundRecordT, callable) -> None
- if not self.payload:
- refundOrder.fail(errorDesc = u'退款通知参数错误')
- return
- if self.payload["body"]["refundStatus"] != "SUCCESS":
- refundOrder.fail(
- errorCode = self.payload["body"].get('failCode', ''),
- errorDesc = self.payload["body"].get('failReason', ''))
- return
- import arrow
- refund_finished_time = arrow.get(
- self.payload["body"]["refundDate"], 'YYYY-MM-DD HH:mm',
- tzinfo = settings.TIME_ZONE).naive # type: datetime.datetime
- matched = refundOrder.succeed(
- tradeRefundNo = str(self.payload["body"].get('bankRequestNum', '')), finishedTime = refund_finished_time)
- if not matched:
- return
- return post_pay(refundOrder, refund_finished_time)
- @property
- def refund_order_no(self): # type:() -> str
- return self.payload["body"]['refundRequestNum']
- @property
- def errorResponse(self): # type:() -> str
- return "error"
- @property
- def successResponse(self): # type:() -> str
- return "ok"
- class JDOpenRefundPuller(RefundPuller):
- def pull(self, payGateWay, payOrder, post_pay): # type:(PaymentGatewayT, RechargeRecordT, callable) -> None
- try:
- result = payGateWay.api_refund_query(requestNum = payOrder.orderNo)
- refund_record_list = result['data']['refundRecordList']
- for refund_record in refund_record_list:
- if refund_record['refundRequestNum'] != self._refundOrder.orderNo:
- logger.debug('order<orderNo={}> has another refund record<orderNo={}>'.format(
- payOrder.orderNo, self._refundOrder.orderNo))
- continue
- else:
- if refund_record["status"] == "FAIL":
- self._refundOrder.fail(errorDesc = refund_record["failReason"])
- elif refund_record["status"] == "SUCCESS":
- import arrow
- completeTime = arrow.get(
- refund_record['refundTime'], 'YYYY-MM-DD HH:mm:ss', tzinfo = settings.TIME_ZONE).naive
- matched = self._refundOrder.succeed(
- tradeRefundNo = refund_record['bankRequestNum'], finishedTime = completeTime)
- if not matched:
- return
- post_pay(self._refundOrder, completeTime)
- elif result["payStatus"] == "INIT":
- pass
- except Exception as e:
- logger.exception(e)
|