在刚刚结束的一个项目中用到了微信支付,从接入微信支付到工具类的封装,在本文中做个积累,方便日后使用。
1.开始接入微信支付的准备工作
首先你需要去微信开放平台注册账号,在这里要吐槽一下,不知道这个微信平台的账号密码验证机制,忘了以前的密码,重新登录,各种找回密码都不行,实在没辙,去注册个Gmail😑,登录成功后,可以看到如下界面。
点击右上角的创建移动应用,一步一步填写必要填入的信息,在这里就不做多余的赘述了。
需要注意的是这里填入的
Bundle ID需要和项目的一一对应
接下来就等一个星期左右,等待微信审核通过你就可以将微信支付SDK集成到项目中,详情可以看官方给出的文档.
pod 集成方法1
pod 'WechatOpenSDK'
在Xcode中,选择你的工程设置项,选中“TARGETS”一栏,在“info”标签栏的“URL type“添加“URL scheme”为你所注册的应用程序id(如下图所示)。
完成之后可以获取到appid(微信开放平台为应用生成的唯一识别码)、商户id、商户secretKey。对于app端来说只用到appid,商户id最好通过接口从server获取,商户secretKey是用来签名的,一般只有server能用到。
2.支付流程
刚开始看这个流程图可能会觉得很复杂,所以总结了我们比较关系的流程是:
- app客户端向服务器发送支付请求
- 服务器在收到客户端请求之后向微信后台调用统一下单API,获得预付单信息
- 服务端生成带签名的客户端支付信息给app
- app客户端用户确认支付,app唤醒微信客户端进行支付
- app获得支付结果后向服务端查询最终的结果并显示
app端的工作:
- 接入微信支付SDK
- 向服务器发送支付请求
- 支付信息唤醒微信app,然后进行支付
- 收到微信支付回调后向服务器确认支付结果
- 根据查询结果展示结果页面告知用户支付结果
服务器端的工作:
- 收到app客户端支付请求后向微信后台请求预支付订单
- 服务器端签名并返回信息给app客户端
- 接收微信后台返回的支付结果,用来app端查询
服务器端返回的字段说明:
- appId:返回的appid
- partnerId: 父级id
- prepayId: 支付id
- packages: 包名(微信默认的为“Sign=WXPay”)
- nonceStr: 生成的随机字符串
- timesTamp: 时间戳
- sign: 签名
3.iOS端使用
在AppDelegate.m
,导入微信SDK头文件WXApi.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[WXApi registerApp:@"注册获得的appid"];//注册appid
return YES;
}
//支持所有iOS系统回调
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
// [self handleOpenURL:url];
BOOL result = [[UMSocialManager defaultManager] handleOpenURL:url sourceApplication:sourceApplication annotation:annotation];
if (!result) {
// 其他如支付等SDK的回调
[self handleOpenURL:url];
}
return YES;
}
- (void)handleOpenURL:(NSURL*)url {
if ([url.host isEqualToString:@"pay"]) { // -- 微信支付
[WXApi handleOpenURL:url delegate:[WXPayService sharedInstance]];
}
}
此处的
WXPayService
就是自己单独抽出来写的一个类,遵循WXApiManagerDelegate
协议
WXPayService.h
1 | #import <Foundation/Foundation.h> |
WXPayService.m
1 |
|
在需要支付的ViewController中导入工具类WXPayService
4.注意点及问题
注意点:
- 设置好scheme,否则应用无法跳转到微信客户端
- 支付签名时的key值全部是小写的
- 如果支付显示验证签名失败
的时候,可以将packages设为默认值(Sign=WXPay)试试
问题:
系统版本大于等于iOS9的,调起微信客户端之后,可以直接点击状态栏左侧按钮返回,这时是不走回调方法的。
解决方案:
在AppDelegate.m的applicationWillEnterForeground方法中,调用查询支付结果接口然后刷新当然页面。需要设置bool变量作为标志,否则每次应用进入前台都去查询,就不符合业务要求了。
进入微信支付页面之后,不做操作,切换到自己应用中,退出当前支付页面,然后再进入微信客户端点击支付或者取消,此时自己的应用会崩溃闪退
原因:退出页面后页面已经出栈被销毁,但wx回调时还是去调用其中的代理方法,就会出现野指针。
解决方案:在页面的viewWillDisappear
方法中加入1
[WXPayService sharedManager].delegate = nil;
5.结束语
微信支付签名建议和服务端协商做二次签名,以保证支付的安全性。
ps: 如有不对的地方,欢迎批评指正,另外安利一下个人的博客