引言
集成微信SDK就不廢話了,在微信第三方登錄做了介紹躺同,傳送門:微信第三方登錄
簽名
微信支付個(gè)人覺得最難的就是簽名這個(gè)概念。其實(shí)就是拼接參數(shù)然后MD5加密得到的一串字符串一樣的東西。而當(dāng)我們要去請求微信官方的接口必須帶上簽名這個(gè)參數(shù)扯俱,關(guān)于簽名的校驗(yàn)官方也提供了校驗(yàn)工具微信官方校驗(yàn)工具
1.統(tǒng)一下單
- URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder
統(tǒng)一下單請求參數(shù).png - 大概意思就是要傳這些參數(shù)給微信,統(tǒng)一下單所需的參數(shù)中的 sign 我們叫一次簽名喇澡。
1.請求統(tǒng)一下單接口如果成功迅栅,會返回預(yù)支付訂單號prepay_id
2.調(diào)起支付接口
- 在開發(fā)中,我們有簽名的地方一般都會放在后臺去處理晴玖,所以下面代碼是我請求我們服務(wù)器读存,讓后臺去統(tǒng)一下單,返回給我調(diào)起微信支付接口所需要的參數(shù)呕屎。
func getData(_ oids: String){
let url = "http://m.tdamm.com/goods/pay/paydo?oids=\(oids)&pay_type=wxpay"
RequestTool.POSTRequestWith(url, parameters: nil, success: { (task, data) in
let dict = data as! NSDictionary
var code = dict.object(forKey: "code") as! Int
if code == 200{
let pay_info = (dict.object(forKey: "data") as! NSDictionary).object(forKey: "pay_info") as! NSDictionary
let prepay_id = pay_info.object(forKey: "prepay_id") as! String
let sign = (dict.object(forKey: "data") as! NSDictionary).object(forKey: "sign") as! String
let noncestr = (dict.object(forKey: "data") as! NSDictionary).object(forKey: "noncestr") as! String
let time = (dict.object(forKey: "data") as! NSDictionary).object(forKey: "timestamp") as! Int
//調(diào)起微信
let req = PayReq()
//應(yīng)用的AppID(固定的)
req.openID = WXAppID
//商戶號(固定的)
req.partnerId = WXPartnerID
//擴(kuò)展字段(固定的)
req.package = "Sign=WXPay"
//統(tǒng)一下單返回的預(yù)支付交易會話ID
req.prepayId = prepay_id
//隨機(jī)字符串
req.nonceStr = noncestr
//時(shí)間戳(10位)
req.timeStamp = UInt32(time)
//簽名
req.sign = sign
WXApi.send(req)
}
}) { (task, error) in
print(error)
}
}
- 從代碼來看让簿,很清楚IOS調(diào)起微信支付接口需要7個(gè)參數(shù),分別是
//應(yīng)用的AppID(固定的)
req.openID = WXAppID
//商戶號(固定的)
req.partnerId = WXPartnerID
//擴(kuò)展字段(固定的)
req.package = "Sign=WXPay"
//統(tǒng)一下單返回的預(yù)支付交易會話ID
req.prepayId = prepay_id
//隨機(jī)字符串
req.nonceStr = noncestr
//時(shí)間戳(10位)
req.timeStamp = UInt32(time)
//簽名
req.sign = sign
而這次要用到的sign我們稱為二次簽名秀睛,因?yàn)橐婚_始后臺不知道生成這個(gè)sign要用什么參數(shù)尔当,所以我自己在iOS端自己MD5加密了。下面是我網(wǎng)上找的MD5加密擴(kuò)展方法蹂安。
extension String {
// MD5 加密字符串
var MD5: String {
let cStr = self.cString(using: .utf8);
let buffer = UnsafeMutablePointer<UInt8>.allocate(capacity: 16)
CC_MD5(cStr!,(CC_LONG)(strlen(cStr!)), buffer)
let md5String = NSMutableString()
for i in 0..<16 {
md5String.appendFormat("%02x", buffer[i])
}
free(buffer)
return md5String as String
}
}
let strA = "appid=\(WXAppID)&noncestr=\(noncestr)&package=Sign=WXPay&partnerid=\(WXPartnerID)&prepayid=\(prepay_id)×tamp=\(time)"
req.sign = ("\(strA)&key=\(key)").MD5.uppercased()
- 通過上面的加密代碼居凶,第二次簽名生成所需的參數(shù)就一目了然了虫给,注意順序和大小寫,一共是7個(gè)參數(shù)侠碧,分別是appid抹估,noncestr,package弄兜,partnerid药蜻,prepayid,timestamp替饿,key(其中的key是你的商戶秘鑰语泽,官方給出的key設(shè)置路徑:微信商戶平臺(pay.weixin.qq.com)-->賬戶設(shè)置-->API安全-->密鑰設(shè)置)。不得不吐槽的就是视卢,當(dāng)初給我的key是錯(cuò)誤的踱卵,導(dǎo)致一直彈簽名失敗的提示框,真的很坑据过。
微信官方校驗(yàn)工具通過這個(gè)工具惋砂,如果和你生成的sign一樣,那你就要看下是不是有的參數(shù)錯(cuò)了绳锅。
3.最后在你的AppDeleate中加入微信的回調(diào)方法
- 當(dāng)然也別忘記了注冊微信(注冊了就無視)
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
//MARK: -注冊微信
WXApi.registerApp(WXAppID)
return true
}
// 微信回調(diào)
func onResp(_ resp: BaseResp!) {
var strTitle = "支付結(jié)果"
var strMsg = "what:\(resp.errCode)"
print(resp.errCode)
// 微信支付回調(diào)
if resp.isKind(of: PayResp.self)
{
print("retcode = \(resp.errCode), retstr = \(resp.errStr)")
switch resp.errCode
{
// 支付成功
case 0 :
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "WXPaySuccessNotification"), object: nil)
// 支付失敗
default:
WXPayFail()
}
}
// 微信登錄回調(diào)
if resp.errCode == 0 && resp.type == 0{//授權(quán)成功
let response = resp as! SendAuthResp
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "WXLoginSuccessNotification"), object: response.code)
}
}
總結(jié)
總體來說代碼很簡單西饵,如果后臺把調(diào)用統(tǒng)一下單接口,二次簽名之后鳞芙,直接返回給你對應(yīng)的參數(shù)眷柔,你直接拿后臺返回給你的參數(shù),一一對應(yīng)的微信調(diào)起接口的參數(shù)就可以了原朝。但是由于后臺一開始沒做過驯嘱,所以我也當(dāng)系統(tǒng)的了解一下微信支付的流程吧。