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

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

<?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;
        }
    }

}