基于Python flask 框架的微信支付 全代码
前台代码忽略
需要了解flask 框架 尤其是 模板传参 和重定向 传参
###############################################《《各种需要用到的函数 不涉及到流程##############################
import hashlib
import time
import requests
from collections import OrderedDict
from random import Random
from bs4 import BeautifulSoup
import lxml
import requests
import jsonAPP_ID = '' # 公众账号appid
MCH_ID = '' # 商户号
API_KEY = '' # 微信商户平台(pay.weixin.qq.com) -->账户设置 -->API安全 -->密钥设置,设置完成后把密钥复制到这里
APP_SECRECT = ''
UFDODER_URL = '
https://api.mch.weixin.qq.com/pay/unifiedorder
' # url是微信下单api 这个不用改NOTIFY_URL = '' # 微信支付结果回调接口,需要你自定义
CREATE_IP = '' # 你服务器上的ip# 生成随机字符串
def random_str(randomlength=8):"""生成随机字符串:param randomlength: 字符串长度:return:"""str = ''chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'length = len(chars) - 1random = Random()for i in range(randomlength):str += chars[random.randint(0, length)]return str# 生成随机字符串 和上面的一样 这是我用来自定义订单号流水号的 out_trade_no
def random_num(randomlength=10):"""生成随机字符串:param randomlength: 字符串长度:return:"""str = ''chars = '1234567890'length = len(chars) - 1random = Random()for i in range(randomlength):str += chars[random.randint(0, length)]str_time=time.strftime("%Y%m%d%H%M%S", time.localtime())return str_time+strdef get_sign(data_dict, key): #这里是用 字典+key MD5加密 第一次用到 是用于 生成预支付订单 第二次用到 是用于接收微信支付成功验证 # 签名函数,参数为签名的数据和密钥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 signdef trans_dict_to_xml(data_dict): # 定义字典转XML的函数data_xml = []for k in sorted(data_dict.keys()): # 遍历字典排序后的keyv = data_dict.get(k) # 取出字典中key对应的valueif 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') # 解析XMLif not xml:return {}data_dict = dict([(item.name, item.text) for item in xml.find_all()])return data_dictdef wx_pay_unifiedorde(detail): # 返回的参数用于调用 微信JS_API detail['sign'] = get_sign(detail, API_KEY)print('访问微信支付统一下单接口detail[sign]')print(detail['sign'])xml = trans_dict_to_xml(detail) # 转换字典为XMLresponse = requests.request('post', UFDODER_URL, data=xml) # 以POST方式向微信公众平台服务器发起请求data_dict = trans_xml_to_dict(response.content) # 将请求返回的数据转为字典print('调用微信统一下单接口的返回值,用户组合param调用微信JSAPI')print(data_dict)return response.contentdef get_openid(code): #很多地方 都需要获得 OPENID 所以写了个函数 print("根据code获取openID code=:" + code)if code != None:url = " https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + APP_ID + "&secret=" + APP_SECRECT + "&code=" + code + "&grant_type=authorization_code"re_data = requests.get(url)data_dict = json.loads(re_data.text) # Json 格式字符换 转换成字典openid = data_dict['openid']print("获取openid:"+openid)return openidelse:return Falsedef jsapi_params(openid, total_fee): #支付流程 最总返回的参数 用于为调用前台JS_API提供参数"""获取微信的Jsapi支付需要的参数:param openid: 用户的openid:param total_fee: 用户的total_fee:return:"""# # 付款金额,单位是分,必须是整数params = {'appid': APP_ID, # APPID'mch_id': MCH_ID, # 商户号'nonce_str': random_str(16), # 随机字符串'out_trade_no': random_num(10), # 字符串时间+1234567890十位随机数'total_fee': total_fee, # 订单总金额'spbill_create_ip': CREATE_IP, # 发送请求服务器的IP地址'openid': openid,'notify_url': NOTIFY_URL, # 支付成功后微信回调路由'body': '供热费', # 商品描述'trade_type': 'JSAPI', # 公众号支付类型}print('调用微信统一下单支付接口')print(params)notify_result = wx_pay_unifiedorde(params)
#######################################################################################3params['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
###############################################各种需要用到的函数 不涉及到流程》》##############################
此处 说一下 微信支付成功验证
调用JSAPI支付成功会 微信会定期返回你支付参数 你需要验证签名 和 金额 确保不是第三方发送的伪代码
签名验证 :微信会定期请求以下你的路由 直到 你返回给他success 和 OK 为止 整个订单才算走完一个完整流程
用 微信返回的所有参数 除了(sign) +key 用Md5 加密 然后与 sign比较 如果相等 签名验证成功 然后再验证钱 金额 和你支付的金额是否相等(我支付的金额 在生成预支付订单时已经存在数据库里了 这里根据 订单号 取一下 ) 验证无误 返回success ok
很多人都卡在签名验证这里了 不知道怎么验证
@app.route('/wx_pay_result/', methods=['GET','POST'])
def wx_pay_result():#return trans_dict_to_xml({'return_code': 'SUCCESS', 'return_msg': 'OK'})if request.method == 'POST':data = request.dataprint('微信支付成功返回凭证')parameters=trans_xml_to_dict(data)print(parameters)parameters_sign=parameters['sign']del parameters['sign']sign=get_sign(parameters,API_KEY)print('MD5 验证签名:'+sign)if parameters['return_code'] == 'SUCCESS' and parameters['result_code'] == 'SUCCESS':print(parameters['out_trade_no'])if sign == parameters_sign:sql="select total_fee from trade_data where out_trade_no='"+parameters['out_trade_no']+"'"success, msg, count, list_data = mydb('mysql', 'select', sql)print(sql)print('费用对比')print(list_data[0][0])print(parameters['total_fee'])if int(list_data[0][0]) == int(parameters['total_fee']):sql = "update trade_data set return_code='%s',result_code='%s',status='验证无误,完成支付' where out_trade_no='%s'" % (parameters['return_code'], parameters['result_code'], parameters['out_trade_no'])success, msg, count, list_data = mydb('mysql', 'update', sql)print(sql)return trans_dict_to_xml({'return_code': 'SUCCESS', 'return_msg': 'OK'})else:return trans_dict_to_xml({'return_code': 'Fail', 'return_msg': 'Fail'})else:return trans_dict_to_xml({'return_code': 'Fail', 'return_msg': 'Fail'})else:sql = "update trade_data set return_code='%s',result_code='%s',status='服务端支付返回错误' where out_trade_no='%s'" % (parameters['return_code'], parameters['return_msg'], parameters['out_trade_no'])success, msg, count, list_data = mydb('mysql', 'update', sql)return trans_dict_to_xml({'return_code': 'FAIL', 'return_msg': 'FAIL'})
还有获取openid 是先获取code 然后用code获取openID 的 state 字段用来传参
点击按钮 获取code 授权 跳转到对应路由 用openID 处理流程
{"name": "业务办理","sub_button": [{"type": "view","name": "查询缴费","url": "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx0b1faae33de88d31&redirect_uri=http://www.apicenter.xyz/user_house_info_nobind/&response_type=code&scope=snsapi_base#wechat_redirect"},
@app.route('/user_house_info_nobind/', methods=['GET', 'POST']) #
def user_house_info_nobind():code = request.args.get("code")openid = get_openid(code)if openid != False:dict_json = {'success': True, 'msg': 'OK', 'count': 2,'data': [{'yhjfh': '123123123', 'yhmc': '', 'addr': '', 'sfmj': 66.88, 'grxz': '居民'},{'yhjfh': '3434343434', 'yhmc': '', 'addr': '松北路123号', 'sfmj': 77.88, 'grxz': '公企'}]}data = dict_json['data']count = dict_json['count']return render_template('user_house_info_nobind.html',data=data,count=count) #用模板渲染else:return "获取失败"
基于Python flask 框架的微信支付 全代码相关推荐
- 基于Python Flask框架+jquery Ajax技术实现的增删改查(CRUD)+Ajax的异步文件上传
运行界面(话不多说先上图) 运行之后的index界面,有登陆.注册功能 登陆界面,输入数据库中用户名.密码不为空且密码是加密的数据,进入main界面 注册界面,用的bootstrop的弹窗,用户名和密 ...
- 基于Python Flask框架的共享自习室预约系统的设计与实现-计算机毕业设计源码+LW文档
1.1选题背景 信息技术的发展改变了我们的生活方式,许多行业的管理模式发生了根本性改变,特别是零售业受到电子商务强烈的冲击,越来越多的人参与到网购中.许多传统行业逐渐凋零,蓬勃发展的信息技术带来了大量 ...
- python flask框架优点_python之全栈(Flask框架)
虚拟环境 虚拟环境顾名思义就是虚拟的,在这里面装任何软件都不会影响到其他的程序,类似与一个抽屉. 使用虚拟环境的好处是:让电脑中安装很多种解释器,并且互不影响 virtualenv的使用 安装virt ...
- 【25】数据可视化:基于 Echarts + Python Flask框架动态实时大屏范例 - 企业宣传
目录 效果展示 多主题样式 一. 确定需求方案 1.确定产品上线部署的屏幕分辨率 2.部署方式 二.整体架构设计 三.编码实现 (基于篇幅及可读性考虑,此处展示部分关键代码) 1.前端html代码 - ...
- [python]用flask框架搭建微信公众号的后台
用flask框架搭建微信公众号的后台 最近用python写了点爬虫,为了要让爬取的数据能够随时显示在我眼前,并实时根据我的指令返回数据.于是采用微信公众号做这个显示窗口,既能发送指令也能显示简单的相关 ...
- python Flask框架如何请求及返回数据——flask详细教程
python Flask框架如何请求及返回数据--flask详细教程 文章目录: 1 Flask介绍 1.1 Flask简单介绍 1.2 Flask相关资料信息 2 Flask快速入门 2.1 Fla ...
- python flask框架剖析_python flask框架实现传数据到js的方法分析
本文实例讲述了python flask框架实现传数据到js的方法.分享给大家供大家参考,具体如下: 首先要清楚后台和前端交互所采用的数据格式. 一般选JSON,因为和js完美贴合. 后台返回的数据进行 ...
- Python Flask框架
Python Flask框架 Flask框架简介 安装过程 Falsk程序的运行过程 基本语法/结构 如有错误,请指正 Flask框架简介 Flask是一个轻量级的可定制框架,使用Python语言编写 ...
- Python Flask框架-开发简单博客-认证蓝图
作者:Eason_LYC 悲观者预言失败,十言九中. 乐观者创造奇迹,一次即可. 一个人的价值,在于他所拥有的.可以不学无术,但不能一无所有! 技术领域:WEB安全.网络攻防 关注WEB安全.网络攻防 ...
最新文章
- 大量LAST_ACK 的分析过程
- BFS求无权图的单源最短路径-邻接矩阵存储
- python列表操作
- java群发图文消息_使用Java语言开发微信公众平台(四)——图文消息的发送与响应...
- 最长无重复字符子串?
- [ZJOI2016]大森林
- 使用struts2来防止表单重复提交
- java文件处理:文件流、上传、下载
- IP地址专题六:计算相关地址
- html 正则表达式密码判断,JS利用正则表达式实现简单的密码强弱判断实例
- mysql 数据恢复 (.ibdata1, bin log)
- 测试人员如何做好需求分析
- Android——实时显示系统时间
- 云重磅 | 阿里巴巴平均每天纳税超1.4亿;谷歌、Face book与AWS将共建美欧新海底电缆;阿里发布谣言粉碎机:1秒辨真伪...
- 电脑控制手机教你实现多个手机同时自动安装卸载软件
- T5模型和GPT2模型初步对比
- [20190328]PPT中的png图片去底色(透明化)
- [简单逆向]某直播APP 收费直播链接获取-AES解密
- Python打印菱形
- canvas-弹珠游戏