支付宝快捷支付notify接口示例

jerry PHP 2015年12月09日 收藏
该示例用于接收支付宝快捷支付notify回调,已经测试。

  1. <?php
    class AlipayAction extends Action {

        public function callback() {
            //得到签名
            $sign = urldecode($_POST['sign']);
            //得到待签名字符串
            $content = urldecode($_POST['content']);
            //验签数据
            $isVerify = $this->verify($content, $sign);
            //判断验签
            if ($isVerify) {
                //验签通过
                echo '2';
            } else {
                //验签失败
                echo '1';
            }
        }

        public function notify() {
            //获取notify_data,不需要解密,是明文的格式,注意不要用I()获取notify_data,避免字符被过滤
            $notify_data =  $_POST['notify_data'];

            //获取sign签名
            $sign = I('sign');

            //验证签名,需要添加notify_data=
            $isVerify = $this->verify('notify_data='.$notify_data, $sign);
            //如果验签没有通过
            if (!$isVerify) {
                echo 'fail';
                return;
            } else {
                echo 'true';
            }

            //获取交易状态
            $trade_status = $this->getDataForXML($notify_data, '/notify/trade_status');
            //判断交易是否完成
            if ($trade_status == 'TRADE_FINISHED') {
                $out_trade_no = $this->getDataForXML($notify_data, '/notify/out_trade_no');
                $m['oid'] = (string) $out_trade_no;
                // 订单状态改成已付款,以下为示例数据库操作
                D('Order')->where($m)->setField('buy', 1);
                echo 'success';
            } else {
                echo 'fail';
            }
        }

        
        /**RSA签名
         * $data待签名数据
         * 签名用商户私钥,必须是没有经过pkcs8转换的私钥
         * 最后的签名,需要用base64编码
         * return Sign签名
         */
        protected function sign($data) {
            //读取私钥文件,注意此处改成你的正确文件路径
            $priKey = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/app/Conf/AliKey/rsa_private_key.pem');
            //转换为openssl密钥,必须是没有经过pkcs8转换的私钥
            $res = openssl_get_privatekey($priKey);
            //调用openssl内置签名方法,生成签名$sign
            $sign = '';
            openssl_sign($data, $sign, $res);
            //释放资源
            openssl_free_key($res);
            //base64编码
            $sign = base64_encode($sign);
            return $sign;
        }

        /**RSA验签
         * $data待签名数据
         * $sign需要验签的签名
         * 验签用支付宝公钥
         * return 验签是否通过 bool值
         */
        protected function verify($data, $sign) {
            //读取支付宝公钥文件,注意此处改成你的正确文件路径
            $pubKey = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/app/Conf/AliKey/alipay_public_key.pem');
            //转换为openssl格式密钥
            $res = openssl_get_publickey($pubKey);
            
            //调用openssl内置方法验签,返回bool值
            $r = openssl_verify($data, base64_decode($sign), $res);
            debug('openssl_verify=' . $r);
            $result = (bool) openssl_verify($data, base64_decode($sign), $res);
            //释放资源
            openssl_free_key($res);
            //返回资源是否成功
            return $result;
        }

        /**通过节点路径返回字符串的某个节点值
         * $res_data——XML 格式字符串
         * 返回节点参数
         */
        protected function getDataForXML($res_data, $node) {
            $xml = simplexml_load_string($res_data);
            $result = $xml->xpath($node);

            while (list (, $node) = each($result)) {
                return $node;
            }
        }

    }