diff --git a/public/download.html b/public/download.html
new file mode 100644
index 0000000..eb91e7e
--- /dev/null
+++ b/public/download.html
@@ -0,0 +1,519 @@
+
+
+
+
+
+
+ 나이스가맹점관리자 - 파일 다운로드
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 요청하신 파일의 다운로드 가능 기간이 만료되었습니다.
+ 필요시 가맹점관리자 앱에서 파일을 다시 신청해 주세요.
+
+
+
+
+
+
+
+ 유효하지 않은 다운로드 링크입니다.
+ 올바른 링크로 다시 접속하거나
+ 가맹점관리자 앱에서 파일을 다시 신청해 주세요.
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/api/download-api.ts b/src/api/download-api.ts
new file mode 100644
index 0000000..d26d828
--- /dev/null
+++ b/src/api/download-api.ts
@@ -0,0 +1,68 @@
+import axios from 'axios';
+
+interface DownloadValidationRequest {
+ key: string;
+ password: string;
+}
+
+interface DownloadValidationResponse {
+ success: boolean;
+ downloadUrl?: string;
+ message?: string;
+}
+
+/**
+ * Validate download password and get download URL
+ * @param key - UUID key from URL parameter
+ * @param password - Business registration number (사업자번호)
+ * @returns Promise with download URL if validation succeeds
+ */
+export async function validateDownloadPassword(
+ key: string,
+ password: string
+): Promise {
+ try {
+ const response = await axios.post(
+ '/api/download/validate',
+ {
+ key,
+ password,
+ } as DownloadValidationRequest
+ );
+
+ return response.data;
+ } catch (error) {
+ if (axios.isAxiosError(error)) {
+ return {
+ success: false,
+ message: error.response?.data?.message || '비밀번호가 일치하지 않습니다.',
+ };
+ }
+
+ return {
+ success: false,
+ message: '오류가 발생했습니다. 다시 시도해 주세요.',
+ };
+ }
+}
+
+/**
+ * Generate secure download link
+ * @param merchantId - Merchant ID
+ * @param fileType - Type of file to download
+ * @returns Promise with download key and URL
+ */
+export async function generateDownloadLink(
+ merchantId: string,
+ fileType: string
+): Promise<{ key: string; url: string }> {
+ const response = await axios.post<{ key: string; url: string }>(
+ '/api/download/generate',
+ {
+ merchantId,
+ fileType,
+ }
+ );
+
+ return response.data;
+}
\ No newline at end of file