크롬 웹스토어에 확장 프로그램 배포하기 — 심사 통과까지

🌐 English

확장을 다 만들고 나면 마지막 단계가 남습니다. 스토어에 올리기. 개발자 모드로 로컬에서 쓸 때는 폴더만 있으면 되지만, 다른 사람에게 주려면 매번 zip을 보내고 "개발자 모드 켜세요"를 설명해야 합니다. 그리고 크롬은 개발자 모드로 로드한 확장에 브라우저를 켤 때마다 경고 배너를 띄웁니다.

이 글은 앞의 두 글에서 만든 매매 봇 컨트롤 패널을 실제로 크롬 웹스토어에 올리고 심사를 통과한 기록입니다. 절차 자체보다 어디서 걸리는지에 무게를 뒀습니다.

먼저 알아야 할 두 가지 숫자

개발자 등록비 5달러. 계정당 한 번 내는 일회성 비용이고, 확장 개수와 무관합니다. 이걸 내야 대시보드에 아이템을 만들 수 있습니다. 결제 후 계정 활성화까지 잠깐 걸릴 수 있습니다.

심사 기간은 며칠 단위. 빠르면 하루 안, 보통은 며칠입니다. 여기서 중요한 건 평균이 아니라 편차입니다. 권한을 많이 요구하거나 설명이 모호하면 수동 검토로 넘어가면서 눈에 띄게 길어집니다. "언제 통과되는지"는 대체로 내가 만든 manifest가 결정합니다.

권한 최소화가 곧 심사 속도다

앞 글에서 manifest 권한을 최소로 유지한 이야기를 했는데, 그 효과가 가장 크게 나타나는 곳이 여기입니다. 이 확장의 권한은 이렇습니다.

"permissions": [

  "windows"

],

"host_permissions": [

  "https://script.google.com/*"

]

심사에서 문제가 되는 것은 대체로 다음 셋입니다.

  • <all_urls> 또는 넓은 host_permissions — "모든 사이트의 데이터를 읽고 변경" 경고가 뜨고, 왜 필요한지 소명해야 합니다
  • content_scripts — 남의 페이지에 코드를 주입한다는 뜻이라 검토 강도가 올라갑니다
  • 원격 코드 실행 — MV3에서는 아예 금지입니다. 외부 스크립트를 eval하거나 CDN에서 받아 실행하면 거절됩니다

이 확장은 셋 다 해당하지 않습니다. content_scripts가 없고, 접근 도메인이 자기 백엔드 하나이며, 모든 코드가 패키지 안에 있습니다. 제출 폼에서 각 권한의 사유를 적는 칸이 있는데, 권한이 하나면 이 칸도 한 줄로 끝납니다.

실제로 적은 사유는 이런 식입니다.

windows — 확장 팝업에서 외부 매뉴얼 링크를 새 창으로 여는 데 사용합니다.

https://script.google.com/* — 이 확장의 백엔드(Google Apps Script 웹앱)를

  호출하기 위해 필요합니다. 이 도메인 외에는 어떤 네트워크 요청도 하지 않습니다.

핵심은 "무엇을 하지 않는지"까지 쓰는 것입니다. 검토자가 확인해야 할 범위를 좁혀 주면 그만큼 빨리 끝납니다.

제출 전에 한 번은 깨지는 것들

업로드 자체에서 걸리는 실수는 대개 정해져 있습니다.

  • zip 안에 폴더가 한 겹 더 있다. manifest.jsonzip 루트에 있어야 합니다. 폴더째 압축하면 거부됩니다
  • 버전을 안 올렸다. 같은 version으로는 다시 못 올립니다. 재제출할 때마다 올려야 합니다
  • 안 쓰는 파일이 남아 있다. 개발 중 만든 샘플 HTML, 쓰지 않는 CSS, 캡처용 임시 파일이 그대로 들어갑니다. 용량 문제라기보다 검토 대상이 늘어납니다
  • 아이콘 크기 누락. 16/48/128 세 벌을 iconsaction.default_icon 양쪽에 넣어 둡니다

배포용 zip은 소스 폴더를 그대로 압축하지 말고, 필요한 파일만 따로 모아 만드는 편이 안전합니다.

dist/

  manifest.json

  popup.html

  popup.js

  api.js

  icons/

    icon16.png

    icon48.png

    icon128.png

스토어 이미지 1280x800

스토어 등록 페이지에는 스크린샷이 최소 1장 필요합니다. 규격은 1280x800(또는 640x400)이고, 여기가 은근히 시간을 잡아먹습니다. 확장 팝업은 폭이 400px이라 그대로 캡처하면 1280x800을 채울 수 없습니다. 남는 공간을 어떻게 할 것인가 하는 문제가 생깁니다.

해결한 방법은 이렇습니다. 팝업과 같은 마크업·같은 CSS를 쓰는 캡처 전용 HTML을 하나 만들고, 배경 위에 팝업을 얹어 1280x800으로 렌더링했습니다.

<!-- store-shot.html : 캡처 전용. 배포 zip 에는 넣지 않는다 -->

<body style="width:1280px;height:800px;display:flex;

             align-items:center;justify-content:center;

             background:linear-gradient(135deg,#0e1116,#1b2430);">

  <div style="width:400px;box-shadow:0 20px 60px rgba(0,0,0,.5);

              border-radius:12px;overflow:hidden;">

    <!-- popup.html 과 동일한 마크업을 그대로 삽입 -->

  </div>

</body>

이러면 두 가지가 좋습니다. 실제 화면과 어긋나지 않고(같은 CSS를 쓰니까), UI를 고칠 때 캡처만 다시 뜨면 됩니다. 스크린샷을 포토샵으로 합성해 두면 다음 버전에서 반드시 실제 화면과 달라집니다.

다크·라이트 두 벌을 준비한 것도 의도적입니다. 스토어 목록에서 테마 전환이 된다는 사실 자체가 정보가 되고, 스크린샷 여러 장으로 기능을 설명하는 것보다 이쪽이 직관적입니다.

1280x800 스토어 등록 이미지 - 다크 테마 종목 카드 화면

실제 제출한 스토어 이미지. 400px 팝업을 1280x800 배경 위에 얹어 렌더링했습니다.

1280x800 스토어 등록 이미지 - 라이트 테마 종목 카드 화면

같은 화면의 라이트 테마. 테마 지원 자체를 스토어에서 보여 주는 역할을 합니다.

개인정보처리방침 — 대부분 여기서 막힌다

제출 과정에서 가장 자주 반려되는 항목이 개인정보 관련 신고입니다. 대시보드에는 이런 것들을 적는 칸이 있습니다.

  • 어떤 사용자 데이터를 수집하는가 (개인 식별 정보, 인증 정보, 위치, 활동 기록 등 항목별 체크)
  • 수집한다면 필요한가
  • 제3자에게 판매·양도하지 않는다는 확인
  • 공개된 개인정보처리방침 URL

여기서 정직해야 합니다. 이 확장은 API 키와 계좌번호를 입력받습니다. 확장 자체가 서버로 수집해 보관하는 것은 아니고 사용자 본인의 백엔드에 저장되지만, "인증 정보를 다룬다"는 사실은 그대로 신고해야 합니다. 여기서 "수집 안 함"으로 체크하고 화면에 API 키 입력란이 보이면 반려됩니다 — 검토자가 스크린샷과 대조합니다.

개인정보처리방침은 접근 가능한 공개 URL이어야 합니다. 블로그 페이지 하나로도 충분하고, 최소한 다음이 들어가야 합니다.

  • 무엇을 입력받는가 (API 키, 계좌번호, 매매 파라미터)
  • 어디에 저장되는가 (사용자 본인의 Apps Script 프로퍼티)
  • 개발자가 그 값에 접근하는가 (접근하지 않는다면 그렇게 명시)
  • 제3자 전송 여부
  • 문의 연락처

덧붙여, 확장이 하는 일과 스토어 설명이 일치해야 합니다. 설명에 없는 기능이 화면에 있거나 그 반대면 "기능 설명 불일치"로 반려됩니다.

금융 관련 확장이라서 추가로 신경 쓴 것

매매 봇 컨트롤 패널은 금융 카테고리에 가까운 물건이라 몇 가지를 더 조심했습니다.

  • 수익을 약속하는 문구를 쓰지 않는다. 설명은 "자동 매매 시스템의 컨트롤 패널"이라는 기능 서술로만 씁니다
  • 증권사와 무관함을 분명히 한다. 이 확장은 공개 REST API를 쓰는 서드파티 도구이고, 증권사가 만들거나 보증한 것이 아닙니다. 브랜드·로고를 쓰지 않고, 이름에도 공식처럼 보이는 표기를 피합니다
  • 위험 고지를 설명에 넣는다. 자동매매로 손실이 날 수 있다는 문장을 스토어 설명과 매뉴얼 양쪽에 둡니다

첫 번째와 두 번째는 스토어 정책 문제이고, 세 번째는 정책 이전에 쓰는 사람에 대한 의무에 가깝습니다.

통과 후

승인되면 스토어 URL이 나오고, 그때부터는 zip을 보내는 대신 링크 하나면 됩니다. 실제로 등록된 결과물은 여기 있습니다 — Stock Trading Bot.

업데이트도 같은 흐름입니다. version을 올려 새 zip을 올리면 다시 심사를 거칩니다. 권한을 추가하는 업데이트는 처음 제출만큼 오래 걸린다고 보는 편이 안전합니다. 권한이 그대로면 대체로 빠릅니다 — 이것도 처음에 권한을 좁게 잡아 둔 값입니다.

참고로 크롬은 기존 사용자에게 자동 업데이트를 밀어 줍니다. 편하지만 되돌릴 수 없다는 뜻이기도 합니다. 매매를 조작하는 확장이라면, 로컬에서 개발자 모드로 한 번 검증하고 올리는 절차를 생략하지 않는 편이 좋습니다.

정리

  • 일회성 5달러, 심사는 며칠 — 편차는 대부분 내 manifest가 만든다
  • 심사를 빠르게 하는 것은 넓은 host_permissions·content_scripts·원격 코드가 없는 것
  • 권한 사유에는 "무엇을 하지 않는지"까지 적어 검토 범위를 좁힌다
  • zip은 manifest가 루트에, 재제출마다 version 올리기, 안 쓰는 파일 빼기
  • 1280x800 이미지는 같은 CSS를 쓰는 캡처 전용 HTML로 만들면 화면과 어긋나지 않는다
  • 개인정보 신고는 정직하게 — 화면에 API 키 입력란이 있으면 "수집 안 함"은 통하지 않는다
  • 금융 도구는 수익 약속 금지 · 증권사와 무관함 명시 · 위험 고지

서버 없는 백엔드(1편) → 크롬 확장 컨트롤 패널(2편) → 스토어 배포(3편)로 한 바퀴가 끝났습니다. 전체를 관통하는 교훈은 하나입니다. 제약을 먼저 받아들이면 설계가 단순해진다. GAS의 1분 트리거가 전략을 골라 줬고, 팝업의 400px가 기능을 골라 줬고, 스토어의 권한 심사가 manifest를 깎아 줬습니다.

※ 이 글은 개발·배포 기록이며 투자 권유가 아닙니다. 자동매매는 시스템 오류·네트워크 장애·예상치 못한 시장 상황으로 손실이 발생할 수 있으며, 투자 판단과 그 결과는 전적으로 본인 책임입니다. 스토어 정책과 심사 기준은 수시로 바뀌므로 제출 전 최신 공식 문서를 확인하시기 바랍니다.

댓글

이 블로그의 인기 게시물

한국투자증권 KIS API로 실시간 시세 받기 (WebSocket 실전)

파이썬으로 업비트 API 연동하기 — 시세 조회부터 주문까지 기초

Go로 자동매매 신호봇 프레임워크 설계하기