Python实现的微信支付方式总结【三种方式】

 更新时间:2019年04月13日 13:53:27   作者:微信1257309054  
这篇文章主要介绍了Python实现的微信支付方式,结合实例形式总结分析了Python实现的三种微信支付方式及相关操作步骤、原理、注意事项,需要的朋友可以参考下

本文实例讲述了Python实现的微信支付方式。分享给大家供大家参考,具体如下:

一、准备环境

1、要有微信公众号,商户平台账号

https://pay.weixin.qq.com/wiki/doc/api/index.html

2、支持的支付方式有

3、备案域名

选择扫码支付,如果使用模式二则不需要域名,只需要可访问的ip地址就行。

4、建一个Django项目。

一、扫码支付

点击“扫码支付”按官方文档配置好回调url(具体如何配置看官网)
先从公众号上获取APP_IDAPP_SECRECT,从商户平台上获取MCH_IDAPI_KEY

1、使用模式一生成支付二维码

这个二维码是没有时间限制的。

create_qrcode.html

创建二维码页面

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>生成扫码支付二维码</title>
</head>
<body>
<form method="post" action="/wxpay/QRcode/" >
输入手机号:<input name="phone"/>
<input id="submit" type="submit" value="生成二维码">
  <br>
  {% if img_url %}
    <img src="{{ img_url }}" style="width: 200px;height: 200px"/>
  {% endif %}
<br>
{{ url }}
</form>
</body>
</html>

pay_settings.py

#微信支付配置
# ========支付相关配置信息===========
import random
import time
import hashlib
from random import Random
import qrcode
from bs4 import BeautifulSoup
APP_ID = "xxx" # 你公众账号上的appid
MCH_ID = "xxx" # 你的商户号
API_KEY = "xxx" # 微信商户平台(pay.weixin.qq.com) -->账户设置 -->API安全 -->密钥设置,设置完成后把密钥复制到这里
APP_SECRECT = "xxx"
UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder" # 该url是微信下单api
NOTIFY_URL = "http://xxx/" # 微信支付结果回调接口,需要改为你的服务器上处理结果回调的方法路径
CREATE_IP = 'xxx' # 你服务器的IP
def random_str(randomlength=8):
  """
  生成随机字符串
  :param randomlength: 字符串长度
  :return:
  """
  str = ''
  chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
  length = len(chars) - 1
  random = Random()
  for i in range(randomlength):
    str+=chars[random.randint(0, length)]
  return str
def order_num(phone):
  """
  生成扫码付款订单号
  :param phone: 手机号
  :return:
  """
  local_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
  result = phone + 'T' + local_time + random_str(5)
  return result
def get_sign(data_dict, key):
  # 签名函数,参数为签名的数据和密钥
  params_list = sorted(data_dict.items(), key=lambda e: e[0], reverse=False) # 参数字典倒排序为列表
  params_str = "&".join(u"{}={}".format(k, v) for k, v in params_list) + '&key=' + key
  # 组织参数字符串并在末尾添加商户交易密钥
  md5 = hashlib.md5() # 使用MD5加密模式
  md5.update(params_str.encode('utf-8')) # 将参数字符串传入
  sign = md5.hexdigest().upper() # 完成加密并转为大写
  return sign
def trans_dict_to_xml(data_dict): # 定义字典转XML的函数
  data_xml = []
  for k in sorted(data_dict.keys()): # 遍历字典排序后的key
    v = data_dict.get(k) # 取出字典中key对应的value
    if k == 'detail' and not v.startswith('<![CDATA['): # 添加XML标记
      v = '<![CDATA[{}]]>'.format(v)
    data_xml.append('<{key}>{value}</{key}>'.format(key=k, value=v))
  return '<xml>{}</xml>'.format(''.join(data_xml)).encode('utf-8') # 返回XML,并转成utf-8,解决中文的问题
def trans_xml_to_dict(data_xml):
  soup = BeautifulSoup(data_xml, features='xml')
  xml = soup.find('xml') # 解析XML
  if not xml:
    return {}
  data_dict = dict([(item.name, item.text) for item in xml.find_all()])
  return data_dict
def wx_pay_unifiedorde(detail):
  """
  访问微信支付统一下单接口
  :param detail:
  :return:
  """
  detail['sign'] = get_sign(detail, API_KEY)
  # print(detail)
  xml = trans_dict_to_xml(detail) # 转换字典为XML
  response = requests.request('post', UFDODER_URL, data=xml) # 以POST方式向微信公众平台服务器发起请求
  # data_dict = trans_xml_to_dict(response.content) # 将请求返回的数据转为字典
  return response.content
def pay_fail(err_msg):
  """
  微信支付失败
  :param err_msg: 失败原因
  :return:
  """
  data_dict = {'return_msg': err_msg, 'return_code': 'FAIL'}
  return trans_dict_to_xml(data_dict)
def create_qrcode(phone,url):
  """
  生成扫码支付二维码
  :param phone: 手机号
  :param url: 支付路由
  :return:
  """
  img = qrcode.make(url) # 创建支付二维码片
  # 你存放二维码的地址
  img_url = r'media/QRcode' + '/' + phone + '.png'
  img.save(img_url)
  return img_url

views.py

from django.shortcuts import render
from django.http import HttpResponse
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from pay_settings.py import *
class Wxpay_QRccode(View):
  """
  生成微信支付二维码
  """
  def get(self, request, *args, **kwargs):
    return render(request, 'create_qrcode.html')
  def post(self, request, *args, **kwargs):
    """
    # 生成可扫码支付的二维码
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    phone = request.data.get('phone', None)
    if not phone:
      return HttpResponse('手机号获取失败')
    paydict = {
      'appid': APP_ID,
      'mch_id': MCH_ID,
      'nonce_str': random_str(phone),
      'product_id': phone, # 商品id,可自定义
      'time_stamp': int(time.time()),
    }
    paydict['sign'] = get_sign(paydict, API_KEY)
    url = "weixin://wxpay/bizpayurl?appid=%s&mch_id=%s&nonce_str=%s&product_id=%s&time_stamp=%s&sign=%s" \
       % (paydict['appid'], paydict['mch_id'], paydict['nonce_str'], paydict['product_id'], paydict['time_stamp'], paydict['sign'])
    # 可以直接在微信中点击该url,如果有错误,微信会弹出提示框,如果是扫码,如果失败,什么提示都没有,不利于调试
    print(url)
    # 创建二维码
    img_url = create_qrcode(url)
    return render(request, 'create_qrcode.html', context={'img_url': img_url})
@method_decorator(csrf_exempt, name='dispatch')
class Wxpay_ModelOne_pay(View):
  """
  使用微信扫一扫扫描二维码,微信系统会自动回调此路由,Post请求
  """
  def post(self, request, *args, **kwargs):
    """
    扫描二维码后,微信系统回调的地址处理
    微信传来的参数格式经trans_xml_to_dict()转成字典
    {'openid': 'xxx',
     'is_subscribe': 'Y',
     'mch_id': 'xxx',
     'nonce_str': 'xxx',
     'sign': 'xxx',
     'product_id': 'xxx',
     'appid': 'xxx'}
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    data_dict = trans_xml_to_dict(request.body) # 回调数据转字典
    sign = data_dict.pop('sign') # 取出签名
    key = API_KEY # 商户交易密钥
    back_sign = get_sign(data_dict, key) # 计算签名
    if sign == back_sign: # 验证签名是否与回调签名相同
      total_fee = 1 # 付款金额,单位是分,必须是整数
      params = {
        'appid': APP_ID, # APPID
        'mch_id': MCH_ID, # 商户号
        'nonce_str': random_str(16), # 随机字符串
        'out_trade_no': order_num(data_dict['product_id']), # 订单编号
        'total_fee': total_fee, # 订单总金额
        'spbill_create_ip': CREATE_IP, # 发送请求服务器的IP地址
        'notify_url': NOTIFY_URL,
        'body': 'xxx公司',  # 商品描述
        'detail': 'xxx商品', # 商品详情
        'trade_type': 'NATIVE', # 扫码支付类型
      }
      # 调用微信统一下单支付接口url
      notify_result = wx_pay_unifiedorde(params)
      #print(trans_xml_to_dict(notify_result))
      return HttpResponse(notify_result)
    return HttpResponse(pay_fail('交易信息有误,请重新扫码'))

2、使用模式二生成支付二维码

这个二维码是有时间限制的。

模式二与模式一相比,流程更为简单,不依赖设置的回调支付URL。商户后台系统先调用微信支付的统一下单接口,微信后台系统返回链接参数code_url,商户后台系统将code_url值生成二维码图片,用户使用微信客户端扫码后发起支付。注意:code_url有效期为2小时,过期后扫码不能再发起支付。具体流程看微信公众号。

主体代码:

pay_settings.py

#微信支付配置
# ========支付相关配置信息===========
import random
import time
import hashlib
from random import Random
from bs4 import BeautifulSoup
APP_ID = "xxx" # 你公众账号上的appid
MCH_ID = "xxx" # 你的商户号
API_KEY = "xxx" # 微信商户平台(pay.weixin.qq.com) -->账户设置 -->API安全 -->密钥设置,设置完成后把密钥复制到这里
APP_SECRECT = "xxx"
UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder" # 该url是微信下单api
NOTIFY_URL = "http://xxx/" # 微信支付结果回调接口,需要改为你的服务器上处理结果回调的方法路径
CREATE_IP = 'xxx' # 你服务器的IP
def get_sign(data_dict, key): 
  """
  签名函数
  :param data_dict: 需要签名的参数,格式为字典
  :param key: 密钥 ,即上面的API_KEY
  :return: 字符串
  """
  params_list = sorted(data_dict.items(), key=lambda e: e[0], reverse=False) # 参数字典倒排序为列表
  params_str = "&".join(u"{}={}".format(k, v) for k, v in params_list) + '&key=' + key
  # 组织参数字符串并在末尾添加商户交易密钥
  md5 = hashlib.md5() # 使用MD5加密模式
  md5.update(params_str.encode('utf-8')) # 将参数字符串传入
  sign = md5.hexdigest().upper() # 完成加密并转为大写
  return sign
def order_num(phone):
  """
  生成扫码付款订单号
  :param phone: 手机号
  :return:
  """
  local_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
  result = phone + 'T' + local_time + random_str(5)
  return result
def random_str(randomlength=8):
  """
  生成随机字符串
  :param randomlength: 字符串长度
  :return: 
  """
  strs = ''
  chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
  length = len(chars) - 1
  random = Random()
  for i in range(randomlength):
    strs += chars[random.randint(0, length)]
  return strs
def trans_dict_to_xml(data_dict):
  """
  定义字典转XML的函数
  :param data_dict: 
  :return: 
  """
  data_xml = []
  for k in sorted(data_dict.keys()): # 遍历字典排序后的key
    v = data_dict.get(k) # 取出字典中key对应的value
    if k == 'detail' and not v.startswith('<![CDATA['): # 添加XML标记
      v = '<![CDATA[{}]]>'.format(v)
    data_xml.append('<{key}>{value}</{key}>'.format(key=k, value=v))
  return '<xml>{}</xml>'.format(''.join(data_xml)) # 返回XML
def trans_xml_to_dict(data_xml):
  """
  定义XML转字典的函数
  :param data_xml: 
  :return: 
  """
  soup = BeautifulSoup(data_xml, features='xml')
  xml = soup.find('xml') # 解析XML
  if not xml:
    return {}
  data_dict = dict([(item.name, item.text) for item in xml.find_all()])
  return data_dict

views.py

import qrcode
from django.shortcuts import render
from pay_settings import *
from django.http import HttpResponse
from django.views import View
class WXPayView(View):
  def get(self,request):
    # 在info.html有一个按钮,点击后跳转到这个类的post()中,具体urls.py设置不详述
    return render(request, 'info.html')
  def post(self,request):
    phone = request.POST.get('phone','')
    if not phone:
      return render(request, 'info.html', {'err_msg': '获取手机号失败'})
    data_dict = wxpay(phone)
    if data_dict.get('return_code') == 'SUCCESS': # 如果请求成功
      qrcode_name = phone + '.png' # 二维码图片名称
      img = qrcode.make(data_dict.get('code_url')) # 创建支付二维码片
      img.save(r'static' + '/' + qrcode_name) 
      return render(request, 'qrcode.html', {'qrcode_img': qrcode_name})
    return render(request, 'info.html', {'err_msg': '获取微信的code_url失败'})
def wxpay(phone):
  nonce_str = random_str() # 拼接出随机的字符串即可,我这里是用 时间+随机数字+5个随机字母
  total_fee = 1 # 付款金额,单位是分,必须是整数
  params = {
    'appid': APP_ID, # APPID
    'mch_id': MCH_ID, # 商户号
    'nonce_str': nonce_str,  # 随机字符串
    'out_trade_no': order_num(phone), # 订单编号,可自定义
    'total_fee': total_fee, # 订单总金额
    'spbill_create_ip': CREATE_IP, # 自己服务器的IP地址
    'notify_url': NOTIFY_URL, # 回调地址,微信支付成功后会回调这个url,告知商户支付结果
    'body': 'xxx公司', # 商品描述
    'detail': 'xxx商品', # 商品描述
    'trade_type': 'NATIVE', # 扫码支付类型
  }
  sign = get_sign(params,API_KEY) # 获取签名
  params['sign'] = sign # 添加签名到参数字典
  # print(params)
  xml = trans_dict_to_xml(params) # 转换字典为XML
  response = requests.request('post', settings._UFDODER_URL, data=xml) # 以POST方式向微信公众平台服务器发起请求
  data_dict = trans_xml_to_dict(response.content) # 将请求返回的数据转为字典
  return data_dict
class Wxpay_Result(View):
  """
  微信支付结果回调通知路由
  """
  def get(self, request, *args, **kwargs):
    machine_code = request.GET.get('machine_code', '获取机器编号失败')
    # 返回支付成功页面,可自定义
    return render(request, 'zfcg.html', {'machine': {'machine_code': machine_code}})
  def post(self, request, *args, **kwargs):
    """
    微信支付成功后会自动回调
    返回参数为:
    {'mch_id': '',
    'time_end': '',
    'nonce_str': '',
    'out_trade_no': '',
    'trade_type': '',
    'openid': '',
     'return_code': '',
     'sign': '',
     'bank_type': '',
     'appid': '',
     'transaction_id': '',
     'cash_fee': '',
     'total_fee': '',
     'fee_type': '', '
     is_subscribe': '',
     'result_code': 'SUCCESS'}
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    data_dict = trans_xml_to_dict(request.body) # 回调数据转字典
    # print('支付回调结果', data_dict)
    sign = data_dict.pop('sign') # 取出签名
    back_sign = get_sign(data_dict, API_KEY) # 计算签名
    # 验证签名是否与回调签名相同
    if sign == back_sign and data_dict['return_code'] == 'SUCCESS':
      '''
      检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。
      '''
      print('微信支付成功会回调!')
      # 处理支付成功逻辑
      # 返回接收结果给微信,否则微信会每隔8分钟发送post请求
      return HttpResponse(trans_dict_to_xml({'return_code': 'SUCCESS', 'return_msg': 'OK'}))
    return HttpResponse(trans_dict_to_xml({'return_code': 'FAIL', 'return_msg': 'SIGNERROR'}))

二、使用JsAPI发起微信支付

在微信公众号中左下角 设置->公众号设置->功能设置,把业务域名,js接口安全域名,网页授权域名设置好。

用户在微信中点击一个路由Url(可把这个url封装成二维码).在后台中的views.py中的WxJsAPIPay类中使用get()函数处理用户的请求,先获取用户的openid,然后调用微信统一下单接口,获取prepay_id,具体看官网。

wx_js_pay.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" id="vp"/>
{#    <script type="text/javascript" src="/static/js/rem.js"></script>#}
{#    <link rel="stylesheet" type="text/css" href="/static/css/base.css" rel="external nofollow" />#}
{#    <link rel="stylesheet" type="text/css" href="/static/css/index.css" rel="external nofollow" />#}
  </head>
  <body>
    <div class="bigbox">
      <div class="top">
        <span>订单详情</span>
      </div>
      <div class="zhong">
      </div>
      <div class="zhifu">
        <button class="btn" type="button" onclick="javascript:callpay();return false;">立即支付</button>
      </div>
    </div>
<script src="https://cdn.bootcss.com/jquery/1.12.1/jquery.js"></script>
<script type="text/javascript">
  //调用微信JS api 支付
  function onBridgeReady() {
    WeixinJSBridge.invoke(
      'getBrandWCPayRequest',
      {
        appId: "{{ params.appid }}",    //公众号名称,由商户传入
        timeStamp: "{{ params.timeStamp }}", //时间戳,自1970年以来的秒数
        nonceStr: "{{ params.nonceStr }}", //随机串
        package: "prepay_id={{ params.prepay_id }}", //预支付id
        signType: "MD5", //微信签名方式
        paySign: "{{ params.sign }}"   //微信签名
      },
      function (res) {
        //支付成功后返回 get_brand_wcpay_request:ok
        if (res.err_msg == "get_brand_wcpay_request:ok") {
          // 跳转到支付成功的页面
          window.location.href = '#';
          {#alert('支付成功');#}
        } else if (res.err_msg == "get_brand_wcpay_request:cancel") {
          alert("您已取消支付!");
          {#alert({{ params.machine_code }});#}
          {#window.location.href = '';#}
        } else if (res.err_msg == "get_brand_wcpay_request:fail") {
          $.each(res, function(key,value){
            alert(value);
            });
          alert("支付失败!");
        }
      }
    );
  }
  function callpay() {
    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();
    }
  }
</script>
  </body>
</html>

pay_settings.py

# encoding: utf-8
import hashlib
import time
import requests
from collections import OrderedDict
from random import Random
from bs4 import BeautifulSoup
APP_ID = "xxx" # 公众账号appid
MCH_ID = "xxx" # 商户号
API_KEY = "xxx" # 微信商户平台(pay.weixin.qq.com) -->账户设置 -->API安全 -->密钥设置,设置完成后把密钥复制到这里
APP_SECRECT = "xxx"
UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder" # url是微信下单api
NOTIFY_URL = "http://xxx/wxpay/pay_result/" # 微信支付结果回调接口,需要你自定义
CREATE_IP = 'xxx' # 你服务器上的ip
# 生成随机字符串
def random_str(randomlength=8):
  """
  生成随机字符串
  :param randomlength: 字符串长度
  :return:
  """
  str = ''
  chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
  length = len(chars) - 1
  random = Random()
  for i in range(randomlength):
    str+=chars[random.randint(0, length)]
  return str
def order_num(phone):
  """
  生成扫码付款订单,
  :param phone: 
  :return:
  """
  local_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))
  result = phone + 'T' + local_time + random_str(5)
  return result
def get_sign(data_dict, key):
  # 签名函数,参数为签名的数据和密钥
  params_list = sorted(data_dict.items(), key=lambda e: e[0], reverse=False) # 参数字典倒排序为列表
  params_str = "&".join(u"{}={}".format(k, v) for k, v in params_list) + '&key=' + key
  # 组织参数字符串并在末尾添加商户交易密钥
  md5 = hashlib.md5() # 使用MD5加密模式
  md5.update(params_str.encode('utf-8')) # 将参数字符串传入
  sign = md5.hexdigest().upper() # 完成加密并转为大写
  return sign
def trans_dict_to_xml(data_dict): # 定义字典转XML的函数
  data_xml = []
  for k in sorted(data_dict.keys()): # 遍历字典排序后的key
    v = data_dict.get(k) # 取出字典中key对应的value
    if k == 'detail' and not v.startswith('<![CDATA['): # 添加XML标记
      v = '<![CDATA[{}]]>'.format(v)
    data_xml.append('<{key}>{value}</{key}>'.format(key=k, value=v))
  return '<xml>{}</xml>'.format(''.join(data_xml)).encode('utf-8') # 返回XML,并转成utf-8,解决中文的问题
def trans_xml_to_dict(data_xml):
  soup = BeautifulSoup(data_xml, features='xml')
  xml = soup.find('xml') # 解析XML
  if not xml:
    return {}
  data_dict = dict([(item.name, item.text) for item in xml.find_all()])
  return data_dict
def wx_pay_unifiedorde(detail):
  """
  访问微信支付统一下单接口
  :param detail:
  :return:
  """
  detail['sign'] = get_sign(detail, API_KEY)
  # print(detail)
  xml = trans_dict_to_xml(detail) # 转换字典为XML
  response = requests.request('post', UFDODER_URL, data=xml) # 以POST方式向微信公众平台服务器发起请求
  # data_dict = trans_xml_to_dict(response.content) # 将请求返回的数据转为字典
  return response.content
def get_redirect_url():
  """
  获取微信返回的重定向的url
  :return: url,其中携带code
  """
  WeChatcode = 'https://open.weixin.qq.com/connect/oauth2/authorize'
  urlinfo = OrderedDict()
  urlinfo['appid'] = APP_ID
  urlinfo['redirect_uri'] = 'http://xxx/wxjsapipay/?getInfo=yes' # 设置重定向路由
  urlinfo['response_type'] = 'code'
  urlinfo['scope'] = 'snsapi_base' # 只获取基本信息
  urlinfo['state'] = 'mywxpay'  # 自定义的状态码
  info = requests.get(url=WeChatcode, params=urlinfo)
  return info.url
def get_openid(code,state):
  """
  获取微信的openid
  :param code:
  :param state:
  :return:
  """
  if code and state and state == 'mywxpay':
    WeChatcode = 'https://api.weixin.qq.com/sns/oauth2/access_token'
    urlinfo = OrderedDict()
    urlinfo['appid'] = APP_ID
    urlinfo['secret'] = APP_SECRECT
    urlinfo['code'] = code
    urlinfo['grant_type'] = 'authorization_code'
    info = requests.get(url=WeChatcode, params=urlinfo)
    info_dict = eval(info.content.decode('utf-8'))
    return info_dict['openid']
  return None
def get_jsapi_params(openid):
  """
  获取微信的Jsapi支付需要的参数
  :param openid: 用户的openid
  :return:
  """
  total_fee = 1 # 付款金额,单位是分,必须是整数
  params = {
    'appid': APP_ID, # APPID
    'mch_id': MCH_ID, # 商户号
    'nonce_str': random_str(16), # 随机字符串
    'out_trade_no': order_num('123'), # 订单编号,可自定义
    'total_fee': total_fee, # 订单总金额
    'spbill_create_ip': CREATE_IP, # 发送请求服务器的IP地址
    'openid': openid,
    'notify_url': NOTIFY_URL, # 支付成功后微信回调路由
    'body': 'xxx公司', # 商品描述
    'trade_type': 'JSAPI', # 公众号支付类型
  }
  # print(params)
  # 调用微信统一下单支付接口url
  notify_result = wx_pay_unifiedorde(params)
  params['prepay_id'] = trans_xml_to_dict(notify_result)['prepay_id']
  params['timeStamp'] = int(time.time())
  params['nonceStr'] = random_str(16)
  params['sign'] = get_sign({'appId': APP_ID,
                "timeStamp": params['timeStamp'],
                'nonceStr': params['nonceStr'],
                'package': 'prepay_id=' + params['prepay_id'],
                'signType': 'MD5',
                },
               API_KEY)
  return params

views.py

from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render
from django.views import View
from pay_settings import *
class WxJsAPIPay(View):
  def get(self, request, *args, **kwargs):
    """
    用户点击一个路由或者扫码进入这个views.py中的函数,首先获取用户的openid,
    使用jsapi方式支付需要此参数
    :param self:
    :param request:
    :param args:
    :param kwargs:
    :return:
    """
    getInfo = request.GET.get('getInfo', None)
    openid = request.COOKIES.get('openid', '')
    if not openid:
      if getInfo != 'yes':
      # 构造一个url,携带一个重定向的路由参数,
      # 然后访问微信的一个url,微信会回调你设置的重定向路由,并携带code参数
        return HttpResponseRedirect(get_redirect_url())
      elif getInfo == 'yes':
   # 我设置的重定向路由还是回到这个函数中,其中设置了一个getInfo=yes的参数
      # 获取用户的openid
        openid = get_openid(request.GET.get('code'), request.GET.get('state', ''))
        if not openid:
          return HttpResponse('获取用户openid失败')
        response = render_to_response('wx_js_pay.html', context={'params': get_jsapi_params(openid)})
        response.set_cookie('openid', openid, expires=60 * 60 * 24 *30)
        return response
      else:
        return HttpResponse('获取机器编码失败')
    else:
      return render(request, 'wx_js_pay.html', context={'params': get_jsapi_params(openid)})

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python数学运算技巧总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总

希望本文所述对大家Python程序设计有所帮助。

相关文章

  • 实例介绍Python中整型

    实例介绍Python中整型

    在本篇内容中我们通过实例分享了关于Python中整型的相关知识点内容,有兴趣的朋友们学习下。
    2019-02-02
  • python tarfile压缩包操作保姆级教程

    python tarfile压缩包操作保姆级教程

    TarFile类就是tar压缩包,其由member块组成, member块则包括header块和data块. 每个member以TarInfo对象形式描述. 所以TarFile就是TarInfo的序列
    2023-02-02
  • 关于pycharm 切换 python3.9 报错 ‘HTMLParser‘ object has no attribute ‘unescape‘ 的问题

    关于pycharm 切换 python3.9 报错 ‘HTMLParser‘ object has no attribu

    这篇文章主要介绍了pycharm 切换 python3.9 报错 ‘HTMLParser‘ object has no attribute ‘unescape‘ 解决,需要的朋友可以参考下
    2020-11-11
  • python+opencv实现车道线检测

    python+opencv实现车道线检测

    这篇文章主要为大家详细介绍了python+opencv实现车道线检测,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-02-02
  • Python实现各种邮件发送

    Python实现各种邮件发送

    这篇文章主要介绍了Python实现各种邮件发送,Python内置对SMTP的支持,可以发送纯文本邮件、HTML邮件以及带附件的邮件,下文详细实现过程需要的小伙伴可以参考一下
    2022-05-05
  • python3.4 将16进制转成字符串的实例

    python3.4 将16进制转成字符串的实例

    今天小编就为大家分享一篇python3.4 将16进制转成字符串的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-06-06
  • PyTorch模型容器与AlexNet构建示例详解

    PyTorch模型容器与AlexNet构建示例详解

    这篇文章主要为大家介绍了PyTorch模型容器与AlexNet构建示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • Python实现的文本对比报告生成工具示例

    Python实现的文本对比报告生成工具示例

    这篇文章主要介绍了Python实现的文本对比报告生成工具,涉及Python基于difflib模块实现对文本内容进行对比的相关操作技巧,需要的朋友可以参考下
    2018-05-05
  • Python基础之数据结构详解

    Python基础之数据结构详解

    这篇文章主要介绍了Python基础之数据结构详解,文中有非常详细的代码示例,对正在学习python基础的小伙伴们有非常好的帮助,需要的朋友可以参考下
    2021-04-04
  • Django多个app urls配置代码实例

    Django多个app urls配置代码实例

    这篇文章主要介绍了Django多个app urls配置代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11

最新评论