alipayrsaPublicKey = 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnb7lP7zW4CR94yAgljj4yNc4j7NyWd7oGhCB5/0PBcg9QQ91bj4dAUMFyu/QNJK2ez2jqVUoDeB13ueOVxwBfINwLm4k6Kw5PnDkSJBuGyE9bUQDEPOpm3/UZmza86uvm5xce54gyn+9OqH0Z4iWt4CuVAG4IwwAaVVhNLwxJQAiKWHYtNzWHtvNQV81CFEJinnV8u1sh40ex0FZlnjcyvSwzOILVqEsLYUaXpp0XDnk9j1yC+sVSAjezIQUplptWuGBnMiA2Q5nZtryNm+BaaVV0wNCs5wTUr4hfvxcw4UitkNEwJTVKp2JUYMgNV8JuX+y/MEIASN8nMiL+rDzYwIDAQAB'; } /** * 支付宝回调处理方法 * 官网文档地址:https://docs.open.alipay.com/204/105301/ * @throws \Exception */ public function notify() { $flag = $this->rsaCheckV1($_POST, NULL, "RSA2"); //验签 if($flag){ //处理业务,并从$_POST中提取需要的参数内容 if($_POST['trade_status'] == 'TRADE_SUCCESS' || $_POST['trade_status'] == 'TRADE_FINISHED'){ // 处理交易完成或者支付成功的通知 file_put_contents('/www/wwwroot/logs/apiqnys.liuniukj.com/alipay.log',date('Y-m-d H:i:s').'回调数据'.var_export($_POST,true).PHP_EOL,FILE_APPEND); $passback_params = urldecode($_POST['passback_params']); // 回传参数 $attach = explode('|',$passback_params); if(empty($attach)){ exit('fail'); } $enterpriseId = $attach[0]; unset($attach[0]); $userCentId = $attach[1]; unset($attach[1]); $allOrdersId = array_values($attach); if (strpos( $_POST['out_trade_no'],'tmp') === false || substr($_POST['out_trade_no'],0,3) == 'tmp') { $updateOrderData = [ 'outerTradeNo' => $_POST['trade_no'], // 该交易在支付宝系统中的交易流水号 'payType' => StatusCode::$payType['aliPay'], 'payStatus' => StatusCode::$standard, 'orderStatus' => StatusCode::$orderStatus['waitDelivery'], 'payTime' => strtotime($_POST['gmt_payment']), // 支付完成时间 'total_fee'=> $_POST['total_amount'],//支付金额 'pay_way'=>StatusCode::$payType['aliPay'] ]; $objMOrder = new MOrder($userCentId, $enterpriseId); if(strpos( $_POST['out_trade_no'],'tmp') === false){ $result = $objMOrder->updateOrderPayData($updateOrderData, ['id'=>$allOrdersId,'no'=>$_POST['out_trade_no']],true); }else{ $result = $objMOrder->updateOrderPayData($updateOrderData, ['id'=>$allOrdersId,'outerTradeNo'=>$_POST['out_trade_no']],true); } if(!$result->isSuccess()){ file_put_contents('/www/wwwroot/logs/apiqnys.liuniukj.com/alipay.log',date('Y-m-d H:i:s').'修改订单状态失败'.var_export($result->getData(),true).PHP_EOL,FILE_APPEND); exit('fail'); }else{ exit('success');// 响应success表示业务处理成功,告知支付宝无需在异步通知 } } //处理会员卡订单 if (strpos( $_POST['out_trade_no'],'tmp') !== false && substr($_POST['out_trade_no'],0,3) == 'vip') { $vipOrderData = [ 'outerTradeNo' => $_POST['trade_no'], 'payType' => StatusCode::$payType['aliPay'], 'payStatus' => StatusCode::$standard, 'payTime' => strtotime($_POST['gmt_payment']), // 支付完成时间 ]; $objMVipCard = new MVipCard($enterpriseId, $userCentId); $result = $objMVipCard->updateVipOrderPayData($vipOrderData, ['id'=>$allOrdersId,'outerTradeNo'=>$_POST['out_trade_no']],true); if(!$result->isSuccess()){ file_put_contents('/www/wwwroot/logs/apiqnys.liuniukj.com/alipay.log',date('Y-m-d H:i:s').'修改会员卡订单状态失败'.var_export($result->getData(),true).PHP_EOL,FILE_APPEND); exit('fail'); }else{ exit('success');// 响应success表示业务处理成功,告知支付宝无需在异步通知 } } exit('fail'); }else{ file_put_contents('/www/wwwroot/logs/apiqnys.liuniukj.com/alipay.log',date('Y-m-d H:i:s').'状态错误'.var_export($_POST,true).PHP_EOL,FILE_APPEND); } }else{ file_put_contents('/www/wwwroot/logs/apiqnys.liuniukj.com/alipay.log',date('Y-m-d H:i:s').'签名验证失败'.var_export($_POST,true).PHP_EOL,FILE_APPEND); } } /** rsaCheckV1 & rsaCheckV2 * 验证签名 * 在使用本方法前,必须初始化AopClient且传入公钥参数。 * 公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。 **/ public function rsaCheckV1($params, $rsaPublicKeyFilePath,$signType='RSA') { $sign = $params['sign']; $params['sign_type'] = null; $params['sign'] = null; return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath,$signType); } public function getSignContent($params) { ksort($params); $stringToBeSigned = ""; $i = 0; foreach ($params as $k => $v) { if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) { // 转换成目标字符集 $v = $this->characet($v, "UTF-8"); if ($i == 0) { $stringToBeSigned .= "$k" . "=" . "$v"; } else { $stringToBeSigned .= "&" . "$k" . "=" . "$v"; } $i++; } } unset ($k, $v); return $stringToBeSigned; } /** * 校验$value是否非空 * if not set ,return true; * if is null , return true; **/ protected function checkEmpty($value) { if (!isset($value)) return true; if ($value === null) return true; if (trim($value) === "") return true; return false; } /** * 转换字符集编码 * @param $data * @param $targetCharset * @return string */ function characet($data, $targetCharset) { if (!empty($data)) { $fileType = "UTF-8"; if (strcasecmp($fileType, $targetCharset) != 0) { $data = mb_convert_encoding($data, $targetCharset, $fileType); // $data = iconv($fileType, $targetCharset.'//IGNORE', $data); } } return $data; } function verify($data, $sign, $rsaPublicKeyFilePath, $signType = 'RSA') { if($this->checkEmpty($this->alipayPublicKey)){ $pubKey= $this->alipayrsaPublicKey; $res = "-----BEGIN PUBLIC KEY-----\n" . wordwrap($pubKey, 64, "\n", true) . "\n-----END PUBLIC KEY-----"; }else { //读取公钥文件 $pubKey = file_get_contents($rsaPublicKeyFilePath); //转换为openssl格式密钥 $res = openssl_get_publickey($pubKey); } ($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确'); //调用openssl内置方法验签,返回bool值 if ("RSA2" == $signType) { $result = (bool)openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256); } else { $result = (bool)openssl_verify($data, base64_decode($sign), $res); } if(!$this->checkEmpty($this->alipayPublicKey)) { //释放资源 openssl_free_key($res); } return $result; } }