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

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实现微信小程序支付内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

(0)
上一篇 2022年3月22日
下一篇 2022年3月22日

相关推荐