나이스페이 결제 검증 및 취소 처리 보강

(cherry picked from commit 1e03160280e0a6b23e9d4b01a8bd726bddccf2cd)
This commit is contained in:
thisgun
2026-08-24 07:44:22 +00:00
parent f4d184979f
commit f7106379b8
9 changed files with 174 additions and 85 deletions
+1 -1
View File
@@ -208,7 +208,7 @@ function is_cancel_shop_pg_order($od){
$is_od_pg_cancel = true;
}
if ($od['od_pg'] === 'nicepay' && in_array($od['od_settle_case'], array('계좌이체', '휴대폰'))) {
if ($od['od_pg'] === 'nicepay' && (in_array($od['od_settle_case'], array('계좌이체', '휴대폰')) || ($od['od_settle_case'] === '가상계좌' && $od['od_status'] === '주문'))) {
$is_od_pg_cancel = true;
}
+8 -1
View File
@@ -385,11 +385,18 @@ if (in_array($_POST['ct_status'], $status_cancel)) {
$tno = $od['od_tno'];
$cancelAmt = $od['od_receipt_price'];
$cancelAmt = (int)$od['od_receipt_price'];
if($od['od_settle_case'] == '가상계좌' && $od['od_status'] == '주문' && $cancelAmt == 0)
$cancelAmt = (int)$od['od_misu'];
// 0:전체 취소, 1:부분 취소(별도 계약 필요)
$partialCancelCode = 0;
if($cancelAmt <= 0) {
$pg_res_cd = '';
$pg_res_msg = '취소 요청금액이 없습니다.';
break;
}
include G5_SHOP_PATH.'/nicepay/cancel_process.php';
+25
View File
@@ -20,6 +20,7 @@ $moid = isset($_POST['Moid']) ? addslashes(clean_xss_tags(stripslashes($_POST['M
$amt = isset($_POST['Amt']) ? (int) preg_replace('/[^0-9]/', '', $_POST['Amt']) : 0; // Amount of payment
$reqReserved = isset($_POST['ReqReserved']) ? clean_xss_tags($_POST['ReqReserved']) : ''; // mall custom field
$netCancelURL = isset($_POST['NetCancelURL']) ? clean_xss_tags($_POST['NetCancelURL']) : ''; // netCancelURL
$Signature = isset($_POST['Signature']) ? clean_xss_tags($_POST['Signature']) : ''; // authentication signature
if (isset($pp['pp_id']) && $pp['pp_id']) { //개인결제
$session_order_id = get_session('ss_personalpay_id');
@@ -40,6 +41,13 @@ if ($order_price != $amt) {
alert("요청한 결제금액이 틀리므로 결제를 진행할수 없습니다.", G5_SHOP_URL);
}
// hex(sha256(AuthToken+MID+Amt+MerchantKey)), 위변조 검증 데이터
$authSignData = bin2hex(hash('sha256', $authToken. $default['de_nicepay_mid'] . $order_price . $default['de_nicepay_key'], true));
if ($Signature != $authSignData) {
alert("유효성 검증이 틀려서 결제를 진행할수 없습니다.");
}
// API CALL foreach example
if (! function_exists('jsonRespDump')) {
function jsonRespDump($resp){
@@ -99,6 +107,11 @@ if($authResultCode === "0000"){
// https://developers.nicepay.co.kr/manual-auth.php
*/
$response = nicepay_reqPost($data, $nextAppURL);
if (! $response) {
alert('응답이 없거나 잘못된 url 입니다.', G5_SHOP_URL);
}
$respArr = json_decode($response, true);
$ResultCode = nicepay_res('ResultCode', $respArr);
@@ -116,6 +129,18 @@ if($authResultCode === "0000"){
die();
}
if ($amount != $order_price) {
if($amount > 0) {
$od_id = $moid;
$cancel_msg = '결제금액 불일치';
$cancelAmt = $amount;
$partialCancelCode = 0;
include G5_SHOP_PATH.'/nicepay/cancel_process.php';
}
alert("승인된 결제금액이 틀리므로 결제를 진행할수 없습니다.", G5_SHOP_URL);
}
if ($ResultCode == '3001') { // 신용카드
$card_cd = nicepay_res('CardCode', $respArr); // 카드사 코드
+14
View File
@@ -244,6 +244,13 @@ if(!$result) {
case 'inicis':
include G5_SHOP_PATH.'/inicis/inipay_cancel.php';
break;
case 'nicepay':
$od_id = $pp['pp_id'];
$tno = $pp_tno;
$cancelAmt = (int)$pg_price;
$partialCancelCode = 0;
include G5_SHOP_PATH.'/nicepay/cancel_process.php';
break;
default:
include G5_SHOP_PATH.'/kcp/pp_ax_hub_cancel.php';
break;
@@ -288,6 +295,13 @@ if($pp_receipt_price > 0 && $pp['pp_id'] && $pp['od_id']) {
case 'inicis':
include G5_SHOP_PATH.'/inicis/inipay_cancel.php';
break;
case 'nicepay':
$od_id = $pp['pp_id'];
$tno = $pp_tno;
$cancelAmt = (int)$pg_price;
$partialCancelCode = 0;
include G5_SHOP_PATH.'/nicepay/cancel_process.php';
break;
default:
include G5_SHOP_PATH.'/kcp/pp_ax_hub_cancel.php';
break;
+12 -1
View File
@@ -3,21 +3,32 @@ include_once('./_common.php');
include_once(G5_SHOP_PATH.'/settle_nicepay.inc.php');
$orderNumber = get_session('ss_order_id');
$is_personalpay_order = false;
if (! $orderNumber) {
$orderNumber = get_session('ss_personalpay_id');
$is_personalpay_order = true;
}
if (! ($default['de_pg_service'] == 'nicepay' && $orderNumber)){
die(json_encode(array('error'=>'올바른 방법으로 이용해 주십시오.')));
}
$price = preg_replace('#[^0-9]#', '', $_POST['price']);
$price = isset($_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'));
$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'=>'가격이 올바르지 않습니다.')));
}
}
$ediDate = preg_replace('/[^0-9]/', '', G5_TIME_YMDHIS);
$hashString = bin2hex(hash('sha256', $ediDate.$default['de_nicepay_mid'].$price.$default['de_nicepay_key'], true));
+12
View File
@@ -127,6 +127,18 @@ if($authResultCode === "0000"){
die();
}
if ($amount != $order_price) {
if($amount > 0) {
$od_id = $moid;
$cancel_msg = '결제금액 불일치';
$cancelAmt = $amount;
$partialCancelCode = 0;
include G5_SHOP_PATH.'/nicepay/cancel_process.php';
}
alert("승인된 결제금액이 틀리므로 결제를 진행할수 없습니다.", G5_SHOP_URL);
}
if ($ResultCode == '3001') { // 신용카드
$card_cd = nicepay_res('CardCode', $respArr); // 카드사 코드
+5 -3
View File
@@ -71,16 +71,18 @@ $useOpt = $useopt;// 현금영수증 발행용도 ("1" - 소비자 소득
$regNum = $reg_num;// 현금결제자 주민등록번호
$ediDate = preg_replace('/[^0-9]/', '', G5_TIME_YMDHIS);
$moid = ($tx == 'personalpay') ? $od['pp_id'] : $od['od_id'];
$receipt_tax_free_amt = ($tx == 'personalpay') ? 0 : (int)$od['od_free_mny'];
// 04 (현금영수증), 01 (매체구분 일반), 시간정보 (12자리), 랜덤 4자리숫자
$tid = $default['de_nicepay_mid'].'04'.'01'.substr($ediDate, 2).rand(1000, 9999);
$signData = bin2hex(hash('sha256', $default['de_nicepay_mid'].$amt_tot.$ediDate.$od['od_id'].$default['de_nicepay_key'], true));
$signData = bin2hex(hash('sha256', $default['de_nicepay_mid'].$amt_tot.$ediDate.$moid.$default['de_nicepay_key'], true));
$data = array(
'MID' => $default['de_nicepay_mid'],
'TID' => $tid,
'EdiDate' => $ediDate,
'Moid' => $od['od_id'],
'Moid' => $moid,
'SignData' => $signData,
'GoodsName' => iconv('utf-8', 'euc-kr', $goodName),
'ReceiptAmt' => $amt_tot,
@@ -89,7 +91,7 @@ $data = array(
'ReceiptSupplyAmt' => $supPrice,
'ReceiptVAT' => $tax,
'ReceiptServiceAmt' => $srcvPrice,
'ReceiptTaxFreeAmt' => (int)$od['od_free_mny'],
'ReceiptTaxFreeAmt' => $receipt_tax_free_amt,
'CharSet' => 'utf-8',
);
+14
View File
@@ -222,6 +222,13 @@ if(!$result) {
case 'inicis':
include G5_SHOP_PATH.'/inicis/inipay_cancel.php';
break;
case 'nicepay':
$od_id = $pp['pp_id'];
$tno = $pp_tno;
$cancelAmt = (int)$pg_price;
$partialCancelCode = 0;
include G5_SHOP_PATH.'/nicepay/cancel_process.php';
break;
default:
include G5_SHOP_PATH.'/kcp/pp_ax_hub_cancel.php';
break;
@@ -266,6 +273,13 @@ if($pp_receipt_price > 0 && $pp['pp_id'] && $pp['od_id']) {
case 'inicis':
include G5_SHOP_PATH.'/inicis/inipay_cancel.php';
break;
case 'nicepay':
$od_id = $pp['pp_id'];
$tno = $pp_tno;
$cancelAmt = (int)$pg_price;
$partialCancelCode = 0;
include G5_SHOP_PATH.'/nicepay/cancel_process.php';
break;
default:
include G5_SHOP_PATH.'/kcp/pp_ax_hub_cancel.php';
break;
+6 -2
View File
@@ -62,7 +62,9 @@ if (in_array($_SERVER['REMOTE_ADDR'], $pg_allow_ips)) {
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']}' ";
where od_id = '{$row['od_id']}'
and od_status = '주문'
and od_cancel_price = '0' ";
$result = sql_query($sql, FALSE);
}
} else {
@@ -71,7 +73,9 @@ if (in_array($_SERVER['REMOTE_ADDR'], $pg_allow_ips)) {
set od_receipt_price = '$Amt',
od_receipt_time = '$receipt_time'
where od_id = '$MOID'
and od_app_no = '$VbankNum' ";
and od_app_no = '$VbankNum'
and od_status = '주문'
and od_cancel_price = '0' ";
$result = sql_query($sql, FALSE);
}