2026-08-18 신설. 질문: "notes.the-moment.us 가 지금 글로벌(영어권) 고객을 받을 수 있는 상태인가."
답: 받을 수 없다. 막는 것은 셋인데, 그 중 결제 하나가 단독으로 원천 불가다.이 문서는 실측이다. 추측한 자리는 "미확인"이라고 적었다.
방침 정본과의 관계 — 이 문서는 아래를 뒤집지 않는다:
-PLAN_ETSY.md§0 — 해외 유통은 Etsy 먼저, Paddle 나중. 🚫 유입 전에 Paddle 되살리지 마라.
-PLAN_GEO.md§2 — 공통 FAQ 를 제품마다 복제하지 마라. 영문판도 같다(/en/guide한 곳).
-momentus/docs/PLAN_PAY_LAYER.md§5-B — 국내는 스마트스토어 유지. notes 를 pay 에 넣지 않는다.
(해외 채널은 그 결정의 대상이 아니다 — 국내/해외를 같은 계산대로 묶지 않는다는 뜻이지 해외를 막는 조항이 아니다.)
-PLAN_I18N_VARIANT.md§2 — 자동 번역 파이프라인·SKU 매트릭스 금지. 사전 한 벌 + 사람이 복제.
| 질문 | 답 |
|---|---|
| 영어권 손님이 지금 살 수 있나 | 못 산다. 해외 카드가 닿는 계산대가 0개다 (§1-2) |
| 영어로 읽히는 페이지가 있나 | 없다. UI·SEO 본문·법적 표기 전부 한국어 하드코딩, i18n 층 0 (§1-1, §1-3) |
| 영문 제품은 있나 | 1종이 draft 로 있다 — kor-jamo-en. 다만 카피가 한국어 + 작업 메모 상태 (§1-1) |
| 파일 전달(배관)은 되나 | 된다. 언어 무관. 문구만 한국어 (§1-4) |
| PDF 엔진은 영문을 만들 수 있나 | 거의 된다. en locale·US 공휴일 이미 있음. 주 시작이 mon 하드코딩인 것만 배선 누락 (§1-1) |
| 제일 먼저 풀 것 | 채널 결정(Etsy 1종) → 그 다음 /en 셸 → 그 다음 결제 (§3) |
| 상태 | 근거 | |
|---|---|---|
| 스토어 셸 언어 선언 | ❌ <html lang="ko"> 리터럴 고정 |
web/src/shop_ui.js:7 |
| UI 문자열 | ❌ 전부 한국어 리터럴. 사전·키·로케일 인자가 한 곳도 없다 | GNB shop_ui.js:531 · 가격 라벨 :603-609("무료"/"가격 준비 중") · 분류 라벨 :617 · 구매 시트 :1156-1173 · 구매내역 :1127-1150 |
| 로케일 감지 | ❌ 없음. navigator.language·Accept-Language 참조 0건 |
shop_ui.js·index.js·api.js 전수 grep |
| 서버 렌더 SEO 본문 | ❌ 한국어 하드코딩 (봇이 보는 전부가 한국어) | web/src/seo.js:81-119(목록·상세) · :239-270(llms.txt) |
| 제품 카드 | ⚠️ 우연히 영문 친화적 — 제목은 name_en, 부제가 copy.headline‖name_kr |
shop_ui.js:630-638 |
| 제품 상세 h1 | ⚠️ copy.headline ‖ name_kr → copy 만 영문화해도 영어가 된다(코드 수정 0) |
shop_ui.js:886-895 |
생성 상세페이지(copy._page) |
❌ 생성기가 <html lang="ko"> 를 박고, 입력 brief 도 한국어 템플릿 |
~/Projects/detailpage-kit/lib/build_page_m7.py:254 · pipeline/worker.py:4922-4941 |
| PDF 엔진(제품 자체) | ✅ 이미 다국어다. language en/ko/ja → locale, 월·요일 로컬라이즈, UI 라벨 사전 | pipeline/buildpdf.py:154(_LANG_LOCALE) · lexicon.py:709(ui()) · pipeline/concept_setup.py:257(카피 언어 규칙) |
| 지역 공휴일 | ✅ US_2026·JP_2026 데이터셋 존재, design.country 로 KR/US/JP/none 선택 |
calendar_data.py:30-42 · pipeline/buildpdf.py:250-254 |
| 주 시작 요일 | ❌ "mon" 하드코딩 2곳. 엔진은 sun 을 지원하는데 위저드 경로가 안 쓴다 |
하드코딩 pipeline/buildpdf.py:130, 256 / 엔진 지원 calendar_data.py:198-210 · roster.py:79-102 |
💡 PLAN_ETSY §2-1 이 "가장 큰 구조 변경"이라 한 주 시작 요일은, 실은 엔진에 이미 있고 배선만 빠졌다.
두 줄짜리 파라미터화 문제지 구조 변경이 아니다. 그 문서의 그 줄은 이 문서로 정정한다.
영문 제품 재고 실측 (GET /api/shop_preview, x-token, 2026-08-18):
전체 93종 — published 4 · draft 89
kor-jamo-en draft 9900 textbook
name_kr = "한글 자음·모음 쓰기" ← 한국어가 남아 있다
name_en = "Korean Alphabet Writing Practice"
copy.headline = "한글 자음·모음 쓰기" ← 상세 h1 이 한국어로 뜬다
copy.lead = "교재 · 데이터셋 kor_jamo (English locale — 한국어 학습자용)" ← 내부 작업 메모
copy._page = 없음 (생성 상세페이지 미제작)
copy._naver = 없음 (구매 경로 없음)
단, copy._detail.items[].plan 은 **이미 영어로 잘 쓰여 있다**
(예: "mieum — m", "① down ② across + down", "ㅁ = m / closed box")
⚠️ 함께 발견한 오염(별건이지만 같이 고쳐야 한다). 2026-08-17 에 복제본을 구우면서
한국어판 kor-jamo 의 copy.lead 가 "…(English locale — 한국어 학습자용)" 로 덮였고,
copy._detail.items[].page 가 영문판 위저드(wz_4247462d-ade) 자산을 가리키고 있다.
코드 수정은 들어갔지만(2081452 fix(wz): 복제가 slug 을 물려주지 않는다) 데이터는 아직 안 고쳤다.
⚠️ 그리고 이 lead 는 정확히 PLAN_GEO.md §5 G2 가 경고한 그 상태다 — 위저드 작업 메모가
구글 설명·llms.txt 에 그대로 나간다. 🚫 이대로 published 로 바꾸지 마라.
| 상태 | 근거 | |
|---|---|---|
| 가격 표시 | ❌ KRW 고정. "₩" + toLocaleString() |
shop_ui.js:597 · :953 · seo.js:19(ko-KR) |
| 구조화 데이터 | ❌ priceCurrency: "KRW" 고정 |
seo.js:192 |
| 실제 구매 버튼 | ❌ 네이버 스마트스토어 링크(유료 제품 전부). 버튼 라벨도 "네이버 스마트스토어" 하드코딩 | shop_ui.js:871-878 (buyAct) |
| 네이버가 해외 결제를 받나 | ❌ 국내 채널. 한국어 UI·국내 결제수단 전제 | 실측 URL: smartstore.naver.com/momentus_store/... (published 3종) |
| Paddle(해외 카드 가능) | ❌ 샌드박스 + 상품 미연결 → 절대 안 열린다 | curl https://pay.the-moment.us/api/checkout-config → {"env":"sandbox","token":"test_…","ready":true} · published 4종 전부 paddle_price_id = null |
| Paddle 코드 완성도 | ✅ 웹훅 서명검증·주문 멱등·엔타이틀먼트·서명 다운로드·메일 다 있다 | web/src/payments.js:24-137, 193-264 |
| Paddle 이 해외 카드를 지원하나 | ✅ 지원한다(MoR — 전세계 VAT 징수·납부 포함). 다만 켜져 있지 않다 | PLAN_PADDLE.md §0 |
| 폴백 동작 | ⚠️ price_id 가 없으면 checkout() 이 mailto: 주문으로 떨어진다 |
shop_ui.js:1234-1242 → order() :1244-1248 |
| 나이스페이 | ❌ 국내 전용. 통화 'KRW' 하드코딩, 안내문 "국내 신용카드" |
web/src/pay_app.js:259-260 · :129 · web/src/nicepay.js:26(api.nicepay.co.kr) |
| pay 층에 notes 가 있나 | ❌ 없다(의도된 것) — 카탈로그 SKU 2건 전부 cue | curl https://pay.the-moment.us/api/catalog · 방침 PLAN_PAY_LAYER.md §5-B |
정리: 해외 카드가 닿는 계산대가 0개다. 네이버=국내, 나이스페이=국내 KRW, Paddle=샌드박스+미연결.
영문 페이지를 아무리 잘 만들어도 결제 버튼을 누르면 한국어 스마트스토어이거나mailto:다.
| 상태 | 근거 | |
|---|---|---|
html lang |
❌ ko 고정 |
shop_ui.js:7 (실측 curl https://notes.the-moment.us/ → <html lang="ko">) |
| hreflang | ❌ 0건 | 실측: 홈 HTML 에 hreflang 문자열 0 |
og:locale |
❌ 없음 | 실측 grep 0건 |
/en 경로 |
❌ 404 (SPA 라우트 목록에 없다) | index.js:38-40 · 실측 /en·/en/ → 404 |
| sitemap | ❌ 단일 언어 URL 만. alternates 없음 | seo.js:217-229 |
| robots / llms.txt | ❌ 전부 한국어 안내문 | seo.js:239-299 |
| 서버 렌더 구조 | ✅ 있다. 봇이 보는 HTML 을 서버가 심는다 — 로케일 분기만 끼우면 그대로 재사용 | index.js:71-99 · seo.js 헤더 |
| AI 봇 허용 | ✅ GPTBot·ClaudeBot·PerplexityBot·OAI-SearchBot 명시 허용 | seo.js:285-293 |
✅ 좋은 소식은 뼈대가 이미 옳다는 것이다. SPA 인데도 봇에게 실제 본문을 서버에서 내주는
구조(2026-08-04 작업)라,/en은 "새로 짓는 일"이 아니라 기존 함수에 locale 인자를 넣는 일이다.
| 상태 | 근거 | |
|---|---|---|
| 무료 다운로드 | ✅ gallery/ 접두만 공개. 언어 무관 |
api.js:53-60(PUBLIC_PREFIX/PUBLIC_PDF/publicRead) · api.js: /img/ 핸들러 |
| 유료 전달 | ✅ stateless HMAC 서명 /d/<token>, 7일 만료 |
payments.js:36-49 |
| 다시 받기 | ✅ 이메일이 주인 키. POST /api/redownload 실측 200 |
api.js:212 · payments.js:230-251 |
| 파일명(비ASCII) | ✅ RFC 5987 filename* 병기 — 한글·영문 다 안전 |
api.js cdAttach() |
| 소유권 키 | ✅ email × product_slug — 국적 무관 |
payments.js 헤더 · PLAN_PAY_LAYER.md §5-4 |
| 전달 이메일 본문 | ❌ 한국어 하드코딩 ("구매 감사합니다 🎉", "플래너를 받으세요", "링크는 7일간 유효") | payments.js:75-93 · 제목 :250 |
| 구매내역 화면 | ❌ 한국어 | shop_ui.js:1127-1150 |
결론: 영어권 손님도 파일은 정확히 받는다. 다만 받는 메일이 한국어다. 이건 P1 이지 P0 가 아니다.
| 상태 | 근거 | |
|---|---|---|
| 표기 블록 | ❌ 한국 전자상거래법 표기 한 벌뿐, 영문 없음 | web/src/legal.js:13-16 |
| 약관·개인정보·환불 | ❌ 3종 전부 <html lang="ko"> |
실측 the-moment.us/legal/{terms,privacy,refund}/ → 200, 전부 lang="ko" |
| 고칠 수 있는 자리 | ⚠️ notes 가 아니다. 정본은 momentus/scripts/gen_site.py 의 BIZ, 반영은 sync_shell.py |
legal.js:1-11 · CLAUDE.md |
🚫
legal.js에 영문을 손으로 적지 마라. 다음 동기화에 덮어쓴다. 영문이 필요하면
momentus의BIZ에 EN 블록을 만들고sync_shell.py로 내려보낸다 —CLAUDE.md2026-08-08 조항.
| # | 막는 것 | 왜 원천 불가인가 | 최소 해법 |
|---|---|---|---|
| P0-1 | 해외 결제 경로 0 (§1-2) | 영어 상세를 아무리 잘 써도 버튼이 네이버/mailto: 다. 살 수가 없다 |
채널을 하나 고른다 — Etsy(자기 결제 보유) 또는 Paddle live 1종 |
| P0-2 | 영어로 파는 제품 0종 (§1-1) | kor-jamo-en 은 draft + 카피가 한국어 + 작업 메모. published 로 올리면 GEO 사고 |
1종만 영문 카피로 정리 |
| P0-3 | 영어 유입 표면 0 (§1-3) | /en 404, hreflang 0. 영어 검색어에 잡힐 페이지가 없다 |
Etsy 리스팅이 유입을 대신한다(§3-①) 또는 /en 셸 |
P0-1 과 P0-3 은 같은 답으로 동시에 풀 수 있다 — 그게
PLAN_ETSY.md의 논지다:
"Paddle 은 팔 곳이 아니라 결제 수단이다. 유입을 만들지 않는다."
Etsy 는 계산대와 유입을 같이 준다. 그래서 ①단계가 Etsy 인 것이다.
/en 로케일 셸 + hreflang (자사몰로 팔 때 필수. Etsy 만이면 미룰 수 있다)PLAN_PADDLE.md §6 정책 3종 링크)payments.js:75-93)₩ 는 우리가 고쳐야 한다)buildpdf.py:130, 256 두 줄)design.country = "US" 또는 "none" (한국 공휴일 제거) — 이미 지원됨Aug 4, 2026 vs 04/08/2026) — 미확인, 엔진 조사 필요PLAN_ETSY.md §4 — 1종으로 수요를 먼저 확인한다.PLAN_I18N_VARIANT.md §2 — 사전 한 벌 + 사람이 쓴다.PLAN_ETSY.md §0 — 아무도 안 오는 계산대가 하나 늘 뿐이다.목표는 "판다"가 아니라 "영어로 존재하게 한다". 코드는 한 줄도 안 고친다.
| 순 | 할 일 | 어디 | 코드 수정 |
|---|---|---|---|
| 1 | kor-jamo 오염 복구 — copy.lead 원복 + _detail.items[].page 를 자기 위저드(wz_0fc4991f-fd5)로 되돌린다 |
어드민/D1 | 0 |
| 2 | kor-jamo-en 카피 영문화 — headline="Korean Alphabet Writing Practice", lead= 영문 사실 문장, sections 영문 |
어드민/D1 | 0 |
| 3 | _detail 의 영문 plan(이미 영어다)을 살려 상세 자산/_page 생성 |
do_detail_page |
0 |
| 4 | 채널 결정 — Etsy 리스팅 1건 (Payoneer → 샵 개설 → 리스팅) | Etsy | 0 |
왜
copy만 고치면 되나 — 카드 제목은name_en(shop_ui.js:630-638), 상세 h1 은
copy.headline ‖ name_kr(:886-895). 즉copy.headline을 영어로 넣는 순간 화면이 영어가 된다.
우연이지만 사실이고, 실측으로 확인했다. 이게 "1일 경로"가 성립하는 이유다.⚠️
_page생성기는<html lang="ko">를 박는다(detailpage-kit/lib/build_page_m7.py:254).
본문 텍스트는 영어로 나오더라도 선언은 ko 다 — ①단계에서는 감수하고 넘어간다(스토어 노출을 안 하므로).
사이트 노출 여부 — 두 갈래. 추천은 A.
PLAN_ETSY.md §3 경고)이 없고, ②단계 /en 셸이 생긴 뒤에 정식으로 건다.CLAUDE.md · pipeline/sale_files.py)작업량: 반나절(카피·자산) + Etsy 계정 작업(별건, 승인 대기 있음).
되돌리기 비용: 거의 0. 코드 변경 0 · status 를 draft 로 되돌리면 끝.
B 를 골랐고 색인이 된 뒤라면 URL 1개가 검색에 남는다(410 로 정리 가능).
/en 로케일 셸 · 영문 법적 표기 · hreflang자사몰에서 팔 결심이 섰을 때만 착수한다. Etsy 만으로 간다면 이 단계는 통째로 미뤄도 된다.
| # | 할 일 | 파일 | 규모 |
|---|---|---|---|
| E1 | 문자열 사전 1벌 STR = {ko:{…}, en:{…}} 도입 + 화면 문자열을 t(key) 로 스윕 |
shop_ui.js (리터럴 수백 개) |
가장 크다 — 1.5~2일 |
| E2 | 셸 언어 파라미터화 — <html lang> · <title> · og:* 를 로케일로 |
shop_ui.js:7-24 · index.js:62-107 |
0.5일 |
| E3 | 라우터에 /en* 추가 + 로케일 판정(경로만. 자동 리다이렉트 금지) |
index.js:38-40 |
0.5일 |
| E4 | seoBody/seoMeta/seoJsonLd/llmsTxt 에 locale 인자 |
seo.js 전역 |
1일 |
| E5 | sitemap 에 /en/* + <xhtml:link rel="alternate" hreflang>(ko/en/x-default) |
seo.js:217-229 |
0.5일 |
| E6 | 제품 로케일 필터 — products 에 locale 컬럼 추가(비파괴 마이그레이션 1개) |
web/migration_locale.sql(신규) · api.js shopData |
0.5일 |
| E7 | 영문 법적 표기 — momentus/scripts/gen_site.py BIZ 에 EN 블록 → sync_shell.py |
⚠️ momentus 저장소 | 0.5일 |
| E8 | 영문 전달 이메일(주문 시 locale 저장 → 메일 분기) | payments.js:75-93, 230-251 |
0.5일 |
| E9 | /en/guide 한 곳에만 영문 공통 FAQ + FAQPage 스키마 |
shop_ui.js·seo.js |
0.5일 |
🚫 E9 를 제품마다 복제하지 마라 —
PLAN_GEO.md§2. 영문판도 91종이 서로를 죽인다.
⚠️ E7 을web/src/legal.js에서 하지 마라 — 생성물이다(legal.js:1-11).
작업량: 코드 5~7일 + 영문 카피 작성(사람). 총 1~2주.
되돌리기 비용: 중간. 코드는 커밋 되돌리기로 끝나지만 색인된 /en/* URL 은 남는다.
되돌리려면 410 또는 ko 로 301 이 필요하다 → 착수 전에 URL 모양(/en/p/<slug>)을 확정하고 시작할 것.
E6 마이그레이션은 컬럼 추가라 비파괴(되돌리기 불필요).
착수 조건: ①에서 Etsy 판매가 실제로 났을 때. 안 났으면 여기 오지 마라 — 영문판 제작 자체가 헛일이고,
그 판단은 1종으로 충분히 난다(PLAN_ETSY.md §4).
| # | 할 일 | 근거/자리 | 비고 |
|---|---|---|---|
| M1 | Paddle live 전환 — 상품/가격 재생성, live 토큰·시크릿 교체, products.paddle_price_id 채우기 |
PLAN_PADDLE.md §6-7 (P5/P6) · payments.js 코드는 이미 완성 |
계정 작업 포함 |
| M2 | Payoneer 정산 연결 | PLAN_PADDLE.md §0 · PLAN_ETSY.md §1 |
Etsy 와 같은 계정을 쓴다 |
| M3 | 통화 표시 분기 — money() 로케일화 + JSON-LD priceCurrency |
shop_ui.js:597, 953 · seo.js:192 |
표시만. 실제 환전은 Paddle |
| M4 | 주 시작 일요일 배선 — week_start 를 위저드 축으로 |
pipeline/buildpdf.py:130, 256 (엔진은 calendar_data.py:198-210 에 이미 있다) |
두 줄 문제. 구조 변경 아님 |
| M5 | 지역 공휴일 — design.country = "US" / "none" |
pipeline/buildpdf.py:250-254 · calendar_data.py:30-42 |
이미 지원. 선택만 노출 |
| M6 | 날짜 형식 조사·분기 (Aug 4, 2026 vs 04/08/2026) |
미확인 — 엔진 조사 선행 | |
| M7 | 상세페이지 생성기 영문화 — brief 템플릿 + <html lang> |
pipeline/worker.py:4922-4941 · detailpage-kit/lib/build_page_m7.py:254 |
킷은 별 저장소 |
| M8 | 영문 유입 — 영문 llms.txt·insights 글·Pinterest·Etsy 태그 |
seo.js:239-270 · PLAN_GEO.md §1 |
작업량: 코드 2~3주 + 계정·심사 대기 + 카피. 총 1~2개월.
되돌리기 비용: 비싸다. M1(Paddle live)은 실주문이 한 건이라도 나면 사실상 못 되돌린다
(환불·세금 신고·엔타이틀먼트가 걸린다). 그래서 1종부터 켠다.
M4~M6 은 새 PDF 를 굽는 일이라 되돌리기는 싸지만 — 🚫 이미 판 제품의 산출물 키를 재사용하지 마라
(CLAUDE.md · pipeline/sale_files.py 가 KeyReuse 로 죽인다. 덮어쓰기 옵션은 일부러 없다).
같은 것을 다시 재기 전에 여기부터 본다.
curl https://notes.the-moment.us/ → <html lang="ko"> · hreflang 0건 · og:locale 없음
curl https://notes.the-moment.us/en → 404
curl https://notes.the-moment.us/api/shop → products 4 (published) · paddle_price_id 0건
유료 3종 전부 copy._naver = 스마트스토어 URL
curl -H x-token …/api/shop_preview → products 93 (draft 89 · published 4)
영문 제품 = kor-jamo-en 1종(draft, _page 없음)
curl https://pay.the-moment.us/api/checkout-config → {"env":"sandbox","token":"test_…","ready":true}
curl https://notes.the-moment.us/api/checkout-config → {"env":"sandbox","token":"","ready":false}
curl https://pay.the-moment.us/health → {"ok":true,"nicepay":true,"skus":2,…} ← skus 2건 전부 cue
curl https://pay.the-moment.us/api/catalog → cue-pass-1m · cue-pass-3m (notes 없음 = 의도된 것)
curl the-moment.us/legal/{terms,privacy,refund}/ → 200, 전부 <html lang="ko">
POST /api/redownload → 200 {"ok":true} (배관 정상)
미확인(추측하지 않고 남긴다)
- Etsy 셀러 계정·Payoneer 개설 여부 — 계정 작업이라 코드로 확인 불가 (PLAN_ETSY.md §2-3 체크리스트 미체크)
- 나이스페이 NICEPAY_API_URL 이 운영인지 샌드박스인지 — 시크릿이라 값을 못 본다
(기본값은 sandbox-api.nicepay.co.kr, nicepay.js:26. 해외와는 무관해서 파고들지 않았다)
- 날짜 형식(M6)이 엔진 어디에서 결정되는지 — build.py 미조사
- 한글 전용 폰트로 영문 조판했을 때의 품질 — 실물 확인 필요