微信官方文档说的"统一下单"这一步交给后台做, 安(sheng)全(shi).
感谢http://www.open-open.com/lib/view/open1460718945871.html
1.去微信开放平台注册应用
https://open.weixin.qq.com/cgi-bin/index?t=home/index&lang=zh_CN&token=2c0fee9c43e1eb8f9febcc7cb73abf598e2d4011
通过邮件我们能获得重要的参数, 都打开笔记软件记录好:
(1):AppID
(2):微信支付商户号
(4):前往商户平台完成入驻
(4):API秘钥(自己设置即可,注意一定要32位字母加数字的组合)记得保存好秘钥,以后要使用
在商户平台不止可以查看关于密钥之类的内容, 以后统计汇款数据, 或者退款也都是在商户平台进行, 每次进入都要输入密码和验证码
- 这些东西整完后, 就可以向工程导入SDK, 我是直接在下面官方文档中心下载后拽进来的, 作为一个cocoaPods党, copy if needed要勾选
readMe.txt与官方文档网站中的app开发步骤的配置环境好好看, 叫你做的一个都别放过
https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_5#
- 在AppDelegate.m文件中, 引入WXApi.h, 引入
然后在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 注册, 据说如果同时还注册了友盟, 要先注册友盟, 再注册微信
[WXApi registerApp:WX_AppID];
- 商户服务器生成支付订单,先调用【统一下单API】生成预付单,获取到prepay_id后将参数再次签名传输给APP发起支付。以下是调起微信支付的关键代码:
- (IBAction)weChatPayButtonAction:(id)sender
{
PayReq *request = [[PayReq alloc] init];
/** 商家向财付通申请的商家id */
request.partnerId = @"1220277201";
/** 预支付订单 */
request.prepayId= @"82010380001603250865be9c4c063c30";
/** 商家根据财付通文档填写的数据和签名 */
request.package = @"Sign=WXPay";
/** 随机串,防重发 */
request.nonceStr= @"lUu5qloVJV7rrJlr";
/** 时间戳,防重发 */
request.timeStamp= 1458893985;
/** 商家根据微信开放平台文档对数据做的签名 */
request.sign= @"b640c1a4565b476db096f4d34b8a9e71960b0123";
/*! @brief 发送请求到微信,等待微信返回onResp
*
* 函数调用后,会切换到微信的界面。第三方应用程序等待微信返回onResp。微信在异步处理完成后一定会调用onResp。支持以下类型
* SendAuthReq、SendMessageToWXReq、PayReq等。
* @param req 具体的发送请求,在调用函数后,请自己释放。
* @return 成功返回YES,失败返回NO。
*/
[WXApi sendReq: request];
}
现在我们只需要在控制器上添加一个button, 名字改成微信支付就可以了
- 关于支付回来, 无论支付成功或失败或取消, 我们如果需要的话都要做相应处理, 回到appDelegate.m
//前面的两个方法被iOS9弃用了,如果是Xcode7.2网上的话会出现无法进入进入微信的onResp回调方法,就是这个原因。本来我是不想写着两个旧方法的,但是一看官方的demo上写的这两个,我就也写了。。。。
//9.0前的方法,为了适配低版本 保留
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
return [WXApi handleOpenURL:url delegate:self];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
return [WXApi handleOpenURL:url delegate:self];
}
//9.0后的方法
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options{
//这里判断是否发起的请求为微信支付,如果是的话,用WXApi的方法调起微信客户端的支付页面(://pay 之前的那串字符串就是你的APPID,)
return [WXApi handleOpenURL:url delegate:self];
}
//微信SDK自带的方法,处理从微信客户端完成操作后返回程序之后的回调方法,显示支付结果的
- (void)onResp:(BaseResp *)resp
{
//启动微信支付的response
NSString *payResoult = [NSString stringWithFormat:@"errcode:%d", resp.errCode];
NSDictionary *dicOfResult = @{
@"weixin_pay_result":resp
};
//将支付结果发送通知
[[NSNotificationCenter defaultCenter] postNotificationName:NOTI_WEI_XIN_PAY_RESULT object:dicOfResult];
if([resp isKindOfClass:[PayResp class]]){
//支付返回结果,实际支付结果需要去微信服务器端查询
switch (resp.errCode) {
case 0:
payResoult = @"支付结果:成功!";
NSLog(@"%@", payResoult);
break;
case -1:
payResoult = @"支付结果:失败!";
NSLog(@"%@", payResoult);
break;
case -2:
payResoult = @"用户已经退出支付!";
NSLog(@"%@", payResoult);
break;
default:
payResoult = [NSString stringWithFormat:@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr];
NSLog(@"%@", payResoult);
break;
}
}
}
5.至此似乎是完成了支付大业, but, 假如ios9+用户点击状态栏返回我们自家app呢, 以上的支付方法回调是不走的!
以下内容感谢http://www.jianshu.com/p/9744c53b5498
但是从微信回来, 无论支付结果如何, 都会走
- (void)applicationWillEnterForeground:(UIApplication *)application{}
我们需要在这里面判断, 是否是因为支付从微信回来, 如果是的话, 去通知刚才跳转支付那个vc, 请求我们自家后台, 告诉我们这个客户钱给了没, 然后我们再做响应操作;
但是, 如果用户在微信支付成功后点击navigation右按钮确认并返回我们的app, 那么wilEnterForeground先走,
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options
后走, 这种情况我们也要加以判断, 避免发送两次通知给调起支付的vc
具体实现是这样: 在发起支付的时候, 进行NSUserDefault的本地记录, 强制写入本地