본문으로 건너뛰기

예치금·마일리지 포함 주문 환불 처리 안정성 개선

PHP 8 · GODO26
변경 파일 수: 2개
변경 파일 목록
총 2개
변경 파일 코드
추가삭제
Admin/order/refund_do_new.php+6-3
변경 전refund_do_new.php
if ($(this).val() == '') {
$(this).val(0);
}
if ($.isNumeric($(this).val())) {
refundPriceSum += parseInt($(this).val());
lessEachRefund = lessRefundPrice + parseInt($(this).val());
 
 
 
} else {
$(this).focus();
}
 
변경 후refund_do_new.php
if ($(this).val() == '') {
$(this).val(0);
}
// 콤마만 제거한 값으로 합계 검증 - 콤마 포함 값은 $.isNumeric 을 우회해 그대로 전송된다.
// (소수점은 제거하지 않는다 - decimal "75900.00" 의 소수점을 지우면 ×100)
var refundPriceVal = String($(this).val()).replace(/,/g, '');
if ($.isNumeric(refundPriceVal)) {
refundPriceSum += parseInt(refundPriceVal);
lessEachRefund = lessRefundPrice + parseInt(refundPriceVal);
} else {
$(this).focus();
}
 
Component/Order/ReOrderCalculation.php+68
변경 전ReOrderCalculation.php
{
use CommonLogStorageTrait; // 공용 로그 저장
 
 
 
 
/**
* @var null|object 디비 접속
*/
}
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public function setRefundCompleteOrderGoodsNew($getData, $autoProcess = false, $userHandleFl = false)
{
$goods = \App::load(\Component\Goods\Goods::class);
$orderAdmin = App::load(\Component\Order\OrderAdmin::class);
 
 
 
 
 
 
 
 
 
// 환불수단에 맞지않는 금액값이 넘어오면 리턴처리
if ($getData['info']['refundMethod'] == '현금환불') {
if ($getData['info']['completePgPrice'] > 0 || $getData['info']['completeDepositPrice'] > 0 || $getData['info']['completeMileagePrice'] > 0) {
}
$checkDivisionVal = 0;
do {
 
foreach ($arrayData as $k => $v) {
if ($checkKey != '') {
if (isset($v['orderDeliverySno']) && $checkKey != '' && $checkKey != $v['orderDeliverySno']) {
}
}
}
 
 
 
 
 
 
 
 
 
 
 
 
} while ($checkDivisionVal == 0);
}
 
$checkDivisionVal = 1;
 
do {
 
 
 
// free supply vat 순으로 체크하면서 오버되면 재분배
if ($orgTotalData['realTaxFreePrice'] < $tempTaxFreeSum) { // 환불 업데이트 free 합계값이 오버인경우
// 오버값
$checkDivisionVal = 0;
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
} while ($checkDivisionVal == 1);
 
return [$updateDeliveryData, $refundDeliveryData];
 
변경 후ReOrderCalculation.php
{
use CommonLogStorageTrait; // 공용 로그 저장
 
// 환불 방법 설정의 결제수단별 완료 환불 금액 입력 키 (산술 처리 전 정규화 대상)
const REFUND_COMPLETE_PRICE_KEYS = ['completeCashPrice', 'completePgPrice', 'completeDepositPrice', 'completeMileagePrice'];
 
/**
* @var null|object 디비 접속
*/
}
}
 
/**
* 환불 금액을 산술 처리 가능한 정수로 정규화한다.
*
* 콤마만 제거하고 소수점은 보존한다. 비숫자를 일괄 제거하면 decimal(12,2) 값
* "75900.00" 의 소수점까지 지워져 ×100 이 된다.
*
* @param string|int|float $completePrice 환불 금액 입력값
* @return int
* @throws Exception 숫자가 아니거나 음수인 경우
*/
protected function normalizeRefundCompletePrice(string|int|float $completePrice): int
{
$normalizedPrice = trim(str_replace(',', '', (string)$completePrice));
 
if ($normalizedPrice === '') {
return 0;
}
if (!is_numeric($normalizedPrice)) {
throw new Exception(__('환불 금액을 숫자로 확인할 수 없습니다. 다시 확인해주세요.'));
}
if ((float)$normalizedPrice < 0) {
throw new Exception(__('환불 금액은 0 보다 작을 수 없습니다. 다시 확인해주세요.'));
}
 
// 소수부 절사 ("75900.00" → 75900)
return (int)(float)$normalizedPrice;
}
 
public function setRefundCompleteOrderGoodsNew($getData, $autoProcess = false, $userHandleFl = false)
{
$goods = \App::load(\Component\Goods\Goods::class);
$orderAdmin = App::load(\Component\Order\OrderAdmin::class);
 
// 콤마가 섞인 값("347,180")은 형변환 시 347 로 잘려 안분 합계가 어긋나 무한루프를 유발한다.
foreach (self::REFUND_COMPLETE_PRICE_KEYS as $completePriceKey) {
if (!isset($getData['info'][$completePriceKey])) {
continue;
}
$getData['info'][$completePriceKey] = $this->normalizeRefundCompletePrice($getData['info'][$completePriceKey]);
}
 
// 환불수단에 맞지않는 금액값이 넘어오면 리턴처리
if ($getData['info']['refundMethod'] == '현금환불') {
if ($getData['info']['completePgPrice'] > 0 || $getData['info']['completeDepositPrice'] > 0 || $getData['info']['completeMileagePrice'] > 0) {
}
$checkDivisionVal = 0;
do {
$beforeDivisionVal = $tempDivisionVal;
foreach ($arrayData as $k => $v) {
if ($checkKey != '') {
if (isset($v['orderDeliverySno']) && $checkKey != '' && $checkKey != $v['orderDeliverySno']) {
}
}
}
// 무한루프 방지: 1회 순회 동안 차액이 줄지 않으면 더 안분할 항목이 없으므로 종료한다.
if ($checkDivisionVal === 0 && $tempDivisionVal === $beforeDivisionVal) {
// 안분이 덜 된 상태로 환불이 진행되므로 error 로 남긴다. (추적용으로 대상 키를 함께 기록)
\Logger::channel('order')->error(__METHOD__ . '[' . __LINE__ . '], 안분 차액을 맞출 수 없어 루프 종료(무한루프 방지): ', [
'strText' => $strText,
'remainDivisionVal' => $tempDivisionVal,
'divisionSum' => $divisionSum,
'orgPrice' => $orgPrice,
'divisionKeys' => array_keys($arrayData),
]);
break;
}
} while ($checkDivisionVal == 0);
}
 
$checkDivisionVal = 1;
 
do {
// 무한루프 방지용 직전 순회 tax 합계 (변화가 없으면 재분배 불가로 보고 종료)
$beforeDivisionSignature = $tempTaxSupplySum . STR_DIVISION . $tempTaxVatSum . STR_DIVISION . $tempTaxFreeSum;
 
// free supply vat 순으로 체크하면서 오버되면 재분배
if ($orgTotalData['realTaxFreePrice'] < $tempTaxFreeSum) { // 환불 업데이트 free 합계값이 오버인경우
// 오버값
$checkDivisionVal = 0;
}
 
// 재분배 후에도 tax 합계가 동일하면 진행이 없는 상태이므로 종료
if ($checkDivisionVal === 1 && $beforeDivisionSignature === ($tempTaxSupplySum . STR_DIVISION . $tempTaxVatSum . STR_DIVISION . $tempTaxFreeSum)) {
// 배송비 tax 안분이 덜 된 상태로 환불이 진행되므로 error 로 남긴다. (추적용으로 대상 키를 함께 기록)
\Logger::channel('order')->error(__METHOD__ . '[' . __LINE__ . '], 배송비 tax 안분이 수렴하지 않아 루프 종료(무한루프 방지): ', [
'orgTotalData' => $orgTotalData,
'tempTaxSupplySum' => $tempTaxSupplySum,
'tempTaxVatSum' => $tempTaxVatSum,
'tempTaxFreeSum' => $tempTaxFreeSum,
'deliveryKeys' => array_keys($refundDeliveryData),
]);
break;
}
 
} while ($checkDivisionVal == 1);
 
return [$updateDeliveryData, $refundDeliveryData];