| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- using System.ComponentModel.DataAnnotations;
- using System.ComponentModel.DataAnnotations.Schema;
- using Domain.Entities.Members;
- using Domain.Entities.Payments.ValueObject;
- namespace Domain.Entities.Payments;
- public class PaymentOrder
- {
- [ForeignKey(nameof(MemberID))]
- public virtual Member? Member { get; private set; }
- [Key]
- public int ID { get; private set; }
- public int MemberID { get; private set; }
- /// <summary>가맹점 주문번호 (unique, 중복 불가)</summary>
- public string OrderID { get; private set; } = default!;
- /// <summary>다날 CPID (계약 완료 후 발급)</summary>
- public string MerchantID { get; private set; } = default!;
- /// <summary>상품명</summary>
- public string OrderName { get; private set; } = "포인트 충전";
- /// <summary>다날 거래번호 (승인 후 저장)</summary>
- public string? TransactionID { get; private set; }
- /// <summary>결제 금액 (부가세 포함 총액)</summary>
- public int Amount { get; private set; }
- /// <summary>충전될 포인트 (= 결제금액, 1:1)</summary>
- public int PointAmount { get; private set; }
- /// <summary>부가세 (표시용)</summary>
- public int VatAmount { get; private set; }
- public PaymentMethod PaymentMethod { get; private set; }
- public PaymentStatus Status { get; private set; }
- public DateTime? PaidAt { get; private set; }
- public DateTime? CancelledAt { get; private set; }
- public string? FailReason { get; private set; }
- /// <summary>가상계좌: 계좌번호</summary>
- public string? VirtualAccountNumber { get; private set; }
- /// <summary>가상계좌: 은행명</summary>
- public string? VirtualAccountBank { get; private set; }
- /// <summary>가상계좌: 예금주</summary>
- public string? VirtualAccountHolder { get; private set; }
- /// <summary>가상계좌: 입금 기한</summary>
- public DateTime? VirtualAccountExpireAt { get; private set; }
- public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
- private PaymentOrder() { }
- public static PaymentOrder Create(
- int memberID,
- string orderID,
- string merchantID,
- int amount,
- PaymentMethod method,
- string orderName = "포인트 충전"
- ) {
- ArgumentOutOfRangeException.ThrowIfNegativeOrZero(memberID);
- ArgumentOutOfRangeException.ThrowIfNegativeOrZero(amount);
- if (string.IsNullOrWhiteSpace(orderID)) {
- throw new ArgumentException("orderID required", nameof(orderID));
- }
- if (string.IsNullOrWhiteSpace(merchantID)) {
- throw new ArgumentException("merchantID required", nameof(merchantID));
- }
- var vat = (int)Math.Round(amount / 11.0);
- return new PaymentOrder
- {
- MemberID = memberID,
- OrderID = orderID,
- MerchantID = merchantID,
- OrderName = orderName,
- Amount = amount,
- PointAmount = amount,
- VatAmount = vat,
- PaymentMethod = method,
- Status = PaymentStatus.Pending
- };
- }
- public void MarkPaid(string transactionID)
- {
- if (Status is not PaymentStatus.Pending and not PaymentStatus.WaitingDeposit)
- {
- throw new InvalidOperationException($"Cannot mark as paid from status {Status}");
- }
- TransactionID = transactionID;
- Status = PaymentStatus.Paid;
- PaidAt = DateTime.UtcNow;
- }
- public void MarkFailed(string reason)
- {
- Status = PaymentStatus.Failed;
- FailReason = reason;
- }
- public void MarkCancelled()
- {
- if (Status != PaymentStatus.Paid)
- {
- throw new InvalidOperationException($"Cannot cancel from status {Status}");
- }
- Status = PaymentStatus.Cancelled;
- CancelledAt = DateTime.UtcNow;
- }
- public void MarkWaitingDeposit(string accountNumber, string bank, string holder, DateTime expireAt)
- {
- Status = PaymentStatus.WaitingDeposit;
- VirtualAccountNumber = accountNumber;
- VirtualAccountBank = bank;
- VirtualAccountHolder = holder;
- VirtualAccountExpireAt = expireAt;
- }
- }
|