Python+Django实现微信扫码支付流程

关注公众号“轻松学编程”了解更多。
获取源码可以加我微信【1257309054】,文末有二维码。
【微信公众号支付官网】https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_1

【必备资料】:微信公众号、商户平台

登录https://mp.weixin.qq.com/cgi-bin/loginpage公众号,左边找到“开发”->“基本配置”,找到:

  • 开发者ID(AppID)

  • 开发者密码(AppSecret)

  • 设置IP白名单

登录https://pay.weixin.qq.com/core/home/login商户平台,找到:

  • 商户号mchID

一、实现生成二维码扫码支付

1、创建一个Django项目,名为wechatPay

2、创建一个子应用,名为pay

3、在项目下创建static文件夹存放静态文件

4、创建templates存放html文件

点击templates文件夹右键,“Mark Directory as”–>“Template Folder”

4.1 创建报名页面buy.html

<!DOCTYPE html>
<html>
<head>
<title>报名</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.0/css/bootstrap.min.css">
<script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdn.bootcss.com/popper.js/1.12.5/umd/popper.min.js"></script>
<script src="https://cdn.bootcss.com/bootstrap/4.1.0/js/bootstrap.min.js"></script>
</head>
<body> <div class="jumbotron text-center">
<h2>报名</h2>
<p>已报名人数:&nbsp;&nbsp;8465</p>
</div> <div class="container">
<h2>填写信息</h2>
<form action="{% url "to_pay" %}" method="post">
{% csrf_token %}
<div class="form-group">
<label for="name">姓名</label>
<input type="text" class="form-control" id="name" placeholder="姓名" name="name">
</div>
<div class="form-group">
<label for="phone">手机号</label>
<input type="phone" class="form-control" id="phone" placeholder="手机号" name="phone">
</div> <button type="submit" class="btn btn-primary">提交</button>
</form>
</div> </body>
</html>

4.2 创建二维码扫码页面qrcode.html

<!DOCTYPE html>
<html lang="zh-CN"> <head>
<meta charset="UTF-8">
<title>扫码支付</title>
</head>
<style>
.box {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%);
text-align: center;
} .conten {
width: 100%;
} body {
background: #ccc;
}
</style> <body>
{% load static %}
<div class="box">
<h2 class="content"><span>扫码支付</span></h2>
<!--<h2>扫码支付</h2>-->
<img src="{% static qrcode_img %}"><!--显示支付二维码--> </div>
</body> </html>

5、项目目录结构

6、settings.py配置

6.1 注册子应用

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
#注册子应用
'pay', ]

6.2 添加微信支付配置

#微信支付配置
# ========支付相关配置信息===========
_APP_ID = "你的appid" # 公众账号appid
_MCH_ID = "你的商户号" # 商户号
_API_KEY = "你的商户号密钥" # 微信商户平台(pay.weixin.qq.com) -->账户设置 -->API安全 -->密钥设置,设置完成后把密钥复制到这里 _UFDODER_URL = "https://api.mch.weixin.qq.com/pay/unifiedorder"; #url是微信下单api
_NOTIFY_URL = "支付结果回调" # 微信支付结果回调接口,需要改为你的服务器上处理结果回调的方法路径
_CREATE_IP = '你的ip' # 发起支付请求的ip APPEND_SLASH=False

6.3 静态文件配置

STATIC_URL = '/static/'
STATIC_ROOT = '/static/'
# 添加静态资源路由地址
STATICFILES_DIRS=[
os.path.join(BASE_DIR,'static'), ]

7、项目下的urls.py配置

from django.conf import settings
from django.contrib import admin
from django.urls import path
from django.views.static import serve
from pay import views urlpatterns = [
path('admin/', admin.site.urls),
path('buy/', views.buy), # 打开购买页面
path('to_pay/', views.wxpay, name='to_pay'), # 跳转二维码扫描页面
path('check_wxpay/', views.check_wxpay), # 支付结果验签
path('static/<str:path>', serve, {'document_root': settings.STATIC_ROOT}), # 静态文件访问配置
]

8、子应用中的views.py配置

from __future__ import unicode_literals

import os
from random import Random
import string
import time from django.shortcuts import render
from django.http.response import HttpResponse, HttpResponseBadRequest
from django.views.decorators.csrf import csrf_exempt # 解除csrf验证 from bs4 import BeautifulSoup
from wechatPay import settings
import random
import requests
import hashlib
import qrcode #报名首页
def buy(request):
return render(request, 'buy.html') # 定义字典转XML的函数
def trans_dict_to_xml(data_dict):
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 # 定义XML转字典的函数
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 wxpay(request):
nonce_str = random_str() # 拼接出随机的字符串即可,我这里是用 时间+随机数字+5个随机字母 total_fee = 1 #付款金额,单位是分,必须是整数
body = 'baoming' # 商品描述
out_trade_no = order_num(user_id=request.POST.get('phone','12345')) # 订单编号 params = {
'appid': settings._APP_ID, # APPID
'mch_id': settings._MCH_ID, # 商户号
'nonce_str':nonce_str, # 回调地址
'out_trade_no': out_trade_no,# 订单编号
'total_fee':total_fee,# 订单总金额
'spbill_create_ip':settings._CREATE_IP,# 发送请求服务器的IP地址
'notify_url':settings._NOTIFY_URL, # 支付回调地址
'body':body, # 商品描述
'trade_type':'NATIVE' #扫码支付
} sign = get_sign(params,settings._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) # 将请求返回的数据转为字典
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 render(request, 'qrcode.html', {'qrcode_img': qrcode_name}) # 为支付页面模板传入二维码图像 return HttpResponse('交易请求失败!') # 支付成功后回调
@csrf_exempt # 去除csrf验证
def check_wxpay(request):
data_dict = trans_xml_to_dict(request.body) # 回调数据转字典
sign = data_dict.pop('sign') # 取出签名
key = settings._API_KEY # 商户交易密钥
back_sign = get_sign(data_dict, key) # 计算签名
if sign == back_sign: # 验证签名是否与回调签名相同
'''
检查对应业务数据的状态,判断该通知是否已经处理过,如果没有处理过再进行处理,如果处理过直接返回结果成功。
'''
print('支付成功!')
return HttpResponse('SUCCESS')
else:
'''
此处编写支付失败后的业务逻辑
''' return HttpResponse('failed') #获取签名
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()) # 将参数字符串传入
sign = md5.hexdigest().upper() # 完成加密并转为大写
return sign #生成订单号
def order_num(package_id=12345, user_id=56789):
# 商品id后2位+下单时间的年月日12+用户2后四位+随机数4位
local_time = time.strftime('%Y%m%d%H%M%S', time.localtime(time.time()))[2:]
result = str(package_id)[-2:] + local_time + str(user_id)[-2:] + str(random.randint(1000, 9999))
return result #生成随机字符串
def random_str(randomlength=8):
str = ''
chars = 'AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789'
length = len(chars) - 1
random = Random()
for i in range(randomlength):
str+=chars[random.randint(0, length)]
return str

9、效果图

启动服务:

python manage.py runserver

在浏览器中输入127.0.0.1:8000/buy/

填写信息点击提交后会跳转到扫码支付页面。

10、注意

说明:现在微信不支持长按识别二维码支付,这个二维码只能通过微信右上角的扫一扫功能进行扫码支付。

附录

第三方依赖库:requirements.txt

beautifulsoup4==4.6.3
certifi==2018.8.24
chardet==3.0.4
colorama==0.3.9
Django==2.1.1
django-qrcode==0.3
django-wechat==0.1a1
html5lib==1.0.1
idna==2.7
image==1.5.25
lxml==4.2.5
optionaldict==0.1.1
Pillow==5.2.0
python-dateutil==2.7.3
pytz==2018.5
qrcode==6.0
requests==2.6.0
six==1.10.0
urllib3==1.23
webencodings==0.5.1
wechatpy==1.7.5
xmltodict==0.11.0

后记

【后记】为了让大家能够轻松学编程,我创建了一个公众号【轻松学编程】,里面有让你快速学会编程的文章,当然也有一些干货提高你的编程水平,也有一些编程项目适合做一些课程设计等课题。

也可加我微信【1257309054】,拉你进群,大家一起交流学习。
如果文章对您有帮助,请我喝杯咖啡吧!
我的微信:

公众号

关注我,我们一起成长~~

Python+Django实现微信扫码支付流程的更多相关文章

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

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

  2. 微信公众号支付|微信H5支付|微信扫码支付|小程序支付|APP微信支付解决方案总结

    最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付.APP微信支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存. 先说注意 ...

  3. C#版微信公众号支付|微信H5支付|微信扫码支付问题汇总及解决方案总结

    最近负责的一些项目开发,都用到了微信支付(微信公众号支付.微信H5支付.微信扫码支付).在开发的过程中,在调试支付的过程中,或多或少都遇到了一些问题,今天总结下,分享,留存.代码在文章结尾处,有需要的 ...

  4. PHP PC端微信扫码支付【模式二】详细教程-附带源码(转)

    博主写这破玩意儿的时候花了大概快两天时间才整体的弄懂逻辑,考虑了一下~还是把所有代码都放出来给大家~抱着开源大无私的精神!谁叫我擅长拍黄片呢?同时也感谢我刚入行时候那些无私帮过我的程序员们! 首先还是 ...

  5. asp.net core 微信扫码支付(扫码支付,H5支付,公众号支付,app支付)之1

    2018-08-13更新生成二维码的方法 在做微信支付前,首先要了解你需要什么方式的微信支付,目前本人做过的支付包含扫码支付.H5支付.公众号支付.App支付等,本人使用的是asp.net mvc c ...

  6. ThinkPHP5微信扫码支付

    1.把微信官网下载的demo放在根目录/vendor/目录下,这里我的是/vendor/wxpay_pc目录 2.把cert里面的文件替换成自己项目的证书(登陆微信商户平台,账户中心,API安全下载) ...

  7. JAVA微信扫码支付模式二功能实现完整例子

    概述 本例子实现微信扫码支付模式二的支付功能,应用场景是,web网站微信扫码支付.实现从点击付费按钮.到弹出二维码.到用户用手机微信扫码支付.到手机上用户付费成功.web网页再自动调整到支付成功后的页 ...

  8. thinkphp.2 thinkphp5微信支付 微信公众号支付 thinkphp 微信扫码支付 thinkphp 微信企业付款5

    前面已经跑通了微信支付的流程,接下来吧微信支付和微信企业付款接入到thinkphp中,版本是3.2 把微信支付类.企业付款类整合到一起放到第三方类库,这里我把微信支付帮助类和企业付款类放到同一个文件了 ...

  9. ThinkPHP微信扫码支付接口

    最近折腾微信扫码支付,看了微信官方文档,找了很多网页,发现和文档/demo不匹配,现在自己算是弄出来了(文件名称有所更改),贴出来分享一下 一.将有用的官方lib文件和使用的相关文件放置到vendor ...

随机推荐

  1. golang go语言 实现链表

    package main import ( "errors" "fmt" "strconv" ) type List struct { Le ...

  2. 小白也能看懂的ArrayList的扩容机制

    来,话不多说进入正题!我们下面用最简单的代码创建ArrayList并添加11个元素,并 一 一 讲解底层源码:在说之前,给大家先普及一些小知识: >ArrayList底层是用数组来实现的 > ...

  3. keepass+坚果云管理我的密码

    目录 前言 下载安装KeePass 创建一个数据库 配置坚果云 手机用坚果云 总结 前言     KeePass是一款免费.小巧.绿色且开源的密码管理工具,多年来一直深受大众的好评,它能为用户提供一个 ...

  4. 温故知新----封装(struct)

    上次提到class是最常见的封装,今天发现别人开发的SDK里面有大量的结构体struct 转载: 1. https://blog.csdn.net/a_forever_dream/article/de ...

  5. Python自学02day——变量和简单的数据类型

    1.变量是什么? 变量存储在内存中的值,这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同的数据类型, ...

  6. 主厨(第4部分)- ASP. netNET Core和Angular 2 CRUD SPA

    下载source - 79.7 KB 介绍 在Master Chef(第1部分)和Master Chef(第2部分)中,我介绍了如何使用ASP.Net Core和Angular JS.在Master ...

  7. NOI 2012 【迷失游乐园】

    这道题,额,反正我是刚了2天,然后就萎了......(是不是觉得我很菜) 题目描述: 放假了,小Z觉得呆在家里特别无聊,于是决定一个人去游乐园玩. 进入游乐园后,小Z看了看游乐园的地图,发现可以将游乐 ...

  8. SpringSecurity原理

    一.认证的两种方式的介绍 1. 基于Session的认证方式 在之前的单体架构时代,我们认证成功之后都会将信息存入到Session中,然后响应给客户端的是对应的Session中数据的key,客户端会将 ...

  9. 如何把base64格式的图片上传到到阿里云oss c#版

    今天碰到需要把canvas上的的图片转存到阿里云oss,于是百度了半天,一个能打的答案都没有.怒了,自己搞起. 代码超级简单,需要先引入nuget 中啊里云的oss api 1 byte[] arr ...

  10. 【原创】xenomai内核解析--双核系统调用(二)--应用如何区分xenomai/linux系统调用或服务

    版权声明:本文为本文为博主原创文章,转载请注明出处.如有错误,欢迎指正. 1. 引出问题 上一篇文章xenomai内核解析--双核系统调用(一)以X86处理器为例,分析了xenomai内核调用的流程, ...