知識
不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!
微信小程序支付功能詳細分析(一、預支付)
發(fā)表時間:2020-10-19
發(fā)布人:葵宇科技
瀏覽次數(shù):121
微信小程序支付功能詳細分析
小記:最近在做微信小程序的支付,中間也遇到了很多問題,總結(jié)一下,給大家避個坑,也給自己記錄一下后面可以作為參考
概要
本文中只寫執(zhí)行邏輯,跟一些算法,不包含具體代碼內(nèi)容,目前開發(fā)采用的是微信小程序、nginx+uwsgi+python+flask
微信小程序支付
官方文檔:https://developers.weixin.qq.com/miniprogram/dev/framework/
整體邏輯
首先先看下整體邏輯
整體邏輯
https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_4&index=3
這個是官方給出的 小程序支付的流程圖,我們來分布講解一下
首先先講解下邏輯,用戶點擊下單,并不是直接小程序發(fā)送給微信后臺服務器,而是小程序把數(shù)據(jù)傳輸給我們自己的服務器,通過我們自己的服務器跟微信后臺服務器交互后獲取支付數(shù)據(jù)傳輸給微信小程序客戶端,再由微信小程序通過統(tǒng)一的支付函數(shù),直接發(fā)送給微信后臺服務器,支付成功,成功后微信后臺服務器會給我們的服務器和微信小程序發(fā)支付成功信息。
為了方便理解,我們把我微信小程序簡稱(客戶端),我們自己的服務器簡稱(A服務器),微信后臺的服務器簡稱(B服務器)
可以看到我們在整個支付流程中, 向B服務器發(fā)送過兩次的支付請求,一次是A服務器發(fā)出,一次是微信小程序發(fā)出。 第一次稱為預支付,第二次才是下單
預支付
我們先講一下預支付
預支付就是A服務器使用統(tǒng)一下單命令向B服務器發(fā)送數(shù)據(jù)并返回一個json數(shù)據(jù),這個json數(shù)據(jù)到時候是要發(fā)送給客戶端,完成第二次下單操作的參數(shù)
預支付步驟:
關于 統(tǒng)一下單 需要幾個參數(shù)我們需要先獲取一下:
1、openid (用戶標識)
2、nonce_str (隨機字符串)
3、out_trade_no (商戶訂單號)
4、sign (簽名)
1、openid(用戶標識)
首先客戶端提起支付請求,我們需要先把微信客戶端的用戶登陸憑證獲取到,然后發(fā)送給A服務器
//微信小程序 js代碼
//微信登陸,獲取代碼,發(fā)送A服務器 并獲取結(jié)果(即openid)
wx.login({
success: function (res) { //登陸成功,獲取用戶登陸憑證 res.code
if (res.code) {
wx.request({ //發(fā)送數(shù)據(jù)給A服務器
url: 'https://你自己的服務器',
data: {
code: res.code, //用戶登陸憑證,這個后面用戶換取openid的東西 主要作用參考圖 2
ordercode: ordercode, //支付金額
},
method: 'post',
success: function (res) {
//返回的數(shù)據(jù)我們待會在做詳細講解///
}
})
} else {
console.log('獲取用戶登錄態(tài)失敗!' + res.errMsg)
}
}
});
圖2
wx.login
官方文檔:https://developers.weixin.qq.com/miniprogram/dev/api/open-api/login/wx.login.html
接下來的部分就全部是 A B兩個服務器之間的數(shù)據(jù)互換了
把A服務器剛才獲取到的數(shù)據(jù),發(fā)送給B服務器,獲取openid(這個相當于客戶的id,在我們自己的小程序中是唯一的,用于辨識是哪個用戶)
下面是openid獲取的演示
# A服務器 python
#后臺我使用的是python 只講下邏輯
#比如下面這個data就是前端發(fā)過來的數(shù)據(jù)
data:{
code: "aaabbbcccc",
ordercode: 100,
}
#定義一個獲取openid 的函數(shù),把整個data都傳進去
def getOpenID(kwargs):
param = {
'code': kwargs['code'], #前端獲取到的用戶登陸憑證
'appid': "wxd00000000000000", #小程序的appid
'secret': "000000000000000000000000",#商戶的密鑰
'grant_type': 'authorization_code', #這個直接固定死值就可以了
}
# 通過code獲取openid
openIdUrl = 'https://api.weixin.qq.com/sns/jscode2session?appid={}&secret={}&js_code={}&grant_type=authorization_code'.format(
param['appid'], param['secret'], param['code'])
resp = requests.get(openIdUrl)
#一定要使用get獲取,不用使用post
#成功后的值
# {
# "openid":"xxxxxxxxxxxxxxxx",
# "session_key":"xxxxxxxxxxxxx"
# }
openId = json.loads(resp.text)
return openId['openid']
getOpenID(data) #執(zhí)行函數(shù)
openid獲取
參考官方文檔:https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/login/auth.code2Session.html
目前我們獲取到了openid
2、nonce_str (隨機字符串)
這個作用主要是為了防止別人模仿發(fā)送假的數(shù)據(jù)給微信,不用太糾結(jié)作用,寫入就可以了,下面講下他的生成方法
官方解釋
#A服務器 python
def get_nonce_str():
char = "abcdefghijklmnopqrstuvwxyz0123456789"
nonce_str = ""
for i in range(0, 32):
rad_num = random.randint(0, len(char) - 1)
nonce_str += char[rad_num]
nonce_str = nonce_str .upper() #注意:最后要全部處理成大寫
return nonce_str
隨機字符串
參考官方文檔:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3
3、out_trade_no (商戶訂單號)
這個就是你自己定義一個訂單號,保證唯一性,可隨意定制
4、sign (簽名)
簽名,主要是防止被偽造,官方給出了簽名算法
簽名生成的通用步驟如下:
第一步,設所有發(fā)送或者接收到的數(shù)據(jù)為集合M,將集合M內(nèi)非空參數(shù)值的參數(shù)按照參數(shù)名ASCII碼從小到大排序(字典序),使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特別注意以下重要規(guī)則:
◆ 參數(shù)名ASCII碼從小到大排序(字典序); ◆ 如果參數(shù)的值為空不參與簽名; ◆ 參數(shù)名區(qū)分大小寫; ◆
驗證調(diào)用返回或微信主動通知簽名時,傳送的sign參數(shù)不參與簽名,將生成的簽名與該sign值作校驗。 ◆
微信接口可能增加字段,驗證簽名時必須支持增加的擴展字段
第二步,在stringA最后拼接上key得到stringSignTemp字符串,并對stringSignTemp進行MD5運算,再將得到的字符串所有字符轉(zhuǎn)換為大寫,得到sign值signValue。◆ key設置路徑:微信商戶平臺(pay.weixin.qq.com)–>賬戶設置–>API安全–>密鑰設置
我們這邊來實現(xiàn)一下
#A服務器 python
# MD5加密
def MD5(str):
md5 = hashlib.md5()
md5.update(str.encode('utf-8'))
return md5.hexdigest()
#簽名
def getSign(kwargs):
keys, paras = sorted(kwargs), [] #先排序
paras = ['{}={}'.format(key, kwargs[key]) for key in keys if key != ''] #去除空值,把格式轉(zhuǎn)換成key=value
stringA = '&'.join(paras) #連接在一起
stringSignTemp = stringA + '&key=' + "xxxxxxxxx" #添加密鑰
sign = MD5(stringSignTemp).upper() #MD5加密
return sign
#1、根據(jù)key排序
#2、去除key為空的值
#3、json格式轉(zhuǎn)程字符串 key = value
#4、字符串添加密鑰
#5、MD5加密 并轉(zhuǎn)大寫
簽名
參考官方文檔:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=4_3
函數(shù)大家都會寫,那里面提到的參數(shù)到底是什么數(shù)據(jù)呢,其實就是統(tǒng)一下單你要提交的所有數(shù)據(jù)
圖片
圖片文獻官方文檔:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1#
就是把里面所有的必填項寫成json,其中的sign 不要寫進去,雖然他是必填,但不要寫進去,這點官方文檔沒有說明
#A服務器 python
pay_info = {
"appid": "xxxxxxxxxxxxxxxxx", #小程序的appid
"mch_id": "xxxxxxxxxxxxxx", #微信支付分配的商戶號
"nonce_str": get_nonce_str(), #隨機字符串 參考2
"body": "產(chǎn)品名稱",
"out_trade_no": out_trade_no, #商戶訂單號 參考3
"total_fee": 1, #費用
"spbill_create_ip": "000.000.000.000",#就是你A服務器的ip
"notify_url": "https://xxxxxx", #這個是支付成功后會返回支付詳情,就返回到你寫的這個網(wǎng)址
"trade_type": "JSAPI", #不用改
"openid": openID, #你剛才獲取的openid
}
getSign(pay_info) #把這個json去生成加密得到 sign
簽名雖然獲取完了,最后還要把剛才的要傳輸?shù)臄?shù)據(jù)xml格式化
pay_info['sign'] = getSign(pay_info)
#注意:要先把生成的sign 放入到剛才的 json里面去,然后再去轉(zhuǎn)xml
#轉(zhuǎn)換成xml
def getxml(kwargs):
# 生成xml
xml = ''
for key, value in kwargs.items():
xml += '<{0}><{1}></{0}>\n'.format(key, value)
xml = '<xml>{0}</xml>'.format(xml)
xml = xml.encode('utf-8')
# print(xml)wx
return xml
此時所有數(shù)據(jù)都獲取完了,也xml格式化成 微信支付中統(tǒng)一下單的格式了,我們下面發(fā)送給B服務器,獲取后面第二步下單的數(shù)據(jù)就可以了
最后一步,統(tǒng)一下單
講幾個著重點:
發(fā)送的一定要是最后格式化的xml
post發(fā)送
發(fā)送的網(wǎng)址:https://api.mch.weixin.qq.com/pay/unifiedorder
def wxpay(xml):
oUrl = 'https://api.mch.weixin.qq.com/pay/unifiedorder'
resp = requests.post(Url, data=xml)
return resp.content
統(tǒng)一下單
參考官方文檔:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_1#
以為結(jié)束了,不,這里有個小坑,一定要注意下
獲取到的數(shù)據(jù) 是不能直接傳給 客戶端的 傳給客戶端的需要是(第2步 下單)所需要的數(shù)據(jù)
這個我們下一張再講吧
藍框部分咱們已經(jīng)全部完成了
相關案例查看更多
相關閱讀
- SEO
- 云南網(wǎng)絡公司
- 小程序公司
- 網(wǎng)頁制作
- 人口普查小程序
- 網(wǎng)站上首頁
- 云南軟件定制
- 小程序密鑰
- 云南網(wǎng)站建設首選
- 云南小程序開發(fā)首選品牌
- 小程序的開發(fā)公司
- 旅游網(wǎng)站建設
- 云南企業(yè)網(wǎng)站
- 云南省建設廳網(wǎng)站
- 貴州小程序開發(fā)
- 網(wǎng)站建設特性
- 報廢車管理系統(tǒng)
- 昆明小程序開發(fā)聯(lián)系方式
- 南通小程序制作公司
- 網(wǎng)站沒排名
- 小程序定制開發(fā)
- 百度小程序開發(fā)
- 麗江小程序開發(fā)
- 網(wǎng)站建設優(yōu)化
- 海報插件
- 服務器
- 云南軟件定制公司
- 網(wǎng)絡公司報價
- 百度小程序公司
- 云南網(wǎng)絡推廣