在记录支付宝支付的开头,只想感叹一句,支付宝的文档写的是真真好呀!非常仔细。。。。(__) 嘻嘻……
一、在支付中添加应用
https://open.alipay.com/platform/home.htm?from=zhuzhan20160818
登录支付宝账户,
1.1 创建一个新的应用
1.2 按照开发文档设置应用信息,可以修改,也可以在上线时再设置
1.3配置应用环境(生成器生成的公钥在这进行设置,iOS使用原始私钥,andriod使用pkcs8私钥)
在这部分对应的支付宝文档对公钥私钥有相应的解释。
1.3.1 私钥生成器的长这个样子
1.3.2私钥生成器的使用
1.3.3 生成公钥私钥后,将公钥粘贴进应用环境的,应用公钥中(这一步需要发送手机号验证码确认后,才能进行公钥设置)
1.4 给应用配置相应的功能
添加功能->选择相应功能—>添加完成
注释:
上线:这里的上线只是在支付宝平台的上线,并不是我们的app在应用商店上线
是否需签约:签约是指应用是否签约购买了这项服务。
1、如果是已经购买的服务,上线后,接口可以直接使用;如果是没有购买的服务,需要购买后才可以使用;
2、不需要签约的服务,应用上线就可以用了
沙箱环境:沙箱环境是一个不需要上线可以直接调用接口测试的环境
1、安卓可以不用上线,使用沙箱环境测试。
2、iOS目前是无法使用沙箱环境测试APP支付的,只能先让应用上线,上线时间1天,非常快,一般用不了1天。
1.5 应用上线,如果在1.2中没有设置应用信息,需要在这里进行修改
二、查看支付宝的集成文档
2.1了解支付宝支付架构
2.2支付宝支付的流程图
2.3具体的接口调用在支付宝的文档中写的非常详细!
2.4 注意事项
2.4.1构造交易数据并签名必须在商户服务端完成,
2.4.2商户的应用私钥绝对不能保存在商户APP客户端中,也不能从服务端下发。
2.4.3同步返回的数据,只是一个简单的结果通知,商户确定该笔交易付款是否成功需要依赖服务端收到支付宝异步通知的结果进行判断。
2.4.4商户系统接收到通知以后,必须通过验签(验证通知中的sign参数)来确保支付通知是由支付宝发送的。建议使用支付宝提供的SDK来完成,详细验签规则参考异步通知验签。
三、集成过程
支付宝集成流程详解
https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.mCFv8i&treeId=193&articleId=105295&docType=1
步骤1:调用order.m里的函数description将商品信息拼接成字符串作为待签名字符串
NSString *authInfoStr = [authInfo description];
步骤2:使用类CreateRSADataSigner,调用signString签名函数做签名
id
步骤3:把签名结果赋值给参数sign,并把sign加入之前的待签名数组中,此时得到的便是要请求给支付宝的全部数据。
authInfoStr = [NSString stringWithFormat:@"%@&sign=%@&sign_type=%@", authInfoStr, signedString, @"RSA"];
*步骤4:调用(AlipaySDK )defaultService类下面的支付接口函数,唤起支付宝支付页面。
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
NSLog(@"reslut = %@",resultDic);
}];
步骤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
[[AlipaySDK defaultService]
processOrderWithPaymentResult:url
standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);//返回的支付结果
}];
五、官方demo
点击订单模拟支付行为==============
-
(void)doAlipayPay
{
/步骤一、需要填写商户app申请的APPID和私钥===================================/NSString *appID = @"支付宝应用的APPID";
NSString *privateKey = @"支付宝应用公钥对应的私钥";//partner和seller获取失败,提示
if ([appID length] == 0 ||
[privateKey length] == 0)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"
message:@"缺少appId或者私钥。"
delegate:self
cancelButtonTitle:@"确定"
otherButtonTitles:nil];
[alert show];
return;
}
//生成订单信息及签名
/步骤二、订单信息设置===================================/
//将商品信息赋予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: 商品数据
/商品信息=======================
total_amount:商品价格(支付金额)
out_trade_no:订单ID(商户订单号)--这个地方用了随机的。正常情况下,服务器端会给!
seller_id:收款商户号
timeout_express:超时时间设置
subject:主题(显示的数据,自己写,不影响支付)
body:内容对一笔交易的具体描述信息(自己写就可以)
===================================/
order.biz_content = [BizContent new];
order.biz_content.body = @"abc";
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]; //商品价格
order.biz_content.seller_id =@"收款商户号";// 收款商户号
/步骤三、将订单信息拼接成字符串=========================================
订单信息串中的各个value是否encode
非encode订单信息串,用于生成签名
encode订单信息串 + 签名,用于最终的支付请求订单信息串===================================/
NSString *orderInfo = [order orderInfoEncoded:NO];
NSString *orderInfoEncoded = [order orderInfoEncoded:YES];
/步骤四、使用类CreateRSADataSigner(获取私钥),调用signString签名函数做签名(并将商户信息签名)需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode=========================================/
id signer = CreateRSADataSigner(privateKey);
NSString *signedString = [signer signString:orderInfo];
// NOTE: 如果加签成功,则继续执行支付
if (signedString != nil) {
NSString *appScheme = @"alisdkdemo";//url types设置
/步骤五、把签名结果赋值给参数sign,并把sign加入之前的待签名数组中,此时得到的便是要请求给支付宝的全部数据(订单字符串)。==============================================/
NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@",
orderInfoEncoded, signedString];
NSLog(@"orderString%@",orderString);
/步骤六、调用支付结果开始支付=========================/
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
NSLog(@"reslut = %@",resultDic);
}];
}
}
// 产生随机订单号
-
(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;
}
六、开发过程中需要注意的事项
1、URL Types需要设置URL Scheme
URL Scheme是跳转其他APP的必须设置。
可以在info.plist文件中设置,也可以在info下找到URL Types进行设置
2、需要设置头文件路径:点击“Build Settings”选项卡,在搜索框中,以关键字“search”搜索,对“Header Search Paths”增加头文件路径:$(SRCROOT)/项目名称。如果头文件信息已增加,可不必再增加。
3、官方的demo中会报一个错误,私钥为空
检查私钥的正确性后,如果还不能解决,尝试使用以下方法修改:
对私钥样式的拼接中进行修改
-----BEGIN PRIVATE KEY-----和-----END PRIVATE KEY-----
修改成
-----BEGIN RSA PRIVATE KEY-----和-----END RSA PRIVATE KEY-----
4、支付宝打开失败,ALI40247错误
这个错误的原因一般是支付宝的应用配置有问题,解决方法:
4.1、检查使用的APPID 私钥是否正确
4.2、检查支付宝中应用是否添加APP支付功能
4.3、检查APP支付功能是否已经签约
如果以上都没问题,可以在支付宝删除应用,再重新创建一个新应用进行测试