iOS

ios集成支付宝支付2016.8

2016-06-26  本文已影响2331人  cj2527

官方接入指南
https://doc.open.alipay.com/doc2/detail.htm?spm=a219a.7629140.0.0.6AJiJ8&treeId=58&articleId=103541&docType=1

1.签约与审核

签约:和支付宝签约,登记商家的信息,然后支付宝会给商家凭据,PID和key。
签约审核很快的,一般一天内就搞定了。

2.PID和密钥管理

PID:合作者身份id,就像你的身份证号码一样,唯一的。
key:密钥,支付宝提供商户接口产品时,会自主提供一个保障商户接入安全的一组信息及其对应的配置平台,这组信息就是密钥。由商户密钥与支付宝密钥交换后与支付宝商户标识(如partnerID、APPID等)绑定。

合作伙伴密钥

在服务市场签约获得的大部分接口,签约主体是商户,接口权限属于具体的商户,这部分接口需要使用PID和密钥来调用,此类接口网关一般为mapi(https://mapi.alipay.com/gateway.do),PID对应的密钥一共有三种签名方式,分别是MD5、RSA、DSA。由于产品的特殊性,每个产品支持哪些签名方式不尽相同,具体需参考各个产品的接口技术文档。
使用合作伙伴密钥的典型功能包括:
快捷登录、移动支付、即时到账收款、手机网站支付等。

补充:公钥和私钥是成对的,它们互相解密。
公钥加密,私钥解密。
私钥数字签名,公钥验证。

如何生成相应的公钥私钥文件(加密签名用)?
Mac下生成很方便,终端切换都某个目录,输入openssl,就可以打开openssl工具来生成。接着只要二句命令就可以搞定。

1、生成私钥pem, 执行命令 openssl genrsa -out rsa_private_key.pem 1024

23F95D24-F951-4FE1-9A5F-22BACAAD0649.png

2、生成公钥,执行命令 openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem

该目录下就会生成两个文件,可以用文本编辑器打开就可以查看字符串了。

F028F40D-DC0A-4CA1-BB73-4E036D9E3BAE.png

公钥字符串需要复制粘贴到支付宝后台

AC1AFD65-3619-4C5D-B3D1-3EC9E100F24F.png

各个RSA都添加一遍,暂时不知道各个业务的具体区别。暂时不提。

3.接口调用

首先下载支付宝的SDK,集成到你的工程中,编译成功后,就可以开始编写代码,进行
接口调用了。具体代码参考本文第5部分工程代码!

4.遇到问题

错误一: rsa_private read error : private key is NULL
两种解决方法
1解决方法:
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-----"];

我采用第一种方法!截图如下:


510806AB-216E-4768-8375-011F40AFB20E.png

2解决方法:
将RSA私钥转换成PKCS8格式,终端命令执行 openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt ( PHP服务端语言读取私钥不需要PKCS8转换)密码为空就行(直接回车)


错误二:LaunchServices: ERROR: There is no registered handler for URL scheme alipay
这句话其实是在告诉你 设备上没有安装 支付宝的客户端,此时会走网页端

错误三:NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9824)
原因是没有适配ios9

5.工程代码
//以下代码也是参考简述简书某个高手的,演示用的.

#import "ViewController.h"
#import <AlipaySDK/AlipaySDK.h>
#import "Order.h"
#import "DataSigner.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    UIButton *button1 = [[UIButton alloc]initWithFrame:CGRectMake(20, 20, 200, 44)];
    [button1 setTitle:@"0.01" forState:UIControlStateNormal];
    button1.backgroundColor = [UIColor redColor];
    [button1 addTarget:self action:@selector(click1) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button1];
    
    
    UIButton *button2 = [[UIButton alloc]initWithFrame:CGRectMake(20, 120, 200, 44)];
    [button2 addTarget:self action:@selector(click2) forControlEvents:UIControlEventTouchUpInside];
    [button2 setTitle:@"0.02" forState:UIControlStateNormal];
    button2.backgroundColor = [UIColor lightGrayColor];
    [self.view addSubview:button2];
    
}


- (void)click1
{
    [self pushAliPay:@"0.01"];
}
- (void)click2
{
    [self pushAliPay:@"0.02"];
}


- (void)pushAliPay:(NSString *)str_price
{
    
   //需要填写商户app申请
    NSString *partner = @"2088开头的";//签约成功,支付宝提供给你的PID
    NSString *seller = @"cj25??@163.com";//你的支付宝账号
    NSString *privateKey = @"MIICXQIBAAKBgQCmIu4gNNn2VmAL7V2i7Y57dsiRG2DiustWKqcRnHyF5vr6cWXDHrr\neSKx86ClTlFDPNBdZ6SKsBVC1fpbGQ3WIJPooQ2cl11l";
     //私钥和公钥都是你自己利用工具手动生成的,在这里私钥有很多,我删了大部分
    
    //partner和seller获取失败,提示
    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;
    }
    
    /*
     *生成订单信息及签名
     */
    //将商品信息赋予AlixPayOrder的成员变量
    Order *order = [[Order alloc] init];
    order.partner = partner;
    order.sellerID = seller;
    order.outTradeNO = [self generateTradeNO]; //订单ID(由商家自行制定)
    order.subject = @"商品标题"; //商品标题
    order.body = @"我是商品描述"; //商品描述
    order.totalFee = [NSString stringWithFormat:@"%.2f",[str_price doubleValue]]; //商品价格
    
    order.notifyURL =  @"http://www.xxx.com/AliNotify.php"; //回调URL.问后台要,   注意不带参数,完整的,而且是可以网上访问的地址,我用的是PHP。
    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 = @"alisdkdemo";//这里设置支付宝回调
    
    //将商品信息拼接成字符串
    NSString *orderSpec = [order description];
    NSLog(@"orderSpec = %@",orderSpec);
    
    //获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode
     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);
        }];
    }
}
#pragma mark -
#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;
}

@end


AppDelegate.m文件

#import "AppDelegate.h"
#import <AlipaySDK/AlipaySDK.h>
@interface AppDelegate ()

@end

@implementation AppDelegate
// 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);
//结果代码
/* 9000 订单支付成功 8000 正在处理中 4000 订单支付失败 6001 用户中途取消 6002 网络连接出错 */
        }];
    }
     NSLog(@"%s",__func__);
    return YES;
}

6.其他小细节
配置URL Schemes:点击项目名称,点击“Info”选项卡,在“URL Types”选项中,点击“+”, 在“URL Schemes”中输入“alisdkdemo”。
这里要和工程代码中的 NSString *appScheme = @"alisdkdemo";//这里设置支付宝回调,两者要保持一致。

注意:正式接入支付宝支付的阶段,注意以下几点:
1服务端:负责生成订单及签名,及接收支付异步通知。
2客户端:负责使用服务端传来的订单信息调用支付宝支付接口,及根据SDK同步返回3的支付结果展示结果页。
3服务端接入:私钥必须放在服务端,签名过程必须放在服务端。(上面测试例子是直接把私钥写在了客户端的代码中了,仅仅是测试)

4.notifyURL:算个人总结吧,我是搞前端的,也去了解了下这后端的知识,这是服务器端的回调,采用的是POST请求,所以
获取参数是用 $_POST['trade_status'];

遇到问题:客户端支付成功,钱也到账了,但以为notify.php没有执行,实际上它是有访问的,可以查看日志,有记录时间访问这个文件的。另外它没有得到它想要的,它会访问很多次,所以这个文件要及时给echo "success"。
另外获取参数它有三个状态值,
一个空,
一个TRADE_SUCCESS,高级版,只是说明支付成功,但交易没有结束的,可能有退款处理
一个TRADE_FINISHED,简单版,即时到账,交易就完成了。
具体区别就看网上的http://blog.163.com/lisoaring@126/blog/static/19205606201521222851548/

上一篇下一篇

猜你喜欢

热点阅读