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

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

一、准备环境

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

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

2、支持的支付方式有

3、备案域名

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

4、建一个Django项目。

一、扫码支付

点击“扫码支付”按官方文档配置好回调url(具体如何配置看官网)
先从公众号上获取APP_ID,APP_SECRECT,从商户平台上获取MCH_ID,API_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程序设计有所帮助。

(0)

相关推荐

  • Python 支付整合开发包的实现

    轻量级支付方式整合集成,实现支付与业务完全剥离,快速简单完成支付模块的开发 特性 屏蔽支付方式之间接入API和数据结构的差异,统一API和数据结构 支持支付类型横向扩展 统一异常处理 支持支付方式及功能 支付方式 pay_type=ali_pay pay_type=wx_pay 通用功能 电脑网站支付 手机网站支付 APP支付 异步通知校验 交易查询 交易取消 退款 退款查询 平台特有功能 微信JS支付 微信企业付款到零钱 使用说明 安装 # installation pip install a

  • python采用django框架实现支付宝即时到帐接口

    因工作需要研究了支付宝即时到帐接口,并成功应用到网站上,把过程拿出来分享. 即时到帐只是支付宝众多商家服务中的一个,表示客户付款,客户用支付宝付款,支付宝收到款项后,马上通知你,并且此笔款项与交易脱离关系,商家可以马上使用. 即时到帐只对企业客户服务,注册成功企业账号以后,申请签约即时到帐产品,大约3-5个工作日后,签约成功,可以马上进入集成产品阶段. 这个是支付宝提供的接口,有asp,c#,java,php四种语言的,每种语言提供GBK和UTF-8两种方案.另带一份支付宝的文档,这份文档我感觉

  • 利用Python开发微信支付的注意事项

    前言 微信支付是由微信及财付通联合推出的移动支付创新产品.如今,随着微信支付的全面开放,相关需求也越来越多,很多开发人员进行微信支付开发及商家申请微信支付时,面临着诸多疑惑. 要想开发顺利进行,首先要对业务流程有个清晰的认识.这里以微信公众号支付为例,因此也借用微信支付官方文档中的业务流程图: 接下来来关注几个开发过程中的关键点,包括: 1.生成商户订单与调用统一下单 API 2.微信服务器交互的数据格式 3.公众号支付下网页内通过 JS-API 调起支付 4.异步通知商户支付结果(回调) 一.

  • Python使用微信SDK实现的微信支付功能示例

    本文实例讲述了Python使用微信SDK实现的微信支付功能.分享给大家供大家参考,具体如下: 最近一段时间一直在搞微信平台开发,v3.37版本微信支付接口变化贼大,所以就看着php的demo移植为Python版,为了保持一致,所以接口方法基本都没有变,这样的好处就是不用写demo了,看着微信官方的demo照葫芦画瓢就可以了. 代码放到github下载地址:https://github.com/Skycrab/wzhifuSDK 还可以点击此处本站下载. 我主要测试了JsApi调用方式,其它的调用

  • Python+PIL实现支付宝AR红包

    本文实例为大家分享了Python+PIL处理支付宝AR红包的具体代码,供大家参考,具体内容如下 思路比较简单: 1.对图片进行锐化处理: 2.设(r_h, g_h, b_h)为支付宝遮罩黑条的RGB值,以此为中心,查找半径为Diff_radius的范围内所有的色值: 3.对每一行符合步骤2的像素点个数进行计数,若该数值超过某个临界值(如:图片宽度的一半),将其所在行替换为上一行非遮罩数据: 4.对处理后的图片高斯滤镜. 以下是python代码: from PIL import Image,Ima

  • Python提取支付宝和微信支付二维码的示例代码

    支付宝或者微信支付导出的收款二维码,除了二维码部分,还有很大一块背景图案,例如下面就是微信支付的收款二维码: 有时候我们仅仅只想要图片中间的方形二维码部分,为了提取出中间部分,我们可以使用图片处理软件,但图片处理软件不利于批处理,且学习也需要一定成本.本文将教你使用 Python 的图像处理库 pillow,轻松批量提取图片中间的方形二维码部分. 提取思路 以微信支付收款码图片为例: 分析图片我们可以看到,二维码位于白色背景中,而白色背景又位于绿色背景上.我们以图片左上角为坐标原点,横向为 x

  • python实现支付宝当面付(扫码支付)功能

    本文实例为大家分享了python实现支付宝当面付示的具体代码,供大家参考,具体内容如下 一.配置信息准备 登录蚂蚁金服开放平台:https://open.alipay.com/platform/home.htm 开发资料阅读:https://docs.open.alipay.com/194/106078 创建好应用,配置好密钥等信息后,就可以开发了. 二.开发支付宝支付工具类 1:相关配置信息 # ========支付相关配置信息=========== ALIPAY_INPUT_CHARSET

  • 利用Python的Flask框架来构建一个简单的数字商品支付解决方案

    作为一个程序员,我有时候忘了自己所具有的能力.当事情没有按照你想要的方式发展时,却很容易忘记你有能力去改变它.昨天,我意识到,我已经对我所出售的书的付款处理方式感到忍无可忍了.我的书完成后,我使用了三个不同的数字商品支付处理器,在对它们三个都感到不满后,我用Python和Flask,两个小时的时间写出了我自己的解决方案.没错!两个小时!现在,这个系统支撑着我的书籍付费流程,整个过程难以置信的简单,你可以在20秒内购买书籍并开始阅读. 往下看,看我是如何在一夜之间完成我自己的数字商品支付解决方案的

  • Python tkinter模块中类继承的三种方式分析

    本文实例讲述了Python tkinter模块中类继承的三种方式.分享给大家供大家参考,具体如下: tkinter class继承有三种方式. 提醒注意这几种继承的运行方式 一.继承 object 1.铺tk.Frame给parent: 说明: self.rootframe = tk.Frame(parent) tk.Label(self.rootframe) import tkinter as tk class MyApp(object): def __init__(self, parent)

  • 使用 Python 实现文件递归遍历的三种方式

    今天有个脚本需要遍历获取某指定文件夹下面的所有文件,我记得很早前也实现过文件遍历和目录遍历的功能,于是找来看一看,嘿,不看不知道,看了吓一跳,原来之前我竟然用了这么搓的实现. 先发出来看看: def getallfiles(dir): """遍历获取指定文件夹下面所有文件""" if os.path.isdir(dir): filelist = os.listdir(dir) for ret in filelist: filename = dir

  • 判断python对象是否可调用的三种方式及其区别详解

    查找资料,基本上判断python对象是否为可调用的函数,有三种方法 使用内置的callable函数 callable(func) 用于检查对象是否可调用,返回True也可能调用失败,但是返回False一定不可调用. 官方文档:https://docs.python.org/3/library/functions.html?highlight=callable#callable 判断对象类型是否是FunctionType type(func) is FunctionType # 或者 isinst

  • Python Selenium 设置元素等待的三种方式

    Selenium 设置元素等待的三种方式 1. sleep 强制等待     2. implicitly_wait() 隐性等待     3. WebDriverWait()显示等待 三种方式的优缺点 1. sleep 强制等待 from selenium import webdriver from time import sleep driver = webdriver.Chrome() sleep(2) #设置等待2秒钟 driver.get('http://www.baidu.com')

  • python中requests模拟登录的三种方式(携带cookie/session进行请求网站)

    一,cookie和session的区别 cookie在客户的浏览器上,session存在服务器上 cookie是不安全的,且有失效时间 session是在cookie的基础上,服务端设置session时会向浏览器发送设置一个设置cookie的请求,这个cookie包括session的id当访问服务端时带上这个session_id就可以获取到用户保存在服务端对应的session 二,爬虫处理cookie和session 带上cookie和session的好处: 能够请求到登录后的界面 带上cook

  • 详解Python进行数据相关性分析的三种方式

    目录 相关性实现 NumPy 相关性计算 SciPy 相关性计算 Pandas 相关性计算 线性相关实现 线性回归:SciPy 实现 等级相关 排名:SciPy 实现 等级相关性:NumPy 和 SciPy 实现 等级相关性:Pandas 实现 相关性的可视化 带有回归线的 XY 图 相关矩阵的热图 matplotlib 相关矩阵的热图 seaborn 相关性实现 统计和数据科学通常关注数据集的两个或多个变量(或特征)之间的关系.数据集中的每个数据点都是一个观察值,特征是这些观察值的属性或属性.

  • 详解Python获取线程返回值的三种方式

    目录 方法一 方法二 方法三 最后的话 提到线程,你的大脑应该有这样的印象:我们可以控制它何时开始,却无法控制它何时结束,那么如何获取线程的返回值呢?今天就分享一下自己的一些做法. 方法一 使用全局变量的列表,来保存返回值 ret_values = [] def thread_func(*args):     ...     value = ...     ret_values.append(value) 选择列表的一个原因是:列表的 append() 方法是线程安全的,CPython 中,GI

  • 命令行运行Python脚本时传入参数的三种方式详解

    如果在运行python脚本时需要传入一些参数,例如gpus与batch_size,可以使用如下三种方式. python script.py 0,1,2 10 python script.py -gpus=0,1,2 --batch-size=10 python script.py -gpus=0,1,2 --batch_size=10 这三种格式对应不同的参数解析方式,分别为sys.argv, argparse, tf.app.run, 前两者是python自带的功能,最后一个是tensorfl

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

    本文实例讲述了Python实现的微信支付方式.分享给大家供大家参考,具体如下: 一.准备环境 1.要有微信公众号,商户平台账号 https://pay.weixin.qq.com/wiki/doc/api/index.html 2.支持的支付方式有 3.备案域名 选择扫码支付,如果使用模式二则不需要域名,只需要可访问的ip地址就行. 4.建一个Django项目. 一.扫码支付 点击"扫码支付"按官方文档配置好回调url(具体如何配置看官网) 先从公众号上获取APP_ID,APP_SEC

  • Python 作为小程序后端的三种实现方法(推荐)

    目录 方法一.微信的云托管 方法二.微信的云函数中转 方法三:自建服务器,备案域名 最后的话 参考资料 微信的小程序是一个很不错的体验,简单,上手快,这几天也在学习使用小程序,自己总结了三种用 Python 作为小程序后端的方式,供你参考. 方法一.微信的云托管 优点:不需要购买服务器,不需要域名备案,按使用量计费,DevOps 自动化,安全鉴权,适合没有运维经验的人. 缺点:费用这块,肯定是比自建服务器费用略高的.就像同一车型,自动挡的车比手动挡的车更贵一样. 所谓云托管,就是一个 Docke

随机推荐