最新项目中要用到支付宝支付、微信支付、银联支付。首先下手的就是支付宝支付,遇到很多问题,查看网上都是以前老版本SDK的讲解,部分并不适用,所以总结一下,希望能帮同胞们解决一些问题。
刚下载SDK&Demo感觉不难 ,心想照着文档一步一步来吧,过程并没有那么简单!!!那我就从最重要的事情说起了。
一、支付功能的必要条件:签约
1.创建应用之后,添加功能。然后一定要上线--》签约。地址:https://openhome.alipay.com/platform/appManage.htm
如果不签约,我遇到的问题是ALI40247. 签约成功之后才能正常支付
2.应用说明文档,需要自己写。下载《应用说明文档示例》,按照格式写
我这里有一份写好的,但是我好像不知道怎么加进来!!!逗比了,有需要的我后边建一个qq群好了!
3.签约。签约成功的样子是这样的:显示已签约,才算成功
好了,到这里签约完成。 备注:这些工作应该是后台做的,就交给他们吧!
二、下载支付宝SDK&demo
下载地址不太好找!我直接粘在这里了! https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.x3h32g&treeId=54&articleId=104509&docType=1
目前我用的最新的(推荐使用)
三、集成SDK
其实这些步骤支付宝官方文档都有了,我按照我的思路写一遍,以备不时之需。
1.把SDK中的这些文件集成到我们的项目
还有一些框架加在 targets--> Build Phases 里面
2.集成好了之后就要复制代码了,直接把demo里面ViewController的代码全部复制过去.
#pragma mark ==============点击订单模拟支付行为============== // //选中商品调用支付宝极简支付 // - (void)doAlipayPay { //重要说明 //这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成; //真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成; //防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险; /*============================================================================*/ /*=======================需要填写商户app申请的===================================*/ /*============================================================================*/ // NSString *partner = @"208870120989419"; // 这是支付宝文档里的测试账号 NSString *appID = @"20161018022204";//20161018022204 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: 商品数据 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 = @"0.02"; //商品价格 //将商品信息拼接成字符串 NSString *orderInfo = [order orderInfoEncoded:NO]; NSString *orderInfoEncoded = [order orderInfoEncoded:YES]; // NSLog(@"%@",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 = @"baiwanpay2016"; // NOTE: 将签名成功字符串格式化为订单字符串,请严格按照该格式 NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@", orderInfoEncoded, signedString]; NSLog(@"%@",orderString); // NOTE: 调用支付结果开始支付 [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) { NSLog(@"reslut = %@",resultDic); }]; } }
这里的 privateKey appID需要自己的
需要注意的是:自己生成一对公钥、私钥。把公钥给后台配置到支付宝平台上面,私钥自己填进去。这步最容易出错,空格、多余字符都不要有!!!
在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); }]; // 授权跳转支付宝钱包进行支付,处理支付结果 [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) { NSLog(@"result = %@",resultDic); // 解析 auth code NSString *result = resultDic[@"result"]; NSString *authCode = nil; if (result.length>0) { NSArray *resultArr = [result componentsSeparatedByString:@"&"]; for (NSString *subResult in resultArr) { if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) { authCode = [subResult substringFromIndex:10]; break; } } } NSLog(@"授权结果 authCode = %@", authCode?:@""); }]; } 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); }]; // 授权跳转支付宝钱包进行支付,处理支付结果 [[AlipaySDK defaultService] processAuth_V2Result:url standbyCallback:^(NSDictionary *resultDic) { NSLog(@"result = %@",resultDic); // 解析 auth code NSString *result = resultDic[@"result"]; NSString *authCode = nil; if (result.length>0) { NSArray *resultArr = [result componentsSeparatedByString:@"&"]; for (NSString *subResult in resultArr) { if (subResult.length > 10 && [subResult hasPrefix:@"auth_code="]) { authCode = [subResult substringFromIndex:10]; break; } } } NSLog(@"授权结果 authCode = %@", authCode?:@""); }]; } return YES; }
到这里,集成部分就完成了。但是编译会出现几个错误。
四、解决一些问题及bug
1) Cannot find interface declaration for ‘NSObject’
解决:在报错的文件中导入头文件#import <Foundation/Foundation.h>
2)找不到 openssl/asn1.h 文件
解决:Build Settings –> Search Paths –> Header Search paths:$(PROJECT_DIR)/
这里一定要注意:$(PROJECT_DIR)/ 后边加的名字并不是我们工程的名字!!!而是我们的SDK所在的文件夹的名字。。比如说:我的工程名是Pay,但是我把支付宝SDK放到了AlipaySDK 这个文件夹下,所以我就写的是 $(PROJECT_DIR)/AlipaySDK 。这里我试了无数路径,一定要注意注意注意!!!
3)报错:rsa_private read error : private key is NULL
解决:在支付宝SDK Util文件夹RSADataSigner.m中-->formatPrivateKey方法里面
begin end后边加上RSA
按照步骤到这里支付宝集成 就基本完成了。可能有些bug漏写了,欢迎大家指正修改。