zoukankan      html  css  js  c++  java
  • 支付宝集成中爬过的一系列坑

    支付宝最近更新了sdk,一切都按照支付宝的要求集成。

    App支付iOS集成流程

    导入代码

    步骤1:启动IDE(如Xcode),把iOS包中的压缩文件中以下文件拷贝到项目文件夹下,并导入到项目工程中。

    AlipaySDK.bundle
    AlipaySDK.framework

    在Build Phases选项卡的Link Binary With Libraries中,增加以下依赖:

    其中,需要注意的是:

    • 如果是Xcode 7.0之后的版本,需要添加libc++.tbd、libz.tbd;
    • 如果是Xcode 7.0之前的版本,需要添加libc++.dylib、libz.dylib(如下图)。

    步骤2:在需要调用AlipaySDK的文件中,增加头文件引用。

    import <AlipaySDK/AlipaySDK.h>

    步骤3:组装请求信息。

    TIPS:这一步应在商户服务端完成,商户服务端直接将组装和签名后的请求串orderString传给客户端,客户端直接传给SDK发起请求。文档和Demo是为了示例效果在客户端实现。
    //将商品信息赋予AlixPayOrder的成员变量
    Order* order = [Order new];
    
    // NOTE: app_id设置
    order.app_id = appID;
    
    // NOTE: 支付接口名称
    order.method = @"alipay.trade.app.pay";
    
    // 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: sign_type设置
    order.sign_type = @"RSA";
    
    // 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 = [NSString stringWithFormat:@"%.2f", 0.01]; //商品价格
    
    //将商品信息拼接成字符串
    NSString *orderInfo = [order orderInfoEncoded:NO];
    NSString *orderInfoEncoded = [order orderInfoEncoded:YES];
    NSLog(@"orderSpec = %@",orderInfo);
    
    // NOTE: 获取私钥并将商户信息签名,外部商户的加签过程请务必放在服务端,防止公私钥数据泄露;
    //       需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode
    id<DataSigner> signer = CreateRSADataSigner(privateKey);
    NSString *signedString = [signer signString:orderInfo];
    
    // NOTE: 如果加签成功,则继续执行支付
    if (signedString != nil) {
        //应用注册scheme,在AliSDKDemo-Info.plist定义URL types
        NSString *appScheme = @"alisdkdemo";
        
        // NOTE: 将签名成功字符串格式化为订单字符串,请严格按照该格式
        NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@",
                                 orderInfoEncoded, signedString];
        
        // NOTE: 调用支付结果开始支付
        [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
            NSLog(@"reslut = %@",resultDic);
        }];
    }

    详细可参见Demo中示例文件

    • AliSDKDemoAPViewController.h
    • AliSDKDemoAPViewController.m
    • AliSDKDemoOrder.h
    • AliSDKDemoOrder.m

    步骤4:配置支付宝客户端返回url处理方法。

    (外部存在支付包钱包,支付宝钱包将处理结果通过url返回。)

    如示例AliSDKDemoAPAppDelegate.m文件中,增加引用代码:

    import <AlipaySDK/AlipaySDK.h>

    AppDelegate中以下代码中的NSLog改为实际业务处理代码:

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

    针对Demo的运行注意

    1、关于签名代码问题

    • AliSDKDemoUtil及下面所有文件
    • AliSDKDemoopenssl及下面所有文件
    • libcrypto.a
    • libssl.a

    这些文件是为示例签名所在客户端本地使用。实际场景下请商户把私钥保存在服务端,在服务端进行支付请求参数签名。

    2、如果遇到运行后报错,类似于以下提示信息:

    Cannot find interface declaration for 'NSObject', superclass of 'Base64'

    那么需要打开报错了的文件,增加头文件。

    # import <Foundation/Foundation.h>

    3、如果商户要在某个文件中使用支付宝的开发包类库,需增加引用头文件。

    # import <AlipaySDK/AlipaySDK.h>

    4、点击项目名称,点击“Build Settings”选项卡,在搜索框中,以关键字“search”搜索,对“Header Search Paths”增加头文件路径:$(SRCROOT)。如果头文件信息已增加,可不必再增加。

    /***************************/

    (⚠️⚠️⚠️⚠️⚠️)

          IOS openssl/asn1.h file not found的解决方法

    比如 我把openssl这个文件导入到了这个工程目录下 :项目名称/公共类/工具&第三方/支付宝SDK/openssl ,中间隔了三个文件夹,那么在Header Search Paths 的设置就得改为 $(SRCROOT)/项目名 称/公共类/工具&第三方/支付宝SDK,
    问题就解决了再反过来看官方的demo,原来他们把openssl这个文件放到了项目根目录下,所以“Header Search Paths”只需要设置$(SRCROOT)/项目名称
    /***************************/
     
     

    6、点击项目名称,点击“Info”选项卡,在“URL Types”选项中,点击“+”,在“URL Schemes”中输入“alisdkdemo”。“alisdkdemo”来自于文件“APViewController.m”的NSString *appScheme = @"alisdkdemo";。

    注意:这里的URL Schemes中输入的alisdkdemo,为测试demo,实际商户的app中要填写独立的scheme,建议跟商户的app有一定的标示度,要做到和其他的商户app不重复,否则可能会导致支付宝返回的结果无法正确跳回商户app。

    配置基本信息

    打开“APViewController.m”文件,对以下2个参数进行编辑。

    NSString *appid = @"";
    NSString *privateKey = @"";

    iOS基本信息配置表:

    参数含义
    appid 应用ID,调用API时用来识别开发者。请参考创建应用并获取APPID
    private_key 应用私钥,pkcs8格式。请参考配置密钥

    注意:这些参数配置仅作为客户端示例使用。商户实际支付过程中参数需要放置在服务端,且整个签名过程必须在服务端进行

    代码示例运行逻辑

    步骤1:调用order.m里的函数description将商品信息拼接成字符串作为待签名字符串,如:

    app_id=2015052600090779&biz_content={"timeout_express":"30m","seller_id":"","product_code":"QUICK_MSECURITY_PAY","total_amount":"0.02","subject":"1","body":"我是测试数据","out_trade_no":"ZQLM3O56MJD4SK3"}&charset=utf-8&method=alipay.trade.app.pay&sign_type=RSA2&timestamp=2016-07-28 20:36:11&version=1.0

    步骤2:使用类CreateRSADataSigner,调用signString签名函数做签名,如:

    "GsSZgPloF1vn52XAItRAldwQAbzIgkDyByCxMfTZG%2FMapRoyrNIJo4U1LUGjHp6gdBZ7U8jA1kljLPqkeGv8MZigd3kH25V0UK3Jc3C94Ngxm5S%2Fz5QsNr6wnqNY9sx%2Bw6DqNdEQnnks7PKvvU0zgsynip50lAhJmflmfHvp%2Bgk%3D"

    步骤3:把签名结果赋值给参数sign,并把sign加入之前的待签名数组中,此时得到的便是要请求给支付宝的全部数据。

    app_id=2015052600090779&biz_content={"timeout_express":"30m","seller_id":"","product_code":"QUICK_MSECURITY_PAY","total_amount":"0.02","subject":"1","body":"我是测试数据","out_trade_no":"ZQLM3O56MJD4SK3"}&charset=utf-8&method=alipay.trade.app.pay&sign_type=RSA2&timestamp=2016-07-28 20:36:11&version=1.0&sign=*

    步骤4:调用(AlipaySDK *)defaultService类下面的支付接口函数,唤起支付宝支付页面。

    (void)payOrder:(NSString *)orderStr
    fromScheme:(NSString *)schemeStr
    callback:(CompletionBlock)completionBlock

    appScheme为app在info.plist注册的scheme。

    步骤5:当这笔交易被买家支付成功后支付宝收银台上显示该笔交易成功,并提示用户“返回”。此时在APAppDelegate.m的 - (BOOL)application:(UIApplication )application openURL:(NSURL )url sourceApplication:(NSString )sourceApplication annotation:(id)annotation 中调用获取返回数据的代码【iOS9.0以上(包括iOS9.0)需要在 - (BOOL)application:(UIApplication )app openURL:(NSURL )url options:(NSDictionary<NSString, id> *)options 中执行 】:

    [[AlipaySDK defaultService]
    processOrderWithPaymentResult:url
    standbyCallback:^(NSDictionary *resultDic) {
    NSLog(@"result = %@",resultDic);//返回的支付结果
    }];

    注意:
    1.同步返回数据校验逻辑请参考……
    2.SDK付款有两种模式:如果外部存在支付宝钱包,则直接跳转到支付宝钱包付款;不存在的场景下,在SDK内部进行H5支付。测试同学需要关注这两类测试场景。

    iOS调用说明

    接口名称:AlipaySDK

    接口描述:提供支付功能。

    Alipay接口主要为商户提供订单支付功能。接口所提供的方法,如下表所示:

    方法名称方法描述
    +(Alipay *)defaultService; 获取服务实例。
    -(void)payOrder:(NSString *)orderStr fromScheme:(NSString *)schemeStr callback:(CompletionBlock)completionBlock; 支付并通过回调返回结果。
    -(void)processOrderWithPaymentResult:(NSURL*)resultUrl standbyCallback:(CompletionBlock)completionBlock; 处理支付宝客户端返回的url(在app被杀模式下,通过这个方法获取支付结果)。

    快捷订单支付iOS

    方法名称:pay方法

    方法原型:(void)payOrder:(NSString )orderStr fromScheme:(NSString )schemeStr callback:(CompletionBlock)completionBlock;

    方法功能:提供给商户快捷订单支付功能。

    参数名称参数描述
    NSString* scheme 商户程序注册的URL protocol,供支付完成后回调商户程序使用。
    (CompletionBlock)completionBlock 快捷支付开发包回调函数,返回免登、支付结果。本地未安装支付宝客户端,或未成功调用支付宝客户端进行支付的情况下(走H5收银台),会通过该completionBlock返回支付结果。相应的结果参考"客户端同步返回参数说明"。
    NSString* orderString app支付请求参数字符串,主要包含商户的订单信息,key=value形式,以&连接。

    orderStr示例如下,参数说明见"请求参数说明":

    app_id=2015052600090779&biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22seller_id%22%3A%22%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.02%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%22314VYGIAGG7ZOYY%22%7D&charset=utf-8&method=alipay.trade.app.pay&sign_type=RSA2&timestamp=2016-08-15%2012%3A12%3A15&version=1.0&sign=MsbylYkCzlfYLy9PeRwUUIg9nZPeN9SfXPNavUCroGKR5Kqvx0nEnd3eRmKxJuthNUx4ERCXe552EV9PfwexqW%2B1wbKOdYtDIb4%2B7PL3Pc94RZL0zKaWcaY3tSL89%2FuAVUsQuFqEJdhIukuKygrXucvejOUgTCfoUdwTi7z%2BZzQ%3D
    

    处理客户端返回url

    方法名称:处理客户端方法

    方法原型:-(void)processOrderWithPaymentResult:(NSURL*)resultUrl standbyCallback:(CompletionBlock)completionBlock;

    方法功能:设备已安装支付宝客户端情况下,处理支付宝客户端返回的url。

    注意:该方法必须实现,否则将会导致在安装手机支付宝的情况下,支付结果无法正常同步返回。

    参数名称参数描述
    NSURL *resultUrl 支付宝客户端回传的url
    CompletionBlock completionBlock 本地安装了支付宝客户端,且成功调用支付宝客户端进行支付的情况下,会通过该completionBlock返回支付结果

    备注:请在APPDelegate的 - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation 中调用该方法,iOS9.0以上(包括iOS9.0)请在 - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options 中调用该方法,具体可参见Demo

    回调接口

    在支付过程结束后,会通过callbackBlock同步返回支付结果(callbackBlock是调用支付同步的回调)。支付结果中参数的提取,必须通过CompletionBlock获取,禁止开发者私自解析支付结果返回的URL,参数说明见"客户端同步返回参数说明"。|

     
  • 相关阅读:
    SSIS Error:Package Validation Error. SSIS Error Code DTS_E_OLEDBERROR. .Error code: 0x80040E37. An OLE DB record is available. Hresult: 0x80040E37
    MDS
    oracle11g rac静默安装+racADG部署搭建
    oracle 19c 单机ADG部署
    对索引组织表以及簇表的一些理解
    对表的连接的总结
    全局临时表
    对分区表的一些总结
    对临时表空间的一些常用查询
    linux 常用命令总结
  • 原文地址:https://www.cnblogs.com/OIMM/p/7655723.html
Copyright © 2011-2022 走看看