227 lines
8.7 KiB
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);
|
||
|
|
?>
|
||
|
|
|