iOS 集成支付宝sdk简单教程以及遇到的坑(2)

一切阅读,皆是误读。  -----安伯托 · 艾柯

想起来上一篇iOS 集成支付宝sdk简单教程以及遇到的坑(1)还漏了两个错误情况,没列出来。

一个是: 

does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE),

obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7

clang: error: unable to execute command: Segmentation fault: 11

clang: error: linker command failed due to signal (use -v to see invocation)

原因是开启了ENABLE_BITCODE,与第三方库不兼容。只要把这个关掉就行了。在build settings里搜bitcode,然后把ENABLE_BITCODE设为no。如图:


另一个是错误:

'openssl/asn1.h' file not found 


解决办法也很简单:在build settings 里搜"search path",找到header search paths ,把值设为$(PROJECT_DIR)/项目名称,如图:

ok,万事具备!!我先去尿个尿。

尿完尿,正式开干。

我们把上次copy的方法提取成一个方法,在需要的地方调用。

- (void)jumpToAlipay{

Order*order = [[Order alloc]init];

order.partner= partner;//支付宝合作商家id

order.sellerID= seller;//支付宝商家id,通常就是合作商家id

order.outTradeNO= [self  generateTradeNO];//订单ID(由商家自行制定)

order.subject= product.subject;//商品标题

order.body= product.body;//商品描述

order.totalFee= [NSStringstringWithFormat:@"%.2f",product.price];//商品价格

order.notifyURL=@"http://www.xxx.com";//回调URL

order.service=@"mobile.securitypay.pay";

order.paymentType=@"1";

order.inputCharset=@"utf-8";

order.itBPay=@"30m";

order.showURL=@"m.alipay.com";

//应用注册scheme,在AlixPayDemo-Info.plist定义URL types

NSString*appScheme =@"xxx";

//将商品信息拼接成字符串

NSString*orderSpec = [order description];

NSLog(@"orderSpec = %@",orderSpec);

//获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode

id 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);

}];

}

}

还有一个生成订单id的方法


- (NSString*)generateTradeNO

{

static int kNumber =15;

NSString*sourceStr =@"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

NSMutableString*resultStr = [[NSMutableString alloc]init];

srand((unsigned)time(0));

for(inti =0; i < kNumber; i++)

{

unsigned index =rand() % [sourceStr length];

NSString*oneStr = [sourceStr substringWithRange:NSMakeRange(index,1)];

[resultStr appendString:oneStr];

}

return resultStr;

重点看一下jumpToAlipay方法里生成订单的几个参数

order.partner= partner;//支付宝合作商家id

order.sellerID= seller;//支付宝商家id,通常就是合作商家id

order.subject= product.subject;//商品标题

order.body= product.body;//商品描述

order.totalFee= [NSStringstringWithFormat:@"%.2f",product.price];//商品价格

order.notifyURL=@"http://www.xxx.com";//回调URL

这些参数都换成自己的值。

NSString*appScheme =@"xxx";  这个参数值在项目的info 页面的URL Types里查看


如果你没设置的,就设置一个,值的内容最好是跟项目有关的有意义的内容。

也可以在plist里查看。


如果没设置就设置一个。

id signer =CreateRSADataSigner(privateKey);

把这句里的privateKey换成自己的私钥,就是通过openssl设置的那个私钥。

perfect!  我想我们真是天才!!

运行项目,点击支付-----没反应。。。

一看控制台,提示:rsa_private read error : private key is NULL

这个问题有两种解决办法。

先看第一种:

把私钥转换成PKCS8格式(如果服务端是用PHP读取私钥不需要PKCS8转换)

参考文档:https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.ZzNd4x&treeId=44&articleId=103242&docType=1

相关命令:

openssl  (进入openssl,然后执行下面的命令)

pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt (注意不要输错了)

如果已经转换成pkcs8格式了,仍然报这个错,那就试试下面的办法:

1)在RSADataSigner.m文件中 搜索代码 [result appendString:@"-----BEGIN PRIVATE KEY-----\n"]; 将其改成 

[result appendString:@"-----BEGIN RSA PRIVATE KEY-----\n"];

2)在RSADataSigner.m文件中 搜索代码 [result appendString:@"\n-----END PRIVATE KEY-----"]; 将其改成 [result appendString:@"\n-----END RSA PRIVATE KEY-----"];

如图:


修改前


修改后

解决了这个问题,继续,运行项目,点击支付-----终于跳转到支付宝了!!!!!


但是,感觉不太对。。。


系统繁忙,稍后再试!!!!


hmmmmmmm。出现这个问题,通常要检查自己的参数有没有错,还有私钥公钥。我这次就是公钥不对,重新生成公钥,上传。

有个小插曲,我按照之前的做法,在原来的支付宝商家服务那上传公钥,怎么都不对,搜了一下才发现支付宝换了个上传地址。。。。。

现在是在开放平台--》账户中心--》合作伙伴密钥--》查看--》修改  (注意不要有空格换行)



然而还有一种公钥:应用公钥。根据文档,这是用于调用api2.0的。

https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.vp1syv&treeId=44&articleId=103243&docType=1

需要用到的可以看看这个文档。

ok,继续,运行项目,点击支付-----终于正常了!!!!

输入密码,支付成功!!!  

剩下来的就是处理回调。这就不多说了。

至此,集成支付宝就真正大功告成。可以去吃火锅撩妹了!!!

哦,还有一个事。@风铃书简在上篇文章留言说不要直接在客户端对接,要放到服务端。我试了一下,由我们的app服务端提供一个接口,支付前,先访问这个接口,获得相关的参数值,比如商户id,合作id,私钥,标题,价格等,其实就是如下的这些参数值:

order.seller= param[@"seller_id"];

order.tradeNO= param[@"out_trade_no"];//订单ID(由商家自行制定)

order.productName= param[@"subject"];//商品标题

order.productDescription= param[@"body"];//商品描述

order.amount= param[@"total_fee"];//商品价格

order.notifyURL=param[@"notify_url"];//回调URL

order.service= param[@"service"];

order.paymentType= param[@"payment_type"];

order.inputCharset= param[@"_input_charset"];

order.itBPay= param[@"it_b_pay"];

order.showUrl= param[@"return_url"];

那么私钥,合作id,商户id都不需要保存在客户端了,生成订单id的方法generateTradeNO也不需要了,that is it.

如果不对,请指教。

最后,猫图镇楼:


如果你觉得文章不错,可以给我打赏点比特股(bts),以示支持。^_^

BTS6jUaVVkz9gN8t9sWY9NR5UbiubSz7QtVDnEtFGpujYeqQSfQ5E

推荐阅读更多精彩内容