该示例用于接收支付宝快捷支付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;
}
}
}