using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Domain.Entities.Members;
namespace Domain.Entities.Payments.Toss;
///
/// 토스페이먼츠 결제 취소 요청 + 응답 통합
/// 전체 취소 / 부분 취소 모두 지원
///
public class TossCancel
{
[ForeignKey(nameof(MemberID))]
public virtual Member? Member { get; private set; }
[ForeignKey(nameof(PaymentOrderID))]
public virtual PaymentOrder? PaymentOrder { get; private set; }
[Key]
public int ID { get; private set; }
public int MemberID { get; private set; }
public int PaymentOrderID { get; private set; }
/// 원거래 결제 키 (취소 대상 paymentKey)
public string PaymentKey { get; private set; } = default!;
/// 가맹점 주문번호
public string OrderID { get; private set; } = default!;
/// 취소 요청 금액
public int CancelAmount { get; private set; }
/// 취소 사유 (Toss cancelReason — 최대 200자)
public string CancelReason { get; private set; } = default!;
/// 취소 요청자 (admin / system / member / webhook)
public string? CancelRequester { get; private set; }
// ── 응답 필드 ────────────────────────────────────────────────────
/// 응답 코드 (SUCCESS = 성공, 그 외 = Toss 에러 코드/EXCEPTION)
public string? ResponseCode { get; private set; }
/// 응답 메시지 (실패 사유)
public string? ResponseMessage { get; private set; }
/// 취소 거래 키 (Toss cancels[].transactionKey)
public string? TransactionKey { get; private set; }
/// 취소 후 Payment.status (CANCELED / PARTIAL_CANCELED)
public string? Status { get; private set; }
/// 취소 일시 (UTC)
public DateTime? CanceledAt { get; private set; }
/// Toss Payment 객체 원문 JSON — 대사/CS 용
public string? RawResponse { get; private set; }
public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
public DateTime? UpdatedAt { get; private set; }
private TossCancel() { }
public static TossCancel CreateRequest(
int memberID,
int paymentOrderID,
string paymentKey,
string orderID,
int cancelAmount,
string cancelReason,
string? cancelRequester = null
) {
return new TossCancel
{
MemberID = memberID,
PaymentOrderID = paymentOrderID,
PaymentKey = paymentKey,
OrderID = orderID,
CancelAmount = cancelAmount,
CancelReason = cancelReason.Length > 200 ? cancelReason[..200] : cancelReason,
CancelRequester = cancelRequester
};
}
/// 취소 성공 응답 수신 시 업데이트
public void SetResponse(
string status,
string? transactionKey = null,
DateTime? canceledAt = null,
string? rawResponse = null
) {
ResponseCode = "SUCCESS";
ResponseMessage = null;
Status = status;
TransactionKey = transactionKey;
CanceledAt = canceledAt;
RawResponse = rawResponse;
UpdatedAt = DateTime.UtcNow;
}
/// 취소 실패/예외 시 업데이트
public void SetError(string code, string message)
{
ResponseCode = code;
ResponseMessage = message.Length > 500 ? message[..500] : message;
UpdatedAt = DateTime.UtcNow;
}
public bool IsSuccess => ResponseCode == "SUCCESS";
}