forked from xiongyuxing/tiku-backend.net
feat(saas): implement marketplace and tenant onboarding
This commit is contained in:
@@ -193,28 +193,6 @@ public sealed class CouponRedemption : AuditableTenantEntity
|
||||
public DateTimeOffset? UsedAt { get; set; }
|
||||
}
|
||||
|
||||
public sealed class TenantSubscription : AuditableTenantEntity
|
||||
{
|
||||
public string PlanCode { get; set; } = string.Empty;
|
||||
public TenantSubscriptionStatus Status { get; set; } = TenantSubscriptionStatus.Trial;
|
||||
public DateTimeOffset? StartsAt { get; set; }
|
||||
public DateTimeOffset? ExpiresAt { get; set; }
|
||||
public string? BillingCycle { get; set; } = "yearly";
|
||||
public int AmountCents { get; set; }
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
}
|
||||
|
||||
public sealed class TenantUsageRecord : Entity, ITenantOwned
|
||||
{
|
||||
public Guid TenantId { get; set; }
|
||||
public string MetricKey { get; set; } = string.Empty;
|
||||
public decimal MetricValue { get; set; }
|
||||
public DateOnly PeriodStart { get; set; }
|
||||
public DateOnly PeriodEnd { get; set; }
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
|
||||
}
|
||||
|
||||
public sealed class CommerceRefundRequest : AuditableTenantEntity
|
||||
{
|
||||
public Guid OrderId { get; set; }
|
||||
@@ -389,7 +367,6 @@ public enum EntitlementScopeType { Tenant, Region, Module, Subject, QuestionBank
|
||||
public enum EntitlementStatus { Active, Revoked, Expired }
|
||||
public enum DiscountType { Percent, Fixed }
|
||||
public enum CouponRedemptionStatus { Claimed, Used, Expired, Cancelled }
|
||||
public enum TenantSubscriptionStatus { Trial, Active, PastDue, Cancelled, Expired }
|
||||
public enum CommerceRefundStatus { Requested, Approved, Processing, Succeeded, Failed, Rejected, Cancelled }
|
||||
public enum RefundEntitlementAction { None, RevokeOnSuccess }
|
||||
public enum ReconciliationBillType { Payment, Refund, Combined }
|
||||
|
||||
@@ -56,7 +56,7 @@ public sealed class BackendPermission : AuditableEntity
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public BackendPermissionArea Area { get; set; } = BackendPermissionArea.Tenant;
|
||||
public string Module { get; set; } = string.Empty;
|
||||
public string PermissionModuleCode { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public bool IsSystem { get; set; } = true;
|
||||
public int SortOrder { get; set; } = 100;
|
||||
|
||||
@@ -3,45 +3,6 @@ using Tiku.Domain.Common;
|
||||
|
||||
namespace Tiku.Domain.Platform;
|
||||
|
||||
public sealed class PlatformSaasPlan : AuditableEntity
|
||||
{
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public PlatformBillingCycle BillingCycle { get; set; } = PlatformBillingCycle.Yearly;
|
||||
public int BaseAmountCents { get; set; }
|
||||
public string Currency { get; set; } = "CNY";
|
||||
public JsonElement IncludedQuotas { get; set; } = JsonDefaults.Object();
|
||||
public JsonElement OveragePrices { get; set; } = JsonDefaults.Object();
|
||||
public JsonElement FeatureFlags { get; set; } = JsonDefaults.Object();
|
||||
public PlatformSaasPlanStatus Status { get; set; } = PlatformSaasPlanStatus.Active;
|
||||
public int SortOrder { get; set; }
|
||||
}
|
||||
|
||||
public sealed class ProductModule : AuditableEntity
|
||||
{
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public ProductModuleStatus Status { get; set; } = ProductModuleStatus.Active;
|
||||
public int SortOrder { get; set; }
|
||||
}
|
||||
|
||||
public sealed class PlanModuleEntitlement : Entity
|
||||
{
|
||||
public string PlanCode { get; set; } = string.Empty;
|
||||
public string ModuleCode { get; set; } = string.Empty;
|
||||
public bool Enabled { get; set; } = true;
|
||||
}
|
||||
|
||||
public sealed class TenantModuleOverride : AuditableTenantEntity
|
||||
{
|
||||
public string ModuleCode { get; set; } = string.Empty;
|
||||
public TenantModuleOverrideMode Mode { get; set; } = TenantModuleOverrideMode.Disabled;
|
||||
public DateTimeOffset? ExpiresAt { get; set; }
|
||||
public string? Reason { get; set; }
|
||||
}
|
||||
|
||||
public sealed class TenantBillingProfile : IHasTimestamps, ITenantOwned
|
||||
{
|
||||
public Guid TenantId { get; set; }
|
||||
@@ -52,7 +13,7 @@ public sealed class TenantBillingProfile : IHasTimestamps, ITenantOwned
|
||||
public string? ContactEmail { get; set; }
|
||||
public string? BillingAddress { get; set; }
|
||||
public string? InvoiceTitle { get; set; }
|
||||
public TenantInvoiceTitleType? InvoiceType { get; set; }
|
||||
public TenantBillingInvoiceTitleType? InvoiceType { get; set; }
|
||||
public string? BankName { get; set; }
|
||||
public string? BankAccountMasked { get; set; }
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
@@ -60,63 +21,13 @@ public sealed class TenantBillingProfile : IHasTimestamps, ITenantOwned
|
||||
public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow;
|
||||
}
|
||||
|
||||
public sealed class TenantInvoice : AuditableTenantEntity
|
||||
{
|
||||
public Guid? CreatedBy { get; set; }
|
||||
public string InvoiceNo { get; set; } = string.Empty;
|
||||
public TenantInvoiceType InvoiceType { get; set; } = TenantInvoiceType.Subscription;
|
||||
public TenantInvoiceStatus Status { get; set; } = TenantInvoiceStatus.Draft;
|
||||
public string Currency { get; set; } = "CNY";
|
||||
public int SubtotalCents { get; set; }
|
||||
public int DiscountCents { get; set; }
|
||||
public int TaxCents { get; set; }
|
||||
public int TotalCents { get; set; }
|
||||
public int PaidCents { get; set; }
|
||||
public int BalanceCents { get; set; }
|
||||
public DateOnly? BillingPeriodStart { get; set; }
|
||||
public DateOnly? BillingPeriodEnd { get; set; }
|
||||
public DateOnly? DueDate { get; set; }
|
||||
public DateTimeOffset? IssuedAt { get; set; }
|
||||
public DateTimeOffset? PaidAt { get; set; }
|
||||
public string? Note { get; set; }
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
}
|
||||
|
||||
public sealed class TenantInvoiceItem : Entity, ITenantOwned
|
||||
{
|
||||
public Guid TenantId { get; set; }
|
||||
public Guid InvoiceId { get; set; }
|
||||
public string ItemType { get; set; } = "subscription";
|
||||
public Guid? ItemRefId { get; set; }
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public decimal Quantity { get; set; } = 1;
|
||||
public int UnitAmountCents { get; set; }
|
||||
public int AmountCents { get; set; }
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
|
||||
}
|
||||
|
||||
public sealed class TenantInvoicePayment : AuditableTenantEntity
|
||||
{
|
||||
public Guid InvoiceId { get; set; }
|
||||
public Guid? ReceivedBy { get; set; }
|
||||
public string PaymentNo { get; set; } = string.Empty;
|
||||
public string Provider { get; set; } = "manual";
|
||||
public string? Method { get; set; }
|
||||
public TenantInvoicePaymentStatus Status { get; set; } = TenantInvoicePaymentStatus.Paid;
|
||||
public int AmountCents { get; set; }
|
||||
public DateTimeOffset? PaidAt { get; set; }
|
||||
public string? ProviderTradeNo { get; set; }
|
||||
public JsonElement RawPayload { get; set; } = JsonDefaults.Object();
|
||||
}
|
||||
|
||||
public sealed class TenantInvoiceReminder : AuditableTenantEntity
|
||||
public sealed class PlatformBillingInvoiceReminder : AuditableTenantEntity
|
||||
{
|
||||
public Guid InvoiceId { get; set; }
|
||||
public Guid? CreatedBy { get; set; }
|
||||
public TenantInvoiceReminderType ReminderType { get; set; } = TenantInvoiceReminderType.Overdue;
|
||||
public TenantInvoiceReminderChannel Channel { get; set; } = TenantInvoiceReminderChannel.Manual;
|
||||
public TenantInvoiceReminderStatus Status { get; set; } = TenantInvoiceReminderStatus.Pending;
|
||||
public PlatformBillingInvoiceReminderType ReminderType { get; set; } = PlatformBillingInvoiceReminderType.Overdue;
|
||||
public PlatformBillingInvoiceReminderChannel Channel { get; set; } = PlatformBillingInvoiceReminderChannel.Manual;
|
||||
public PlatformBillingInvoiceReminderStatus Status { get; set; } = PlatformBillingInvoiceReminderStatus.Pending;
|
||||
public DateOnly ReminderDate { get; set; }
|
||||
public int ReminderLevel { get; set; } = 1;
|
||||
public DateOnly? DueDate { get; set; }
|
||||
@@ -163,13 +74,13 @@ public sealed class PlatformAuditAlert : AuditableEntity
|
||||
public string? ResolutionNote { get; set; }
|
||||
}
|
||||
|
||||
public sealed class PlatformDunningNotificationChannel : AuditableEntity
|
||||
public sealed class PlatformBillingDunningNotificationChannel : AuditableEntity
|
||||
{
|
||||
public string ChannelCode { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public bool Enabled { get; set; } = true;
|
||||
public PlatformDunningProvider Provider { get; set; } = PlatformDunningProvider.Generic;
|
||||
public PlatformBillingDunningProvider Provider { get; set; } = PlatformBillingDunningProvider.Generic;
|
||||
public string WebhookUrl { get; set; } = string.Empty;
|
||||
public string? SecretRef { get; set; }
|
||||
public string[] ReminderTypes { get; set; } = ["overdue", "final_notice"];
|
||||
@@ -180,13 +91,13 @@ public sealed class PlatformDunningNotificationChannel : AuditableEntity
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
}
|
||||
|
||||
public sealed class PlatformDunningNotificationEvent : AuditableTenantEntity
|
||||
public sealed class PlatformBillingDunningNotificationEvent : AuditableTenantEntity
|
||||
{
|
||||
public Guid ChannelId { get; set; }
|
||||
public Guid ReminderId { get; set; }
|
||||
public Guid InvoiceId { get; set; }
|
||||
public PlatformDunningProvider Provider { get; set; } = PlatformDunningProvider.Generic;
|
||||
public PlatformDunningNotificationStatus Status { get; set; } = PlatformDunningNotificationStatus.Pending;
|
||||
public PlatformBillingDunningProvider Provider { get; set; } = PlatformBillingDunningProvider.Generic;
|
||||
public PlatformBillingDunningNotificationStatus Status { get; set; } = PlatformBillingDunningNotificationStatus.Pending;
|
||||
public int Attempts { get; set; }
|
||||
public DateTimeOffset ScheduledAt { get; set; } = DateTimeOffset.UtcNow;
|
||||
public DateTimeOffset? NextAttemptAt { get; set; }
|
||||
@@ -200,17 +111,11 @@ public sealed class PlatformDunningNotificationEvent : AuditableTenantEntity
|
||||
}
|
||||
|
||||
public enum PlatformBillingCycle { Monthly, Quarterly, Yearly, OneTime }
|
||||
public enum PlatformSaasPlanStatus { Active, Archived }
|
||||
public enum ProductModuleStatus { Active, Archived }
|
||||
public enum TenantModuleOverrideMode { Enabled, Disabled }
|
||||
public enum TenantInvoiceTitleType { None, NormalVat, SpecialVat }
|
||||
public enum TenantInvoiceType { Subscription, ServiceFee, UsageOverage, ManualAdjustment }
|
||||
public enum TenantInvoiceStatus { Draft, Issued, Paid, Void, Overdue }
|
||||
public enum TenantInvoicePaymentStatus { Pending, Paid, Failed, Refunded }
|
||||
public enum TenantInvoiceReminderType { DueSoon, Overdue, FinalNotice, Manual }
|
||||
public enum TenantInvoiceReminderChannel { Manual, Internal, Sms, Email, Wechat, Crm }
|
||||
public enum TenantInvoiceReminderStatus { Pending, Sent, Acknowledged, Dismissed, Failed }
|
||||
public enum TenantBillingInvoiceTitleType { None, NormalVat, SpecialVat }
|
||||
public enum PlatformBillingInvoiceReminderType { DueSoon, Overdue, FinalNotice, Manual }
|
||||
public enum PlatformBillingInvoiceReminderChannel { Manual, Internal, Sms, Email, Wechat, Crm }
|
||||
public enum PlatformBillingInvoiceReminderStatus { Pending, Sent, Acknowledged, Dismissed, Failed }
|
||||
public enum PlatformAlertSeverity { Low, Medium, High, Critical }
|
||||
public enum PlatformAuditAlertStatus { Open, Acknowledged, Resolved, Ignored }
|
||||
public enum PlatformDunningProvider { Generic, Dingtalk, Feishu, Wecom }
|
||||
public enum PlatformDunningNotificationStatus { Pending, Processing, Sent, Retrying, Failed, Discarded }
|
||||
public enum PlatformBillingDunningProvider { Generic, Dingtalk, Feishu, Wecom }
|
||||
public enum PlatformBillingDunningNotificationStatus { Pending, Processing, Sent, Retrying, Failed, Discarded }
|
||||
|
||||
244
Tiku.Domain/Platform/SaasBillingEntities.cs
Normal file
244
Tiku.Domain/Platform/SaasBillingEntities.cs
Normal file
@@ -0,0 +1,244 @@
|
||||
using System.Text.Json;
|
||||
using Tiku.Domain.Common;
|
||||
using Tiku.Domain.Operations;
|
||||
|
||||
namespace Tiku.Domain.Platform;
|
||||
|
||||
public sealed class SaasFeature : AuditableEntity
|
||||
{
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Category { get; set; } = string.Empty;
|
||||
public string? Description { get; set; }
|
||||
public int ReferencePriceCents { get; set; }
|
||||
public string Currency { get; set; } = "CNY";
|
||||
public SaasFeatureStatus Status { get; set; } = SaasFeatureStatus.Draft;
|
||||
public bool IsCore { get; set; }
|
||||
public int SortOrder { get; set; } = 100;
|
||||
}
|
||||
|
||||
public sealed class PermissionModule : AuditableEntity
|
||||
{
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public BackendPermissionArea Area { get; set; } = BackendPermissionArea.Tenant;
|
||||
public string? RequiredFeatureCode { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public int SortOrder { get; set; } = 100;
|
||||
}
|
||||
|
||||
public sealed class SaasOffering : AuditableEntity
|
||||
{
|
||||
public string Code { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public SaasOfferingType Type { get; set; } = SaasOfferingType.BasePlan;
|
||||
public SaasOfferingStatus Status { get; set; } = SaasOfferingStatus.Draft;
|
||||
public string? Description { get; set; }
|
||||
public int SortOrder { get; set; } = 100;
|
||||
}
|
||||
|
||||
public sealed class SaasOfferingVersion : AuditableEntity
|
||||
{
|
||||
public Guid OfferingId { get; set; }
|
||||
public int Version { get; set; } = 1;
|
||||
public SaasOfferingVersionStatus Status { get; set; } = SaasOfferingVersionStatus.Draft;
|
||||
public PlatformBillingCycle BillingCycle { get; set; } = PlatformBillingCycle.Yearly;
|
||||
public int OriginalAmountCents { get; set; }
|
||||
public int AmountCents { get; set; }
|
||||
public string Currency { get; set; } = "CNY";
|
||||
public DateTimeOffset? EffectiveAt { get; set; }
|
||||
public DateTimeOffset? PublishedAt { get; set; }
|
||||
public DateTimeOffset? RetiredAt { get; set; }
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
}
|
||||
|
||||
public sealed class SaasOfferingVersionFeature : Entity
|
||||
{
|
||||
public Guid OfferingVersionId { get; set; }
|
||||
public string FeatureCode { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public sealed class SaasFeatureLimitDefinition : AuditableEntity
|
||||
{
|
||||
public string MetricCode { get; set; } = string.Empty;
|
||||
public string FeatureCode { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Unit { get; set; } = "count";
|
||||
public SaasFeatureLimitKind Kind { get; set; } = SaasFeatureLimitKind.Current;
|
||||
public int WarningPercent { get; set; } = 80;
|
||||
public bool IsHardLimit { get; set; } = true;
|
||||
}
|
||||
|
||||
public sealed class SaasOfferingVersionLimit : Entity
|
||||
{
|
||||
public Guid OfferingVersionId { get; set; }
|
||||
public string MetricCode { get; set; } = string.Empty;
|
||||
public long LimitValue { get; set; }
|
||||
}
|
||||
|
||||
public sealed class TenantSaasSubscription : AuditableTenantEntity
|
||||
{
|
||||
public Guid BaseOfferingVersionId { get; set; }
|
||||
public Guid? ScheduledBaseOfferingVersionId { get; set; }
|
||||
public TenantSaasSubscriptionStatus Status { get; set; } = TenantSaasSubscriptionStatus.Trial;
|
||||
public DateTimeOffset StartsAt { get; set; }
|
||||
public DateTimeOffset CurrentPeriodStart { get; set; }
|
||||
public DateTimeOffset CurrentPeriodEnd { get; set; }
|
||||
public bool CancelAtPeriodEnd { get; set; }
|
||||
public DateTimeOffset? CancelledAt { get; set; }
|
||||
public long LifecycleVersion { get; set; }
|
||||
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
|
||||
}
|
||||
|
||||
public sealed class TenantSaasSubscriptionItem : AuditableTenantEntity
|
||||
{
|
||||
public Guid SubscriptionId { get; set; }
|
||||
public Guid OfferingVersionId { get; set; }
|
||||
public Guid? SourceOrderItemId { get; set; }
|
||||
public TenantSaasSubscriptionItemType ItemType { get; set; } = TenantSaasSubscriptionItemType.BasePlan;
|
||||
public TenantSaasSubscriptionItemStatus Status { get; set; } = TenantSaasSubscriptionItemStatus.Active;
|
||||
public DateTimeOffset StartsAt { get; set; }
|
||||
public DateTimeOffset EndsAt { get; set; }
|
||||
}
|
||||
|
||||
public sealed class TenantFeatureOverride : AuditableTenantEntity
|
||||
{
|
||||
public string FeatureCode { get; set; } = string.Empty;
|
||||
public TenantFeatureOverrideMode Mode { get; set; } = TenantFeatureOverrideMode.Disabled;
|
||||
public DateTimeOffset? ExpiresAt { get; set; }
|
||||
public string Reason { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public sealed class TenantFeatureUsage : AuditableTenantEntity
|
||||
{
|
||||
public string MetricCode { get; set; } = string.Empty;
|
||||
public DateTimeOffset PeriodStart { get; set; }
|
||||
public DateTimeOffset PeriodEnd { get; set; }
|
||||
public long UsedValue { get; set; }
|
||||
public long LimitValueSnapshot { get; set; }
|
||||
public bool WarningIssued { get; set; }
|
||||
public long Version { get; set; }
|
||||
}
|
||||
|
||||
public sealed class PlatformBillingQuote : AuditableTenantEntity
|
||||
{
|
||||
public string QuoteNo { get; set; } = string.Empty;
|
||||
public string IdempotencyKey { get; set; } = string.Empty;
|
||||
public PlatformBillingQuoteStatus Status { get; set; } = PlatformBillingQuoteStatus.Active;
|
||||
public PlatformBillingOrderPurpose Purpose { get; set; } = PlatformBillingOrderPurpose.NewSubscription;
|
||||
public int OriginalAmountCents { get; set; }
|
||||
public int DiscountAmountCents { get; set; }
|
||||
public int TotalAmountCents { get; set; }
|
||||
public string Currency { get; set; } = "CNY";
|
||||
public DateTimeOffset ExpiresAt { get; set; }
|
||||
public JsonElement FeatureSnapshot { get; set; } = JsonDefaults.Array();
|
||||
public JsonElement LimitSnapshot { get; set; } = JsonDefaults.Object();
|
||||
}
|
||||
|
||||
public sealed class PlatformBillingQuoteItem : Entity, ITenantOwned
|
||||
{
|
||||
public Guid TenantId { get; set; }
|
||||
public Guid QuoteId { get; set; }
|
||||
public Guid OfferingVersionId { get; set; }
|
||||
public PlatformBillingItemType ItemType { get; set; } = PlatformBillingItemType.BasePlan;
|
||||
public int Quantity { get; set; } = 1;
|
||||
public int UnitAmountCents { get; set; }
|
||||
public int AmountCents { get; set; }
|
||||
public JsonElement Snapshot { get; set; } = JsonDefaults.Object();
|
||||
}
|
||||
|
||||
public sealed class PlatformBillingOrder : AuditableTenantEntity
|
||||
{
|
||||
public Guid QuoteId { get; set; }
|
||||
public string OrderNo { get; set; } = string.Empty;
|
||||
public string IdempotencyKey { get; set; } = string.Empty;
|
||||
public PlatformBillingOrderPurpose Purpose { get; set; } = PlatformBillingOrderPurpose.NewSubscription;
|
||||
public PlatformBillingOrderStatus Status { get; set; } = PlatformBillingOrderStatus.PendingPayment;
|
||||
public int OriginalAmountCents { get; set; }
|
||||
public int DiscountAmountCents { get; set; }
|
||||
public int TotalAmountCents { get; set; }
|
||||
public string Currency { get; set; } = "CNY";
|
||||
public DateTimeOffset ExpiresAt { get; set; }
|
||||
public DateTimeOffset? PaidAt { get; set; }
|
||||
public DateTimeOffset? CancelledAt { get; set; }
|
||||
public JsonElement Snapshot { get; set; } = JsonDefaults.Object();
|
||||
}
|
||||
|
||||
public sealed class PlatformBillingOrderItem : Entity, ITenantOwned
|
||||
{
|
||||
public Guid TenantId { get; set; }
|
||||
public Guid OrderId { get; set; }
|
||||
public Guid OfferingVersionId { get; set; }
|
||||
public PlatformBillingItemType ItemType { get; set; } = PlatformBillingItemType.BasePlan;
|
||||
public int Quantity { get; set; } = 1;
|
||||
public int UnitAmountCents { get; set; }
|
||||
public int AmountCents { get; set; }
|
||||
public JsonElement Snapshot { get; set; } = JsonDefaults.Object();
|
||||
}
|
||||
|
||||
public sealed class PlatformBillingPayment : AuditableTenantEntity
|
||||
{
|
||||
public Guid OrderId { get; set; }
|
||||
public string PaymentNo { get; set; } = string.Empty;
|
||||
public string IdempotencyKey { get; set; } = string.Empty;
|
||||
public string Provider { get; set; } = string.Empty;
|
||||
public string Method { get; set; } = string.Empty;
|
||||
public PlatformBillingPaymentStatus Status { get; set; } = PlatformBillingPaymentStatus.Pending;
|
||||
public int AmountCents { get; set; }
|
||||
public string? ProviderTradeNo { get; set; }
|
||||
public DateTimeOffset? PaidAt { get; set; }
|
||||
public JsonElement ClientPayload { get; set; } = JsonDefaults.Object();
|
||||
}
|
||||
|
||||
public sealed class PlatformBillingPaymentEvent : Entity, ITenantOwned
|
||||
{
|
||||
public Guid TenantId { get; set; }
|
||||
public Guid PaymentId { get; set; }
|
||||
public string Provider { get; set; } = string.Empty;
|
||||
public string ProviderEventId { get; set; } = string.Empty;
|
||||
public string EventType { get; set; } = string.Empty;
|
||||
public JsonElement Payload { get; set; } = JsonDefaults.Object();
|
||||
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
|
||||
}
|
||||
|
||||
public sealed class PlatformBillingRefund : AuditableTenantEntity
|
||||
{
|
||||
public Guid OrderId { get; set; }
|
||||
public Guid? PaymentId { get; set; }
|
||||
public string RefundNo { get; set; } = string.Empty;
|
||||
public PlatformBillingRefundStatus Status { get; set; } = PlatformBillingRefundStatus.Requested;
|
||||
public int AmountCents { get; set; }
|
||||
public string Reason { get; set; } = string.Empty;
|
||||
public string? ProviderRefundNo { get; set; }
|
||||
public DateTimeOffset? CompletedAt { get; set; }
|
||||
}
|
||||
|
||||
public sealed class PlatformBillingInvoice : AuditableTenantEntity
|
||||
{
|
||||
public Guid? OrderId { get; set; }
|
||||
public string InvoiceNo { get; set; } = string.Empty;
|
||||
public PlatformBillingInvoiceStatus Status { get; set; } = PlatformBillingInvoiceStatus.Draft;
|
||||
public int TotalAmountCents { get; set; }
|
||||
public string Currency { get; set; } = "CNY";
|
||||
public DateOnly? DueDate { get; set; }
|
||||
public DateTimeOffset? IssuedAt { get; set; }
|
||||
public DateTimeOffset? PaidAt { get; set; }
|
||||
public JsonElement BillingProfileSnapshot { get; set; } = JsonDefaults.Object();
|
||||
}
|
||||
|
||||
public enum SaasFeatureStatus { Draft, Active, Archived }
|
||||
public enum SaasOfferingType { BasePlan, AddOn }
|
||||
public enum SaasOfferingStatus { Draft, Active, Archived }
|
||||
public enum SaasOfferingVersionStatus { Draft, Published, Retired }
|
||||
public enum SaasFeatureLimitKind { Current, Period }
|
||||
public enum TenantSaasSubscriptionStatus { Trial, Active, PastDue, Cancelled, Expired, Suspended }
|
||||
public enum TenantSaasSubscriptionItemType { BasePlan, AddOn }
|
||||
public enum TenantSaasSubscriptionItemStatus { Pending, Active, Scheduled, Cancelled, Expired }
|
||||
public enum TenantFeatureOverrideMode { Enabled, Disabled }
|
||||
public enum PlatformBillingQuoteStatus { Active, Converted, Expired, Cancelled }
|
||||
public enum PlatformBillingOrderPurpose { NewSubscription, Renewal, Upgrade, Downgrade, AddOn }
|
||||
public enum PlatformBillingOrderStatus { PendingPayment, Paid, Cancelled, Expired, Refunded }
|
||||
public enum PlatformBillingItemType { BasePlan, AddOn }
|
||||
public enum PlatformBillingPaymentStatus { Pending, Succeeded, Failed, Refunded }
|
||||
public enum PlatformBillingRefundStatus { Requested, Processing, Succeeded, Failed, Cancelled }
|
||||
public enum PlatformBillingInvoiceStatus { Draft, Issued, Paid, Void, Overdue }
|
||||
@@ -63,6 +63,7 @@ public sealed class TenantAuthPolicy : IHasTimestamps, ITenantOwned
|
||||
{
|
||||
public Guid TenantId { get; set; }
|
||||
public bool AllowExternalStudentSelfRegistration { get; set; }
|
||||
public string[] AllowedStudentLoginMethods { get; set; } = ["password"];
|
||||
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
|
||||
public DateTimeOffset UpdatedAt { get; set; } = DateTimeOffset.UtcNow;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user