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); ?>