Files
sam-sales/barobill/etax/api/issue.php

227 lines
8.7 KiB
PHP

<?php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
// 바로빌 API 설정 로드
require_once(__DIR__ . '/barobill_config.php');
// POST 데이터 읽기
$input = json_decode(file_get_contents('php://input'), true);
if (!$input) {
http_response_code(400);
echo json_encode([
"success" => false,
"error" => "Invalid request data"
], JSON_UNESCAPED_UNICODE);
exit;
}
// 바로빌 API 호출 또는 시뮬레이션
// 테스트 모드: SOAP 클라이언트만 있으면 실제 API 호출 시도 (CERTKEY는 선택사항)
// 운영 모드: SOAP 클라이언트와 CERTKEY 모두 필요
$useRealAPI = !empty($barobillSoapClient) && ($isTestMode || !empty($barobillCertKey));
// 디버깅 정보: 실제 API 호출 여부 확인
$debugInfo = [
'hasSoapClient' => !empty($barobillSoapClient),
'hasCertKey' => !empty($barobillCertKey),
'hasCorpNum' => !empty($barobillCorpNum),
'isTestMode' => $isTestMode ?? false,
'soapUrl' => $barobillSoapUrl ?? null,
'willUseRealAPI' => $useRealAPI
];
if ($useRealAPI) {
// 실제 바로빌 SOAP API 호출
$apiResult = issueTaxInvoice($input);
if ($apiResult['success']) {
$apiData = $apiResult['data'];
// SOAP 응답에서 MgtKey 추출 (RegistAndIssueTaxInvoice는 MgtKey를 반환)
// 응답이 숫자(양수)면 성공, 그 값이 바로빌 세금계산서 ID일 수 있음
// 또는 객체일 경우 MgtKey 속성 확인
$mgtKey = '';
if (is_object($apiData) && isset($apiData->MgtKey)) {
$mgtKey = $apiData->MgtKey;
} elseif (is_array($apiData) && isset($apiData['MgtKey'])) {
$mgtKey = $apiData['MgtKey'];
} else {
// MgtKey가 없으면 입력에서 생성한 키 사용
$mgtKey = $input['issueKey'] ?? 'MGT' . date('YmdHis') . rand(1000, 9999);
}
// 새 세금계산서 데이터 생성
$newInvoice = [
"id" => "inv_" . time(),
"issueKey" => $mgtKey, // MgtKey를 issueKey로 사용
"mgtKey" => $mgtKey, // 바로빌 관리번호
"supplierBizno" => $input['supplierBizno'] ?? '',
"supplierName" => $input['supplierName'] ?? '',
"recipientBizno" => $input['recipientBizno'] ?? '',
"recipientName" => $input['recipientName'] ?? '',
"supplyDate" => $input['supplyDate'] ?? date('Y-m-d'),
"items" => $input['items'] ?? [],
"totalSupplyAmt" => $input['totalSupplyAmt'] ?? 0,
"totalVat" => $input['totalVat'] ?? 0,
"total" => $input['total'] ?? 0,
"status" => "issued",
"memo" => $input['memo'] ?? '',
"createdAt" => date('Y-m-d\TH:i:s'),
"barobillInvoiceId" => is_numeric($apiData) ? (string)$apiData : ($apiData->InvoiceID ?? '')
];
// 파일에 저장
$dataFile = __DIR__ . '/invoices_data.json';
$existingData = [];
if (file_exists($dataFile)) {
$fileContent = file_get_contents($dataFile);
if ($fileContent !== false) {
$existingData = json_decode($fileContent, true);
if (!is_array($existingData)) {
$existingData = [];
}
}
}
if (!isset($existingData['invoices'])) {
$existingData['invoices'] = [];
}
$existingData['invoices'][] = $newInvoice;
// 최대 100개까지만 저장
if (count($existingData['invoices']) > 100) {
$existingData['invoices'] = array_slice($existingData['invoices'], -100);
}
// 파일 저장 시도 및 에러 확인
$jsonData = json_encode($existingData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
$saveResult = @file_put_contents($dataFile, $jsonData);
$saveSuccess = ($saveResult !== false);
if (!$saveSuccess) {
$errorMsg = "파일 저장 실패: " . $dataFile;
if (!is_writable(dirname($dataFile))) {
$errorMsg .= " (디렉토리 쓰기 권한 없음)";
} elseif (!is_writable($dataFile) && file_exists($dataFile)) {
$errorMsg .= " (파일 쓰기 권한 없음)";
}
error_log("세금계산서 저장 실패: " . $errorMsg);
}
$response = [
"success" => true,
"message" => "세금계산서가 성공적으로 발행되었습니다.",
"data" => [
"issueKey" => $newInvoice['issueKey'],
"mgtKey" => $newInvoice['mgtKey'],
"barobillInvoiceId" => $newInvoice['barobillInvoiceId'],
"status" => "issued",
"issuedAt" => $newInvoice['createdAt']
],
"invoice" => $newInvoice,
"api_response" => $apiData,
"soap_request" => $apiResult['soap_request'] ?? null,
"soap_response" => $apiResult['soap_response'] ?? null,
"saved" => $saveSuccess,
"dataFile" => $saveSuccess ? null : $dataFile,
"simulation" => false,
"debug" => $debugInfo,
"note" => "✅ 실제 바로빌 API를 호출했습니다."
];
} else {
$response = [
"success" => false,
"error" => $apiResult['error'] ?? "API 호출 실패",
"error_code" => $apiResult['error_code'] ?? null,
"error_detail" => $apiResult['error_detail'] ?? null,
"soap_request" => $apiResult['soap_request'] ?? null,
"soap_response" => $apiResult['soap_response'] ?? null
];
}
} else {
// 시뮬레이션 모드 (API 키가 없을 때)
$issueKey = "BARO-" . date('Y') . "-" . str_pad(rand(1, 9999), 4, '0', STR_PAD_LEFT);
$newInvoice = [
"id" => "inv_" . time(),
"issueKey" => $issueKey,
"supplierBizno" => $input['supplierBizno'] ?? '',
"supplierName" => $input['supplierName'] ?? '',
"recipientBizno" => $input['recipientBizno'] ?? '',
"recipientName" => $input['recipientName'] ?? '',
"supplyDate" => $input['supplyDate'] ?? date('Y-m-d'),
"items" => $input['items'] ?? [],
"totalSupplyAmt" => $input['totalSupplyAmt'] ?? 0,
"totalVat" => $input['totalVat'] ?? 0,
"total" => $input['total'] ?? 0,
"status" => "issued",
"memo" => $input['memo'] ?? '',
"createdAt" => date('Y-m-d\TH:i:s'),
"barobillInvoiceId" => "BB-" . uniqid()
];
// 파일에 저장
$dataFile = __DIR__ . '/invoices_data.json';
$existingData = [];
if (file_exists($dataFile)) {
$fileContent = file_get_contents($dataFile);
if ($fileContent !== false) {
$existingData = json_decode($fileContent, true);
if (!is_array($existingData)) {
$existingData = [];
}
}
}
if (!isset($existingData['invoices'])) {
$existingData['invoices'] = [];
}
$existingData['invoices'][] = $newInvoice;
if (count($existingData['invoices']) > 100) {
$existingData['invoices'] = array_slice($existingData['invoices'], -100);
}
// 파일 저장 시도 및 에러 확인
$jsonData = json_encode($existingData, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
$saveResult = @file_put_contents($dataFile, $jsonData);
$saveSuccess = ($saveResult !== false);
if (!$saveSuccess) {
$errorMsg = "파일 저장 실패: " . $dataFile;
if (!is_writable(dirname($dataFile))) {
$errorMsg .= " (디렉토리 쓰기 권한 없음)";
} elseif (!is_writable($dataFile) && file_exists($dataFile)) {
$errorMsg .= " (파일 쓰기 권한 없음)";
}
error_log("세금계산서 저장 실패: " . $errorMsg);
}
$response = [
"success" => true,
"message" => "세금계산서가 성공적으로 발행되었습니다. (시뮬레이션 모드)",
"data" => [
"issueKey" => $issueKey,
"barobillInvoiceId" => $newInvoice['barobillInvoiceId'],
"status" => "issued",
"issuedAt" => $newInvoice['createdAt']
],
"invoice" => $newInvoice,
"simulation" => true,
"saved" => $saveSuccess,
"dataFile" => $saveSuccess ? null : $dataFile,
"debug" => $debugInfo,
"warning" => "⚠️ 시뮬레이션 모드입니다. 실제 바로빌 API를 호출하려면 CERTKEY를 설정하세요."
];
usleep(500000); // 0.5초 지연 시뮬레이션
}
echo json_encode($response, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
?>