ApiPurchaseCancel.cs 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. using System.ComponentModel.DataAnnotations;
  2. using System.ComponentModel.DataAnnotations.Schema;
  3. namespace Domain.Entities.Developers;
  4. /// <summary>
  5. /// API 결제 취소 감사 기록. ApiPurchase 1:1 (PurchaseID UNIQUE — 중복 취소 방지).
  6. /// WasConfirmed=false → 보류 중 취소 (지갑 무관, Recovered/Shortfall 0).
  7. /// WasConfirmed=true → 확정 후 취소 (StoreRevenue 회수, 잔액 부족분은 ShortfallAmount 에 기록).
  8. /// </summary>
  9. public class ApiPurchaseCancel
  10. {
  11. [ForeignKey(nameof(PurchaseID))]
  12. public virtual ApiPurchase? Purchase { get; private set; }
  13. [Key]
  14. public int ID { get; private set; }
  15. public int PurchaseID { get; private set; }
  16. public int ApplicationID { get; private set; }
  17. public int ChannelID { get; private set; }
  18. public int CreditedMemberID { get; private set; }
  19. /// <summary>확정(지갑 적립) 후의 취소였는지</summary>
  20. public bool WasConfirmed { get; private set; }
  21. /// <summary>실제 회수액 (KRW). 보류 중 취소면 0.</summary>
  22. public int RecoveredAmount { get; private set; }
  23. /// <summary>잔액 부족으로 회수하지 못한 금액 (KRW). 0 이면 완전 회수.</summary>
  24. public int ShortfallAmount { get; private set; }
  25. public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
  26. private ApiPurchaseCancel() { }
  27. public static ApiPurchaseCancel Create(ApiPurchase purchase, bool wasConfirmed, int recoveredAmount, int shortfallAmount)
  28. {
  29. if (purchase.ID <= 0)
  30. {
  31. throw new ArgumentException("Purchase must be persisted.", nameof(purchase));
  32. }
  33. if (recoveredAmount < 0)
  34. {
  35. throw new ArgumentOutOfRangeException(nameof(recoveredAmount));
  36. }
  37. if (shortfallAmount < 0)
  38. {
  39. throw new ArgumentOutOfRangeException(nameof(shortfallAmount));
  40. }
  41. return new ApiPurchaseCancel
  42. {
  43. PurchaseID = purchase.ID,
  44. ApplicationID = purchase.ApplicationID,
  45. ChannelID = purchase.ChannelID,
  46. CreditedMemberID = purchase.CreditedMemberID,
  47. WasConfirmed = wasConfirmed,
  48. RecoveredAmount = recoveredAmount,
  49. ShortfallAmount = shortfallAmount
  50. };
  51. }
  52. }