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的参数进行判断成功与否,需要和后台进行二次确认,异步返回给后台的数据才是最终的

 

看官方给的说法

差不多介绍到这里了,自己微信遇到的坑没有接入支付宝的时候多,接过支付宝再接入

微信,真的太简单了,有空再写个支付宝支付,觉得有帮到大家的记得给个赞哦~~~

遇到其他问题了再补充

 

12.6日更新:同一订单支付两次的问题,商户保证支付平台大姨妈的情况下去重



遇到了这么个场景,当你支付完的时候支付宝或者微信没有及时回调,用户已经支付,但是平台还在处理中,也没有异步通知商户后台,例如第一张图的支付宝同步状态码8000 or 6004,第二张图的-1,那么这个时候我们App做完一系列操作之后非人类用户以为没支付,但是其实已经支付了,支付宝和微信大姨妈了,土豪买家又点了支付,这个时候是和9000支付成功不同的,成功的时候支付宝是会去重的,不会让你重复支付的,微信暂时不清楚,这个时候后台还没收到任何回调,又拉起了支付,竟然还能支付,神奇的两个订单产生了,虽然最终最会成功一个订单,另一个订单会支付失败,这个情况遇到了还是很懵逼的,记录下,有不同意见的可以留言分享下。

我的做法就是:

对于同步回调的状态码,让后台再开一个接口post给他,他根据这个状态码避免同一个已支付的订单,但是在处理中的时候重复签名,重复去支付,这样就又能愉快的玩耍了,虽然是比较罕见的操作,但是也得稍微留意下

 

这里就没有Demo了,有个官方的已经很详细了

点击打开微信官方Demo链接

 

原文地址:https://www.cnblogs.com/sunfuyou/p/8386112.html

时间: 2024-11-08 23:11:09

iOS开发微信支付的相关文章

IOS开发--微信支付

前言:下面介绍微信支付的开发流程的细节,图文并茂,你可以按照我的随笔流程过一遍代码.包你也学会了微信支付.而且支付也是面试常问的内容. 正文: 1.首先在开始使用微信支付之前,有一些东西是开发者必须要知道的,打开下面链接: https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=3_1 然后可以看到下面的页面,这个就是微信支付商户平台的开发文档,很多东西是可以查阅和了解的,在开发使用微信SDK支付功能的时候,遇到了问题也可以到这找找相关须知信

iOS开发微信支付的介绍与实现

1.前期准备 1) 到微信开放平台注册账号 需要登录邮箱验证 填写您的商户信息 2) 进入管理中心 --- 移动应用 --- 创建移动应用 --- 根据页面完善应用资料 3) 审核过后,通过应用详情页面,查看应用详情,查看AppID和AppSecret相关信息 4) 创建这些是没有支付能力的,需要额外申请,还是根据提示一步步填写,填写完之后会发一封邮件到您的预留的邮箱,然后到商户平台点击打开链接填写资料,最主要的是验证下开户收款账号,会收到一波几分钱的巨额财产,那么这个时候如果你填写的是你的开户

IOS开发之支付功能概述

前言:本随笔将对IOS开发的支付功能进行一个概述. 内容大纲: 一.常见的支付方案简介 二.第三方支付SDK 三.苹果官方支付方案 四.Web支付方案 正文: 一.常见的支付方案简介 在微信支付中 微信支付的网址是: https://pay.weixin.qq.com/wiki/doc/api/index.html 进去之后,我们可以看到网页,但我接下来主要讲的是app支付 app支付的过程:商业app通过集成微信SDK,用户解析后跳转到微信内软件支付的过程. 点进去app支付: 我们可以看到A

开发微信支付的一点心得

由于使用了别人封装的微信公众平台SDK http://www.cnblogs.com/x3d/p/3740454.html  ,所以省去了完整理解开发手册的时间. 微信支付,即便交了保证金,你还是处理测试阶段,不能正式发布.必须到你通过程序测试提交订单.发货通知等数据到微信的系统中,才能申请发布. 然后,因为在微信中是通过JS方式调用API,必须在微信后台设置支付授权目录,而且要到二级三级目录下去,这对于使用MVC框架来说,是个小问题. 使用MVC,在开发环境,url往往是native url格

python开发微信支付学习记录(转)

前言 微信支付是由微信及财付通联合推出的移动支付创新产品.如今,随着微信支付的全面开放,相关需求也越来越多,很多开发人员进行微信支付开发及商家申请微信支付时,面临着诸多疑惑. 要想开发顺利进行,首先要对业务流程有个清晰的认识.这里以微信公众号支付为例,因此也借用微信支付官方文档中的业务流程图: 接下来来关注几个开发过程中的关键点,包括: 1.生成商户订单与调用统一下单 API 2.微信服务器交互的数据格式 3.公众号支付下网页内通过 JS-API 调起支付 4.异步通知商户支付结果(回调) 一.

Android开发 --微信支付开发(转载!)(开发工具:Eclipse)

Android_APP 微信支付接口开发 日期:2015-10-06 12:47:33 作者: 来源: 人气:3549 1.首先说一下我们在开发微信支付接口的时候遇到最多和最疑惑的问题,那就是明明 appid.商户号.API密钥 都对照了好几遍确实是和自己的一样,并且也没有在Log日志中出现签名错误等信息,却始终调不起微信支付,或是直接回到支付结果后的界面并提示 “微信支付结果:null;code=-1”.这就是微信支付中的一个深坑之处(为什么说这是深坑之处呢?会在下面特别说明). 2.下面就教

C#开发微信支付之企业向用户付款

1.企业付款的介绍 所谓企业付款指的是,在功能开放后诸如保险行业的客户理赔.退保.商品退款.发放征集活动奖金.抽奖互动等操作都可以通过企业付款完成.而此前,微信支付只能提供客户向企业单向付款. 商户如果需要给用户付款,可以直接将钱打入用户的"微信零钱"中,微信支付将做零钱入账消息通知,零钱收支明细会展示相应记录.针对无零钱账户的历史客户端版本,资金将进入用户的红包账户,微信支付无消息通知用户,企业可选择自行触达用户. 通过认证的企业号可以开通微信支付功能.通过认证的企业号可以管理平台的

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

微信支付时,安卓机调用 jsapi可以支付,IOS就不行,点击立即支付,直接返回原立即支付页面,跟刷新页面差不多,解决方案很简单:两句话而已. 不得不说,微信支付坑太多了,我擦..... <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <asp:Button ID="btnSubmit" runat="server" Text

iOS集成微信支付

微信支付的开发 前言:之前听说过微信支付有很多坑,其实没有想象的那么坑,整体感觉很容易上手,按照它的流程来不会有错!PS:官方的流程看的TMD烦,好啦,废话有点多,进入开发.(ps:每个微信的版本一直都在更新,这是2015/6/1给你们做的标记 1.    导入微信支付库 微信开放平台新增了微信模块用户统计功能,便于开发者统计微信功能模块的用户使用和活跃情况.开发者需要在工程中链接上:SystemConfiguration.framework,libz.dylib,libsqlite3.0.dy