原文转载自「刘悦的技术博客」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. [SQLServer]NetCore中将SQLServer数据库备份为Sql脚本

    NetCore中将SQLServer数据库备份为Sql脚本 描述: 最近写项目收到了一个需求, 就是将SQL Server数据库备份为Sql脚本, 如果是My Sql之类的还好说, 但是在网上搜了一大 ...

  2. 【leetcode】42. 接雨水

    目录 题目 题解 题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水. 示例 1: 输入:height = [0,1,0,2,1,0,1,3,2,1 ...

  3. Zookeeper安装学习(一)

    学习内容:Zookeeper本地安装 前提准备:①JDK安装成功 ②通过XShell7将Zookeeper安装包(apache-zookeeper-3.5.7-bin.tar.gz)拷贝到Linux系 ...

  4. 【Java面试】如何理解Spring Boot中的Starter?

    一个工作了3年的Java程序员,遇到一个Spring Boot的问题. 他对这个问题有一些了解,但是回答得不是很好,希望参考我的高手回答. 这个问题是:"如何理解Spring Boot中的S ...

  5. 用t-SNE进行流形学习(digits数据集)

    流行学习算法: 是一类用于可视化的算法,它允许进行更复杂的映射,通常也可以给出更好的可视化. t-SNE算法是其中一种. PCA是用于变换数据的首选方法,也可以进行可视化,但它的性质(先旋转然后减少方 ...

  6. dubbo的消费者是怎么获取提供者服务接口引用的?

    本文主要解读dubbo消费者是如何引用服务端接口的,是如何像本地调用一样调用远程服务的. 并试着从设计者的角度思考,为何这样设计. @Component public class DubboConsu ...

  7. JS:表达式

    js代码的形式: 1.直接量 2.表达式 3.语句 1; "a"; true; null; var a; function fn(){}; b; var c = 20; var f ...

  8. 自己实现一个自定义React项目脚手架「ReactCli」

    前言 首先为什么想到自己实现一个React脚手架呢?是因为之前刚接触create-react-app时,觉得不太灵活.虽然文件目录很清晰,但是还是觉得不如VueCLI的可以自定义配置更加灵活.当然Re ...

  9. Linux shell 2>&1的意思

    在脚本里经常看到 ./xxx.sh > /dev/null 2>&1 ./xxx.sh > log.file 2>&1 在shell中输入输出都有对应的文件描述 ...

  10. WPF开发随笔收录-DrawingVisual绘制高性能曲线图

    一.前言 项目中涉及到了心率监测,而且数据量达到了百万级别,通过WPF实现大数据曲线图时,尝试过最基础的Canvas来实现,但是性能堪忧,而且全部画出来也不实际.同时也尝试过找第三方的开源库,但是因为 ...