캘리포니아 게임 EOL 패치 의무화 — SaaS 운영자가 지금 점검할 실무 영향

목차

End-of-Life 패치는 서비스가 공식 종료될 때 사용자가 기존에 구매한 콘텐츠를 계속 사용할 수 있도록 클라이언트나 서버 코드를 마지막으로 손보는 작업을 말한다. 캘리포니아는 2024년 9월 서명된 AB 2426을 시작으로 디지털 콘텐츠의 "구매" 표시 자체를 규제하기 시작했다. 같은 흐름에서 게임 EOL 패치 의무화 논의가 이어지고 있고, 이 흐름이 게임만의 문제로 끝나지 않는다는 점이 SaaS 운영자에게 중요하다.

실제로, 여기서 다룰 건 게이머 권리 운동이 아니라, 백엔드 운영자 관점에서 본 실무 영향이다. 결제 화면 문구, 매출 인식, 종료 시점의 패치 설계, 데이터 export 엔드포인트까지 차례로 짚는다.

AB 2426의 실제 조문과 EOL 패치 논의의 위치

AB 2426은 게임 셧다운 자체를 막는 법이 아니다. 작성 시점(2026년 5월) 기준 시행 중인 조항은 디지털 스토어가 "Buy" 버튼을 표시할 때 사용자가 영구 소유권을 얻는지 아니면 라이선스를 얻는지 명확히 고지하도록 강제하는 것이다. 위반 시 캘리포니아 소비자 보호법(False Advertising Law)에 따라 과징금이 부과된다(출처: California Legislative Information, AB 2426).

특히, EOL 패치 의무화는 그 다음 단계의 논의다. 2024년 유럽에서 시작된 "Stop Killing Games" 캠페인이 EU 시민 발의안 정족수에 근접하면서 미국 주의회들도 비슷한 법안을 검토하기 시작한 것으로 알려져 있다. 캘리포니아 의회의 후속 법안 초안에는 ① 서버 의존 게임이 종료될 때 LAN/로컬 모드로 전환할 수 있는 패치 배포 의무, ② 잔여 가치에 대한 비례 환불, ③ 종료 12개월 전 사전 고지 같은 항목이 담겨 있는 것으로 보인다(출처: 캘리포니아 의회 공개 의안 추적 시스템).

여기까지 보면 게임 회사 문제 같다. 그런데 법안의 정의 조항을 읽어보면 "Online Service Dependent Digital Goods"라고 광범위하게 정의되어 있다. 게임만 콕 집어 말하는 게 아니다. 정의 조항이 통과 과정에서 좁혀질 수도 있고, 그대로 살아남을 수도 있다. 어느 쪽이든 SaaS 운영자에게 무관한 일이 아니다.

"게임만의 문제"라는 통념이 위험한 이유

그래서, 업계 미팅에서 가장 많이 듣는 반응이 이거다. "우리는 게임 만드는 회사 아니라서 상관없다." 실제로 그럴까.

특히, 법안 초안의 정의를 그대로 적용하면 다음이 전부 포함될 가능성이 있다.

  • 클라우드 의존 카메라/홈캠 (서버 종료 시 벽돌화되는 하드웨어)
  • 구독형 SaaS 도구 (협업 도구의 무료 플랜 폐쇄)
  • 결제 시스템 SDK (제공자가 종료할 때 가맹점이 가져갈 수 있는 형태인지)
  • IoT 펌웨어 의존 가전 (스마트 도어락의 클라우드 모드)
  • 영구 라이선스로 판 데스크톱 도구 (활성화 서버 의존 구조)

특히 B2B SaaS는 안전하다는 인식이 강한데, 라이선스 계약에 "any time, for any reason 종료 가능" 조항을 넣어두면 그만이라는 식이다. 캘리포니아 소비자법(CCPA)이나 AB 2426 후속 입법이 그 조항을 그대로 인정해 줄지는 다른 문제다. 작성 시점 기준 직접 판례는 아직 없는 것으로 보인다.

5년차 운영자 입장에서 봤을 때, 게임 EOL 의무화가 통과되면 그 다음 입법 모델은 SaaS로 옮겨가는 게 시간문제로 보인다. GDPR이 광고 추적에서 시작해 모든 개인정보로 확장된 흐름과 비슷하다. 잘 되고 있을 때 미리 점검하는 쪽이 낫다.

SaaS 환불 회계 — 매출 인식 시점이 뒤집힌다

게다가, EOL 환불 의무가 들어가면 회계 처리가 완전히 달라진다. 법적 영향 중 운영자가 가장 먼저 체감하는 부분이 여기다.

IFRS 15 변동대가 규정과 충돌

현재 일반적인 ARR 기반 매출 인식은 IFRS 15(또는 ASC 606) 기준으로 "서비스 제공 기간에 걸쳐 인식"한다. 연간 결제 100만 원이면 12개월에 걸쳐 인식한다. 문제는 영구 라이선스나 평생 구독 같은 일회성 결제다. 지금까지는 결제 시점에 일시 인식하거나, 추정 서비스 기간으로 안분하는 게 일반적이었다.

그런데, EOL 환불 의무가 들어가면 환불 가능성이 "확률적"이 아니라 "법적 의무"가 된다. 그러면 변동대가(Variable Consideration) 추정치가 들어가야 하고, IFRS 15.50 기준으로 환불 충당부채를 부채로 잡아야 한다. 결제 시점에 잡힌 매출의 일부를 부채로 떼어 둔다는 뜻이다.

처리 방식 결제 시점 인식 환불 충당부채 종료 시 비용
EOL 의무 전 100% 매출 없음 마케팅 비용 처리
EOL 의무 후 매출 – 충당부채 잔여 가치 기준 충당부채 환입

영구 라이선스 모델의 매출 충격

그러나, 체감상 영구 라이선스 모델로 운영하는 회사는 매출이 즉시 10~20% 가까이 깎여 보일 수 있다. 잔여 가치 산정 기준에 따라 더 클 수도 있다. 평생 구독 모델로 IPO 준비 중이면 회계 감사 단계에서 가장 먼저 지적받을 가능성이 높다.

산정 공식 예시는 이렇다. 영구 라이선스 가격이 100만 원이고 정상 사용 가능 기간을 5년(1825일)으로 가정한다면, 사용 N일째 종료 시 환불액은 100만 원 × (1825 - N) / 1825 가 된다. 이 산식 자체를 약관에 박아 두면 종료 시점의 분쟁이 줄어든다.

EOL 패치를 기술적으로 어떻게 만드나

실제로, 법안이 통과되든 안 되든, 미리 EOL 패치 구조를 만들어 두면 운영 부담이 확 줄어든다. 잘 되면 안 건드리는 게 원칙이긴 한데, 종료 시나리오는 잘 되는 시점에 미리 짜놔야 한다.

1) 서버 의존성을 분리하라

서비스 종료 시 가장 큰 문제는 인증 서버다. 클라이언트가 부팅할 때마다 인증 API를 때리는 구조면 서버가 죽는 순간 전체가 죽는다. 핵심은 인증을 "오프라인 fallback" 가능하게 설계하는 것이다.

# auth_strategy.py
class AuthStrategy:
    def __init__(self, primary, fallback):
        self.primary = primary  # 서버 인증
        self.fallback = fallback  # 로컬 토큰 검증

    def authenticate(self, credentials):
        try:
            # 3초 타임아웃으로 서버 시도
            return self.primary.verify(credentials, timeout=3)
        except (TimeoutError, ConnectionError):
            # 서버 죽었으면 로컬 검증으로
            return self.fallback.verify_signed_token(credentials)

    def issue_eol_token(self, user_id, expiry_years=10):
        # EOL 시점에 발급하는 장기 서명 토큰
        return self.fallback.sign({
            "user_id": user_id,
            "exp": time.time() + expiry_years * 365 * 86400,
            "mode": "eol_offline",
        })

핵심은 issue_eol_token이다. 서비스 종료 6개월 전에 모든 활성 사용자에게 10년짜리 서명 토큰을 발급해 두면, 서버가 죽어도 로컬 검증으로 작동한다. 키 페어는 클라이언트에 공개키만 박아 두고 개인키는 폐쇄 보관한다.

2) Feature flag로 EOL 모드 토글

EOL 패치를 만드는 시점이 따로 있는 게 아니라, 처음부터 코드 안에 EOL 모드가 들어 있어야 한다. 그래야 종료 시점에 마지막 배포로 플래그만 켜면 된다.

// config/runtime.ts
export const RUNTIME_MODE = {
  NORMAL: "normal",
  EOL_TRANSITION: "eol_transition",  // 종료 고지 기간
  EOL_OFFLINE: "eol_offline",         // 서버 끄고 로컬만
} as const;

export function getDisabledFeatures(mode: string) {
  if (mode === RUNTIME_MODE.EOL_OFFLINE) {
    return [
      "multiplayer_matchmaking",
      "leaderboard_sync",
      "cloud_save",
      "in_app_purchase",  // 결제 차단 필수
    ];
  }
  if (mode === RUNTIME_MODE.EOL_TRANSITION) {
    // 신규 결제만 막고 기존 기능은 유지
    return ["new_subscription", "renewal"];
  }
  return [];
}

in_app_purchase를 EOL_OFFLINE 모드에서 차단하는 게 중요하다. 종료 직전까지 결제 받고 환불 의무 회피하면 그게 가장 큰 법적 리스크다. 신규 결제 차단은 EOL_TRANSITION 단계에서 미리 시작해야 한다.

3) 데이터 export 엔드포인트는 진작에 만들어 둬라

또한, SaaS 운영자라면 GDPR 때문에 이미 만들어 뒀을 수도 있는데, 캘리포니아 CCPA는 형식 요건이 조금 다르다. 둘 다 만족하는 export는 JSON + CSV 동시 제공이 안전하다.

# export_user_data.py
async def export_for_eol(user_id: str, target_dir: str):
    # 모든 테넌트 데이터를 한 번에 묶어서 zip
    user_data = await db.fetch_all_user_data(user_id)

    paths = {
        "profile.json": json.dumps(user_data.profile),
        "purchases.csv": to_csv(user_data.purchases),
        "content.zip": await pack_user_content(user_id),
        "manifest.txt": build_eol_manifest(user_data),
    }

    return await zip_to_signed_url(
        paths,
        target_dir,
        expires_days=90,
    )

그래서, 서명 URL의 만료 기간을 90일로 잡은 이유는, 너무 길면 URL 유출 시 책임 소재가 모호해진다. 30일 알림 → 60일 후 알림 → 90일 마감의 3단계로 운영하는 게 합리적으로 보인다. 다만 환불 신청 기한은 export 기한보다 길게 잡아야 분쟁이 줄어든다.

캘리포니아 외 지역의 흐름

이처럼, 캘리포니아만 보면 안 된다. EU의 디지털 서비스법(DSA), 영국의 ICO 가이드라인, 한국의 전자상거래법 개정안이 비슷한 방향으로 가고 있는 듯하다. EU는 "Stop Killing Games" 시민 발의안이 정족수에 근접해 EU 집행위 검토 단계로 넘어가는 것으로 알려져 있다(출처: European Citizens’ Initiative 공식 페이지).

이처럼, 한국은 게임산업진흥법 개정안에서 종료 6개월 전 고지 의무가 이미 들어 있다. 작성 시점 기준 환불 비례 산정 방식은 사업자 재량으로 남아 있는 것으로 보인다. 캘리포니아처럼 잔여 가치 기준이 강제되면 산정 공식 자체를 명시해 두는 게 안전하다.

지역별 의무를 비교해 보면 흥미로운 점이 있다. EU는 "기능 보존(playable offline)"에 무게가 실려 있고, 캘리포니아는 "고지·환불"에 무게가 있다. 한국은 그 중간쯤이다. 셋 다 만족하려면 결국 위에서 다룬 3단계 — 인증 분리, EOL 플래그, 데이터 export — 가 답으로 수렴한다.

정책 변화 모니터링은 자동화하라

법안 추적을 사람이 매주 하는 건 비효율적이다. 캘리포니아 의회는 모든 의안의 상태 변화를 RSS로 제공한다. 관심 의안 번호만 등록해 두면 슬랙 채널로 흘릴 수 있다.

# bill_watcher.py
import feedparser
import httpx

BILL_FEED = "https://leginfo.legislature.ca.gov/faces/billNavClient.xhtml?bill_id={bill_id}"
WATCH_BILLS = ["AB-2426", "SB-XXXX"]  # 후속 EOL 법안 번호로 교체

async def check_status_changes(slack_webhook: str):
    for bill_id in WATCH_BILLS:
        feed = feedparser.parse(BILL_FEED.format(bill_id=bill_id))
        latest = feed.entries[0]
        if has_changed_since_last_run(bill_id, latest.id):
            await httpx.post(slack_webhook, json={
                "text": f"[{bill_id}] 상태 변경: {latest.title}",
                "blocks": build_bill_block(latest),
            })

이 스크립트를 GitHub Actions 크론으로 하루에 한 번 돌리는 게 일반적이다. 의안 상태가 "Engrossed" → "Enrolled" → "Chaptered" 순으로 진행되는데, Engrossed 단계에 진입한 시점이 운영자가 슬슬 준비해야 할 시그널로 보인다.

지금 점검할 4가지

운영자 입장에서 지금 당장 할 수 있는 건 다음 4가지로 좁힐 수 있다.

  1. 결제 화면 문구 점검 — "구매(Buy)" 버튼이 라이선스 부여인지 영구 소유인지 명확히 표시되어 있는가. AB 2426은 이미 시행 중이라 위반이면 바로 위험하다.
  2. EOL 환불 정책 초안 작성 — 잔여 가치 산정 공식을 미리 약관에 박아 두자. 영구 라이선스 100만 원·정상 사용 가능 5년 가정의 경우, 사용 N일째 종료 시 100만 × (1825 - N) / 1825 같은 식.
  3. 데이터 export 엔드포인트 점검 — GDPR/CCPA 요건에 맞는 형식인지, 만료 기간이 명확한지, 서명 URL 갱신 절차가 있는지.
  4. 회계팀과 충당부채 시뮬레이션 — 영구 라이선스 매출의 몇 %를 충당부채로 잡을지 IFRS 15.50 기준으로 검토. 감사 받기 전에 미리.

결국, 정책 변화 추적은 캘리포니아 의회 공식 트래커(leginfo.legislature.ca.gov)와 EU 시민 발의안 페이지를 RSS로 걸어두는 게 가장 빠르다. 인용한 모든 출처는 2026년 5월 기준이며, 의안 진행 상황은 그 이후 달라질 수 있다.

관련 글