_inWhiteList){ return true; } $this->_notifyUrl = "http://{$_SERVER['HTTP_HOST']}/v1/notifyJdPay"; $this->_Account = $this->getKey($this->_apiCode); //验证是否具有访问这个接口的权限 if(!isset($this->_Account['jdMerchant']) || !isset($this->_Account['jdDesKey']) || !isset($this->_Account['jdNotifyUrlArr']) ){ HelperService::returnJson(['code'=>400,'msg'=>'jdPay interface unauthorized access','data'=>[]]); } $this->_merchant = $this->_Account['jdMerchant']; } /** * 平台版京东支付 */ public function platformJdPay(){ $params = $this->_sysParams; $rule = [ //'showPayStoreName|收银台展示收款商户'=>'require', 'orderNo|订单号'=>'require', 'tradeName|订单商品名'=>'require', 'amount|支付金额(分)'=>'require|number', 'orderType|支付类型(0、实物;1、虚拟)订单'=>'require|number|between:0,1', 'callbackUrl|同步回调地址'=>'require', 'userId|用户id(保证唯一即可/免登)'=>'require' ]; $validate = new Validate($rule); if(!$validate->check($params)){ HelperService::returnJson(['code'=>400,'msg'=>$validate->getError()]); } $requestArr = [ //'payMerchant'=>"{$params['showPayStoreName']}",//收银台展示的收款商户,默认为商户号对应的商户, 'tradeNum'=>"{$params['orderNo']}",//交易流水号 'tradeName'=>"{$params['tradeName']}",//商户订单的标题/商品名称/关键字等 'tradeTime'=>date('YmdHis'),//订单生成时间。格式:“yyyyMMddHHmmss” 'amount'=>"{$params['amount']}",//金额(分),大于0 'orderType'=>"{$params['orderType']}",//订单类型,0实物;1虚拟 'currency'=>'CNY',//货币种类 'callbackUrl'=>"{$params['callbackUrl']}",//同步通知url 'notifyUrl'=>$this->_notifyUrl,//异步通知url 'userId'=>"{$params['userId']}" ]; $signArr=[ 'version'=>'V2.0', 'merchant'=>$this->_merchant//商户号 ]; $createSignArr = array_merge($signArr,$requestArr); $sign = $this->getSign($createSignArr); $signArr['sign'] = $sign; $encryRequestArr = $this->encryptQuery($requestArr); $url = 'https://h5pay.jd.com/jdpay/saveOrder';//统一下单支付 $html = $this->_createHtml($url, array_merge($encryRequestArr,$signArr)); HelperService::addLog($createSignArr, $url, 'JDPAY'); $this->assign('html',$html); return $this->fetch('jdpay/pay'); } private function _createHtml($url,$postParams){ $html = "
"; return $html; } public function notifyJdPay(){ $oldParams = $this->_oldParams; $url = HelperService::getHttpHeader().$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; try{ $resData = $this->decryptResXml($oldParams); if($resData['result']['code']=='000000'){ $tradeNum = isset($resData['tradeNum'])?$resData['tradeNum']:""; //一年之内,同一笔订单不能复现,否则屏蔽 if(Cache::has("JD{$tradeNum}")){ HelperService::addLog(['resData'=>$resData,'return'=>'success'], $url, 'JDPAY'); die('success'); } foreach($this->_notifyUrlArr as $notifyUrl){ $isSsl = strpos($notifyUrl, 'https://')!==false?true:false; $postData = json_encode($resData); $times = 3; while ($times--){ $res = HelperService::httpPost($notifyUrl,$postData, $isSsl); HelperService::addLog(['request'=>$postData,'res'=>$res,'times'=>$times], $notifyUrl, "JDPAY_DETAIL"); if($res !== false){ break; } } } Cache::set("JD{$tradeNum}",time(),365*86400); HelperService::addLog(['resData'=>$resData,'return'=>'success'], $url, 'JDPAY'); die('success'); } HelperService::addLog(['resData'=>$resData,'return'=>'fail'], $url, 'JDPAY'); die('fail'); } catch (\Exception $ex){ HelperService::addLog(['resData'=>$oldParams,'return'=>$ex->getMessage()], $url, 'JDPAY'); die('fail'); } } private function getSign($param){ ksort($param); $queryStr = $this->httpBuildQuery($param); $sha256SourceSignString = hash("sha256", $queryStr); $sign = OpensslService::encryptByPrivateKey($this->_apiCode, $sha256SourceSignString); return $sign; } private function httpBuildQuery($arr=[]){ $queryStr = ''; foreach($arr as $key=>$val){ if($val===""){ continue; } if(!empty($queryStr)){ $queryStr.='&'; } $queryStr .= "$key=$val"; } return $queryStr; } private function encryptQuery($param){ $desKey = $this->_Account['jdDesKey']; $keys = base64_decode($desKey); foreach($param as &$val){ $val = OpensslService::encrypt2HexStr($keys, $val); } return $param; } private function decryptResXml($resultData){ $resultXml = simplexml_load_string($resultData); $resultObj = json_decode(json_encode($resultXml),TRUE); if(!isset($resultObj["encrypt"])){ die($resultXml); } $encryptXml = $resultObj["encrypt"]; $encryptStr=base64_decode($encryptXml); $desKey = $this->_getJdDesKeyByMerchant($resultObj['merchant']); $keys = base64_decode($desKey); $reqBody = OpensslService::decrypt4HexStr($keys, $encryptStr); //echo "请求返回encrypt Des解密后:".$reqBody."\n"; $bodyXml = simplexml_load_string($reqBody); //echo "请求返回encrypt Des解密后:".$bodyXml->saveXML()."\n"; $resData = json_decode(json_encode($bodyXml),TRUE); return $resData; } /** * 遍历目录下该jd商户号是否等于回传的商户号 * @param type $merchant * @return type */ private function _getJdDesKeyByMerchant($merchant){ $fileList = scandir("COMPANY_LIST"); foreach($fileList as $fileName){ $authFileName = "COMPANY_LIST/$fileName/auth.php"; if(strpos($fileName,'.')===false && file_exists($authFileName)){ $fileContent = require_once($authFileName); if(isset($fileContent['jdMerchant']) &&$fileContent['jdMerchant'] == $merchant){ //将异步通知接口回传 $this->_notifyUrlArr = $fileContent['jdNotifyUrlArr']; $this->_notifyApiCode = $fileName; return $fileContent['jdDesKey']; } } } HelperService::returnJson(['code'=>200,'msg'=>'desKey is error','data'=>[]]); } }