diff --git a/TakeoutSaaS.Docs b/TakeoutSaaS.Docs
index 9006c8a..6680599 160000
--- a/TakeoutSaaS.Docs
+++ b/TakeoutSaaS.Docs
@@ -1 +1 @@
-Subproject commit 9006c8a58995d4adddab28599193c3631935ee43
+Subproject commit 66805999120ba0e2df1e3c11100f523e2d3a7fef
diff --git a/src/Api/TakeoutSaaS.TenantApi/Contracts/Member/MemberStoredCardContracts.cs b/src/Api/TakeoutSaaS.TenantApi/Contracts/Member/MemberStoredCardContracts.cs
new file mode 100644
index 0000000..d77b5b7
--- /dev/null
+++ b/src/Api/TakeoutSaaS.TenantApi/Contracts/Member/MemberStoredCardContracts.cs
@@ -0,0 +1,399 @@
+namespace TakeoutSaaS.TenantApi.Contracts.Member;
+
+///
+/// 储值卡方案列表请求。
+///
+public sealed class StoredCardPlanListRequest
+{
+ ///
+ /// 门店 ID。
+ ///
+ public string StoreId { get; set; } = string.Empty;
+}
+
+///
+/// 保存储值卡方案请求。
+///
+public sealed class SaveStoredCardPlanRequest
+{
+ ///
+ /// 门店 ID。
+ ///
+ public string StoreId { get; set; } = string.Empty;
+
+ ///
+ /// 方案 ID(编辑时传)。
+ ///
+ public string? PlanId { get; set; }
+
+ ///
+ /// 充值金额。
+ ///
+ public decimal RechargeAmount { get; set; }
+
+ ///
+ /// 赠送金额。
+ ///
+ public decimal GiftAmount { get; set; }
+
+ ///
+ /// 排序值。
+ ///
+ public int SortOrder { get; set; } = 100;
+
+ ///
+ /// 状态(enabled/disabled)。
+ ///
+ public string Status { get; set; } = "enabled";
+}
+
+///
+/// 修改方案状态请求。
+///
+public sealed class ChangeStoredCardPlanStatusRequest
+{
+ ///
+ /// 门店 ID。
+ ///
+ public string StoreId { get; set; } = string.Empty;
+
+ ///
+ /// 方案 ID。
+ ///
+ public string PlanId { get; set; } = string.Empty;
+
+ ///
+ /// 状态(enabled/disabled)。
+ ///
+ public string Status { get; set; } = "disabled";
+}
+
+///
+/// 删除方案请求。
+///
+public sealed class DeleteStoredCardPlanRequest
+{
+ ///
+ /// 门店 ID。
+ ///
+ public string StoreId { get; set; } = string.Empty;
+
+ ///
+ /// 方案 ID。
+ ///
+ public string PlanId { get; set; } = string.Empty;
+}
+
+///
+/// 充值记录分页查询请求。
+///
+public sealed class StoredCardRechargeRecordListRequest
+{
+ ///
+ /// 门店 ID。
+ ///
+ public string StoreId { get; set; } = string.Empty;
+
+ ///
+ /// 开始日期(yyyy-MM-dd)。
+ ///
+ public string? StartDate { get; set; }
+
+ ///
+ /// 结束日期(yyyy-MM-dd)。
+ ///
+ public string? EndDate { get; set; }
+
+ ///
+ /// 关键字(会员名称/手机号/单号)。
+ ///
+ public string? Keyword { get; set; }
+
+ ///
+ /// 页码。
+ ///
+ public int Page { get; set; } = 1;
+
+ ///
+ /// 每页条数。
+ ///
+ public int PageSize { get; set; } = 8;
+}
+
+///
+/// 充值记录导出请求。
+///
+public sealed class ExportStoredCardRechargeRecordRequest
+{
+ ///
+ /// 门店 ID。
+ ///
+ public string StoreId { get; set; } = string.Empty;
+
+ ///
+ /// 开始日期(yyyy-MM-dd)。
+ ///
+ public string? StartDate { get; set; }
+
+ ///
+ /// 结束日期(yyyy-MM-dd)。
+ ///
+ public string? EndDate { get; set; }
+
+ ///
+ /// 关键字(会员名称/手机号/单号)。
+ ///
+ public string? Keyword { get; set; }
+}
+
+///
+/// 写入充值记录请求。
+///
+public sealed class WriteStoredCardRechargeRecordRequest
+{
+ ///
+ /// 门店 ID。
+ ///
+ public string StoreId { get; set; } = string.Empty;
+
+ ///
+ /// 会员 ID(必填)。
+ ///
+ public string MemberId { get; set; } = string.Empty;
+
+ ///
+ /// 方案 ID(可空)。
+ ///
+ public string? PlanId { get; set; }
+
+ ///
+ /// 充值金额。
+ ///
+ public decimal RechargeAmount { get; set; }
+
+ ///
+ /// 赠送金额。
+ ///
+ public decimal GiftAmount { get; set; }
+
+ ///
+ /// 支付方式(wechat/alipay/cash/card/balance)。
+ ///
+ public string PaymentMethod { get; set; } = "wechat";
+
+ ///
+ /// 充值时间(可空,默认当前时间)。
+ ///
+ public DateTime? RechargedAt { get; set; }
+
+ ///
+ /// 备注。
+ ///
+ public string? Remark { get; set; }
+}
+
+///
+/// 储值卡方案统计响应。
+///
+public sealed class StoredCardPlanStatsResponse
+{
+ ///
+ /// 储值总额。
+ ///
+ public decimal TotalRechargeAmount { get; set; }
+
+ ///
+ /// 赠金总额。
+ ///
+ public decimal TotalGiftAmount { get; set; }
+
+ ///
+ /// 本月充值。
+ ///
+ public decimal CurrentMonthRechargeAmount { get; set; }
+
+ ///
+ /// 储值用户。
+ ///
+ public int RechargeMemberCount { get; set; }
+}
+
+///
+/// 储值卡方案响应。
+///
+public sealed class StoredCardPlanResponse
+{
+ ///
+ /// 方案 ID。
+ ///
+ public string PlanId { get; set; } = string.Empty;
+
+ ///
+ /// 充值金额。
+ ///
+ public decimal RechargeAmount { get; set; }
+
+ ///
+ /// 赠送金额。
+ ///
+ public decimal GiftAmount { get; set; }
+
+ ///
+ /// 到账金额。
+ ///
+ public decimal ArrivedAmount { get; set; }
+
+ ///
+ /// 排序。
+ ///
+ public int SortOrder { get; set; }
+
+ ///
+ /// 状态。
+ ///
+ public string Status { get; set; } = "enabled";
+
+ ///
+ /// 累计充值次数。
+ ///
+ public int RechargeCount { get; set; }
+
+ ///
+ /// 累计充值金额。
+ ///
+ public decimal TotalRechargeAmount { get; set; }
+}
+
+///
+/// 储值卡方案列表响应。
+///
+public sealed class StoredCardPlanListResultResponse
+{
+ ///
+ /// 方案列表。
+ ///
+ public List Items { get; set; } = [];
+
+ ///
+ /// 页面统计。
+ ///
+ public StoredCardPlanStatsResponse Stats { get; set; } = new();
+}
+
+///
+/// 充值记录响应。
+///
+public sealed class StoredCardRechargeRecordResponse
+{
+ ///
+ /// 记录 ID。
+ ///
+ public string RecordId { get; set; } = string.Empty;
+
+ ///
+ /// 充值单号。
+ ///
+ public string RecordNo { get; set; } = string.Empty;
+
+ ///
+ /// 会员 ID。
+ ///
+ public string MemberId { get; set; } = string.Empty;
+
+ ///
+ /// 会员名称。
+ ///
+ public string MemberName { get; set; } = string.Empty;
+
+ ///
+ /// 手机号(脱敏)。
+ ///
+ public string MemberMobileMasked { get; set; } = string.Empty;
+
+ ///
+ /// 充值金额。
+ ///
+ public decimal RechargeAmount { get; set; }
+
+ ///
+ /// 赠送金额。
+ ///
+ public decimal GiftAmount { get; set; }
+
+ ///
+ /// 到账金额。
+ ///
+ public decimal ArrivedAmount { get; set; }
+
+ ///
+ /// 支付方式编码。
+ ///
+ public string PaymentMethod { get; set; } = "unknown";
+
+ ///
+ /// 支付方式文案。
+ ///
+ public string PaymentMethodText { get; set; } = "未知";
+
+ ///
+ /// 充值时间(本地显示字符串)。
+ ///
+ public string RechargedAt { get; set; } = string.Empty;
+
+ ///
+ /// 方案 ID。
+ ///
+ public string? PlanId { get; set; }
+
+ ///
+ /// 备注。
+ ///
+ public string? Remark { get; set; }
+}
+
+///
+/// 充值记录分页结果响应。
+///
+public sealed class StoredCardRechargeRecordListResultResponse
+{
+ ///
+ /// 列表项。
+ ///
+ public List Items { get; set; } = [];
+
+ ///
+ /// 页码。
+ ///
+ public int Page { get; set; }
+
+ ///
+ /// 每页条数。
+ ///
+ public int PageSize { get; set; }
+
+ ///
+ /// 总条数。
+ ///
+ public int TotalCount { get; set; }
+}
+
+///
+/// 充值记录导出响应。
+///
+public sealed class StoredCardRechargeRecordExportResponse
+{
+ ///
+ /// 文件名。
+ ///
+ public string FileName { get; set; } = string.Empty;
+
+ ///
+ /// Base64 内容。
+ ///
+ public string FileContentBase64 { get; set; } = string.Empty;
+
+ ///
+ /// 导出总数。
+ ///
+ public int TotalCount { get; set; }
+}
diff --git a/src/Api/TakeoutSaaS.TenantApi/Controllers/MemberStoredCardController.cs b/src/Api/TakeoutSaaS.TenantApi/Controllers/MemberStoredCardController.cs
new file mode 100644
index 0000000..fbbfb80
--- /dev/null
+++ b/src/Api/TakeoutSaaS.TenantApi/Controllers/MemberStoredCardController.cs
@@ -0,0 +1,283 @@
+using System.Globalization;
+using MediatR;
+using Microsoft.AspNetCore.Authorization;
+using Microsoft.AspNetCore.Mvc;
+using TakeoutSaaS.Application.App.Members.StoredCard.Commands;
+using TakeoutSaaS.Application.App.Members.StoredCard.Dto;
+using TakeoutSaaS.Application.App.Members.StoredCard.Queries;
+using TakeoutSaaS.Application.App.Stores.Services;
+using TakeoutSaaS.Infrastructure.App.Persistence;
+using TakeoutSaaS.Module.Authorization.Attributes;
+using TakeoutSaaS.Shared.Abstractions.Results;
+using TakeoutSaaS.Shared.Web.Api;
+using TakeoutSaaS.TenantApi.Contracts.Member;
+
+namespace TakeoutSaaS.TenantApi.Controllers;
+
+///
+/// 会员中心储值卡管理。
+///
+[ApiVersion("1.0")]
+[Authorize]
+[Route("api/tenant/v{version:apiVersion}/member/stored-card")]
+public sealed class MemberStoredCardController(
+ IMediator mediator,
+ TakeoutAppDbContext dbContext,
+ StoreContextService storeContextService)
+ : BaseApiController
+{
+ private const string ViewPermission = "tenant:member:stored-card:view";
+ private const string ManagePermission = "tenant:member:stored-card:manage";
+
+ ///
+ /// 获取储值卡方案列表。
+ ///
+ [HttpGet("plan/list")]
+ [PermissionAuthorize(ViewPermission, ManagePermission)]
+ [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
+ public async Task> PlanList(
+ [FromQuery] StoredCardPlanListRequest request,
+ CancellationToken cancellationToken)
+ {
+ var storeId = StoreApiHelpers.ParseRequiredSnowflake(request.StoreId, nameof(request.StoreId));
+ await EnsureStoreAccessibleAsync(storeId, cancellationToken);
+
+ var result = await mediator.Send(new GetStoredCardPlanListQuery
+ {
+ StoreId = storeId
+ }, cancellationToken);
+
+ return ApiResponse.Ok(new StoredCardPlanListResultResponse
+ {
+ Items = result.Items.Select(MapPlan).ToList(),
+ Stats = new StoredCardPlanStatsResponse
+ {
+ TotalRechargeAmount = result.Stats.TotalRechargeAmount,
+ TotalGiftAmount = result.Stats.TotalGiftAmount,
+ CurrentMonthRechargeAmount = result.Stats.CurrentMonthRechargeAmount,
+ RechargeMemberCount = result.Stats.RechargeMemberCount
+ }
+ });
+ }
+
+ ///
+ /// 保存储值卡方案。
+ ///
+ [HttpPost("plan/save")]
+ [PermissionAuthorize(ManagePermission)]
+ [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
+ public async Task> SavePlan(
+ [FromBody] SaveStoredCardPlanRequest request,
+ CancellationToken cancellationToken)
+ {
+ var storeId = StoreApiHelpers.ParseRequiredSnowflake(request.StoreId, nameof(request.StoreId));
+ await EnsureStoreAccessibleAsync(storeId, cancellationToken);
+
+ var result = await mediator.Send(new SaveStoredCardPlanCommand
+ {
+ StoreId = storeId,
+ PlanId = StoreApiHelpers.ParseSnowflakeOrNull(request.PlanId),
+ RechargeAmount = request.RechargeAmount,
+ GiftAmount = request.GiftAmount,
+ SortOrder = request.SortOrder,
+ Status = request.Status
+ }, cancellationToken);
+
+ return ApiResponse.Ok(MapPlan(result));
+ }
+
+ ///
+ /// 修改储值卡方案状态。
+ ///
+ [HttpPost("plan/status")]
+ [PermissionAuthorize(ManagePermission)]
+ [ProducesResponseType(typeof(ApiResponse), StatusCodes.Status200OK)]
+ public async Task> ChangePlanStatus(
+ [FromBody] ChangeStoredCardPlanStatusRequest request,
+ CancellationToken cancellationToken)
+ {
+ var storeId = StoreApiHelpers.ParseRequiredSnowflake(request.StoreId, nameof(request.StoreId));
+ await EnsureStoreAccessibleAsync(storeId, cancellationToken);
+
+ var result = await mediator.Send(new ChangeStoredCardPlanStatusCommand
+ {
+ StoreId = storeId,
+ PlanId = StoreApiHelpers.ParseRequiredSnowflake(request.PlanId, nameof(request.PlanId)),
+ Status = request.Status
+ }, cancellationToken);
+
+ return ApiResponse.Ok(MapPlan(result));
+ }
+
+ ///
+ /// 删除储值卡方案。
+ ///
+ [HttpPost("plan/delete")]
+ [PermissionAuthorize(ManagePermission)]
+ [ProducesResponseType(typeof(ApiResponse