Polar
OAuth로 Polar.sh 판매자 계정을 연동해 매출/구독/주문 메트릭을 한 곳에서 추적합니다. 다중 organization server-side 합산.
Last updated: 2026-05-18
Polar 연동은 OAuth 2.0 + PKCE (S256) + client_secret_post 방식으로 read-only 토큰만 받습니다. 토큰은 AES-256-GCM 암호화되어 저장되며, refresh token은 single-use rotating입니다.
사전 준비
- Polar 계정 + 1개 이상의 organization (없어도 연동은 가능, 데이터는 0건)
- OAuth 권한 승인 가능 (organization owner / member)
- Starter / Plus / Max 플랜 (수익 알림은 유료 기능)
OAuth 연결
계정 설정 열기
/dashboard/account 또는 /dashboard/integrations의 Polar 카드에서 Connect 클릭.
Polar 인증
데스크탑은 팝업, 모바일은 페이지 이동으로 polar.sh 로그인 화면이 열립니다. 로그인 후 read-only 권한에 동의하세요.
Organization 자동 발견
Opseer가 계정 내 active organization 목록을 가져와 metadata에 저장합니다. 신규 가입자라 organization이 없으면 빈 상태로 연동됩니다.
완료
팝업이 닫히거나 확인 페이지가 표시됩니다. 계정/연동 페이지에 연결된 organization 목록이 표시됩니다.
Polar는 계정 단위 연동입니다. 한 번 연결하면 Opseer 모든 프로젝트에서 동일하게 사용됩니다. organization이 0개여도 연동은 정상 — polar.sh에서 organization 만들면 다음 Refresh에서 자동 인식.
요청 권한 (Scopes)
9개 모두 read-only — Opseer는 Polar 데이터를 변경하지 않습니다.
- openid, email — 계정 식별
- metrics:read — daily 메트릭 시계열
- subscriptions:read, organizations:read — 구독/조직 정보
- orders:read, refunds:read — 주문/환불
- products:read, customers:read — 상품/고객
표시되는 데이터
/dashboard/revenue/polar에서 단일 metrics API 호출로 daily 시계열 + multi-organization server-side 합산을 받아 표시합니다.
핵심 메트릭 (Today/Yesterday + Period summary)
- MRR (Monthly Recurring Revenue) — 활성 구독의 월간 정기 매출 합
- Revenue / Net Revenue — 매출 / 환불 차감 후
- Active Subscriptions — 시점 활성 구독 수
- New Subscriptions / Churned Subscriptions — 기간 신규/만료 구독
- Trial MRR — 트라이얼 중 구독의 MRR
- Average Revenue Per User (ARPU)
Polar 고유 메트릭 (상단 / 하단 카드)
- Cumulative Revenue — 시작부터 누적 매출 (시점값)
- Checkout Conversion — 결제 페이지 전환율
- Orders — 신규 + 갱신 + 일회성 통합 결제 건수
- Renewed Subscriptions — 갱신 구독 카운트
- Canceled Subscriptions — 취소 의사 (만료 전)
- One-time Products / Revenue — 일회성 상품 매출
다중 organization 처리
Polar 계정에 여러 organization이 있으면 모든 active organization의 메트릭을 server-side로 합산해 표시합니다 (단일 API 호출).
- 연결 시 metadata.organizations[]에 자동 저장
- Refresh 시 새 organization 자동 발견 + 갱신
- status="active"만 쿼리 대상 (created/review/blocked 등 제외)
- Per-organization 상세표는 multi-org일 때만 노출
통화가 다른 organization이 섞여있으면 (예: USD + EUR) 합산값에 통화 변환 없이 표시됩니다. 상단에 amber 경고 배너 노출.
캐시 정책
- 90일 sliding window — Refresh 버튼 클릭 시에만 fetch
- Period 전환은 cache JSON 합산 (round-trip 0)
- today/yesterday는 realtime (Polar는 D-1 lag 없음)
- Custom range는 cache 윈도우 밖 임의 기간을 단발 API로 조회 (cache write X). 시작일 자유, 폭 max 90일
Sandbox vs production
Opseer는 production만 지원합니다. sandbox는 별도 OAuth client 발급이 필요하며 base URL도 다릅니다 (sandbox-api.polar.sh).
토큰 rotation 정책
- access_token: 10일 만료
- refresh_token: single-use rotating — refresh마다 새 token 발급, 이전 즉시 폐기
- Opseer는 동시 refresh race를 Pattern A+B (re-read winner)로 처리
- 명시적 revoke 또는 refresh token 분실 시에만 재인증 필요
연동 해제
Polar 카드(계정/연동 페이지)의 "Disconnect" 클릭. 암호화된 토큰이 제거되고 연동이 inactive로 표시됩니다. polar.sh 측에서도 완전히 폐기하려면 polar.sh/settings의 Connected Apps에서 Opseer를 revoke하세요.
보안
- OAuth 2.0 + PKCE (S256) — code_verifier는 Opseer 서버 외부로 나가지 않음
- Confidential client + client_secret_post — client_secret은 server-side 전용
- AES-256-GCM 토큰 암호화 저장 (opseer_user_integration.config)
- sub_type=user — user-level token으로 모든 organization 접근
- write scope 요청 X — Opseer는 Polar 데이터를 변경할 수 없음
문제 해결
"organization 없음" 안내
연동은 됐지만 polar.sh에 organization이 없는 상태. polar.sh/dashboard에서 organization을 먼저 만들고 Refresh 또는 disconnect/reconnect하세요.
"OAuth failed" 또는 invalid_grant
Refresh token race 또는 명시적 revoke. 연동 해제 후 재연결하면 새 토큰 발급됩니다.
Multi-currency 경고 배너
여러 organization이 다른 통화를 쓰는 경우 합산값이 통화 변환 없이 표시됩니다. 정확한 분리는 organization별 상세표에서 확인.