123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225 |
- <?php
- /**
- * 支付宝支付通知类
- * Created by PhpStorm.
- * User: phperstar
- * Date: 2019/11/28
- * Time: 5:00 PM
- */
- namespace JinDouYun\Controller\Common;
- use Mall\Framework\Core\StatusCode;
- use JinDouYun\Controller\BaseController;
- use JinDouYun\Model\Order\MOrder;
- use JinDouYun\Model\Market\MVipCard;
- class AliPayNotify extends BaseController
- {
- //使用文件读取文件格式,请只传递该值(支付宝公钥文件方式)
- private $alipayPublicKey = null;
- //使用读取字符串格式,请只传递该值(支付宝公钥字符串方式)
- private $alipayrsaPublicKey;
- public function __construct($isCheckAcl = false, $isMustLogin = false, $checkToken = false)
- {
- parent::__construct($isCheckAcl, $isMustLogin, $checkToken);
- $this->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;
- }
- }
|