iOS 支付宝集成中的那些坑

96
Lonely__M
2016.01.26 15:06* 字数 582

本文Demo地址

1.下载支付宝SDK以及Demohttps://doc.open.alipay.com/doc2/detail?treeId=54&articleId=103419&docType=1

2.解压下载的.zip包,选择iOS客户端,看到的目录结构如下

Paste_Image.png

3.导入AliSDKDemo中的AliAlipaySDK.bundle AlipaySDK.framework libcrypto.a libssl.a四个文件到工程中

Paste_Image.png

4.导入demo中相关文件到项目中


Paste_Image.png

5.导入后项目结构应该是这样的 其中AliPaySDK是笔者新建的文件夹用于存放支付宝项目文件的,你们可以自己创建文件夹

Paste_Image.png

6.导入系统依赖库

Paste_Image.png

7.此时如果编译的话,会报错

Paste_Image.png

解决方法 在Header Search Paths中添加AliPaySDK路径

注意 AliPaySDK为笔者自己创建的文件目录 ,你们可以自行创建,然后换成自己的路径就可以了
Paste_Image.png

8.客户端调用支付宝SDK



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

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    UIButton *payButton = [UIButton buttonWithType:UIButtonTypeCustom];
    payButton.frame = CGRectMake(10, 100, self.view.frame.size.width-20, 40);
    [payButton setTitle:@"pay 0.01元" forState:UIControlStateNormal];
    [payButton setTitle:@"pay 0.01元" forState:UIControlStateSelected];
    [payButton setBackgroundColor:[UIColor orangeColor]];
    [payButton addTarget:self action:@selector(payAction) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:payButton];
}

/**
 *  支付按钮
 */
- (void)payAction
{
    /*============================================================================*/
    /*=======================需要填写商户app申请的===================================*/
    /*============================================================================*/
    NSString *partner = @"2088*********"; /** 合作商户ID  PID */
    NSString *seller = @"填写支付宝账号"; /** 支付宝账号ID  */
    NSString *privateKey = @"很长的一串字符  文章下面有说明如何获取"; /** 商户私钥 自助生成 */
    /*============================================================================*/
    /*============================================================================*/
    /*============================================================================*/
    
    //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.seller = seller;
    order.tradeNO = [self generateTradeNO]; //订单ID(由商家自行制定)
    order.productName = @"runbey测试商品"; //商品标题
    order.productDescription = @"runbey商品描述"; //商品描述
    order.amount = @"0.01"; //商品价格
    order.notifyURL =  @"http://*****"; //回调URL 异步通知服务器支付结果,便于服务器更新订单状态
    
//实际项目开发中 订单信息应该由服务器返回


    order.service = @"mobile.securitypay.pay";
    order.paymentType = @"1";
    order.inputCharset = @"utf-8";
    order.itBPay = @"30m";
    order.showUrl = @"m.alipay.com";
    
    //应用注册scheme 便于支付结束后重新打开客户端
    NSString *appScheme = @"ybpaydemo";
    
    //将商品信息拼接成字符串
    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"];
        
        NSLog(@"签名字符串:%@",orderString);
        
        [[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;
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

9.针对以上代码做几点说明

1.Mac终端中输入 openssl 进入Openssl程序

  1. 生成私钥 命令 genrsa -out rsa_private_key.pem 1024
    3.iOS客户端需要将生成的私钥转换成PKCS8格式 命令 pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
获取到pkcs8格式的字符串就是项目中需要的privatekey,取-----BEGIN PRIVATE KEY----------END PRIVATE KEY-----

中间的部分 切记!!!!
4.生成公钥 命令 rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem


  • 支付宝集成出现“系统繁忙,请稍后重试(ALI64)”错误的解决办法

1.用记事本打开上面第四步生成的公钥 rsa_public_key.pem,并将里面的密钥拷贝出来,粘贴到合作伙伴密钥管理中得RSA加密里,特别需要注意的是,需要将密钥中的空格、回车等删除,使该密钥为一行字符串。
2.用记事本打开上面第四步生成的公钥 rsa_public_key.pem,并将里面的密钥拷贝出来,粘贴到开放平台密钥管理中得RSA加密里,特别需要注意的是,需要将密钥中的空格、回车等删除,使该密钥为一行字符串。


至此,完成了支付宝iOS客户端的集成。

记录点滴,与君共勉。

iOS随笔
Web note ad 1