= 10) { // 추가 검증: 실제 CERTKEY는 보통 영문/숫자/하이픈 조합 // 설명 텍스트는 한글이나 특수문자가 많음 $koreanCharCount = preg_match_all('/[가-힣]/u', $content); $totalCharCount = mb_strlen($content, 'UTF-8'); // 한글 비율이 10% 미만이고, 길이가 적절하면 CERTKEY로 인식 if ($koreanCharCount / max($totalCharCount, 1) < 0.1) { $barobillCertKey = $content; } } } if (empty($barobillCertKey) && file_exists($legacyApiKeyFile)) { $barobillCertKey = trim(file_get_contents($legacyApiKeyFile)); } // 사업자번호 읽기 $barobillCorpNum = ''; if (file_exists($corpNumFile)) { $content = trim(file_get_contents($corpNumFile)); if (!empty($content) && !preg_match('/^\[여기에/', $content)) { $barobillCorpNum = str_replace('-', '', $content); } } // 테스트 모드 확인 $isTestMode = false; if (file_exists($testModeFile)) { $testMode = trim(file_get_contents($testModeFile)); $isTestMode = (strtolower($testMode) === 'test' || strtolower($testMode) === 'true'); } // 바로빌 사용자 ID (계좌 사용내역 조회에 필요) // 빈 값이면 전체 계좌 조회, 특정 사용자만 조회하려면 사용자 ID 입력 $barobillUserIdFile = $_SERVER['DOCUMENT_ROOT'] . '/apikey/barobill_user_id.txt'; $barobillUserId = ''; if (file_exists($barobillUserIdFile)) { $content = trim(file_get_contents($barobillUserIdFile)); if (!empty($content) && !preg_match('/^\[여기에/', $content)) { $barobillUserId = $content; } } // 테넌트별 설정 (DB에서 가져오기) require_once($_SERVER['DOCUMENT_ROOT'] . '/session.php'); require_once($_SERVER['DOCUMENT_ROOT'] . '/lib/mydb.php'); $selectedTenantId = $_SESSION['eaccount_tenant_id'] ?? null; // DB에서 테넌트 정보 가져오기 if ($selectedTenantId) { try { $pdo = db_connect(); if ($pdo) { $sql = "SELECT id, company_name, corp_num, barobill_user_id FROM {$DB}.barobill_companies WHERE id = ?"; $stmt = $pdo->prepare($sql); $stmt->execute([$selectedTenantId]); $tenant = $stmt->fetch(PDO::FETCH_ASSOC); if ($tenant) { $barobillUserId = $tenant['barobill_user_id']; $barobillCorpNum = $tenant['corp_num']; } } } catch (Exception $e) { error_log('테넌트 정보 로드 실패: ' . $e->getMessage()); } } else { // 세션에 테넌트 ID가 없으면 '(주)주일기업'을 기본값으로 찾기 try { $pdo = db_connect(); if ($pdo) { // '(주)주일기업' 또는 barobill_user_id가 'juil5130'인 회사 찾기 $sql = "SELECT id, company_name, corp_num, barobill_user_id FROM {$DB}.barobill_companies WHERE company_name LIKE '%주일기업%' OR company_name LIKE '%주일%' OR barobill_user_id = 'juil5130' ORDER BY id ASC LIMIT 1"; $stmt = $pdo->query($sql); $tenant = $stmt->fetch(PDO::FETCH_ASSOC); if ($tenant) { $barobillUserId = $tenant['barobill_user_id']; $barobillCorpNum = $tenant['corp_num']; $selectedTenantId = $tenant['id']; // 세션에 저장 $_SESSION['eaccount_tenant_id'] = $selectedTenantId; } } } catch (Exception $e) { error_log('기본 테넌트 정보 로드 실패: ' . $e->getMessage()); } } /** * 바로빌 사용자 ID 반환 */ function getBarobillUserId() { global $barobillUserId; return $barobillUserId; } // 바로빌 계좌 SOAP 웹서비스 URL (BANK.asmx) // 바로빌 계좌 SOAP 웹서비스 URL (BANKACCOUNT.asmx) $barobillAccountSoapUrl = $isTestMode ? 'https://testws.baroservice.com/BANKACCOUNT.asmx?WSDL' // 테스트 환경 : 'https://ws.baroservice.com/BANKACCOUNT.asmx?WSDL'; // 운영 환경 // SOAP 클라이언트 초기화 $barobillAccountSoapClient = null; $barobillInitError = ''; if (!empty($barobillCertKey) || $isTestMode) { try { // SSL 검증 비활성화 및 타임아웃 설정 $context = stream_context_create([ 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true ] ]); $barobillAccountSoapClient = new SoapClient($barobillAccountSoapUrl, [ 'trace' => true, 'encoding' => 'UTF-8', 'exceptions' => true, 'connection_timeout' => 30, 'stream_context' => $context, 'cache_wsdl' => WSDL_CACHE_NONE // WSDL 캐시 비활성화 ]); } catch (Exception $e) { $barobillInitError = $e->getMessage(); error_log('바로빌 계좌 SOAP 클라이언트 생성 실패: ' . $e->getMessage()); } } /** * 바로빌 계좌 SOAP 웹서비스 호출 함수 * * @param string $method SOAP 메서드명 * @param array $params SOAP 메서드 파라미터 * @return array 응답 데이터 */ function callBarobillAccountSOAP($method, $params = []) { global $barobillAccountSoapClient, $barobillCertKey, $barobillCorpNum, $isTestMode, $barobillInitError, $barobillAccountSoapUrl; if (!$barobillAccountSoapClient) { $errorMsg = $isTestMode ? '바로빌 계좌 SOAP 클라이언트가 초기화되지 않았습니다. (' . ($barobillInitError ?: '알 수 없는 오류') . ')' : '바로빌 계좌 SOAP 클라이언트가 초기화되지 않았습니다. CERTKEY를 확인하세요. (' . ($barobillInitError ?: '알 수 없는 오류') . ')'; return [ 'success' => false, 'error' => $errorMsg, 'error_detail' => [ 'cert_key_file' => $_SERVER['DOCUMENT_ROOT'] . '/apikey/barobill_cert_key.txt', 'soap_url' => $barobillAccountSoapUrl, 'init_error' => $barobillInitError, 'test_mode' => $isTestMode ] ]; } if (empty($barobillCertKey) && !$isTestMode) { return [ 'success' => false, 'error' => 'CERTKEY가 설정되지 않았습니다. apikey/barobill_cert_key.txt 파일을 확인하세요.' ]; } if (empty($barobillCorpNum)) { return [ 'success' => false, 'error' => '사업자번호가 설정되지 않았습니다. apikey/barobill_corp_num.txt 파일을 확인하세요.' ]; } // CERTKEY와 CorpNum 자동 추가 // 테스트 모드에서도 CERTKEY가 있으면 사용 (일부 API는 테스트 모드에서도 CERTKEY 필요) if (!isset($params['CERTKEY'])) { if ($isTestMode) { // 테스트 모드: CERTKEY가 있으면 사용, 없으면 빈 값 // 주의: 일부 API는 테스트 모드에서도 CERTKEY가 필요할 수 있음 $params['CERTKEY'] = !empty($barobillCertKey) ? $barobillCertKey : ''; } else { // 운영 모드: CERTKEY 필수 $params['CERTKEY'] = $barobillCertKey; } } if (!isset($params['CorpNum'])) { $params['CorpNum'] = $barobillCorpNum; } try { error_log('바로빌 계좌 API 호출 - Method: ' . $method . ', CorpNum: ' . $barobillCorpNum); // SOAP 요청 로그 수집 (CERTKEY는 마스킹) $logParams = $params; if (isset($logParams['CERTKEY'])) { $logParams['CERTKEY'] = substr($logParams['CERTKEY'], 0, 8) . '...' . substr($logParams['CERTKEY'], -4); } $soapRequest = [ 'method' => $method, 'url' => $barobillAccountSoapUrl, 'params' => $logParams, 'timestamp' => date('Y-m-d H:i:s') ]; $result = $barobillAccountSoapClient->$method($params); // SOAP 요청/응답 XML 로그 수집 $soapRequestXml = $barobillAccountSoapClient->__getLastRequest(); $soapResponseXml = $barobillAccountSoapClient->__getLastResponse(); $resultProperty = $method . 'Result'; if (isset($result->$resultProperty)) { $resultData = $result->$resultProperty; // 에러 코드 체크 (음수 값 또는 객체 내부의 음수 값) $errorCode = null; // 직접 숫자로 반환된 경우 if (is_numeric($resultData) && $resultData < 0) { $errorCode = $resultData; } // 객체 내부에 BankAccountNum이 음수인 경우 (예: -10002) elseif (is_object($resultData)) { if (isset($resultData->BankAccountNum) && is_numeric($resultData->BankAccountNum) && $resultData->BankAccountNum < 0) { $errorCode = $resultData->BankAccountNum; } // 다른 필드에서도 음수 값 체크 foreach (get_object_vars($resultData) as $key => $value) { if (is_numeric($value) && $value < 0 && ($key == 'CurrentPage' || $key == 'ErrorCode' || $key == 'ResultCode')) { $errorCode = $value; break; } } } if ($errorCode !== null) { $errorMsg = '바로빌 계좌 API 오류 코드: ' . $errorCode; // 상세 에러 메시지 매핑 $errorMessages = [ -10002 => '인증 실패 (-10002). CERTKEY가 올바르지 않거나 만료되었습니다. 바로빌 개발자센터에서 CERTKEY를 확인하세요.', -50214 => '은행 로그인 실패 (-50214). 바로빌 사이트에서 계좌 비밀번호/인증서를 점검해주세요.', -24005 => '사용자 정보 불일치 (-24005). 사업자번호를 확인해주세요.', -25001 => '등록된 계좌가 없습니다 (-25001). 바로빌 사이트에서 계좌를 등록해주세요.', -25005 => '조회된 데이터가 없습니다 (-25005).', -25006 => '계좌번호가 잘못되었습니다 (-25006).', -25007 => '조회 기간이 잘못되었습니다 (-25007).', ]; if (isset($errorMessages[$errorCode])) { $errorMsg = $errorMessages[$errorCode]; } return [ 'success' => false, 'error' => $errorMsg, 'error_code' => $errorCode, 'debug' => [ 'request' => $soapRequest, 'request_xml' => $soapRequestXml, 'response_xml' => $soapResponseXml ] ]; } return [ 'success' => true, 'data' => $resultData, 'debug' => [ 'request' => $soapRequest, 'request_xml' => $soapRequestXml, 'response_xml' => $soapResponseXml ] ]; } return [ 'success' => true, 'data' => $result, 'debug' => [ 'request' => $soapRequest, 'request_xml' => $soapRequestXml, 'response_xml' => $soapResponseXml ] ]; } catch (SoapFault $e) { return [ 'success' => false, 'error' => 'SOAP 오류: ' . $e->getMessage(), 'error_code' => $e->getCode() ]; } catch (Exception $e) { return [ 'success' => false, 'error' => 'API 호출 오류: ' . $e->getMessage() ]; } } ?>