支付宝即时到账支付全解析

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

    简单介绍了支付宝即时到账支付-即PC端支付的申请、接入、使用、确认支付结果等相关流程

    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. 打开地址跳转支付宝收银台进行扫码或者输入密码支付
    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
    
    $MAPI_GATEWAY = "https://mapi.alipay.com/gateway.do";    //mapi 入口 路由
    
    $data = array();
    $data['service'] = "create_direct_pay_by_user"; 
    $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);
    
    $params = createLinkstringUrlencode($data);
    
    $url = $MAPI_GATEWAY . '?' . $params;
    

    一些函数:

    /**
     * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
     * @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;
      }
    
    /**
     * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串 并对字符串做urlencode编码
     * @param $para mixed 需要拼接的数组
     * @return string 拼接完成以后的字符串
     */
    public static function createLinkstringUrlencode($para) {    
      $arg  = "";    
      while (list ($key, $val) = each ($para)) {        
        if($val == "") {            
          continue;        
        }        
        $arg.=$key."=".urlencode($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 异步结果通知

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

    验证签名可以直接下载支付宝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. 客户端收到同步支付结果后建议一段时间内轮询检查服务端,获取服务端的结果,支付最终状态以服务端为准

    结尾

    更多文章关注我的公众号


    我的公众号

    相关文章

      网友评论

      • 5c753f1ff42e:Func是什么类,好像没有找到代码
        5c753f1ff42e:@Tsy远 Func::arrayToXml($arr, $xml_data); 么有找到
        Tsy远:在下面一些函数那一段。就是一个 class Func
      • Mr大大大:想开发一个这个功能,但是自己是个人,没法申请,希望能借用一下你的配置参数。我知道这很冒昧,但我实在申请不上。如果方便的话,我的邮箱827840318@qq.com
        Mr大大大:@Tsy远 没关系 我知道这个比较隐私
        Tsy远:这个不大方便啊,不好意思啦

      本文标题:支付宝即时到账支付全解析

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