原文转载自「刘悦的技术博客」https://v3u.cn/a_id_112

其实微信支付有很多种形式,刷脸,扫码,APP支付,小程序支付等,这边只说明小程序支付的实现,不过原理上都大同小异。

首先,需要注册微信公众号平台https://mp.weixin.qq.com,并且开通微信支付功能,随后将你的小程序关联一个微信商户:pay.weixin.qq.com,这一系列申请下来之后,你手中需要有微信小程序appid,微信小程序秘钥,商户号,以及商户秘钥,这四个关键的支付配置变量。

然后大体流程分两步:

1 在自己的后台服务器上访问微信提供的接口,拿到预支付交易会话标识prepay_id、微信返回的随机字符串nonce_str,这两个参数是要返回给自己的小程序的,小程序在调起微信支付接口时需要这两个参数。

2 小程序拿到后台传递的参数,需要后台传递5个参数,timeStamp,nonceStr,package,signType,paySign。然后在小程序上调起支付接口时传递我们拿到的参数,就可以完成支付。

先构造后台接口,这里我们使用Django作为后台服务:

from django.shortcuts import render
#导包
from django.http import HttpResponse,HttpResponseRedirect,JsonResponse
#导入类视图
from django.views import View
import requests
import hashlib
import xmltodict client_appid = '你的小程序appid'
Mch_id = '你的商户编号'
Mch_key = '商户交易秘钥' def myindex(request):
return HttpResponse('这里是首页') def myback(request):
return HttpResponse('这里是回调网址') def get_nonce_str():
import uuid
return str(uuid.uuid4()).replace('-', '') def getWxPayOrdrID():
import datetime date=datetime.datetime.now()
#根据当前系统时间来生成商品订单号。时间精确到微秒
payOrdrID=date.strftime("%Y%m%d%H%M%S%f") return payOrdrID #生成签名的函数
def paysign(appid,body,mch_id,nonce_str,notify_url,openid,out_trade_no,spbill_create_ip,total_fee):
ret= {
"appid": appid,
"body": body,
"mch_id": mch_id,
"nonce_str": nonce_str,
"notify_url":notify_url,
"openid":openid,
"out_trade_no":out_trade_no,
"spbill_create_ip":spbill_create_ip,
"total_fee":total_fee,
"trade_type": 'JSAPI'
} #处理函数,对参数按照key=value的格式,并按照参数名ASCII字典序排序
stringA = '&'.join(["{0}={1}".format(k, ret.get(k))for k in sorted(ret)])
stringSignTemp = '{0}&key={1}'.format(stringA,Mch_key)
sign = hashlib.md5(stringSignTemp.encode("utf-8")).hexdigest()
return sign.upper() def generate_sign(param):
'''生成签名'''
stringA = ''
ks = sorted(param.keys())
print(param)
# 参数排序
for k in ks:
stringA += (k + '=' + param[k] + '&')
# 拼接商户KEY
stringSignTemp = stringA + "key=" + Mch_key
# md5加密,也可以用其他方式
hash_md5 = hashlib.md5(stringSignTemp.encode('utf8'))
sign = hash_md5.hexdigest().upper()
return sign #获取全部参数信息,封装成xml,传递过来的openid和客户端ip,和价格需要我们自己获取传递进来
def get_bodyData(openid,client_ip,price):
body = 'Mytest' #商品描述
notify_url = 'http://localhost:8000/back' #填写支付成功的回调地址,微信确认支付成功会访问这个接口
nonce_str =get_nonce_str() #随机字符串
out_trade_no =getWxPayOrdrID() #商户订单号
total_fee =str(price) #订单价格,单位是 分 #获取签名
sign=paysign(client_appid,body,Mch_id,nonce_str,notify_url,openid,out_trade_no,client_ip,total_fee) bodyData = '<xml>'
bodyData += '<appid>' + client_appid + '</appid>' # 小程序ID
bodyData += '<body>' + body + '</body>' #商品描述
bodyData += '<mch_id>' + Mch_id + '</mch_id>' #商户号
bodyData += '<nonce_str>' + nonce_str + '</nonce_str>' #随机字符串
bodyData += '<notify_url>' + notify_url + '</notify_url>' #支付成功的回调地址
bodyData += '<openid>' + openid + '</openid>' #用户标识
bodyData += '<out_trade_no>' + out_trade_no + '</out_trade_no>'#商户订单号
bodyData += '<spbill_create_ip>' + client_ip + '</spbill_create_ip>'#客户端终端IP
bodyData += '<total_fee>' + total_fee + '</total_fee>' #总金额 单位为分
bodyData += '<trade_type>JSAPI</trade_type>' #交易类型 小程序取值如下:JSAPI bodyData += '<sign>' + sign + '</sign>'
bodyData += '</xml>' return bodyData #统一下单支付接口
def payOrder(request):
import time
#获取价格 单位是分
price= int(request.GET.get("price",1)) #获取客户端ip
client_ip,port=request.get_host().split(":") #获取小程序openid
#openid='of2Fa5C2BNn77OOh1hfydxK4pVJc'
openid = request.GET.get("openid") #请求微信的url
url='https://api.mch.weixin.qq.com/pay/unifiedorder' #拿到封装好的xml数据
body_data=get_bodyData(openid,client_ip,price) #获取时间戳
timeStamp=str(int(time.time())) #请求微信接口下单
respone=requests.post(url,body_data.encode("utf-8"),headers={'Content-Type': 'application/xml'})
print(respone.content)
#回复数据为xml,将其转为字典
content=xmltodict.parse(respone.content)
print(content) return_code = content['xml']['return_code'] if return_code=='SUCCESS':
prepay_id = content['xml']['prepay_id']
# 时间戳
timeStamp = str(int(time.time()))
# 5. 五个参数
data = {
"appId":client_appid ,
"nonceStr": get_nonce_str(),
"package": "prepay_id=" + prepay_id,
"signType": 'MD5',
"timeStamp": timeStamp,
}
# 6. paySign签名
paySign = generate_sign(data)
data["paySign"] = paySign # 加入签名
print(data)
# 7. 传给前端的签名后的参数
return JsonResponse(data,safe=False,json_dumps_params={'ensure_ascii':False})
else:
return HttpResponse("请求支付失败")

剩下的就简单了,在前端mpvue写支付请求逻辑,由前端请求后端的django统一支付接口,获取关键的五个变量,随后利用这五个变量,请求微信官网支付接口,完成支付逻辑

paytest(){

      console.log('支付测试');
console.log(this.userinfo.openid); wx.request({
url: 'http://127.0.0.1:8000/pay/',
header: {
'content-type': 'application/json'
},
data: {'openid': this.userinfo.openid,'price': 1},
success: function (res) {
wx.requestPayment({
timeStamp: res.data.timeStamp,
nonceStr: res.data.nonceStr,
package: res.data.package,
signType: res.data.signType,
paySign: res.data.paySign,
'success': function (res) {
console.log(res)
},
'fail': function (res) {
console.log(res)
}
})
}
}) }

需要注意的是,请求后台接口时,openid和price是必须要传递的,openid是微信小程序当前用户的唯一标识,而price是价格,单位是分

最后,完成了支付,没什么难的,有一些地方需要提醒:后台接口如果需要在本地调试的话,只能用127.0.0.1这种ip的形式,微信不支持localhost,另外需要xmltodict这个三方库将微信统一支付接口返回的xml转成dict,话说都什么年代了,微信接口居然还在使用xml。

附上代码:

后端django:https://gitee.com/QiHanXiBei/mydjango

前端mpvue:https://gitee.com/QiHanXiBei/mpvue

原文转载自「刘悦的技术博客」 https://v3u.cn/a_id_112

Mpvue1.0+Python3.7+Django2.0.4实现微信小程序的支付功能的更多相关文章

  1. Taro-UI 2.0样式在H5上生效,微信小程序不生效?

    答案: https://taro-ui.aotu.io/#/docs/questions taro-ui 自定义样式覆盖小程序组件样式使用到了 globalClass 这个微信小程序特性,由于微信小程 ...

  2. WordPress版微信小程序2.2.0版发布

    2017年8月12日WordPress版微信小程序2.2.0版通过了微信的审核正式发布,此版本的更新以完善功能为主.主要更新的功能是:站内链接,猜你喜欢,热点文章. WordPress版微信小程序开放 ...

  3. Djang1.8+Python2.0迁移到Django2.0+Python3.6注意事项(转)

    Djang1.8+Python2.0迁移到Django2.0+Python3.6注意事项 参考:https://blog.csdn.net/weixin_40475396/article/detail ...

  4. python3.5+django2.0快速入门(二)

    昨天写了python3.5+django2.0快速入门(一)今天将讲解配置数据库,创建模型,还有admin的后台管理. 配置数据库 我们打开mysite/mysite/settings.py这个文件. ...

  5. python3.5+django2.0快速入门(一)

    因为这篇教程需要用到anaconda的一些操作,如果还不懂anaconda的操作的同学可以看下这篇文章python 入门学习之anaconda篇. 创建python3+的开发环境 直接在终端输入:co ...

  6. Python3.6+Django2.0以上 xadmin站点的配置和使用

    1. xadmin的介绍 django自带的admin站点虽然功能强大,但是界面不是很好看.而xadmin界面好看,功能更强大,并完全支持Bootstrap主题模板.xadmin内置了丰富的插件功能. ...

  7. Django2.0+小程序技术打造微信小程序助手✍✍✍

    Django2.0+小程序技术打造微信小程序助手  整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课程本身没问题 ...

  8. 微信小程序0.11.122100版本新功能解析

    微信小程序0.11.122100版本新功能解析   新版本就不再吐槽了,整的自己跟个愤青似的.人老了,喷不动了,把机会留给年轻人吧.下午随着新版本开放,微信居然破天荒的开放了开发者论坛.我很是担心官方 ...

  9. 微信小程序(原名微信应用号)开发工具0.9版安装教程

    微信小程序全称微信公众平台·小程序,原名微信公众平台·应用号(简称微信应用号) 声明 微信小程序开发工具类似于一个轻量级的IDE集成开发环境,目前仅开放给了少部分受微信官方邀请的人士(据说仅200个名 ...

随机推荐

  1. grafana展示zabbix统计

    1.安装grafana   参照官网文档:https://grafana.com/grafana/download 我这边是centos系统,执行这两个命令 wget https://dl.grafa ...

  2. .Net 6 WebApi 项目部署到 Linux 系统上的 Docker 容器

    1.创建一个基础的WebApi项目 注意:因为发布时候,Dockerfile文件必须和解决方案.cspro文件放在同级,所以建议勾上这个,当时遇到这个问题,导致打包镜像时找不到.cspro文件,搞了好 ...

  3. 204. Count Primes - LeetCode

    Queston 204. Count Primes Solution 题目大意:给一个数,求小于这个数的素数的个数 思路:初始化一个boolean数组,初始设置为true,先遍历将2的倍数设置为fal ...

  4. Java 对象实现 Serializable 的原因

    java.io.Serializable 是 Java 中的一种标记接口(marker interface).标记接口是一种特殊的接口,java.io.Serializable 接口没有任何方法,也没 ...

  5. 个人冲刺(四)——体温上报app(二阶段)

    冲刺任务:完成用户注册功能和数据库类 RegisterActivity.java package com.example.helloworld; import android.content.Inte ...

  6. mysql查询关键字补充与多表查询

    目录 查询关键字补充 having过滤 distinct去重 order by排序 limit分页 regexp正则 多表查询 子查询 连表查询 查询关键字补充 having过滤 关键字having和 ...

  7. CentOS 7.0 使用 yum 安装 MariaDB

    CentOS 7.0 使用 yum 安装 MariaDB 与 MariaDB 的简单配置   1.安装MariaDB 安装命令 yum -y install mariadb mariadb-serve ...

  8. Navicat 连接 MySQL

    目录 简述 新建连接 常见错误 简述 Navicat 是一套快速.可靠和全面的数据库管理工具,专门用于简化数据库管理和降低管理成本.Navicat 图形界面直观,提供简便的管理方法,设计和操作 MyS ...

  9. RMQ——ST表

    ST表 ST表是一种解决RMQ问题的强有力工具, 可以做到O(nlogn)预处理,O(1)查询. st[i][j] 表示区间 [i, i + 2 ^ j - 1] 的最大值. 初值 st[i][0] ...

  10. .NET C#基础(6):命名空间 - 有名字的作用域

    0. 文章目的   面向C#新学者,介绍命名空间(namespace)的概念以及C#中的命名空间的相关内容. 1. 阅读基础   理解C与C#语言的基础语法.   理解作用域概念. 2. 名称冲突与命 ...