iOS开发之支付宝集成

 

项目中要用到支付功能,须要支付宝,微信,银联三大支付,因此打算总结一下,写两篇文章,方便之后的查阅, 你们在作的时候也能稍微参考下,用到的地方避免再次被坑。这是第二篇支付宝集成,第一篇银联支付在这里。原本要用那个ping++的神器,能够集成各类支付手段,异常的方便,可是考虑到安全性问题的话,支付的渠道仍是不让第三方参与的好,否则会不安全,因而就苦逼地慢慢的一个一个集成了。。。。这里就代理支付宝的集成过程:html

 

刚开始觉得支付宝集成仍是比较简单的,看了几个文章,网上的各位大神也是各类秀操做,说集成很简单,可是,真正作起来就不是那回事了, 特别是新版的1月11号更新的,我正好是这一天开始看的,网上的经验什么的 大都是比较老的,比较新的能用到的文章很少(可是好文章仍是有的,对我帮助也很大),如今我就来一步一步说一下本身集成支付宝的血泪史!前端

下载支付宝SDK

首先是开发包下载,仍是比较难发现的,网上之前文章中的连接都打不开,我找了很久才找到的。最新的地址在这里(注意的是下载出来的SDK包里面并无传说中的开发文档,须要其余地方找或者看网页上的)。
公钥、私钥、PID、sellerID、key这些东西的用途和获取方式在文档上都有详细的说明,这里再也不赘述,必定要把概念分清楚再去作,否则一会就乱了。若是遇到问题的话我们能够再一块儿探讨。git

支付流程理解

开发文档、开发文档、开发文档,重要的事情必定要说三遍!!!建议先把开发文档仔仔细细看一遍,必定要看,本小白刚开始的时候没有老老实实地看完,结果遇到不少不少的坑,以血和泪劝解你们,浪费的挺多的时间的,因此建议必定要好好看看,特别是交互流程这一部分
github


交互流程


流程就是跟我们平时在手机上买东西是同样的:
1.用户选好了商品后,点击提交订单(通常是这样),选择使用支付宝付款。
2.手机客户端(你作的APP)把用户选择的商品的信息传给大家后台服务器。
3.后台的服务器将各类数据拼接签名后生成一个签名后的字符串,回传到客户端APP上。
4.用户点击确认支付按钮,调用手机支付宝客户端(在你手机上装的那个),利用后台传过来的那个参数调起支付宝,让支付宝客户端传给他们服务器交互,进行付款。(这一步是支付宝本身完成的,安全性高)
5.支付宝的服务器将支付的结果(可能成功也可能不成功)返回给手机支付宝客户端和大家公司的后台服务器。
6.大家公司后台服务器收到后通常是更新下数据信息(这个我们不用管),手机支付宝客户端会显示一下支付成功,我们的客户端也能够显示一个订单支付成功之类的东西(就像在手机12306订票,用支付宝支付后支付宝客户端会说一次支付成功,12306也会说一次支付成功,我们就像12306客户端同样,须要再说一次订单支付成功)。web

到这里就完成了支付的过程了。我以为这个流程仍是很容易理解的。
其中我们就是商户客户端须要作的就是:
• 调用支付宝支付接口
• 处理支付宝返回的支付结果
支付宝文档上的应用范例:算法

ps:签名部分为了安全起见都放在了后台,若是大家执意要在手机客户端作签名,不怕被拦截那就再加上一步签名。也才三步,仍是很简单。后端

调用支付接口

在调用支付宝支付接口前,咱们须要先生成一个订单,文档中描述时,是将这步也放在客户端来作了,但这个最好是 放在服务器端来作,后台生成订单而后拼接,签名,而后服务器端直接给客户端传一个加密签名过的参数就能够了,这样比较安全,官方demo上放在客户端生成订单而且签名是由于没有服务给你用啊,因此就客户端上生成了~~~。
我作的时候,为了安全,生成订单,拼接字符串,签名,都是在服务器上作的,全部的订单信息,商户信息等都掌握在本身的手中,这样的话APP端就不怕被拦截数据,而且调用起来也就特别简单了,只须要调用支付的接口,打开支付宝APP客户端进行支付就好了,没有用户的手机上没有安装支付宝客户端的话会调用网页来支付,也是同样的。
若是只须要发送订单和处理支付返回结果,只须要添加AlipaySDK.bundle和AlipaySDK.framework这两个就好了,下载的SDK中很容易发现。
快捷支付方法是这个:安全

-(void)payOrder:(NSString *)orderStr fromScheme:(NSString *)schemeStr callback:(CompletionBlock)completionBlock;

在支付的按钮中,试用支付宝这个类,再调用这个方法就行啦!以下如:
服务器


调用这个方法

在调用支付宝接口的时候,咱们须要两个参数,orderStringAPPScheme, APPScheme是app在info.plist注册的scheme。
orderstring 这个是一个订单的字符串,由后台拼接生成的,还须要签名的。例如:
partner="2088101568358171"&seller_id="xxx@alipay.com"&out_trade_no="0819145412-6177"&subject="测试"&body="测试测试"&total_fee="0.01"&notify_url="http://notify.msp.hk/notify.htm"&service="mobile.securitypay.pay"&payment_type="1"&input_charset="utf-8"&it_bpay="30m"&sign="lBBK%2F0w5LOajrMrji7DUgEqNjIhQbidR13GovA5r3TgIbNqv231yC1NksLdw%2Ba3JnfHXoXuet6XNNHtn7VE%2BeCoRO1O%2BR1KugLrQEZMtG5jmJIe2pbjm%2F3kb%2FuGkpG%2BwYQYI51%2BhA3YBbvZHVQBYveBqK%2Bh8mUyb7GM1HxWs9k4%3D"&sign_type="RSA".微信

流程就这么简单,接下来是集成SDK的时间,这部分很坑,由于是咱们是商品的数据签名什么的都在后台作的,因此客户端作的时候遇到的坑就很少说了,能够参考这篇文章,基本上遇到的坑都能找到。
还有这篇是有人对这个进行的一个简单的封装,若是签名,数据部分须要在APP上作的话,能够直接用这个,封装很简单,也是加了个类目进行作出来的,实现很简单。你们能够参考一下。

支付宝的SDK给了一个处理返回结果的方法,就是那个openURL的那个,在demo的appdelegate里面有。

if ([url.host isEqualToString:@"safepay"]) { [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) { NSLog(@"result = %@",resultDic); ​ }]; }

关于签名(主要是在客户端签名时候注意的)

支付宝上要用那个RSA,这是个算法,因此为了方便,可使用第三方的方法,或者找demo上的代码粘贴上去!不过仍是那句话,为了安全,最好仍是后台的作,不怕被拦截了 。
签名的时候,涉及到了RSA公钥、私钥的生产,RSA的签名、验证签名,SHA1值的计算,base64和URL编码等等等等烦人的东西,估计支付的程序猿也不想麻烦,就用了一个开源的代码来统一解决这些问题,就是openssl这个文件夹。
若是你执意要在客户端上签名(前面说过,并不安全),也能够用demo中的openssl这个文件夹,那你须要导入这几个文件夹:DEMO中的openssl目录头文件,两个库文件libcrypto.a libssl.a,DEMO里支付宝本身写的Util目录,以下图:


用到的文件

支付宝文档上的集成流程详解,写的很详细了,通常遇到的问题都有提到。

推荐几篇好文章,能够参考下,减小点坑(一、四、5务必看看,颇有启发的):
1.集成支付宝钱包支付iOS SDK的方法与经验
2.IOS集成到支付宝的步骤及问题
3.这个也是遇到的一些问题和解决方法
4.iOS应用之支付宝集成总结
5.iOS 集成支付宝


这篇文章是在客户端作签名的,写的也很详细


今天又遇到个问题:调起了支付宝客户端,可是支付不了。


支付失败

这个是由于,若是订单来自服务器此错误表示后台返回的签名订单含有特殊字符 ,须要编码。
因为RSA签名机制每次生成的签名都不同,也就是是二进制数,后台返回签名的订单时,是基于base64位编码的 。可能基于base64位编码生成带有+=/等在url序列中不被容许的字符。当咱们拿着后台不进行特殊字符处理的订单做为参数去调用支付宝的接口时,便会出现因为支付宝客户端吊起支付宝服务器是URL有问题,致使错误ALI64 。
解决办法是 让后台处理一下参数中的特殊字符,具体的这里有示例.



文/WK_IOSDevelpoer(简书做者)
原文连接:http://www.jianshu.com/p/b88f87a552a1
 
 
补充:
 

iOS 移动支付之种类

iOS 端的移动支付,大概包括:支付宝支付、微信支付、银联卡支付、paypal支付,如今又多出一个Apple pay支付;

如何集成这些种类的支付方式

谈及如何集成这些支付方式,面对各类支付方式的SDK以及Demo写的详细的天衣无缝,我还真不如还如何去写,这里我就接地气的写写,写的很差请勿喷哦☺!

支付宝支付

大体有如下步骤:

1.向支付宝申请, 与支付宝签约,得到商户PID(partner)和帐号ID(seller)和私钥(privateKey)

注:*这一步,通常公司会搞定的,这里只是让你知道前因后果☺
  没有支付宝帐号的同窗,能够点击这里注册帐号
  已经有支付宝帐号的同窗点击这里申请移动支付
申请签约有个门槛比较难,就是无论你是我的仍是企业,都须要营业执照,这点有点蛋疼,不过人家也是为了有质量的管理申请者嘛,能够理解,我这里没有营业执照,申请工做就死在了摇篮里,不过大体流程,我基本弄清楚了,不过做为开发者,这申请工做就不用多关心了,通常公司都会有申请过的,我这里写出来也就是让咱们开发者也大概知道流程,而不是直接就是用,只知去向,不知来龙。  
申请签约成功后,就能够查看 PID(partner)和帐号ID(seller)和私钥(privateKey) ,查看地址点击这里 进行登陆,点击下图中的查询PID和Key;
Pay

可是这里查询到的Key 是公钥,不是私钥,你到底该怎么弄私钥呢?同窗们,不用急,支付宝文档写的仍是比较清楚的,点击这里能够查看RSA私钥及公钥生成

这里文档给出了两种平台下的生产方式,咱们既然是iOS 开发者,那就选择Linux用户生产的方式吧,能够直接在Mac的终端敲这些命令; 啊神支付
敲过这些命令后,会在本地生产两个文件,分别是私钥和公钥文件
在命令行敲入(以行为单位)
$cd ~/
$open . //打开文件的存放位置
想要查看文件内容,还须要使用命令
$cat rsa_private_key.pem //会在终端显示文件中的内容,这就是私钥
到这里,第一步基本上就能够了,具体还须要本身动手试试,否则仍是会一头雾水。

2.下载支付宝SDK以及Demo

这一步,没啥好说的,给个地址就行SDK以及Demo下载地址

3.集成SDK到工程中(生成订单信息,签名加密)

支付宝官方集成文档

集成支付宝SDK的步骤,这里是官方给出的集成文档, 按照步骤集成老是会出错,这不是咱们脑子不行,而是官方毕竟是官方。
查看支付宝给出的Demo,会发现这些文件必需要加到项目中: 啊神
其中小方框中的为必须加入,而除了小方框之外的,那就要看大家后台人员是否将签名成功字符串格式化的订单字符串,给你传到前端来,若是没有,那就必须你本身在前端处理; 按理说,这些应该由后台来处理,为了订单信息的安全,以及前端业务的轻运行,都该有后端来处理(注:这点不懂,没关系,后面还会根据代码在进行讲解;

集成中可能遇到的错误

1)Cannot find interface declaration for ‘NSObject’
啊神
解决方案:a. 能够在报错的文件中加入#import <Foundation/Foundation.h>
b. 能够建个pch文件加入

`
#ifdef __OBJC__
#import UIKit/UIKit.h
#import Foundation/Foundation.h
#endif
`

 

2)提示找不到 openssl/asn1.h 文件
啊神
解决方案:Build Settings –> Search Paths –> Header Search paths:$(PROJECT_DIR)/ASPayDemo/Alipay
啊神

3)_CNCopyCurrentNetworkInfo,referenced from:
啊神
解决方案:添加SystemConfiguration.framework

啊神

部署代码

NSString *partner = @""; //PID

    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];
        return;
    }
    
    Order *order = [[Order alloc] init];
    order.partner = partner;
    order.seller = seller;
    order.tradeNO = @"20160324012412412"; //订单ID(由商家自行制定)
    order.productName = @"iOS 高级教程"; //商品标题
    order.productDescription = @"这是一本关于iOS的一本高级教程书"; //商品描述
    order.amount = @"0.1"; //商品价格
    order.notifyURL = @"http://www.devashen.com/Notify/Alipay/"; //回调URL
    
    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];
    
    
    //获取私钥并将商户信息签名,外部商户能够根据状况存放私钥和签名,只须要遵循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) {
            if ([[resultDic objectForKey:@"resultStatus"] isEqualToString:@"9000"]) {
                //9000为支付成功
                
            }
            
        }];
    }

看代码,若是后台将签名成功字符串格式化的订单字符串,给你传到前端来,那咱们就只须要作不多的工做就能够了,只须要直接处理订单字符串便可:

[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {
            if ([[resultDic objectForKey:@"resultStatus"] isEqualToString:@"9000"]) {
                //9000为支付成功
                
            }
            
        }];

最后,千万别忘了,在Appdelegate中,处理支付宝客户端返回url处理方法, 少了这一步,支付宝SDK的回调方法是不会执行的:

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
   //跳转支付宝钱包进行支付,处理支付结果
        [[AlipaySDK defaultService] processOrderWithPaymentResult:url standbyCallback:^(NSDictionary *resultDic) {
            NSLog(@"result = %@",resultDic);
        }];
    return YES;
}

到这里,支付宝支付基本上完成, 火烧眉毛的你,赶忙去试验试验吧, 别忘了给大家相关负责人要对应的PID、收款帐号、以及私钥,固然若是后台直接传给你订单字符串的话,你能够直接给后台要接口了,置于PID什么的你就不用管了。

相关链接

本文章对应的Demo, 包含后端是、否给你订单字符串的两种处理

支付宝移动支付SDK官方文档

相关文章
相关标签/搜索