一.微信小程序支付
真的,在接到這個(gè)任務(wù)的時(shí)候,本以為很簡(jiǎn)單,不就是普通的瀏覽器復(fù)制粘貼,最不濟(jì)找下gpt給生成一下,但是到實(shí)際開發(fā)就不同了,不是后端出問題就是前端,搜資料,上百度上google,基本每一個(gè)人講的都不一樣,不是這問題就是那問題,特別是微信官方,自己接口的邏輯也不整清楚,就算是報(bào)錯(cuò),參數(shù)錯(cuò)誤連個(gè)提示也沒有,而且用python寫后端的少之又少,我只是想說,python-flask寫接口簡(jiǎn)直不要太好用,java真的太胖了,這里的胖就是指的是,像小程序這種邏輯和體量并不大的項(xiàng)目來說,python作為后端就是不是太好用
二.前期準(zhǔn)備(你必須會(huì)的,要準(zhǔn)備的)
2.1你必須會(huì)的
uniapp開發(fā)小程序的前端
這個(gè)國內(nèi)的資源還是蠻全的,一搜一大把,先搜《uniapp開發(fā)第一個(gè)小程序hello word》一天搞點(diǎn)到入門
python-flask開發(fā)小程序的后端
這個(gè)更多,先搜《python-flask如何開發(fā)后端接口》
2.2要準(zhǔn)備的
appid:不用多說,小程序的appid
mch_id:商家號(hào),先搜《微信支付》,點(diǎn)擊進(jìn)去,一通申請(qǐng),一通綁定到小程序
今天篇文章主要是講代碼開發(fā)的,需要講講怎么綁定的可以評(píng)論,專門來講講怎么綁定怎么申請(qǐng)或者
文章最后會(huì)寫怎么聯(lián)系我
key:商家支付密鑰
沒了,沒了,就這三個(gè),基本就是登錄注冊(cè),得到這些玩意
三.開始第一步
首先你有個(gè)可以獲取openid的接口,可以就是我們python-flask里面寫就ok了
先看看整體
import flask
from flask import request, jsonify, send_file
from gevent import pywsgi
from flask_cors import CORS
import requests
import json
from datetime import datetime
import hashlib
import string
import random
import xmltodict
import time
import threading
#你的代碼區(qū)開始
#你的代碼區(qū)結(jié)束
if __name__ == '__main__':
server2 = pywsgi.WSGIServer(('0.0.0.0', 7004), server)
server2.serve_forever()
我們就往開發(fā)到結(jié)束來進(jìn)行講解
首先還是你要有一個(gè)獲取openid的接口
@server.route('/api/GetOpenid')
def GetOpenidYSGJ():
# 獲取用戶的code,從而獲取用戶的唯一標(biāo)識(shí)openid
code = request.args.get('code')
res = {}
if code!="":
response = requests.get('https://api.weixin.qq.com/sns/jscode2session?appid=xxxxxxxxxx&secret=1c56f6b24ad40c468879ae3bae6bcd5b&js_code='+code+'&grant_type=authorization_code')
resdata=json.loads(response.text)
try:
if resdata['openid'] != "":
res['openid'] = resdata['openid']
return res
else:
res['openid'] = "0"
return res
except:
res['openid'] = "0"
return res
else:
res['openid']="0"
return res
看懂了曬,前端訪問這個(gè)接口/api/GetOpenid,傳入code,code開發(fā)小程序的都是wx.login()或者uniapp開發(fā)的,uni.logo()就能獲取code,code以獲取就獲取到openid了
開始第二步
首先創(chuàng)建4個(gè)方法
1.獲取隨機(jī)字符串generate_nonce_str()
2.獲取簽名generate_sign((data, key),
3.將字典轉(zhuǎn)換為xml格式dict_to_xml(data)
4.將xml格式的數(shù)據(jù)轉(zhuǎn)換為字典xml_to_dict(xml_data)
分別是
def generate_nonce_str(length=32):
chars = string.ascii_letters + string.digits
return ''.join(random.choice(chars) for _ in range(length))
def generate_sign(data, key):
sorted_keys = sorted(data.keys())
stringA = '&'.join([f"{key}={data[key]}" for key in sorted_keys])
stringSignTemp = f"{stringA}&key={key}".encode('utf-8')
sign = hashlib.md5(stringSignTemp).hexdigest().upper()
return sign
def dict_to_xml(data):
"""
將字典轉(zhuǎn)換為xml格式
"""
xml_data = ["<xml>"]
for k, v in data.items():
xml_data.append(f"<{k}>{v}</{k}>")
xml_data.append("</xml>")
return "".join(xml_data)
def xml_to_dict(xml_data):
"""
將xml格式的數(shù)據(jù)轉(zhuǎn)換為字典
"""
xml_dict = {}
soup = BeautifulSoup(xml_data, 'xml')
for item in soup.find_all():
xml_dict[item.name] = item.text
return xml_dict
創(chuàng)建微信支付接口請(qǐng)求unifiedorder
@server.route('/api/unifiedorder', methods=['POST'])
def unifiedorder():
# 獲取請(qǐng)求中的訂單信息
data = request.json
# 獲取當(dāng)前時(shí)間戳
client_ip = request.headers.get('X-Forwarded-For', request.headers.get('X-Real-IP', request.remote_addr))
#獲取隨機(jī)字符串的方法
sss=generate_nonce_str()
# 構(gòu)造統(tǒng)一下單請(qǐng)求參數(shù)
params = {
'appid': '你的小程序appid',
'mch_id': '商品號(hào)',
'nonce_str': sss,
'body': data['body'],
'out_trade_no': data['out_trade_no'],
'total_fee': data['total_fee'],
'spbill_create_ip': client_ip,
'notify_url': 'https://xxxxxxxxxx/wallpaper/api/your_notify_url', # 異步通知地址
'trade_type': 'JSAPI', # 小程序支付
'openid': data['openid'], # 用戶在小程序中的openid
}
# 生成簽名
sign = generate_sign(params, '微信商戶的密鑰V2的')
params['sign'] = sign
param = {'root': params}
xml = xmltodict.unparse(param)
# 將參數(shù)轉(zhuǎn)換為 XML 格式
xml_data = dict_to_xml(params)
# 發(fā)送請(qǐng)求到微信支付服務(wù)器
response = requests.post('https://api.mch.weixin.qq.com/pay/unifiedorder', data=xml.encode('utf-8'),headers={'Content-Type': 'text/xml'})
# 解析微信支付服務(wù)器的響應(yīng)
result = xmltodict.parse(response.content.decode('utf-8'))
# 封裝返回結(jié)果
# 從微信支付服務(wù)器返回的結(jié)果中提取用于驗(yàn)證簽名的部分參數(shù)
result_params = {
'appId': '小程序的appid',
'timeStamp': str(int(time.time())),
'nonceStr': generate_nonce_str(),
'package': "prepay_id="+result['xml']['prepay_id'],
'signType': 'MD5',
}
result_params['paySign'] = generate_sign(result_params, '微信商戶的密鑰V2的')
return json.dumps(result_params)
開始第三步,回調(diào)地址
創(chuàng)建python回調(diào)地址接口
@server.route('/api/your_notify_url', methods=['POST'])
def handle_payment_notification():
# 處理微信支付結(jié)果異步通知的邏輯
data = request.data
# 在這里處理通知數(shù)據(jù),驗(yàn)證簽名等操作
print("有用戶充值啦")
# 解析微信支付服務(wù)器的響應(yīng)
result = xmltodict.parse(data.decode('utf-8'))
print(result)
#獲取openid
openid=result['xml']['openid']
#獲取充值了多少
cash_fee=result['xml']['cash_fee']
# 狀態(tài)
result_code = result['xml']['result_code']
# 狀態(tài)2
return_code = result['xml']['return_code']
# 訂單號(hào)
transaction_id = result['xml']['transaction_id']
if result_code=="SUCCESS" and return_code=="SUCCESS":
# 進(jìn)行你的數(shù)據(jù)處理
print(openid)
print(cash_fee)
print(type(cash_fee))
# 返回成功響應(yīng)給微信支付服務(wù)器
# 構(gòu)建回復(fù)內(nèi)容
response_data = {"code":"SUCCESS","message":"ok"}
return 'SUCCESS',200
開始第四步,前端調(diào)用
我這里用的前端是uniapp
創(chuàng)建按鈕進(jìn)行請(qǐng)求
就是一個(gè)簡(jiǎn)單的創(chuàng)建按鈕,然后綁定事件,舉例綁定的事件是chongzhi()
具體事件代碼就是
generateUniqueOrderNumber() {
// 這里可以使用你的邏輯生成唯一訂單號(hào)
return 'your_order_' + new Date().getTime();
},
chongzhi(amount){
const lll=this;
try{
// 假設(shè)以下參數(shù)是從前端獲取的
const body = "Kbit";
const total_fee = amount; // 訂單總金額,單位為分
const openid = uni.getStorageSync("openid");
// 生成商戶訂單號(hào),這里可以使用你自己的邏輯生成唯一訂單號(hào)
const out_trade_no = this.generateUniqueOrderNumber();
console.log("----------------"+out_trade_no)
// 發(fā)送支付請(qǐng)求
uni.request({
url: "https://你的服務(wù)器/api/unifiedorder",
method: "POST",
data: JSON.stringify({
body: body,
out_trade_no: out_trade_no,
total_fee: total_fee,
openid: openid,
}),
success: (res) => {
// 調(diào)起支付
uni.requestPayment({
provider: 'wxpay',
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);
if(res.errMsg=="requestPayment:ok"){
//成功付款,進(jìn)行查詢和提示成功
//查詢余額
//請(qǐng)求用戶的個(gè)人信息
uni.showToast({
title: "充值成功",
})
},
fail: function (err) {
console.log("失敗了")
console.log(err);
}
});
},
fail: (err) => {
console.error('支付請(qǐng)求失敗:', err);
uni.showToast({
title: err,
duration: 2000, // 提示的延遲時(shí)間,單位毫秒,默認(rèn)值 1500
mask: true, // 是否顯示透明蒙層,防止觸摸穿透,默認(rèn)值 false
success: function() {
// 提示框關(guān)閉后的回調(diào)函數(shù)
}
})
},
});
console.log(amount)
}catch (e) {
// TODO handle the exception
console.log("充值失敗,聯(lián)系客服")
console.log(e)
}
},
是不是超級(jí)的簡(jiǎn)單,很簡(jiǎn)單的四步就能充值成功,前端其實(shí)沒啥講的,主要是python來做微信支付的后端很少人講到,所以才寫了這一篇,希望能幫到大家
總結(jié)
總之就是一個(gè)很簡(jiǎn)單的v2版本的微信支付,簡(jiǎn)單來說就是3個(gè)外部接口,分別是獲取openid的接口、微信支付主接口和回調(diào)接口,其他4個(gè)方法主要是來處理數(shù)據(jù),前端更簡(jiǎn)單,傳入該傳入的值,金額,主要坑的點(diǎn)是在簽名環(huán)節(jié),網(wǎng)上很多方法,我這個(gè)方法是百分之百可以用的,不會(huì)出現(xiàn)簽名錯(cuò)誤
如果不懂的,可以通過關(guān)注微信公眾號(hào):程序員PG
來聯(lián)系我
這邊會(huì)提供文章來源:http://www.zghlxwxcb.cn/news/detail-814212.html
- 提供test的反向代理(如果沒有服務(wù)器想用自己的電腦當(dāng)服務(wù)器的,我可以用我的服務(wù)器給你做代理)
- 提供源碼,更進(jìn)一步的指導(dǎo)
- 提供技術(shù)服務(wù)
ok 這次就講到這里了,如果有大神或者其他伙伴看出問題的,歡迎評(píng)論,大家一起交流文章來源地址http://www.zghlxwxcb.cn/news/detail-814212.html
到了這里,關(guān)于uniapp前端+python后端=微信小程序支付到底怎么開發(fā)???國內(nèi)的資料為什么沒一篇能講清楚,簡(jiǎn)簡(jiǎn)單單的只需要3步就可以了-V2版本的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!