iOS-通俗易懂的微信支付接入和爬坑指南,十分钟轻松搞完
现在基本所有的App都会接入支付宝支付以及微信支付,也有很多第三方提供给你
SDK帮你接入,但是这种涉及到支付的东西还是自己服务器搞来的好一些,其实搞懂了
逻辑非常的简单,下面直接给大家说说下基本流程和接入需要注意的东西。
支付宝详细爬坑接入指南传送门
前期准备(这个东西一般来讲我们不需要来操心,但是还是稍微介绍下)
1.到微信开放平台注册账号点击打开链接
2.进入管理中心------移动应用------创建移动应用----根据页面完善应用资料
3.审核过后,通过应用详情页面,查看应用详情,查看AppID和AppSecret相关信息
4.创建这些是没有支付能力的,需要额外申请,还是根据提示一步步填写,填写完之后会发一封邮件到您的预留的邮箱,然后到商户平台点击打开链接填写资料,最主要的是验证下开户收款账号,会收到一波几分钱的巨额财产,那么这个时候如果你填写的是你的开户账号,直接跑路吧,这些钱够你在深圳买房了。。。。。。如果你是个好人,那么找你们财务验证下是否有收到,就代表通过了,愉快的代码时间来了
开撸代码之前先看下基本流程
商户系统和微信支付系统主要交互说明:
步骤1:用户在商户APP中选择商品,提交订单,选择微信支付。
步骤2:商户后台收到用户支付单,调用微信支付统一下单接口。点击打开链接
步骤3:统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay
步骤4:商户APP调起微信支付。点击打开链接
步骤5:商户后台接收支付通知。点击打开链接
步骤6:商户后台查询支付结果。点击打开链接
看完流程,来看看咱们客户端要做什么准备
1.SDK接入
2.依赖库导入(貌似还差个libc++.dylib,也一并加入)
3.iOS 9 配置白名单
4.配置下Scheme(这填写的是申请回来的ID)
终于可以愉快的写代码了
1.向微信注册你的AppID
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {// Override point for customization after application launch.//注册APP,这里的字符串就是Wechat URL Scheme里面对应的ID 也是申请回来的ID,必须一致[WXApi registerApp:@"这里填写申请回来的ID"];return YES;
}
2.请求服务器的参数,拉起微信支付App(超级关键,注意听)
#pragma mark - 微信支付
- (void)wechatPay
{// 把生成的订单信息组装起来传给服务器,如何组装就和服务器约定好[[TWTShoppingCartLogic sharedData] goToWechatEasyPay:self.orderStr way:@"2" complete:^(NSError *error, id data) {NSMutableString *stamp = [data objectForKey:@"timestamp"];//调起微信支付PayReq* req = [[PayReq alloc] init];req.partnerId = [data objectForKey:@"partnerid"];req.prepayId = [data objectForKey:@"prepayid"];req.nonceStr = [data objectForKey:@"noncestr"];req.timeStamp = stamp.intValue;req.package = [data objectForKey:@"package"];req.sign = [data objectForKey:@"sign"];[WXApi sendReq:req];}];
}
这里请求的方法和步骤就不写了,无非就是post信息给服务器,咱们看看需要的数据格式(假数据)
{
"appid" : "wxb4b",微信开放平台审核通过的AppID
"noncestr" : "171127dd056d05e423c8b9e",随机字符串
"package" : "Sign=WXPay", 固定值
"partnerid" : "130", 微信支付分配的商户ID
"prepayid" : "wx201609291601", 预支付交易会话ID
"sign" : "684371081C049B6017641", 签名,除了sign,剩下6个组合的再次签名字符串
"timestamp" : 147513 当前时间
}
注意啦!!!!!!
第一种:老司机后台类型
其实当你把订单传给后台的时候,后台事先会把订单通过微信的生成预支付订单生成
prepayID点击打开链接,那么对于老司机来说,怎么可能把这种返回的数据返回给你?
他们会把接受的prepayID根据上面的结构组装起来,那么预支付订单生成的时候也会返
回sign字段,老司机不会直接用,后台会把这个字段,也就是剩下6个字段再次md5签
名生成签名算法新的sign字段组装完毕返回给你,这种情况下直接在App上配置模型,
拉起微信支付,非常舒畅,一气呵成!!!
第二种:无法理解类型后台(让你自己签名)
当你把订单传给他的时候,同样他会生成个预订单prepayID,那么这种司机开车特别
猛,直接把返回的参数根据格式组装后弹回给你,sign字段也是预订单生成后的,没有
经过二次md5签名,他也没有告诉你,那么你也特别猛,没问他,直接用他的字段,组
装完毕,拉起微信,我擦,你会直接懵逼了,那么你将会只会看到这个。
问题不大,就是自己签名了,自己写个本地的md5玩玩(假的千万别用,网上
找来的分享下)
//创建package签名
-(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=%@", self.spKey];//得到MD5 sign签名NSString *md5Sign =[contentString MD5];return md5Sign;
}- (NSMutableDictionary*)payWithprePayid:(NSString*)prePayid{if(prePayid == nil){NSLog(@"prePayid 为空");return nil;}//获取到prepayid后进行第二次签名NSString *package, *time_stamp, *nonce_str;//设置支付参数time_t now;time(&now);time_stamp = [NSString stringWithFormat:@"%ld", now];nonce_str = [time_stamp MD5];//重新按提交格式组包,微信客户端暂只支持package=Sign=WXPay格式,须考虑升级后支持携带package具体参数的情况//package = [NSString stringWithFormat:@"Sign=%@",package];package = @"Sign=WXPay";//第二次签名参数列表NSMutableDictionary *signParams = [NSMutableDictionary dictionary];NSLog(@"%@",signParams);[signParams setObject: self.appId forKey:@"appid"];[signParams setObject: self.mchId forKey:@"partnerid"];[signParams setObject: nonce_str forKey:@"noncestr"];[signParams setObject: package forKey:@"package"];[signParams setObject: time_stamp forKey:@"timestamp"];[signParams setObject: prePayid forKey:@"prepayid"];//生成签名NSString *sign = [self createMd5Sign:signParams];//添加签名[signParams setObject: sign forKey:@"sign"];//返回参数列表return signParams;
}
如果真的要在App端二次签名的话,那加密的时候还要加入申请的密钥,但是真的不好
这样做,其一:服务器已经做过一次签名了,第二次做了返回给你就好了,没必要再给
App。其二:不安全,全放在App上,这种东西一定要放到服务器
小技巧:其实出现上面那种情况有几种可能
1.sign没有二次签名
2.noncerStr是服务器返回的,不要自己生成
3.package是写死的,不要写错了
4.timeStamp是10位数
5.自己签名的sign一定要全部大写
6.为了避免上面的情况,交给服务器管理,我们负责组装拉起微信支付就好了
3.处理回调信息
Appdelegate
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {// 跳转到URL scheme中配置的地址//NSLog(@"跳转到URL scheme中配置的地址-->%@",url);return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];
}
//支付成功时调用,回到第三方应用中
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {if ([url.scheme isEqualToString:WECHAT_APPKEY])//微信调用结束{return [WXApi handleOpenURL:url delegate:[WXApiManager sharedManager]];}}
这里的处理是根据微信官网提供的方法, 代理到专门处理的单利当中去统一处理WXApiManager
注意点:有些人用NSNotificationCenter来通知到发出请求的界面去,然后在发起的界面处理回调的逻辑,但是这里
你要考虑一种非人类的交互,TMD有人在拉起微信支付的时候把自己的App给推出了或者App自己挂了,那么当回调
生效的时候,原先拉起微信支付App的界面已经消失了,你发的通知他收不到了,这种情况我是存到本地的
[[NSUserDefaultsstandardUserDefaults]setValue:self.orderStrforKey:@"WECHAT_PAY_ORDER_TRADEID"];
[[NSUserDefaultsstandardUserDefaults]synchronize];
处理回调的时候直接从本地读取
最终处理逻辑的地方(这里不能直接用他的返回接过,要二次确认)
//微信回调,有支付结果的时候会回调这个方法
- (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);// 这里别用返回的状态来确定是否正真支付成功了,这样是不对的,我们必须拿着存到本地的traderID去服务器再次check,这样和服务器收到的异步回调结果匹配之后才能确认是否真的已经支付成功了[[TWTShoppingCartLogic sharedData] gotoCheckWeChatOrder:tradeID compelete:^(NSError *error, id data) {// 二次确认}];break;default:strMsg = [NSString stringWithFormat:@"支付结果:失败!retcode = %d, retstr = %@", resp.errCode,resp.errStr];NSLog(@"错误,retcode = %d, retstr = %@", resp.errCode,resp.errStr);break;}}}
还是总结下重要的地方吧
1.App Scheme一定要配置正确
2.千万不能用生成预订单返回的Sign,要重新生成(和后台沟通)
3.要考虑拉起App支付的时候自己程序被退出或者自杀了
4.一定不能用异步返回给App的参数进行判断成功与否,需要和后台进行二次确认,异步返回给后台的数据才是最终的
看官方给的说法
差不多介绍到这里了,自己微信遇到的坑没有接入支付宝的时候多,接过支付宝再接入
微信,真的太简单了,有空再写个支付宝支付,觉得有帮到大家的记得给个赞哦~~~
遇到其他问题了再补充
这里就没有Demo了,有个官方的已经很详细了
点击打开微信官方Demo链接
http://xfenglin.com/a/12007996715.html
iOS-通俗易懂的微信支付接入和爬坑指南,十分钟轻松搞完相关推荐
- 亲历H5移动端游戏微信支付接入及那些坑(一)——支付方式与坑
最近项目进入中后期,开始接入支付.要求是使用微信支付,呵呵,好笑的是不知老板从哪里听来的,居然和我说只要是熟手,接个微信支付两小时搞定,我只能再次呵呵.先不说支付处理逻辑,而且公司本来也没现成的接入模 ...
- 亲历H5移动端游戏微信支付接入及那些坑(二)——获取Openid和授权
第一篇中将一些坑说明,那么这篇开始正式进入接入步骤.具体的参数说明,我不会列出,毕竟微信官方文档都有,我想大家都看的懂,而且这接口也有可能微信会变动,所以不列出来,也是不想引起大家的误解,接入步骤只起 ...
- C#开发微信门户及应用(32)--微信支付接入和API封装使用
C#开发微信门户及应用(32)--微信支付接入和API封装使用 在微信的应用上,微信支付是一个比较有用的部分,但也是比较复杂的技术要点,在微商大行其道的年代,自己的商店没有增加微信支付好像也说不过去, ...
- iOS 苹果手机客户端微信支付调起失败--无法调起微信的原因
1. iOS 苹果手机客户端微信支付调起失败–无法调起微信的原因 微信的SDK分两种,一种包含支付的SDK,另一中是不包含支付的SDK, 因为项目早期集成的是微信分享的SDK,不带支付的功能,所以更换 ...
- ##iOS中的微信支付 支付验证签名失败
iOS中的微信支付 支付验证签名失败 今天要在项目中添加微信支付,iOS端的所有东西都已经按照文档搞好了,可就是跳转到微信的时候显示"支付验证签名失败",可是安卓端的都没有问题,就 ...
- 微信支付接入的那点事儿
本文来自作者 javen 在 GitChat 上分享「微信支付接入的那点事儿」,「阅读原文」查看交流实录 「文末高能」 编辑 | 嘉仔 前言 本次 Chat 中涉及到的图片.统计数据均来自于网络,截图 ...
- iOS WKWebView H5微信支付跳转
iOS WKWebView H5微信支付跳转 需求:iOS客户端实现嵌入H5进行微信支付跳转到微信客户端,支付完成后再跳转回我们的APP,解决WKWebView无法跳转回APP的BUG. 阅读前提: ...
- 【纯干货】微信支付接入攻略—JAVA代码分享
[纯干货]微信支付接入攻略-JAVA代码分享 [声明]本文作者是Gekec网站开发总监Arne Chen.Arne在实际接入微信支付时遇到诸多问题并且逐一解决的过程中总结了不少实战经验.文中引用代码是 ...
- 苹果手机 微信PHP问题,安卓、ios APP调用微信支付时,页面出现空白 。(php微信支付,app发起微信支付白屏)?...
安卓.ios APP调用微信支付时,页面出现空白 我的后端是用php开发的.我是先调用微信的统一下单生成,生成prepay_id预支付订单号,代码如下: public function send_pa ...
最新文章
- mysql中数据表如何关联_mysql 如何导入/导出2个关联表中的数据
- 分区表在安装系统(MBR)丢失或损坏
- 【原】React中,map出来的元素添加事件无法使用
- 基于堆叠式长短期记忆神经网络模型StackingLSTM的时间序列数据预测模型构建
- 【参考】MTK线刷工具错误代码大全及解决方法
- win7家庭版升级旗舰的密钥
- 计算机网络基础简答题
- CAD组合成块,CAD合并成块,CAD炸开后再合并,CAD中炸开的图块合并在一起
- 手机上传日志文件给服务器,手机内容远程上传到服务器
- 站在山顶上看golang的前世今生与未来展望
- 计算机练打字最难的一段话,电脑盲打字一般练多久 你用多久练会了盲打?
- 谷歌浏览器播放h.265_Google删除H.264
- linux虚拟机按键不好用,虚拟机(vmware)linux中ctrl按键失灵 解决办法
- meterpreter + 键盘记录
- 如何解释“运维到底是干啥的”?
- 前端html小技巧(form篇):复选框、单选按钮的使用
- pulp.apis.core.PulpSolverError: PuLP: cannot execute glpsol.exe的一种解决方案
- Debian 安装 git
- 鹰软件测试简历自我,276关于老鹰的老炮儿片头的练习测试
- 中国HIS企业发展思考与展望