django 调用微信接口(微信支付、微信用户信息)

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 + '&timestamp=' + 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 + \
              "&notify_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

猜你喜欢

转载自blog.csdn.net/qq_33042187/article/details/78874550
今日推荐