iOS 인앱 결제(IAP) 도입을 위해선 StoreKit 2와 App Store Server API를 활용하는 것이 현대적인 표준이다. 이 글에서는 코드를 작성하기 전, 관리자 페이지에서 반드시 설정해야 할 인프라 및 권한 설정을 다룬다.
전체 구조도
구축할 흐름은 다음과 같다. 안드로이드에 비해 구조는 단순하지만, 인증 키 관리가 핵심이다.
- App Store Connect: 상품 관리, 금융 계약, 웹훅 설정의 중심이다.
- App Store Server API Key: 백엔드 서버가 애플 서버와 통신(구독 상태 조회, 영수증 검증)하기 위한 인증 수단이다.
- Server Notifications V2: 애플이 결제/구독 변경 이벤트를 우리 서버(Webhook)로 직접 전송한다.
Step 1. 유료 앱 계약 및 세금/금융 정보 설정 (최우선)
이걸 안 하면 결제 테스트 자체가 불가능하다. 개발 설정보다 먼저 비즈니스 설정을 끝내야 한다.
- App Store Connect 접속 > [비즈니스(Business)] 메뉴로 이동한다.
- '유료 앱(Paid Apps)' 계약이 체결되어 있는지 확인한다.
- 상태가 '활성(Active)'이 아니라면 다음 정보를 모두 입력해야 한다.
- 계좌 정보: 수익을 지급받을 은행 계좌.
- 세금 양식: 미국 세금 양식(W-8BEN 등) 작성.
- 이 절차가 승인되기까지 최대 24~48시간이 걸리므로 가장 먼저 해둔다.
Step 2. App ID에서 인앱 결제 기능 활성화
앱의 식별자(App ID)에 "이 앱은 돈을 받습니다"라는 권한을 부여하는 과정이다.
- Apple Developer Portal > [Certificates, Identifiers & Profiles]로 이동한다.
- 좌측 메뉴 [Identifiers] 클릭 > 해당 앱의 App ID를 선택한다.
- Capabilities 탭에서 In-App Purchase 항목이 체크되어 있는지 확인한다. (보통 기본적으로 체크되어 있지만, 확인은 필수다.)
- 변경 사항이 있다면 [Save] 한다.
Step 3. 인앱 상품(Product) 등록
코드에서 호출할 상품 ID를 만든다.
- [App Store Connect] > [내 앱(My Apps)] > 해당 앱 선택.
- 좌측 메뉴 [수익 창출(Monetization)] > [인앱 결제(In-App Purchases)]로 이동한다.
- 단건 구매라면 [소모품/비소모품], 정기 결제라면 [구독] 메뉴로 간다.
- [+] 버튼을 눌러 상품을 생성한다.
- 제품 ID (Product ID): 코드에서 사용할 고유 ID (예:
com.sample.app.premium.monthly). 수정 불가능하니 신중히 짓는다. - 가격 및 표시 이름: 적절히 입력한다.
- 스크린샷/심사 메모:
- 개발 중에는 '스크린샷 누락' 경고가 떠도 테스트는 가능하다. (나중에 심사 제출 전에는 반드시 결제 화면 캡처본을 올려야 한다.)
- 상태가 '제출 준비 완료(Ready to Submit)' 혹은 '메타데이터 누락(Missing Metadata)' 상태면 테스트 가능하다.
Step 4. App Store Server API 키 생성 (백엔드 필수)
백엔드 서버가 애플 서버에 "이 영수증 유효해?"라고 물어보거나 구독 상태를 조회할 때 사용하는 인증 키다. (과거의 Shared Secret 방식보다 이 방식을 강력 권장한다.)
- [App Store Connect] > [사용자 및 액세스(Users and Access)] 이동.
- 상단 탭 [통합(Integrations)] 클릭 > 좌측 메뉴 [인앱 결제(In-App Purchase)] 선택.
- [키 생성(+)] 클릭.
- 이름: 식별 가능한 이름 (예:
Billing Server Key).
- 이름: 식별 가능한 이름 (예:
- 생성 후 다음 3가지 데이터를 백엔드 개발자에게 전달한다.
- Issuer ID: 화면 상단에 표시된 UUID.
- Key ID: 생성된 키 목록에 있는 ID.
- Private Key (.p8 파일): [API 키 다운로드]를 눌러 받는다. (단 한 번만 다운로드 가능하니 잃어버리면 안 된다.)
Step 5. Server Notifications V2 (Webhook) 설정
실시간 구독 갱신, 환불, 취소 알림을 받을 웹훅 주소를 등록한다. 안드로이드의 Pub/Sub 역할을 한다.
- [App Store Connect] > [내 앱] > 해당 앱 선택.
- 좌측 메뉴 [일반(General)] > [앱 정보(App Information)] 이동.
- 하단으로 스크롤하여 [App Store 서버 알림(App Store Server Notifications)] 섹션을 찾는다.
- 프로덕션 URL (Production URL): 실제 배포 후 사용할 백엔드 URL.
- 샌드박스 URL (Sandbox URL): 개발 및 테스트 중에 사용할 백엔드 URL.
- Tip: 개발 단계에선 두 URL에 동일한 개발 서버 주소를 넣어도 된다.
- 버전: 반드시 [버전 2 (Version 2)]를 선택한다. (V1은 지원 중단 예정).
- [저장] 한다.
Step 6. 샌드박스 테스터(Sandbox Tester) 계정 생성
개발자가 본인의 실제 Apple ID로 결제하면 진짜 돈이 나간다. 가상 결제를 위한 테스트 계정을 만들어야 한다.
- [App Store Connect] > [사용자 및 액세스] 이동.
- 좌측 하단 [샌드박스(Sandbox)] > [테스터(Testers)] 클릭.
- [+] 버튼 클릭하여 계정 생성.
- 이메일: 실제 존재하지 않는 이메일도 가능하나, 가입 인증 메일 확인이 필요할 수 있으므로 '일회용 이메일'이나 '본인 이메일의 alias(예:
myname+test1@gmail.com)'를 사용하는 것이 좋다. - 지역: 한국 스토어를 테스트할 거면 App Store 국가를 '대한민국'으로 설정한다.
- 이메일: 실제 존재하지 않는 이메일도 가능하나, 가입 인증 메일 확인이 필요할 수 있으므로 '일회용 이메일'이나 '본인 이메일의 alias(예:
- 사용법:
- 테스트 기기(아이폰)의 설정 > App Store > 하단 '샌드박스 계정' 영역에 이 아이디로 로그인한다. (기기 전체 아이클라우드 로그인이 아니다!)
Step 7. (레거시 지원용) 앱용 공유 암호 (App-Specific Shared Secret)
최신 StoreKit 2만 쓴다면 필요 없지만, 레거시 검증 라이브러리를 쓰거나 백엔드 솔루션에 따라 요구하는 경우가 있다.
- [App Store Connect] > [내 앱] > [수익 창출] > [인앱 결제].
- 우측 상단 [앱용 공유 암호(App-Specific Shared Secret)] 클릭.
- [관리] > 생성된 코드를 복사하여 백엔드 개발자에게 전달한다.
세팅 체크리스트
다음 항목들이 준비되었는지 확인 후 개발팀에 전달한다.
- Agreement: '유료 앱 계약'이 활성 상태인가? (계좌/세금 정보 등록 완료)
- Dev Portal: App ID의 'In-App Purchase' 기능이 켜져 있는가?
- Connect: 인앱 상품(Product ID)이 생성되어 있는가?
- To Backend: Issuer ID, Key ID, .p8 파일 (Server API용)을 전달했는가?
- To Backend: (필요시) Shared Secret을 전달했는가?
- Connect: Server Notification URL (Sandbox/Prod)에 백엔드 웹훅 주소를 입력했는가?
- To Frontend: 샌드박스 테스터 계정 아이디/비번을 공유했는가?
마치며
iOS는 GCP 같은 중간 미들웨어 설정이 없어 비교적 직관적이다. 하지만 '계약 상태'나 '키(Key) 권한' 문제로 에러가 나는 경우가 90% 이상이다. 위 과정을 빠짐없이 진행했다면, 이제 iOS 개발자는 StoreKit을 붙이고, 백엔드 개발자는 애플 서버와 통신만 하면 된다.
