IOS开发支付宝集成

作者: 曾迦 | 来源:发表于2015-12-16 15:21 被阅读6930次

    开发准备


    1.首先新建项目,然后去官网下载最新的开发包:
    http://doc.open.alipay.com/doc2/detail?treeId=59&articleId=103563&docType=1,
    当然也可以用CocoaPods来下载不过用这个下载的话只会下载到单纯的客户端与网络服务请求的SDK不包含加密的那些代码,而有些公司是要把加密做到本地的所以选择哪种方式看开发者的习惯于公司需求.
    2.下载后打开点击开发包可以打开更新日志来比对当前版本不要去一些非官网的地方下载SDK有可能不是最新版本会出现BUG
    3.打开客户端开发包找到IOS对应的包文件解压得到开发包,包含1个framework文件一个bundle文件一个Demo文件夹

    一般情况下支付功能的交互流程


    比如我们去某个APP去支付一个产品,流程为:
    1.用户点击支付->
    2.客户端请求服务器用户支付->
    3.服务器接收请求生成金额订单等要给第三方支付的一切信息,并生成回调参数传给客户端->
    4.客户端接收信息(一般会再让用户确认支付或者干脆购买后是生成订单,然后才是付款)并将服务器给的信息分别传入SDK需要的参数中,调用SDK的支付方法->
    5.由SDK向SDK自己的服务器发出支付请求,SDK自己的服务器接收支付请求处理成功后,给客户端本身与公司的后台都发送一条支付成功的消息,客户端与后台根据这条消息再做处理.

    针对开发环境的一些设置


    支付又分为2种情况本地签名,和服务器签名,我用到正好都是公司要求本地签,服务器的我就稍微说1点.

    服务器签名:
    /**
     *  支付接口
     *
     *  @param orderStr       订单信息
     *  @param schemeStr      调用支付的app注册在info.plist中的scheme
     *  @param compltionBlock 支付结果回调Block
     */
    - (void)payOrder:(NSString *)orderStr
          fromScheme:(NSString *)schemeStr
            callback:(CompletionBlock)completionBlock;
    
    

    服务器签名注意的是在callback:回调中要进行验签,就是把服务器给的订单签名信息在用公钥解密,比对订单细节,检查是否被他人篡改,并且如果是wap支付,不会反回在appDelegateapplication:openURL方法.

    本地签名:

    先拖入实现加密的文件与模型:

    加密的文件.png

    这时候会报错(补充一点: 有些朋友找不到NSString或者一些数据类型报错都是因为缺少Foundation头文件,可能我写的不太明白,有些朋友还是不太懂)大部分错误都是因为一些文件中在支付宝的Demo的Pch文件中统一添加的#import <Foundation/Foundation.h>,如果我们的项目中没有这一步,那么要么也建立pch要么单独添加上.

    这时还会有一个错误:

    路径找不到.png

    注意这里的Header Search Paths 路径为空:

    路径为空.png

    打开电脑这个文件的所在地 双击Header Search Paths将电脑的文件拖入Header Search Paths会生成一个路径:

    生成的路径.png

    导入一来框架: 这个最好跟着Demo一个一个往里添加,也不要光看网上资料主要还是看Demo:

    导入框架.png

    添加SDK和静态库:


    SDK静态库.png

    报错:这个错误与另外一种说SDK不支持64位比较常见,都是把静态库或者SDK都删了重新导入就行了


    错误信息.png
    到这里应该已经可以运行程序了.
    如果还是出现了编译错误等问题,导入框架不全与SDK静态库的路径错误比例比较大.
    建议等能够运行程序后在进行开发.
    

    正式开发

    首先我们介绍一段代码:

      NSString *orderSpec = [order description];
    

    将商品的信息添加为字符串order是一个对象,而description]是将这个对象的属性进行拼接返回一个字符串.

    在介绍3个属性:

    //合作商户ID。用签约支付宝账号登录ms.alipay.com后,在账户信息页面获取。
    NSString *partner = @"";
    //账户ID。用签约支付宝账号登录ms.alipay.com后,在账户信息页面获取。
    NSString *seller = @"";
    //商户私钥,自助生成
    NSString *privateKey = @"";
    

    这3个属性必须是个人或公司申请后才能得到的..我用的公司的就不写上了请自行填写.

    //将商品信息赋予AlixPayOrder的成员变量
        Order *order = [[Order alloc] init];
        order.partner = partner;
        order.seller = seller;
        order.tradeNO = @"G111111111111"; //订单ID(由商家自行制定)
        order.productName = @"我的测试"; //商品标题
        order.productDescription = @"我的商品描述"; //商品描述
        order.amount = @"0.01"; //商品价格
        order.notifyURL =  @"http://www.xxx.com"; //回调URL
        
        order.service = @"mobile.securitypay.pay";
        order.paymentType = @"1";
        order.inputCharset = @"utf-8";
        order.itBPay = @"30m";
        order.showUrl = @"m.alipay.com";
        
        //应用注册scheme,在AlixPayDemo-Info.plist定义URL types
        NSString *appScheme = @"alisdkdemo";
        
        //将商品信息拼接成字符串
        NSString *orderSpec = [order description];
        NSLog(@"orderSpec = %@",orderSpec);
        
        //获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode
        id<DataSigner> signer = CreateRSADataSigner(privateKey);
        NSString *signedString = [signer signString:orderSpec];
        
        
        NSString *orderString = nil;
    
    

    生成加密后的字符串 注意的是NSString *appScheme = @"alisdkdemo";这个值是从支付宝的商户地址中填写的,请保持一致.

    最后处理结果:

    if (signedString != nil) {
            orderString = [NSString stringWithFormat:@"%@&sign=\"%@\"&sign_type=\"%@\"",
                           orderSpec, signedString, @"RSA"];
            
            [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
                
                //结果处理,其实就是取字典里面的内容,这个取字符串然后变个模型就好了 或者直接取不便模型,方法很多.
                NSLog(@"开始确认支付状态 %@",resultDic[@"resultStatus"]);
                AlixPayResult* resultModel = [AlixPayResult itemWithDictory:resultDic];
                if (resultModel)
                {
                    //状态返回9000为成功
                    if (resultModel.statusCode == 9000)
                    {
                        /*
                         *用公钥验证签名 严格验证请使用result.resultString与result.signString验签
                         */
                        NSLog(@"支付宝交易成功");
                        
                        /*
                         *用公钥验证签名 严格验证请使用result.resultString与result.signString验签
                         */
                        
                        //交易成功
                        NSString* key = AlipayPubKey;//签约帐户后获取到的支付宝公钥
                        id<DataVerifier> verifier;
                        verifier = CreateRSADataVerifier(key);
                        
                        // 验证签名
                        if ([verifier verifyString:resultModel.resultString withSign:resultModel.signString])
                        {
                            //验证签名成功,交易结果无篡改
                            NSLog(@"验证成功");
                        }
                    }
                }
                else if([resultDic[@"resultStatus"]isEqualToString:@"6001"])
                {
                                   //用户取消
                    NSLog(@"用户主动取消支付");
                }else
                {
                   
                }
            }];
    }
    

    这里注意:if([resultDic[@"resultStatus"]isEqualToString:@"6001"])支付宝有BUG 这个6001 不要信,可以和公司商量下,是加个确认接口还是一定时间内检查后台,总之很有可能用户付钱成功,SDK通知你用户手动取消,这个BUG是在弱网状态下比较多.

    然后记得在 AppDelegate里面加上如下代码:

    //只要是调用手机上的支付宝客户端,在支付宝客户端操作完成返回自己的app时,都会调用这个方法,
    - (BOOL)application:(UIApplication *)application
                openURL:(NSURL *)url
      sourceApplication:(NSString *)sourceApplication
             annotation:(id)annotation {
        //跳转支付宝钱包进行支付,需要将支付宝钱包的支付结果回传给SDK(这个是将支付宝客户端的支付结果传回给SDK)
        if ([url.host isEqualToString:@"safepay"]) {
            [[AlipaySDK defaultService]
             processOrderWithPaymentResult:url
             standbyCallback:^(NSDictionary *resultDic)
             {
                 NSLog(@" ------result = %@",resultDic);//返回的支付结果
             }];
        }
        return YES;
    }
    

    最后记得把这里写了:

    URL.Types.png

    NSString *appScheme = @"alisdkdemo"代码 网页上申请的 图片上那里填写的保持一致.


    补充: 如果要用swift来调用支付宝SDK 最好把支付的与回调的逻辑单独建立工具类传递数据便好,从流程上本身无太大区别稍微注意的是在swiftAlipaySDK.h有可能因为语言环境问题出现缺少引入类的情况,少什么补什么就好,其他也一样.

    如有问题欢迎留言...

    相关文章

      网友评论

      • 草原野马:还有就是支付成功后验证签名失败了,可以做一些什么处理
      • 草原野马:有个问题请教下 支付成功后的签名验证成功后和 if ([verifier verifyString:resultModel.resultString withSign:resultModel.signString])
        {
        //验证签名成功,交易结果无篡改
        NSLog(@"验证成功");
        }



        分别和app delete里面的支付成功的回调 ,分别成功或者失败可以做什么操作,比如签名验证失败了,我需要做设么操作吗
      • 半生飘零:最后那个NSLog //返回的支付结果 不打印 是为什么啊 楼主
      • FB不是非死不可:payOrder 中的callback 好像只有网页支付的时候才会有回调,客户端支付的话如何捕捉到支付结果
        FB不是非死不可:@曾迦 已经解决了,谢啦
        曾迦:@FB不是非死不可 然后记得在 AppDelegate里面加上如下代码: 我在文章中的最下端有写
      • 李国安:非常感谢!
      • 简书白兔:你好,我想问一下,集成支付宝支付,那三个属性,我们公司暂时没有申请,那我怎么测试demo。
        曾迦:@CrazyBub 我记得下载的SDK里有一个Demo 那个Demo上应该有可以测试用的码吧
        sonialiu:@CrazyBub 好像有沙箱环境测试
      • acbb784fc973:楼主,我想请教个问题,支付宝怎么向APP服务器充值或者提现,SDK里面有个方法吗
      • 8ae158dda3f2:问个问题,privateKey 是不是就是本地终端生成的RSA私钥,支付宝的“交易安全校验码” 又是什么东西,有什么用。还有那个支付宝的公钥又是什么,难道就是这个“交易安全校验码”?
      • whereandhere:您好,我想问下。我写了回调地址,支付成功,后台却说没有收到支付宝的信息
        whereandhere:@曾迦 恩,谢谢你回答
        曾迦:@whereandhere 支付宝服务器 向你们后台发的信息 应该和客户端 没太大关系吧... 只要你这边SDK通知你支付成功后 确实扣款成功 那么就是 支付宝服务器 和你们后台服务器的问题了
      • CX_cxy:博主,我想问下,你说的那个支付宝bug, 6001 有解决办法吗? 我这边是进入支付宝直接就提示“交易已经支付,请勿重新付款”,然后返回6001错误码.
        曾迦:@CX_cxy 会不会是这个单号你们测试过了
      • 228c7253990f:AlixPayResult 类在官方demo 没有找到,是不是现在支付完成不需要验证吗? 顺便提供(AlixPayResult.m)
        58cb860debdd:@xuxg 是呀,现在没有了
      • c4322766f2b8:如果再加上app跳转的各种截图就更好了!
      • 阳光的大男孩儿:搞定了,一种是因为没有#import <Foundation/Foundation.h>,另一种原因是因为,缺少文件路径。你说的对,我写的文件路径有问题。
      • 阳光的大男孩儿:我想问问一下,博主,怎么运行支付宝下载的demo呢?我也对于那三个属性我也有了,我放到只下载好的支付宝里面,就是运行不出来,密匙一直显示为空,是怎么回事?
        阳光的大男孩儿:@WK_IOSDevelpoer 什么事BID?怎么改?
        曾迦:@依然那么爱你1314 是运行不起来还是什么问题?,那3个属性是公司申请的嘛?如果是的话如楼上所说,公司申请时的BID和支付宝下载Demo的BID肯定是不一样的,可以改改试试,或者支付宝下载的那个Demo我忘了是不是有默认的属性了,可以用那个默认属性试试,要么就自己写个demo用公司的BID加上那3个属性.
        Ke_Wang:@依然那么爱你1314 把BID改一下,我就是改一下能运行了
      • 秋桐树下:不错👍

      本文标题:IOS开发支付宝集成

      本文链接:https://www.haomeiwen.com/subject/lnnuhttx.html