초기 커밋: 5130 레거시 시스템
- URL 하드코딩 → .env APP_URL 기반 동적 URL로 변경 - DB 연결 하드코딩 → .env 기반으로 변경 - MySQL strict mode DATE 오류 수정
This commit is contained in:
510
ecard/api/barobill_card_config.php
Normal file
510
ecard/api/barobill_card_config.php
Normal file
@@ -0,0 +1,510 @@
|
||||
<?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: 기타)
|
||||
]);
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
252
ecard/api/cards.php
Normal file
252
ecard/api/cards.php
Normal file
@@ -0,0 +1,252 @@
|
||||
<?php
|
||||
/**
|
||||
* 등록된 카드 목록 조회 API (GetCardEx2)
|
||||
* API 레퍼런스: https://dev.barobill.co.kr/docs/references/카드조회-API#GetCardEx2
|
||||
*
|
||||
* ============================================================================
|
||||
* 데이터 흐름
|
||||
* ============================================================================
|
||||
*
|
||||
* [호출 경로]
|
||||
* 화면(ecard/index.php) → 이 API(cards.php) → barobill_card_config.php::getCardList()
|
||||
* → 바로빌 SOAP API(GetCardEx2) → 바로빌 서버
|
||||
*
|
||||
* [카드 정보 출처]
|
||||
* - 카드 정보는 바로빌 웹사이트(https://www.barobill.co.kr)에서 등록된 정보
|
||||
* - 카드번호, 카드사, Web ID, Web 비밀번호 등은 바로빌에 저장되어 있음
|
||||
* - 이 API는 바로빌 서버에서 등록된 카드 목록을 조회만 수행
|
||||
*
|
||||
* [반환 데이터]
|
||||
* - cardNum: 카드번호 (전체)
|
||||
* - cardNumMasked: 카드번호 (마스킹 처리, 예: "1234-****-****-5678")
|
||||
* - cardCompany: 카드사 코드 (예: "04", "06", "02")
|
||||
* - cardCompanyName: 카드사 이름 (예: "삼성카드", "신한카드", "KB국민카드")
|
||||
* - cardBrand: 카드 브랜드 (예: "비자", "마스터카드", "카드")
|
||||
* - alias: 카드 별칭
|
||||
* - webId: 카드사 웹 ID (카드사 홈페이지 로그인 ID)
|
||||
* - status: 카드 상태 (0=대기중, 1=정상, 2=해지, 3=수집오류, 4=일시중지)
|
||||
*
|
||||
* [주의사항]
|
||||
* - Web 비밀번호는 보안상 반환하지 않음
|
||||
* - 카드 등록/수정/삭제는 바로빌 웹사이트에서 직접 해야 함
|
||||
*/
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
require_once('barobill_card_config.php');
|
||||
|
||||
try {
|
||||
$availOnly = isset($_GET['availOnly']) ? intval($_GET['availOnly']) : 0;
|
||||
|
||||
$result = getCardList($availOnly);
|
||||
|
||||
if ($result['success']) {
|
||||
$cards = [];
|
||||
foreach ($result['data'] as $card) {
|
||||
// GetCardEx2 응답 필드 매핑
|
||||
// CardCompanyCode (등록 시), CardCompanyName (조회 시)
|
||||
$cardCompanyCode = $card->CardCompanyCode ?? $card->CardCompany ?? '';
|
||||
|
||||
// 카드 브랜드 (비자, 마스터카드 등) 추측
|
||||
$cardBrand = guessCardTypeFromNumber($card->CardNum ?? '');
|
||||
|
||||
// 카드 회사명 (신한, KB 등)
|
||||
$cardCompanyName = !empty($card->CardCompanyName)
|
||||
? $card->CardCompanyName
|
||||
: getCardCompanyName($cardCompanyCode);
|
||||
|
||||
$cards[] = [
|
||||
'cardNum' => $card->CardNum ?? '',
|
||||
'cardNumMasked' => maskCardNumber($card->CardNum ?? ''),
|
||||
'cardCompany' => $cardCompanyCode,
|
||||
'cardCompanyName' => $cardCompanyName,
|
||||
'cardBrand' => $cardBrand, // 카드 브랜드 (비자, 마스터카드 등)
|
||||
'alias' => $card->Alias ?? '',
|
||||
'cardType' => $card->CardType ?? '',
|
||||
'cardTypeName' => getCardTypeName($card->CardType ?? ''),
|
||||
'status' => $card->Status ?? '',
|
||||
'statusName' => getCardStatusName($card->Status ?? ''),
|
||||
'collectCycle' => $card->CollectCycle ?? '',
|
||||
'collectCycleName' => getCollectCycleName($card->CollectCycle ?? ''),
|
||||
'lastCollectDate' => formatDate($card->LastCollectDate ?? ''),
|
||||
'lastCollectResult' => $card->LastCollectResult ?? '',
|
||||
'lastCollectResultName' => getCollectResultName($card->LastCollectResult ?? ''),
|
||||
'nextExtendDate' => formatDate($card->NextExtendDate ?? ''),
|
||||
'registDate' => formatDate($card->RegistDate ?? ''),
|
||||
'webId' => $card->WebId ?? ''
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'success' => true,
|
||||
'cards' => $cards,
|
||||
'count' => count($cards)
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
} else {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'error' => $result['error'],
|
||||
'error_code' => $result['error_code'] ?? null
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'error' => '서버 오류: ' . $e->getMessage()
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 카드번호 마스킹
|
||||
*/
|
||||
function maskCardNumber($cardNum) {
|
||||
if (strlen($cardNum) < 8) return $cardNum;
|
||||
return substr($cardNum, 0, 4) . '-****-****-' . substr($cardNum, -4);
|
||||
}
|
||||
|
||||
/**
|
||||
* 날짜 포맷팅
|
||||
*/
|
||||
function formatDate($date) {
|
||||
if (empty($date)) return '';
|
||||
if (strlen($date) === 8) {
|
||||
return substr($date, 0, 4) . '-' . substr($date, 4, 2) . '-' . substr($date, 6, 2);
|
||||
}
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* 카드번호로 카드 종류 추측 (BIN 코드 기반)
|
||||
*/
|
||||
function guessCardTypeFromNumber($cardNum) {
|
||||
if (empty($cardNum) || strlen($cardNum) < 4) {
|
||||
return '카드';
|
||||
}
|
||||
|
||||
$bin = substr($cardNum, 0, 4);
|
||||
|
||||
// 주요 카드사 BIN 코드
|
||||
$binMappings = [
|
||||
'4518' => '비자',
|
||||
'4092' => '비자',
|
||||
'4569' => '비자',
|
||||
'4563' => '비자',
|
||||
'5' => '마스터카드', // 5로 시작
|
||||
'3528' => 'JCB',
|
||||
'3529' => 'JCB',
|
||||
'3' => '아멕스/다이너스', // 34, 37로 시작
|
||||
'9' => '국내전용카드'
|
||||
];
|
||||
|
||||
// 정확한 매칭 시도
|
||||
if (isset($binMappings[$bin])) {
|
||||
return $binMappings[$bin];
|
||||
}
|
||||
|
||||
// 첫 번째 숫자로 매칭 시도
|
||||
$firstDigit = substr($cardNum, 0, 1);
|
||||
if (isset($binMappings[$firstDigit])) {
|
||||
return $binMappings[$firstDigit];
|
||||
}
|
||||
|
||||
return '카드';
|
||||
}
|
||||
|
||||
/**
|
||||
* 카드사 코드 -> 이름 변환
|
||||
* 바로빌 카드사 코드 참고
|
||||
*/
|
||||
function getCardCompanyName($code) {
|
||||
$companies = [
|
||||
'01' => '비씨카드',
|
||||
'02' => 'KB국민카드',
|
||||
'03' => '하나카드(외환)',
|
||||
'04' => '삼성카드',
|
||||
'06' => '신한카드',
|
||||
'07' => '현대카드',
|
||||
'08' => '롯데카드',
|
||||
'11' => 'NH농협카드',
|
||||
'12' => '수협카드',
|
||||
'13' => '씨티카드',
|
||||
'14' => '우리카드',
|
||||
'15' => '광주카드',
|
||||
'16' => '전북카드',
|
||||
'21' => '하나카드',
|
||||
'22' => '제주카드',
|
||||
'23' => 'SC제일카드',
|
||||
'25' => 'KDB산업카드',
|
||||
'26' => 'IBK기업카드',
|
||||
'27' => '새마을금고',
|
||||
'28' => '신협카드',
|
||||
'29' => '저축은행',
|
||||
'30' => '우체국카드',
|
||||
'31' => '카카오뱅크',
|
||||
'32' => 'K뱅크',
|
||||
'33' => '토스뱅크',
|
||||
'BC' => '비씨카드',
|
||||
'KB' => 'KB국민카드',
|
||||
'HANA' => '하나카드',
|
||||
'SAMSUNG' => '삼성카드',
|
||||
'SHINHAN' => '신한카드',
|
||||
'HYUNDAI' => '현대카드',
|
||||
'LOTTE' => '롯데카드',
|
||||
'NH' => 'NH농협카드',
|
||||
'SUHYUP' => '수협카드',
|
||||
'CITI' => '씨티카드',
|
||||
'WOORI' => '우리카드',
|
||||
'KJBANK' => '광주카드',
|
||||
'JBBANK' => '전북카드'
|
||||
];
|
||||
return $companies[$code] ?? $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* 카드 종류 코드 -> 이름 변환
|
||||
*/
|
||||
function getCardTypeName($type) {
|
||||
$types = [
|
||||
'1' => '개인카드',
|
||||
'2' => '법인카드'
|
||||
];
|
||||
return $types[$type] ?? $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 카드 상태 코드 -> 이름 변환
|
||||
*/
|
||||
function getCardStatusName($status) {
|
||||
$statuses = [
|
||||
'0' => '대기중',
|
||||
'1' => '정상',
|
||||
'2' => '해지',
|
||||
'3' => '수집오류',
|
||||
'4' => '일시중지'
|
||||
];
|
||||
return $statuses[$status] ?? $status;
|
||||
}
|
||||
|
||||
/**
|
||||
* 수집주기 코드 -> 이름 변환
|
||||
*/
|
||||
function getCollectCycleName($cycle) {
|
||||
$cycles = [
|
||||
'1' => '1일 1회',
|
||||
'2' => '1일 2회',
|
||||
'3' => '1일 3회'
|
||||
];
|
||||
return $cycles[$cycle] ?? $cycle;
|
||||
}
|
||||
|
||||
/**
|
||||
* 수집결과 코드 -> 이름 변환
|
||||
*/
|
||||
function getCollectResultName($result) {
|
||||
$results = [
|
||||
'0' => '대기',
|
||||
'1' => '성공',
|
||||
'2' => '실패',
|
||||
'3' => '진행중'
|
||||
];
|
||||
return $results[$result] ?? $result;
|
||||
}
|
||||
?>
|
||||
|
||||
65
ecard/api/debug_raw.php
Normal file
65
ecard/api/debug_raw.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
/**
|
||||
* 바로빌 API 응답 raw 데이터 확인용 (디버그)
|
||||
*/
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
require_once('barobill_card_config.php');
|
||||
|
||||
try {
|
||||
$startDate = $_GET['startDate'] ?? date('Ymd', strtotime('-60 days'));
|
||||
$endDate = $_GET['endDate'] ?? date('Ymd');
|
||||
|
||||
// SOAP 직접 호출
|
||||
global $barobillCardSoapClient, $barobillCertKey, $barobillCorpNum;
|
||||
|
||||
$params = [
|
||||
'CERTKEY' => $barobillCertKey,
|
||||
'CorpNum' => $barobillCorpNum,
|
||||
'ID' => '',
|
||||
'CardNum' => '',
|
||||
'StartDate' => $startDate,
|
||||
'EndDate' => $endDate,
|
||||
'CountPerPage' => 10,
|
||||
'CurrentPage' => 1,
|
||||
'OrderDirection' => 2
|
||||
];
|
||||
|
||||
$result = $barobillCardSoapClient->GetPeriodCardApprovalLog($params);
|
||||
$resultData = $result->GetPeriodCardApprovalLogResult;
|
||||
|
||||
// raw 데이터 출력
|
||||
$output = [
|
||||
'params' => $params,
|
||||
'resultKeys' => is_object($resultData) ? array_keys(get_object_vars($resultData)) : 'not object',
|
||||
'CurrentPage' => $resultData->CurrentPage ?? null,
|
||||
'MaxIndex' => $resultData->MaxIndex ?? null
|
||||
];
|
||||
|
||||
// CardLogList 확인
|
||||
if (isset($resultData->CardLogList)) {
|
||||
$output['CardLogListKeys'] = is_object($resultData->CardLogList) ? array_keys(get_object_vars($resultData->CardLogList)) : 'not object';
|
||||
|
||||
if (isset($resultData->CardLogList->CardApprovalLog)) {
|
||||
$logs = $resultData->CardLogList->CardApprovalLog;
|
||||
if (!is_array($logs)) {
|
||||
$logs = [$logs];
|
||||
}
|
||||
|
||||
if (!empty($logs)) {
|
||||
$firstLog = $logs[0];
|
||||
$output['firstLogKeys'] = is_object($firstLog) ? array_keys(get_object_vars($firstLog)) : 'not object';
|
||||
$output['firstLogData'] = $firstLog;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode($output, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
|
||||
|
||||
} catch (Exception $e) {
|
||||
echo json_encode([
|
||||
'error' => $e->getMessage()
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
?>
|
||||
|
||||
402
ecard/api/usage.php
Normal file
402
ecard/api/usage.php
Normal file
@@ -0,0 +1,402 @@
|
||||
<?php
|
||||
/**
|
||||
* 카드 사용내역 조회 API
|
||||
*
|
||||
* ============================================================================
|
||||
* 데이터 흐름
|
||||
* ============================================================================
|
||||
*
|
||||
* [호출 경로]
|
||||
* 화면(ecard/index.php) → 이 API(usage.php) → barobill_card_config.php::getPeriodCardUsage()
|
||||
* → 바로빌 SOAP API(GetPeriodCardApprovalLog) → 바로빌 서버
|
||||
*
|
||||
* [사용내역 정보 출처]
|
||||
* - 바로빌이 카드사에서 자동으로 수집한 사용내역
|
||||
* - 카드 등록 시 설정한 수집주기(CollectCycle)에 따라 1일 1회~3회 자동 수집
|
||||
* - 수집된 데이터는 바로빌 서버에 저장됨
|
||||
*
|
||||
* [수집 과정]
|
||||
* 1. 카드 등록 시 Web ID/비밀번호로 카드사 홈페이지에 로그인
|
||||
* 2. 바로빌이 설정된 수집주기에 따라 카드사에서 사용내역 자동 수집
|
||||
* 3. 수집된 데이터를 바로빌 서버에 저장
|
||||
* 4. 이 API를 통해 저장된 사용내역 조회
|
||||
*
|
||||
* 파라미터:
|
||||
* - type: daily(일별), monthly(월별), period(기간별, 기본값)
|
||||
* - cardNum: 카드번호 (빈값이면 전체)
|
||||
* - startDate: 시작일 (YYYYMMDD) - period 타입
|
||||
* - endDate: 종료일 (YYYYMMDD) - period 타입
|
||||
* - baseDate: 기준일 (YYYYMMDD) - daily 타입
|
||||
* - baseMonth: 기준월 (YYYYMM) - monthly 타입
|
||||
* - page: 페이지 번호 (기본 1)
|
||||
* - limit: 페이지당 건수 (기본 50)
|
||||
* - debug: 1이면 디버그 정보 포함
|
||||
*
|
||||
* [반환 데이터]
|
||||
* - approvalDateTime: 승인일시
|
||||
* - cardNum: 카드번호 (마스킹)
|
||||
* - cardNumFull: 카드번호 (전체)
|
||||
* - merchantName: 가맹점명
|
||||
* - merchantBizNum: 가맹점 사업자번호
|
||||
* - amount: 승인금액
|
||||
* - vat: 부가세
|
||||
* - serviceCharge: 봉사료
|
||||
* - approvalType: 승인유형 (1=승인, 2=취소)
|
||||
* - installment: 할부개월 (0=일시불)
|
||||
* - approvalNum: 승인번호
|
||||
*/
|
||||
header('Content-Type: application/json; charset=utf-8');
|
||||
|
||||
require_once('barobill_card_config.php');
|
||||
|
||||
// 디버그 모드
|
||||
$debugMode = isset($_GET['debug']) && $_GET['debug'] == '1';
|
||||
|
||||
try {
|
||||
$type = $_GET['type'] ?? 'period';
|
||||
$cardNum = $_GET['cardNum'] ?? '';
|
||||
$page = max(1, intval($_GET['page'] ?? 1));
|
||||
$limit = min(100, max(10, intval($_GET['limit'] ?? 50)));
|
||||
$orderDirection = intval($_GET['order'] ?? 2); // 2: 내림차순 (최신순)
|
||||
|
||||
$result = null;
|
||||
|
||||
// cardNum이 빈 값이면 전체 카드 조회 (각 카드별로 조회 후 병합)
|
||||
if (empty($cardNum)) {
|
||||
// 등록된 카드 목록 조회
|
||||
$cardsResult = getCardList(1); // 사용 가능한 카드만
|
||||
if (!$cardsResult['success'] || empty($cardsResult['data'])) {
|
||||
$result = [
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'currentPage' => 1,
|
||||
'countPerPage' => $limit,
|
||||
'maxPageNum' => 1,
|
||||
'maxIndex' => 0,
|
||||
'logs' => []
|
||||
]
|
||||
];
|
||||
} else {
|
||||
// 각 카드별로 조회 후 병합
|
||||
$allLogs = [];
|
||||
foreach ($cardsResult['data'] as $card) {
|
||||
$cardNumToQuery = $card->CardNum ?? '';
|
||||
if (empty($cardNumToQuery)) continue;
|
||||
|
||||
switch ($type) {
|
||||
case 'daily':
|
||||
$baseDate = $_GET['baseDate'] ?? date('Ymd');
|
||||
$tempResult = getDailyCardUsage($cardNumToQuery, $baseDate, 100, 1, $orderDirection);
|
||||
break;
|
||||
case 'monthly':
|
||||
$baseMonth = $_GET['baseMonth'] ?? date('Ym');
|
||||
$tempResult = getMonthlyCardUsage($cardNumToQuery, $baseMonth, 100, 1, $orderDirection);
|
||||
break;
|
||||
case 'period':
|
||||
default:
|
||||
$startDate = $_GET['startDate'] ?? date('Ymd', strtotime('-30 days'));
|
||||
$endDate = $_GET['endDate'] ?? date('Ymd');
|
||||
$tempResult = getPeriodCardUsage($cardNumToQuery, $startDate, $endDate, 100, 1, $orderDirection);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($tempResult['success'] && !empty($tempResult['data']['logs'])) {
|
||||
$allLogs = array_merge($allLogs, $tempResult['data']['logs']);
|
||||
}
|
||||
}
|
||||
|
||||
// UseDT 기준으로 정렬
|
||||
usort($allLogs, function($a, $b) use ($orderDirection) {
|
||||
$aTime = $a->UseDT ?? '';
|
||||
$bTime = $b->UseDT ?? '';
|
||||
return $orderDirection == 1 ? strcmp($aTime, $bTime) : strcmp($bTime, $aTime);
|
||||
});
|
||||
|
||||
// 페이징 처리
|
||||
$totalCount = count($allLogs);
|
||||
$maxPageNum = ceil($totalCount / $limit);
|
||||
$offset = ($page - 1) * $limit;
|
||||
$pagedLogs = array_slice($allLogs, $offset, $limit);
|
||||
|
||||
$result = [
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'currentPage' => $page,
|
||||
'countPerPage' => $limit,
|
||||
'maxPageNum' => $maxPageNum,
|
||||
'maxIndex' => $totalCount,
|
||||
'logs' => $pagedLogs
|
||||
]
|
||||
];
|
||||
}
|
||||
} else {
|
||||
// 특정 카드 조회
|
||||
switch ($type) {
|
||||
case 'daily':
|
||||
$baseDate = $_GET['baseDate'] ?? date('Ymd');
|
||||
$result = getDailyCardUsage($cardNum, $baseDate, $limit, $page, $orderDirection);
|
||||
break;
|
||||
|
||||
case 'monthly':
|
||||
$baseMonth = $_GET['baseMonth'] ?? date('Ym');
|
||||
$result = getMonthlyCardUsage($cardNum, $baseMonth, $limit, $page, $orderDirection);
|
||||
break;
|
||||
|
||||
case 'period':
|
||||
default:
|
||||
$startDate = $_GET['startDate'] ?? date('Ymd', strtotime('-30 days'));
|
||||
$endDate = $_GET['endDate'] ?? date('Ymd');
|
||||
$result = getPeriodCardUsage($cardNum, $startDate, $endDate, $limit, $page, $orderDirection);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($result['success']) {
|
||||
$logs = [];
|
||||
|
||||
// 디버그: raw 로그 데이터 출력
|
||||
if ($debugMode && !empty($result['data']['logs'])) {
|
||||
$firstLog = $result['data']['logs'][0];
|
||||
error_log('CardApprovalLog raw data: ' . print_r($firstLog, true));
|
||||
// 디버그: 모든 필드명 확인
|
||||
if (is_object($firstLog)) {
|
||||
$fields = get_object_vars($firstLog);
|
||||
error_log('CardApprovalLog fields: ' . implode(', ', array_keys($fields)));
|
||||
error_log('ApprovalAmount value: ' . ($firstLog->ApprovalAmount ?? 'NOT SET'));
|
||||
error_log('Amount value: ' . ($firstLog->Amount ?? 'NOT SET'));
|
||||
error_log('TotalAmount value: ' . ($firstLog->TotalAmount ?? 'NOT SET'));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($result['data']['logs'] as $log) {
|
||||
// UseDT 형식: YYYYMMDDHHMMSS
|
||||
$useDT = $log->UseDT ?? '';
|
||||
$approvalDate = '';
|
||||
$approvalTime = '';
|
||||
if (strlen($useDT) >= 8) {
|
||||
$approvalDate = substr($useDT, 0, 4) . '-' . substr($useDT, 4, 2) . '-' . substr($useDT, 6, 2);
|
||||
}
|
||||
if (strlen($useDT) >= 14) {
|
||||
$approvalTime = substr($useDT, 8, 2) . ':' . substr($useDT, 10, 2) . ':' . substr($useDT, 12, 2);
|
||||
} elseif (strlen($useDT) >= 12) {
|
||||
$approvalTime = substr($useDT, 8, 2) . ':' . substr($useDT, 10, 2);
|
||||
}
|
||||
|
||||
$logs[] = [
|
||||
'cardNum' => maskCardNumber($log->CardNum ?? ''),
|
||||
'cardNumFull' => $log->CardNum ?? '',
|
||||
'approvalNum' => $log->ApprovalNum ?? '',
|
||||
'approvalDate' => $approvalDate,
|
||||
'approvalTime' => $approvalTime,
|
||||
'approvalDateTime' => $approvalDate . ' ' . $approvalTime,
|
||||
'merchantName' => $log->UseStoreName ?? '',
|
||||
'merchantBizNum' => $log->UseStoreCorpNum ?? '',
|
||||
// 금액 필드: 여러 가능한 필드명 시도
|
||||
// ApprovalAmount가 실제 승인금액 (화면에 표시할 금액)
|
||||
'amount' => intval($log->ApprovalAmount ?? 0),
|
||||
'amountFormatted' => number_format(intval($log->ApprovalAmount ?? 0)),
|
||||
'vat' => intval($log->Tax ?? 0),
|
||||
'vatFormatted' => number_format(intval($log->Tax ?? 0)),
|
||||
'serviceCharge' => intval($log->ServiceCharge ?? 0),
|
||||
// totalAmount는 화면에서 사용하므로 ApprovalAmount를 사용
|
||||
'totalAmount' => intval($log->ApprovalAmount ?? 0),
|
||||
'totalAmountFormatted' => number_format(intval($log->ApprovalAmount ?? 0)),
|
||||
'approvalType' => $log->ApprovalType ?? '',
|
||||
'approvalTypeName' => getApprovalTypeName($log->ApprovalType ?? ''),
|
||||
'installment' => $log->PaymentPlan ?? '',
|
||||
'installmentName' => getInstallmentName($log->PaymentPlan ?? ''),
|
||||
'currencyCode' => $log->CurrencyCode ?? 'KRW',
|
||||
'memo' => $log->Memo ?? '',
|
||||
'cardCompany' => $log->CardCompany ?? '',
|
||||
'cardCompanyName' => getCardCompanyNameFromLog($log->CardCompany ?? ''),
|
||||
// 추가 필드
|
||||
'useKey' => $log->UseKey ?? '',
|
||||
'storeAddress' => $log->UseStoreAddr ?? '',
|
||||
'storeCeo' => $log->UseStoreCeo ?? '',
|
||||
'storeBizType' => $log->UseStoreBizType ?? '',
|
||||
'storeTel' => $log->UseStoreTel ?? ''
|
||||
];
|
||||
}
|
||||
|
||||
// 통계 계산
|
||||
$totalAmount = array_sum(array_column($logs, 'totalAmount'));
|
||||
$approvalCount = count(array_filter($logs, function($l) { return $l['approvalType'] == '1'; }));
|
||||
$cancelCount = count(array_filter($logs, function($l) { return $l['approvalType'] == '2'; }));
|
||||
|
||||
$response = [
|
||||
'success' => true,
|
||||
'data' => [
|
||||
'logs' => $logs,
|
||||
'pagination' => [
|
||||
'currentPage' => $result['data']['currentPage'],
|
||||
'countPerPage' => $result['data']['countPerPage'],
|
||||
'maxPageNum' => $result['data']['maxPageNum'],
|
||||
'totalCount' => $result['data']['maxIndex']
|
||||
],
|
||||
'summary' => [
|
||||
'totalAmount' => $totalAmount,
|
||||
'totalAmountFormatted' => number_format($totalAmount),
|
||||
'count' => count($logs),
|
||||
'approvalCount' => $approvalCount,
|
||||
'cancelCount' => $cancelCount
|
||||
]
|
||||
]
|
||||
];
|
||||
|
||||
// 디버그 정보 추가 (성공한 경우에도 항상 첫 번째 로그의 필드 정보 출력)
|
||||
if (!empty($result['data']['logs'])) {
|
||||
$firstLog = $result['data']['logs'][0];
|
||||
if (is_object($firstLog)) {
|
||||
// 모든 필드를 배열로 변환
|
||||
$allFields = get_object_vars($firstLog);
|
||||
$fieldNames = array_keys($allFields);
|
||||
|
||||
// 금액 관련 필드 찾기 (대소문자 구분 없이)
|
||||
$amountFields = [];
|
||||
foreach ($fieldNames as $fieldName) {
|
||||
if (stripos($fieldName, 'amount') !== false ||
|
||||
stripos($fieldName, 'cost') !== false ||
|
||||
stripos($fieldName, 'price') !== false ||
|
||||
stripos($fieldName, '금액') !== false) {
|
||||
$amountFields[$fieldName] = (string)($firstLog->$fieldName ?? 'NULL');
|
||||
}
|
||||
}
|
||||
|
||||
// 디버그 모드일 때만 상세 정보 출력
|
||||
if ($debugMode) {
|
||||
$response['debug'] = [
|
||||
'userId' => getBarobillUserId(),
|
||||
'params' => $_GET,
|
||||
'firstLogFields' => $fieldNames,
|
||||
'firstLogAllValues' => array_map(function($v) {
|
||||
return is_string($v) ? $v : (is_numeric($v) ? (string)$v : gettype($v));
|
||||
}, $allFields),
|
||||
'amountFields' => $amountFields
|
||||
];
|
||||
} else {
|
||||
// 디버그 모드가 아니어도 금액 필드 정보는 항상 포함 (문제 해결용)
|
||||
$response['debug'] = [
|
||||
'amountFields' => $amountFields,
|
||||
'allFields' => $fieldNames
|
||||
];
|
||||
}
|
||||
}
|
||||
} elseif ($debugMode) {
|
||||
$response['debug'] = [
|
||||
'userId' => getBarobillUserId(),
|
||||
'params' => $_GET,
|
||||
'message' => 'No logs found'
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode($response, JSON_UNESCAPED_UNICODE);
|
||||
} else {
|
||||
$response = [
|
||||
'success' => false,
|
||||
'error' => $result['error'],
|
||||
'error_code' => $result['error_code'] ?? null
|
||||
];
|
||||
|
||||
// 디버그 정보 추가
|
||||
if ($debugMode) {
|
||||
$response['debug'] = [
|
||||
'userId' => getBarobillUserId(),
|
||||
'params' => $_GET
|
||||
];
|
||||
}
|
||||
|
||||
echo json_encode($response, JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
echo json_encode([
|
||||
'success' => false,
|
||||
'error' => '서버 오류: ' . $e->getMessage()
|
||||
], JSON_UNESCAPED_UNICODE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 카드번호 마스킹
|
||||
*/
|
||||
function maskCardNumber($cardNum) {
|
||||
if (strlen($cardNum) < 8) return $cardNum;
|
||||
return substr($cardNum, 0, 4) . '-****-****-' . substr($cardNum, -4);
|
||||
}
|
||||
|
||||
/**
|
||||
* 날짜 포맷팅
|
||||
*/
|
||||
function formatDate($date) {
|
||||
if (strlen($date) === 8) {
|
||||
return substr($date, 0, 4) . '-' . substr($date, 4, 2) . '-' . substr($date, 6, 2);
|
||||
}
|
||||
return $date;
|
||||
}
|
||||
|
||||
/**
|
||||
* 시간 포맷팅
|
||||
*/
|
||||
function formatTime($time) {
|
||||
if (strlen($time) === 6) {
|
||||
return substr($time, 0, 2) . ':' . substr($time, 2, 2) . ':' . substr($time, 4, 2);
|
||||
} elseif (strlen($time) === 4) {
|
||||
return substr($time, 0, 2) . ':' . substr($time, 2, 2);
|
||||
}
|
||||
return $time;
|
||||
}
|
||||
|
||||
/**
|
||||
* 승인 유형 이름
|
||||
*/
|
||||
function getApprovalTypeName($type) {
|
||||
$types = [
|
||||
'1' => '승인',
|
||||
'2' => '취소'
|
||||
];
|
||||
return $types[$type] ?? $type;
|
||||
}
|
||||
|
||||
/**
|
||||
* 할부 이름
|
||||
*/
|
||||
function getInstallmentName($installment) {
|
||||
if (empty($installment) || $installment == '0' || $installment == '00') {
|
||||
return '일시불';
|
||||
}
|
||||
return $installment . '개월';
|
||||
}
|
||||
|
||||
/**
|
||||
* 카드사 이름 (로그용)
|
||||
*/
|
||||
function getCardCompanyNameFromLog($code) {
|
||||
$companies = [
|
||||
'01' => '비씨',
|
||||
'02' => 'KB국민',
|
||||
'03' => '하나(외환)',
|
||||
'04' => '삼성',
|
||||
'06' => '신한',
|
||||
'07' => '현대',
|
||||
'08' => '롯데',
|
||||
'11' => 'NH농협',
|
||||
'12' => '수협',
|
||||
'13' => '씨티',
|
||||
'14' => '우리',
|
||||
'15' => '광주',
|
||||
'16' => '전북',
|
||||
'21' => '하나',
|
||||
'22' => '제주',
|
||||
'23' => 'SC제일',
|
||||
'25' => 'KDB산업',
|
||||
'26' => 'IBK기업',
|
||||
'27' => '새마을금고',
|
||||
'28' => '신협',
|
||||
'29' => '저축은행',
|
||||
'30' => '우체국',
|
||||
'31' => '카카오뱅크',
|
||||
'32' => 'K뱅크',
|
||||
'33' => '토스뱅크'
|
||||
];
|
||||
return $companies[$code] ?? $code;
|
||||
}
|
||||
?>
|
||||
|
||||
Reference in New Issue
Block a user