• 实战--接入最坑的支付宝



    Paste_Image.png

    因为项目中需要用到支付,所以这一周就开始集成支付,因为微信支付貌似需要缴纳200元才能使用微信第三方登陆,支付等功能,所以公司先要求集成支付宝,百度了一下,集成支付宝的过程,很多人都说集成支付宝太坑了,但我觉的前端还好,坑的是后台,后台天天吆喝着支付宝官方的文档和demo太坑了,如果是后台的话,不要太相信支付宝官方文档和demo,话不多说,集成开始!!!!!

    支付大概流程图


    (下面的话是引用 )
    (文/WK_IOSDevelpoer(简书作者)
    原文链接:http://www.jianshu.com/p/b88f87a552a1)

    1.用户选好了商品后,点击提交订单(一般是这样),选择使用支付宝付款。
    2.手机客户端(你做的APP)把用户选择的商品的信息传给你们后台服务器。
    3.后台的服务器将各种数据拼接签名后生成一个签名后的字符串,回传到客户端APP上。
    4.用户点击确认支付按钮,调用手机支付宝客户端(在你手机上装的那个),利用后台传过来的那个参数调起支付宝,让支付宝客户端传给他们服务器交互,进行付款。(这一步是支付宝自己完成的,安全性高)
    5.支付宝的服务器将支付的结果(可能成功也可能不成功)返回给手机支付宝客户端和你们公司的后台服务器。
    6.你们公司后台服务器收到后一般是更新下数据信息(这个咱们不用管),手机支付宝客户端会显示一下支付成功,咱们的客户端也可以显示一个订单支付成功之类的东西(就像在手机12306订票,用支付宝支付后支付宝客户端会说一次支付成功,12306也会说一次支付成功,咱们就像12306客户端一样,需要再说一次订单支付成功)。

    1.下载官方demo和sdk

    https://github.com/chenyang-ios/alipay.git
    里面有官方demo和sdk,下这个就行,在一起呢!!!

    2、配置支付宝sdk


    01配置支付宝的SDK.png

    3、导入依赖库


    Paste_Image.png

    4、添加 URL schme


    05URL schme配置.png

    5、添加白名单

    在info.plist里面添加


    Paste_Image.png

    6、在pch文件里面导入

    增加一个预编译头文件,导入
    import <Foundation/Foundation.h>
    import <UIKit/UIKit.h>

    7、编译,会报错


    Paste_Image.png

    解决办法:Targets->Build Settings->Header Search Path中添加AliPaySDK文件夹的路径

    !!!!!添加路径的时候直接将路径拖进去就行了,不要看到里面有个加号,先点击加号,再拖进去,那是没用的~这个我弄了半天,烦人!!!!


    Paste_Image.png

    8.如果编译没问题就成功一大半了,我们开始集成代码,直接上代码,用的话直接粘贴复制!!!在点击支付的按钮的触发事件里面写

    "

      //1. partnerID
                NSString *partnerID = @"2088421512225446";
    
                //2. sellerID
    
                NSString *sellerId = @"miracle@mcqiji.com";
    
                //3. 私钥
    
                NSString *privatekey = @"MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALvqLWelnudXoSuEWXS+8RUMiTg0qrFWP2PrDFg9Keb9DyiCJbabZp7eoX1EJxETWuoXsNpmTS0IkYG5GSMdEcf1kFYR8XRr4dkFsXv+cOd0i+uXm26/IlYm48jX6VANtQBqESbv+7vYQoPeCD6fPh2bqD9BLaRtyGs10bGBm0GFAgMBAAECgYBT6K19qqbaBnchR2fqiZh9HavoPRw7M5f6teo9PJKJYlZycCsG7z1Tk3XoyZXoOgxOm2WNIEE16q2Oj2h6FXDqY7n17bw64lxERpFIMzuKEqVSGeDqHaVEFtN1EE1XRH04DY00UQEaIEpdX0FeRkxzpHWeRVQUpPreX0wT3ENBwQJBAPZSRBjrhPlO8xRhq4uGBp4bejNbYilgIhkkCC5/qYIBUxwoW4kSYvsJ/8tywYQ5I8I6Py1bRBBocyUFNe2yhvMCQQDDTGcBZv9Gs5etGWC3MFNYwQXDip3iL6R7Rv8xuD70N9YUneVPxP+Nikb2dihbuvyAMIfjyt70rwVp3c+gBiOnAkAHl5mJuxiqJojPhAMplcP2c5pcouBvrgrfA4FNDZpH64qIP6Yyn2J1omVD/BGC5c/4WJtB5qI+bzm9Vl/HJ82JAkEAgLzfdbQweKmwRUHiWD954ZqzsvewJcakFUNyu5KppREdhM+ktpW0o9fP+W1gIz+6bMIRAd7cY8zvs56s297QJwJAFSROxXaKUTQJ2DPrDL6YPE+7QjuS31KJMhJXWs7XPWWELigdHYrhCDPO5BQb7Vkz9p5prZRUDIINZbqJA7qSHQ==";
                    /*
                 *生成订单信息及签名
                 */
                //将商品信息赋予AlixPayOrder的成员变量
                Order *order = [[Order alloc] init];
                order.partner = partnerID;
                order.sellerID = sellerId;
                order.outTradeNO = _num; //订单ID(由商家自行制定)
                order.subject = _titl; //商品标题
                order.body = _cont; //商品描述
                order.totalFee = [NSString stringWithFormat:@"%@",jiage]; //商品价格
                order.notifyURL = huiURL; //回调URL
    
                order.service = @"mobile.securitypay.pay";
                order.paymentType = @"1";
                order.inputCharset = @"utf-8";
                order.itBPay = min;
                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;
                if (qianming != nil) {
                    orderString = [NSString stringWithFormat:@"%@&sign="%@"&sign_type="%@"",
                                   orderSpec,qianming, @"RSA"];
    
                    NSLog(@"%@",orderString);
    
                    [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
                        NSLog(@"reslut = %@",resultDic);
    
    
                    }];
                }

    为了安全订单信息都是后台给你的


    Paste_Image.png

    这个官方签名订单信息,官方demo把订单号和签名都放在前端了,但是实际开发是签名订单号都是后台做的,让后台给你就行,到时候这两句话屏蔽,将


    Paste_Image.png

    将官方的画框的直接替换成从后台获取的的签名就行

    在appdelegate.m文件的代码,有两个方法,一个是9.0之后的,一个是9.0之前的,为了安全我都写了

    导入头文件
    import <AlipaySDK/AlipaySDK.h>

    //9.0之后的
    - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
    {
    
        //如果极简开发包不可用,会跳转支付宝钱包进行支付,需要将支付宝钱包的支付结果回传给开发包
        if ([url.host isEqualToString:@"alisdkdemo"]) {
            [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
                //【由于在跳转支付宝客户端支付的过程中,商户app在后台很可能被系统kill了,所以pay接口的callback就会失效,请商户对standbyCallback返回的回调结果进行处理,就是在这个方法里面处理跟callback一样的逻辑】
                NSLog(@"result = %@",resultDic);
    
                NSInteger orderState=[resultDic[@"resultStatus"] integerValue];
    
                if (orderState==9000) {
                    NSString *allString=resultDic[@"result"];
                    NSString * FirstSeparateString=@""&";
                    NSString *  SecondSeparateString=@"="";
                    NSMutableDictionary *dic=[NSMutableDictionary dictionaryWithDictionary:[UserInfo VEComponentsStringToDic:allString withSeparateString:FirstSeparateString AndSeparateString:SecondSeparateString]] ;
    
                    NSLog(@"ali=%@",dic);
    
                    if ([dic[@"success"]isEqualToString:@"true"]) {
                        [[NSNotificationCenter defaultCenter] postNotificationName:@"AliPaySucceed" object:nil userInfo:dic];
    
                        NSLog(@"支付成功");
    
                        [[NSNotificationCenter  defaultCenter] postNotificationName:@"result" object:nil userInfo:resultDic];
    
    
    
                    }
    
                }else{
                    NSString *returnStr;
                    switch (orderState) {
                        case 8000:
                            returnStr=@"订单正在处理中";
                            break;
                        case 4000:
                            returnStr=@"订单支付失败";
                            break;
                        case 6001:
                            returnStr=@"订单取消";
                            break;
                        case 6002:
                            returnStr=@"网络连接出错";
                            break;
    
                        default:
                            break;
                    }
    
                }
    
    
    
    
    
            }];
        }
        if ([url.host isEqualToString:@"platformapi"]){//支付宝钱包快登授权返回authCode
    
            [[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
                //【由于在跳转支付宝客户端支付的过程中,商户app在后台很可能被系统kill了,所以pay接口的callback就会失效,请商户对standbyCallback返回的回调结果进行处理,就是在这个方法里面处理跟callback一样的逻辑】
                NSLog(@"result = %@",resultDic);
    
    
            }];
        }
        return YES;
    }
    //9.0之前的方法
    -(BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString *,id> *)options{
    
    
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
    
    
            NSLog(@"result = %@",resultDic);
    
            NSInteger orderState=[resultDic[@"resultStatus"] integerValue];
    
            if (orderState==9000) {
                NSString *allString=resultDic[@"result"];
                NSString * FirstSeparateString=@""&";
                NSString *  SecondSeparateString=@"="";
                NSMutableDictionary *dic=[NSMutableDictionary dictionaryWithDictionary:[UserInfo VEComponentsStringToDic:allString withSeparateString:FirstSeparateString AndSeparateString:SecondSeparateString]] ;
    
                NSLog(@"ali=%@",dic);
    
                if ([dic[@"success"]isEqualToString:@"true"]) {
                    [[NSNotificationCenter defaultCenter] postNotificationName:@"AliPaySucceed" object:nil userInfo:dic];
    
                    NSLog(@"支付成功");
    
                    [[NSNotificationCenter  defaultCenter] postNotificationName:@"result" object:nil userInfo:resultDic];
    
    
    
                }
    
            }else{
                NSString *returnStr;
                switch (orderState) {
                    case 8000:
                        returnStr=@"订单正在处理中";
                        break;
                    case 4000:
                        returnStr=@"订单支付失败";
                        break;
                    case 6001:
                        returnStr=@"订单取消";
                        break;
                    case 6002:
                        returnStr=@"网络连接出错";
                        break;
    
                    default:
                        break;
                }
    
            }
    
        }];
    
        return YES;
    
    }

    appdelegate里面的方法block是走app客户端的时候才会调用,如果手机没有客户端,就回自动跳到网页端,没事,支付宝直接写好了,我们不用管,网页端支付成功会走这个block


    Paste_Image.png

    客户端的话会走这个block


    Paste_Image.png

    支付成功的页面跳转问题,我用的是通知,不能直接跳的!!!这个要注意,比如用客户端

    在appdelegate里面


    Paste_Image.png

    在点击支付的里面


    Paste_Image.png

    注意如果遇到这个问题,一般是签名错了,问后台,让他改!!!


    Paste_Image.png

    支付成功以后支付宝给你返回的9000(代表支付成功),或者其他的,这个只是支付宝通知的,直返完成支付宝还会给后台异步通知,后台要判断签名被人篡改没有,最终的支付状态还是要听后台的,在那两个block里面在进行一次网络请求,让后台给你支付状态,成不成功听后台的!!!!!!我感觉我想到的我都写了,还有什么问题可以给我留言~~~

    出处这里:http://www.jianshu.com/p/13db9e3adad8

  • 相关阅读:
    LeetCode——Generate Parentheses
    LeetCode——Best Time to Buy and Sell Stock IV
    LeetCode——Best Time to Buy and Sell Stock III
    LeetCode——Best Time to Buy and Sell Stock
    LeetCode——Find Minimum in Rotated Sorted Array
    Mahout实现基于用户的协同过滤算法
    使用Java对文件进行解压缩
    LeetCode——Convert Sorted Array to Binary Search Tree
    LeetCode——Missing Number
    LeetCode——Integer to Roman
  • 原文地址:https://www.cnblogs.com/xiaohouzai/p/7041813.html
Copyright © 2020-2023  润新知