🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
511 lines
18 KiB
PHP
511 lines
18 KiB
PHP
<?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 - 테스트 모드 설정 (선택)
|
|
*
|
|
* ============================================================================
|
|
* 카드 정보 출처 및 데이터 흐름
|
|
* ============================================================================
|
|
*
|
|
* 1. 카드 등록 정보 (카드번호, 카드사, Web ID, Web 비밀번호 등)
|
|
* - 출처: 바로빌 웹사이트(https://www.barobill.co.kr)에서 직접 등록
|
|
* - 등록 방법: 바로빌 웹사이트 로그인 → 카드 관리 → 카드 등록
|
|
* - 등록 시 필요한 정보:
|
|
* * 카드번호 (CardNum)
|
|
* * 카드사 코드 (CardCompany: 01=BC, 02=KB, 04=삼성, 06=신한 등)
|
|
* * 카드 종류 (CardType: 1=개인, 2=법인)
|
|
* * 카드사 웹 ID (WebId: 카드사 홈페이지 로그인 ID)
|
|
* * 카드사 웹 비밀번호 (WebPwd: 카드사 홈페이지 로그인 비밀번호)
|
|
* * 카드 별칭 (Alias: 선택사항)
|
|
* * 수집주기 (CollectCycle: 1=1일1회, 2=1일2회, 3=1일3회)
|
|
*
|
|
* 2. 화면에 표시되는 카드 정보 조회 경로
|
|
* [화면] ecard/index.php
|
|
* ↓ (JavaScript fetch)
|
|
* [API] ecard/api/cards.php
|
|
* ↓ (함수 호출)
|
|
* [설정] ecard/api/barobill_card_config.php::getCardList()
|
|
* ↓ (SOAP API 호출)
|
|
* [바로빌] GetCardEx2 API
|
|
* ↓ (응답)
|
|
* [바로빌] CardEx 객체 배열 반환
|
|
* ↓ (데이터 변환)
|
|
* [API] cards.php에서 JSON으로 변환
|
|
* ↓ (응답)
|
|
* [화면] React 컴포넌트에서 카드 목록 표시
|
|
*
|
|
* 3. 카드 사용내역 조회 경로
|
|
* [화면] ecard/index.php
|
|
* ↓ (JavaScript fetch)
|
|
* [API] ecard/api/usage.php
|
|
* ↓ (함수 호출)
|
|
* [설정] ecard/api/barobill_card_config.php::getPeriodCardUsage()
|
|
* ↓ (SOAP API 호출)
|
|
* [바로빌] GetPeriodCardApprovalLog API
|
|
* ↓ (응답)
|
|
* [바로빌] CardApprovalLog 객체 배열 반환
|
|
* ↓ (데이터 변환)
|
|
* [API] usage.php에서 JSON으로 변환
|
|
* ↓ (응답)
|
|
* [화면] React 컴포넌트에서 사용내역 테이블 표시
|
|
*
|
|
* 4. 주요 함수 설명
|
|
* - getCardList(): 바로빌에 등록된 카드 목록 조회
|
|
* - getPeriodCardUsage(): 기간별 카드 사용내역 조회
|
|
* - getDailyCardUsage(): 일별 카드 사용내역 조회
|
|
* - getMonthlyCardUsage(): 월별 카드 사용내역 조회
|
|
* - registerCard(): 카드 등록 (프로그래밍 방식, 현재 미사용)
|
|
*
|
|
* 5. 주의사항
|
|
* - 카드 정보는 바로빌 서버에 저장되며, 이 시스템은 조회만 수행합니다
|
|
* - 카드 등록/수정/삭제는 바로빌 웹사이트에서 직접 해야 합니다
|
|
* - Web ID와 Web 비밀번호는 카드사 홈페이지 로그인 정보입니다
|
|
* - 카드사별로 Web ID/비밀번호 형식이 다를 수 있습니다
|
|
*/
|
|
|
|
// 인증서 키(CERTKEY) 파일 경로
|
|
$certKeyFile = $_SERVER['DOCUMENT_ROOT'] . '/apikey/barobill_cert_key.txt';
|
|
$legacyApiKeyFile = $_SERVER['DOCUMENT_ROOT'] . '/apikey/barobill_api_key.txt';
|
|
$corpNumFile = $_SERVER['DOCUMENT_ROOT'] . '/apikey/barobill_corp_num.txt';
|
|
$testModeFile = $_SERVER['DOCUMENT_ROOT'] . '/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 = $_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;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 바로빌 사용자 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 (Exception $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' => $_SERVER['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 (Exception $e) {
|
|
return [
|
|
'success' => false,
|
|
'error' => 'API 호출 오류: ' . $e->getMessage()
|
|
];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 등록된 카드 목록 조회 (GetCardEx2 API 사용)
|
|
* API 레퍼런스: https://dev.barobill.co.kr/docs/references/카드조회-API#GetCardEx2
|
|
*
|
|
* 데이터 출처: 바로빌 서버에 등록된 카드 정보
|
|
* - 카드 등록은 바로빌 웹사이트(https://www.barobill.co.kr)에서 직접 해야 함
|
|
* - 이 함수는 등록된 카드 정보를 조회만 수행
|
|
*
|
|
* 반환되는 카드 정보:
|
|
* - CardNum: 카드번호 (바로빌에 등록된 카드번호)
|
|
* - CardCompanyCode: 카드사 코드 (01=BC, 02=KB, 04=삼성, 06=신한 등)
|
|
* - CardCompanyName: 카드사 이름
|
|
* - WebId: 카드사 웹 ID (카드사 홈페이지 로그인 ID)
|
|
* - Alias: 카드 별칭
|
|
* - CardType: 카드 종류 (1=개인, 2=법인)
|
|
* - Status: 카드 상태 (0=대기중, 1=정상, 2=해지, 3=수집오류, 4=일시중지)
|
|
* - CollectCycle: 수집주기 (1=1일1회, 2=1일2회, 3=1일3회)
|
|
*
|
|
* @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];
|
|
}
|
|
|
|
/**
|
|
* 기간별 카드 사용내역 조회
|
|
*
|
|
* 데이터 출처: 바로빌 서버에서 수집된 카드 사용내역
|
|
* - 바로빌이 카드사에서 자동으로 수집한 사용내역을 조회
|
|
* - 수집주기(CollectCycle)에 따라 1일 1회~3회 자동 수집
|
|
*
|
|
* 반환되는 사용내역 정보:
|
|
* - CardNum: 카드번호
|
|
* - UseDT: 사용일시 (YYYYMMDDHHMMSS)
|
|
* - UseStoreName: 가맹점명
|
|
* - UseStoreCorpNum: 가맹점 사업자번호
|
|
* - ApprovalAmount: 승인금액
|
|
* - Tax: 부가세
|
|
* - ServiceCharge: 봉사료
|
|
* - ApprovalType: 승인유형 (1=승인, 2=취소)
|
|
* - PaymentPlan: 할부개월 (0=일시불)
|
|
* - ApprovalNum: 승인번호
|
|
*
|
|
* @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
|
|
]
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 카드 등록
|
|
*
|
|
* ⚠️ 주의: 현재 이 함수는 사용되지 않습니다.
|
|
* 카드 등록은 바로빌 웹사이트(https://www.barobill.co.kr)에서 직접 해야 합니다.
|
|
*
|
|
* 카드 등록 시 필요한 정보:
|
|
* - CardNum: 카드번호 (예: "1234567890123456")
|
|
* - CardCompany: 카드사 코드 (예: "04"=삼성, "06"=신한, "02"=KB)
|
|
* - CardType: 카드 종류 ("1"=개인, "2"=법인)
|
|
* - WebId: 카드사 웹 ID (카드사 홈페이지 로그인 ID)
|
|
* - WebPwd: 카드사 웹 비밀번호 (카드사 홈페이지 로그인 비밀번호)
|
|
* - Alias: 카드 별칭 (선택사항, 예: "법인카드1")
|
|
* - CollectCycle: 수집주기 ("1"=1일1회, "2"=1일2회, "3"=1일3회)
|
|
* - Usage: 용도 ("1"=세금계산서, "2"=기타)
|
|
*
|
|
* 카드사 코드 참고:
|
|
* - 01: BC카드
|
|
* - 02: KB국민카드
|
|
* - 04: 삼성카드
|
|
* - 06: 신한카드
|
|
* - 07: 현대카드
|
|
* - 08: 롯데카드
|
|
* - 11: NH농협카드
|
|
* - 21: 하나카드
|
|
*
|
|
* @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: 기타)
|
|
]);
|
|
}
|
|
|
|
?>
|
|
|