当前位置:科学 > 正文

【天天速看料】mpvue1.0+python3.7+Django2.0.4实现微信小程序的支付功能

2023-01-19 06:42:46  来源:刘悦技术分享

其实微信支付有很多种形式,刷脸,扫码,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 Viewimport requestsimport hashlibimport xmltodictclient_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



关键词: Django ____

推荐阅读

虎门大桥怎么样了 虎门大桥没有问题可以恢复通车了吗?

关于虎门大桥已经连续几天成为热门话题了,5月5日,最开始为了保障安全,对交通实行双向封闭。5月10日,组织报告测评,而今天根据官方消息 【详细】

2025年取消燃油车 2025年取消燃油车是真的吗?

相信很多人都听说过中国2025年取消燃油车,接下来小编就带大家介绍一下相关知识,大家可以了解一下。汽车一般使用汽油、柴油等化石燃料作为 【详细】

未成年打赏可退还是真的吗?未成年打赏可退有什么法律依据?

今日,未成年打赏可退还的消息引发人们的热切讨论,未成年人网络打赏引发的纠纷,多年来成为人们关注的社会热点问题,那么未成年打赏可退还 【详细】

首都第二国际机场在哪里 首都第二国际机场为何选址大兴?

首都第二国际机场为何选址大兴?大兴位于北京的南部,为什么选在南边建设机场?现在北京机场有几个?为了确保首都的安全,南部修建了北京第二 【详细】

4万以下的新车有哪些 4万以下的新车推荐

现在汽车已经成为了人们日常生活中或不可缺的代步工具了,但是很多车对于一些家庭来说还是比较昂贵的。所以今天,我们就来为大家分享一下4 【详细】

相关新闻

关于我们  |  联系方式  |  免责条款  |  招聘信息  |  广告服务  |  帮助中心

联系我们:85 572 98@qq.com备案号:粤ICP备18023326号-40

科技资讯网 版权所有