记得我做的第一个iOS应用就有接入支付宝的功能,然而当时并没有成功接入。一个是因为当时自己大三刚刚开窍菜的抠脚,另一个是因为网上传闻iOS添加支付宝的SDK难用程度已经突破了天际!所以就自动放弃了~
但是!!我终于在一年后的今天给它弄上了!!现在返回去看其实也不难,虽然坑很多
引用《火星救援》马克说的话:
You just begin. You do the math. You solve one problem and you solve the next one, and then the next. And if you solve enough problems, you get to come home.
遇到困难去做就是了,可能有成堆的问题,但是一个问题一个问题的去解决,只要解决的问题足够多,这个困难就过去了。同样,一个你不熟悉的框架或者系统,一开始自己会感到手足无措,完全不知道该怎么办,这时候只需要每天学一个技术,每天看一点文档,慢慢的就会了,然后就熟悉了,最后就可以在别人崇拜的眼光面前摇摇头说:“我也只是略懂啦~”。
准备 首先要去支付宝填申请,可以得到一个parnter
和一个seller
。然后自己要在自己的电脑上生成一组RSA,把公钥交给支付宝,私钥自己留着。具体生成方法支付宝的SDK里面有写,或者可以看这个openssl生成RSA公私钥 ,两分钟的事。
下载SDK 首先要从网上下载SDK。下载地址
运行 demo 得到SDK后先运行下他给的iOS端的demo。demo中APViewController.m
里面找到下面这几行代码,填上你的parnter
、seller
和privateKey
,然后运行看下能不能支付成功,如果可以的话,说明你的三个参数没有问题,可以准备接入了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 NSString *partner = @"" ; NSString *seller = @"" ; NSString *privateKey = @"" ;
接入 首先把SDK包中的几个东西拖到你的项目中去:AlipaySDK.bundle
,AlipaySDK.framework
,libcrypto.a
和libssl.a
。
然后把demo中Util
文件夹拖入你的项目中:注意!要选择Create groups
!!! 注意!要选择Create groups
!!! 注意!要选择Create groups
!!!
**Util
**拖进去后应该是黄色的而不是蓝色的!!!
然后把demo中openssl
文件夹拖入你的项目中:
注意这次选Create folder reference
!!
然后把demo中这几个文件拖到你的项目中:Product.h
,Product.m
,APAuthV2Info.h
,APAuthV2Info.m
,Order.h
,Order.m
现在你的项目里面应该包含这些东西(特别注意下Util文件夹和openssl文件夹的颜色):
在你要用到支付的地方引入以下头文件
1 2 3 4 #import "Order.h" #import <AlipaySDK/AlipaySDK.h> #import "DataSigner.h" #import "Product.h"
然后参考demo的支付写了下面这个支付函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 - (void )Alipay{ Product *product = [[Product alloc] init]; product.subject = @"1" ; product.body = @"人在塔在" ; product.price = 0.01 f+pow(10 ,-2 ); NSString *partner = @"" ; NSString *seller = @"" ; NSString *privateKey = @“私钥”; if ([partner length] == 0 || [seller length] == 0 || [privateKey length] == 0 ) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"缺少partner或者seller或者私钥。" delegate:self cancelButtonTitle:@"确定" otherButtonTitles:nil ]; [alert show]; } product.price = 0.01 f+pow(10 ,-2 ); Order *order = [[Order alloc] init]; order.partner = partner; order.seller = seller; order.tradeNO = [self generateTradeNO]; order.productName = product.subject; order.productDescription = product.body; order.amount = [NSString stringWithFormat:@"%.2f" ,product.price]; order.notifyURL = @"http://www.xxx.com" ; order.service = @"mobile.securitypay.pay" ; order.paymentType = @"1" ; order.inputCharset = @"utf-8" ; order.itBPay = @"30m" ; order.showUrl = @"m.alipay.com" ; NSString *appScheme = @"alisdkdemo" ; NSString *orderSpec = [order description]; NSLog (@"orderSpec = %@" ,orderSpec); id <DataSigner> 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) { NSLog (@"reslut = %@" ,resultDic); }]; } } - (NSString *)generateTradeNO { static int kNumber = 15 ; NSString *sourceStr = @"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" ; NSMutableString *resultStr = [[NSMutableString alloc] init]; srand(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; }
按照官方的说法,这样子就差不多算是把支付宝接入了;现在点击运行。。。。会惊奇的发现:Boom! sha ka la ka!!
报了超多错!这就是支付宝坑的地方,接下来我们来填坑。
填坑 Util/base64.h:63:21: Cannot find interface declaration for ‘NSObject’, superclass of ‘Base64’ 在base64.h
中加入#import <Foundation/Foundation.h>
官方古老的demo加到了PCH
中,所以不会报错~结果他说都不说一声!!!坑啊有没有!!!
Util/openssl_wrapper.m:11:9: ‘rsa.h’ file not found 在Build setting
中搜索search
,找到Header Search Paths
,添加$(PROJECT_DIR)/openssl
和$(PROJECT_DIR)
如图:
“_CNCopyCurrentNetworkInfo”, referenced from: 这类错很多,大概有这些:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 Undefined symbols for architecture x86_64: "_CNCopyCurrentNetworkInfo" , referenced from: -[APayReachability wifiInterface] in AlipaySDK +[internal_DeviceInfo getSSIDInfo] in AlipaySDK +[internal_DeviceInfo getNetworkInfo] in AlipaySDK "_CNCopySupportedInterfaces" , referenced from: -[APayReachability wifiInterface] in AlipaySDK +[internal_DeviceInfo getSSIDInfo] in AlipaySDK +[internal_DeviceInfo getNetworkInfo] in AlipaySDK "_CTRadioAccessTechnologyCDMA1x" , referenced from: -[AliSecXReachability networkStatusForFlags:] in AlipaySDK "_CTRadioAccessTechnologyEdge" , referenced from: -[AliSecXReachability networkStatusForFlags:] in AlipaySDK "_CTRadioAccessTechnologyGPRS" , referenced from: -[AliSecXReachability networkStatusForFlags:] in AlipaySDK "_CTRadioAccessTechnologyLTE" , referenced from: -[AliSecXReachability networkStatusForFlags:] in AlipaySDK "_OBJC_CLASS_$_CMMotionManager " , referenced from: objc-class-ref in AlipaySDK "_OBJC_CLASS_$_CTTelephonyNetworkInfo " , referenced from: objc-class-ref in AlipaySDK "_SCNetworkReachabilityCreateWithAddress" , referenced from: +[APayReachability reachabilityWithAddress:] in AlipaySDK +[AliSecXReachability reachabilityWithAddress:] in AlipaySDK "_SCNetworkReachabilityCreateWithName" , referenced from: +[APayReachability reachabilityWithHostname:] in AlipaySDK +[AliSecXReachability reachabilityWithHostName:] in AlipaySDK "_SCNetworkReachabilityGetFlags" , referenced from: -[APayReachability isReachable] in AlipaySDK -[APayReachability isReachableViaWWAN] in AlipaySDK -[APayReachability isReachableViaWiFi] in AlipaySDK -[APayReachability connectionRequired] in AlipaySDK -[APayReachability isConnectionOnDemand] in AlipaySDK -[APayReachability isInterventionRequired] in AlipaySDK -[APayReachability reachabilityFlags] in AlipaySDK ... "_SCNetworkReachabilityScheduleWithRunLoop" , referenced from: -[AliSecXReachability startNotifier] in AlipaySDK "_SCNetworkReachabilitySetCallback" , referenced from: -[APayReachability startNotifier] in AlipaySDK -[APayReachability stopNotifier] in AlipaySDK -[AliSecXReachability startNotifier] in AlipaySDK "_SCNetworkReachabilitySetDispatchQueue" , referenced from: -[APayReachability startNotifier] in AlipaySDK -[APayReachability stopNotifier] in AlipaySDK "_SCNetworkReachabilityUnscheduleFromRunLoop" , referenced from: -[AliSecXReachability stopNotifier] in AlipaySDK "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(char const*, unsigned long)" , referenced from: CAliSecXURL::encodeURIComponent(CAliSecXBuffer&) in AlipaySDK "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::reserve(unsigned long)" , referenced from: CAliSecXURL::encodeURIComponent(CAliSecXBuffer&) in AlipaySDK "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()" , referenced from: CAliSecXURL::encodeURIComponent(CAliSecXBuffer&) in AlipaySDK "std::nothrow" , referenced from: CAliSecXBuffer::CAliSecXBuffer(unsigned long) in AlipaySDK CAliSecXBuffer::_copy(unsigned char const*, unsigned long) in AlipaySDK CAliSecXBuffer::resize(unsigned long) in AlipaySDK "std::terminate()" , referenced from: ___clang_call_terminate in AlipaySDK "operator delete[](void*)" , referenced from: CAliSecXBuffer::~CAliSecXBuffer() in AlipaySDK CAliSecXBuffer::release() in AlipaySDK CAliSecXBuffer::~CAliSecXBuffer() in AlipaySDK CAliSecXBuffer::operator=(CAliSecXBuffer const&) in AlipaySDK CAliSecXBuffer::resize(unsigned long) in AlipaySDK alisec_crypto_Hex2Bin(CAliSecXBuffer const&) in AlipaySDK alisec_crypto_Bin2Hex(CAliSecXBuffer const&) in AlipaySDK ... "operator new[](unsigned long, std::nothrow_t const&)" , referenced from: CAliSecXBuffer::CAliSecXBuffer(unsigned long) in AlipaySDK CAliSecXBuffer::_copy(unsigned char const*, unsigned long) in AlipaySDK CAliSecXBuffer::resize(unsigned long) in AlipaySDK "___cxa_begin_catch" , referenced from: ___clang_call_terminate in AlipaySDK "___gxx_personality_v0" , referenced from: +[ASSStorageAccesser saveStorageModel:] in AlipaySDK +[ASSStorageAccesser loadStorageModelFromKeychain] in AlipaySDK +[ASSStorageAccesser loadPreviousApdid] in AlipaySDK +[ASSStorageAccesser getRandomizedID] in AlipaySDK +[ASSStorageAccesser getNewRadomizedID] in AlipaySDK +[ASSStorageAccesser loadLastLoginTime] in AlipaySDK +[ASSStorageAccesser saveCurrentLoginTime:] in AlipaySDK ... "_deflate" , referenced from: +[ASSCommonUtils gzipData:] in AlipaySDK +[DTGZipUtil compressGZip:] in AlipaySDK "_deflateEnd" , referenced from: +[ASSCommonUtils gzipData:] in AlipaySDK +[DTGZipUtil compressGZip:] in AlipaySDK "_deflateInit2_" , referenced from: +[ASSCommonUtils gzipData:] in AlipaySDK +[DTGZipUtil compressGZip:] in AlipaySDK "_kCNNetworkInfoKeyBSSID" , referenced from: +[UIDevice(APEX) networkDic] in AlipaySDK "_kCNNetworkInfoKeySSID" , referenced from: +[UIDevice(APEX) networkDic] in AlipaySDK ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation)
这种问题通过在General
->Link Framework and Libraiies
中添加以下framework解决:
libz.tbd
libc++.tbd
Security.framework
CoreMotion.Framework
CFNetwork.framework
CoreTelephony.framework
SystemConfiguration.framework
如图:
强迫症可以挪下位置~~
现在运行,应该就可以了,别的问题我好像也没有遇到~(记得联网!!!!)
交易订单处理失败,请稍候再试。(ALI64) 我出现这个问题是因为product.body
放了空值,这里不能为空~
补充下,支付完成的回调需要在AppDelegate.h
中的-(BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation;
函数中调用:
1 2 3 4 5 6 7 8 if ([url.host isEqualToString:@"safepay" ]) { [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { }]; return YES ; }
来处理回调,不然应用无法知道有没有支付成功。返回9000
代表支付成功。
注意仔细查看本文中Alipay
函数的最后几行,在那个地方有个[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback……
函数,在这个函数中处理回调的结果!!
AppDelegate.h
里面的standbyCallback:\^(NSDictionary \*resultDic) {}];
是不会有回调结果的!!!