Files
sam-sales/eaccount/api/barobill_account_config.php

367 lines
14 KiB
PHP
Raw Normal View History

<?php
/**
* 바로빌 계좌 API 설정 파일
*
* ⚠️ 중요: 바로빌은 SOAP 웹서비스를 사용합니다 (REST API가 아님)
*
* 계좌 입출금내역 조회를 위해서는 바로빌 웹사이트(https://www.barobill.co.kr)에서
* 계좌를 먼저 등록해야 합니다.
*
* 설정 파일:
* 1. apikey/barobill_cert_key.txt - CERTKEY (인증서 )
* 2. apikey/barobill_corp_num.txt - 사업자번호
* 3. apikey/barobill_test_mode.txt - 테스트 모드 설정 (선택)
*/
// 인증서 키(CERTKEY) 파일 경로
// load .env file
require_once __DIR__ . '/../../lib/DotEnv.php';
(new DotEnv(__DIR__ . '/../../.env'))->load();
// 인증서 키(CERTKEY) 파일 경로
$documentRoot = getenv('DOCUMENT_ROOT');
$certKeyFile = $documentRoot . '/apikey/barobill_cert_key.txt';
$legacyApiKeyFile = $documentRoot . '/apikey/barobill_api_key.txt';
$corpNumFile = $documentRoot . '/apikey/barobill_corp_num.txt';
$testModeFile = $documentRoot . '/apikey/barobill_test_mode.txt';
// CERTKEY 읽기
$barobillCertKey = '';
if (file_exists($certKeyFile)) {
$content = trim(file_get_contents($certKeyFile));
// 설명 텍스트 필터링: 실제 CERTKEY만 추출
// 설명 텍스트 패턴 체크
$isPlaceholder = false;
$placeholderPatterns = [
'/^\[여기에/', // [여기에로 시작
'/^=/', // =로 시작
'/바로빌 CERTKEY/', // '바로빌 CERTKEY' 문자열 포함
'/================================/', // 구분선 포함
'/설정 방법:/', // '설정 방법:' 포함
'/인증서 관리/', // '인증서 관리' 포함
'/개발자센터/', // '개발자센터' 포함
'/⚠️/', // 경고 이모지 포함
'/참고:/', // '참고:' 포함
];
foreach ($placeholderPatterns as $pattern) {
if (preg_match($pattern, $content)) {
$isPlaceholder = true;
break;
}
}
// 실제 CERTKEY는 보통 20자 이상의 영문/숫자 조합
// 설명 텍스트가 아니고, 충분히 긴 경우에만 CERTKEY로 인식
if (!empty($content) && !$isPlaceholder && strlen($content) >= 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 = getenv('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(getenv('DOCUMENT_ROOT') . '/session.php');
require_once(getenv('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 (Throwable $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' => getenv('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 (Throwable $e) {
return [
'success' => false,
'error' => 'API 호출 오류 (치명적): ' . $e->getMessage()
];
}
}
?>