469 lines
20 KiB
PHP
469 lines
20 KiB
PHP
<?php
|
|
// 버전 1.0 : 2014/11/06 문석호, 최초 작성
|
|
/**
|
|
* 2014.12.02 : 1) 로깅 시 주요 정보 마스킹 처리, 2) PayMethod key check
|
|
*/
|
|
class CnsPayWebConnector {
|
|
private $LogPath = "";
|
|
private $ActionUrl = "";
|
|
private $cancelUrl = "";
|
|
private $phpVersion = "";
|
|
private $encodeKey = "";
|
|
private $requestData = array();
|
|
private $resultData = array();
|
|
public function CnsActionUrl($url) {
|
|
$this->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 = "";
|
|
if (is_array($strLogText)) {
|
|
$log_string = "[".date("Y/m/d H:i:s")."] \r\n";
|
|
foreach (array_keys($strLogText) as $key) {
|
|
$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;
|
|
|
|
}
|
|
|
|
}
|
|
?>
|