나이스페이 결제 응답 검증 보강

(cherry picked from commit 50c2d6b6cfeaa10bbb65b2537a05c0525528cc63)
This commit is contained in:
thisgun
2026-08-24 07:44:22 +00:00
parent f7106379b8
commit a21f3103bb
10 changed files with 189 additions and 101 deletions
+12 -4
View File
@@ -117,10 +117,11 @@ if($authResultCode === "0000"){
$ResultCode = nicepay_res('ResultCode', $respArr);
$ResultMsg = nicepay_res('ResultMsg', $respArr);
$tno = nicepay_res('TID', $respArr);
$amount = (int) nicepay_res('Amt', $respArr, 0);
$app_time = nicepay_res('AuthDate', $respArr);
$pay_method = nicepay_res('PayMethod', $respArr);
$od_app_no = $app_no = nicepay_res('AuthCode', $respArr); // 승인 번호 (신용카드, 계좌이체, 휴대폰)
$response_amt = nicepay_res('Amt', $respArr, 0);
$amount = (int) $response_amt;
$app_time = nicepay_res('AuthDate', $respArr);
$pay_method = nicepay_res('PayMethod', $respArr);
$od_app_no = $app_no = nicepay_res('AuthCode', $respArr); // 승인 번호 (신용카드, 계좌이체, 휴대폰)
$pay_type = $NICEPAY_METHOD[$pay_method];
// 승인된 코드가 아니면 결제가 되지 않게 합니다.
@@ -129,6 +130,13 @@ if($authResultCode === "0000"){
die();
}
$responseSignature = nicepay_res('Signature', $respArr);
$responseSignData = bin2hex(hash('sha256', $tno . $mid . $response_amt . $merchantKey, true));
if ($responseSignature != $responseSignData) {
alert("승인 응답 유효성 검증이 틀려서 결제를 진행할수 없습니다.", G5_SHOP_URL);
}
if ($amount != $order_price) {
if($amount > 0) {
$od_id = $moid;
+6 -5
View File
@@ -71,10 +71,11 @@ function nicepay_create_signdata(frm)
var result = true;
$.ajax({
url: g5_url+"/shop/nicepay/createsigndata.php",
type: "POST",
data: {
price : frm.good_mny.value
},
type: "POST",
data: {
price : frm.good_mny.value,
moid : frm.Moid ? frm.Moid.value : ''
},
dataType: "json",
async: false,
cache: false,
@@ -137,4 +138,4 @@ function nicepay_create_signdata(frm)
<input type="hidden" name="comm_vat_mny" value="<?php echo $comm_vat_mny; ?>"> <!-- 부가세 -->
<input type="hidden" name="comm_free_mny" value="<?php echo $comm_free_mny; ?>"> <!-- 비과세 금액 -->
<?php } ?>
</form>
</form>
+24 -13
View File
@@ -3,12 +3,23 @@ include_once('./_common.php');
include_once(G5_MSHOP_PATH.'/settle_nicepay.inc.php');
$authResultCode = isset($_POST['AuthResultCode']) ? clean_xss_tags($_POST['AuthResultCode']) : ''; // authentication result code 0000:success
$authResultMsg = isset($_POST['AuthResultMsg']) ? clean_xss_tags($_POST['AuthResultMsg']) : ''; // authentication result message
$mid = isset($_POST['MID']) ? clean_xss_tags($_POST['MID']) : ''; // merchant id
$moid = isset($_POST['Moid']) ? addslashes(clean_xss_tags(stripslashes($_POST['Moid']))) : ''; // order number
$sql = " select * from {$g5['g5_shop_order_data_table']} where od_id = '$moid' ";
$row = sql_fetch($sql);
$authResultMsg = isset($_POST['AuthResultMsg']) ? clean_xss_tags($_POST['AuthResultMsg']) : ''; // authentication result message
$mid = isset($_POST['MID']) ? clean_xss_tags($_POST['MID']) : ''; // merchant id
$moid = isset($_POST['Moid']) ? addslashes(clean_xss_tags(stripslashes($_POST['Moid']))) : ''; // order number
if ($default['de_nicepay_mid'] != $mid) {
alert("요청한 상점 mid와 설정된 mid가 틀리므로 결제를 진행할수 없습니다.", G5_SHOP_URL);
}
$session_order_id = get_session('ss_order_id');
$session_personalpay_id = get_session('ss_personalpay_id');
if (!$moid || ($session_order_id != $moid && $session_personalpay_id != $moid)) {
alert("요청한 주문번호가 틀려서 결제를 진행할수 없습니다.", G5_SHOP_URL);
}
$sql = " select * from {$g5['g5_shop_order_data_table']} where od_id = '$moid' and dt_pg = 'nicepay' ";
$row = sql_fetch($sql);
if (empty($row)) {
die('');
@@ -19,12 +30,12 @@ $data = unserialize(base64_decode($row['dt_data']));
if(isset($data['pp_id']) && $data['pp_id']) {
$order_action_url = G5_HTTPS_MSHOP_URL.'/personalpayformupdate.php';
$page_return_url = G5_SHOP_URL.'/personalpayform.php?pp_id='.$data['pp_id'];
} else {
$order_action_url = G5_HTTPS_MSHOP_URL.'/orderformupdate.php';
$page_return_url = G5_SHOP_URL.'/orderform.php';
if($_SESSION['ss_direct'])
$page_return_url .= '?sw_direct=1';
}
} else {
$order_action_url = G5_HTTPS_MSHOP_URL.'/orderformupdate.php';
$page_return_url = G5_SHOP_URL.'/orderform.php';
if(isset($_SESSION['ss_direct']) && $_SESSION['ss_direct'])
$page_return_url .= '?sw_direct=1';
}
$params = array();
$var_datas = array();
@@ -84,4 +95,4 @@ if ($authResultCode === '0000') {
// 실패시
alert('오류 : '.$authResultMsg.' 코드 : '.$authResultCode, $page_return_url);
}
}
+4 -3
View File
@@ -1617,9 +1617,6 @@ function pay_approval()
f.TaxFreeAmt.value = pf.comm_free_mny.value;
<?php } ?>
if (! nicepay_create_signdata(f)) {
return false;
}
<?php } ?>
// 주문 정보 임시저장
@@ -1646,6 +1643,10 @@ function pay_approval()
<?php } ?>
<?php if ($default['de_pg_service'] == 'nicepay') { ?>
if (! nicepay_create_signdata(f)) {
return false;
}
nicepayStart(f);
return false;
<?php } ?>
+4 -4
View File
@@ -305,10 +305,6 @@ function pay_approval()
f.TaxFreeAmt.value = pf.comm_free_mny.value;
<?php } ?>
if (! nicepay_create_signdata(f)) {
return false;
}
<?php } ?>
//var new_win = window.open("about:blank", "tar_opener", "scrollbars=yes,resizable=yes");
@@ -338,6 +334,10 @@ function pay_approval()
<?php } ?>
<?php if($default['de_pg_service'] == 'nicepay') { ?>
if (! nicepay_create_signdata(f)) {
return false;
}
nicepayStart(f);
return;
+28 -14
View File
@@ -36,17 +36,31 @@ try{
'CharSet' => 'utf-8'
);
/*
****************************************************************************************
* <Cancel Request>
****************************************************************************************
*/
$response = nicepay_reqPost($data, "https://pg-api.nicepay.co.kr/webapi/cancel_process.jsp"); //Cancel API call
$result = json_decode($response, true);
}catch(Exception $e){
$e->getMessage();
$ResultCode = "9999";
$ResultMsg = "통신실패";
}
/*
****************************************************************************************
* <Cancel Request>
****************************************************************************************
*/
$response = nicepay_reqPost($data, "https://pg-api.nicepay.co.kr/webapi/cancel_process.jsp"); //Cancel API call
$result = json_decode($response, true);
if (isset($result['ResultCode'])) {
$responseTid = isset($result['TID']) ? $result['TID'] : $tid;
$responseCancelAmt = isset($result['CancelAmt']) ? $result['CancelAmt'] : $cancelAmt;
$responseSignature = isset($result['Signature']) ? $result['Signature'] : '';
$responseSignData = bin2hex(hash('sha256', $responseTid . $mid . $responseCancelAmt . $merchantKey, true));
if ($responseSignature != $responseSignData) {
$result['ResultCode'] = '9998';
$result['ResultMsg'] = '취소 응답 유효성 검증 실패';
}
}
}catch(Exception $e){
$e->getMessage();
$result = array(
'ResultCode' => '9999',
'ResultMsg' => '통신실패'
);
}
+43 -12
View File
@@ -2,31 +2,62 @@
include_once('./_common.php');
include_once(G5_SHOP_PATH.'/settle_nicepay.inc.php');
$orderNumber = get_session('ss_order_id');
$is_personalpay_order = false;
$session_order_id = get_session('ss_order_id');
$personalpay_id = get_session('ss_personalpay_id');
$orderNumber = (isset($_POST['moid']) && !is_array($_POST['moid'])) ? addslashes(clean_xss_tags(stripslashes($_POST['moid']))) : '';
$price_checked = false;
if (! $orderNumber) {
$orderNumber = get_session('ss_personalpay_id');
$is_personalpay_order = true;
if (!$orderNumber) {
$orderNumber = $session_order_id;
}
if (!$orderNumber) {
$orderNumber = $personalpay_id;
}
if (! ($default['de_pg_service'] == 'nicepay' && $orderNumber)){
die(json_encode(array('error'=>'올바른 방법으로 이용해 주십시오.')));
}
if ($session_order_id != $orderNumber && $personalpay_id != $orderNumber) {
die(json_encode(array('error'=>'주문 정보가 올바르지 않습니다.')));
}
if (! ($default['de_pg_service'] == 'nicepay' && $orderNumber)){
die(json_encode(array('error'=>'올바른 방법으로 이용해 주십시오.')));
}
$price = isset($_POST['price']) ? preg_replace('#[^0-9]#', '', $_POST['price']) : '';
$price = (isset($_POST['price']) && !is_array($_POST['price'])) ? preg_replace('#[^0-9]#', '', $_POST['price']) : '';
if (strlen($price) < 1) {
die(json_encode(array('error'=>'가격이 올바르지 않습니다.')));
}
if ($is_personalpay_order) {
$pp_id = preg_replace('/[^0-9]/', '', get_session('ss_personalpay_id'));
if ($orderNumber) {
$sql = " select dt_data from {$g5['g5_shop_order_data_table']} where od_id = '$orderNumber' and dt_pg = 'nicepay' ";
$row = sql_fetch($sql);
if (isset($row['dt_data']) && $row['dt_data']) {
$order_data = unserialize(base64_decode($row['dt_data']));
$order_price = (isset($order_data['good_mny'])) ? preg_replace('#[^0-9]#', '', $order_data['good_mny']) : '';
if (strlen($order_price) < 1 || (int)$order_price !== (int)$price) {
die(json_encode(array('error'=>'가격이 올바르지 않습니다.')));
}
$price_checked = true;
}
}
if (!$price_checked && $personalpay_id == $orderNumber) {
$pp_id = preg_replace('/[^0-9]/', '', $personalpay_id);
$pp = sql_fetch(" select pp_id, pp_price from {$g5['g5_shop_personalpay_table']} where pp_id = '$pp_id' and pp_use = '1' ");
if (! (isset($pp['pp_id']) && $pp['pp_id']) || (int)$pp['pp_price'] !== (int)$price) {
die(json_encode(array('error'=>'가격이 올바르지 않습니다.')));
}
$price_checked = true;
}
if (!$price_checked) {
die(json_encode(array('error'=>'주문 정보가 올바르지 않습니다.')));
}
$ediDate = preg_replace('/[^0-9]/', '', G5_TIME_YMDHIS);
+13 -5
View File
@@ -114,11 +114,12 @@ if($authResultCode === "0000"){
$ResultCode = nicepay_res('ResultCode', $respArr);
$ResultMsg = nicepay_res('ResultMsg', $respArr);
$tno = nicepay_res('TID', $respArr);
$amount = (int) nicepay_res('Amt', $respArr, 0);
$app_time = nicepay_res('AuthDate', $respArr);
$pay_method = nicepay_res('PayMethod', $respArr);
$od_app_no = $app_no = nicepay_res('AuthCode', $respArr); // 승인 번호 (신용카드, 계좌이체, 휴대폰)
$tno = nicepay_res('TID', $respArr);
$response_amt = nicepay_res('Amt', $respArr, 0);
$amount = (int) $response_amt;
$app_time = nicepay_res('AuthDate', $respArr);
$pay_method = nicepay_res('PayMethod', $respArr);
$od_app_no = $app_no = nicepay_res('AuthCode', $respArr); // 승인 번호 (신용카드, 계좌이체, 휴대폰)
$pay_type = $NICEPAY_METHOD[$pay_method];
// 승인된 코드가 아니면 결제가 되지 않게 합니다.
@@ -127,6 +128,13 @@ if($authResultCode === "0000"){
die();
}
$responseSignature = nicepay_res('Signature', $respArr);
$responseSignData = bin2hex(hash('sha256', $tno . $mid . $response_amt . $merchantKey, true));
if ($responseSignature != $responseSignData) {
alert("승인 응답 유효성 검증이 틀려서 결제를 진행할수 없습니다.", G5_SHOP_URL);
}
if ($amount != $order_price) {
if($amount > 0) {
$od_id = $moid;
+6 -5
View File
@@ -73,10 +73,11 @@ function nicepay_create_signdata(frm)
var result = true;
$.ajax({
url: g5_url+"/shop/nicepay/createsigndata.php",
type: "POST",
data: {
price : frm.good_mny.value
},
type: "POST",
data: {
price : frm.good_mny.value,
moid : frm.Moid ? frm.Moid.value : ''
},
dataType: "json",
async: false,
cache: false,
@@ -95,4 +96,4 @@ function nicepay_create_signdata(frm)
}
</script>
<?php }
<?php }
+49 -36
View File
@@ -31,56 +31,69 @@ if (in_array($_SERVER['REMOTE_ADDR'], $pg_allow_ips)) {
$VbankName = isset($_POST['VbankName']) ? addslashes(clean_xss_tags(stripslashes($_POST['VbankName']))) : ''; //가상계좌 은행명
$VbankInputName = isset($_POST['VbankInputName']) ? addslashes(clean_xss_tags(stripslashes($_POST['VbankInputName']))) : ''; //입금자 명
$CancelDate = isset($_POST['CancelDate']) ? addslashes(clean_xss_tags(stripslashes($_POST['CancelDate']))) : ''; //취소일시
//가상계좌채번시 현금영수증 자동발급신청이 되었을경우 전달되며
//가상계좌채번시 현금영수증 자동발급신청이 되었을경우 전달되며
//RcptTID 에 값이 있는경우만 발급처리 됨
$RcptTID = isset($_POST['RcptTID']) ? addslashes(clean_xss_tags(stripslashes($_POST['RcptTID']))) : ''; //현금영수증 거래번호
$RcptType = isset($_POST['RcptType']) ? addslashes(clean_xss_tags(stripslashes($_POST['RcptType']))) : ''; //현금 영수증 구분(0:미발행, 1:소득공제용, 2:지출증빙용)
$RcptAuthCode = isset($_POST['RcptAuthCode']) ? addslashes(clean_xss_tags(stripslashes($_POST['RcptAuthCode']))) : ''; //현금영수증 승인번호
// 입금통보 코드가 4110 성공이면
if ($ResultCode === '4110') {
// 입금결과 처리
$sql = " select pp_id, od_id from {$g5['g5_shop_personalpay_table']} where pp_id = '$MOID' and pp_app_no = '$VbankNum' ";
$sql = " select pp_id, od_id, pp_price from {$g5['g5_shop_personalpay_table']} where pp_id = '$MOID' and pp_app_no = '$VbankNum' ";
$row = sql_fetch($sql);
$result = false;
$is_personalpay_order = (isset($row['pp_id']) && $row['pp_id']);
$receipt_time = preg_replace("/([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})/", "\\1-\\2-\\3 \\4:\\5:\\6", $AuthDate);
if($row['pp_id']) {
// 개인결제 UPDATE
$sql = " update {$g5['g5_shop_personalpay_table']}
set pp_receipt_price = '$Amt',
pp_receipt_time = '$receipt_time'
where pp_id = '$MOID'
and pp_app_no = '$VbankNum' ";
$result = sql_query($sql, false);
if($is_personalpay_order) {
if((int)$row['pp_price'] === $Amt) {
// 개인결제 UPDATE
$sql = " update {$g5['g5_shop_personalpay_table']}
set pp_receipt_price = '$Amt',
pp_receipt_time = '$receipt_time'
where pp_id = '$MOID'
and pp_app_no = '$VbankNum' ";
$result = sql_query($sql, false);
if($row['od_id']) {
// 주문서 UPDATE
$sql = " update {$g5['g5_shop_order_table']}
set od_receipt_price = od_receipt_price + '$Amt',
od_receipt_time = '$receipt_time',
od_shop_memo = concat(od_shop_memo, \"\\n개인결제 ".$row['pp_id']." 로 결제완료 - ".$receipt_time."\")
where od_id = '{$row['od_id']}'
and od_status = '주문'
and od_cancel_price = '0' ";
$result = sql_query($sql, FALSE);
}
} else {
// 주문서 UPDATE
$sql = " update {$g5['g5_shop_order_table']}
set od_receipt_price = '$Amt',
od_receipt_time = '$receipt_time'
where od_id = '$MOID'
and od_app_no = '$VbankNum'
and od_status = '주문'
and od_cancel_price = '0' ";
$result = sql_query($sql, FALSE);
}
if($row['od_id']) {
// 주문서 UPDATE
$sql = " update {$g5['g5_shop_order_table']}
set od_receipt_price = od_receipt_price + '$Amt',
od_receipt_time = '$receipt_time',
od_shop_memo = concat(od_shop_memo, \"\\n개인결제 ".$row['pp_id']." 로 결제완료 - ".$receipt_time."\")
where od_id = '{$row['od_id']}'
and od_status = '주문'
and od_cancel_price = '0' ";
$result = sql_query($sql, FALSE);
}
}
} else {
$sql = " select od_id, od_misu
from {$g5['g5_shop_order_table']}
where od_id = '$MOID'
and od_app_no = '$VbankNum'
and od_status = '주문'
and od_cancel_price = '0' ";
$od_row = sql_fetch($sql);
if(isset($od_row['od_id']) && $od_row['od_id'] && (int)$od_row['od_misu'] === $Amt) {
// 주문서 UPDATE
$sql = " update {$g5['g5_shop_order_table']}
set od_receipt_price = '$Amt',
od_receipt_time = '$receipt_time'
where od_id = '$MOID'
and od_app_no = '$VbankNum'
and od_status = '주문'
and od_cancel_price = '0' ";
$result = sql_query($sql, FALSE);
}
}
if($result) {
if ($row['od_id'])
if (isset($row['od_id']) && $row['od_id'])
$od_id = $row['od_id'];
else
$od_id = $MOID;
@@ -95,7 +108,7 @@ if (in_array($_SERVER['REMOTE_ADDR'], $pg_allow_ips)) {
if($row['cnt'] == 1) {
// 미수금 정보 업데이트
$info = get_order_info($od_id);
$add_update_sql = '';
// 현금영수증 발급시 1 또는 2 이면