在iOS开发中,常常会涉及到支付功能,而微信支付是必不可少的,这里笔者就简单整理了一下微信支付的流程,即使分享也是对自己学习的总结。
微信商户申请步骤:http://kf.qq.com/faq/120911VrYVrA150906F3qqY3.html
1.在微信开放平台注册一个账号:https://open.weixin.qq.com
2.进入管理中心–>移动应用–>创建移动应用;根据页面提示完善应用资料
3.审核通过后,进入应用详情页–>查看应用详情,这里可以查看AppID和AppSecret以及一些接口信息
4.应用创建时是没有支付能力的,需要额外申请,具体的申请过程,可根据网页提示即可完成
5.审核通过后,微信平台会给你填写审核资料时预留邮箱发送一个邮件,邮件中包含了与支付能力相关的微信商户号的信息,然后到微信的商户平台:https://pay.weixin.qq.com 填写相关资料,最主要的是验证开户行,微信会向你填写的开户银行账户汇一笔钱(一般是几分钱),让你们的财务查一下,然后验证一下即可,通过后即获取了支付能力
微信支付开发者文档:
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_1
在文档中,点击”支付账户—>支付账户“,可以看到关于APPID的信息:
注意:
1.这个APPID是开发中使用微信支付必须要用的东西,而这个APPID也只有商户通过在该微信支付平台注册,花个300元,填写很多相关重要信息,还要上传营业执照等必要手续,才能获取的APPID。
2.而商业app应用程序,在客户使用app微信消费,程序会根据这个唯一的APPID,查找到商户,然后把消费者的金额数传递到商户的账户里。
3.对于开发者,微信支付平台提供了测试的Demo,也在Demo源码中提供了有用的用于测试代码的APPID。这样开发者就除去了花个300元买个APPID的必要性。
微信支付开发步骤:
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5
微信SDK下载:
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319164&token=&lang=zh_CN
1.添加微信支付SDK,把官方SDK包中的SDKExport文件夹拖到自己的工程里,.text文件可以不用拖,是提供给开发者阅读的。
2.打开red_me.text文件,里面主要是各各SDK版本中更新所解决的问题,以及注意事项,红色框中的部分是需要用的。
3.点击项目名,在Build Phases选项卡的Link Binary With Libraries中,增加以下依赖:Security.framework、CoreTelephony.framework、SystemConfiguration.framework、libc++.tbd、libz.tbd、libsqlite3.tbd、libWeChatSDK.a
4.项目设置APPID,在工程项目中添加商户自己的APPID
商户在微信开放平台申请开发APP应用后,微信开放平台会生成APP的唯一标识APPID。
5.由于iOS9默认限制了http协议的访问,所以Xcode7以后就需要在开发中手动添加 App Transport Security Settings 设置,在info.plist中添加如下配置(文中以XML格式描述)
<key>NSAppTransportSecuritykey>
<dict>
<key>NSAllowsArbitraryLoadskey>
<true/>
dict>
6.iOS 9.0以上的系统如果要正常调起微信,还需要将使用的URL Schemes添加为白名单,在App对应的info.plist中添加如下配置(文中以XML格式描述)。
<key>LSApplicationQueriesSchemeskey>
<array>
<string>weixinstring>
array>
修改后info.plist文件中就会出现红色框中的两项内容
7.注册APPID,在AppDelegate里注册微信
在需要使用微信支付的地方导入:
#import "WXApi.h"
在AppDelegate中的didFinishLaunchingWithOptions方法中添加以下代码向微信注册APP:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//向微信注册APPID
[WXApi registerApp:@"wxb4ba3c02aa476ea1" withDescription:@"demo 2.0"];
return YES;
}
8.发起支付,调其微信支付
在这之前,我们先打开微信官方提供的Demo
在官方给的代码中,我们会注意到一些细节,比如Demo中使用了MRC的autorelease,你可以把它去掉;类方法可以换成实例方法,根据你的实际项目开发需求:
- (NSString *)jumpToBizPay {
//根据查询微信API文档,我们需要添加两个需要的判断
//判断是否安装了微信
if (![WXApi isWXAppInstalled]) {
NSLog(@"没有安装微信");
return nil;
}else if (![WXApi isWXAppSupportApi]){
NSLog(@"不支持微信支付");
return nil;
}
NSLog(@"安装了微信,而且微信支持支付");
//支付流程实现
NSString *urlString = @"http://wxpay.weixin.qq.com/pub_v2/app/app_pay.php?plat=ios";
//解析服务端返回json数据
NSError *error;
//加载一个NSURL对象
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];
//将请求的url数据放到NSData对象中
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
if ( response != nil) {
NSMutableDictionary *dict = NULL;
//IOS5自带解析类NSJSONSerialization从response中解析出数据放到字典中
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"];
//调起微信支付
PayReq *req= [[PayReq alloc] init];
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 @"服务器返回错误";
}
}
接着添加一个支付按钮,调用上述的方法
NSString *weixinBackStr = [self jumpToBizPay];
if (![weixinBackStr isEqualToString:@""]) {
NSLog(@"微信支付返回的信息:%@",weixinBackStr);
}
这里还要注意一点,在调起微信支付之前,需要进行判断是否安装了微信
//根据查询微信API文档,我们需要添加两个需要的判断
//判断是否安装了微信
if (![WXApi isWXAppInstalled]) {
NSLog(@"没有安装微信");
return nil;
}else if (![WXApi isWXAppSupportApi]){
NSLog(@"不支持微信支付");
return nil;
}
NSLog(@"安装了微信,而且微信支持支付");
9.最后就是处理微信支付的返回信息(回调方法)
在官方Demo中可以看到具体如何使用
我们只需要红色框中的代码即可
#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;
}
UIAlertController *alert = [UIAlertController alertControllerWithTitle:strTitle message:strMsg preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *certainAction = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
}];
[alert addAction:certainAction];
[self.window.rootViewController presentViewController:alert animated:YES completion:nil];
}
}
10.根据实际开发需求,我们可能还需要回传App的相关信息
-(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
return [WXApi handleOpenURL:url delegate:self];
}
常见问题为微信支付调起不成功,每次调起只能调起一个带有你返回确认按钮的页面。
原因:参数错误,特别注意参数(签名),后台的返回的参数不正确。
解决方案:逐个校验参数,签名可以本地加密处理,不要依赖后台的返回签名,有的时候后台返回的是不正确的
本文只是一个简单的发起支付流程的演示,下单、签名、查单和支付通知均在服务器后台实现。若遇到其他问题欢迎和楼主分享评论。
以上部分概述内容出自以下博客的链接,以此感谢!!!
http://www.cnblogs.com/goodboy-heyang/p/5255818.html
http://www.cnblogs.com/jys509/p/5130990.html