支付宝App支付全解析

作者: Tsy远 | 来源:发表于2016-07-11 10:07 被阅读17562次

    简单介绍了支付宝App支付的申请、接入、使用、确认支付结果等相关流程

    0 系列文章

    系列一 微信App支付全解析
    系列二 支付宝App支付全解析
    系列三 微信公众号支付全解析
    系列四 微信扫码支付全解析
    系列五 支付宝即时到账支付全解析
    系列六 微信退款全解析
    系列七 支付宝退款全解析
    系列八 支付宝开放平台支付更新升级全解析

    1 申请

    登录支付宝商家服务,进入移动支付。签约。

    签约通过后,一共需要以下参数可以完成支付:

    1. partnerid
    2. sellerid
    3. rsa私钥
    4. 支付宝公钥

    1.1 partnerid

    商户合作者身份。

    进入我的商家服务
    获取pid

    Paste_Image.png

    注:支付宝还有一个开放平台,每个应用一个appid,一个pid可以有多个appid,但是移动支付、即时到账收款、手机网站支付这三种支付渠道属于只需要pid即可支付的支付方式,不需要申请应用

    1.2 sellerid

    登录支付宝账户,一般为邮箱或者手机号

    1.3 rsa私钥和支付宝公钥

    rsa私钥公钥是自己生成,然后将公钥上传支付宝,私钥自己保存。

    详见官网文档

    Paste_Image.png

    2 接入流程

    参考支付宝移动支付接入文档

    主要几个步骤:

    1. 生成支付参数(放在服务端,需要生成签名)
    2. 调用客户端SDK发起支付
    3. 服务端异步接收支付结果

    2.1 生成支付参数

    $partner = "";  //你的pid
    $seller_id = "";  //seller_id
    $subject = "支付宝移动支付测试";  //交易主题
    $body = "支付宝移动支付测试detail";  //交易详细说明
    $total_fee = "0.01";    //支付金额 单位是元
    $out_trade_no = "";  //自己业务系统生成的交易no,可以唯一标识
    $rsa_path = "";  //rsa私钥路径
    $notify_url = "";    //接收支付结果通知url
    
    $data = array();
    $data['service'] = "mobile.securitypay.pay"; 
    $data['partner'] =$partner;
    $data['_input_charset'] = "utf-8";
    $data['notify_url'] = $notify_url;
    $data['out_trade_no'] = $out_trade_no;    
    $data['subject'] = $subject;
    $data['payment_type'] = "1";
    $data['seller_id'] = seller_id;
    $data['total_fee'] = $total_fee;
    $data['body'] = $body;
    
    //签名
    $unsign_str =createLinkString(argSort($data));
    $sign =rsaSign($unsign_str, $rsa_path);
    $sign = urlencode(mb_convert_encoding($sign, "UTF-8"));  //需要进行utf8格式转换
    
    $pay_params = $unsign_str . "&sign=" . $sign . "&sign_type=RSA";
    

    一些函数:

    /**
     * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @param $para mixed 需要拼接的数组
     * @return string 拼接完成以后的字符串
     */
    public static function createLinkString($para) {    
      $arg  = "";    
      while (list ($key, $val) = each ($para)) {        
        if($val == "") {            
          continue;        
        }        
        $arg.=$key."=".$val."&";    
      }    
      //去掉最后一个&字符    
      $arg = substr($arg,0,count($arg)-2);    
      //如果存在转义字符,那么去掉转义    
      if(get_magic_quotes_gpc()){
        $arg = stripslashes($arg);
      }    
      return $arg;
      }
    
    /**
     * 数组排序 按照ASCII字典升序
     * @param $para mixed 排序前数组
     * @return mixed 排序后数组
     */
    public static function argSort($para) {    
      ksort($para);    
      reset($para);    
      return $para;
    }
    
    /**
     * RSA签名
     * @param $data string 待签名数据
     * @param $private_rsa_path string 用户私钥地址
     * @return mixed
     *      失败:false
     *      成功:签名结果
     */
    public static function rsaSign($data, $private_rsa_path) {    
      $private_rsa = file_get_contents($private_rsa_path);    
      $res = openssl_get_privatekey($private_rsa);    
      if(!$res) {        
        return false;    
      }    
      openssl_sign($data, $sign, $res);    
      openssl_free_key($res);    
      //base64编码    
      $sign = base64_encode($sign);    
      return $sign;
    }
    

    3. 调用支付

    3.1 Android

    可以直接参考调用我二次封装过的Android SDK。将生成的pay_param直接传入支付宝支付即可发起支付。
    Github地址:https://github.com/tsy12321/PayAndroid

    3.2 iOS

    二次封装过的iOS SDK。
    Github地址:https://github.com/tsy12321/PayiOS

    4 异步结果通知

    注:尤其要注意通知结果验证成功后要能正确处理重复通知,放置多次发货造成资金损失

    验证签名可以直接下载支付宝sdk例子,进行直接调用。
    下载地址:https://doc.open.alipay.com/doc2/detail.htm?treeId=54&articleId=104509&docType=1
    打开其中服务端Demo将里面验证通知部分取出来使用。

    $$alipay_partnerid = "";  //你的pid
    $$alipay_public_key_path = "";  //支付宝公钥路径
    
    $alipayNotify = new AlipayNotify($alipay_partnerid, $alipay_public_key_path);
    $verify_result = $alipayNotify->verifyNotify();
    if(!$verify_result) {    
      //签名验证失败 todo 
      die("fail");
    }
    
    //成功接收并验证了通知
    echo("success");
    
    if($_POST['trade_status'] !== "TRADE_SUCCESS" && $_POST['trade_status'] !== "TRADE_FINISHED") {    
      if($_POST['trade_status'] === "WAIT_BUYER_PAY") {                    
        //wait bueyer pay通知可以忽略    
        die("success");    
      } else if($_POST['trade_status'] === "TRADE_CLOSED" && $_POST['refund_status'] === "REFUND_SUCCESS") {   //全额退款也是成功        
        //当退款成功时 可能会触发通知closed的通知,也可以算作成功支付
      } else {    //支付失败        
        //支付失败处理  todo
      }
    }
    
    //支付成功处理 发货
    //todo
    
    

    5 其他

    1. 客户端收到同步支付结果后建议一段时间内轮询检查服务端,获取服务端的结果,支付最终状态以服务端为准

    结尾

    更多文章关注我的公众号


    我的公众号

    相关文章

      网友评论

      • 你好_ddb0:博主,你好.申请app支付被驳回了,理由是产品必须已经上架,请问这必须上架到国内应用商店才可以吗?自己公司官网行不行
      • 003be78a6f72:我想问一下,现在公司叫我写一个java服务器端处理安卓客户端的接口,该怎么下手啊,完全没思路
        003be78a6f72:@Tsy远 哦哦,好的!谢了,我再去研究研究
        Tsy远:不好意思才看到。
        首先你先了解整个支付的流程,可以看官方文档配合我的博客,重点看流程的跳转和各个数据从哪边来。
        我这边大概说一下,首先服务端要提供一个创建订单的接口,客户端下单支付的时候调用。创建本地一个订单记录,然后根据支付宝微信的文档生成支付参数,并签名。然后传回客户端。客户端收到参数后再根据文档调用客户端的支付sdk,就会发起支付。支付完成后支付宝或者微信的服务器会异步发给你服务器支付结果通知。你要收到这条通知并验证,然后取到里面的订单信息和支付结果然后更新自己数据库订单的支付状态。然后提供一个查询订单状态的接口,可以让客户端调用查询最后的支付结果。
        整个流程应该就是这样
      • 七岁小猫:新版支付宝PID已经作为支付宝账户登录授权业务使用,支付好像不需要了
        Tsy远:@七岁小猫 这篇文章已经说明了哦:http://www.jianshu.com/p/59341ea9d86d
      • 62a89a5eab21:支付宝已经不用在APP端配置appid了吗?
        Tsy远:要的
        62a89a5eab21:@Tsy远 请问依赖了你的github后,开放平台上文档上的混淆规则还需要自己添加吗
        Tsy远:不用了 作为参数穿进去就行
      • a661ba673c5f:你好,我app支付对接成功。针对app支付成功的交易,我在pc后台处理退款,是调用哪个接口呢?
        Tsy远:你可以看下我最新的支付宝支付文章啊
      • f6be504df30e:支付宝 移动支付调起参数 中没有return_url 同步回调地址啊
        f6be504df30e:@Tsy远 好的 谢谢
        Tsy远:没有。网页支付才有 就是即时支付
      • 宇宙只有巴掌大:能否提供一个 json 串的样本 博主,我们服务端不知道咋搞,问题是我也不是很清楚我需要啥....
        宇宙只有巴掌大: @Tsy远 你要是有样本,json串我就可以让服务端做成跟你一样的
        宇宙只有巴掌大: @Tsy远 大神问题是看不懂php
        Tsy远:@宇宙只有巴掌大 文章里面有代码是生成pay param的啊
      • 聪葱忙忘:写的很好,不过有个问题想问你,“客户端收到同步支付结果后建议一段时间内轮询检查服务端,获取服务端的结果,支付最终状态以服务端为准”这里,客户端该如何获取服务端的结果?服务端在处理成功时写入数据库吗?
        聪葱忙忘:@Tsy远 好的我明白了,谢谢
        Tsy远:对的。要记录该笔订单状态啊。客户端根据订单id查询支付状态

      本文标题:支付宝App支付全解析

      本文链接:https://www.haomeiwen.com/subject/kbzdjttx.html