결제리스트

PAYMENTS · /payments

실제 화면 열기 ↗
종류
목록
부르는 것
1
lib 함수
가드레일
11
177
로그인 필요수강 · 결제

화면

관리자 세션으로 촬영한 실제 화면입니다.

PAYMENTS 캡처

이 화면이 부르는 것

  • ·listOrdersForAdmin()
소스 src/app/(console)/payments/page.tsx

같은 규칙을 쓰는 화면

이 화면 하나뿐입니다.

개발 스펙

ADMIN-PAYMENTS완료이 스펙은 1개 화면이 함께 씁니다

이 화면에서 할 수 있어야 하는 것 (3)

  • 관리자가 결제 내역을 상태 · 수단 · 키워드로 찾는다.
  • 무통장 입금을 확인해 수강권을 연다.
  • 결제를 환불하고 수강권을 회수한다.

비즈니스 규칙 (4)

  • 입금확인은 무통장 ready 주문에만 뜬다. 누르면 success + 수강권 활성화.
  • 환불은 success 주문에만 뜬다. 카드는 PG 취소를, 무통장은 상태 정리만 한다.
  • 취소 해시 = sha256(MID + CancelAmt + EdiDate + MerchantKey), 성공코드 2001.
    근거: NICEPAY/3.02/Test/cancelResult_utf.php:13
  • lecture → 수강권 매핑: tesol→pay_yn, tec→pay_tec_yn, tesoltec→둘 다, phonics→pay_phonics_yn, apostille→pay_apostille_yn.
    근거: 원본에는 없던 매핑. 원본은 관리자가 회원 수정 화면에서 직접 켰다(admin/member/mb_proc.php).

API (3)

메서드경로권한모듈 · 설명
GET/api/commerce/admin/orders관리자
결제 목록(상태 · 수단 · 키워드 필터).
domains:commerce:commerce-web
POST/api/commerce/admin/orders/{orderNo}/confirm관리자
무통장 입금 확인 → 수강권 활성화.
domains:commerce:commerce-web
400 NOT_BANK_ORDER
409 ALREADY_CANCELLED
POST/api/commerce/admin/orders/{orderNo}/refund관리자
환불 → 수강권 회수. 카드는 PG 취소를 부른다.
domains:commerce:commerce-web
요청: { reason }
409 ALREADY_CANCELLED
422 NO_TID — PG 거래번호 없음(레거시)
502 PG_CANCEL_FAILED

가드레일 (11) — id 가 곧 테스트 이름이다

id반드시 만족해야 하는 것등급
order-amount-requires-admin
결제 금액은 관리자만 고칠 수 있어야 한다.
원본 payment_amount.php 는 세션 확인 없이 idx 와 amount 만 받아 UPDATE 했다.
critical
order-amount-range-checked
0 이하이거나 1억을 넘는 금액은 거부해야 한다.
원본은 목록 입력칸 값을 그대로 저장했다 — 자릿수를 틀려도 들어갔다.
high
order-amount-not-on-cancelled
취소된 주문의 금액은 고칠 수 없어야 한다.
장부가 어긋난다 — 취소 금액과 결제 금액이 따로 논다.
high
order-amount-updates
고치면 금액만 바뀌고 상태·결제수단은 그대로여야 한다.
normal
order-amount-editor-shown
결제 목록에서 금액을 바로 고칠 수 있어야 한다.
원본도 목록 입력칸에서 고쳤다.
normal
admin-requires-admin-role
수강생 세션으로 관리자 API 를 호출하면 거부돼야 한다. 화면 가드만으로 충분하지 않다.
critical
admin-confirm-opens-entitlement
입금확인 후 해당 회원의 수강권 플래그가 Y 가 돼야 한다.
critical
admin-refund-revokes-entitlement
환불 후 수강권 플래그가 N 으로 회수돼야 한다.
critical
admin-refund-requires-pg-success
카드 환불은 PG 취소가 성공해야만 상태를 cancel 로 바꾼다. PG 실패 시 상태가 그대로여야 한다.
critical
admin-refund-no-tid-blocked
TID 없는 카드 주문은 환불을 막고 안내해야 한다. 상태를 바꾸면 안 된다.
high
admin-no-double-refund
이미 cancel 인 주문은 다시 환불되면 안 된다.
high

구현 계획 (12/12)

  1. OrderRepository.updateAmount 포트commerce-domain
  2. 유스케이스 — 관리자 확인 · 범위 검사 · 취소 주문 차단 · 변경 로그commerce-app
  3. payment.amount 수정 어댑터 (상태는 건드리지 않는다)commerce-infrastructure
  4. POST /admin/orders/{orderNo}/amountcommerce-web
  5. 결제 목록의 금액 입력칸과 확인 대화상자wvctesol-admin
  6. Order · OrderState · Entitlement · 포트 2개commerce-domain
  7. PlaceOrderUseCase · AdminOrderUseCasecommerce-app
  8. OrderRepositoryAdapter · NicepayGatewaycommerce-infrastructure
  9. /api/commerce/admin/orders 구현commerce-web
  10. /api/commerce/admin/orders/{orderNo}/confirm 구현commerce-web
  11. /api/commerce/admin/orders/{orderNo}/refund 구현commerce-web
  12. Next.js 를 BFF 로 전환 — Prisma 직접 접근 제거wvctesol

서버 사이드 구현 계획 — 자바 객체별 요구사항 (6/6)

객체모듈책임 · 지켜야 할 것
PlaceOrderUseCase
service
commerce-app
주문 생성.
  • 금액을 요청에서 받지 않는다. 상품 코드로 서버가 다시 읽는 것이 유일한 출처다.
  • 연락처는 숫자만 남긴다. 원본도 하이픈 없이 저장한다.
  • 비로그인 주문을 허용한다 — memberId 가 null 일 수 있다.
AdminOrderUseCase
service
commerce-app
입금확인 · 환불.
  • 모든 진입점에서 RequireAdmin.check 를 부른다. 화면 가드만으로는 부족하다.
  • 카드 환불은 PG 취소가 성공해야만 상태를 바꾼다. 실패하면 예외를 던져 트랜잭션을 되돌린다.
  • TID 가 없는 레거시 카드 주문은 막고 안내한다. 상태를 건드리지 않는다.
  • 이미 cancel 인 주문은 409 로 거부한다.
Entitlement
class
commerce-domain
상품 코드 → 수강권 플래그 매핑.
  • 원본에는 이 매핑이 없다 — 결제가 회원 플래그를 건드리지 않았고 관리자가 직접 켰다.
  • tesoltec 은 pay_yn 과 pay_tec_yn 을 모두 연다.
  • 컬럼 이름이 여기서만 나온다. 사용자 입력이 SQL 식별자가 되지 않는다.
OrderState
enum
commerce-domain
주문 상태.
  • 무통장도 입금 확인 전까지 READY 다. 원본은 즉시 success 였지만 확인 UI 가 없었기 때문이다.
  • 알 수 없는 값은 READY 로 읽는다 — 레거시 행에 빈 state 가 있다.
NicepayGateway
class
commerce-infrastructure
NICEPAY 취소 연동.
  • SignData = sha256(MID + CancelAmt + EdiDate + MerchantKey), 성공코드 2001.
  • 상점키는 환경변수로만 받는다. 없으면 available()=false 이고 카드 환불을 시도조차 하지 않는다.
  • 도메인은 이 클래스를 모른다 — PaymentGateway 포트로만 만난다.
OrderRepositoryAdapter
class
commerce-infrastructure
payment 테이블 조작.
  • 원본 insertPayment 처럼 cost 와 amount 에 같은 값을 넣는다.
  • setEntitlement 의 컬럼 이름은 Entitlement 매핑에서만 온다.

테스트 방법 (11)

가드레일종류확인 방법
order-amount-requires-admine2e비로그인·수강생 토큰으로 수정 → 401, 금액 그대로
order-amount-range-checkede2e0 · 음수 · 9억 → INVALID_AMOUNT
order-amount-not-on-cancellede2e환불 후 수정 → ALREADY_CANCELLED
order-amount-updatese2e수정 후 금액만 바뀌고 state·type 은 그대로
order-amount-editor-showne2e결제 목록에 입력칸과 수정 버튼이 보인다
admin-requires-admin-rolee2equiztester 토큰으로 관리자 API 호출 → 401/403
admin-confirm-opens-entitlemente2e무통장 주문 입금확인 후 해당 회원 수강권 플래그가 Y
admin-refund-revokes-entitlemente2e환불 후 수강권 플래그가 N
admin-refund-requires-pg-successe2ePG 취소가 실패하도록 만든 뒤 환불 → state 가 success 그대로
admin-refund-no-tid-blockede2etid 가 null 인 카드 주문 환불 → 안내 메시지, state 불변
admin-no-double-refunde2ecancel 주문에 환불 재요청 → 거부

정하지 못한 것 · 확인이 필요한 것

  • 관리자 콘솔은 별도 프로젝트(wvctesol-admin :3896)로 옮겼다. API 서버는 사용자 앱과 공유한다.