Files
Gnuboard7/plugins/_bundled/sirsoft-pay_nicepayments/docs/frontend.md
T
HeuJung 9cf9c3ff8c fix(core,board,ecommerce,payments,basic): KVE-2026 보안 게이트 6묶음 + 자격증명 전송로 정합
KISA 제보 취약점(KVE-2026-1914/1919/2019/2029/2041/2042/2043/2044)과
그 수정 과정에서 드러난 자격증명 전송로 결함을 함께 해소한다.

globalHeaders 는 데이터소스와 apiCall 핸들러에만 적용되는데, 코어 ApiClient 를
직접 부르는 경로들이 그 사실을 모른 채 게이트된 엔드포인트를 호출하고 있었다.
서버는 정당한 사용자를 거부하고 화면은 이미 버튼을 내준 뒤라, 예외도 로그도 없이
그 자리만 비는 형태로만 드러났다. 전송로 10축을 전수 열거해 6건을 고치고,
같은 실수가 반복되지 않도록 규정과 coverage 에 등재했다.

아웃바운드 프록시가 사이트 자기 자신으로 가는 내부 요청까지 가로채 저장이 수십 초씩
걸리던 문제도 함께 고쳤다. 실패가 폴백으로 삼켜져 화면에는 지연으로만 나타났다.
2026-09-06 00:42:29 +09:00

5.0 KiB

나이스페이먼츠 — 프론트엔드

레이아웃·액션 핸들러·전역 진입점·에셋 · 진입점: AGENTS.md

레이아웃

레이아웃 1개 (루트: resources/layouts).

그룹 개수
admin 1개
레이아웃 그룹 종류 extends
plugin_settings admin 화면 _admin_base

다른 PG 플러그인들과 마찬가지로 이 플러그인이 소유한 화면 레이아웃은 관리자 설정 화면 하나뿐입니다 — 체크아웃·주문상세·마이페이지의 결제 UI는 이 플러그인 소유가 아니라 §레이아웃 확장(다른 확장/템플릿 레이아웃에 주입되는 조각)으로 존재합니다.

액션 핸들러

핸들러 2개 (정의: resources/js/handlers/index.ts).

핸들러 레이아웃에서 부르는 이름
requestPayment sirsoft-pay_nicepayments.requestPayment
setPaymentMethod sirsoft-pay_nicepayments.setPaymentMethod

setPaymentMethod가 별도로 필요한 이유는 나이스페이먼츠 간편결제 버튼(네이버페이/카카오페이/ 삼성페이/애플페이/PAYCO/11pay/SSG페이/L.pay 8종)이 레이아웃 컴포넌트가 아니라 PG가 제공하는 DOM을 그대로 쓰기 때문입니다 — React 상태로 선택 하이라이트를 그리는 대신 DOM을 직접 조작해 선택된 버튼에 테두리를 입힙니다(updateEasyPayButtonStyles). requestPayment 하나로 PC/모바일 2가지 프로토콜(§docs/architecture.md "인증→승인 2단계")을 모두 처리합니다.

전역 진입점

항목 값
엔트리 파일 resources/js/index.ts
전역 객체 window.__SirsoftNicepayments
재등록 진입점 initPlugin()

로케일 전환 시 코어가 이 진입점을 호출해 핸들러를 다시 등록합니다. 진입점은 핸들러 재등록만 수행하고 1회성 부팅 작업을 포함하지 않습니다.

window.__SirsoftNicepayments로 노출되는 이유는 코어가 로케일 전환 시 이 이름으로 재등록 진입점을 찾기 때문입니다(§코어 AGENTS.md "재등록 진입점"). 나이스페이먼츠 결제창 스크립트 자체는 이 진입점이 미리 로드하지 않습니다 — requestPayment 핸들러가 결제 시도 시점에 동적으로 스크립트를 삽입한 뒤 goPay()를 호출합니다.

에셋

경로 구분
dist/js/plugin.iife.js 빌드 산출물 (커밋 대상)
editor-spec.json 레이아웃 편집기 스펙 (manifest)

로딩 설정: {"strategy":"global","priority":100,"dependencies":[]}

나이스페이먼츠가 제공하는 결제창 SDK는 이 목록에 없습니다 — requestPayment 핸들러가 결제 시도 시점에 동적으로 로드하는 제3자 자산이라, 이 플러그인이 빌드 시 번들링하는 dist/ 산출물과는 다른 층입니다. CSS 산출물이 없는 것은 결제창 자체는 PG 가 그리고, 이 플러그인은 간편결제 버튼 같은 최소한의 UI만 코어 컴포넌트로 구성하기 때문입니다.

비회원 주문의 자격 증명

영수증·결제수단 표시는 주문 정보를 서버에서 다시 조회해 만든다. 이 요청은 레이아웃의 globalHeaders 배선을 타지 않는 직접 호출(fetch)이므로, 자격 증명을 호출부가 직접 실어야 한다.

  • 회원: Authorization: Bearer …
  • 비회원: X-Guest-Order-Token: … (코어 storageHandlers 가 sessionStorage 에 저장, 전역 상태 폴백)

두 경로 모두 resources/js/guestOrderToken.ts 의 buildOrderRequestHeaders() 한 곳을 거친다. 비회원 분기를 비우면 서버는 그 주문을 찾을 수 없다고 응답하고, 화면에는 영수증 버튼이 아예 나타나지 않는다 — 예외도 콘솔 오류도 남지 않아 운영자가 원인을 알 수 없다. 서버(UserReceiptController)는 비회원을 이미 지원하므로, 이 배선이 빠지면 서버 기능이 도달 불가 상태로만 남는다.

주문 상세 화면의 경로 판정(ORDER_SHOW_RE)도 회원(/mypage/orders/{N})과 비회원(/shop/guest/orders/{N}) 두 주소를 함께 매칭해야 한다. 한쪽을 빼면 그 화면에서는 조회가 시작조차 되지 않는다.