- BarobillSoapService: PHP SoapClient 기반 SOAP 래퍼 (회원/계좌/카드/인증서) - BarobillBankSyncService: 은행 거래내역 SOAP 조회 → DB 캐시 동기화 - BarobillCardSyncService: 카드 거래내역 SOAP 조회 → DB 캐시 동기화 - HometaxSyncService: 홈택스 세금계산서 upsert 동기화 - BarobillSyncController: 동기화/회원/인증서/잔액 API 11개 엔드포인트 - SyncBarobillDataJob: 매일 06:00/06:30 자동 동기화 스케줄러 - BarobillController.status() 보강: 실제 계좌/카드 수 표시
663 lines
22 KiB
PHP
663 lines
22 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Barobill;
|
|
|
|
use App\Models\Barobill\BarobillConfig;
|
|
use App\Models\Barobill\BarobillMember;
|
|
use App\Services\Service;
|
|
use Illuminate\Support\Facades\Log;
|
|
use SoapClient;
|
|
use SoapFault;
|
|
use Throwable;
|
|
|
|
/**
|
|
* 바로빌 SOAP API 서비스 (API 프로젝트 독립 구현)
|
|
*
|
|
* MNG의 BarobillService 패턴을 참고하여 API 프로젝트용으로 독립 작성.
|
|
* 서비스 고객(tenant_id=2~N)이 사용하는 SOAP 호출을 담당한다.
|
|
*
|
|
* @see https://dev.barobill.co.kr/
|
|
* @see https://ws.baroservice.com/CORPSTATE.asmx (회원관리)
|
|
* @see https://ws.baroservice.com/BANKACCOUNT.asmx (계좌조회)
|
|
* @see https://ws.baroservice.com/CARD.asmx (카드조회)
|
|
* @see https://ws.baroservice.com/TI.asmx (세금계산서)
|
|
*/
|
|
class BarobillSoapService extends Service
|
|
{
|
|
protected ?SoapClient $corpStateClient = null;
|
|
|
|
protected ?SoapClient $bankAccountClient = null;
|
|
|
|
protected ?SoapClient $cardClient = null;
|
|
|
|
protected ?SoapClient $tiClient = null;
|
|
|
|
protected string $certKey = '';
|
|
|
|
protected string $corpNum = '';
|
|
|
|
protected bool $isTestMode = true;
|
|
|
|
protected array $soapUrls = [];
|
|
|
|
/**
|
|
* 에러 코드 매핑
|
|
*/
|
|
protected array $errorMessages = [
|
|
-11101 => '사업자번호가 설정되지 않았거나 유효하지 않습니다.',
|
|
-11102 => 'CERTKEY가 유효하지 않습니다.',
|
|
-11103 => '인증서가 만료되었거나 유효하지 않습니다.',
|
|
-11104 => '해당 사업자가 등록되어 있지 않습니다.',
|
|
-11105 => '이미 등록된 사업자입니다.',
|
|
-11106 => '아이디가 이미 존재합니다.',
|
|
-11201 => '필수 파라미터가 누락되었습니다.',
|
|
-25001 => '조회 결과가 없습니다.',
|
|
-25005 => '조회 기간에 데이터가 없습니다.',
|
|
-26001 => '공동인증서가 등록되어 있지 않습니다.',
|
|
-32000 => '알 수 없는 오류가 발생했습니다.',
|
|
-32001 => '사업자번호가 유효하지 않습니다.',
|
|
-32002 => '아이디가 유효하지 않습니다.',
|
|
-32003 => '비밀번호가 유효하지 않습니다.',
|
|
-32004 => '상호명이 유효하지 않습니다.',
|
|
-32005 => '대표자명이 유효하지 않습니다.',
|
|
-32006 => '이메일 형식이 유효하지 않습니다.',
|
|
-32010 => '이미 등록된 사업자번호입니다.',
|
|
-32011 => '이미 등록된 아이디입니다.',
|
|
-32012 => '이미 등록된 아이디입니다. 다른 아이디를 사용해주세요.',
|
|
-32013 => '비밀번호 형식이 유효하지 않습니다. (영문/숫자/특수문자 조합 8자리 이상)',
|
|
-32014 => '연락처 형식이 유효하지 않습니다.',
|
|
-32020 => '파트너 사업자번호가 유효하지 않습니다.',
|
|
-32021 => '파트너 인증키(CERTKEY)가 유효하지 않습니다.',
|
|
-99999 => '서버 내부 오류가 발생했습니다.',
|
|
];
|
|
|
|
public function __construct()
|
|
{
|
|
$this->isTestMode = (bool) config('services.barobill.test_mode', true);
|
|
$this->initializeConfig();
|
|
}
|
|
|
|
// =========================================================================
|
|
// 설정/초기화
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 서버 모드 전환 (회원사별 설정 적용)
|
|
*/
|
|
public function switchServerMode(bool $isTestMode): self
|
|
{
|
|
if ($this->isTestMode !== $isTestMode) {
|
|
$this->isTestMode = $isTestMode;
|
|
$this->resetClients();
|
|
$this->initializeConfig();
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* 서버 모드 문자열로 전환
|
|
*/
|
|
public function setServerMode(string $mode): self
|
|
{
|
|
return $this->switchServerMode($mode === 'test');
|
|
}
|
|
|
|
public function getServerMode(): string
|
|
{
|
|
return $this->isTestMode ? 'test' : 'production';
|
|
}
|
|
|
|
/**
|
|
* 설정 초기화 (서버 모드에 따른 설정 로드)
|
|
*/
|
|
protected function initializeConfig(): void
|
|
{
|
|
$dbConfig = $this->loadConfigFromDatabase();
|
|
|
|
if ($dbConfig) {
|
|
$this->certKey = $dbConfig->cert_key;
|
|
$this->corpNum = $dbConfig->corp_num ?? '';
|
|
$this->soapUrls = $this->buildSoapUrls($dbConfig->base_url);
|
|
} else {
|
|
$this->certKey = $this->isTestMode
|
|
? config('services.barobill.cert_key_test', '')
|
|
: config('services.barobill.cert_key_prod', '');
|
|
$this->corpNum = config('services.barobill.corp_num', '');
|
|
$baseUrl = $this->isTestMode
|
|
? 'https://testws.baroservice.com'
|
|
: 'https://ws.baroservice.com';
|
|
$this->soapUrls = $this->buildSoapUrls($baseUrl);
|
|
}
|
|
}
|
|
|
|
protected function loadConfigFromDatabase(): ?BarobillConfig
|
|
{
|
|
try {
|
|
return BarobillConfig::getActive($this->isTestMode);
|
|
} catch (\Exception $e) {
|
|
Log::warning('[BarobillSoap] DB 설정 로드 실패', ['error' => $e->getMessage()]);
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
protected function buildSoapUrls(string $baseUrl): array
|
|
{
|
|
$baseUrl = rtrim($baseUrl, '/');
|
|
|
|
return [
|
|
'corpstate' => $baseUrl.'/CORPSTATE.asmx?WSDL',
|
|
'ti' => $baseUrl.'/TI.asmx?WSDL',
|
|
'bankaccount' => $baseUrl.'/BANKACCOUNT.asmx?WSDL',
|
|
'card' => $baseUrl.'/CARD.asmx?WSDL',
|
|
];
|
|
}
|
|
|
|
protected function resetClients(): void
|
|
{
|
|
$this->corpStateClient = null;
|
|
$this->bankAccountClient = null;
|
|
$this->cardClient = null;
|
|
$this->tiClient = null;
|
|
}
|
|
|
|
/**
|
|
* 설정 상태 확인
|
|
*/
|
|
public function checkConfiguration(): array
|
|
{
|
|
$dbConfig = $this->loadConfigFromDatabase();
|
|
|
|
return [
|
|
'cert_key_set' => ! empty($this->certKey),
|
|
'corp_num_set' => ! empty($this->corpNum),
|
|
'test_mode' => $this->isTestMode,
|
|
'mode_label' => $this->isTestMode ? '테스트' : '운영',
|
|
'soap_url' => $this->soapUrls['corpstate'] ?? '',
|
|
'config_source' => $dbConfig ? 'database' : 'env',
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 회원사 설정 기반 초기화 (동기화 서비스에서 사용)
|
|
*/
|
|
public function initForMember(BarobillMember $member): self
|
|
{
|
|
$this->switchServerMode($member->isTestMode());
|
|
|
|
return $this;
|
|
}
|
|
|
|
// =========================================================================
|
|
// SOAP 클라이언트
|
|
// =========================================================================
|
|
|
|
protected function createSoapClient(string $wsdlUrl): ?SoapClient
|
|
{
|
|
try {
|
|
$context = stream_context_create([
|
|
'ssl' => [
|
|
'verify_peer' => false,
|
|
'verify_peer_name' => false,
|
|
'allow_self_signed' => true,
|
|
],
|
|
]);
|
|
|
|
return new SoapClient($wsdlUrl, [
|
|
'trace' => true,
|
|
'encoding' => 'UTF-8',
|
|
'exceptions' => true,
|
|
'connection_timeout' => 30,
|
|
'stream_context' => $context,
|
|
'cache_wsdl' => WSDL_CACHE_BOTH,
|
|
]);
|
|
} catch (Throwable $e) {
|
|
Log::error('[BarobillSoap] 클라이언트 생성 실패', [
|
|
'url' => $wsdlUrl,
|
|
'error' => $e->getMessage(),
|
|
]);
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
protected function getCorpStateClient(): ?SoapClient
|
|
{
|
|
return $this->corpStateClient ??= $this->createSoapClient($this->soapUrls['corpstate']);
|
|
}
|
|
|
|
protected function getBankAccountClient(): ?SoapClient
|
|
{
|
|
return $this->bankAccountClient ??= $this->createSoapClient($this->soapUrls['bankaccount']);
|
|
}
|
|
|
|
protected function getCardClient(): ?SoapClient
|
|
{
|
|
return $this->cardClient ??= $this->createSoapClient($this->soapUrls['card']);
|
|
}
|
|
|
|
protected function getTiClient(): ?SoapClient
|
|
{
|
|
return $this->tiClient ??= $this->createSoapClient($this->soapUrls['ti']);
|
|
}
|
|
|
|
// =========================================================================
|
|
// SOAP 호출 (핵심)
|
|
// =========================================================================
|
|
|
|
/**
|
|
* SOAP 메서드 호출
|
|
*/
|
|
public function call(string $service, string $method, array $params = []): array
|
|
{
|
|
$client = match ($service) {
|
|
'corpstate' => $this->getCorpStateClient(),
|
|
'ti' => $this->getTiClient(),
|
|
'bankaccount' => $this->getBankAccountClient(),
|
|
'card' => $this->getCardClient(),
|
|
default => null,
|
|
};
|
|
|
|
if (! $client) {
|
|
return [
|
|
'success' => false,
|
|
'error' => "SOAP 클라이언트 초기화 실패 ({$service})",
|
|
'error_code' => -1,
|
|
];
|
|
}
|
|
|
|
if (empty($this->certKey)) {
|
|
return [
|
|
'success' => false,
|
|
'error' => 'CERTKEY가 설정되지 않았습니다.',
|
|
'error_code' => -2,
|
|
];
|
|
}
|
|
|
|
if (! isset($params['CERTKEY'])) {
|
|
$params['CERTKEY'] = $this->certKey;
|
|
}
|
|
|
|
try {
|
|
$startTime = microtime(true);
|
|
$result = $client->$method($params);
|
|
$resultProperty = $method.'Result';
|
|
$elapsed = round((microtime(true) - $startTime) * 1000);
|
|
|
|
Log::debug("[BarobillSoap] {$method} 완료 ({$elapsed}ms)");
|
|
|
|
if (isset($result->$resultProperty)) {
|
|
$resultData = $result->$resultProperty;
|
|
|
|
if (is_numeric($resultData) && $resultData < 0) {
|
|
$errorMessage = $this->errorMessages[(int) $resultData]
|
|
?? "바로빌 API 오류 코드: {$resultData}";
|
|
|
|
Log::error('[BarobillSoap] API 오류', [
|
|
'method' => $method,
|
|
'error_code' => $resultData,
|
|
'error_message' => $errorMessage,
|
|
]);
|
|
|
|
return [
|
|
'success' => false,
|
|
'error' => $errorMessage,
|
|
'error_code' => (int) $resultData,
|
|
'data' => $resultData,
|
|
];
|
|
}
|
|
|
|
return ['success' => true, 'data' => $resultData];
|
|
}
|
|
|
|
return ['success' => true, 'data' => $result];
|
|
|
|
} catch (SoapFault $e) {
|
|
Log::error('[BarobillSoap] SOAP 오류', [
|
|
'method' => $method,
|
|
'fault' => $e->getMessage(),
|
|
]);
|
|
|
|
return [
|
|
'success' => false,
|
|
'error' => 'SOAP 오류: '.$e->getMessage(),
|
|
'error_code' => $e->getCode(),
|
|
];
|
|
} catch (Throwable $e) {
|
|
Log::error('[BarobillSoap] 호출 오류', [
|
|
'method' => $method,
|
|
'error' => $e->getMessage(),
|
|
]);
|
|
|
|
return [
|
|
'success' => false,
|
|
'error' => 'API 호출 오류: '.$e->getMessage(),
|
|
'error_code' => -999,
|
|
];
|
|
}
|
|
}
|
|
|
|
// =========================================================================
|
|
// 회원관리 (CORPSTATE)
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 회원사 등록
|
|
*/
|
|
public function registCorp(array $data): array
|
|
{
|
|
$params = [
|
|
'CorpNum' => $this->formatBizNo($data['biz_no']),
|
|
'CorpName' => $data['corp_name'],
|
|
'CEOName' => $data['ceo_name'],
|
|
'BizType' => $data['biz_type'] ?? '',
|
|
'BizClass' => $data['biz_class'] ?? '',
|
|
'PostNum' => $data['post_num'] ?? '',
|
|
'Addr1' => $data['addr'] ?? '',
|
|
'Addr2' => '',
|
|
'MemberName' => $data['manager_name'] ?? '',
|
|
'JuminNum' => '',
|
|
'ID' => $data['barobill_id'],
|
|
'PWD' => $data['barobill_pwd'],
|
|
'Grade' => '2',
|
|
'TEL' => $data['tel'] ?? '',
|
|
'HP' => $data['manager_hp'] ?? '',
|
|
'Email' => $data['manager_email'] ?? '',
|
|
];
|
|
|
|
return $this->call('corpstate', 'RegistCorp', $params);
|
|
}
|
|
|
|
/**
|
|
* 회원사 정보 수정
|
|
*/
|
|
public function updateCorpInfo(array $data): array
|
|
{
|
|
$params = [
|
|
'CorpNum' => $this->formatBizNo($data['biz_no']),
|
|
'CorpName' => $data['corp_name'],
|
|
'CEOName' => $data['ceo_name'],
|
|
'BizType' => $data['biz_type'] ?? '',
|
|
'BizClass' => $data['biz_class'] ?? '',
|
|
'PostNum' => $data['post_num'] ?? '',
|
|
'Addr1' => $data['addr'] ?? '',
|
|
'Addr2' => '',
|
|
'MemberName' => $data['manager_name'] ?? '',
|
|
'TEL' => $data['tel'] ?? '',
|
|
'HP' => $data['manager_hp'] ?? '',
|
|
'Email' => $data['manager_email'] ?? '',
|
|
];
|
|
|
|
return $this->call('corpstate', 'UpdateCorpInfo', $params);
|
|
}
|
|
|
|
/**
|
|
* 회원사 상태 조회
|
|
*/
|
|
public function getCorpState(string $corpNum): array
|
|
{
|
|
return $this->call('corpstate', 'GetCorpState', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
]);
|
|
}
|
|
|
|
// =========================================================================
|
|
// 계좌조회 (BANKACCOUNT)
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 등록계좌 목록 조회
|
|
*/
|
|
public function getBankAccounts(string $corpNum, bool $availOnly = true): array
|
|
{
|
|
return $this->call('bankaccount', 'GetBankAccountEx', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
'AvailOnly' => $availOnly ? 1 : 0,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 계좌 기간별 입출금내역 조회
|
|
*/
|
|
public function getPeriodBankAccountTransLog(
|
|
string $corpNum,
|
|
string $id,
|
|
string $bankAccountNum,
|
|
string $startDate,
|
|
string $endDate,
|
|
int $countPerPage = 1000,
|
|
int $currentPage = 1
|
|
): array {
|
|
return $this->call('bankaccount', 'GetPeriodBankAccountTransLog', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
'ID' => $id,
|
|
'BankAccountNum' => $bankAccountNum,
|
|
'StartDate' => $startDate,
|
|
'EndDate' => $endDate,
|
|
'TransDirection' => 1,
|
|
'CountPerPage' => $countPerPage,
|
|
'CurrentPage' => $currentPage,
|
|
'OrderDirection' => 2,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 계좌조회 신청 URL 조회
|
|
*/
|
|
public function getBankAccountScrapRequestUrl(string $corpNum, string $userId, string $userPwd): array
|
|
{
|
|
return $this->call('bankaccount', 'GetBankAccountScrapRequestURL', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
'ID' => $userId,
|
|
'PWD' => $userPwd,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 인증서 등록 URL 조회
|
|
*/
|
|
public function getCertificateRegistUrl(string $corpNum, string $userId, string $userPwd): array
|
|
{
|
|
return $this->call('bankaccount', 'GetCertificateRegistURL', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
'ID' => $userId,
|
|
'PWD' => $userPwd,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 인증서 유효성 확인
|
|
*/
|
|
public function checkCertificateValid(string $corpNum): array
|
|
{
|
|
return $this->call('bankaccount', 'CheckCERTIsValid', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 인증서 만료일 조회
|
|
*/
|
|
public function getCertificateExpireDate(string $corpNum): array
|
|
{
|
|
return $this->call('bankaccount', 'GetCertificateExpireDate', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 인증서 등록일 조회
|
|
*/
|
|
public function getCertificateRegistDate(string $corpNum): array
|
|
{
|
|
return $this->call('bankaccount', 'GetCertificateRegistDate', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 충전잔액 조회
|
|
*/
|
|
public function getBalanceCostAmount(string $corpNum): array
|
|
{
|
|
return $this->call('bankaccount', 'GetBalanceCostAmountEx', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 현금충전 URL 조회
|
|
*/
|
|
public function getCashChargeUrl(string $corpNum, string $userId, string $userPwd): array
|
|
{
|
|
return $this->call('bankaccount', 'GetCashChargeURL', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
'ID' => $userId,
|
|
'PWD' => $userPwd,
|
|
]);
|
|
}
|
|
|
|
// =========================================================================
|
|
// 카드조회 (CARD)
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 등록카드 목록 조회
|
|
*/
|
|
public function getCards(string $corpNum, bool $availOnly = true): array
|
|
{
|
|
return $this->call('card', 'GetCardEx2', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
'AvailOnly' => $availOnly ? 1 : 0,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 카드 등록
|
|
*/
|
|
public function registCard(string $corpNum, array $cardData): array
|
|
{
|
|
return $this->call('card', 'RegistCardEx', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
'CardCompany' => $cardData['card_company'] ?? '',
|
|
'CardType' => $cardData['card_type'] ?? '1',
|
|
'CardNum' => preg_replace('/[^0-9]/', '', $cardData['card_num'] ?? ''),
|
|
'WebId' => $cardData['web_id'] ?? '',
|
|
'WebPwd' => $cardData['web_pwd'] ?? '',
|
|
'Alias' => $cardData['alias'] ?? '',
|
|
'Usage' => $cardData['usage'] ?? '',
|
|
'CollectCycle' => $cardData['collect_cycle'] ?? '1',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 카드 기간별 사용내역 조회
|
|
*/
|
|
public function getPeriodCardLog(
|
|
string $corpNum,
|
|
string $id,
|
|
string $cardNum,
|
|
string $startDate,
|
|
string $endDate,
|
|
int $countPerPage = 1000,
|
|
int $currentPage = 1
|
|
): array {
|
|
return $this->call('card', 'GetPeriodCardLog', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
'ID' => $id,
|
|
'CardNum' => preg_replace('/[^0-9]/', '', $cardNum),
|
|
'StartDate' => $startDate,
|
|
'EndDate' => $endDate,
|
|
'CountPerPage' => $countPerPage,
|
|
'CurrentPage' => $currentPage,
|
|
'OrderDirection' => 'D',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 카드 등록 신청 URL 조회
|
|
*/
|
|
public function getCardScrapRequestUrl(string $corpNum, string $userId, string $userPwd): array
|
|
{
|
|
return $this->call('card', 'GetCardScrapRequestURL', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
'ID' => $userId,
|
|
'PWD' => $userPwd,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 카드 관리 URL 조회
|
|
*/
|
|
public function getCardManagementUrl(string $corpNum, string $userId, string $userPwd): array
|
|
{
|
|
return $this->call('card', 'GetCardManagementURL', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
'ID' => $userId,
|
|
'PWD' => $userPwd,
|
|
]);
|
|
}
|
|
|
|
// =========================================================================
|
|
// 홈택스 (TI)
|
|
// =========================================================================
|
|
|
|
/**
|
|
* 홈택스 매입/매출 URL 조회
|
|
*/
|
|
public function getHomeTaxUrl(string $corpNum, string $userId, string $userPwd): array
|
|
{
|
|
return $this->call('ti', 'GetHomeTaxURL', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
'ID' => $userId,
|
|
'PWD' => $userPwd,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 세금계산서 발행 URL 조회
|
|
*/
|
|
public function getTaxInvoiceIssueUrl(string $corpNum, string $userId, string $userPwd): array
|
|
{
|
|
return $this->call('ti', 'GetTaxInvoiceIssueURL', [
|
|
'CorpNum' => $this->formatBizNo($corpNum),
|
|
'ID' => $userId,
|
|
'PWD' => $userPwd,
|
|
]);
|
|
}
|
|
|
|
// =========================================================================
|
|
// 유틸리티
|
|
// =========================================================================
|
|
|
|
protected function formatBizNo(string $bizNo): string
|
|
{
|
|
return preg_replace('/[^0-9]/', '', $bizNo);
|
|
}
|
|
|
|
/**
|
|
* 은행 코드 목록
|
|
*/
|
|
public static array $bankCodes = [
|
|
'02' => '산업은행', '03' => '기업은행', '04' => '국민은행',
|
|
'07' => '수협은행', '11' => 'NH농협은행', '20' => '우리은행',
|
|
'23' => '제일은행(SC)', '26' => '신한은행', '27' => '한국씨티은행',
|
|
'31' => '대구은행', '32' => '부산은행', '34' => '광주은행',
|
|
'35' => '제주은행', '37' => '전북은행', '39' => '경남은행',
|
|
'45' => '새마을금고연합', '48' => '신협', '71' => '우체국',
|
|
'81' => 'KEB하나은행', '88' => '신한은행(통합)',
|
|
'89' => '케이뱅크', '90' => '카카오뱅크', '92' => '토스뱅크',
|
|
];
|
|
|
|
/**
|
|
* 카드사 코드 목록
|
|
*/
|
|
public static array $cardCompanyCodes = [
|
|
'01' => '비씨카드', '02' => '국민카드', '04' => '삼성카드',
|
|
'05' => '현대카드', '06' => '롯데카드', '07' => '신한카드',
|
|
'08' => '하나카드', '09' => '우리카드', '10' => 'NH농협카드',
|
|
'11' => '씨티카드',
|
|
];
|
|
}
|