前提是已經(jīng)創(chuàng)建完應(yīng)用了在微信的官網(wǎng)上。根據(jù)上一篇的微信獲得支付能力的步驟,這一篇主要制作微信支付的demo。回顧上一篇內(nèi)容請看iOS微信支付步驟以及出現(xiàn)的問題總結(jié)(一)
查看下一篇iOS微信支付步驟以及出現(xiàn)的問題總結(jié)(三)?。
往往回憶就是痛苦的因?yàn)橛洸蛔≡?jīng)的經(jīng)歷,還是喜歡簡單粗暴。
1.微信支付的demo與SDK。網(wǎng)址
2.下載完之后,里面有好多的沒用的文件,包括登錄,分享,等等。(看到這里好惡心,為啥不單獨(dú)做一個demo呢,哎,還能不能愉快的玩耍了)。
如下 的文件夾目錄的內(nèi)容:
3.創(chuàng)建一個wxDemo工程。
4.查看微信的官方文檔。iOS微信支付文檔
5.因?yàn)楝F(xiàn)在 的工程是iOS9 ,所以需要配置網(wǎng)址與白名單。
6.改變bitcode設(shè)置為NO。
7.添加URL Types,如下。
8.添加微信SDK到wxDemo里面。
9.添加框架,用來安裝應(yīng)用。iOS文檔鏈接 。需要添加以下庫:
SystemConfiguration.framework,
libz.dylib,
libsqlite3.0.dylib,
libc++.dylib
如下圖:
10.在Appdelegate.m里面添加如下代碼:
//注冊微信支付
[WXApi ? ? ? registerApp:@"wxXXXXXXXXXX"]; 此時運(yùn)行編譯,快捷鍵commd+b 運(yùn)行程序會出現(xiàn)以下錯誤,以下是錯誤的信息:
Undefined symbols for architecture x86_64:
"_OBJC_CLASS_$_CTTelephonyNetworkInfo", referenced from:
objc-class-ref in libWeChatSDK.a(MTAHelper.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
錯誤的圖片:
11.修改錯誤操作,由于缺少一個依賴庫:添加一個CoreTelephony.frame 依賴庫,就可以解決了。
12.根據(jù)微信里面的demo,添加需要的代碼。以下是文件目錄的一些解釋:里面主要的方法就是支付的網(wǎng)絡(luò)請求以及調(diào)用微信客戶端的代碼。
13.添加一個按鈕的方法,實(shí)現(xiàn)支付。
說明:支付目前來說有兩種實(shí)現(xiàn)方式,一種是本地的app直接實(shí)現(xiàn)跳轉(zhuǎn)進(jìn)行支付;另一種方式是通過后臺服務(wù)器進(jìn)行網(wǎng)絡(luò)請求。下面的這一種是通過服務(wù)器進(jìn)行支付的跳轉(zhuǎn)。
- (void)WXPay {
NSString*urlString=@"http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php?plat=ios";
//解析服務(wù)端返回json數(shù)據(jù)
NSError*error;
//加載一個NSURL對象
NSURLRequest*request = [NSURLRequestrequestWithURL:[NSURLURLWithString:urlString]];
//將請求的url數(shù)據(jù)放到NSData對象中
NSData*response = [NSURLConnectionsendSynchronousRequest:requestreturningResponse:nilerror:nil];
if(response !=nil) {
NSMutableDictionary*dict =NULL;
//IOS5自帶解析類NSJSONSerialization從response中解析出數(shù)據(jù)放到字典中
dict = [NSJSONSerializationJSONObjectWithData:responseoptions:NSJSONReadingMutableLeaveserror:&error];
NSLog(@"********url:%@",urlString);
if(dict !=nil){
NSMutableString*retcode = [dictobjectForKey:@"retcode"];
if(retcode.intValue==0){
NSMutableString*stamp= [dictobjectForKey:@"timestamp"];
//調(diào)起微信支付 ?
//注意:此處的key一定要與demo中的key的字符一致,一個也不能少,一個也不能錯。
PayReq* req= [[PayReqalloc]init];
req.partnerId= [dictobjectForKey:@"partnerid"];
req.prepayId= [dictobjectForKey:@"prepayid"];
req.nonceStr= [dictobjectForKey:@"noncestr"];
req.timeStamp= stamp.intValue;
req.package= [dictobjectForKey:@"package"];
req.sign= [dictobjectForKey:@"sign"];
[WXApisendReq:req];
//日志輸出
NSLog(@"appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",[dictobjectForKey:@"appid"],req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.package,req.sign);
}else{
NSLog(@"%@",[dictobjectForKey:@"retmsg"]);
}
}else{
NSLog(@"服務(wù)器返回錯誤,未獲取json對象");
}
}else{
NSLog(@"服務(wù)器返回錯誤");
}
}
14.在完成此處之后,點(diǎn)擊支付按鈕會出現(xiàn)下面的問題:
在跳轉(zhuǎn)到支付界面之后,僅僅會出現(xiàn)一個“確定”的白色按鈕。如下圖:
通過查找信息,是由于配置的參數(shù)問題。因此我們不用服務(wù)器端進(jìn)行網(wǎng)絡(luò)請求直接用自己生成這些參數(shù),然后就可以實(shí)現(xiàn)支付功能了。
15.下面是獲取參數(shù)的解釋。
參數(shù)解釋:
partnerId:?商家向財(cái)付通申請的商家id(就是自己的id,也就是在你申請開發(fā)者資質(zhì)認(rèn)證之后,有一個商戶平臺,這個平臺對應(yīng)的id,就是你自己的id。好像還沒有說明白。)
獲取方式:
打開鏈接,直接將微信發(fā)送給你的郵件里面的內(nèi)容登陸商戶平臺,就找到了partnerid了。微信商戶平臺
prepayId:?預(yù)支付訂單(需要向微信服務(wù)器提交申請后返回的一個支付交易ID)
獲取方式:
這個一般情況下是服務(wù)器端已經(jīng)申請好的,客戶端直接調(diào)用。
a、微信的服務(wù)端返回的參數(shù)的說明:參數(shù)說明。(看著很亂,可是呢,還是太亂)
b、還要生成一個簽名,這個官方文檔也是寫了。簽名(雖然看著很簡單,但是還是搞不定,坑太多,哎,沒辦法就是這么坑,多看幾遍就好了)
根據(jù)微信的接口,返回的xml的數(shù)據(jù)參數(shù)。將數(shù)據(jù)解析之后,就能獲得prepayid。
nonceStr: 隨機(jī)串,防重發(fā)(隨機(jī)字符串,不長于32位)
獲取方式:
注意:#pragma mark-? 需要引入依賴庫libcommonCrypto.tbd并且引入頭文件#import <CommonCrypto/CommonGigest.h>
const ?char*str = [input ? UTF8String];
unsigned ? char ? result[CC_MD5_DIGEST_LENGTH];
CC_MD5(str,strlen(str),result);
NSMutableString* ?ret = [NSMutableString ?stringWithCapacity:CC_MD5_DIGEST_LENGTH*2];
for(int i = 0 ;i <CC_MD5_DIGEST_LENGTH;i++) {
?[ret appendFormat:@"%02X",result[i]];
}
NSLog(@"%@",[ret? uppercaseString]);
注意:就是一個隨機(jī)數(shù)。noncestr就是在第一次生成簽名的時候的那個隨機(jī)數(shù),不要再次生成。
timeStamp:時間戳,防重發(fā)(標(biāo)準(zhǔn)北京時間,時區(qū)為東八區(qū),自1970年1月1日 0點(diǎn)0分0秒以來的秒數(shù))
獲取方式:
NSString* timeString = [NSString ? ? ?stringWithFormat:@"%.0f"[[NSDate date]timeIntervalSince1970]];
由于:
@property(nonatomic,assign)UInt32 ?timeStamp;
所以在提交的時候需要轉(zhuǎn)換成對應(yīng)的格式,UInt32 格式。
sign:商家根據(jù)微信開放平臺文檔對數(shù)據(jù)做的簽名,鏈接
這里的簽名不同于你第一次申請的prepayid的簽名,這里的簽名的參數(shù)是appid,prepayid,partnerid,timestamp,noncestr,package ? 這幾個排序后再拼接的key最后生成一個sign。
上面這些只是介紹了這些參數(shù)如何獲取,在下面一篇文章中,開始仔細(xì)介紹,最后一步的支付流程,也就是配置參數(shù)、服務(wù)器相關(guān)的一些配置。
參考資源:
2.iOS微信支付