在生活具有广泛性、高效性、使用方便性的支付方式是扫码支付,扫码的优点在于推广成本低,上至钓鱼台国宾馆,下至发廊地摊都能用,打印出来就完事了,而相比其他支付方式,现金的找零及假钞问题,信用卡的办理门槛、pos机的沉没成本,就算微信可集成的h5支付和小程序支付,奈何很多老年人根本不会用小程序和手机浏览器,更别说再进行支付操作了,所以基于二维码的扫码支付的确是非常符合国情的。
本次我们使用前后端分离项目Vue.js+Tronado来集成微信的扫码支付功能,体验一下21世纪泛用性最高的支付方式,首先注册微信公众平台:https://mp.weixin.qq.com
同时确保获取微信支付接口的权限:

随后注册微信支付商户平台:https://pay.weixin.qq.com/
获取微信支付的商户号(在账户信息页面):

获取微信支付接口的秘钥(账户中心->api安全):

同时在产品中心->开发配置页面,将支付域名配置好:

这里不像微信小程序,小程序只能允许https协议接口,而扫码支付域名既支持https也支持http,非常方便,同时注意域名必须是一个备案域名。
至此,微信支付的前置操作就搞定了,下面我们来编写后台接口wx_pay.py,首先导入依赖的库和一些工具方法:

import requests
from django.http import HttpResponse, HttpResponseRedirectimport random
import time
import hashlibimport qrcode
from bs4 import BeautifulSoupdef 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 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))  # 返回XMLdef 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())  # 将参数字符串传入sign = md5.hexdigest().upper()  # 完成加密并转为大写return sign

qrcode模块用来生成二维码,bs4模块用来将微信接口返回的xml解析成json,在21世纪的第二十个年头,微信接口居然还在使用原始的xml,这种反人类行为实在不能理解。

接下来我们来编写支付逻辑,参考微信官方文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=6_5&index=3

业务流程说明:

(1)商户后台系统根据用户选购的商品生成订单。

(2)用户确认支付后调用微信支付【统一下单API】生成预支付交易;

(3)微信支付系统收到请求后生成预支付交易单,并返回交易会话的二维码链接code_url。

(4)商户后台系统根据返回的code_url生成二维码。

(5)用户打开微信“扫一扫”扫描二维码,微信客户端将扫码内容发送到微信支付系统。

(6)微信支付系统收到客户端请求,验证链接有效性后发起用户支付,要求用户授权。

(7)用户在微信客户端输入密码,确认支付后,微信客户端提交授权。

(8)微信支付系统根据用户授权完成支付交易。

(9)微信支付系统完成支付交易后给微信客户端返回交易结果,并将交易结果通过短信、微信消息提示用户。微信客户端展示支付交易结果页面。

(10)微信支付系统通过发送异步消息通知商户后台系统支付结果。商户后台系统需回复接收情况,通知微信后台系统不再发送该单的支付通知。

(11)未收到支付通知的情况,商户后台系统调用【查询订单API】。

(12)商户确认订单已支付后给用户发货。

一望而知,我们需要调用微信的统一下单接口,文档:https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_1
编写逻辑:

import requests
import random
import time
import hashlib
import qrcode
from bs4 import BeautifulSoupdef 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 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))  # 返回XMLdef 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())  # 将参数字符串传入sign = md5.hexdigest().upper()  # 完成加密并转为大写return signclass Zhifubao:def pay(self):print ('支付宝')class Weixing():def pay(self):print ('微信')def wx_pay(self,total_fee):url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'  # 微信扫码支付接口key = '945bec9df3614cffb74e39aba8fbf7d7'  # 商户api秘钥total_fee = total_fee  # 支付金额,单位分body = '123123'  # 商品描述out_trade_no = 'order_%s' % random.randrange(100000, 999999)  # 订单编号params = {'appid': 'wx092344a76b9979ff',  # APPID'mch_id': '1602932608',  # 商户号'notify_url': 'http://wxpay.v3u.cn/wx_back/',  # 支付域名回调地址'product_id': 'goods_%s' % random.randrange(100000, 999999),  # 商品编号'trade_type': 'NATIVE',  # 支付类型(扫码支付)'spbill_create_ip': '114.254.176.137',  # 发送请求服务器的IP地址'total_fee': total_fee,  # 订单总金额'out_trade_no': out_trade_no,  # 订单编号'body': body,  # 商品描述'nonce_str': 'ibuaiVcKdpRxkhJA'  # 字符串}sign = get_sign(params, key)  # 获取签名params.setdefault('sign', sign)  # 添加签名到参数字典xml = trans_dict_to_xml(params)  # 转换字典为XMLresponse = requests.request('post', url, data=xml)  # 以POST方式向微信公众平台服务器发起请求data_dict = trans_xml_to_dict(response.content)  # 将请求返回的数据转为字典print(data_dict)qrcode_name = out_trade_no + '.png'  # 支付二维码图片保存路径if data_dict.get('return_code') == 'SUCCESS':  # 如果请求成功img = qrcode.make(data_dict.get('code_url'))  # 创建支付二维码片img.save('./static/' + qrcode_name)  # 保存支付二维码return qrcode_nameclass Factory: #工厂def way(self,name):if name == 'zhifubao':return Zhifubao()if name == 'weixin':return Weixing()# fa = Factory()
# d = fa.way('weixin')
# print(d.wx_pay(1))

随后配置路由:

启动Tornado服务:

python main.py

至此,后台逻辑基本搞定,下面就是如何在前端进行调用,同时让用户进行扫描操作,编写weixin_pay.vue组件:

<template><div><center><h1>扫码支付</h1></center><van-field v-model="money" label="金额" /><van-button color='orange' @click='submit'>生成二维码</van-button><van-image :src="src" v-if="src"/></div></template><script>export default {data() {return {money:"1",src:"",};},methods: {submit:function(){this.axios.get('https://localhost/weixin/',{params:{'money':this.money}}).then((result) =>{console.log(result.data);this.src = "https://localhost/static/"+result.data.image});},},
};
</script>

随后使用微信扫一扫功能进行扫码支付,需要注意的是,该二维码有效期只有五分钟,所以最好加上刷新功能。

支付成功之后,我们还需要对交易进行确认,所以根据微信官方文档,调用统一查询接口:

https://pay.weixin.qq.com/wiki/doc/api/native.php?chapter=9_2,根据接口文档编写逻辑:

    def wx_check(self,out_trade_no):# 统一订单查询接口url = "https://api.mch.weixin.qq.com/pay/orderquery"out_trade_no = out_trade_no # 支付后的商户订单号key = '945bec9df3614cffb74e39aba8fbf7d7'  # 商户api密钥params = {'appid': 'wx092344a76b9979ff',  # APPID'mch_id': '1602932608',  # 商户号'out_trade_no': out_trade_no,  # 订单编号'nonce_str': 'ibuaiVcKdpRxkhJA'  # 随机字符串}sign = get_sign(params, key)  # 获取签名params.setdefault('sign', sign)  # 添加签名到参数字典xml = trans_dict_to_xml(params)  # 转换字典为XMLresponse = requests.request('post', url, data=xml)  # 以POST方式向微信公众平台服务器发起请求data_dict = trans_xml_to_dict(response.content)  # 将请求返回的数据转为字典print(data_dict)return ('ok')

这里需要注意的是,查询的订单编号可以使商户自己的订单编号,也可以是微信订单号,二者必取其一:



结语:至此,整个微信扫码支付流程全部跑通

Win10环境前后端分离项目基于Vue.js+Tornado+Python3实现微信(wechat)扫码支付流程相关推荐

  1. Win10环境前后端分离项目基于Vue.js+Django+Python3实现微信(wechat)扫码支付流程(2021年最新攻略)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_182 之前的一篇文章:mpvue1.0+python3.7+Django2.0.4实现微信小程序的支付功能,主要介绍了微信小程序内 ...

  2. 基于web的前后端分离nodejs和vue.js医院分诊系统

    (1)系统设置模块:包括权限管理和用户信息管理.此模块主要功能包括:添加.修改.删除和查看用户信息,给用户分配权限进行角色管理. (2)用户管理:用户进行登录和注册,进行挂号 (3)患者管理模块:此模 ...

  3. 前后端分离,基于vue+elementUI的动态菜单

    制作动态菜单的思路: 就是当前用户登陆后,保存用户的信息,通过用户的id,去查找该用户对象的菜单.后台获取的菜单数据,最终传给前台形式就是父菜单里包含了所有的子菜单:并在前台登录成功后,把菜单数据取出 ...

  4. 前后端分离项目,vue+uni-app+php+mysql外卖点餐小程序系统 开题报告

      毕业论文 基于Vue.js外卖点餐小程序系统 开题报告 学    院: 专    业: 年    级: 学生姓名: 指导教师: 黄菊华   XXXX大学本科生毕业论文(设计)开题报告书 姓   名 ...

  5. 前后端分离项目,vue+uni-app+php+mysql在线教育视频点播小程序系统 开题报告

      毕业论文 基于Vue.js视频点播小程序系统 开题报告 学    院: 专    业: 年    级: 学生姓名: 指导教师: 黄菊华   XXXX大学本科生毕业论文(设计)开题报告书 姓   名 ...

  6. 前后端分离项目,vue+uni-app+php+mysql外卖点餐系统设计与实现(H5移动项目)

    功能介绍 [后台管理员功能] 会员列表:查看所有注册会员信息,支持删除 录入资讯:录入资讯标题.内容等信息 管理资讯:查看已录入资讯列表,支持删除和修改 广告设置:上传图片和设置小程序首页轮播图广告地 ...

  7. 前后端分离项目,vue+uni-app+php+mysql教室预约系统(H5移动项目) 开题报告

      毕业论文 基于Vue.js的教室预约系统(H5) 开题报告 学    院: 专    业: 年    级: 学生姓名: 指导教师: 黄菊华   XXXX大学本科生毕业论文(设计)开题报告书 姓   ...

  8. 前后端分离项目,vue+uni-app+php+mysql教室预约小程序系统 开题报告

      毕业论文 基于Vue.js的教室预约小程序系统 开题报告 学    院: 专    业: 年    级: 学生姓名: 指导教师: 黄菊华   XXXX大学本科生毕业论文(设计)开题报告书 姓   ...

  9. 前后端分离项目,vue+uni-app+php+mysql图书购物商城小程序系统 开题报告

      毕业论文 基于Vue.js图书商城小程序系统 开题报告 学    院: 专    业: 年    级: 学生姓名: 指导教师: 黄菊华   XXXX大学本科生毕业论文(设计)开题报告书 姓   名 ...

最新文章

  1. 快学习使用Linux吧,避免勒索病毒大肆入侵
  2. 使用python处理实验数据-yechen_pro_20171231
  3. IEDA中彻底删除项目
  4. 【华为云 ModelArts-Lab AI实战营】第二期
  5. matepad适配鸿蒙,消息称华为 MatePad2 搭载骁龙888 4G 华为鸿蒙OS计划适配高通平台...
  6. 华为P50标准版规格曝光:或搭载骁龙888 4G
  7. 第七届蓝桥杯javaB组真题解析-抽签(第五题)
  8. 关于linux文件权限的说明
  9. HiJson简要说明
  10. windows7下硬盘安装linux
  11. 六轴UR机械臂正逆运动学求解_MATLAB代码(标准DH参数表)
  12. 测试固态硬盘写入数据软件,持续写入100TB 三星840EVO耐久度测试
  13. 基于深度学习的目标检测的IOU损失函数介绍
  14. 苹果手机内屏幕出现彩色条纹怎么办
  15. DirectX12 - Triangle Culling and Winding Order(三角形的剔除与绕序)
  16. Android 使用crosswalk实例
  17. python脚本下载百度或必应图片
  18. linux 查看环境变量和修改环境变量
  19. echarts折线图无数据断开解决方法
  20. 视频发微信文件过大怎么办大于200m视频发送微信?

热门文章

  1. 调用百度AI平台API进行文字识别和图片识别
  2. gtx1660ti性能如何
  3. python网络爬虫,爬取猫眼电影中复联4上映前南昌市的票房
  4. 开发游戏只为向女友求婚,每个关卡都是泪点!我是一个普通人,但是想成为你另一半玩家...
  5. **vue定时器混乱问题**
  6. JREX 的使用与下载
  7. 情侣头像动漫:超宠老婆的情侣头像动漫高清
  8. [幸福的七种颜色] 精彩文摘(中)
  9. Google ARCore发布
  10. 基于DCT的数字水印算法