一、介绍
支付宝的集成还是比较简单的,按照文档来一步步操作,基本上很顺利。不过,仍然有两个地方会是坑。这里我集成成功了,在此整理一下。说先说一下我遇到的坑如下:
第一个坑:下载的SDK文件AliPay.bundle和AliPay.framework一直报错,找不到库,没法使用。什么原因,我暂时还不知道。
解决办法:将官方提供的demo中SDK文件拖入项目中,替换掉自己下载的SDK即可
第二个坑:拖入的openssl目录下的所有#include <openssl/xxx.h>找不到路径。原因是在demo中openssl目录直接被放到了项目根目录下,而我们拖入是被放到了工程目录下,路径不一致,需要更改路径。
解决办法:在Build setting下设置Header Search Path路径。
例如我的路经设置图为,是根据下面图显示的openssl设置的:
二、看看我的项目图
三、准备
(1)在支付宝开发者平台注册登录账号创建应用获取appid,蚂蚁金服开放平台(open.alipay.com)
(2)配置密钥,开发者调用接口前需要先生成RSA密钥,RSA密钥包含应用私钥(APP_PRIVATE_KEY)、应用公钥(APP_PUBLIC_KEY)。生成密钥后在开放平台管理中心进行密钥配置,配置完成后可以获取支付宝公钥(ALIPAY_PUBLIC_KEY)。详细步骤请参考《配置应用环境》。
(3)集成并配置sdk,要将库添加完整(下面有一个libPods-xxx这个是使用cocopods开发项目自动生成的,没有使用cocoPods开发的不用管)
注意:在xcode8.0后,需要再多添加一个依赖库SystemConfiguration.framework,不然要报错了。
(4)设置URL Schemes,这个必须保证唯一性,因为支付完成后会根据这个调回到我们自己的app,我将这个在pch中做了定义,值必须保持一样
四、使用
在pch设置宏定义并导入头文件
// Prefix header // 夏远全 // The contents of this file are implicitly included at the beginning of every source file. // #import <Availability.h> #ifndef __IPHONE_5_0 #warning "This project uses features only available in iOS SDK 5.0 and later." #endif #ifdef __OBJC__ #import <UIKit/UIKit.h> #import <Foundation/Foundation.h> #import <AlipaySDK/AlipaySDK.h> //支付宝SDK #import "PayManager.h" //支付宝调起支付类 #import "DataSigner.h" //支付宝签名类 #import "Order.h" //订单模型 #import "APAuthV2Info.h" //授权模型 /** ----------------------------------- 支付宝支付需要配置的参数 ----------------------------------- */ //开放平台登录https://openhome.alipay.com/platform/appManage.htm //管理中心获取APPID #define AlipayAPPID @"xxxxxxxxx" //管理中心获取PIDID #define PIDID @"xxxxxxxxx" //支付宝私钥(用户自主生成,使用pkcs8格式的私钥,文档上提供了两种生成方式,自己去选择吧) #define AlipayPrivateKey @"xxxxxxxxx" //应用注册scheme,在AliSDKDemo-Info.plist定义URL types #define URLScheme @"AliPayKit" //支付宝支付接口 #define AlipayUrl @"alipay.trade.app.pay" #endif
在AppDelegate.m中回调
- (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; }
在工具类PayManager.m中实现支付
// PayManager.m // AliPayKit // // Created by 夏远全 on 16/12/20. // Copyright © 2016年 广州市东德网络科技有限公司. All rights reserved. // #import "PayManager.h" @implementation PayManager #pragma mark - 进行支付 +(void)openAliPayForPaying{ /*=========================================================*/ /*====客户端调用支付宝支付(实际操作请放到服务端)=================*/ /*=========================================================*/ //AppId和PrivateKey没有配置下的提示 if ([AlipayAPPID length] == 0 || [AlipayPrivateKey length] == 0) { [self alertShow]; return; } //将商品信息赋予AlixPayOrder的成员变量 Order* order = [Order new]; order.app_id = AlipayAPPID; // NOTE: app_id设置 order.method = AlipayUrl; // 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: 支付版本 order.sign_type = @"RSA"; // NOTE: sign_type设置 // 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(AlipayPrivateKey); NSString *signedString = [signer signString:orderInfo]; // NOTE: 如果加签成功,则继续执行支付 if (signedString != nil) { //应用注册scheme,在AliSDKDemo-Info.plist定义URL types NSString *appScheme = URLScheme; // NOTE: 将签名成功字符串格式化为订单字符串,请严格按照该格式 NSString *orderString = [NSString stringWithFormat:@"%@&sign=%@", orderInfoEncoded, signedString]; // NOTE: 调用支付结果开始支付 [[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) { NSLog(@"reslut = %@",resultDic); }]; } } #pragma mark - 随机字符串 //==============产生随机订单号============== + (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; } #pragma mark - 提示信息 +(void)alertShow{ //去除警告 #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" //AppId和PrivateKey没有配置下的提示 if ([AlipayAPPID length] == 0 || [AlipayPrivateKey length] == 0) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"缺少appId或者私钥。" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil]; [alert show]; } #pragma clang diagnostic pop } @end
五、模拟器和真机演示的截图如下:
首先我生成的私钥如下:
支付截图:
完成的demo地址,github:https://github.com/xiayuanquan/AliPaykit,希望有帮助