客户端 iOS 集成流程

导入代码

通过 CocoaPods 导入

pod 'AlipaySDK-iOS'

手动导入

启动 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(如下图所示)。

增加头文件引用

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

import <AlipaySDK/AlipaySDK.h>

组装请求信息

注意:
这一步应在商户服务端完成,商户服务端直接将组装和签名后的请求串 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 中示例文件

  • AliSDKDemo\APViewController.h

  • AliSDKDemo\APViewController.m

  • AliSDKDemo\Order.h

  • AliSDKDemo\Order.m

配置返回 url 处理方法

本步骤指引开发者配置支付宝客户端返回 url 处理方法(外部存在支付宝钱包,支付宝钱包将处理结果通过 url 返回)。

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

import <AlipaySDK/AlipaySDK.h>

@implementation 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.以下文件供示例签名所在客户端本地使用。实际场景下请商户把私钥保存在服务端,在服务端进行支付请求参数签名。

  • AliSDKDemo\Util及下面所有文件

  • AliSDKDemo\openssl及下面所有文件

  • 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)/项目名称。如果头文件信息已增加,可不必再增加。

5.点击项目名称,点击 Build Phases 选项卡,在“Link Binary with Librarles”选项中,新增“AlipaySDK.framework”和“SystemConfiguration.framework”两个系统库文件。如果商户项目中已有这两个库文件,可不必再增加。

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 中调用获取返回数据的代码(iOS 9.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 支付。测试人员需要关注这两类测试场景。

针对 Swift 接入 AlipaySDK 的问题

如果项目使用 Swift 为开发语言,需要添加桥接文件,如 Bridging-Header.h。

同时,在项目 Build Settings 中设置桥接文件的位置(如下图所示)。

添加成功后,在桥接文件中写入 #import <AlipaySDK/AlipaySDK.h>
如此,在需要调用 AlipaySDK 的地方,即可直接使用,具体调用方式参照 OC。

注意
运行时如果发生以下报错,

则在桥接文件中,写入#import <UIKit/UIKit.h>

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及以上请在 - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<NSString*, id> *)options 中调用该方法,具体可参见 Demo

回调接口

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

联调问题排查

联调过程中的问题可以参考:常见联调问题

onlineServer