iOS之“支付宝支付”开发流程

来源:互联网 发布:淘宝上有两个稻香村 编辑:程序博客网 时间:2024/04/28 18:12

支付宝快捷支付的主要步骤:

  • 先与支付宝签约,获得商户ID(partner)和账号ID(seller);
  • 下载相应的公钥私钥文件(加密签名用);
  • 下载支付宝SDK;
  • 生成订单信息;
  • 调用支付宝客户端,由支付宝客户端跟支付宝安全服务器打交道;
  • 支付完毕后返回支付结果给商户客户端和服务。

而iOS客户端需要做的是:

  • 调用支付宝支付接口;
  • 处理支付宝返回的支付结果。

在调用支付宝支付接口前,还需要先生成一个订单,下载的支付宝文档中描述时,是将这步也放在客户端来做了,但也可以在服务器端生成这个订单(支付宝会在支付成功后通知服务器端,所以在服务器端生成订单的话,开发者掌握所有订单,而且也会更安全)。

  • 生成订单(可以在iOS客户端内生成,也可以在服务器端生成);
  • 调用支付宝支付接口,发送订单;
  • 处理支付宝返回的支付结果。

支付宝支付的安全问题,需要在生成订单和处理支付结果的时候做一个安全性校验:即生成订单时对数据签名,收到支付结果时对数据进行签名验证,以检验数据是否被篡改过(支付宝目前只支持采用RSA加密方式做签名验证)。简单地说,就是在生产订单时,需要使用私钥生成签名值;在处理返回的支付结果时,需要使用公钥验证返回结果是否被篡改。

支付宝iOS SDK的官方下载地址:
https://b.alipay.com/order/productDetail.htm?productId=2013080604609654&tabId=4#ps-tabinfo-hash

压缩包里有两个相关文档:
《支付宝钱包支付接口开发包2.0标准版.pdf》
《支付宝钱包支付接口开发包2.0标准版接入与使用规则.pdf》

集成支付宝支付的主要流程:

  • 将需要的文件,静态库等拖入工程中,这里有include,libs,Utilities,libcrypto.a,libssl.a文件(如果只需要发送订单和处理支付返回结果,只需要添加AlipaySDK.bundle和AlipaySDK.framework)。如下图:
    这里写图片描述

  • 设置Head Search Paths 和 Library Search Paths
    即:targets->Build Setting ->Search Paths->Always Search User Paths和 Library Search Paths,注意:Always Search User Paths 和 Library Search Paths的路径一定要根据这个地址能找到对应的头文件。

这里写图片描述

  • 设置partner、seller、RSA private key、RSA public key
    一般是设置在-info文件中。
    这里写图片描述

  • 支付成功后,回到应用程序中
    需要设置回调的标示,同样在-info文件中,添加个节点:
    这里写图片描述

  • 发送订单的方法:

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

如果手机内没安装支付宝的app,会直接展现支付宝web支付界面,通过callback返回支付结果;如果手机内安装了支付宝的app,会跳转到支付宝的app支付,然后通过openURL的回调返回支付结果。

  • 调用支付宝
[[AlipaySDK defaultService] payOrder:orderString fromScheme:appScheme callback:^(NSDictionary *resultDic) {     if ([resultDic[@"resultStatus"] intValue] == 9000) {         //支付成功      }      else{         NSString *resultMes = resultDic[@"memo"];         resultMes = (resultMes.length<=0?@"支付失败":resultMes);         NSLog(@"%@",resultMes);                       }    }];

支付宝的SDK只给了一个处理返回结果的方法,没有提供处理openURL的方法:

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

SDK提供了处理openURL返回结果的方法:

- (void)processOrderWithPaymentResult:(NSURL *)resultUrl standbyCallback:(CompletionBlock)completionBlock;

两个回调block都统一定义为typedef void(^CompletionBlock)(NSDictionary *resultDic)。

resultStatus状态码对应的信息:

  • 9000:订单支付成功
  • 8000:正在处理中
  • 4000:订单支付失败
  • 6001:用户中途取消
  • 6002:网络连接出错

result是订单信息,以及签名验证信息。

代码过程展示:

  • 在AppDelegate中:
- (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;}- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {    [self parseURL:url application:application];    return YES;}//签名验证- (void)parseURL:(NSURL *)url application:(UIApplication *)application {    AlixPay *alixpay = [AlixPay shared];    AlixPayResult *result = [alixpay handleOpenURL:url];    if (result) {        //是否支付成功        if (9000 == result.statusCode) {            /*             *用公钥验证签名             */            id<DataVerifier> verifier = CreateRSADataVerifier([[NSBundle mainBundle] objectForInfoDictionaryKey:@"RSA public key"]);            if ([verifier verifyString:result.resultString withSign:result.signString]) {                UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示"                                                                      message:result.statusMessage                                                                     delegate:nil                                                            cancelButtonTitle:@"确定"                                                            otherButtonTitles:nil];                [alertView show];            }//验签错误            else {                UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示"                                                                      message:@"签名错误"                                                                     delegate:nil                                                            cancelButtonTitle:@"确定"                                                            otherButtonTitles:nil];                [alertView show];            }        }        //如果支付失败,可以通过result.statusCode查询错误码        else {            UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示"                                                                  message:result.statusMessage                                                                 delegate:nil                                                        cancelButtonTitle:@"确定"                                                        otherButtonTitles:nil];            [alertView show];        }    }   }
  • 在需要支付的页面选中商品调用支付宝安全支付
- (void)payTreasurePay {    /*     *商户的唯一的parnter和seller。     *签约后,支付宝会为每个商户分配一个唯一的 parnter 和 seller。     */    //如果partner和seller数据存于其他位置,请改写下面两行代码    NSString *partner = @"商户的parnter";    NSString *seller  = @"商户的seller";    //partner和seller获取失败,提示    if ([partner length] == 0 || [seller length] == 0)    {        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示"                                                        message:@"缺少partner或者seller"                                                       delegate:self                                              cancelButtonTitle:@"确定"                                              otherButtonTitles:nil];        [alert show];        return;    }    /*     *生成订单信息及签名     */    //将商品信息赋予AlixPayOrder的成员变量    AlixPayOrder *order = [[AlixPayOrder alloc] init];    order.partner = partner;    order.seller = seller;    order.tradeNO = @"订单ID";             //订单ID(由商家自行制定)    order.productName = @"商品标题";        //商品标题    order.productDescription = @"商品描述"; //商品描述    order.amount = [NSString stringWithFormat:@"%.2f",2.5]; //商品价格    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 = URLScheme;    //将商品信息拼接成字符串    NSString *orderSpec = [order description];    NSLog(@"orderSpec = %@",orderSpec);    //获取私钥并将商户信息签名,外部商户可以根据情况存放私钥和签名,只需要遵循RSA签名规范,并将签名字符串base64编码和UrlEncode    NSString *privateKey = @"私钥";    id<DataSigner> signer = CreateRSADataSigner(privateKey);    NSLog(@"prikey = %@",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) {           NSString *resultStatus=resultDic[@"resultStatus"];           if([resultStatus isEqualToString: @"9000"]){              [self alert:@"恭喜" msg:@"您已成功支付啦!"];           }else{              [self alert:@"提示" msg:@"支付失败,可在待付款订单中查看"];       }          [self.navigationController popToRootViewControllerAnimated:YES];        }];        /*        //获取安全支付单例并调用安全支付接口        AlixPay * alixpay = [AlixPay shared];        int ret = [alixpay pay:orderString applicationScheme:appScheme];        if(ret == 9000){            [self alert:@"恭喜" msg:@"您已成功支付啦!"];        }else{            [self alert:@"提示" msg:@"支付失败,可在待付款订单中查看"];        }        [self.navigationController popToRootViewControllerAnimated:YES];        if (ret == kSPErrorAlipayClientNotInstalled) {            UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:@"提示"                                                                 message:@"您还没有安装支付宝快捷支付,请先安装。"                                                                delegate:self                                                       cancelButtonTitle:@"确定"                                                       otherButtonTitles:nil];            [alertView show];        }        else if (ret == kSPErrorSignError) {            NSLog(@"签名错误!");        }      */    }}- (void)alert:(NSString *)title msg:(NSString *)msg{    UIAlertView *alter = [[UIAlertView alloc] initWithTitle:title message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];    [alter show];}

注:
RSA加密算法,除了可加解密外,还可用来作签名校验。简单的说,RSA会生成一个私钥和一个公钥,私钥应该独自保管,公钥可以分发出去。做签名验证时,可以用私钥对需要传输的数据做签名加密,生成一个签名值,之后分发数据,接收方通过公钥对签名值做校验,如果一致则认为数据无篡改。

支付宝demo(包括ios,android,wp)下载地址:
http://download.csdn.net/download/pearlhuzhu/5736965

解决在iOS9上调用支付宝不可回调的问题以及支付宝的嵌入流程:
http://blog.csdn.net/baby_hua/article/details/51004405

0 0
原创粉丝点击