Django实现微信小程序支付的示例代码


Posted in Python onSeptember 03, 2020

1.下载相关的库

微信官方已经提供了方便开发者的SDK,可是使用pip方式下载:

pip install wechatpy

2. 在项目的settings.py文件添加相关配置

具体的参数需要自己到小程序微信公众平台和微信商户平台获取。

WECHAT = {
    'APPID': 'appid',               # 小程序ID
    'APPSECRET': 'appsecret',			# 小程序SECRET
    'MCH_ID': 'mch_id',                   # 商户号
    'TOTAL_FEE': '1',                      # 总金额, 单位为“分”
    'SPBILL_CREATE_IP': '127.0.0.1',              # 终端IP
    'NOTIFY_URL': 'http://127.0.0.1:8000/wechat/payNotify/',     # 通知地址
    'TRADE_TYPE': 'JSAPI',                   # 交易类型
    'MERCHANT_KEY': 'merchant_key',     # 商户KEY
    'BODY': '商品描述',                # 商品描述
}

3. 给Django项目新建app

  • 例如我新建的app为:Pay
  • 在settings.py文件的INSTALLED_APPS添加刚才新建的app

4. 编写app/views.py:

from django.http import HttpResponse
import requests
import json
from django.conf import settings
from wechatpy.pay import WeChatPay
from app_base.base_viewset import BaseAPIView
from rest_framework import permissions
from lxml import etree as et
from rest_framework import status


class WeChatPayViewSet(BaseAPIView):
  """
  通过小程序前端 wx.login() 接口获取临时登录凭证 code
  将 code 作为参数传入,调用 get_user_info() 方法获取 openid
  """

  def get_user_info(self, js_code):
    """
    使用 临时登录凭证code 获取 session_key 和 openid 等
    支付部分仅需 openid,如需其他用户信息请按微信官方开发文档自行解密
    """
    req_params = {
      'appid': settings.WECHAT['APPID'],
      'secret': settings.WECHAT['APPSECRET'],
      'js_code': js_code,
      'grant_type': 'authorization_code',
    }
    user_info = requests.get('https://api.weixin.qq.com/sns/jscode2session',
                 params=req_params, timeout=3, verify=False)
    return user_info.json()

  def get(self, request):
    code = request.GET.get("code", None)
    openid = self.get_user_info(code)['openid']

    pay = WeChatPay(settings.WECHAT['APPID'], settings.WECHAT['MERCHANT_KEY'], settings.WECHAT['MCH_ID'])
    order = pay.order.create(
      trade_type=settings.WECHAT['TRADE_TYPE'], # 交易类型,小程序取值:JSAPI
      body=settings.WECHAT['BODY'], # 商品描述,商品简单描述
      total_fee=settings.WECHAT['TOTAL_FEE'], # 标价金额,订单总金额,单位为分
      notify_url=settings.WECHAT['NOTIFY_URL'], # 通知地址,异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数。
      user_id=openid # 用户标识,trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识。
    )
    wxpay_params = pay.jsapi.get_jsapi_params(order['prepay_id'])
    return HttpResponse(json.dumps(wxpay_params))


class WeChatPayNotifyViewSet(BaseAPIView):
  permission_classes = (permissions.AllowAny, )

  def get(self, request):
    _xml = request.body
    # 拿到微信发送的xml请求 即微信支付后的回调内容
    xml = str(_xml, encoding="utf-8")
    print("xml", xml)
    return_dict = {}
    tree = et.fromstring(xml)
    # xml 解析
    return_code = tree.find("return_code").text
    try:
      if return_code == 'FAIL':
        # 官方发出错误
        return_dict['message'] = '支付失败'
        # return Response(return_dict, status=status.HTTP_400_BAD_REQUEST)
      elif return_code == 'SUCCESS':
        # 拿到自己这次支付的 out_trade_no
        _out_trade_no = tree.find("out_trade_no").text
        # TODO 这里省略了 拿到订单号后的操作 看自己的业务需求
    except Exception as e:
      pass
    finally:
      return HttpResponse(return_dict, status=status.HTTP_200_OK)

补充一些继承的类:

# -*- coding: utf-8 -*-
from rest_framework.authentication import TokenAuthentication
from rest_framework.views import APIView
from rest_framework import permissions

__author__ = 'JayChen'


class BaseAPIView(APIView):
  permission_classes = (permissions.IsAuthenticated,)
  # authentication_classes = (TokenAuthentication,)

5. 给Pay app添加urls.py并编写

# -*- coding: utf-8 -*-

__author__ = 'JayChen'

from django.conf.urls import url
from rest_framework.urlpatterns import format_suffix_patterns
from pay import views

app_name = 'pay'
urlpatterns = [
  # 微信小程序支付
  url(r'^pay/', views.WeChatPayViewSet.as_view(), name='pay'),
  # 支付结果回调
  url(r'^payNotify/', views.WeChatPayNotifyViewSet.as_view(), name='pay_notify'),
]

6.在项目的urls.py添加上面新增的urls.py

from django.contrib import admin
from django.urls import path, include
from rest_framework_jwt.views import obtain_jwt_token

urlpatterns = [
  path('admin/', admin.site.urls),
  path('token_auth/', obtain_jwt_token, name='jwt_token'),
  path('user/', include('auth_jwt.urls')),
  
  path('wechat/', include('pay.urls')), # 微信支付相关
]

7.调试

微信小程序登陆后会得到一个code,把这个code作为参数发送给Django项目的后端:
例如:http://0.0.0.0:8000/wechat/pay/?code=033h0P0w3ANPRU2ntl0w36HHyy1h0P08

注意:这个code每次登录都会返回,并且只能使用一次,然后就失效。

返回的数据:

{
  "appId": "wx14b75285dfe1",
  "timeStamp": "1595228",
  "nonceStr": "1Wtu5lKb6T3fJLiNzc09ay2Z",
  "signType": "MD5",
  "package": "prepay_id=wx02158826854686197390000",
  "paySign": "89599A11E051D3B20FF57"
}

小程序拿到这些数据就能调起支付。

到此这篇关于Django实现微信小程序支付的文章就介绍到这了,更多相关Django实现微信小程序支付内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Windows下Python使用Pandas模块操作Excel文件的教程
May 31 Python
Python3.5 创建文件的简单实例
Apr 26 Python
python爬虫解决验证码的思路及示例
Aug 01 Python
Python中pymysql 模块的使用详解
Aug 12 Python
python实现二分类和多分类的ROC曲线教程
Jun 15 Python
Python数据相关系数矩阵和热力图轻松实现教程
Jun 16 Python
python3.7添加dlib模块的方法
Jul 01 Python
django template实现定义临时变量,自定义赋值、自增实例
Jul 12 Python
使用OpenCV实现道路车辆计数的使用方法
Jul 15 Python
利用python清除移动硬盘中的临时文件
Oct 28 Python
pytorch显存一直变大的解决方案
Apr 08 Python
Python爬虫之爬取二手房信息
Apr 27 Python
解决Python3.7.0 SSL低版本导致Pip无法使用问题
Sep 03 #Python
一篇文章搞懂python的转义字符及用法
Sep 03 #Python
容易被忽略的Python内置类型
Sep 03 #Python
python类共享变量操作
Sep 03 #Python
Python pip install之SSL异常处理操作
Sep 03 #Python
详解python tkinter 图片插入问题
Sep 03 #Python
解决PyCharm IDE环境下,执行unittest不生成测试报告的问题
Sep 03 #Python
You might like
php从数组中随机抽取一些元素的代码
2012/11/05 PHP
windows7下安装php的imagick和imagemagick扩展教程
2014/07/04 PHP
php实现微信支付之企业付款
2018/05/30 PHP
TP5框架实现一次选择多张图片并预览的方法示例
2020/04/04 PHP
Yii Framework框架开发微信公众平台示例
2020/04/26 PHP
仿新浪微博返回顶部的jquery实现代码
2012/10/01 Javascript
js实现网站首页图片滚动显示
2013/02/04 Javascript
Bootstrap基本样式学习笔记之表单(3)
2016/12/07 Javascript
NodeJs模拟登陆正方教务
2017/04/28 NodeJs
Nodejs 发布自己的npm包并制作成命令行工具的实例讲解
2018/05/15 NodeJs
微信小程序wx:for循环的实例详解
2018/10/07 Javascript
什么时候不能在 Node.js 中使用 Lock Files
2019/06/24 Javascript
js的新生代垃圾回收知识点总结
2019/08/22 Javascript
json_decode 索引为数字时自动排序问题解决方法
2020/03/28 Javascript
小程序富文本提取图片可放大缩小
2020/05/26 Javascript
微信小程序自定义顶部组件customHeader的示例代码
2020/06/03 Javascript
如何构建一个Vue插件并生成npm包
2020/10/26 Javascript
使用Python操作MySQL的一些基本方法
2015/08/16 Python
使用anaconda的pip安装第三方python包的操作步骤
2018/06/11 Python
python实现RabbitMQ的消息队列的示例代码
2018/11/08 Python
Python (Win)readline和tab补全的安装方法
2019/08/27 Python
Python pip配置国内源的方法
2020/02/14 Python
Python分类测试代码实例汇总
2020/07/23 Python
解决selenium+Headless Chrome实现不弹出浏览器自动化登录的问题
2021/01/09 Python
意大利运动服减价商店:ScontoSport
2020/03/10 全球购物
C语言50道问题
2014/10/23 面试题
培训主管的岗位职责
2013/11/23 职场文书
中职生自荐信范文
2014/06/15 职场文书
甜品店创业计划书
2014/09/21 职场文书
小学师德师风整改措施
2014/10/27 职场文书
国际贸易实务实训报告
2014/11/05 职场文书
礼仪培训心得体会
2016/01/22 职场文书
2019年行政人事个人工作总结范本!
2019/07/19 职场文书
jquery插件实现代码雨特效
2021/04/24 jQuery
Python 如何安装Selenium
2021/05/06 Python
Spring Boot 排除某个类加载注入IOC的操作
2021/08/02 Java/Android