微信退款

refund_url:'https://api.mch.weixin.qq.com/secapi/pay/refund' 退款url
import pycurl
import optparse
class RefundHandler(BaseHandler):
    allowed_methods = ('POST')
    fields = ()
    model = RefundInfo

    def read(self, request, *args, **kwargs):
        return 'read'

    def create(self, request, *args, **kwargs):
        out_trade_no = str(request.POST.get('out_trade_no'))
        appid        = int(request.POST.get('app',0))
        log.debug(out_trade_no)
        data = get_object_or_404(WxNotify,out_trade_no = out_trade_no)
        params = {}
        params['appid'] = data.appid
        params['mch_id'] = data.mch_id
        params['nonce_str'] = data.nonce_str
        params['transaction_id'] = data.transaction_id
        params['out_trade_no'] =data.out_trade_no
        params['out_refund_no'] = str(RindomStr(16))
        params['total_fee'] = data.total_fee
        params['refund_fee'] = data.total_fee
        params['op_user_id'] = data.mch_id
        # params['sign'] = get_sign(params)
        thirdinfo_paths = thirdinfo_path(appid)
        xml = get_xml(params,thirdinfo_paths.APIKEY)
        # headers = {'Content-Type': 'application/xml'}
        # r = requests.post(refund_url, data=xml, headers=headers)
        # log.debug(r.content)
        r = postXmlSSL(xml,refund_url,thirdinfo_paths.SSLCERT_PATH,thirdinfo_paths.SSLKEY_PATH,second=30,cert=True,post=True)
        log.debug(r)
        options = optparse.Values({"pretty": False})
        jsonstr = json.loads(xml2json(r,options))['xml']
        # convertedDict = xmltodict.parse(r)
        # log.debug(convertedDict)
        # jsonStr = json.dumps(convertedDict)
        # jsonstr = jsonStr.replace('\\','')
        try:
            data = request.POST.copy()
            data.update(jsonstr)
            log.debug(data)
            f = RefundInfoForm(data,request=request)
            if f.is_valid():
                f.save()
            else:
                raise FormValidationError(f)
        except:
            log.debug(jsonstr)
        if jsonstr['result_code'] == 'SUCCESS':
            pay_order = PayOrder.objects.all().filter(order_id=out_trade_no)
            ##########################################################################
            #若是type爲退貨,則修改退貨狀態爲完成,同時更新退貨完成時間,payorder的狀態不修改
            type = request.POST.get('type','')
            if type == 'salesreturn':
                refundstatus = get_object_or_404(RefundStatus,payorder=pay_order)
                refundstatus.status = 'complete'
                refundstatus.f_time = datetime.datetime.now()
                refundstatus.save()
                return jsonstr
            ##########################################################################
            pay_order.update(status="closed")
        return jsonstr
def postXmlSSL(xml, url,SSLCERT_PATH, SSLKEY_PATH,second=30, cert=True, post=True):
        """使用證書"""
        curl = pycurl.Curl()
        curl.setopt(pycurl.URL, url)
        curl.setopt(pycurl.TIMEOUT, second)
        #設置證書
        #使用證書:cert 與 key 分別屬於兩個.pem文件
        #默認格式爲PEM,能夠註釋
        if cert:
            curl.setopt(pycurl.SSLKEYTYPE, "PEM")
            curl.setopt(pycurl.SSLKEY, SSLKEY_PATH)
            curl.setopt(pycurl.SSLCERTTYPE, "PEM")
            curl.setopt(pycurl.SSLCERT, SSLCERT_PATH)
        #post提交方式
        if post:
            curl.setopt(pycurl.POST, True)
            curl.setopt(pycurl.POSTFIELDS, xml)
        buff = StringIO()
        curl.setopt(pycurl.WRITEFUNCTION, buff.write)
        curl.perform()
        return buff.getvalue()
def get_xml(params,APIKEY):
    get_sign(params,APIKEY)
    xml = '<xml>'
    for k,v in params.items():
        k = str(k).encode('utf-8')
        v = str(v).encode('utf-8')
        xml += '<' + k + '>' + v + '</' + k + '>'
    xml+='</xml>'
    return xml
相關文章
相關標籤/搜索