前言:集成支付宝可以分为客户端签名和服务器端签名两种,前者需要将PrivateKey放在本地,支付宝不推荐使用,推荐使用服务器端签名这种,这里我在这里分两种跟大家进行。
// NOTE: 重要说明:NSString* text = @"重要说明:\n本Demo为了方便向商户展示支付宝的支付流程,所以订单信息的加签过程放在客户端完成;\n在商户的真实App内,为了防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;\n商户privatekey等数据严禁放在客户端,订单信息的加签过程也务必放在服务端完成;\n若商户接入时不遵照此说明,因此造成了损失,需自行承担。";
1、集成前准备:
创建应用啥的就就该你们后台去做吧,这里就不耽误时间了,点击蚂蚁金服开放平台,点击sdk&demo下载相应的demo和sdk,打开iOS demo,自己新建一个AlipaySdk文件夹把demo里面的这几个相应的文件夹导入到AlipaySdk文件夹下,形成如下的结构,仔细点,别搞错了。搞完后,放在你工程里面你要管理的位置。
2、点击Build Phases -> Link Binary With Libraries,看AlipaySDK.bundle,AlipaySDK.framework,libcrypto.a,libssl.a是否已经添加进去了,没有的话,点击+添加
3、设置索引目录,要不然会报文件找不到的错误
上图是我们app设置的索引目录,这个根据自己的app文件结构作相应的调整
4、设置url schemes,设置如下:
我这设置的是alisdkdemo,跟他们demo里面的一样,懒得改了,也可以根据自己的app做相应的修改。
5、设置支付宝成功之后的回调的方法,在appDelegate中:代码如下
- (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 *)options
{
if ([url.host isEqualToString:@"safepay"]) {
//跳转支付宝钱包进行支付,处理支付结果
[[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
NSLog(@"result = %@",resultDic);
}];
}
return YES;
}
6、墨迹半天了,开始上干货,这里首先是客户端签名的代码:如下:
- (void)aliPay{
NSString *appID = AliAppID;
NSString *rsa2PrivateKey = @"";
NSString *rsaPrivateKey = self.privateKey.length > 0 ?self.privateKey : PRIVATEKEY;
//partner和seller获取失败,提示
if ([appID length] == 0 ||
([rsa2PrivateKey length] == 0 && [rsaPrivateKey length] == 0))
{
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示"
message:@"缺少appId或者私钥,请检查参数设置"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *action = [UIAlertAction actionWithTitle:@"知道了"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action){
}];
[alert addAction:action];
[VisibleViewController() presentViewController:alert animated:YES completion:^{ }];
return;
}
/*
*生成订单信息及签名
*/
//将商品信息赋予AlixPayOrder的成员变量
APOrderInfo* order = [APOrderInfo 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 = (rsa2PrivateKey.length > 1) ? @"RSA2":@"RSA";
order.notify_url = self.notifyURL;
// NOTE: 商品数据
order.biz_content = [APBizContent new];
order.biz_content.body = self.productDescription;
order.biz_content.subject = self.productName;
order.biz_content.out_trade_no = self.tradeNO; //订单ID(由商家自行制定)
order.biz_content.timeout_express = @"30m"; //超时时间设置
order.biz_content.total_amount = self.amount; //商品价格
order.biz_content.product_code = @"QUICK_MSECURITY_PAY";
//将商品信息拼接成字符串
NSString *orderInfo = [order orderInfoEncoded:NO];
NSString *orderInfoEncoded = [order orderInfoEncoded:YES];
DLog(@"lallalall orderSpec = %@",orderInfo);
// NOTE: 获取私钥并将商户信息签名,外部商户的加签过程请务必放在服务端,防止公私钥数据泄露;
// 需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode
NSString *signedString = nil;
APRSASigner* signer = [[APRSASigner alloc] initWithPrivateKey:((rsa2PrivateKey.length > 1)?rsa2PrivateKey:rsaPrivateKey)];
if ((rsa2PrivateKey.length > 1)) {
signedString = [signer signString:orderInfo withRSA2:YES];
} else {
signedString = [signer signString:orderInfo withRSA2:NO];
}
DLog(@"获取到的数据是:%@",signedString);
// 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) {
DLog(@"支付宝回调的结果是:reslut = %@",resultDic);
callBack(resultDic[@"resultStatus"]);
}];
}
}
//将上面的方法拖到项目中,报错的参数就是你要根据需要修改的参数,不知道的也可以看这个链接支付宝参数链接看那些是必须传的还有填写的内容和格式。
完成以上6项步骤不出啥问题,你已经能成功在ios 客户端集成支付宝v2.0了,但是。。。。。
看到我最上面的警告不,支付宝是不推荐客户端加签的,如果没你们服务器端不想加签的话就你们自己搞。
二、服务器端加签后ios 客户端的的做法如下:
AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
mgr.responseSerializer.acceptableContentTypes= [NSSet setWithObjects:@"text/html",@"application/json",nil];
NSString*appScheme = @"alisdkdemo";
[mgr POST:@"xxxx"parameters:nil progress:nilsuccess:^(NSURLSessionDataTask * _Nonnull task,id_Nullable responseObject) {
// 从后台获取加签后的字符串NSString*orderNo = responseObject[@"orderNo"];
// 调起支付宝客户端进行支付操作
[[AlipaySDK defaultService] payOrder:orderNo fromScheme:appScheme callback:^(NSDictionary*resultDic) {NSLog(@"%@",resultDic);
}];
} failure:^(NSURLSessionDataTask * _Nullable task,NSError* _Nonnull error) {
}];
对,你没错,就是这么简单。。。
根据需要跟服务器端商量跟他们传什么参数,服务器端返回加签后的订单支付串,你拿到该订单支付串和设置的URL scheme调用支付宝的支付接口发起支付请求就完了,惊不惊喜,意不意外!
[[AlipaySDK defaultService] payOrder:orderNo fromScheme:appScheme callback:^(NSDictionary*resultDic) {NSLog(@"%@",resultDic);
}];
总结:
支付宝推荐使用服务器端加签的方法,相信大多数iOS开发的小伙伴也都坚决响应这一号召吧!但是,咱们客户端集成的咱们也要会,不要碰见个傲娇的后台就不干,咋办!咱技多不压身。撒油那啦!