import hashlib
import random
import string
import urllib
import xml.etree.ElementTree as et
import time
import requests
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36',
}
class WeChatConfig(object):
appid = '微信appid'
AppSecret = '微信AppSecret'
mch_id = '微信商户id'
api_key = '微信支付密钥'
def get_access_token():
"""
jssdk 刷新accesstoken的方法
微信基础接口所需的 accesstoken
:param appid:
:param secret:
:
:return:
"""
appid = WeChatConfig.appid
secret = WeChatConfig.AppSecret
url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' + \
appid + '&secret=' + secret
html = requests.get(url, headers=headers).text
m = eval(html)
return m
def get_open_id_token(APPID, SECRET, CODE):
"""
通过前端传的code 和 WeChatConfig中的基本信息 来获取用户的openid还有一个网页授权的accesstoken
"""
url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid=' + APPID + \
'&secret=' + SECRET + '&code=' + CODE + '&grant_type=authorization_code'
html = requests.get(url, headers=headers)
html_response = html.json()
return html_response
def get_user_info2(access_token, openid):
"""
这个access_token是基础accessToken
通过 openid 和 基础接口的accesstoken 来获取用户信息 和下面的get_user_info不同的是 这个更加详细
:param access_token:
:param openid:
:return:
微信公众平台开发文档介绍:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839
"""
url = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang=zh_CN'.format(access_token,
openid)
html = requests.get(url, headers=headers)
html.encoding = 'utf-8'
html_response = html.json()
return html_response
def get_user_info(access_token, openid):
"""
这个access_token是网页授权 获取用户信息
:param access_token:
:param openid:
:return:
微信公众平台开发文档介绍:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
"""
url = 'https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN' % (access_token, openid)
html = requests.get(url, headers=headers)
html.encoding = 'utf-8'
html_response = html.json()
return html_response
def get_ticket(access_token):
"""
:param access_token: 基础accesstoken
:return:
"""
url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?' \
'access_token=' + access_token + '&type=jsapi'
html = requests.get(url, headers=headers).text
m = eval(html)
return m
def get_sign(ticket, url):
"""
前端调用jssdk所需要的签名
"""
return_dict = {}
timestamp = int(time.time() * 1000)
noncestr = ''.join(random.sample(string.ascii_letters + string.digits, 8))
sign = 'jsapi_ticket=' + ticket + '&noncestr=' + noncestr + '×tamp=' + str(
timestamp) + '&url=' + url
sha = hashlib.sha1(sign.encode('utf-8'))
encrypts = sha.hexdigest()
return_dict = {"timestamp": timestamp, "nonceStr": noncestr,
"signature": encrypts, "appId": WeChatConfig.appid}
return return_dict
def get_Package(body,
notify_url,
openid,
spbill_create_ip,
total_fee,
out_trade_no,
):
"""
前端调起微信H5支付所需要的参数
这里获取的是 prepay_id
"""
appid = WeChatConfig.appid
mch_id = WeChatConfig.mch_id
api_key = WeChatConfig.api_key
nonce_str = ''.join(random.sample(
string.ascii_letters + string.digits, 32))
# timeStamp = time.time()
# out_trade_no = "{0}{1}".format(WeChatConfig.appid, int(timeStamp * 100))
stringA = "appid=" + appid + \
"&body=" + body + \
"&mch_id=" + mch_id + \
"&nonce_str=" + nonce_str + \
"¬ify_url=" + notify_url + \
"&openid=" + openid + \
"&out_trade_no=" + out_trade_no + \
"&spbill_create_ip=" + spbill_create_ip + \
"&total_fee=" + total_fee + \
"&trade_type=JSAPI"
stringSignTemp = stringA + "&key=" + api_key # api-key未知
paySign = hashlib.md5(stringSignTemp.encode('utf-8')).hexdigest().upper()
# print('paySign=', paySign)
PayXml = "<xml>\
<appid>" + appid + "</appid>\
<body>" + body + "</body>\
<mch_id>" + mch_id + "</mch_id>\
<nonce_str>" + nonce_str + "</nonce_str>\
<notify_url>" + notify_url + "</notify_url>\
<openid>" + openid + "</openid>\
<out_trade_no>" + out_trade_no + "</out_trade_no>\
<spbill_create_ip>" + spbill_create_ip + "</spbill_create_ip>\
<total_fee>" + total_fee + "</total_fee>\
<trade_type>JSAPI</trade_type>\
<sign>" + paySign + "</sign>\
</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=PayXml.encode('utf-8'))
tree = et.parse(unifiedorderXML)
root = tree.getroot()
# psign = root.find('sign').text
prepay_id = root.find("prepay_id").text
package = "prepay_id=" + prepay_id
return package
def get_PaySign(package):
"""
将 要传给前端的数据全部打包发给前端
"""
timestamp = int(time.time() * 1000)
noncestr = ''.join(random.sample(string.ascii_letters + string.digits, 8))
stringB = "appId=" + WeChatConfig.appid + "&nonceStr=" + noncestr + "&package=" + package + "&signType=MD5&timeStamp=" + str(
timestamp)
stringBSignTemp = stringB + "&key={0}".format(WeChatConfig.api_key)
paysign = hashlib.md5(stringBSignTemp.encode('utf-8')).hexdigest().upper()
# 生成微信支付签名
Payment = {}
Payment['timestamp'] = timestamp
Payment['noncestr'] = noncestr
Payment['paySign'] = paysign
Payment['package'] = package
return Payment
以上是调用微信接口相关
关于俩个accesstoken和俩个调用微信用户信息的接口大家可以看下这篇文章
微信获取用户信息的两个接口和两个ACCESS_TOKEN
关于微信支付 我也是通过前人的总结了解的 如下
python+h5微信支付总结
关于如何储存 基础accesstoken的方法
本人是通过数据库拉取有效期内的accesstoken
新建一张model
class AccessToken(models.Model):
# access_token # 存放access_token
# expires # 存放毫秒数
# update_time # 更新时间戳
access_token = models.CharField(max_length=255, null=True, blank=True, verbose_name='基础accessToken')
expires = models.IntegerField(default=7200, verbose_name='可存放的时间')
update_time = models.IntegerField(null=True, blank=True, verbose_name='更新时间')
class Meta:
verbose_name = '微信accesstoken记录表'
verbose_name_plural = '微信accesstoken记录表'
db_table = 'WCaccesstoken'
def __str__(self):
return self.access_token
如何验证 accesstoken是否有效
import time
def send_accesstoken():
try:
accesstoken = AccessToken.objects.get(id=1)
update_time = accesstoken.update_time
now_time = int(time.time())
if update_time < now_time:
# 验证是否过期
M_accesstoken = get_access_token()
access_token = M_accesstoken['access_token']
accesstoken.access_token = access_token
_updatetime = int(time.time()) + 7200
# 更新过期时间
accesstoken.update_time = _updatetime
accesstoken.save()
return access_token
else:
return accesstoken.access_token
except:
M_accesstoken = get_access_token()
access_token = M_accesstoken['access_token']
_accesstoken = AccessToken()
_accesstoken.access_token = access_token
_updatetime = int(time.time()) + 7200
_accesstoken.update_time = _updatetime
_accesstoken.save()
return access_token