在iOS開發中,常常會涉及到支付功能,這裡對常見的微信支付做一下詳細說明
微信開放平台(微信支付需要付費的,注冊成功後使用的主要為AppKey/SecretKey,其中SecrectKey交由後台完成集成)
微信開放平台是商戶APP接入微信支付開放接口的申請入口,通過此平台可申請微信APP支付。
1)首先應該下載SDK並導入項目(這裡以友盟自帶微信支付說明,具體內容相似)
如果項目中使用了友盟社會化分享SDK,那麼你將不需要重復導入SDK,友盟中已經集成了微信支付。具體SDK如下:
vcyoz8LU2Nfu0MK1xFNESyzIu7rztbnI68T6tcTP7sS/oaO+38zltcRTREvI58/Co7o8YnIgLz4NCjxpbWcgYWx0PQ=="這裡寫圖片描述" src="/uploadfile/Collfiles/20160413/20160413100311242.png" title="\" />
2)在添加完SDK後需要添加相應的庫以及文件
3)然後是添加對應的url用於調起
4) 添加白名單、關閉Bitcode(對於http/https適配iOS9.0自行修改)
在完成了上面的操作之後,我們所導入的SDK就可以使用了,很簡單
1) 首先我們要進行注冊
導入#import “WXApi.h”
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
ViewController *userGuideViewController = [[ViewController alloc] init];
self.window.rootViewController = userGuideViewController;
[WXApi registerApp:@"這裡添加APPKey"];
return YES;
}
2)接著我們要寫一個調起
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options
{
// 跳轉到URL scheme中配置的地址
//NSLog(@"跳轉到URL scheme中配置的地址-->%@",url);
return [WXApi handleOpenURL:url delegate:(id)self];
}
3)然後是回調
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { // NSLog(@"****************url.host -- %@",url.host); if ([url.scheme isEqualToString:@"這裡添加AppKey"]) { return [WXApi handleOpenURL:url delegate:(id)self]; } return YES; }- (void) onResp:(BaseResp*)resp { NSString *strMsg = [NSString stringWithFormat:@"errcode:%d", resp.errCode]; NSString *strTitle = @"支付結果"; if([resp isKindOfClass:[PayResp class]]){ switch (resp.errCode) { case WXSuccess: strMsg = @"支付結果:成功!"; break; case WXErrCodeUserCancel: strMsg = @"支付結果:用戶點擊取消!"; break; case WXErrCodeSentFail: strMsg = @"支付結果:發送失敗!"; break; case WXErrCodeAuthDeny: strMsg = @"支付結果:授權失敗!"; break; default: strMsg = @"支付結果:微信不支持!"; break; } UIAlertView *alert = [[UIAlertView alloc] initWithTitle:strTitle message:strMsg delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil]; [alert show]; } }
- (void) onResp:(BaseResp*)resp
{
NSString *strMsg = [NSString stringWithFormat:@"errcode:%d", resp.errCode];
NSString *strTitle = @"支付結果";
if([resp isKindOfClass:[PayResp class]]){
switch (resp.errCode) {
case WXSuccess:
strMsg = @"支付結果:成功!";
break;
case WXErrCodeUserCancel:
strMsg = @"支付結果:用戶點擊取消!";
break;
case WXErrCodeSentFail:
strMsg = @"支付結果:發送失敗!";
break;
case WXErrCodeAuthDeny:
strMsg = @"支付結果:授權失敗!";
break;
default:
strMsg = @"支付結果:微信不支持!";
break;
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:strTitle message:strMsg delegate:self cancelButtonTitle:@"確定" otherButtonTitles:nil, nil];
[alert show];
}
}
1) 最後是在項目中需要進行微信支付的地方使用支付(這是完成整個支付流程中最重要的一部分,也是最需要注意的地方)
首先要進行一次網絡請求,後台接口,將你的商品信息發送到後台,生成訂單後返回,返回信息中最少要包含六個參數,通過這些參數調起支付。
導入#import “WXApi.h”
//返回參數調起支付
PayReq* req = [[PayReq alloc] init];
NSMutableDictionary *dict=[result objectForKey:@"resultCode"];
req.openID = [dict objectForKey:@"appid"];
req.partnerId = [dict objectForKey:@"mch_id"];
req.prepayId = [dict objectForKey:@"prepay_id"];
req.nonceStr = [self md5:time_stamp];
req.timeStamp = [time_stamp intValue];
req.package = @"Sign=WXpay";
//簽名(這個簽名可以自己進行簽名,也可以後台操作,由後台返回)
NSMutableDictionary *signParams=[[NSMutableDictionary alloc] init];
[signParams setObject: req.openID forKey:@"appid"];
[signParams setObject: req.nonceStr forKey:@"noncestr"];
[signParams setObject: req.package forKey:@"package"];
[signParams setObject: req.partnerId forKey:@"partnerid"];
[signParams setObject: time_stamp forKey:@"timestamp"];
[signParams setObject: req.prepayId forKey:@"prepayid"];
req.sign = [self createMd5Sign:signParams];
//調起支付(**參數有一個錯誤,將不能完成調起**)
[WXApi sendReq:req];
2) 自行加密處理(這部分可以由後台完成)
//微信支付加密
-(NSString *) md5:(NSString *)str
{
const char *cStr = [str UTF8String];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, (unsigned int)strlen(cStr), digest );
NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[output appendFormat:@"%02X", digest[i]];
return output;
}
-(NSString*) createMd5Sign:(NSMutableDictionary*)dict
{
NSMutableString *contentString =[NSMutableString string];
NSArray *keys = [dict allKeys];
//按字母順序排序
NSArray *sortedArray = [keys sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1 compare:obj2 options:NSNumericSearch];
}];
//拼接字符串
for (NSString *categoryId in sortedArray) {
if (![[dict objectForKey:categoryId] isEqualToString:@""]
&& ![categoryId isEqualToString:@"sign"]
&& ![categoryId isEqualToString:@"key"]
)
{
[contentString appendFormat:@"%@=%@&", categoryId, [dict objectForKey:categoryId]];
}
}
//添加key字段
[contentString appendFormat:@"key=%@", @"這裡添加SecretKey"];
NSString *md5Sign =[WXUtil md5:contentString];
return md5Sign;
}
1) 常見問題為微信支付調起不成功,每次調起只能調起一個帶有你返回確認按鈕的頁面。
原因:參數錯誤,特別注意參數(簽名),後台的返回的參數不正確。
解決方案:逐個校驗參數,簽名可以本地加密處理,不要依賴後台的返回簽名,有的時候後台返回的是不正確的。