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)); // 설명 텍스트가 아닌 실제 키만 추출 (대괄호 안의 내용 제외, =로 시작하는 경우 제외) if (!empty($content) && !preg_match('/^\[여기에/', $content) && !preg_match('/^=/', $content) && strpos($content, '바로빌 CERTKEY') === false) { $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; } } /** * 바로빌 사용자 ID 반환 */ function getBarobillUserId() { global $barobillUserId; return $barobillUserId; } // 바로빌 카드 SOAP 웹서비스 URL $barobillCardSoapUrl = $isTestMode ? 'https://testws.baroservice.com/CARD.asmx?WSDL' // 테스트 환경 : 'https://ws.baroservice.com/CARD.asmx?WSDL'; // 운영 환경 // SOAP 클라이언트 초기화 $barobillCardSoapClient = null; if (!empty($barobillCertKey) || $isTestMode) { try { $barobillCardSoapClient = new SoapClient($barobillCardSoapUrl, [ 'trace' => true, 'encoding' => 'UTF-8', 'exceptions' => true, 'connection_timeout' => 30 ]); } catch (Throwable $e) { error_log('바로빌 카드 SOAP 클라이언트 생성 실패: ' . $e->getMessage()); } } /** * 바로빌 카드 SOAP 웹서비스 호출 함수 * * @param string $method SOAP 메서드명 * @param array $params SOAP 메서드 파라미터 * @return array 응답 데이터 */ function callBarobillCardSOAP($method, $params = []) { global $barobillCardSoapClient, $barobillCertKey, $barobillCorpNum, $isTestMode; if (!$barobillCardSoapClient) { return [ 'success' => false, 'error' => '바로빌 카드 SOAP 클라이언트가 초기화되지 않았습니다. CERTKEY를 확인하세요.', 'error_detail' => [ 'cert_key_file' => getenv('DOCUMENT_ROOT') . '/apikey/barobill_cert_key.txt', 'soap_url' => $isTestMode ? 'https://testws.baroservice.com/CARD.asmx?WSDL' : 'https://ws.baroservice.com/CARD.asmx?WSDL' ] ]; } 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 자동 추가 if (!isset($params['CERTKEY'])) { $params['CERTKEY'] = $barobillCertKey; } if (!isset($params['CorpNum'])) { $params['CorpNum'] = $barobillCorpNum; } try { error_log('바로빌 카드 API 호출 - Method: ' . $method . ', CorpNum: ' . $barobillCorpNum); $result = $barobillCardSoapClient->$method($params); $resultProperty = $method . 'Result'; if (isset($result->$resultProperty)) { $resultData = $result->$resultProperty; // 에러 코드 체크 (음수 값) if (is_numeric($resultData) && $resultData < 0) { return [ 'success' => false, 'error' => '바로빌 카드 API 오류 코드: ' . $resultData, 'error_code' => $resultData ]; } return [ 'success' => true, 'data' => $resultData ]; } return [ 'success' => true, 'data' => $result ]; } catch (SoapFault $e) { return [ 'success' => false, 'error' => 'SOAP 오류: ' . $e->getMessage(), 'error_code' => $e->getCode() ]; } catch (Throwable $e) { return [ 'success' => false, 'error' => 'API 호출 오류 (치명적): ' . $e->getMessage() ]; } } /** * 등록된 카드 목록 조회 (GetCardEx2 API 사용) * API 레퍼런스: https://dev.barobill.co.kr/docs/references/카드조회-API#GetCardEx2 * * @param int $availOnly 0: 전체, 1: 사용가능한 카드만 * @return array 카드 목록 */ function getCardList($availOnly = 0) { $result = callBarobillCardSOAP('GetCardEx2', [ 'AvailOnly' => $availOnly ]); if (!$result['success']) { return $result; } $cards = []; $data = $result['data']; // GetCardEx2는 CardEx 배열을 반환 if (!isset($data->CardEx)) { return ['success' => true, 'data' => []]; } if (!is_array($data->CardEx)) { $cards = [$data->CardEx]; } else { $cards = $data->CardEx; } // 에러 체크: CardNum이 음수면 에러 코드 if (count($cards) == 1 && isset($cards[0]->CardNum) && $cards[0]->CardNum < 0) { return [ 'success' => false, 'error' => '카드 목록 조회 실패', 'error_code' => $cards[0]->CardNum ]; } return ['success' => true, 'data' => $cards]; } /** * 기간별 카드 사용내역 조회 * * @param string $cardNum 카드번호 (빈값이면 전체) * @param string $startDate 시작일 (YYYYMMDD) * @param string $endDate 종료일 (YYYYMMDD) * @param int $countPerPage 페이지당 건수 * @param int $currentPage 현재 페이지 * @param int $orderDirection 정렬 (1: 오름차순, 2: 내림차순) * @param string $userId 바로빌 사용자 ID (빈값이면 전체) * @return array 사용내역 */ function getPeriodCardUsage($cardNum = '', $startDate = '', $endDate = '', $countPerPage = 50, $currentPage = 1, $orderDirection = 2, $userId = '') { global $barobillCorpNum; // 바로빌 사용자 ID 파일에서 읽기 (없으면 빈값) $barobillUserId = getBarobillUserId(); if (!empty($userId)) { $barobillUserId = $userId; } $result = callBarobillCardSOAP('GetPeriodCardApprovalLog', [ 'ID' => $barobillUserId, 'CardNum' => $cardNum, 'StartDate' => $startDate, 'EndDate' => $endDate, 'CountPerPage' => $countPerPage, 'CurrentPage' => $currentPage, 'OrderDirection' => $orderDirection ]); if (!$result['success']) { return $result; } return parseCardUsageResult($result['data']); } /** * 일별 카드 사용내역 조회 * * @param string $cardNum 카드번호 (빈값이면 전체) * @param string $baseDate 기준일 (YYYYMMDD) * @param int $countPerPage 페이지당 건수 * @param int $currentPage 현재 페이지 * @param int $orderDirection 정렬 (1: 오름차순, 2: 내림차순) * @param string $userId 바로빌 사용자 ID (빈값이면 전체) * @return array 사용내역 */ function getDailyCardUsage($cardNum = '', $baseDate = '', $countPerPage = 50, $currentPage = 1, $orderDirection = 2, $userId = '') { $barobillUserId = getBarobillUserId(); if (!empty($userId)) { $barobillUserId = $userId; } $result = callBarobillCardSOAP('GetDailyCardApprovalLog', [ 'ID' => $barobillUserId, 'CardNum' => $cardNum, 'BaseDate' => $baseDate, 'CountPerPage' => $countPerPage, 'CurrentPage' => $currentPage, 'OrderDirection' => $orderDirection ]); if (!$result['success']) { return $result; } return parseCardUsageResult($result['data']); } /** * 월별 카드 사용내역 조회 * * @param string $cardNum 카드번호 (빈값이면 전체) * @param string $baseMonth 기준월 (YYYYMM) * @param int $countPerPage 페이지당 건수 * @param int $currentPage 현재 페이지 * @param int $orderDirection 정렬 (1: 오름차순, 2: 내림차순) * @param string $userId 바로빌 사용자 ID (빈값이면 전체) * @return array 사용내역 */ function getMonthlyCardUsage($cardNum = '', $baseMonth = '', $countPerPage = 50, $currentPage = 1, $orderDirection = 2, $userId = '') { $barobillUserId = getBarobillUserId(); if (!empty($userId)) { $barobillUserId = $userId; } $result = callBarobillCardSOAP('GetMonthlyCardApprovalLog', [ 'ID' => $barobillUserId, 'CardNum' => $cardNum, 'BaseMonth' => $baseMonth, 'CountPerPage' => $countPerPage, 'CurrentPage' => $currentPage, 'OrderDirection' => $orderDirection ]); if (!$result['success']) { return $result; } return parseCardUsageResult($result['data']); } /** * 카드 사용내역 결과 파싱 * * @param object $data SOAP 응답 데이터 * @return array 파싱된 결과 */ function parseCardUsageResult($data) { // 에러 체크 if (isset($data->CurrentPage) && $data->CurrentPage < 0) { $errorCode = $data->CurrentPage; // -24005: 조회 데이터 없음 (정상 케이스로 처리) // -24001: 등록된 카드 없음 // -24002: 조회 기간 오류 if ($errorCode == -24005 || $errorCode == -24001) { // 데이터 없음 - 빈 배열 반환 (에러가 아님) return [ 'success' => true, 'data' => [ 'currentPage' => 1, 'countPerPage' => 50, 'maxPageNum' => 1, 'maxIndex' => 0, 'logs' => [] ] ]; } return [ 'success' => false, 'error' => '카드 사용내역 조회 실패', 'error_code' => $errorCode ]; } $logs = []; if (isset($data->CardLogList) && isset($data->CardLogList->CardApprovalLog)) { if (!is_array($data->CardLogList->CardApprovalLog)) { $logs = [$data->CardLogList->CardApprovalLog]; } else { $logs = $data->CardLogList->CardApprovalLog; } } return [ 'success' => true, 'data' => [ 'currentPage' => $data->CurrentPage ?? 1, 'countPerPage' => $data->CountPerPage ?? 50, 'maxPageNum' => $data->MaxPageNum ?? 1, 'maxIndex' => $data->MaxIndex ?? 0, 'logs' => $logs ] ]; } /** * 카드 등록 * * @param array $cardData 카드 데이터 * @return array 응답 데이터 */ function registerCard($cardData) { return callBarobillCardSOAP('RegistCardEx', [ 'CollectCycle' => $cardData['collectCycle'] ?? '1', // 수집주기 (1: 1일 1회) 'CardCompany' => $cardData['cardCompany'] ?? '', // 카드사 코드 'CardType' => $cardData['cardType'] ?? '1', // 카드 종류 (1: 개인, 2: 법인) 'CardNum' => $cardData['cardNum'] ?? '', // 카드번호 'WebId' => $cardData['webId'] ?? '', // 카드사 웹 ID 'WebPwd' => $cardData['webPwd'] ?? '', // 카드사 웹 비밀번호 'Alias' => $cardData['alias'] ?? '', // 카드 별칭 'Usage' => $cardData['usage'] ?? '1' // 용도 (1: 세금계산서, 2: 기타) ]); } ?>