前言
??上一篇寫了下支付寶綁定和支付寶支付的功能,接下來寫一下微信綁定和微信支付的功能。在此做個(gè)記錄,如果有說的不對(duì)的地方,歡迎大佬指出并糾正。
微信授權(quán)
??微信授權(quán)其實(shí)就是使用微信第三方登錄,需要用戶同意授權(quán),使用微信登錄你的 APP,這樣你的 APP 就可以通過微信 SDK 提供的接口去獲取對(duì)應(yīng)的微信信息。例如:你的微信賬戶的唯一標(biāo)示等。
-
微信授權(quán)流程圖
授權(quán)流程 - 微信授權(quán)流程
- APP 通過在微信開放者平臺(tái)注冊(cè)拿到的AppID去喚起微信SDK。
- 微信開放平臺(tái)返回臨時(shí)票據(jù)(code)。
- 通過臨時(shí)票據(jù)(code)去和appId以及appSecret向微信開放平臺(tái)換取access_token,這一步可以放在前段處理也可以放在后端處理,推薦放在后端,理由是因?yàn)楹蠖颂幚硐啾惹岸胃踩?/li>
- 拿到上一步換取到的access_token去調(diào)用微信開發(fā)平臺(tái)提供的微信授權(quán)接口完成授權(quán)。
- 微信授權(quán)代碼示例
/// 微信登錄
///
/// - Parameter auth: 授權(quán)信息(存在默認(rèn)值)
public func sendAuthResp(auth: WechatAuth? = nil) {
let req = SendAuthReq()
if auth == nil {
req.scope = "snsapi_userinfo,snsapi_base"
req.state = "0774"
} else {
req.scope = auth!.scope
req.state = auth!.state
}
WXApi.send(req)
}
??其中SendAuthReq中的scope是用戶授權(quán)的作用域,使用逗號(hào)(,)分隔,如獲取用戶個(gè)人信息則填寫snsapi_userinfo。state是第三方程序本身用來標(biāo)識(shí)其請(qǐng)求的唯一性,用于保持請(qǐng)求和回調(diào)的狀態(tài),授權(quán)請(qǐng)求后原樣帶回給第三方。
public func onReq(_ req: BaseReq!) {
}
public func onResp(_ resp: BaseResp!) {
if resp.isKind(of: SendAuthResp.self) {
// 微信登錄,在這里拿到臨時(shí)票據(jù)(code)去換取access_token
/*
前段獲?。? 1.請(qǐng)求該鏈接去獲取access_token:
http請(qǐng)求方式: GET
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
返回成功的格式為:
{
"access_token":"ACCESS_TOKEN",
"expires_in":7200,
"refresh_token":"REFRESH_TOKEN",
"openid":"OPENID",
"scope":"SCOPE",
"unionid":"o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
2.請(qǐng)求該鏈接去獲取用戶的個(gè)人信息:
http請(qǐng)求方式: GET
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
正確的Json返回結(jié)果:
{
"openid":"OPENID",
"nickname":"NICKNAME",
"sex":1,
"province":"PROVINCE",
"city":"CITY",
"country":"COUNTRY",
"headimgurl": "http://wx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
"privilege":[
"PRIVILEGE1",
"PRIVILEGE2"
],
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
*/
/*
后端獲?。簩⑴R時(shí)票據(jù)(code)傳給App Service,由App Service向微信平臺(tái)去獲取access_token
然后再通過access_token去獲取用戶信息,最后將用戶信息返回給App
*/
} else if resp.isKind(of: PayResp.self) {
// 微信支付
} else if resp.isKind(of: SendMessageToWXResp.self) {
// 微信分享
}
}
}
微信支付
-
微信支付流程圖
微信支付流程圖.png - 微信支付流程
- APP 用戶通過訂單信息告訴App Service將要進(jìn)行微信支付。
- App Service通過訂單信息去微信平臺(tái)獲取微信支付的訂單信息。
- App Service把微信支付的訂單信息返回給App。
- App拿到App Service返回的微信支付的訂單信息去喚起微信完成支付。
- 微信支付代碼示例
public func onReq(_ req: BaseReq!) {
}
public func onResp(_ resp: BaseResp!) {
if resp.isKind(of: SendAuthResp.self) {
// 微信登錄
} else if resp.isKind(of: PayResp.self) {
// 微信支付
payRespHandle(resp: resp as! PayResp)
} else if resp.isKind(of: SendMessageToWXResp.self) {
// 微信分享
}
}
fileprivate func payRespHandle(resp: PayResp) {
if resp.errCode == WXSuccess.rawValue {
print("WechatPay Success")
paySuccessHandle?(resp.returnKey)
} else if resp.errCode == WXErrCodeUserCancel.rawValue {
print("WechatPay UserCancel")
payCancelHandle?()
} else {
let error = WechatError(domain: "微信支付錯(cuò)誤信息", code: resp.errCode, meesgae: resp.errStr)
payFailedHandle?(error)
}
}
注意
-
access_token是調(diào)用授權(quán)關(guān)系接口的調(diào)用憑證,由于access_token有效期(目前為2個(gè)小時(shí))較短,當(dāng)access_token超時(shí)后,可以使用refresh_token進(jìn)行刷新。refresh_token擁有較長(zhǎng)的有效期(30天)且無法續(xù)期,當(dāng)refresh_token失效的后,需要用戶重新授權(quán)后才可以繼續(xù)獲取用戶頭像昵稱。 - 在用戶修改微信頭像后,舊的微信頭像URL將會(huì)失效,所以在獲取用戶信息后,將頭像圖片保存下來,避免微信頭像URL失效后的異常情況

