ActionUrl = $url; } public function CnsPayVersion($ver) { $this->phpVersion = $ver; } public function CnsPayWebConnector($LogDir) { $this->cancelUrl = $this->ActionUrl."/lite/cancelProcess.jsp"; if (substr($LogDir, strlen($LogDir) - 1) == "/") { $LogDir = substr($LogDir, 0, strlen($LogDir) - 1); } @mkdir($LogDir); $this->LogPath = $LogDir."/"; } public function setRequestData($request) { try { foreach (array_keys($request) as $key) { if(is_array($request[$key])) continue; $this->requestData[$key] = iconv("UTF-8", "EUC-KR", $request[$key]); } return "_TRUE_"; } catch (Exception $ex) { $this->writeLog("setRequestData() Exception Code ".$ex->getCode()." : ".$ex->getMessage()." in ".$ex->getFile()." on line ".$ex->getLine()); return "_FAIL_"; } } public function addRequestData($key, $value) { try { $this->requestData[$key] = $value; return "_TRUE_"; } catch (Exception $ex) { $this->writeLog("addRequestData() Exception Code ".$ex->getCode()." : ".$ex->getMessage()." in ".$ex->getFile()." on line ".$ex->getLine()); return "_FAIL_"; } } public function getResultData($key) { try { if (!in_array($key, array_keys($this->resultData))) { return ""; } else if ($key == "Amt") { if ($this->resultData[$key] != null && $this->resultData[$key] != "null" && $this->resultData[$key] != "") { return $this->resultData[$key]; } else { return "0"; } } return $this->resultData[$key]; } catch (Exception $ex) { $this->writeLog("getResultData() Exception Code ".$ex->getCode()." : ".$ex->getMessage()." in ".$ex->getFile()." on line ".$ex->getLine()); return "_FAIL_"; } } // 2014.12.02 추가 (check key in array) private function getRequestData($key) { if (array_key_exists($key, $this->requestData)) { return $this->requestData[$key]; } else { return ""; } } public function requestAction() { $encodeKey = $this->requestData["EncodeKey"]; unset($this->requestData["EncodeKey"]); try { if ($this->requestData["actionType"] != "CL0" && $this->requestData["actionType"] != "CI0") { if ($this->getRequestData("PayMethod") != "ESCROW") { $this->requestData["TID"] = $this->generateTID($this->requestData["MID"], $this->getRequestData("PayMethod")); } } $serviceUrl = $this->setActionType($this->requestData["actionType"], $this->getRequestData("PayMethod")); if ($serviceUrl == "_FAIL_" || $serviceUrl == "CNSPAY_10") { $this->resultData["ResultCode"] = "JL10"; $this->resultData["ResultMsg"] = "actionType 설정이 잘못되었습니다."; return "_FAIL_"; } $this->writeLog("Request"); $this->writeLog($this->requestData); $requestMessage = $this->makeRequestText($this->requestData); $resultMessage = $this->connectToServer($serviceUrl, $requestMessage); $this->writeLog("Result"); // 2014.12.02 수신 전문 로깅 처리 제외 //$this->writeLog($resultMessage); if ($resultMessage == "_FAIL_" || substr($resultMessage, 0, 4) == "FAIL") { $resultCode = ""; $resultMsg = ""; $netCancelFlag = $this->requestNetCancel(); if ($netCancelFlag == "_TRUE_") { $resultCode = "JL32"; $resultMsg = "PGWEB서버 통신중 오류가 발생하였습니다. (NET_CANCEL)"; } else { // netCancel 실패이면, $resultCode = "JL33"; $resultMsg = "네트웍이 불안정으로 승인 실패하였습니다. 결제가 비 정상 처리 될 수 있으니 거래내역을 반드시 확인해주십시오."; } $this->resultData["ResultCode"] = $resultCode; $this->resultData["ResultMsg"] = $resultMsg; return "_FAIL_"; } $resultMessage = $this->parseResult($resultMessage); //$this->writeLog($this->resultData); // 2014.12.02 로깅 시 주요 데이터 마스킹 처리 $this->writeLog($this->resultDataMask($this->resultData)); if ($resultMessage == "_FAIL_" || $resultMessage == "CNSPAY_41") { $this->resultData["ResultCode"] = "JL41"; $this->resultData["ResultMsg"] = "응답전문이 없습니다."; return "_FAIL_"; } return "_TRUE_"; } catch (Exception $ex) { $this->writeLog("requestAction() Exception Code ".$ex->getCode()." : ".$ex->getMessage()." in ".$ex->getFile()." on line ".$ex->getLine()); return "_FAIL_"; } } // 2014.12.02 결과 배열 마스킹 private function resultDataMask($strLogText) { $arrMask = array(); if (is_array($strLogText)) { foreach (array_keys($strLogText) as $key) { $k = str_replace("\n", "", trim($key)); $arrMask[$k] = $this->requestMask($k, $strLogText[$key]); } return $arrMask; } else { return str_replace("\n", "", trim($strLogText)); } } // 2014.12.02 주요 정보 마스킹 private function requestMask ($name, $text) { $value = str_replace("\n", "", trim($text)); if ($value == null || strlen(trim($value)) == 0) return ""; if ($name == "X_CARDNO" || $name == "realPan" || $name == "cardNo" || $name == "CardBin" || $name == "CardNo") { return $this->masking($value, 6, true, false); } else if ($name == "BuyerName" || $name == "buyerName") { return $this->masking($value, 1, true, false); } else if ($name == "BuyerEmail") { return $this->masking($value, 6, false, true); } else if ($name == "BuyerTel" || $name == "DstAddr") { return $this->masking($value, 5, false, false); } else if ($name == "BuyerAddr") { return $this->masking($value, 6, true, false); } else if ($name == "UserIP" || $name == "MallIP" || $name == "CancelPwd" || $name == "mallUserID" || $name == "MallUserID" || $name == "CancelIP") { return $this->masking($value, mb_strlen(iconv('euc-kr','utf-8',$value), 'utf-8'), true, true); } else { return $value; } } // 2014.12.02 마스킹 처리 private function masking($string, $num, $isLeftOrder, $beginMasking) { if ( $string == null ) return ""; $res = ""; $res2 = ""; $sleng = 0; $str = iconv('euc-kr','utf-8',$string); $n = mb_strlen($str, 'utf-8'); if ( $num >= 1 ) { if ( $n < $num ) { $res = $str; } else { if($beginMasking) { if ($isLeftOrder) { $res = str_repeat("*", $n); } else { $sleng = $num; $res2 = mb_substr($str, $sleng, $n, 'utf-8'); for ( $j = 0; $j < $sleng; $j++ ) { $res .= "*"; } $res .= $res2; } } else { $sleng = $num; $res2 = mb_substr($str, 0, $sleng, 'utf-8'); for ( $j = $sleng; $j < $n; $j++ ) { $res .= "*"; } $res = $res2 . $res; } } } else { $res = $str; } return iconv('utf-8','euc-kr',$res); } private function requestNetCancel() { try { // 예기치 못한 오류인경우 망상취소 시도. $serviceUrl = $this->cancelUrl; $this->requestData["actionType"] = "CL0"; $this->requestData["CancelIP"] = $this->requestData["MallIP"]; if ($this->requestData["Amt"] == null) { return "_FAIL_"; } else { if (is_numeric($this->requestData["Amt"])) { $this->requestData["CancelAmt"] = $this->requestData["Amt"]; } else { $this->requestData["CancelAmt"] = parameterDecrypt($encodeKey, $this->requestData["Amt"]); } } $this->requestData["CancelMsg"] = "NICE_NET_CANCEL"; $this->requestData["PartialCancelCode"] = "0"; $this->requestData["NetCancelCode"] = "1"; if ($this->getRequestData("PayMethod") == "BILL" || $this->getRequestData("PayMethod") == "KAKAOPAY") $this->requestData["PayMethod"] = "CARD"; $requestMessage = makeRequestText($this->requestData); $resultMessage = connectToServer($serviceUrl, $this->requestData); if ($resultMessage == "_FAIL_" || substr($resultMessage, 0, 4) == "FAIL") { $resultMessage = connectToServer2($serviceUrl, $this->requestData, 20); if ($resultMessage == "_FAIL_" || substr($resultMessage, 0, 4) == "FAIL") { //$this->resultData["ResultCode"] = "JL41"; //$this->resultData["ResultMsg"] = "망상취소 오류"; return "_FAIL_"; } } return "_TRUE_"; } catch (Exception $ex) { $this->writeLog("requestNetCancel() Exception Code ".$ex->getCode()." : ".$ex->getMessage()." in ".$ex->getFile()." on line ".$ex->getLine()); return "_FAIL_"; } } private function generateTID($mid, $svcCd) { try { $iRandom = str_pad(rand(0, 9999), 4, "0", STR_PAD_LEFT); return $mid.$this->getSvcCd($svcCd)."01".date("ymdHis").$iRandom; } catch (Exception $ex) { $this->writeLog("generateTID() Exception Code ".$ex->getCode()." : ".$ex->getMessage()." in ".$ex->getFile()." on line ".$ex->getLine()); return "_FAIL_"; } } private function getSvcCd($svcCd) { try { if ($svcCd == "CARD" || $svcCd == "BILL" || $svcCd == "KAKAOPAY") { return "01"; } else if ($svcCd == "BANK") { return "02"; } else if ($svcCd == "VBANK") { return "03"; } else if ($svcCd == "CELLPHONE") { return "05"; } else if ($svcCd == "MOBILE_BILLING") { return "05"; } else if ($svcCd == "MOBILE_BILL") { return "05"; } return "00"; } catch (Exception $ex) { $this->writeLog("getSvcCd() Exception Code ".$ex->getCode()." : ".$ex->getMessage()." in ".$ex->getFile()." on line ".$ex->getLine()); return "_FAIL_"; } } private function setActionType($type, $paymethod) { try { if ($type == null) return "CNSPAY_10"; $builder = $this->ActionUrl; if ($type == "CL0") { $builder = $builder."/lite/cancelProcess.jsp"; } else if ($type == "CI0") { $builder = $builder."/lite/tidInfoProcess.jsp"; } else if ($type == "PY0") { if ($paymethod == "CASHRCPT") { // 현금영수증인경우 $builder = $builder."/lite/cashReceiptProcess.jsp"; } else if ($paymethod == "BILL") { $builder = $builder."/lite/billingProcess.jsp"; } else if ($paymethod == "BILLKEY") { $builder = $builder."/lite/billkeyProcess.jsp"; } else if ($paymethod == "ESCROW") { $builder = $builder."/lite/escrowProcess.jsp"; } else if ($paymethod == "MOBILE_AUTH") { $builder = $builder."/lite/mobileAuth.jsp"; } else if ($paymethod == "MOBILE_BILL") { $builder = $builder."/lite/mobileBill.jsp"; } else if ($paymethod == "MOBILE_BILLING") { $builder = $builder."/lite/mobileBillingProcess.jsp"; } else if ($paymethod == "MOBILE_AUTH_REQ") { $builder = $builder."/lite/mobileConfirmRequest.jsp"; } else if ($paymethod == "MOBILE_AUTH_RES") { $builder = $builder."/lite/mobileConfirmResult.jsp"; } else if ($paymethod == "CARD_ARS") { $builder = $builder."/lite/cardArsProcess.jsp"; } else if ($paymethod == "MOBILE_AUTH_NS") { $builder = $builder."/lite/mobileAuth_NS.jsp"; } else if ($paymethod == "OM_SUB_INS") { $builder = $builder."/lite/payproxy/subMallSetProcess.jsp"; } else if ($paymethod == "OM_SUB_PAY") { $builder = $builder."/lite/payproxy/subMallIcheProcess.jsp"; } else if ($paymethod == "LOTTE_POINT") { $builder = $builder."/api/checkLottePoint.jsp"; } else if ($paymethod == "HPBILLKEY") { $builder = $builder."/lite/hpBillkeyProcess.jsp"; } else if ($paymethod == "HPCARD_AUTH") { $builder = $builder."/lite/hpCardAuthProcess.jsp"; } else if ($paymethod == "HPCARD_BILLKEY") { $builder = $builder."/lite/hpCardBillkeyProcess.jsp"; } else { $builder = $builder."/lite/payProcess.jsp"; } } return $builder; } catch (Exception $ex) { $this->writeLog("setActionType() Exception Code ".$ex->getCode()." : ".$ex->getMessage()." in ".$ex->getFile()." on line ".$ex->getLine()); return "_FAIL_"; } } private function makeRequestText($reqData) { try { $strParameter = ""; foreach (array_keys($reqData) as $key) { $strParameter = $strParameter.$key."=".urlencode($reqData[$key])."&"; } $strParameter = substr($strParameter, 0, strlen($strParameter) - 1); return $strParameter; } catch (Exception $ex) { $this->writeLog("makeRequestText() Exception Code ".$ex->getCode()." : ".$ex->getMessage()." in ".$ex->getFile()." on line ".$ex->getLine()); return "_FAIL_"; } } private function connectToServer($urlStr, $reqData) { try { return $this->connectToServer2($urlStr, $reqData, 15); } catch (Exception $ex) { $this->writeLog("connectToServer() Exception Code ".$ex->getCode()." : ".$ex->getMessage()." in ".$ex->getFile()." on line ".$ex->getLine()); return "_FAIL_"; } } private function connectToServer2($urlStr, $reqData, $timeout) { try { // php에 cURL 모듈 설치 필요(리눅스 - curl.so, 윈도우 - php_curl.dll 확장모듈 필요) $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $urlStr); //접속할 URL 주소 //curl_setopt($ch, CURLOPT_PORT, 6464); //접속할 port, 주소에 있으므로 설정하지 않음 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 인증서 체크같은데 true 시 안되는 경우가 많다. //curl_setopt($ch, CURLOPT_SSLVERSION, 3); // SSL 버젼 (https 접속시에 필요, 기본값으로 해야하므로 설정하지 않음) curl_setopt($ch, CURLOPT_HEADER, 0); // 헤더 출력 여부 curl_setopt($ch, CURLOPT_POST, 1); // Post Get 접속 여부 curl_setopt($ch, CURLOPT_POSTFIELDS, $reqData); // Post 값 Get 방식처럼적는다. curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); // TimeOut 값 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 결과값을 받을것인지 curl_setopt($ch, CURLOPT_USERAGENT, $this->phpVersion); // 버전 $result = curl_exec($ch); $errcode = curl_error($ch); if ($errcode != "") $result = $errcode; //$errcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); //if ($errcode != 200) $result = $errcode; curl_close($ch); return $result; } catch (Exception $ex) { $this->writeLog("connectToServer2() Exception Code ".$ex->getCode()." : ".$ex->getMessage()." in ".$ex->getFile()." on line ".$ex->getLine()); return "_FAIL_"; } } private function parseResult($resultMessage) { try { if ($resultMessage == null) return "CNSPAY_41"; $parsedArr = explode("|", $resultMessage); foreach ($parsedArr as $valueArr) { $posit = strpos($valueArr, "="); $key = substr($valueArr, 0, $posit); $value = substr($valueArr, $posit + 1); $this->resultData[$key] = $value; } return "_TRUE_"; } catch (Exception $ex) { $this->writeLog("parseResult() Exception Code ".$ex->getCode()." : ".$ex->getMessage()." in ".$ex->getFile()." on line ".$ex->getLine()); return "_FAIL_"; } } public function writeLog($strLogText) { $log_string = ""; $exclude = array('MID', 'merchantEncKey', 'merchantHashKey', 'CancelPwd'); if (is_array($strLogText)) { $log_string = "[".date("Y/m/d H:i:s")."] \r\n"; foreach (array_keys($strLogText) as $key) { if(in_array($key, $exclude)) continue; $log_string = $log_string." [".$key."] => ".$strLogText[$key]."\r\n"; } } else { $log_string = "[".date("Y/m/d H:i:s")."] ".$strLogText."\r\n"; } $log_filenm = $this->LogPath.date("Ymd")."_CNSpay.log"; $log_file = fopen($log_filenm, "a"); if($log_file == false) return; flock($log_file, LOCK_EX); //fwrite($log_file, $log_string); fputs($log_file, $log_string); fflush($log_file); flock($log_file, LOCK_UN); fclose($log_file); } public function makeDateString($sDate) { try { if ($sDate == null) return ""; $strValue = ""; if (strlen($sDate) == 12) { $strValue = $strValue."20".substr($sDate, 0, 2)."-"; $strValue = $strValue.substr($sDate, 2, 2)."-"; $strValue = $strValue.substr($sDate, 4, 2). " "; $strValue = $strValue.substr($sDate, 6, 2).":"; $strValue = $strValue.substr($sDate, 8, 2).":"; $strValue = $strValue.substr($sDate, 10, 2); } else if (strlen($sDate) == 14) { $strValue = $strValue.substr($sDate, 0, 4)."-"; $strValue = $strValue.substr($sDate, 4, 2)."-"; $strValue = $strValue.substr($sDate, 6, 2)." "; $strValue = $strValue.substr($sDate, 8, 2).":"; $strValue = $strValue.substr($sDate, 10, 2).":"; $strValue = $strValue.substr($sDate, 12, 2); } else if (strlen($sDate) == 8) { $strValue = $strValue.substr($sDate, 0, 4)."-"; $strValue = $strValue.substr($sDate, 4, 2)."-"; $strValue = $strValue.substr($sDate, 6, 2); } else { $strValue = $sDate; } return $strValue; } catch (Exception $ex) { writeLog("makeDateString() Exception Code ".$ex->getCode()." : ".$ex->getMessage()." in ".$ex->getFile()." on line ".$ex->getLine()); return "_FAIL_"; } } public function makeHashInputString($salt) { $result = ""; for($count = 0;$count < strlen($salt)/2;$count++) { $temp0 = substr($salt, 2*$count, 2); $temp1 = hexdec($temp0); $temp3 = reset(unpack("l", pack("l", $temp1 +0xffffff00))); $temp4 = pack('C*', $temp3); $result = $result.$temp4; } return $result; } } ?>