微信支付

 

統一下單接口json

'https://api.mch.weixin.qq.com/pay/unifiedorder'api

參數:微信

appid:微信公衆號APPIDapp

mch_id :微信的商戶IDdom

nonce_str:32爲之內的隨機字符串post

body:訂單的信息(標題不一樣的支付方式標題的表現形式不一樣)url

out_trade_no:訂單ID(該商品在後臺的ID號)debug

total_fee:訂單金額code

spbill_create_ip:客戶端請求IP地址orm

trade_type:支付類型(APP[app支付],JSAPI[公衆號支付須要openid],MWEB[H5支付]) 

notify_url:支付回調地址

代碼:

def weixinpay(appid,mch_id,nonce_str,body,order_id,total_fee,trade_type,openid,spbill_create_ip):
    params = {
        'appid':appid,
        'mch_id':mch_id,
        'nonce_str':nonce_str,
        'body':body,
        'out_trade_no':order_id,
        'total_fee':total_fee,
        'spbill_create_ip':spbill_create_ip,
        'trade_type':trade_type,
        'openid':openid,
        'notify_url':''.join(['http://',settings.WAPI_PROXY_DOMAIN,'/wapi/wxpay/notify/'])
    }
    if params['openid'] == '':
        params.pop('openid')
        return params
    else:
        return params

#將鍵值對轉換成key=value&key=value的形式

def key_value(value):

    key_sort = sorted(value.keys())

    arry=[]

    for k in key_sort:

        v = str(value.get(k,'')).strip()

        v = v.encode('utf-8')

        k = k.encode('utf-8')

        arry.append('%s=%s'%(k,v))

    temp = '&'.join(arry)

    return temp

#生成sign

def get_sign(params,APIKEY):

    stringA = key_value(params)

    stringSignTemp=stringA + '&key=' + APIKEY

    sign = (md5(stringSignTemp).hexdigest()).upper()

    params['sign'] = sign

    return sign

#拼接xml

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>'

    retrun xml

#經過統一下單接口請求獲取prepay_id

def get_prepay_id(params,APIKEY):
    xml = get_xml(params,APIKEY)
    headers = {'Content-Type': 'application/xml'}
    r = requests.post(url, data=xml, headers=headers)
    re_xml = ElementTree.fromstring(r.text.encode('utf8'))
    xml_status = re_xml.getiterator('return_code')[0].text
    xml_msg = re_xml.getiterator('return_msg')[0].text
    if len(re_xml.getiterator('result_code')) != 0:
        xml_result_code = re_xml.getiterator('result_code')[0].text
        if xml_result_code != 'SUCCESS':
            xml_err_code    = re_xml.getiterator('err_code')[0].text
            if xml_result_code != 'SUCCESS':
                return HttpResponseBadRequest({xml_result_code: [u'%s' % xml_err_code]})

    if xml_status != 'SUCCESS':
        error = u"鏈接微信出錯啦!"
        return error
    prepay_id = re_xml.getiterator('prepay_id')[0].text

    params['prepay_id'] = prepay_id
    if params['trade_type'] != 'JSAPI':
        params['package'] = 'Sign=WXPay'
    params['timestamp'] = str(int(time.time()))

 

獲取prepay_id後再次簽名,返回給終端參數

APIKEY:申請後獲得的密鑰

def re_finall(params,APIKEY):
        #獲得prepay_id後再次簽名,返回給終端參數
        tag = get_prepay_id(params,APIKEY)
        if not params.has_key('prepay_id'):
            return tag
        if params['trade_type'] != 'JSAPI':
            sign_again_params = {
                'appid': params['appid'],
                'noncestr': params['nonce_str'],
                'package': params['package'],
                'partnerid': params['mch_id'],
                'timestamp': params['timestamp'],
                'prepayid': params['prepay_id']
            }
            sign = get_sign(sign_again_params,APIKEY)
            params['sign'] = sign
            return params
        else:
            sign_again_params = {
                'appId': params['appid'],
                'nonceStr': params['nonce_str'],
                'package': 'prepay_id='+params['prepay_id'],
                'signType': 'MD5',
                'timeStamp': params['timestamp'],
                # 'prepayid': params['prepay_id']
            }
            sign = get_sign(sign_again_params,APIKEY)
            params['sign'] = sign
            return params

#驗證簽名:    

def checkSign(params,APIKEY):
    signlocal = params.pop('sign')
    sign = get_sign(params,APIKEY)
    if sign != signlocal:
        return False
    return True

支付回調信息:

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
相關文章
相關標籤/搜索