python+h5微信支付总结

微信支付的必要条件:1.域名必须备案;2.在公众号授权目录下授权调起支付的页面
1.必要的参数
 appid:这个在公众号里可以拿到
mch_id:公众号里可以拿到
api_key:微信支付商户平台中自己设置
app_secret:微信支付商户平台中拿到
out_trade_no:这个自己设置,我是用一个字符串+时间戳生成
2.获取openid
django中,一个函数通过下面
return HttpResponseRedirect(https://open.weixin.qq.com/connect/oauth2/authorize?appid=你的appid&redirect_uri=跳转的地址&response_type=code&scope=snsapi_base&state=#wechat_redirect')
跳转到pay(),通过下面代码:
code=request.GET.get('code')
fp=urllib.request.urlopen("https://api.weixin.qq.com/sns/oauth2/access_token?appid=你的appid&secret=你的app_secret&code="+code+"&grant_type=authorization_code")
token=fp.read().decode('utf-8')
tokenjson=json.loads(token)
openid=tokenjson['openid']
获取到openid

3.获取最重要的prepay_id
首先获取签名paysign,通过下面代码:
	
stringA="appid=你的appid&body=取个支付名称&mch_id=你的mch_id&nonce_str=随机串¬ify_url=支付完成后通知地址&openid=刚刚获取的openid&out_trade_no=刚刚设置的out_trade_no&spbill_create_ip=用户的ip&total_fee=此次支付的费用&trade_type=JSAPI"
stringSignTemp=stringA+"&key=就是api_key"
paysign=hashlib.md5(stringSignTemp.encode('utf-8')).hexdigest().upper()
其中nonce_str就是随机生成一个字符串,不要超过32位,用户的ip地址,python通过下面代码获得:
ip = request.META['REMOTE_ADDR'] 

获取paysign后,我们就可以设置要传的XML了:
pay_xml=""+appid+""+body+""+mch_id+""+nonceStr+"notify_url"+openid+""+out_trade_no+""+ip+""+fee+"JSAPI"+paysign+" "

然后传给统一支付API,返回一个xml:
req=urllib.request.Request("https://api.mch.weixin.qq.com/pay/unifiedorder")
req.add_header('User-Agent', 'Mozilla/6.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/8.0 Mobile/10A5376e Safari/8536.25')
unifiedorderXML=urllib.request.urlopen(req,data=pay_xml.encode('utf-8'))

获取prepay_id,并设置好前端要用的package参数:
tree = et.parse(unifiedorderXML)
root = tree.getroot()
psign=root.find('sign').text
prepay_id=root.find("prepay_id").text
package="prepay_id="+prepay_id

3.设置前端调起支付的支付签名
和获取prepay_id的签名方法类似,要把除了支付签名的所有前端调起支付需要用的参数加上api_key,通过hashlib.md5()来获取支付签名,前端支付签名获取代码如下:
stringB="appId=wx86a70b910e3ee10e&nonceStr="+s['nonceStr']+"&package="+package+"&signType=MD5&timeStamp="+str(s['timestamp'])
stringBSignTemp=stringB+"&key=51012419930123201521220107abcdef"
paysign=hashlib.md5(stringBSignTemp.encode('utf-8')).hexdigest().upper()


4.h5前端调起支付

function onBridgeReady(){
   WeixinJSBridge.invoke('getBrandWCPayRequest', {
                            "appId": "{{appid}}", // 公众号名称,由商户传入
                            "timeStamp": "{{sign.timestamp}}", // 时间戳
                            "nonceStr":"{{sign.nonceStr}}", // 随机串
                            "package": "{{package}}", // 扩展包
                            "signType": "MD5", // 微信签名方式:1.sha1
                            "paySign":"{{paysign}}"// 微信签名
                        }, function(res) {
                           
                                            if (res.err_msg == "get_brand_wcpay_request:ok") {
                                document.getElementById("myForm").submit();
                            } else {
                                alert('错误:' + res.err_msg);
                                 不需要显示任何东西,因为微信本身已经显示了,alert('错误:' + res.err_msg);
                            }
                            alert(res.err_msg);
                            
                        });

}
function pay(){
    

  if(typeof WeixinJSBridge=="undefined"){
    if(document.addEventListener){
      document.addEventListener('WeixinJSBridgeReady',onBridgeReady,false);
    }else if(document.attachEvent){
      document.attachEvent('WeixinJSBridgeReady',onBridgeReady);
      document.attachEvent('onWeixinJSBridgeReady',onBridgeReady);
    }
  } else {
    onBridgeReady();
  }
}

注意的地方,参数appId那个i是大写,如果写成小写了,会报get_brand_wcpay_request:fail错误的



你可能感兴趣的:(django,python,微信,支付)