diff --git a/Document/12_BusinessTodo.md b/Document/12_BusinessTodo.md
index ca1a132..5eaadc5 100644
--- a/Document/12_BusinessTodo.md
+++ b/Document/12_BusinessTodo.md
@@ -6,8 +6,8 @@
## Phase 1(当前阶段):租户/商家入驻、门店与菜品、扫码堂食、基础下单支付、预购自提、第三方配送骨架
- [x] 管理端租户 API:注册、实名认证、套餐订阅/续费/升降配、审核流,Swagger ≥6 个端点,含审核日志。
- 已交付:`src/Api/TakeoutSaaS.AdminApi/Controllers/TenantsController.cs` 暴露注册、详情、实名提交、审核、订阅创建/升降配、审核日志 8 个端点;对应命令/查询位于 `src/Application/TakeoutSaaS.Application/App/Tenants`,仓储实现 `EfTenantRepository`,并写入 `TenantAuditLog` 记录。Swagger 自动收录上述接口,满足 Phase1 租户管理要求。
-- [ ] 商家入驻 API:证照上传、合同管理、类目选择,驱动待审/审核/驳回/通过状态机,文件持久在 COS。
- - 当前:`MerchantsController` 只暴露基础 CRUD(`src/Api/TakeoutSaaS.AdminApi/Controllers/MerchantsController.cs:21-88`),缺少证照/合同上传、COS 存储与状态机端点。
+- [x] 商家入驻 API:证照上传、合同管理、类目选择,驱动待审/审核/驳回/通过状态机,文件持久在 COS。
+ - 已交付:`src/Api/TakeoutSaaS.AdminApi/Controllers/MerchantsController.cs` 新增证照上传/审核、合同创建与状态更新、商户审核、审核日志、类目列表等 8 个端点;应用层新增 `AddMerchantDocumentCommand`、`CreateMerchantContractCommand`、`ReviewMerchantCommand` 等 Handler;`MerchantDocument/Contract/Audit` DTO 完整返回详情,文件 URL 仍通过 `/api/admin/v1/files/upload` 上 COS。仓储实现扩展 `EfMerchantRepository` 支持文档/合同/AuditLog 持久化,`TakeoutAppDbContext` 新增 `merchant_audit_logs` 表实现状态机追踪。
- [ ] RBAC 模板:平台管理员、租户管理员、店长、店员四角色模板;API 可复制并允许租户自定义扩展。
- 当前:`RolesController`/`PermissionsController` 已提供角色与权限 CRUD(`src/Api/TakeoutSaaS.AdminApi/Controllers/RolesController.cs:16-88`、`.../PermissionsController.cs:16-63`),但没有“模板复制”或按租户批量初始化的接口。
- [ ] 配额与套餐:TenantPackage CRUD、订阅/续费/配额校验(门店/账号/短信/配送单量),超额返回 409 并记录 TenantQuotaUsage。
diff --git a/src/Api/TakeoutSaaS.AdminApi/Controllers/MerchantCategoriesController.cs b/src/Api/TakeoutSaaS.AdminApi/Controllers/MerchantCategoriesController.cs
new file mode 100644
index 0000000..72684f0
--- /dev/null
+++ b/src/Api/TakeoutSaaS.AdminApi/Controllers/MerchantCategoriesController.cs
@@ -0,0 +1,74 @@
+using System.Collections.Generic;
+using MediatR;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Http;
+using Microsoft.AspNetCore.Mvc;
+using TakeoutSaaS.Application.App.Merchants.Commands;
+using TakeoutSaaS.Application.App.Merchants.Dto;
+using TakeoutSaaS.Application.App.Merchants.Queries;
+using TakeoutSaaS.Module.Authorization.Attributes;
+using TakeoutSaaS.Shared.Abstractions.Constants;
+using TakeoutSaaS.Shared.Abstractions.Results;
+using TakeoutSaaS.Shared.Web.Api;
+
+namespace TakeoutSaaS.AdminApi.Controllers;
+
+///
+/// 商户类目管理。
+///
+[ApiVersion("1.0")]
+[Authorize]
+[Route("api/admin/v{version:apiVersion}/merchant-categories")]
+public sealed class MerchantCategoriesController(IMediator mediator) : BaseApiController
+{
+ ///
+ /// 列出所有类目。
+ ///
+ [HttpGet]
+ [PermissionAuthorize("merchant_category:read")]
+ [ProducesResponseType(typeof(ApiResponse>), StatusCodes.Status200OK)]
+ public async Task>> List(CancellationToken cancellationToken)
+ {
+ var result = await mediator.Send(new ListMerchantCategoriesQuery(), cancellationToken);
+ return ApiResponse>.Ok(result);
+ }
+
+ ///
+ /// 新增类目。
+ ///
+ [HttpPost]
+ [PermissionAuthorize("merchant_category:create")]
+ [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
+ public async Task> Create([FromBody] CreateMerchantCategoryCommand command, CancellationToken cancellationToken)
+ {
+ var result = await mediator.Send(command, cancellationToken);
+ return ApiResponse.Ok(result);
+ }
+
+ ///
+ /// 删除类目。
+ ///
+ [HttpDelete("{categoryId:long}")]
+ [PermissionAuthorize("merchant_category:delete")]
+ [ProducesResponseType(typeof(ApiResponse