zoukankan      html  css  js  c++  java
  • 支付宝集成——如何在回调地址中使用自定义参数

    alipay支付宝集成时,有同步返回地址return_url和异步通知地址notify_url,这两个地址中的参数与签名验证有非常大的关系,在支付宝的说明中,强调return_url不可以有自定义参数,否则会导致sign和mysign不相等,但有时我们需要一些自定义参数来做判断,怎么办呢?

     

    签名验证机制

    支付宝签名有两次,第一次是发送的时候,第二次是返回的时候,返回又分为同步返回和异步通知,这两个的签名方式是相同的。

    向支付宝发送参数时,调用如下函数产生签名,并构建生成表单的数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    function buildRequestPara($para_temp,$aliapy_config) {
        //除去待签名参数数组中的空值和签名参数
        $para_filter = paraFilter($para_temp);
        //对待签名参数数组排序
        $para_sort = argSort($para_filter);
        //生成签名结果
        $mysign = buildMysign($para_sort, trim($aliapy_config['key']), strtoupper(trim($aliapy_config['sign_type'])));
        //签名结果与签名方式加入请求提交参数组中
        $para_sort['sign'] = $mysign;
        $para_sort['sign_type'] = strtoupper(trim($aliapy_config['sign_type']));
        return $para_sort;
    }

    数据返回时,调用下面的函数生成签名

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    function verifyReturn(){
        if(empty($_GET)) {//判断POST来的数组是否为空
            return false;
        }
        else {
            //生成签名结果
            $mysign = $this->getMysign($_GET);
            //获取支付宝远程服务器ATN结果(验证是否是支付宝发来的消息)
            $responseTxt = 'true';
            if (! empty($_GET["notify_id"])) {$responseTxt = $this->getResponse($_GET["notify_id"]);}
             
            //写日志记录
            $log_text = "responseTxt=".$responseTxt." notify_url_log:sign=".$_GET["sign"]."&mysign=".$mysign.",";
            $log_text = $log_text.createLinkString($_GET);
            logResult($log_text);
             
            //验证
            //$responsetTxt的结果不是true,与服务器设置问题、合作身份者ID、notify_id一分钟失效有关
            //mysign与sign不等,与安全校验码、请求时的参数格式(如:带自定义参数等)、编码格式有关
            if (preg_match("/true$/i",$responseTxt) && $mysign == $_GET["sign"]) {
                return true;
            } else {
                return false;
            }
        }
    }
    function getMysign($para_temp) {
        //除去待签名参数数组中的空值和签名参数
        $para_filter = paraFilter($para_temp);
        //对待签名参数数组排序
        $para_sort = argSort($para_filter);
        //生成签名结果
        $mysign = buildMysign($para_sort, trim($this->aliapy_config['key']), strtoupper(trim($this->aliapy_config['sign_type'])));
        return $mysign;
    }

    两者最终都要调用buileMysign函数,如下

    1
    2
    3
    4
    5
    6
    7
    8
    function buildMysign($sort_para,$key,$sign_type = "MD5") {
        //把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
        $prestr = createLinkstring($sort_para);
        //把拼接后的字符串再与安全校验码直接连接起来
        $prestr = $prestr.$key;
        //把最终的字符串签名,获得签名结果
        $mysgin = sign($prestr,$sign_type);
        return $mysgin;

    从这些过程可以得出以下结论

    • 支付宝的签名是根据程序构建的参数进行的,发送时参数由本地程序构建,所以受自己控制,只要参数正确,基本可以成功,去除空参数等操作是支付宝的库函数来完成的。
    • 接收回传的参数时,对于同步返回的参数,$_GET数组的内容非常重要,因为验证回传参数时(调用verfyReturn()函数),首先将$_GET的内容全部传给getMysign()方法,支付宝会get给我们一个sign,只有根据回传参数产生出相同的sign,才可以验证通过。这就是我们不能使用自定义参数的原因,如果增加了自定义参数,getMysign()就会带有杂质,跟支付宝生成的sign过程不同了,自然结果就要不对。

    如何让自定义参数跟支付宝兼容

    这个自定义参数问题只存在于return_url中,因为同步回传使用GET方式,异步通知使用POST方式,POST不受url中的自定义参数影响。

    假设你的自定义参数是custom_val

    在调用支付宝的验证参数前,将这个自定义参数从$_GET数组中去掉,支付宝验证结束后再恢复就可以了。

    1
    2
    3
    4
    5
    6
    7
    8
    $get_temp = $_GET;
    unset($_GET['custom_val']);
    //调用支付宝验证签名接口
    $alipayNotify = new AlipayNotify($aliapy_config);
    $verify_result = $alipayNotify->verifyNotify();
    //恢复$_GET数组
    $_GET = $get_temp;
    unset($get_temp);

    为什么notify_url地址不能带有自定义参数

    在指定notify_url时,合法的方式如

    http://www.solagirl.net/notify_url.php

    不合法的方式如

    http://www.solagirl.net/notify_url.php?order_id=10

    与其说第二种格式不合法,不如说它是无效的。为什么这样说?因为不论你在这个地址后面带上多少自定义的参数,支付宝通过异步方式向你POST数据时,都会把?后面的参数去掉,所以带了也是白带,起不了任何作用,更不可能影响签名判断。这点似乎不如paypal方便,要区分执行过程只能靠POST过来的数据。

    因此支付宝的notify_url不是不可以带有自定义参数,而是带了也没用,自作多情而已。

  • 相关阅读:
    TimesTen的安装和连接
    推荐10款免费而优秀的图表插件
    做了一个jquery插件,使表格的标题列可左右拉伸
    基于SSM实现的简易员工管理系统(基于阿里云的网站上线篇)
    基于SSM实现的简易员工管理系统
    基于局域网的超简易即时通讯软件(二)
    基于局域网的超简易即时通讯软件(一)
    我的Vim常用快捷键
    php最新面试题
    2017php经典面试题
  • 原文地址:https://www.cnblogs.com/u0mo5/p/4577076.html
Copyright © 2011-2022 走看看