| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347 |
- @page "{id:int}"
- @model Admin.Pages.Payments.Danal.Confirm.ViewModel
- @using Domain.Entities.Payments.ValueObject
- @using SharedKernel.Extensions
- @{
- ViewData["Title"] = "다날 결제 상세";
- string MethodName(PaymentMethod m) => m switch
- {
- PaymentMethod.Card => "신용카드",
- PaymentMethod.VirtualAccount => "가상계좌",
- PaymentMethod.Mobile => "휴대폰",
- PaymentMethod.Transfer => "계좌이체",
- PaymentMethod.NaverPay => "네이버페이",
- PaymentMethod.KakaoPay => "카카오페이",
- PaymentMethod.Payco => "페이코",
- PaymentMethod.Integrated => "통합",
- _ => "-"
- };
- }
- <div class="container">
- <h3>@ViewData["Title"]</h3>
- <hr />
- <partial name="_StatusMessage" />
- @if (Model.Data is null)
- {
- <div class="alert alert-danger">결제 내역을 불러올 수 없습니다.</div>
- }
- else
- {
- var confirm = Model.Data.Confirm;
- var cancel = Model.Data.Cancel;
- var isCardLike = confirm.Method is PaymentMethod.Card or PaymentMethod.NaverPay or PaymentMethod.KakaoPay or PaymentMethod.Payco;
- var isMobile = confirm.Method == PaymentMethod.Mobile;
- var isTransfer = confirm.Method == PaymentMethod.Transfer;
- var isVAccount = confirm.Method == PaymentMethod.VirtualAccount;
- <h5 class="mb-3">다날 결제 요청</h5>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">PK</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@confirm.ID</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">회원</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">[@confirm.MemberID] @(confirm.MemberName ?? "-") / @confirm.MemberEmail</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">결제 수단</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@MethodName(confirm.Method)</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">거래번호</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@confirm.TransactionID</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">주문번호</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@confirm.OrderID</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">요청 금액</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@confirm.Amount.ToString("N0") 원</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">CPID</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@confirm.MerchantID</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">상품명</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(string.IsNullOrEmpty(confirm.OrderName) ? "-" : confirm.OrderName)</div>
- </div>
- </div>
- <hr />
- <h5 class="mb-3">다날 결제 응답</h5>
- @if (string.IsNullOrEmpty(confirm.ResponseCode))
- {
- <div class="alert alert-warning">다날 결제 요청 후 최종 승인 응답이 기록되지 않았습니다.</div>
- }
- else
- {
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">응답 코드</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">[@confirm.ResponseCode] @confirm.ResponseMessage</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">최종 승인 금액</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.TotalAmount.HasValue ? confirm.TotalAmount.Value.ToString("N0") + " 원" : "-")</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">할인 금액</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.DiscountAmount.HasValue ? confirm.DiscountAmount.Value.ToString("N0") + " 원" : "-")</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">사용자 이름</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.UserName ?? "-")</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">승인 일시</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">
- @(string.IsNullOrEmpty(confirm.TransDate) && string.IsNullOrEmpty(confirm.TransTime) ? "-" : $"{confirm.TransDate} {confirm.TransTime}")
- </div>
- </div>
- </div>
- @if (isCardLike)
- {
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">카드사</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(string.IsNullOrEmpty(confirm.CardName) ? "-" : $"[{confirm.CardCode}] {confirm.CardName}")</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">카드번호</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.CardNo ?? "-")</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">할부 개월</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.InstallmentMonths.HasValue ? $"{confirm.InstallmentMonths} 개월" : "-")</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">승인번호</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.ApproveNo ?? "-")</div>
- </div>
- </div>
- }
- @if (isMobile)
- {
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">결제 승인 일시</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.ApprovalDateTime ?? "-")</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">정기결제 키</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.AuthKey ?? "-")</div>
- </div>
- </div>
- }
- @if (isTransfer)
- {
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">출금계좌</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.AccountNumber ?? "-")</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">은행 코드</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.BankCode ?? "-")</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">사용자 ID</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.UserId ?? "-")</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">사용자 이메일</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.UserEmail ?? "-")</div>
- </div>
- </div>
- }
- @if (isVAccount)
- {
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">입금은행</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.BankName ?? "-")</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">입금 마감</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">
- @(string.IsNullOrEmpty(confirm.ExpireDate) && string.IsNullOrEmpty(confirm.ExpireTime) ? "-" : $"{confirm.ExpireDate} {confirm.ExpireTime}")
- </div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">가상계좌 번호</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.VirtualAccountNumber ?? "-")</div>
- </div>
- </div>
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">현금영수증</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@(confirm.UseCashReceipt == "Y" ? "사용" : confirm.UseCashReceipt == "N" ? "미사용" : "-")</div>
- </div>
- </div>
- }
- @if (confirm.UpdatedAt is not null)
- {
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">수정 일시</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@confirm.UpdatedAt.GetDateAt()</div>
- </div>
- </div>
- }
- <div class="row mb-2">
- <label class="col-sm-2 col-form-label">등록 일시</label>
- <div class="col-sm-10">
- <div class="form-control-plaintext">@confirm.CreatedAt.GetDateAt()</div>
- </div>
- </div>
- <hr />
- <h5 class="mb-3">다날 결제 취소</h5>
- @if (cancel is not null)
- {
- <div class="alert alert-success" role="alert">
- 이미 다날 결제 취소가 완료되었습니다. (@(cancel.CancelType == Domain.Entities.Payments.Danal.ValueObject.DanalCancelType.Full ? "전액" : "부분") 환불 — @cancel.Amount.ToString("N0") 원)
- </div>
- }
- else if (confirm.OrderStatus == PaymentStatus.Paid)
- {
- var isForcedCancel = confirm.ResponseCode != "0000";
- if (isForcedCancel)
- {
- <div class="alert alert-danger" role="alert">
- <strong>주의 — 다날 응답 코드가 [@(string.IsNullOrEmpty(confirm.ResponseCode) ? "응답 미수신" : confirm.ResponseCode)] 인 강제 환불입니다.</strong><br />
- PaymentOrder.Status 는 <code>Paid</code> 이지만 DanalConfirm 응답이 비정상입니다. 다날 PG 콘솔에서 실제 거래 상태를 사전 확인 후 진행하세요.
- </div>
- }
- <div class="alert alert-warning" role="alert">
- 다날 결제 승인 후 전액 취소가 가능합니다. (취소 금액: <u>@confirm.Amount.ToString("N0") 원</u>)<br />
- 취소 요청자는 주체를 구분하기 위해 사용합니다. 취소 사유는 추후 거래 상태 식별 및 대응을 위해 활용됩니다.
- </div>
- <form id="fAdminWrite" method="post" asp-page-handler="Cancel" accept-charset="utf-8" autocomplete="off" data-forced="@(isForcedCancel ? "1" : "0")">
- @Html.AntiForgeryToken()
- <div class="row mb-2">
- <label asp-for="Input.CancelRequester" class="col-sm-2 col-form-label">취소 요청자</label>
- <div class="col-sm-10">
- <input asp-for="Input.CancelRequester" class="form-control" maxlength="20" placeholder="20자 이내" required />
- <span asp-validation-for="Input.CancelRequester" class="text-danger"></span>
- </div>
- </div>
- <div class="row mb-2">
- <label asp-for="Input.CancelReason" class="col-sm-2 col-form-label">취소 사유</label>
- <div class="col-sm-10">
- <textarea asp-for="Input.CancelReason" class="form-control" placeholder="최대 255자" rows="3" maxlength="255" required></textarea>
- <span asp-validation-for="Input.CancelReason" class="text-danger"></span>
- </div>
- </div>
- <div class="d-grid gap-2 text-center d-md-block">
- <button type="submit" class="btn btn-danger">결제 취소 (전액 @confirm.Amount.ToString("N0") 원)</button>
- </div>
- </form>
- }
- else if (confirm.OrderStatus == PaymentStatus.Cancelled)
- {
- <div class="alert alert-info" role="alert">
- 이미 취소된 주문입니다. (PaymentOrder.Status = Cancelled)
- </div>
- }
- else if (confirm.OrderStatus == PaymentStatus.Failed)
- {
- <div class="alert alert-secondary" role="alert">
- 결제가 실패한 주문입니다. 환불할 금액이 없습니다. (PaymentOrder.Status = Failed)
- </div>
- }
- else if (confirm.OrderStatus is PaymentStatus.Pending or PaymentStatus.WaitingDeposit)
- {
- <div class="alert alert-warning" role="alert">
- 결제가 아직 완료되지 않았습니다. (PaymentOrder.Status = @confirm.OrderStatus) — 입금 대기 / 처리 중인 거래는 취소할 수 없습니다.
- </div>
- }
- else
- {
- <div class="alert alert-warning" role="alert">
- 승인되지 않은 결제는 취소할 수 없습니다.
- </div>
- }
- }
- <hr />
- <div class="d-grid gap-2 text-center d-md-block">
- <a href="/Payments/Danal/Confirm@(Request.QueryString)" class="btn btn-sm btn-secondary">뒤로가기</a>
- </div>
- <br />
- <br />
- <br />
- }
- </div>
- @section Scripts {
- <script>
- $(document).on("submit", "#fAdminWrite", function (e) {
- e.preventDefault();
- var forced = $(this).data("forced") === 1 || $(this).data("forced") === "1";
- var message = forced
- ? "[강제 환불] 다날 응답 코드가 비정상이지만 PaymentOrder.Status 는 Paid 입니다.\n다날 PG 콘솔에서 실제 거래 상태를 확인하셨습니까?\n전액 결제 취소를 진행합니다 — 다날 API 를 실제로 호출합니다."
- : "전액 결제 취소를 진행하시겠습니까?\n다날 API를 실제로 호출합니다.";
- if (!confirm(message)) {
- return false;
- }
- this.submit();
- });
- </script>
- }
|