516 lines
25 KiB
PHP
516 lines
25 KiB
PHP
<?php
|
|
/**
|
|
* 계좌 입출금내역 조회 API (GetPeriodBankAccountLog)
|
|
*/
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
require_once('barobill_account_config.php');
|
|
|
|
try {
|
|
$startDate = isset($_GET['startDate']) ? $_GET['startDate'] : date('Ymd');
|
|
$endDate = isset($_GET['endDate']) ? $_GET['endDate'] : date('Ymd');
|
|
$bankAccountNum = isset($_GET['accountNum']) ? $_GET['accountNum'] : ''; // 특정 계좌만 조회 시, 빈 값이면 전체 계좌
|
|
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
|
|
$limit = isset($_GET['limit']) ? intval($_GET['limit']) : 50;
|
|
|
|
// 바로빌 사용자 ID (설정 파일에서 로드)
|
|
$userId = getBarobillUserId();
|
|
|
|
// 계좌번호 하이픈 제거
|
|
$bankAccountNum = str_replace('-', '', $bankAccountNum);
|
|
|
|
// 전체 계좌 조회: 빈 값이면 모든 계좌의 거래 내역을 조회
|
|
if (empty($bankAccountNum)) {
|
|
// 먼저 등록된 계좌 목록 가져오기
|
|
$accountResult = callBarobillAccountSOAP('GetBankAccountEx', [
|
|
'AvailOnly' => 0 // 전체 계좌
|
|
]);
|
|
|
|
if ($accountResult['success']) {
|
|
$accountData = $accountResult['data'];
|
|
$accountList = [];
|
|
|
|
// BankAccount 또는 BankAccountEx에서 계좌 목록 추출
|
|
if (isset($accountData->BankAccount)) {
|
|
if (is_array($accountData->BankAccount)) {
|
|
$accountList = $accountData->BankAccount;
|
|
} else if (is_object($accountData->BankAccount)) {
|
|
$accountList = [$accountData->BankAccount];
|
|
}
|
|
} else if (isset($accountData->BankAccountEx)) {
|
|
if (is_array($accountData->BankAccountEx)) {
|
|
$accountList = $accountData->BankAccountEx;
|
|
} else if (is_object($accountData->BankAccountEx)) {
|
|
$accountList = [$accountData->BankAccountEx];
|
|
}
|
|
}
|
|
|
|
// 각 계좌별로 거래 내역 조회
|
|
$allLogs = [];
|
|
$allSummary = ['totalDeposit' => 0, 'totalWithdraw' => 0, 'count' => 0];
|
|
$debugAllAccounts = [];
|
|
|
|
foreach ($accountList as $accIndex => $acc) {
|
|
if (!is_object($acc)) continue;
|
|
|
|
$accNum = $acc->BankAccountNum ?? '';
|
|
if (empty($accNum) || (is_numeric($accNum) && $accNum < 0)) {
|
|
continue; // 에러 코드 스킵
|
|
}
|
|
|
|
// 각 계좌의 거래 내역 조회
|
|
$accResult = callBarobillAccountSOAP('GetPeriodBankAccountTransLog', [
|
|
'ID' => $userId,
|
|
'BankAccountNum' => $accNum,
|
|
'StartDate' => $startDate,
|
|
'EndDate' => $endDate,
|
|
'TransDirection' => 1,
|
|
'CountPerPage' => 1000, // 전체 조회를 위해 큰 값 사용
|
|
'CurrentPage' => 1,
|
|
'OrderDirection' => 2
|
|
]);
|
|
|
|
if ($accResult['success']) {
|
|
$accData = $accResult['data'];
|
|
|
|
// 에러 코드 체크
|
|
$errorCode = null;
|
|
if (isset($accData->CurrentPage) && is_numeric($accData->CurrentPage) && $accData->CurrentPage < 0) {
|
|
$errorCode = $accData->CurrentPage;
|
|
} elseif (isset($accData->BankAccountNum) && is_numeric($accData->BankAccountNum) && $accData->BankAccountNum < 0) {
|
|
$errorCode = $accData->BankAccountNum;
|
|
}
|
|
|
|
// -25005, -25001은 데이터 없음 (정상)
|
|
if (!$errorCode || ($errorCode == -25005 || $errorCode == -25001)) {
|
|
// 거래 내역 파싱
|
|
if (isset($accData->BankAccountLogList) && isset($accData->BankAccountLogList->BankAccountTransLog)) {
|
|
$rawLogs = is_array($accData->BankAccountLogList->BankAccountTransLog)
|
|
? $accData->BankAccountLogList->BankAccountTransLog
|
|
: [$accData->BankAccountLogList->BankAccountTransLog];
|
|
|
|
foreach ($rawLogs as $log) {
|
|
$deposit = floatval($log->Deposit ?? 0);
|
|
$withdraw = floatval($log->Withdraw ?? 0);
|
|
|
|
// 거래일시 파싱: TransDT 필드 사용 (YYYYMMDDHHmmss 형식)
|
|
$transDT = $log->TransDT ?? '';
|
|
$transDate = '';
|
|
$transTime = '';
|
|
$dateTime = '';
|
|
|
|
if (!empty($transDT) && strlen($transDT) >= 14) {
|
|
// TransDT: "20251203100719" -> "2025-12-03 10:07:19"
|
|
$transDate = substr($transDT, 0, 8); // YYYYMMDD
|
|
$transTime = substr($transDT, 8, 6); // HHmmss
|
|
$dateTime = substr($transDT, 0, 4) . '-' . substr($transDT, 4, 2) . '-' . substr($transDT, 6, 2) . ' ' .
|
|
substr($transDT, 8, 2) . ':' . substr($transDT, 10, 2) . ':' . substr($transDT, 12, 2);
|
|
} else {
|
|
// 기존 방식도 지원 (다양한 필드명 확인)
|
|
$transDate = $log->TransDate ?? $log->TradeDate ?? $log->Date ?? '';
|
|
$transTime = $log->TransTime ?? $log->TradeTime ?? $log->Time ?? '';
|
|
|
|
if (!empty($transDate) && !empty($transTime)) {
|
|
$dateStr = (string)$transDate;
|
|
$timeStr = (string)$transTime;
|
|
|
|
if (strlen($dateStr) == 8 && strlen($timeStr) >= 4) {
|
|
$dateTime = substr($dateStr, 0, 4) . '-' . substr($dateStr, 4, 2) . '-' . substr($dateStr, 6, 2) . ' ' .
|
|
substr($timeStr, 0, 2) . ':' . substr($timeStr, 2, 2);
|
|
if (strlen($timeStr) >= 6) {
|
|
$dateTime .= ':' . substr($timeStr, 4, 2);
|
|
}
|
|
} elseif (strlen($dateStr) == 10 && strpos($dateStr, '-') !== false) {
|
|
$dateTime = $dateStr . ' ' . substr($timeStr, 0, 2) . ':' . substr($timeStr, 2, 2);
|
|
if (strlen($timeStr) >= 6) {
|
|
$dateTime .= ':' . substr($timeStr, 4, 2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 적요 파싱: TransRemark1 필드 사용
|
|
$summary = $log->TransRemark1 ?? $log->Summary ?? $log->Content ?? $log->Description ?? $log->Remark ?? $log->Note ?? '';
|
|
|
|
// 추가 적요 정보: TransRemark2
|
|
$remark2 = $log->TransRemark2 ?? '';
|
|
|
|
// 거래 유형: TransType (예: CC)
|
|
$transType = $log->TransType ?? '';
|
|
|
|
// 거래 방향: TransDirection (예: 입금, 출금)
|
|
$transDirection = $log->TransDirection ?? '';
|
|
|
|
// 취급점: TransOffice
|
|
$transOffice = $log->TransOffice ?? '';
|
|
|
|
// 적요 정보 결합
|
|
$fullSummary = $summary;
|
|
if (!empty($remark2)) {
|
|
$fullSummary = (!empty($fullSummary) ? $fullSummary . ' ' . $remark2 : $remark2);
|
|
}
|
|
if (!empty($transType)) {
|
|
$fullSummary = (!empty($fullSummary) ? $fullSummary . ' (' . $transType . ')' : '(' . $transType . ')');
|
|
}
|
|
|
|
// 보낸분/받는분 정보 (기존 필드명도 지원)
|
|
$cast = $log->Cast ?? $log->Counterpart ?? $log->Opponent ?? $log->Name ?? '';
|
|
|
|
// 취급점/수단 정보
|
|
$branch = $transOffice ?: ($log->Branch ?? $log->HandlingBranch ?? $log->Method ?? '');
|
|
|
|
// 디버그: 첫 번째 계좌의 첫 번째 로그 정보 저장
|
|
if ($accIndex === 0 && empty($debugAllAccounts)) {
|
|
$debugAllAccounts['first_account_first_log'] = [
|
|
'account_num' => $accNum,
|
|
'log_raw_fields' => [],
|
|
'parsed' => [
|
|
'transDate' => $transDate,
|
|
'transTime' => $transTime,
|
|
'transDateTime' => $dateTime,
|
|
'summary' => $summary,
|
|
'fullSummary' => $fullSummary,
|
|
'cast' => $cast,
|
|
'branch' => $branch
|
|
]
|
|
];
|
|
// 원본 로그의 모든 필드 저장
|
|
foreach ($log as $key => $value) {
|
|
$debugAllAccounts['first_account_first_log']['log_raw_fields'][$key] =
|
|
is_string($value) ? substr($value, 0, 100) : (is_numeric($value) ? $value : gettype($value));
|
|
}
|
|
}
|
|
|
|
$allLogs[] = [
|
|
'transDate' => $transDate,
|
|
'transTime' => $transTime,
|
|
'transDateTime' => $dateTime,
|
|
'bankAccountNum' => $log->BankAccountNum ?? $accNum,
|
|
'bankName' => $log->BankName ?? ($acc->BankName ?? ''),
|
|
'deposit' => $deposit,
|
|
'withdraw' => $withdraw,
|
|
'depositFormatted' => number_format($deposit),
|
|
'withdrawFormatted' => number_format($withdraw),
|
|
'balance' => floatval($log->Balance ?? 0),
|
|
'balanceFormatted' => number_format(floatval($log->Balance ?? 0)),
|
|
'summary' => $fullSummary ?: $summary,
|
|
'cast' => $cast,
|
|
'memo' => $log->Memo ?? '',
|
|
'identity' => $log->Identity ?? '',
|
|
'branch' => $branch
|
|
];
|
|
|
|
$allSummary['totalDeposit'] += $deposit;
|
|
$allSummary['totalWithdraw'] += $withdraw;
|
|
$allSummary['count']++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 날짜/시간 기준으로 정렬 (최신순)
|
|
usort($allLogs, function($a, $b) {
|
|
$dateA = $a['transDate'] . $a['transTime'];
|
|
$dateB = $b['transDate'] . $b['transTime'];
|
|
return strcmp($dateB, $dateA); // 내림차순
|
|
});
|
|
|
|
// 페이지네이션 계산
|
|
$maxPageNum = ceil($allSummary['count'] / $limit);
|
|
$startIndex = ($page - 1) * $limit;
|
|
$paginatedLogs = array_slice($allLogs, $startIndex, $limit);
|
|
|
|
$response = [
|
|
'success' => true,
|
|
'data' => [
|
|
'logs' => $paginatedLogs,
|
|
'pagination' => [
|
|
'currentPage' => $page,
|
|
'countPerPage' => $limit,
|
|
'maxPageNum' => $maxPageNum,
|
|
'maxIndex' => $allSummary['count']
|
|
],
|
|
'summary' => $allSummary
|
|
]
|
|
];
|
|
|
|
// 디버그 정보 추가
|
|
if (!empty($debugAllAccounts)) {
|
|
$response['debug_all_accounts'] = $debugAllAccounts;
|
|
}
|
|
|
|
// 디버그: 전체 계좌 조회 시 첫 번째 로그 확인
|
|
if (!empty($paginatedLogs) && isset($paginatedLogs[0])) {
|
|
$response['debug_first_log_parsed'] = $paginatedLogs[0];
|
|
}
|
|
|
|
echo json_encode($response, JSON_UNESCAPED_UNICODE);
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 단일 계좌 조회 (기존 로직)
|
|
$result = callBarobillAccountSOAP('GetPeriodBankAccountTransLog', [
|
|
'ID' => $userId,
|
|
'BankAccountNum' => $bankAccountNum,
|
|
'StartDate' => $startDate,
|
|
'EndDate' => $endDate,
|
|
'TransDirection' => 1, // 1:전체? (API 예제 값), 2:입금, 3:출금 추정 (확인 필요) - 우선 예제값 1 사용
|
|
'CountPerPage' => $limit,
|
|
'CurrentPage' => $page,
|
|
'OrderDirection' => 2 // 1:오름차순, 2:내림차순
|
|
]);
|
|
|
|
if ($result['success']) {
|
|
$resultData = $result['data'];
|
|
|
|
// 에러 코드 체크 (다양한 필드에서 확인)
|
|
$errorCode = null;
|
|
|
|
// CurrentPage가 음수인 경우
|
|
if (isset($resultData->CurrentPage) && is_numeric($resultData->CurrentPage) && $resultData->CurrentPage < 0) {
|
|
$errorCode = $resultData->CurrentPage;
|
|
}
|
|
// BankAccountNum이 음수인 경우 (예: -10002)
|
|
elseif (isset($resultData->BankAccountNum) && is_numeric($resultData->BankAccountNum) && $resultData->BankAccountNum < 0) {
|
|
$errorCode = $resultData->BankAccountNum;
|
|
}
|
|
|
|
// -25005: 데이터 없음 (정상), -25001: 계좌 없음 (정상)
|
|
if ($errorCode && ($errorCode == -25005 || $errorCode == -25001)) {
|
|
echo json_encode([
|
|
'success' => true,
|
|
'data' => [
|
|
'logs' => [],
|
|
'summary' => ['totalDeposit' => 0, 'totalWithdraw' => 0, 'count' => 0],
|
|
'pagination' => ['currentPage' => 1, 'maxPageNum' => 1]
|
|
]
|
|
], JSON_UNESCAPED_UNICODE);
|
|
return;
|
|
}
|
|
|
|
// 다른 오류 코드인 경우
|
|
if ($errorCode) {
|
|
// 상세 에러 메시지 매핑
|
|
$errorMsg = '계좌 내역 조회 실패: ' . $errorCode;
|
|
$errorMessages = [
|
|
-10002 => '인증 실패 (-10002). CERTKEY가 올바르지 않거나 만료되었습니다. 바로빌 개발자센터에서 CERTKEY를 확인하세요.',
|
|
-50214 => '은행 로그인 실패 (-50214). 바로빌 사이트에서 계좌 비밀번호/인증서를 점검해주세요.',
|
|
-24005 => '사용자 정보 불일치 (-24005). 사업자번호를 확인해주세요.',
|
|
];
|
|
|
|
if (isset($errorMessages[$errorCode])) {
|
|
$errorMsg = $errorMessages[$errorCode];
|
|
}
|
|
|
|
throw new Exception($errorMsg);
|
|
}
|
|
|
|
// 데이터 파싱 (BankAccountTransLog)
|
|
$logs = [];
|
|
$rawLogs = [];
|
|
if (isset($resultData->BankAccountLogList) && isset($resultData->BankAccountLogList->BankAccountTransLog)) {
|
|
if (is_array($resultData->BankAccountLogList->BankAccountTransLog)) {
|
|
$rawLogs = $resultData->BankAccountLogList->BankAccountTransLog;
|
|
} else {
|
|
$rawLogs = [$resultData->BankAccountLogList->BankAccountTransLog];
|
|
}
|
|
}
|
|
|
|
// 디버그: 첫 번째 로그의 전체 구조 확인
|
|
$debugInfo = [];
|
|
if (!empty($rawLogs) && is_object($rawLogs[0])) {
|
|
$firstLog = $rawLogs[0];
|
|
$debugInfo['first_log_structure'] = [];
|
|
$debugInfo['first_log_all_keys'] = [];
|
|
foreach ($firstLog as $key => $value) {
|
|
$debugInfo['first_log_all_keys'][] = $key;
|
|
$debugInfo['first_log_structure'][$key] = [
|
|
'type' => gettype($value),
|
|
'value' => is_string($value) ? $value : (is_numeric($value) ? $value : gettype($value)),
|
|
'length' => is_string($value) ? strlen($value) : null
|
|
];
|
|
}
|
|
}
|
|
|
|
$totalDeposit = 0;
|
|
$totalWithdraw = 0;
|
|
|
|
foreach ($rawLogs as $logIndex => $log) {
|
|
$deposit = floatval($log->Deposit ?? 0);
|
|
$withdraw = floatval($log->Withdraw ?? 0);
|
|
|
|
$totalDeposit += $deposit;
|
|
$totalWithdraw += $withdraw;
|
|
|
|
// 거래일시 파싱: TransDT 필드 사용 (YYYYMMDDHHmmss 형식)
|
|
$transDT = $log->TransDT ?? '';
|
|
$transDate = '';
|
|
$transTime = '';
|
|
$dateTime = '';
|
|
|
|
if (!empty($transDT) && strlen($transDT) >= 14) {
|
|
// TransDT: "20251203100719" -> "2025-12-03 10:07:19"
|
|
$transDate = substr($transDT, 0, 8); // YYYYMMDD
|
|
$transTime = substr($transDT, 8, 6); // HHmmss
|
|
$dateTime = substr($transDT, 0, 4) . '-' . substr($transDT, 4, 2) . '-' . substr($transDT, 6, 2) . ' ' .
|
|
substr($transDT, 8, 2) . ':' . substr($transDT, 10, 2) . ':' . substr($transDT, 12, 2);
|
|
} else {
|
|
// 기존 방식도 지원 (다양한 필드명 확인)
|
|
$transDate = $log->TransDate ?? $log->TradeDate ?? $log->Date ?? '';
|
|
$transTime = $log->TransTime ?? $log->TradeTime ?? $log->Time ?? '';
|
|
|
|
if (!empty($transDate) && !empty($transTime)) {
|
|
$dateStr = (string)$transDate;
|
|
$timeStr = (string)$transTime;
|
|
|
|
if (strlen($dateStr) == 8 && strlen($timeStr) >= 4) {
|
|
$dateTime = substr($dateStr, 0, 4) . '-' . substr($dateStr, 4, 2) . '-' . substr($dateStr, 6, 2) . ' ' .
|
|
substr($timeStr, 0, 2) . ':' . substr($timeStr, 2, 2);
|
|
if (strlen($timeStr) >= 6) {
|
|
$dateTime .= ':' . substr($timeStr, 4, 2);
|
|
}
|
|
} elseif (strlen($dateStr) == 10 && strpos($dateStr, '-') !== false) {
|
|
$dateTime = $dateStr . ' ' . substr($timeStr, 0, 2) . ':' . substr($timeStr, 2, 2);
|
|
if (strlen($timeStr) >= 6) {
|
|
$dateTime .= ':' . substr($timeStr, 4, 2);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 적요 파싱: TransRemark1 필드 사용
|
|
$summary = $log->TransRemark1 ?? $log->Summary ?? $log->Content ?? $log->Description ?? $log->Remark ?? $log->Note ?? '';
|
|
|
|
// 추가 적요 정보: TransRemark2
|
|
$remark2 = $log->TransRemark2 ?? '';
|
|
|
|
// 거래 유형: TransType (예: CC)
|
|
$transType = $log->TransType ?? '';
|
|
|
|
// 거래 방향: TransDirection (예: 입금, 출금)
|
|
$transDirection = $log->TransDirection ?? '';
|
|
|
|
// 취급점: TransOffice
|
|
$transOffice = $log->TransOffice ?? '';
|
|
|
|
// 적요 정보 결합
|
|
$fullSummary = $summary;
|
|
if (!empty($remark2)) {
|
|
$fullSummary = (!empty($fullSummary) ? $fullSummary . ' ' . $remark2 : $remark2);
|
|
}
|
|
if (!empty($transType)) {
|
|
$fullSummary = (!empty($fullSummary) ? $fullSummary . ' (' . $transType . ')' : '(' . $transType . ')');
|
|
}
|
|
|
|
// 보낸분/받는분 정보 (기존 필드명도 지원)
|
|
$cast = $log->Cast ?? $log->Counterpart ?? $log->Opponent ?? $log->Name ?? '';
|
|
|
|
// 취급점/수단 정보
|
|
$branch = $transOffice ?: ($log->Branch ?? $log->HandlingBranch ?? $log->Method ?? '');
|
|
|
|
$logs[] = [
|
|
'transDate' => $transDate,
|
|
'transTime' => $transTime,
|
|
'transDateTime' => $dateTime,
|
|
'bankAccountNum' => $log->BankAccountNum ?? '',
|
|
'bankName' => $log->BankName ?? '',
|
|
'deposit' => $deposit,
|
|
'withdraw' => $withdraw,
|
|
'depositFormatted' => number_format($deposit),
|
|
'withdrawFormatted' => number_format($withdraw),
|
|
'balance' => floatval($log->Balance ?? 0),
|
|
'balanceFormatted' => number_format(floatval($log->Balance ?? 0)),
|
|
'summary' => $fullSummary ?: $summary, // 적요 (통합 정보)
|
|
'cast' => $cast, // 보낸분/받는분
|
|
'memo' => $log->Memo ?? '',
|
|
'identity' => $log->Identity ?? '', // 고유번호
|
|
'branch' => $branch, // 취급점/수단
|
|
'rawData' => json_encode($log, JSON_UNESCAPED_UNICODE) // 디버깅용 원본 데이터
|
|
];
|
|
}
|
|
|
|
$response = [
|
|
'success' => true,
|
|
'data' => [
|
|
'logs' => $logs,
|
|
'pagination' => [
|
|
'currentPage' => $resultData->CurrentPage ?? 1,
|
|
'countPerPage' => $resultData->CountPerPage ?? 50,
|
|
'maxPageNum' => $resultData->MaxPageNum ?? 1,
|
|
'maxIndex' => $resultData->MaxIndex ?? 0
|
|
],
|
|
'summary' => [
|
|
'totalDeposit' => $totalDeposit,
|
|
'totalWithdraw' => $totalWithdraw,
|
|
'count' => count($logs)
|
|
]
|
|
]
|
|
];
|
|
|
|
// 디버그 정보 추가
|
|
if (isset($result['debug'])) {
|
|
$response['debug'] = $result['debug'];
|
|
}
|
|
|
|
// API 응답 구조 디버그 정보 추가
|
|
if (!empty($debugInfo)) {
|
|
$response['debug_api_structure'] = $debugInfo;
|
|
}
|
|
|
|
// 첫 번째 로그의 원본 데이터도 포함 (필드명 확인용)
|
|
if (!empty($rawLogs) && is_object($rawLogs[0])) {
|
|
$response['debug_first_log_raw'] = [];
|
|
foreach ($rawLogs[0] as $key => $value) {
|
|
$response['debug_first_log_raw'][$key] = is_string($value) ? $value : (is_numeric($value) ? $value : gettype($value));
|
|
}
|
|
}
|
|
|
|
echo json_encode($response, JSON_UNESCAPED_UNICODE);
|
|
|
|
} else {
|
|
// API Error Handling (Graceful Fallback)
|
|
// If API fails (e.g., SoapClient missing), return empty list with warning
|
|
// so the UI doesn't break.
|
|
$response = [
|
|
'success' => true, // Masquerade as success to render empty table
|
|
'data' => [
|
|
'logs' => [],
|
|
'pagination' => [
|
|
'currentPage' => 1,
|
|
'countPerPage' => $limit,
|
|
'maxPageNum' => 1,
|
|
'maxIndex' => 0
|
|
],
|
|
'summary' => [
|
|
'totalDeposit' => 0,
|
|
'totalWithdraw' => 0,
|
|
'count' => 0
|
|
]
|
|
],
|
|
'warning' => 'API 연동 실패: ' . $result['error'], // Custom warning field
|
|
'api_error_code' => $result['error_code'] ?? null
|
|
];
|
|
|
|
// Add debug info if available
|
|
if (isset($result['debug'])) {
|
|
$response['debug'] = $result['debug'];
|
|
}
|
|
|
|
echo json_encode($response, JSON_UNESCAPED_UNICODE);
|
|
}
|
|
} catch (Throwable $e) {
|
|
// Global Exception/Error Handling
|
|
echo json_encode([
|
|
'success' => true, // Return true to avoid UI breakage
|
|
'data' => [
|
|
'logs' => [],
|
|
'pagination' => ['currentPage' => 1, 'maxPageNum' => 1],
|
|
'summary' => ['totalDeposit' => 0, 'totalWithdraw' => 0, 'count' => 0]
|
|
],
|
|
'warning' => '시스템 오류: ' . $e->getMessage()
|
|
], JSON_UNESCAPED_UNICODE);
|
|
}
|
|
?>
|