← 목록
기타 2026-06-27 5KB 읽기 5분

공유 커머스 엔진 + 크라우니 마켓(shop) + PayGate

개요

take·subscribe가 같은 백엔드 엔진을 공유하도록 크라우니커머스엔진을 추출하고, 그 엔진 위에 shop.crowny.org(쿠팡식 입점 멀티테넌트 쇼핑몰)와 paygate.crowny.org(나이스/토스 같은 PG사)를 신규 구축. 엔진을 고도화하면 4개 서비스가 동반 고도화된다.

1) 공유 커머스 엔진 — /Users/ef/crowny-commerce-engine/엔진.js (v1.0.0)

순수 Node stdlib. 공통 primitive 단일 원본:
  • id(sha256·scrypt hashPw·safeEq·token·genId), valid(userId·owner·id·slug), store(atomicWrite·readJSON·jsonl·listJSON)
  • http(sendJSON·sendFile·readBody·staticHandler SPA폴백)
  • createUsers(dir,{emailUnique}) — scrypt 인증 + owner/email 인덱스(signup/login/byOwner/ownerOfId/validOwner)
  • createAdmin(file,{envId,envPw,defId,defPw}) — id+pw → 부팅 세션토큰
  • createServiceKey(file,env) — 서버간 키
  • require 방식: require('/Users/ef/crowny-commerce-engine/엔진.js'). 이관 = 함수명 유지·엔진 위임(동작 동일).
이관 완료(전부 E2E 검증): subscribe(7/7) · take(10/10, 기존 데이터 보존) · shop·paygate(신규). → 4서비스 공유 엔진 v1.0.0.

2) shop.crowny.org — 크라우니 마켓 (:9955)

  • 쿠팡식 직관 SPA(브라우즈 공개, 결제 시 로그인). 홈·스토어·상품상세·장바구니(localStorage)·체크아웃·내주문.
  • 입점 멀티테넌트: 판매자별 스토어 /@<slug>(경로 라우팅, 공유 가능). 입점 신청→상품 CRUD(이미지9). /seller 대시보드.
  • 기본 스토어 /@crowny 5상품: 에스케이 선크림 76,500 · 아르띠스떼 에너지크림 76,500 · 동그람씨 키링 7,650 · 동그람씨 엽서 2,550 · 멜로우 마스크팩 25,500.
  • 체크아웃 → PayGate 결제 생성 → 결제창 → 웹훅(HMAC 검증) → 주문 결제완료. shop = PayGate 가맹점(자동 부트스트랩 data/paygate.json).
  • URL 분리: 서버간=localhost, 브라우저(payUrl/returnUrl)=공개 https. /admin 주문·입점.

3) paygate.crowny.org — 크라우니 PayGate (:9954)

  • PG사 역할: 가맹점 계약(signup→apiKey) → 결제 생성(POST /api/payments, X-Merchant-Key) → 결제페이지 /pay/<id> 승인(내부PG) → 가맹점 webhookUrl HMAC(apiKey) 통지 → 정산(매출−수수료 3%).
  • 사업자 핫라인 결제: 대시보드에서 금액·주문명 입력 → 결제링크 발급 → 고객에게 전송. /merchant.
  • 환불/취소, 정산 요약, /admin 가맹점·결제. 한선씨 결제판정.한선(상태전이·승인·수수료 4상, 9/9).

한선씨 SSOT

  • 결제판정.한선(PG 상태기계·수수료), 기존 구독판정/이용권판정/주문검증 유지.

검증

  • 전체 결제 E2E 10/10(공개): 입점→상품→장바구니→체크아웃→PG결제(수수료3%)→승인→웹훅→주문 결제완료.
  • 4서비스 공개 https 200, 전용 cert+stunnel 직결.

인프라

  • LaunchAgent: org.crowny.shop(9955)·org.crowny.paygate(9954). 전용 cert(만료 2026-09-25)+stunnel SNI 직결(s-shop/s-paygate). gateway.yaml 등록.
  • 포트: 9953은 kps메신저 점유 → shop=9955로 재배치.

잔여 / 운영

  • 관리자 기본: shop admin/shop1004 · paygate admin/paygate1004 — 변경 권장.
  • PayGate 울트라 적대감사 진행(결제/정산/웹훅/SSRF) → 결과 반영 예정.
  • 향후: 가맹점별 정산 출금, 실 카드 acquirer 연동(현재 내부 승인), 엔진 npm 패키지화.

PayGate 울트라 적대감사 (Workflow 25에이전트) — 21건 확인·수정완료

4렌즈(상태·권한·웹훅·멱등) → 21건 발견·전부 확인 → critical/high 수정:
  • [CRIT] 승인/취소 무인증(무료결제 위조·DoS) → capability 토큰: 결제 생성 시 token 발급, payUrl=/pay/<id>?t=<token>, 조회·승인·취소 모두 token(또는 가맹점/관리자) 검증.
  • [HIGH] webhookUrl/returnUrl SSRF·오픈리다이렉트 → 엔진 valid.publicUrl(loopback·사설·링크로컬·非http 거부). shop webhookUrl을 공개 URL로 변경(localhost 차단되므로).
  • [HIGH] Infinity/음수/초과 금액Number.isFinite + 0<amount<=1e8.
  • [HIGH] returnUrl XSS → pay.html esc에 단일따옴표 추가 + onclick 제거(addEventListener) + safeUrl scheme 검사 후 location.href.
  • [HIGH] 결제조회 PII 열거 → payViewPublic(buyerName 등 제외) + token 게이트.
  • [HIGH] 핫라인 무제한 DoS → 대기결제 100건 상한. [MED] readBody 전 인증 → create 결제 키검사 앞으로.
  • 보안 수정 E2E 11/11(무토큰 승인·조회·취소 403, SSRF·Infinity 400) + 최종 공개 결제 플로우 4/4.
  • 잔여(저위험): 웹훅 nonce 재전송·HMAC키=apiKey 단일·정산 status혼재 — 운영 메모.