SubSovereign on Roku — 통합 가이드
이 가이드는 여러분의 Roku 채널을 *"누가 결제했는지 전혀 모르는 상태"*에서 *"올바른 사용자에게 올바른 기능을 열어주고, 내 서버에서 직접 검증하는 상태"*로 바꿔드립니다. SDK는 BrightScript 파일 하나로 구성되며, 구독 도구 사용 경험이 없어도 바로 시작할 수 있습니다.
SubSovereign이 해주는 것
사용자는 Roku Pay(Roku Channel Store)를 통해 구독합니다. SubSovereign은 채널이 필요로 하는 단 하나의 질문에 안정적으로 답합니다: 이 사용자가 실제로 무엇을 결제했는가?
- 채널은 SubSovereign에 사용자의 이용 권한 — 잠금 해제된 접근 권한 — 을 요청합니다.
- 서버 측 영수증 검증이 서버에서 Roku와 직접 이루어지므로, 변조된 클라이언트가 구독을 위조할 수 없습니다.
- 자체 호스팅 방식입니다: 여러분의 인프라에서 실행되고, 사용자 데이터는 여러분이 보관하며, 수익 배분이 없습니다 — 사용자가 지불한 금액의 100%가 여러분의 것입니다.
기기를 신뢰하지 마십시오. 기기는 요청하고, 서버가 결정합니다.
시작하기 전에
다음이 필요합니다: 실행 중인 SubSovereign 서버, 대시보드에 등록된 앱(**appId**와 API 키 발급), 그리고 Roku Pay 상품과 연결된 접근 레벨(티어, 예: pro). Roku Developer Dashboard에서 상품을 설정하고, 구매는 평소처럼 roChannelStore로 처리하면 됩니다 — SubSovereign은 그 이후에 검증하고 기록합니다.
1단계 — SDK 추가
SubSovereign.brs를 채널의 source/ 폴더에 넣으면 됩니다. 끝입니다 — 패키지 관리자가 필요 없습니다. HTTP 호출에는 Roku 인증서 번들이 이미 연결된 roUrlTransfer를 사용합니다.
2단계 — 채널 시작 시 한 번만 설정
채널 초기화 시점(예: Main)에서 SubSovereign_Configure를 호출하여 API 키, 앱 ID, 안정적인 사용자 식별자, 서버 URL을 전달합니다:
SubSovereign_Configure("YOUR_APP_API_KEY", "your-app-id", userId, "https://subs.yourdomain.com/api/v1")
동일한 사용자에게는 항상 같은 userId를 사용하세요. 그래야 기기가 바뀌어도 접근 권한이 유지됩니다. (설정은 m에 저장되므로, 이후 호출할 스레드와 동일한 스레드에서 설정하세요 — 6단계 참고.)
3단계 — 사용자 접근 권한 확인
SubSovereign_CheckEntitlements()는 객체를 반환합니다. hasAccess로 빠르게 예/아니오를 확인하세요:
result = SubSovereign_CheckEntitlements()
if result.hasAccess = true
unlockProFeatures()
else
showFreeExperience() ' free tier, or send them to the Channel Store
end if
요청이 실패하면 객체는 hasAccess = false와 error 필드를 반환합니다 — 네트워크 오류가 발생해도 실수로 잠금이 해제되지 않고, 항상 잠긴 상태(폐쇄 실패)로 처리됩니다.
4단계 — 구독 판매
평소처럼 Roku Pay(roChannelStore)로 구매를 진행합니다. Roku가 성공적인 거래를 반환하면, 서버가 Roku와 직접 검증할 수 있도록 transactionId(상품 ID 및 부여할 접근 레벨 포함)를 SubSovereign에 전달합니다:
result = SubSovereign_ValidateRokuPurchase(transactionId, productId, "pro")
if result.granted = true
entitlements = SubSovereign_CheckEntitlements() ' re-check, then unlock
unlockProFeatures()
end if
구매는 서버가 Roku와 확인을 마쳐야만 유효합니다.
5단계 — 기능 플래그와 동의
채널 업데이트 없이 서버에서 기능을 점진적으로 배포합니다:
flags = SubSovereign_GetFeatureFlags()
if flags.newPlayer = true then showNewPlayer()
GDPR 동의를 기록합니다(응답 대기 없음):
purposes = { analytics: true, marketing: false }
SubSovereign_RecordConsent(purposes, "GDPR")
6단계 — 네트워크 호출은 렌더 스레드 밖에서 실행
SubSovereign_CheckEntitlements와 SubSovereign_ValidateRokuPurchase는 서버 응답을 기다립니다(최대 15초). 렌더/UI 스레드에서는 절대 호출하지 마세요 — 네트워크가 느리면 화면이 멈춥니다. Task 노드 안에서 실행하고 결과를 씬으로 전달하세요:
' in a Task node's function:
SubSovereign_Configure(m.top.apiKey, m.top.appId, m.top.userId, m.top.baseUrl)
m.top.result = SubSovereign_CheckEntitlements() ' observed field the scene listens on
SubSovereign_RecordConsent는 응답을 기다리지 않으므로 직접 호출해도 안전합니다.
권장 사항
- 채널 실행 시 확인 — 사용자가 잠긴 콘텐츠에 도달하기 전에 접근 권한을 올바르게 설정하세요.
- 구매 후 재확인 — UI에 새로운 접근 권한이 즉시 반영되도록 하세요.
- 클라이언트를 신뢰하지 마세요 — 서버에 물어보세요. 서버가 Roku와 거래를 검증합니다.
- 이용 권한 및 검증 호출에는 항상 Task 노드를 사용하세요.
빠른 참조
| 원하는 작업 | 호출 |
|---|---|
| SDK 설정 | SubSovereign_Configure(apiKey, appId, userId, baseUrl) |
| 사용자 이용 권한 확인 | SubSovereign_CheckEntitlements() → hasAccess 포함 객체 반환 |
| Roku Pay 구매 검증 | SubSovereign_ValidateRokuPurchase(transactionId, productId, accessLevel) |
| 기능 플래그 읽기 | SubSovereign_GetFeatureFlags() |
| GDPR 동의 기록 | SubSovereign_RecordConsent(purposes, jurisdiction) |
다음 단계
- 다른 플랫폼별 가이드도 있습니다: Android, iOS, Web / React Native.
- 개념이 처음이신가요? SubSovereign 작동 원리를 읽어보세요.