前言
雖然ApplePay的進軍中國市場,但是就目前而言,微信支付和支付寶仍占據(jù)主導地位,本章主要是介紹項目中的微信支付是如何集成SDK的.想要了解更多關于iOS的知識,可以關注我的微博,@WilliamAlex大叔一起分享今天學到的iOS相關知識.
集成微信支付的主要思路
- 思路 : 在集成之前,我們先要詳細了解官方文檔中微信支付這一板塊,它已經(jīng)給我們提出了集成步驟.
- 主要步驟 :
1, 項目設置APPID
2, 注冊APPID
3, 調(diào)起支付
4, 處理支付結果的回調(diào)
- 詳細說明步驟;
1, 設置項目的APPID:
商戶在微信開放平臺申請開發(fā)APP應用后趁蕊,微信開放平臺會生成APP的唯一標識APPID。在Xcode中打開項目市埋,設置項目屬性中的URL Schemes為您的APPID
2, 注冊APPID:
商戶APP工程中引入微信lib庫和頭文件,調(diào)用API前甥捺,需要先向微信注冊您的APPID
3, 調(diào)起支付:
商戶服務器生成支付訂單淹辞,先調(diào)用【統(tǒng)一下單API】生成預付單牛隅,獲取到prepay_id后將參數(shù)再次簽名傳輸給APP發(fā)起支付
4, 處理支付結果的回調(diào):
照微信SDK Sample飘庄,在類實現(xiàn)onResp函數(shù)脑蠕,支付完成后,微信APP會返回到商戶APP并回調(diào)onResp函數(shù)竭宰,開發(fā)者需要在該函數(shù)中接收通知空郊,判斷返回錯誤碼,如果支付成功則去后臺查詢支付結果再展示用戶實際支付結果切揭。注意 一定不能以客戶端返回作為用戶支付的結果,應以服務器端的接收的支付通知或查詢API返回的結果為準
- 微信注冊ID :wxb4ba3c02aa476ea1: 這個ID可以直接在下載的示例項目SDKSample中的AppDelegate中找到
集成思路明白以后,我們開始集成微信支付
集成前的準備工作
-
了解微信開發(fā)文檔
-
文檔中需要注意的點
-
我們只需要根據(jù)文檔中的提示步驟即可集成
-
下載官方文檔中提供的頭文件和靜態(tài)庫
-
創(chuàng)建自己的一個項目集成微信支付
-
導入頭文件
-
-
編譯后可能會報很多錯誤,這時候我們需要導入相關的依賴文件
-
編譯項目項目會崩潰掉,錯誤提示我們需要在info.plist文件中添加兩個key
-
添加的結果
-
項目APPID的設置
-
注冊APPID
-
向微信注冊支付
-
-
調(diào)起微信支付
- 注意: 這個方法是監(jiān)聽模擬微信支付按鈕的方法
-
具體實現(xiàn)
- 處理支付結果的回調(diào)
- 注意: 處理支付結果的回調(diào)是代理方法,所以需要遵守協(xié)議.
- 代碼實現(xiàn)
- 向微信注冊(注冊ID:wxb4ba3c02aa476ea1)
// 導入頭文件,第一步就是向微信注冊.
#import "AppDelegate.h"
#import "WXApi.h"
@interface AppDelegate ()<WXApiDelegate>
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//向微信注冊
[WXApi registerApp:@"wxb4ba3c02aa476ea1" withDescription:@"com.William.Alex"];
return YES;
}
注意點 :
1,注冊時的ID是根據(jù)公司要求到微信公眾平臺申請注冊的,需要300元人民幣,所以我這里就用官方文檔中提供測試用的ID.
2, 項目中遵守了代理協(xié)議,主要是用于處理支付結果回調(diào)使用,后面會用到.
調(diào)起微信支付
#import "ViewController.h"
#import "WXApi.h"
@interface ViewController ()
@end
@implementation ViewController
/**
* 調(diào)起微信支付
*/
- (IBAction)payFormoneryInAlexWallet {
NSString *res = [self jumpToBizPay];
if( ![res isEqual:@""] ) {
UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"支付失敗"
message:res
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
// 提示用戶支付失敗,res是支付失敗后系統(tǒng)返回的信息
NSLog(@"支付失敗信息%@",res);
[alter show];
}
}
- (NSString *)jumpToBizPay {
// 判斷用戶當前用戶是否下載微信/是否支持微信支付
if ( ![WXApi isWXAppInstalled] ) { // 表示用戶沒有安裝微信
// 提示用戶需要安裝微信才能使用微信支付
NSLog(@"需要安裝微信才能使用微信支付");
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"支付失敗"
message:@"是否前往Appstore中下載微信"
delegate:self
cancelButtonTitle:@"取消"
otherButtonTitles:nil, nil];
[alertView show];
return nil;
}else if(![WXApi isWXAppSupportApi])
{ // 表示當前不支持微信支付
// 提示用戶當前環(huán)境不支持微信支付
NSLog(@"不支持微信支付");
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"支付失敗"
message:@"當前不支持微信支付"
delegate:self
cancelButtonTitle:@"取消"
otherButtonTitles:nil, nil];
[alertView show];
return nil;
}
NSString *urlString = @"http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php?plat=ios";
//解析服務端返回json數(shù)據(jù)
NSError *error;
//加載一個NSURL對象
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
//將請求的url數(shù)據(jù)放到NSData對象中
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
if ( response != nil) {
NSMutableDictionary *dict = NULL;
//IOS5自帶解析類NSJSONSerialization從response中解析出數(shù)據(jù)放到字典中
dict = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&error];
NSLog(@"url:%@",urlString);
if(dict != nil){
NSMutableString *retcode = [dict objectForKey:@"retcode"];
if (retcode.intValue == 0){
NSMutableString *stamp = [dict objectForKey:@"timestamp"];
//調(diào)起微信支付
PayReq* req = [[PayReq alloc] init]; // 將autoresease去掉,類方法變?yōu)閷ο蠓椒纯? req.partnerId = [dict objectForKey:@"partnerid"];
req.prepayId = [dict objectForKey:@"prepayid"];
req.nonceStr = [dict objectForKey:@"noncestr"];
req.timeStamp = stamp.intValue;
req.package = [dict objectForKey:@"package"];
req.sign = [dict objectForKey:@"sign"];
[WXApi sendReq:req];
//日志輸出
NSLog(@"appid=%@\npartid=%@\nprepayid=%@\nnoncestr=%@\ntimestamp=%ld\npackage=%@\nsign=%@",[dict objectForKey:@"appid"],req.partnerId,req.prepayId,req.nonceStr,(long)req.timeStamp,req.package,req.sign );
return @"";
}else{
return [dict objectForKey:@"retmsg"];
}
}else{
return @"服務器返回錯誤锁摔,未獲取到json對象";
}
}else{
return @"服務器返回錯誤";
}
}
注意 : 官方文檔中提供的是類方法,并且環(huán)境是MRC,如果公司要求是MRC,那么直接去:項目-->Bulid-->comple Source -->雙擊文件-->填寫-fobjc-arc.又或者將MRC中釋放對象的屬性去掉,將類方法,變?yōu)閷嵗椒纯?
處理支付結果的回調(diào)
/**
* 不管支付授權是否成功或者失敗,又或者是用戶自己取消授權,都會調(diào)用該代理方法
*/
#pragma mark - WXApiDelegate
- (void)onResp:(BaseResp *)resp {
if([resp isKindOfClass:[PayResp class]]){
//支付返回結果廓旬,實際支付結果需要去微信服務器端查詢
NSString *strMsg,*strTitle = [NSString stringWithFormat:@"支付結果"];
switch (resp.errCode) {
case WXSuccess:
strMsg = @"支付結果:成功!";
NSLog(@"支付成功-PaySuccess谐腰,retcode = %d", resp.errCode);
break;
default:
strMsg = [NSString stringWithFormat:@"支付結果:失斣斜!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
NSLog(@"錯誤十气,retcode = %d, retstr = %@", resp.errCode,resp.errStr);
break;
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:strTitle message:strMsg delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
[alert show];
}
}
總結
-
可能會疑惑的幾點:
-
1, 微信官方文檔提供的Demo中使用的MRC(有autorelease等屬性標識),為什么文章中不是MRC呢?
答:我將官方文檔中的類方法變成了對象方法了,在本篇文章中,直接調(diào)用該方法即可,整體是在ARC環(huán)境下創(chuàng)建的.這是一種方法,還有一種方法就是ARC和MRC混編,如下圖步驟設置即可.
-
-
2 官方文檔中的示例是這樣的
-
3 調(diào)起微信支付,需要監(jiān)聽按鈕的點擊哦