美文网首页iosiOSDevSupport
iOS接入支付宝支付(小白都能看懂的支付宝支付)

iOS接入支付宝支付(小白都能看懂的支付宝支付)

作者: lyonLiu | 来源:发表于2016-06-15 10:23 被阅读24551次

    因为近期项目中需要接入支付宝支付功能,自己也爬了很多的坑,所以做了一下这边文章供大家学习参考,远离爬坑,文章主要讲到以下五部分:


    一、支付宝开放平台创建应用

    二、签约移动支付功能

    三、接入支付前的准备工作附准备工作中遇到难题的解决方法

    四、配置官方Demo附BUG解决方法

    五、集成项目,具体代码编写、


    本文为本人学习记录笔记,如需转载,请注明出处@iOSlyon


    支付宝开放平台创建应用 登录支付宝开放平台

    管理中心创建应用

    1. 应用创建完成后点击查看我的应用详情进行移动支付功能的签约
    或者
    2.进入支付宝商家服务页面"https://b.alipay.com/newIndex.htm"选择移动支付功能进行签约


    签约过程以下以签约移动支付功能为例子

    商户签约审核签约审核具体步骤请参见支付宝官方文档签约与审核
    或者
    ️️️️️️️ 下列图示

    • 填写签约信息


      填写签约信息

    上图的附件文档因为有次文档错误导致审核不通过,所以以下贴出审核成功的文档供大家参考

    Paste_Image.png

    上述签约步骤审核通过之后就可以开始集成工作了


    接入前准备工作

    第一步、商户密钥管理密钥作用

    2.1.生成步骤
    2.2.上传步骤

    这个步骤完全可以看官方文档中的操作,官方文档写得很详细,但是其中有几点需要说明:

    一、说明问题
    上传密钥步骤不知道怎么上传?因为密钥是pem文件,但是上传的是字符串文本。
    一、解决方法
    将生成的pem文件复制一份到桌面,改成Txt文件打开即可获取我们需要的字符串,记住当我们引用这两个长的字符串时,字符串不能包括,换行,空格,以及其他误加的字符,所以复制的时候一定要小心。

    二、说明问题
    Mac 自带openssl环境,不用安装,直接终端输入openssl就可以。


    配置官方Demo代码部分下载Demo

    支付宝官方Demo中需要配置商户的资料(如下)

    //开放平台登录https://openhome.alipay.com/platform/appManage.htm
    //管理中心获取APPID
    #define MXAlipayAPPID       @"请配置你的AppID"
    //支付宝私钥(用户自主生成,使用pkcs8格式的私钥)
    #define MXAlipayPrivateKey  @"请配置你的支付宝pkcs8私钥"
     
    
    配置以上数据后,真机编译,遇到以下问题
    • 输出错误信息如配置信息中的私钥(即上述PartnerPrivKey)使用的不适pkcs8的私钥的话,则会报以下错误
    rsa_private read error : private key is NULL
    
    • 解决方法:
    • 方法一将私钥转成PKCS8替换一下原私钥即可转换方法如下
      ( PHP服务端语言读取私钥不需要PKCS8转换)
    OpenSSL> genrsa -out rsa_private_key.pem   1024  #生成私钥
    OpenSSL> pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt -out rsa_private_key_pkcs8.pem #Java开发者需要将私钥转换成PKCS8格式
    OpenSSL> rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem #生成公钥
    OpenSSL> exit #退出OpenSSL程序
    
    • 方法二检查PID是否写正确
    接下来重新运行,上述错误已经解决,但遇到新问题如下图
    • 弹框显示


    • 解决方法: 可参考百度中查到的结果上述问题解决方法

      • 问题源头是因为私钥跟商户上传的公钥不匹配

    处理完上述问题之后,就可以进行支付操作了


    测试Demo具体操作

    1.创建一个AlipayDemoTest项目
    2.新建一个AliSDK文件夹,提取SDK包中以下文件到此文件夹里,

    支付宝所需导入SDK文件

    3.编译项目,会出现以下问题:

    1)"Unknown type name ‘NSString‘ "或"Unknown type name ‘NSData‘ "

    报错信息

    这是因为缺少Foundation类库和UIKit类库,支付宝Demo中之所以没有出现此错误,是因为在.pch文件中导入过这些类库

    解决办法:只需要在出现错误的文件中导入这些类库即可

    导入库

    2)‘openssl/asn1.h‘ file not found

    报错信息

    这是openssl文件夹头文件链接问题,如果openssl文件夹随意拉进项目中,即使添加头文件链接,也可能解决不了此问题,

    这也是一开始就将所需要的文件放到一个新建文件夹中再添加到项目中的原因。

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


    4.编译项目,会出现以下问题:

    Paste_Image.png

    解决方法:在xcode中,点击项目名,选择"target"->"Link Binary With Libraries"添加依赖库。

    Paste_Image.png
    编辑程序,已经可以成功编译了,接下来就是集成代码了
    
    #import "AppDelegate.h"
    #import <AlipaySDK/AlipaySDK.h>
    @interface AppDelegate ()
    
    @end
    
    @implementation AppDelegate
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
        // Override point for customization after application launch.
        return YES;
    }
    
    - (BOOL)application:(UIApplication *)application
                openURL:(NSURL *)url
      sourceApplication:(NSString *)sourceApplication
             annotation:(id)annotation
    {
        
        if ([url.host isEqualToString:@"safepay"]) {
            //跳转支付宝钱包进行支付,处理支付结果
            [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
                NSLog(@"result = %@",resultDic);
            }];
        }
        return YES;
    }
    
    // NOTE: 9.0以后使用新API接口
    - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options
    {
        if ([url.host isEqualToString:@"safepay"]) {
            //跳转支付宝钱包进行支付,处理支付结果
            [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
                NSLog(@"result = %@",resultDic);
            }];
        }
        return YES;
    }
    
    @end
    
    #import "ViewController.h"
    #import "Order.h"
    #import "DataSigner.h"
    #import <AlipaySDK/AlipaySDK.h>
    
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
     
     
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        /*=========================================================*/
        /*====客户端调用支付宝支付(实际操作请放到服务端)=================*/
        /*=========================================================*/
        
        //AppId和PrivateKey没有配置下的提示
        if (  [MXAlipayAPPID length] == 0
            ||[MXAlipayPrivateKey length] == 0
            ||[MXAlipayAPPID isEqualToString:@"请配置你的AppID"]
            ||[MXAlipayPrivateKey isEqualToString:@"请配置你的支付宝pkcs8私钥"])
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
                                                            message:@"缺少appId或者私钥。"
                                                           delegate:self
                                                  cancelButtonTitle:@"确定"
                                                  otherButtonTitles:nil];
            [alert show];
            return;
        }
        
        //商品价格
        NSString *price = [NSString stringWithFormat:@"%.2f", 0.01];
        
        
        //将商品信息赋予AlixPayOrder的成员变量
        Order* order    = [Order new];
        order.app_id    = MXAlipayAPPID;// NOTE: app_id设置
        order.method    = MXUrlAlipay;  // NOTE: 支付接口名称
        order.charset = @"utf-8";       // NOTE: 参数编码格式
        
        NSDateFormatter* formatter = [NSDateFormatter new];
        [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
        order.timestamp = [formatter stringFromDate:[NSDate date]];    // NOTE: 当前时间点
        
        order.version   = @"1.0";       // NOTE: 支付版本
        order.sign_type = @"RSA";       // NOTE: sign_type设置
        
        // NOTE: 商品数据
        order.biz_content                   = [BizContent new];
        order.biz_content.body              = @"我是测试数据";
        order.biz_content.subject           = @"1";
        order.biz_content.out_trade_no      = [self generateTradeNO];   //订单ID(由商家自行制定)
        order.biz_content.timeout_express   = @"30m";                   //超时时间设置
        order.biz_content.total_amount      = price;                    //商品价格
        
        //将商品信息拼接成字符串
        NSString *orderInfo         = [order orderInfoEncoded:NO];
        NSString *orderInfoEncoded  = [order orderInfoEncoded:YES];
        NSLog(@"orderSpec = %@",orderInfo);
        
        // NOTE: 获取私钥并将商户信息签名,外部商户的加签过程请务必放在服务端,防止公私钥数据泄露;
        //       需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode
        id<DataSigner> signer = CreateRSADataSigner(MXAlipayPrivateKey);
        NSString *signedString = [signer signString:orderInfo];
        
        // NOTE: 如果加签成功,则继续执行支付
        if (signedString != nil) {
            //应用注册scheme,在AliSDKDemo-Info.plist定义URL types
            NSString *appScheme = MXURLScheme;
            
            // NOTE: 将签名成功字符串格式化为订单字符串,请严格按照该格式
            NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@",
                                     orderInfoEncoded, signedString];
            
            // NOTE: 调用支付结果开始支付
            [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
                NSLog(@"reslut = %@",resultDic);
            }];
        }
    }
    
    #pragma mark - Private Method
    
    //==============产生随机订单号==============
    
    + (NSString *)generateTradeNO
    {
        static int kNumber = 15;
        
        NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        NSMutableString *resultStr = [[NSMutableString alloc] init];
        srand((unsigned)time(0));
        for (int i = 0; i < kNumber; i++)
        {
            unsigned index = rand() % [sourceStr length];
            NSString *oneStr = [sourceStr substringWithRange:NSMakeRange(index, 1)];
            [resultStr appendString:oneStr];
        }
        return resultStr;
    }
    @end
    

    这里也可以下载我自己搭建的DEMO

    已解决所有错误

    下载后替换掉MXAlipayConfig.h中的配置参数即可运行,前提是你的参数不能错

    使用方法可以参考Demo中的ReadMe文件

    正式接入阶段


    服务端
    负责生成订单及签名,及接受支付异步通知。
    客户端
    负责使用服务端传来的订单信息调用支付宝支付接口,及根据SDK同步返回的支付结果展示结果页。
    服务端接入
    私钥必须放在服务端,签名过程必须放在服务端。


    集成支付宝后打包ipa,报如下一系列警告:


    Paste_Image.png

    解决方法:

    1. Go to Build Settings -> Build Options -> Debug Information Format
    2. Change the Debug setting from "DWARF with dSYM File" to "DWARF"
    3. Leave the Release setting at "DWARF with dSYM File"
      AlipaySDK.framework 是先 build 的静态 lib ,然后转成的 framework ,但是在 build 静态 lib 时 CLANG_ENABLE_MODULES 没有被设置成 disabled 。

    常见问题

    APP支付报错ALI64处理方案
    APP支付报错ALI40247处理方案

    相关文章

      网友评论

      • 卓敦:是不是支付宝集成都是后台集成,APP端只需要接入SDK就行了吧,后台提供APPkey给我
        lyonLiu:@卓敦 是的,客户端最后只要获取后台返回的字符串去调用支付宝SDK即可。
      • 9fcd33829c9b:大佬 我小白一个 就是支付宝项目中 需签约 但是状态
        • 已生效 能接支付功能还是不能接啊
      • 1剑天下:支付成功之后会自动跳转原来的app里面么?如果支付成功之后立马杀死支付宝,那些回调还走么
      • 梵高的老巫婆:请教下 Order.m中 orderInfoEncoded方法中需要传入自己商户的app_id吗 还有支付接口名称需不需要改?
      • Top_木木:为什么我单独运行开发者平台的De mo时,它总报错 rsa_private read error : private key is NULL,而且我按照你的解决方法,还是一直会报这个错,我把RSA私钥转换格式了,还是不行,我是直接运行de mo的。。求解
        吉s她Hmm:这个工程就是有点问题。。。哪个pch文件在我这里报错。我也不知道是为什么。
      • 断剑:请教一下你们这个支付宝支付审核的时候,需要什么特殊处理吗?
      • Vampire丶Lv:强势Mark
      • 不余先生:不错不错!赞赞赞!
      • AaronDobreva:在支付成功后我接不到返回码,请问这个问题是因为什么?
        菜鸟秦伟康:是呀,我也是模拟器上可以但是真机有错误就没有
      • 丶丶夏天:这个orderSpec 是服务器端的还是客户端的
      • 丶丶夏天:#pragma mark 以下为客户端操作 / 应在服务端操作 (下列有说明)
        #pragma mark - 以下为服务端操作 实际操作应在服务端操作(以上客户端操作仅作为参考)
        这两句没看明白 :cry:
        lyonLiu:@2f0e9d948df7 是的。大部分由服务端去实现,移动端只是调起支付宝
        丶丶夏天:@2f0e9d948df7 是不是“#pragma mark 以下为客户端操作 / 应在服务端操作 (下列有说明)” 这个下面的一大段代码是不该有的,实际开发中以“#pragma mark - 以下为服务端操作 实际操作应在服务端操作(以上客户端操作仅作为参考)”这个下面那段代码为准
      • Hengry:还有个坑:
        使用支付宝集成支付报错 Undefined symbols for architecture x86_64: "_BIO_ctrl", referenced from: _rsa_si
        这种情况 将 AliSDKDemo 中的Framework (AliSDKDemo.framework)下的libcrypto.a 和 libel.a 拷贝,然后导入到自己的项目中搞定

        来源:http://blog.csdn.net/boyqicheng/article/details/50246931
      • May_Dobin:很不错
        lyonLiu:@冰火小小 谢谢:smile:

      本文标题:iOS接入支付宝支付(小白都能看懂的支付宝支付)

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