1、前期准备

  • 1) 到微信开放平台注册账号

    • 需要登录邮箱验证
    • 填写您的商户信息
  • 2) 进入管理中心 --- 移动应用 --- 创建移动应用 --- 根据页面完善应用资料
  • 3) 审核过后,通过应用详情页面,查看应用详情,查看AppID和AppSecret相关信息
  • 4) 创建这些是没有支付能力的,需要额外申请,还是根据提示一步步填写,填写完之后会发一封邮件到您的预留的邮箱,然后到商户平台点击打开链接填写资料,最主要的是验证下开户收款账号,会收到一波几分钱的巨额财产,那么这个时候如果你填写的是你的开户账号,直接跑路吧,这些钱够你在深圳买房了。。。。。。如果你是个好人,那么找你们财务验证下是否有收到,就代表通过了,愉快的代码时间来了.

2、实现过程

  • 步骤1:

    • 用户在商户APP中选择商品,提交订单,选择微信支付。
  • 步骤2:
    • 商户后台收到用户支付单,调用微信支付统一下单接口。
  • 步骤3:
    • 统一下单接口返回正常的prepay_id,再按签名规范重新生成签名后,将数据传输给APP。参与签名的字段名为appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式为Sign=WXPay
  • 步骤4:
    • 商户APP调起微信支付。
  • 步骤5:
    • 商户后台接收支付通知。
  • 步骤6:
    • 商户后台查询支付结果。

3、代码部分

  • 3.1 工程配置

    • 1) 通过手动配置

      • SDK接入
      • 依赖库导入(貌似还差个libc++.dylib,也一并加入)
      • iOS 9 配置白名单
      • 配置下Scheme(这填写的是申请回来的ID)
    • 2) 实用pod方式配置
      • 在工程的Podfile里面添加以下代码:
      pod 'WechatOpenSDK'
      • 保存并执行pod install,然后用后缀为.xcworkspace的文件打开工程。

        • 注意:

          • 命令行下执行pod search WechatOpenSDK,如显示的WechatOpenSDK版本不是最新的,则先执行pod repo update操作更新本地repo的内容
      • 在Xcode中,选择你的工程设置项,选中“TARGETS”一栏,在“info”标签栏的“URL type“添加“URL scheme”为你所注册的应用程序id(如下图所示)。
  • 3.2 代码实现

    • 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;}}
    }

4、需要注意的问题

  • 1.App Scheme一定要配置正确
  • 2.千万不能用生成预订单返回的Sign,要重新生成(和后台沟通)
  • 3.要考虑拉起App支付的时候自己程序被退出或者自杀了
  • 4.一定不能用异步返回给App的参数进行判断成功与否,需要和后台进行二次确认,异步返回给后台的数据才是最终的

5、常见问题及解决办法

转载于:https://www.cnblogs.com/CH520/p/10801180.html

iOS开发微信支付的介绍与实现相关推荐

  1. 解决ios H5微信支付不能跳回App的问题

    解决ios H5微信支付不能跳回App的问题 app项目是uni-app开发的安卓和iOS版本,安卓测试无问题,以下主要说iOS的解决方案. 问题点:app用webview打开H5页面,在H5页面发起 ...

  2. iOS开发UI篇—简单介绍静态单元格的使用

    iOS开发UI篇-简单介绍静态单元格的使用 一.实现效果与说明 说明:观察上面的展示效果,可以发现整个界面是由一个tableview来展示的,上面的数据都是固定的,且几乎不会改变. 要完成上面的效果, ...

  3. 如何使用easywechat开发微信支付功能

    easywechat是神一样的存在.非常好用.希望大家都能转到这上面来. 用easywechat来开发微信支付功能,步骤如下: 一,需要有一个商品下单页面,页面上有你的商品的信息,还要有购买数量,和一 ...

  4. 微信小程序开发-微信支付之免密支付(自动扣费)一 小程序+java接口

    微信小程序开发-微信支付之免密支付(自动扣费)一 小程序+java接口 链接: 点击进入

  5. 小程序云开发 ——微信支付

    云开发的微信支付:免鉴权.免签名计算.免 access_token,在云函数内原生调用微信支付接口.以前的实现微信支付,必须要有自己的服务器,有自己的备案域名,还有后端部分代码 云开发-微信支付,官方 ...

  6. 关于IOS调用微信支付jsapi不起作用的解决方法

    关于IOS调用微信支付jsapi不起作用的解决方法 参考文章: (1)关于IOS调用微信支付jsapi不起作用的解决方法 (2)https://www.cnblogs.com/randy619/p/5 ...

  7. ios 开发 微信分享失败_一个失落的孩子如何在失败的情况下从失败变成了iOS开发人员...

    ios 开发 微信分享失败 by Jordan LaGrone 乔丹·拉格隆(Jordan LaGrone) 一个失落的孩子如何在失败的情况下从失败变成了iOS开发人员 (How a lost kid ...

  8. 微信小程序云开发微信支付、订单查询、申请退款

    微信小程序云开发微信支付 使用云开发微信支付功能的前提 统一下单 查询订单 申请退款 常见问题总结: 使用云开发微信支付功能的前提 小程序主体为企业或者工商个体户 小程序完成了微信认证 小程序接入微信 ...

  9. php开发微信商户平台支付宝支付,不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...

    我们知道,开发微信支付需要申请服务号并且需要一系列的资料才可以开通.怪麻烦的,现在我们可以用第三方开放的免签约微信支付接口,支付宝接口和QQ钱包接口,实现实时到帐的微信支付开发. 我们只需要在第三方的 ...

最新文章

  1. 小实验:用创建进程()打开计算器,然后关闭进程句柄。再用打开进程(进程ID),使用两次,得到两个进程句柄。实验目的:这两个进程句柄都能控制这个进程吗?通过该试验加深对句柄的理解!!...
  2. System.Data.OracleClient 需要 Oracle 客户端软件 8.1.7 或更高版本?
  3. android 日历下面备注,怎样在日历的下面加备注?
  4. java传值的代码_SpringMVC的简单传值(实现代码)
  5. 第五节:泛型(泛型类、接口、方法、委托、泛型约束、泛型缓存、逆变和协变)
  6. Bootstrap 带下拉的导航
  7. 2种图像增强方法:图像点运算和图像灰度化处理
  8. 填错银行卡号导致放款失败?小心中招钓鱼网贷
  9. android关于okhttp中对于onFailure回调的异常捕获
  10. python网络通信中cs架构_python3基于TCP实现CS架构文件传输
  11. matlab和气象,matlab在气象上的应用
  12. 最新iOS面试题:APP性能优化(①系列更新)
  13. EXCEL TIPS From Webs
  14. kettle 9.1 连接hadoop clusters (CDH 6.2)
  15. Java实现对已有的PDF添加页码
  16. 什么是物联网卡ICCID?如何查看?
  17. 【python】画玫瑰花喽!!!
  18. 计算机开放电子书归档 2018 1
  19. 百合数c语言360问答,百合数量的含义?
  20. WIN7远程桌面连接方法!远程控制教程!XP远程桌面连接教程!如何设置远程桌面连接?远程桌面连接设置...

热门文章

  1. OpenGL学习之路17---- 镜面反射光
  2. 苏州大学在职研究生计算机专业,苏州大学在职研究生入学须知
  3. 小米蓝牙温度计2接入home assistant
  4. codeforces 1635E-Cars (二分图染色+拓扑排序)
  5. 测试硬盘软件hd不能结束进程,终于解决了HD TUNE以及所有其他硬盘检测工具都不能使用的情况。。...
  6. Element的Cascader 级联选择器禁用和回显问题
  7. uni-app-微信小程序-预览报错
  8. 怎么可以修改pr基本图形中的文字_AE特效文字转PR图形预设
  9. 前端漂亮的字体 font-family
  10. 2021 CNSS招新赛 WEB WP