顺晟科技
2021-06-16 10:48:56
254
其实微信支付的形式有很多,刷脸、扫码、APP支付、小程序支付等。这里只说明小程序支付的实现,但原则上是类似的。
首先你需要注册微信微信官方账号平台https://mp.weixin.qq.com,开通微信支付功能。然后,把你的小程序和一个微信商人联系起来:pay.weixin.qq.com。这一系列应用之后,你需要有四个关键的支付配置变量:微信小程序appid、微信小程序密钥、商户号、商户密钥。
然后一般过程分为两步:
1.在自己的后台服务器上访问微信提供的界面,获取微信返回的预付费交易会话标识previous _ id和随机字符串nonce_str。这两个参数将返回到您的applet,它在调整微信支付界面时需要这两个参数。
2.当小程序获得后台传递的参数时,它需要在后台传递五个参数,即时间戳、非时间戳、包、签名类型和支付签名。然后,当支付接口在小程序中被提升时,我们可以通过我们得到的参数来完成支付。
首先,构建后台界面。这里我们使用Django作为后台服务:
从django .快捷键导入渲染
#包装指南
来自django.http import HttpResponse,HttpResponseRedirect,JsonResponse
#导入类视图
从django.views导入视图
导入请求
导入hashlib
导入xmltodict
Client_appid='您的applet appid '
Mch_id='您的商户编号'
Mch_key='商户交易密钥'
def myindex(请求):
返回HttpResponse(“这里是主页”)
def myback(请求):
返回HttpResponse('这里是回调URL ')
def get_nonce_str():
导入uuid
返回字符串(uuid.uuid4())。替换('-','')
def getWxPayOrdrID():
导入日期时间
date=datetime.datetime.now()
#根据当前系统时间生成商品订单号。时间到微秒
payOrdrID=date . str time(“% Y % M % d % H % M % S % f”)
返回付款信息
#生成签名的函数
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,
sp bill _ create _ IP ' : spill _ create _ IP,
total_fee':total_fee,
trade_type': 'JSAPI '
}
#处理函数,以key=value格式和参数名称的ASCII字典顺序对参数排序
stringA=' '。join([“{ 0 }={ 1 }”。格式(k,ret.get(k))为k在sorted(ret)]
stringSignTemp=“{ 0 }键={1}”。格式(stringA,Mch_key)
sign=hashlib . MD5(StringSignTemp . encode(' utf-8 '))。hexdigest()
返回符号. upper()
def generate_sign(param):
''生成签名'''
stringA=' '
ks=已排序(param.keys())
打印(参数)
#参数排序
对于ks:中的k
stringA=(k '=' param[k]' ')
#缝合商家密钥
stringSignTemp=StringA ' key=' Mch _ key
# md5加密,但也有其他方式
hash _ MD5=hashlib . MD5(StringSignTemp . encode(' utf8 '))
sign=hash_md5.hexdigest()。上()
返回标志
#获取所有参数信息,打包成xml,传openid和客户端ip,价格需要自己获取传进去
def get_bodyData(openid,client_ip,price):
正文='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 '
body data=' AppID ' client _ AppID '/AppID ' # applet id
BodyData='body' body '/body' #商品描述
body data=' mch _ id ' mch _ id '/mch _ id ' #商户编号
body data=' nonce _ str ' nonce _ str '/nonce _ str ' # random string
body DATa=' notify _ URL ' notify _ URL '/notify _ URL ' #支付成功的回调地址
body DATa=' open id ' open id '/open id ' #用户标识
正文数据=' out _ trade _ no ' out _ trade _ no '/out _ trade _ no ' #商户订单号
body DATa=' sp bill _ create _ IP ' client _ IP '/sp bill _ create _ IP ' #客户端终端互联网协议(互联网协议)
正文数据=' total _ fee ' total _ fee '/total _ fee ' #总金额单位为分
正文数据=' trade _ typeJSAPI/trade _ type ' #交易类型小程序取值如下:JSAPI
bodyData='sign' sign '/sign '
bodyData='/xml '
返回车身数据
#统一下单支付接口
延期付款(请求):
导入时间
#获取价格单位是分
price=int(请求. GET.get('price ',1))
#获取客户端互联网协议(互联网协议的缩写)
client_ip,port=request.get_host().拆分(' : ')
#获取小程序信息
# OpenID=' 2fa 5 C2 bn 77 ooh 1 hfydx k4 pvjc '
openid=请求. GET.get('openid ')
#请求微信的全球资源定位器(统一资源定位符)
URL=' https://API。mch。微信。QQ。' com/pay/United order '
#拿到封装好的可扩展标记语言数据
body_data=get_bodyData(openid,client_ip,price)
#获取时间戳
timeStamp=str(int(time.time()))
#请求微信接口下单
响应=请求。post(URL,body_data.encode('utf-8 '),header={ ' Content-TYPe ' : ' application/XML ' })
print(respone.content)
#回复数据为xml,将其转为字典
content=xmltodict。解析(响应。内容)
打印(内容)
return _ code=content[' XML '][' return _ code ']
if return_code=='SUCCESS':
预付id=内容['xml']['预付id']
# 时间戳
timeStamp=str(int(time.time()))
# 5.五个参数
数据={
appId':client_appid,
nonceStr ' : get _ nonce _ str(),
包' : '预付_id='预付_id,
签名类型: 'MD5 ',
TiMer ' : TiMer,
}
# 6.支付签名签名
paySign=generate_sign(数据)
数据['paySign']=paySign #加入签名
打印(数据)
# 7.传给前端的签名后的参数
返回JsonResponse(数据,safe=False,JSON _ dumps _ params={ ' confirm _ ascii ' : False })
else:
返回HttpResponse('请求支付失败)
剩下的就简单了,在前端没朋友写支付请求逻辑,由前端请求后端的框架统一支付接口,获取关键的五个变量,随后利用这五个变量,请求微信官网支付接口,完成支付逻辑
paytest(){
console.log('支付测试');
控制台。log(这个。用户信息。open id);
wx.request({
URL : ' http://127。0 .0 .1:8000/pay/',
header: {
内容类型' : '应用程序/json '
},
数据: { ' OpenID ' :这个。userinfo。OpenID,' price': 1},
成功:功能(res) {
wx.requestPayment({
时间戳: RES .数据。时间戳,
非波峰:分辨率数据。非波峰,
package: res.data.package,
signType: res.data.signType,
paySign: res.data.paySign,
成功' :功能(res) {
console.log(res)
},
失败' :功能(res) {
console.log(res)
}
})
}
})
}
需要注意的是,请求后台接口时,openid和价格是必须要传递的,openid是微信小程序当前用户的标识,而价格是价格,单位是分
最后,完成了支付,没什么难的,有一些地方需要提醒:后台接口如果需要在本地调试的话,只能用127.0.0.1这种互联网协议(互联网协议的缩写)的形式,微信不支持localhost,另外需要xmltodict这个三方库将微信统一支付接口返回的可扩展标记语言转成迪克特,话说都什么年代了,微信接口居然还在使用xml。
11
2022-12
04
2022-06
17
2022-03
18
2021-11
19
2021-06
16
2021-06