Files
sam-manage/app/Services/Nts/NtsBusinessService.php
2026-02-25 11:45:01 +09:00

207 lines
6.8 KiB
PHP

<?php
namespace App\Services\Nts;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
/**
* 국세청 사업자등록 상태조회 서비스
* 공공데이터포털 API 사용
*/
class NtsBusinessService
{
/**
* API URL
*/
private const API_URL = 'https://api.odcloud.kr/api/nts-businessman/v1/status';
/**
* 서비스 키 (공공데이터포털에서 발급)
*/
private string $serviceKey;
public function __construct()
{
$this->serviceKey = config('services.nts.service_key', 'EFI7Fchltxh8LNyMu%2BUE9GSklj4ZsJqpL1UAYP6S0ci9D7fqJA98RRdxJos8KxwwEr6L9GAuAEB6E9IA1v1j2Q%3D%3D');
}
/**
* 사업자등록 상태 조회
*
* @param string $businessNumber 사업자등록번호 (10자리, 하이픈 없이)
*/
public function getBusinessStatus(string $businessNumber): array
{
// 사업자번호에서 숫자만 추출
$bizNo = preg_replace('/[^0-9]/', '', $businessNumber);
if (strlen($bizNo) !== 10) {
return [
'success' => false,
'error' => '사업자등록번호는 10자리여야 합니다.',
'code' => 'INVALID_FORMAT',
];
}
$url = self::API_URL.'?serviceKey='.$this->serviceKey;
Log::info('국세청 사업자등록 상태 조회', [
'biz_no' => $bizNo,
]);
try {
$response = Http::timeout(30)
->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json',
])
->post($url, [
'b_no' => [$bizNo],
]);
$result = $response->json();
Log::info('국세청 API 응답', [
'biz_no' => $bizNo,
'match_cnt' => $result['match_cnt'] ?? 0,
'status_code' => $response->status(),
]);
if (! $response->successful()) {
return [
'success' => false,
'error' => 'HTTP 오류: '.$response->status(),
'code' => 'HTTP_ERROR',
'http_status' => $response->status(),
];
}
$matchCnt = $result['match_cnt'] ?? 0;
if ($matchCnt >= 1 && isset($result['data'][0])) {
$data = $result['data'][0];
return [
'success' => true,
'data' => [
'b_no' => $data['b_no'] ?? $bizNo,
'b_stt' => $data['b_stt'] ?? '', // 상태 (영업, 휴업, 폐업)
'b_stt_cd' => $data['b_stt_cd'] ?? '', // 상태코드 (01: 계속사업자, 02: 휴업자, 03: 폐업자)
'tax_type' => $data['tax_type'] ?? '', // 과세유형
'tax_type_cd' => $data['tax_type_cd'] ?? '', // 과세유형코드
'end_dt' => $data['end_dt'] ?? '', // 폐업일
'utcc_yn' => $data['utcc_yn'] ?? '', // 단위과세전환여부
'tax_type_change_dt' => $data['tax_type_change_dt'] ?? '', // 과세유형전환일
'invoice_apply_dt' => $data['invoice_apply_dt'] ?? '', // 세금계산서적용일
'rbf_tax_type' => $data['rbf_tax_type'] ?? '', // 직전과세유형
'rbf_tax_type_cd' => $data['rbf_tax_type_cd'] ?? '', // 직전과세유형코드
],
'raw' => $result,
];
}
// 조회 실패 (국세청에 등록되지 않은 사업자번호)
$errorMsg = $result['data'][0]['tax_type'] ?? '조회된 결과가 없습니다.';
return [
'success' => false,
'error' => $errorMsg,
'code' => 'NOT_FOUND',
'raw' => $result,
];
} catch (\Exception $e) {
Log::error('국세청 API 호출 실패', [
'biz_no' => $bizNo,
'error' => $e->getMessage(),
]);
return [
'success' => false,
'error' => '국세청 API 호출 중 오류가 발생했습니다: '.$e->getMessage(),
'code' => 'EXCEPTION',
];
}
}
/**
* 여러 사업자번호 일괄 상태 조회
*
* @param array $businessNumbers 사업자등록번호 배열
*/
public function getBusinessStatusBulk(array $businessNumbers): array
{
$bizNos = array_map(function ($num) {
return preg_replace('/[^0-9]/', '', $num);
}, $businessNumbers);
// 유효하지 않은 번호 필터링
$validBizNos = array_filter($bizNos, fn ($num) => strlen($num) === 10);
if (empty($validBizNos)) {
return [
'success' => false,
'error' => '유효한 사업자등록번호가 없습니다.',
'code' => 'INVALID_FORMAT',
];
}
$url = self::API_URL.'?serviceKey='.$this->serviceKey;
try {
$response = Http::timeout(30)
->withHeaders([
'Content-Type' => 'application/json',
'Accept' => 'application/json',
])
->post($url, [
'b_no' => array_values($validBizNos),
]);
$result = $response->json();
if (! $response->successful()) {
return [
'success' => false,
'error' => 'HTTP 오류: '.$response->status(),
'code' => 'HTTP_ERROR',
];
}
return [
'success' => true,
'data' => $result['data'] ?? [],
'match_cnt' => $result['match_cnt'] ?? 0,
'raw' => $result,
];
} catch (\Exception $e) {
return [
'success' => false,
'error' => '국세청 API 호출 중 오류가 발생했습니다: '.$e->getMessage(),
'code' => 'EXCEPTION',
];
}
}
/**
* 사업자 상태 코드를 한글로 변환
*/
public static function getStatusLabel(string $statusCode): string
{
return match ($statusCode) {
'01' => '계속사업자',
'02' => '휴업자',
'03' => '폐업자',
default => '알 수 없음',
};
}
/**
* 사업자 상태가 정상(영업중)인지 확인
*/
public static function isActiveStatus(string $statusCode): bool
{
return $statusCode === '01';
}
}