Files
sam-manage/app/Services/Coocon/CooconService.php
pro 7ed908f53d feat:쿠콘 API 신용평가 조회 기능 구현
- CooconConfig 모델 및 마이그레이션 추가
- CooconService 클래스 구현 (OA12~OA17 API)
- CreditController 확장 (설정 관리, 조회 기능)
- 설정 관리 화면 추가 (CRUD, 활성화 토글)
- 사업자번호 조회 화면 업데이트 (API 연동)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 19:33:51 +09:00

312 lines
9.3 KiB
PHP

<?php
namespace App\Services\Coocon;
use App\Models\Coocon\CooconConfig;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
/**
* 쿠콘 API 서비스
* 나이스평가정보 연동 API
*/
class CooconService
{
private ?CooconConfig $config = null;
private bool $isTestMode = true;
/**
* API ID 상수
*/
public const API_CREDIT_SUMMARY = 'OA12'; // 신용요약정보
public const API_SHORT_TERM_OVERDUE = 'OA13'; // 단기연체정보 (한국신용정보원)
public const API_NEGATIVE_INFO_KCI = 'OA14'; // 신용도판단정보 (한국신용정보원)
public const API_NEGATIVE_INFO_CB = 'OA15'; // 신용도판단정보 (신용정보사)
public const API_SUSPENSION_INFO = 'OA16'; // 당좌거래정지정보 (금융결제원)
public const API_WORKOUT_INFO = 'OA17'; // 법정관리/워크아웃정보
/**
* API 이름 목록
*/
public const API_NAMES = [
self::API_CREDIT_SUMMARY => '신용요약정보',
self::API_SHORT_TERM_OVERDUE => '단기연체정보 (한국신용정보원)',
self::API_NEGATIVE_INFO_KCI => '신용도판단정보 (한국신용정보원)',
self::API_NEGATIVE_INFO_CB => '신용도판단정보 (신용정보사)',
self::API_SUSPENSION_INFO => '당좌거래정지정보 (금융결제원)',
self::API_WORKOUT_INFO => '법정관리/워크아웃정보',
];
/**
* 기본 URL
*/
private const BASE_URL_TEST = 'https://dev2.coocon.co.kr:8443/sol/gateway/oapi_relay.jsp';
private const BASE_URL_PRODUCTION = 'https://sgw.coocon.co.kr/sol/gateway/oapi_relay.jsp';
public function __construct(bool $isTestMode = true)
{
$this->isTestMode = $isTestMode;
$this->loadConfig();
}
/**
* 설정 로드
*/
private function loadConfig(): void
{
$this->config = CooconConfig::getActive($this->isTestMode);
}
/**
* 설정 재로드
*/
public function reloadConfig(): self
{
$this->loadConfig();
return $this;
}
/**
* 테스트 모드 설정
*/
public function setTestMode(bool $isTestMode): self
{
$this->isTestMode = $isTestMode;
$this->loadConfig();
return $this;
}
/**
* 설정 존재 여부
*/
public function hasConfig(): bool
{
return $this->config !== null;
}
/**
* 현재 설정 조회
*/
public function getConfig(): ?CooconConfig
{
return $this->config;
}
/**
* API URL 조회
*/
private function getBaseUrl(): string
{
if ($this->config && $this->config->base_url) {
return $this->config->base_url;
}
return $this->isTestMode ? self::BASE_URL_TEST : self::BASE_URL_PRODUCTION;
}
/**
* API 호출 공통 메서드
*/
private function callApi(string $apiId, array $params = []): array
{
if (!$this->config) {
return [
'success' => false,
'error' => '쿠콘 API 설정이 없습니다. 설정을 먼저 등록해주세요.',
'code' => 'NO_CONFIG',
];
}
$url = $this->getBaseUrl();
$trSeq = $this->generateTransactionSequence();
$requestData = array_merge([
'API_KEY' => $this->config->api_key,
'API_ID' => $apiId,
'TR_SEQ' => $trSeq,
], $params);
Log::info('쿠콘 API 호출', [
'api_id' => $apiId,
'tr_seq' => $trSeq,
'url' => $url,
'params' => array_merge($params, ['API_KEY' => '***masked***']),
]);
try {
$response = Http::timeout(30)
->withHeaders([
'Content-Type' => 'application/json',
])
->post($url, $requestData);
$result = $response->json();
Log::info('쿠콘 API 응답', [
'api_id' => $apiId,
'tr_seq' => $trSeq,
'rslt_cd' => $result['RSLT_CD'] ?? 'N/A',
'rslt_msg' => $result['RSLT_MSG'] ?? 'N/A',
]);
if (!$response->successful()) {
return [
'success' => false,
'error' => 'HTTP 오류: ' . $response->status(),
'code' => 'HTTP_ERROR',
'http_status' => $response->status(),
];
}
$rsltCode = $result['RSLT_CD'] ?? '';
if ($rsltCode === '00000000') {
return [
'success' => true,
'data' => $result['RSLT_DATA'] ?? [],
'tr_seq' => $result['TR_SEQ'] ?? $trSeq,
'message' => $result['RSLT_MSG'] ?? '정상처리되었습니다.',
'raw' => $result,
];
}
return [
'success' => false,
'error' => $result['RSLT_MSG'] ?? '알 수 없는 오류',
'code' => $rsltCode,
'raw' => $result,
];
} catch (\Exception $e) {
Log::error('쿠콘 API 호출 실패', [
'api_id' => $apiId,
'tr_seq' => $trSeq,
'error' => $e->getMessage(),
]);
return [
'success' => false,
'error' => '쿠콘 API 호출 중 오류가 발생했습니다: ' . $e->getMessage(),
'code' => 'EXCEPTION',
];
}
}
/**
* 거래일련번호 생성
*/
private function generateTransactionSequence(): string
{
return date('YmdHis') . substr(microtime(), 2, 6);
}
/**
* 신용요약정보 조회 (OA12)
*
* @param string $companyKey 사업자번호, 법인번호, 업체코드 중 하나
*/
public function getCreditSummary(string $companyKey): array
{
return $this->callApi(self::API_CREDIT_SUMMARY, [
'Companykey' => $companyKey,
]);
}
/**
* 단기연체정보 조회 (OA13) - 한국신용정보원
*
* @param string $companyKey 사업자번호, 법인번호, 업체코드 중 하나
* @param string|null $reqDate 기준일자 (YYYYMMDD), 미입력시 현재 날짜
*/
public function getShortTermOverdueInfo(string $companyKey, ?string $reqDate = null): array
{
$params = ['Companykey' => $companyKey];
if ($reqDate) {
$params['reqDate'] = $reqDate;
}
return $this->callApi(self::API_SHORT_TERM_OVERDUE, $params);
}
/**
* 신용도판단정보 조회 (OA14) - 한국신용정보원 (공공정보 포함)
*
* @param string $companyKey 사업자번호, 법인번호, 업체코드 중 하나
*/
public function getNegativeInfoKCI(string $companyKey): array
{
return $this->callApi(self::API_NEGATIVE_INFO_KCI, [
'Companykey' => $companyKey,
]);
}
/**
* 신용도판단정보 조회 (OA15) - 신용정보사
*
* @param string $companyKey 사업자번호, 법인번호, 업체코드 중 하나
*/
public function getNegativeInfoCB(string $companyKey): array
{
return $this->callApi(self::API_NEGATIVE_INFO_CB, [
'Companykey' => $companyKey,
]);
}
/**
* 당좌거래정지정보 조회 (OA16) - 금융결제원
*
* @param string $companyKey 사업자번호, 법인번호, 업체코드 중 하나
*/
public function getSuspensionInfo(string $companyKey): array
{
return $this->callApi(self::API_SUSPENSION_INFO, [
'Companykey' => $companyKey,
]);
}
/**
* 법정관리/워크아웃정보 조회 (OA17)
*
* @param string $companyKey 사업자번호, 법인번호, 업체코드 중 하나
* @param int $pageNo 페이지 번호
* @param int $pageSize 페이지 사이즈
*/
public function getWorkoutInfo(string $companyKey, int $pageNo = 1, int $pageSize = 10): array
{
return $this->callApi(self::API_WORKOUT_INFO, [
'Companykey' => $companyKey,
'pageNo' => (string) $pageNo,
'pageSize' => (string) $pageSize,
]);
}
/**
* 전체 신용정보 조회 (모든 API 호출)
*
* @param string $companyKey 사업자번호, 법인번호, 업체코드 중 하나
*/
public function getAllCreditInfo(string $companyKey): array
{
$results = [];
// 신용요약정보
$results['summary'] = $this->getCreditSummary($companyKey);
// 단기연체정보
$results['shortTermOverdue'] = $this->getShortTermOverdueInfo($companyKey);
// 신용도판단정보 (한국신용정보원)
$results['negativeInfoKCI'] = $this->getNegativeInfoKCI($companyKey);
// 신용도판단정보 (신용정보사)
$results['negativeInfoCB'] = $this->getNegativeInfoCB($companyKey);
// 당좌거래정지정보
$results['suspensionInfo'] = $this->getSuspensionInfo($companyKey);
// 법정관리/워크아웃정보
$results['workoutInfo'] = $this->getWorkoutInfo($companyKey);
return $results;
}
}