前言
虽然ApplePay的进军中国市场,但是就目前而言,微信支付和支付宝仍占据主导地位,本章主要是介绍项目中的微信支付是如何集成SDK的.想要了解更多关于iOS的知识,可以关注我的微博,@WilliamAlex大叔一起分享今天学到的iOS相关知识.
集成微信支付的主要思路
- 思路 : 在集成之前,我们先要详细了解官方文档中微信支付这一板块,它已经给我们提出了集成步骤.
- 主要步骤 :
1, 项目设置APPID
2, 注册APPID
3, 调起支付
4, 处理支付结果的回调
- 详细说明步骤;
1, 设置项目的APPID:
商户在微信开放平台申请开发APP应用后,微信开放平台会生成APP的唯一标识APPID。在Xcode中打开项目,设置项目属性中的URL Schemes为您的APPID
2, 注册APPID:
商户APP工程中引入微信lib库和头文件,调用API前,需要先向微信注册您的APPID
3, 调起支付:
商户服务器生成支付订单,先调用【统一下单API】生成预付单,获取到prepay_id后将参数再次签名传输给APP发起支付
4, 处理支付结果的回调:
照微信SDK Sample,在类实现onResp函数,支付完成后,微信APP会返回到商户APP并回调onResp函数,开发者需要在该函数中接收通知,判断返回错误码,如果支付成功则去后台查询支付结果再展示用户实际支付结果。注意 一定不能以客户端返回作为用户支付的结果,应以服务器端的接收的支付通知或查询API返回的结果为准
- 微信注册ID :wxb4ba3c02aa476ea1: 这个ID可以直接在下载的示例项目SDKSample中的AppDelegate中找到
集成思路明白以后,我们开始集成微信支付
-
集成前的准备工作
-
了解微信开发文档
选择APP支付版块.png -
文档中需要注意的点
支付结果回调.png -
我们只需要根据文档中的提示步骤即可集成
集成步骤.png -
下载官方文档中提供的头文件和静态库
头文件和静态库.png -
创建自己的一个项目集成微信支付
-
导入头文件
导入头文件.png
-
-
编译后可能会报很多错误,这时候我们需要导入相关的依赖文件
添加依赖.png
-
编译项目项目会崩溃掉,错误提示我们需要在info.plist文件中添加两个key
添加key.png -
添加的结果
添加key.png -
项目APPID的设置
设置白名单.png -
注册APPID
-
向微信注册支付
向微信注册.png
-
-
调起微信支付
调起微信支付.png- 注意: 这个方法是监听模拟微信支付按钮的方法
-
具体实现
支付的实现01.png
- 处理支付结果的回调
- 注意: 处理支付结果的回调是代理方法,所以需要遵守协议.
- 代码实现
- 向微信注册(注册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是根据公司要求到微信公众平台申请注册的,需要300元人民币,所以我这里就用官方文档中提供测试用的ID.
-
2, 项目中遵守了代理协议,主要是用于处理支付结果回调使用,后面会用到.
-
调起微信支付
#import "ViewController.h"
#import "WXApi.h"
@interface ViewController ()
@end
@implementation ViewController
/**
* 调起微信支付
*/
- (IBAction)payFormoneryInAlexWallet {
NSString *res = [self jumpToBizPay];
if( ![res isEqual:@""] ) {
UIAlertView *alter = [[UIAlertView alloc] initWithTitle:@"支付失败"
message:res
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
// 提示用户支付失败,res是支付失败后系统返回的信息
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])
{ // 表示当前不支持微信支付
// 提示用户当前环境不支持微信支付
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数据
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]; // 将autoresease去掉,类方法变为对象方法即可
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 @"服务器返回错误";
}
}
-
注意 : 官方文档中提供的是类方法,并且环境是MRC,如果公司要求是MRC,那么直接去:项目-->Bulid-->comple Source -->双击文件-->填写-fobjc-arc.又或者将MRC中释放对象的属性去掉,将类方法,变为实例方法即可.
-
处理支付结果的回调
/**
* 不管支付授权是否成功或者失败,又或者是用户自己取消授权,都会调用该代理方法
*/
#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呢?
答:我将官方文档中的类方法变成了对象方法了,在本篇文章中,直接调用该方法即可,整体是在ARC环境下创建的.这是一种方法,还有一种方法就是ARC和MRC混编,如下图步骤设置即可.
ARC和MRC的混编.png
-
-
2 官方文档中的示例是这样的
微信示例.png -
3 调起微信支付,需要监听按钮的点击哦
监听按钮的点击.png
网友评论