在iOS应用里集成支付宝支付,需要公司和支付宝签约,然后生成相应的密钥。密钥的生成支付宝的开发文档里已经说的非常清楚。
官方的文档和SDK:
https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.zpWFOY&treeId=59&articleId=104352&docType=1
接口名称:AlipaySDK
接口描述:提供支付功能。
Alipay接口主要为商户提供订单支付功能。接口所提供的方法,如下表所示:
方法名称 | 方法描述 |
---|---|
+(Alipay *)defaultService; |
获取服务实例。 |
-(BOOL)isLogined; |
检测本地是否曾登录使用过。 |
-(void)payOrder:(NSString *)orderStr fromScheme:(NSString *)schemeStr callback:(CompletionBlock)completionBlock; |
支付并通过回调返回结果。 |
//【callback处理支付结果】
方法名称:pay方法
方法原型:(void)payOrder:(NSString *)orderStr fromScheme:(NSString *)schemeStr callback:(CompletionBlock)completionBlock;
方法功能:提供给商户快捷订单支付功能。
参数名称 | 参数描述 |
---|---|
NSString* scheme | 商户程序注册的URL protocol,供支付完成后回调商户程序使用。 |
(CompletionBlock)completionBlock | 快捷支付开发包回调函数,返回免登、支付结果。本地未安装支付宝客户端,或未成功调用支付宝客户端进行支付的情况下(走H5收银台),会通过该completionBlock返回支付结果。相应的结果参考“同步通知参数说明”。 |
NSString* orderStr | 主要包含商户的订单信息,key=“value”形式,以&连接。 |
支付参数示例如下,参数说明见“请求参数说明”:
1
|
partner=
"2088101568358171"
&seller_id=
"[email protected]"
&out_trade_no=
"0819145412-6177"
&subject=
"测试"
&body=
"测试测试"
&total_fee=
"0.01"
¬ify_url=
"http://notify.msp.hk/notify.htm"
&service=
"mobile.securitypay.pay"
&payment_type=
"1"
&_input_charset=
"utf-8"
&it_b_pay=
"30m"
&sign=
"lBBK%2F0w5LOajrMrji7DUgEqNjIhQbidR13GovA5r3TgIbNqv231yC1NksLdw%2Ba3JnfHXoXuet6XNNHtn7VE%2BeCoRO1O%2BR1KugLrQEZMtG5jmJIe2pbjm%2F3kb%2FuGkpG%2BwYQYI51%2BhA3YBbvZHVQBYveBqK%2Bh8mUyb7GM1HxWs9k4%3D"
&sign_type=
"RSA"
|
必须的参数:
service | 接口名称 | String | 接口名称,固定值。 | 不可空 | mobile.securitypay.pay | 接口名称 | String | 接口名称,固定值 |
|
_input_charset | 参数编码字符集 | String | 商户网站使用的编码格式,固定为utf-8。 | 不可空 | utf-8 |
sign_type | 签名方式 | String | 签名类型,目前仅支持RSA。 | 不可空 | RSA |
sign | 签名 | String | 请参见签名。 | 不可空 |
notify_url | 服务器异步通知页面路径 | String(200) | 支付宝服务器主动通知商户网站里指定的页面http路径。 | 不可空 | http://notify.msp.hk/notify.htm |
out_trade_no | 商户网站唯一订单号 | String(64) | 支付宝合作商户网站唯一订单号。 | 不可空 | 0819145412-6177 |
subject | 商品名称 | String(128) | 商品的标题/交易标题/订单标题/订单关键字等。该参数最长为128个汉字。 | 不可空 | 测试 |
payment_type | 支付类型 | String(4) | 支付类型。默认值为:1(商品购买)。 | 不可空 | 1 |
seller_id | 卖家支付宝账号 | String(16) | 卖家支付宝账号(邮箱或手机号码格式)或其对应的支付宝唯一用户号(以2088开头的纯16位数字)。 | 不可空 | [email protected] |
total_fee | 总金额 | Number | 该笔订单的资金总额,单位为RMB-Yuan。取值范围为[0.01,100000000.00],精确到小数点后两位。 | 不可空 | 0.01 |
body | 商品详情 | String(512) | 对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。 | 不可空 | 测试测试 |
方法名称:处理客户端方法
方法原型:-(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
中调用该方法,具体可参见Demo。*)options
在支付过程结束后,会通过callbackBlock同步返回支付结果。
返回结果需要通过resultStatus以及result字段的值来综合判断并确定支付结果。在resultStatus=9000,并且success=“true”以及sign=“xxx”校验通过的情况下,证明支付成功。其它情况归为失败。较低安全级别的场合,也可以只通过检查resultStatus以及success=“true”来判定支付结果。以下为订单支付成功的完成信息示例:
1
2
3
4
5
|
{
memo =
""
;
result =
"partner=\"2088101568358171\"&seller_id=\"[email protected]\"&out_trade_no=\"0819145412-6177\"&subject=\"测试\"&body=\"测试测试\"&total_fee=\"0.01\"¬ify_url=\"http://notify.msp.hk/notify.htm\"&service=\"mobile.securitypay.pay\"&payment_type=\"1\"&_input_charset=\"utf-8\"&it_b_pay=\"30m\"&success=\"true\"&sign_type=\"RSA\"&sign=\"hkFZr+zE9499nuqDNLZEF7W75RFFPsly876QuRSeN8WMaUgcdR00IKy5ZyBJ4eldhoJ/2zghqrD4E2G2mNjs3aE+HCLiBXrPDNdLKCZgSOIqmv46TfPTEqopYfhs+o5fZzXxt34fwdrzN4mX6S13cr3UwmEV4L3Ffir/02RBVtU=\""
;
resultStatus =
"9000"
;
}
|
注意:
支付结果的提取,必须通过CompletionBlock获取,禁止开发者私自解析支付结果返回的URL。获取值的Key对应resultStatus、memo与result(result中的值,开发者可以自行解析);
为了保障已有商户的正常使用,返回参数ResultStatus首字母为大写。在新的SDK中已经用统一的工具类实现了ResultStatus到resultStatus的转换,商户从CompletionBlock中获取resultStatus即可。
其中参数说明:
请求参数说明:
- 商户在请求参数中,自己附属的一些额外参数,不要和支付宝系统中约定的key(下表中)重名,否则将可能导致未知的异常。
比如请求参数格式out_trade_no="1234566"&total_fee="123.5"&rn_check="TRE"
其中out_trade_no、total_fee、rn_check都是支付业务处理关键key,这个里面商户自己将out_trade_no、total_fee认为是支付宝必须传输的参数,rn_check=“TRE”是商户自己的业务数据,但是由于rn_check也是支付宝关键key,支付宝将会认为这个rn_check是支付宝业务的参数,将导致误解析,导致支付出现不可预料的异常。- 支付宝建议,商户不要在请求参数中添加除了支付宝指定的关键key外,还有其他的key用&连接。
比如out_trade_no="1234566"&total_fee="123.5"&homepage="http://www.***.com"
,其中homepage是商户自己的业务key,支付宝建议不要在请求参数中附带和支付无关的业务系统自身的key相关数据。- 商户的请求参数中,所有的key(支付宝关键key或者商户自己的key),其对应的value中都不应该出现支付宝关键key,比如out_trade_no、total_fee、seller_id等,否则该类交易将可能被支付宝拦截,禁止支付。
比如如下的请求out_trade_no="1234566"&total_fee="123.5"&homepage="http://www.***.com"&body="这个辣条不错 out_trade_no=123 total_fee=123.5"&memo="备忘seller_id=2088123213"
这个请求里面的body对应的value值中有支付宝关键key“out_trade_no”以及“total_fee”,请求中对于memo字段中含有seller_id,这样的业务请求参数支付宝将会拦截。
参数 参数名称 类型(字节长度) 参数说明 是否可为空 样例 service 接口名称 String 接口名称,固定值。 不可空 mobile.securitypay.pay partner 合作者身份ID String(16) 签约的支付宝账号对应的支付宝唯一用户号。以2088开头的16位纯数字组成。 不可空 2088101568358171 _input_charset 参数编码字符集 String 商户网站使用的编码格式,固定为utf-8。 不可空 utf-8 sign_type 签名方式 String 签名类型,目前仅支持RSA。 不可空 RSA sign 签名 String 请参见签名。 不可空 lBBK%2F0w5LOajrMrji7DUgEqNjIhQbidR13GovA5r3TgIbNqv231yC1NksLdw%2Ba3JnfHXoXuet6XNNHtn7VE%2BeCoRO1O%2BR1KugLrQEZMtG5jmJI notify_url 服务器异步通知页面路径 String(200) 支付宝服务器主动通知商户网站里指定的页面http路径。 不可空 http://notify.msp.hk/notify.htm
app_id 客户端号 String 标识客户端。 可空 external appenv 客户端来源 String 标识客户端来源。参数值内容约定如下:appenv=”system=客户端平台名^version=业务系统版本” 可空 appenv=”system=android^version=3.0.1.2” out_trade_no 商户网站唯一订单号 String(64) 支付宝合作商户网站唯一订单号。 不可空 0819145412-6177 subject 商品名称 String(128) 商品的标题/交易标题/订单标题/订单关键字等。该参数最长为128个汉字。 不可空 测试 payment_type 支付类型 String(4) 支付类型。默认值为:1(商品购买)。 不可空 1 seller_id 卖家支付宝账号 String(16) 卖家支付宝账号(邮箱或手机号码格式)或其对应的支付宝唯一用户号(以2088开头的纯16位数字)。 不可空 [email protected]
total_fee 总金额 Number 该笔订单的资金总额,单位为RMB-Yuan。取值范围为[0.01,100000000.00],精确到小数点后两位。 不可空 0.01 body 商品详情 String(512) 对一笔交易的具体描述信息。如果是多种商品,请将商品描述字符串累加传给body。 不可空 测试测试 goods_type 商品类型 String(1) 具体区分本地交易的商品类型。
1:实物交易;
0:虚拟交易。
默认为1(实物交易)。可空 1 hb_fq_param 花呗分期参数 String Json格式。
hb_fq_num:花呗分期数,比如分3期支付;
hb_fq_seller_percent:卖家承担收费比例,比如100代表卖家承担100%。
两个参数必须一起传入。
具体花呗分期期数和卖家承担收费比例可传入的数值请咨询支付宝。可空 {“hb_fq_num”:“3”,“hb_fq_seller_percent”:“100”} rn_check 是否发起实名校验 String(1) T:发起实名校验;
F:不发起实名校验。可空 T it_b_pay 未付款交易的超时时间 String 设置未付款交易的超时时间,一旦超时,该笔交易就会自动被关闭。当用户输入支付密码、点击确认付款后(即创建支付宝交易后)开始计时。取值范围:1m~15d,或者使用绝对时间(示例格式:2014-06-13 16:00:00)。m-分钟,h-小时,d-天,1c-当天(1c-当天的情况下,无论交易何时创建,都在0点关闭)。该参数数值不接受小数点,如1.5h,可转换为90m。 可空 30m extern_token 授权令牌 String(32) 开放平台返回的包含账户信息的token(授权令牌,商户在一定时间内对支付宝某些服务的访问权限)。通过授权登录后获取的alipay_open_id,作为该参数的value,登录授权账户即会为支付账户。 可空 1b258b84ed2faf3e88b4d979ed9fd4db 说明:部分参数类型为String,未指明长度范围,表明系统不校验该参数的长度。
客户端返回码
更新时间:2015/10/15 访问次数:72374
返回码 含义 9000 订单支付成功 8000 正在处理中 4000 订单支付失败 6001 用户中途取消 6002 网络连接出错 导入代码
更新时间:2016/04/19 访问次数:78963步骤1:启动IDE(如Xcode),把iOS包中的压缩文件中以下文件拷贝到项目文件夹下,并导入到项目工程中。
12AlipaySDK.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的文件中,增加头文件引用。
1#
import
步骤3:如果你的app基于9.0编译,那么为了适配iOS9.0中的App Transport Security(ATS)对http的限制,这里需要对支付宝的请求地址alipay.com、alipayobjects.com做例外,在app对应的info.list中添加如下配置(文中以XML格式描述)。
12345678910111213141516171819202122232425262728
NSAppTransportSecurity
NSExceptionDomains
alipay.com
NSIncludesSubdomains
<
true
/>
NSTemporaryExceptionAllowsInsecureHTTPLoads
<
true
/>
NSTemporaryExceptionMinimumTLSVersion
TLSv1. 0
NSTemporaryExceptionRequiresForwardSecrecy
<
false
/>
alipayobjects.com
NSIncludesSubdomains
<
true
/>
NSTemporaryExceptionAllowsInsecureHTTPLoads
<
true
/>
NSTemporaryExceptionMinimumTLSVersion
TLSv1. 0
NSTemporaryExceptionRequiresForwardSecrecy
<
false
/>
说明:
如果商户配置了如下的配置:
1234
NSAppTransportSecurity
NSAllowsArbitraryLoads <true
/>
则上述的NSAppTransportSecurity可以不配置。
步骤4:配置请求信息。
1234567891011121314151617181920212223242526272829303132333435363738Order *order = [[Order alloc] init];
order.partner = partner;
order.seller = seller;
order.tradeNO = [self generateTradeNO];
//订单ID(由商家?自?行制定)
order.productName = product.subject;
//商品标题
order.productDescription = product.body;
//商品描述
order.amount = [NSString stringWithFormat:@
"%.2f"
,product.price];
//商
品价格
order.notifyURL = @
"http://www.test.com"
; //回调URL
order.service = @
"mobile.securitypay.pay"
;
order.paymentType = @
"1"
;
order.inputCharset = @
"utf-8"
;
order.itBPay = @
"30m"
;
//应用注册scheme,在AlixPayDemo-Info.plist定义URL types
NSString *appScheme = @
"alisdkdemo"
;
//将商品信息拼接成字符串
NSString *orderSpec = [order description];
NSLog(@
"orderSpec = %@"
,orderSpec);
//获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode
id
signer = CreateRSADataSigner(privateKey); NSString *signedString = [signer signString:orderSpec];
//将签名成功字符串格式化为订单字符串,请严格按照该格式
NSString *orderString = nil;
if
(signedString != nil) {
orderString = [NSString stringWithFormat:@
"%@&sign=\"%@\"&sign_type=\"%@\""
,
orderSpec, signedString, @
"RSA"
];
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
//【callback处理支付结果】
NSLog(@
"reslut = %@"
,resultDic);
}];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
- liSDKDemo\Order.m
步骤5:配置支付宝客户端返回url处理方法。
(外部存在支付包钱包,支付宝钱包将处理结果通过url返回。)
如示例AliSDKDemo\APAppDelegate.m文件中,增加引用代码:
1#
import
在@implementation AppDelegate中增加如下代码:
12345678910111213141516171819- (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) {
//【由于在跳转支付宝客户端支付的过程中,商户app在后台很可能被系统kill了,所以pay接口的callback就会失效,请商户对standbyCallback返回的回调结果进行处理,就是在这个方法里面处理跟callback一样的逻辑】
NSLog(@
"result = %@"
,resultDic);
}];
}
if
([url.host isEqualToString:@
"platformapi"
]){
//支付宝钱包快登授权返回authCode
[[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
//【由于在跳转支付宝客户端支付的过程中,商户app在后台很可能被系统kill了,所以pay接口的callback就会失效,请商户对standbyCallback返回的回调结果进行处理,就是在这个方法里面处理跟callback一样的逻辑】
NSLog(@
"result = %@"
,resultDic);
}];
}
return
YES;
}
步骤4:配置请求信息。
1234567891011121314151617181920212223242526272829303132333435363738Order *order = [[Order alloc] init];
order.partner = partner;
order.seller = seller;
order.tradeNO = [self generateTradeNO];
//订单ID(由商家?自?行制定)
order.productName = product.subject;
//商品标题
order.productDescription = product.body;
//商品描述
order.amount = [NSString stringWithFormat:@
"%.2f"
,product.price];
//商
品价格
order.notifyURL = @
"http://www.test.com"
; //回调URL
order.service = @
"mobile.securitypay.pay"
;
order.paymentType = @
"1"
;
order.inputCharset = @
"utf-8"
;
order.itBPay = @
"30m"
;
//应用注册scheme,在AlixPayDemo-Info.plist定义URL types
NSString *appScheme = @
"alisdkdemo"
;
//将商品信息拼接成字符串
NSString *orderSpec = [order description];
NSLog(@
"orderSpec = %@"
,orderSpec);
//获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode
id
signer = CreateRSADataSigner(privateKey); NSString *signedString = [signer signString:orderSpec];
//将签名成功字符串格式化为订单字符串,请严格按照该格式
NSString *orderString = nil;
if
(signedString != nil) {
orderString = [NSString stringWithFormat:@
"%@&sign=\"%@\"&sign_type=\"%@\""
,
orderSpec, signedString, @
"RSA"
];
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
//【callback处理支付结果】
NSLog(@
"reslut = %@"
,resultDic);
}];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
详细可参见Demo中示例文件
- AliSDKDemo\APViewController.h
- AliSDKDemo\APViewController.m
- AliSDKDemo\Order.h
- AliSDKDemo\Order.m
步骤5:配置支付宝客户端返回url处理方法。
(外部存在支付包钱包,支付宝钱包将处理结果通过url返回。)
如示例AliSDKDemo\APAppDelegate.m文件中,增加引用代码:
1#
import
在@implementation AppDelegate中增加如下代码:
12345678910111213141516171819- (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) {
//【由于在跳转支付宝客户端支付的过程中,商户app在后台很可能被系统kill了,所以pay接口的callback就会失效,请商户对standbyCallback返回的回调结果进行处理,就是在这个方法里面处理跟callback一样的逻辑】
NSLog(@
"result = %@"
,resultDic);
}];
}
if
([url.host isEqualToString:@
"platformapi"
]){
//支付宝钱包快登授权返回authCode
[[AlipaySDK defaultService] processAuthResult:url standbyCallback:^(NSDictionary *resultDic) {
//【由于在跳转支付宝客户端支付的过程中,商户app在后台很可能被系统kill了,所以pay接口的callback就会失效,请商户对standbyCallback返回的回调结果进行处理,就是在这个方法里面处理跟callback一样的逻辑】
NSLog(@
"result = %@"
,resultDic);
}];
}
return
YES;
}