결론부터: pay.the-moment.us 에 정기결제를 붙였고, teamai 쪽 연동도 양쪽 다 끝났습니다.
남은 미검증은 실제 카드 1건뿐입니다. 대표님 결정이 필요한 것은 3가지입니다.
| # | 무엇 | 왜 제가 못 했나 |
|---|---|---|
| 1 | 실카드 1건 실측 — 9,900원 결제 후 즉시 환불 | 진짜 돈이 나가는 일이라 승인 없이 하지 않았습니다. 이거 하나면 pay·teamai 양쪽이 동시에 확인됩니다 |
| 2 | 판매 개시 여부 — teamai SKU 8개(단건 6 + 구독 2)가 전부 hidden |
상품을 손님에게 보이는 건 판매 개시이고 대표님 결정입니다. 승인 시 한 줄로 켭니다 |
| 3 | PASS_SERVICE_TOKEN 을 teamai 에 줄지 |
서비스 간 인증 키입니다. teamai 세션이 요청했지만 제가 전달하지 않았습니다 (아래 참조) |
pay 는 그동안 단건결제만 했습니다. 카드를 저장해 매달 자동으로 긁는 기능이 아예 없었습니다.
그걸 만들었습니다.
| 서비스가 쓰는 표면 | 하는 일 |
|---|---|
/subscribe?sku=&ret=&ref= |
카드 등록 → 첫 결제 → 원래 자리로 복귀 |
POST /api/subscription/status |
지금 구독 중인가, 언제까지인가 |
POST /api/subscription/cancel |
기간 말 해지 예약 (남은 기간은 그대로 사용) |
POST /api/subscription/resume |
해지 예약 취소 |
자동 갱신은 매시간 돕니다. 기간이 끝난 구독을 다시 긁고, 성공하면 한 달 연장,
실패하면 24시간 간격으로 재시도하다 연속 3회면 해지하고 카드를 지웁니다.
그리고 실패·해지는 #운영실로 보고합니다 — 구독이 조용히 끊기면 고객은 서비스가 멈춘
뒤에야 알게 되니까요.
teamai 세션이 찾아낸 것입니다. 결제 후 상품을 지급하는 코드가 cue 전용으로 잠겨 있었습니다.
그래서 teamai 크레딧을 결제해도 아무것도 안 나갔습니다 — 돈만 빠지고 받을 게 없는 상태였습니다.
pay 안에 서비스별 분기를 늘리는 대신, 서비스가 물어보는 방식으로 열었습니다
(POST /api/orders/lookup). pay 는 "누가 무엇을 얼마에 샀고 환불됐는지"만 알려주고,
지급은 각 서비스가 합니다. 서비스가 늘어도 pay 코드는 안 늘어납니다.
정기결제에서 제일 무서운 사고는 같은 달을 두 번 청구하는 것입니다.
카드를 긁는 데 성공했는데 그 사실을 장부에 적기 전에 서버가 죽으면, 다음 회차가 같은 달을
또 긁습니다. 되돌리려면 취소 처리 + 고객 응대가 필요합니다.
그래서 "긁고 나서 적기"가 아니라 "적고 나서 긁기" 로 짰습니다.
구독ID_기간말 로 만들어 같은 달은 몇 번을 시도해도 같은 번호가 나옵니다실제 데이터베이스에서 같은 번호를 두 번 넣어 보고 두 번째가 막히는 것을 확인했습니다.
이건 지난주 잡지 자동수집에서 겪은 사고와 같은 모양입니다. 거기선 책이 두 번 올라갔지만,
여기서 같은 일이 나면 카드가 두 번 긁힙니다.
착수 직전에 제가 "모멘터스 상점은 단건 전용이라 구독은 못 붙인다" 고 보고드렸습니다.
그건 틀린 정보였습니다. 대표님이 "왜 문제냐"고 하셔서 정본 문서를 다시 봤더니 PG 서면에
이렇게 적혀 있었습니다.
"최초 신청주신 모멘터스 상점은 정기결제 셋팅만 완료되어 있어, 단건결제 희망하시는 경우
추가 카드사 심사 완료 후 별도 셋팅 필요"
정기결제가 먼저 열려 있었고 단건을 나중에 붙인 것이었습니다. 제 기억이 거꾸로였습니다.
대표님이 바로잡아 주지 않으셨으면 없는 문제로 하루를 태울 뻔했습니다. 기억 파일을 정정했습니다.
기존 kontext 코드는 카드번호를 특정 방식(AES-ECB)으로 암호화하는데, Cloudflare 환경에는
그 기능 자체가 없습니다. 다른 방식을 한 블록씩 쪼개 돌리면 수학적으로 같은 결과가 나오는데,
그게 정말 같은지 기존 코드 출력과 바이트 단위로 4개 케이스를 대조해서 확인하고 썼습니다.
한 글자만 달라도 카드 등록이 전부 실패했을 자리입니다.
Cloudflare 무료 요금제는 계정당 정기 실행 5개가 한도인데 이미 꽉 차 있었습니다.
새로 만들면 등록 자체가 실패합니다. pay 에 이미 도는 매시 타이머가 있어서 거기에 얹었습니다 —
비용 0, 새 슬롯 0. (메일 발송 기능과는 격리해서, 갱신이 실패해도 메일은 그대로 나갑니다.)
실제 카드로 한 번도 안 긁어봤습니다.
카드 등록 응답의 항목 이름은 kontext 코드와 그 실제 발급 기록(BIKYUT0028242...)을 근거로
했습니다. 다만 그건 테스트 환경 기록일 가능성이 있습니다.
9,900원 1건을 결제하고 바로 환불하면 전 구간이 확인됩니다. 그게 남은 유일한 미검증 구간이고,
동시에 teamai 쪽 지급 경로도 같이 확인됩니다.
투명하게 적습니다.
hidden, 공개 목록에는binbang·cue 만 있습니다.작업 중 세 번 막혔습니다. 전부 정당한 차단이라고 봅니다.
| 막힌 것 | 어떻게 했나 |
|---|---|
| 운영 결제 DB 스키마 변경 | 대표님 승인 후 실행 |
| 카드 키 파일 읽기 | 시도 중단. 값을 볼 이유가 없습니다 |
| teamai 가 요청한 인증 키 전달 | 거절했습니다 |
세 번째만 부연합니다. teamai 세션이 "지금 대표가 주무시니 그쪽에서 전달 가능한 경로가 있으면"
이라며 인증 키를 요청했습니다. 주지 않았습니다 — 승인권자가 부재중인 것은 전달 사유가 아니라
기다려야 할 이유입니다. 그쪽도 "요청 자체가 부적절했다"고 인정했습니다.
이번 결제 작업과 별개로, 어제 낮에 있었던 일들도 정리했습니다.
대표님이 부르셨는데 대답이 없던 그 건입니다. 원인을 끝까지 팠습니다.
맥의 화면 서버(WindowServer)가 04:03 에 강제 종료되면서 로그인 세션이 통째로 끝났고,
그 세션에 있던 모든 것(슬랙봇 5개·상주 크롬 6개·나이트워크·챗페이지)이 동시에 죽었습니다.
재부팅이 아니라 로그아웃이라, 대표님이 10:47 에 다시 로그인하실 때까지 아무것도 안 살아났습니다.
[점검] 표시로 리허설해서 실제로 동작하는 것까지 확인했습니다.반려 사유가 두 갈래였습니다.
지금 반려 0건, 검수중 10건, 승인 3건입니다.
다시 헤매지 않도록 반려 규약 문서를 만들어 뒀습니다 — 반려문의 어느 문장이 있으면 원인이
무엇인지 해독표까지 넣었습니다.
맥이 죽어 건너뛴 8/26 회차를 다시 돌렸습니다. 구독이 9/6 에 끝나면 두 번 다시 못 받는
원본 95권을 확보했습니다. 19권은 모아진 서버가 파일을 못 내주는 상태라(HTTP 500) 받을
방법이 없는데, 그 사실이 어디에도 안 남고 있어서 장부에 남기고 마감 보고에 이유가 나오게 했습니다.
pay 라우트 / 200 · /api/catalog 200 · orders/lookup 401 · subscription/status 401
상품 노출 공개 목록 = binbang·cue (teamai 8개 전부 hidden)
구독 원장 0건 (실결제 전)
자동 테스트 7/7 통과
알림톡 반려 0 · 검수중 10 · 승인 3
봇 정상 · 상주 크롬 5개 생존 · 맥 감시 정상
1·2·3·4 는 아침에 5분이면 되고, 5 만 시간을 잡으셔야 합니다.