Advanced Commerce API 환불은 iOS 개발자가 환불을 시작할 수 있는 유일한 방법이며, 최종 결정은 여전히 Apple이 내립니다
대부분의 iOS 개발자는 고객에게 환불해 줄 수 없습니다. Apple의 Advanced Commerce API를 쓰는 앱은 환불을 요청하고, 구독을 철회하고, 원하는 금액을 돌려줄 수 있습니다. 각 엔드포인트의 작동 방식, Apple이 여전히 거절할 수 있는 부분, 돈 문제가 꼬이는 지점을 정리합니다.

핵심 요약
- 한 Apple 엔지니어는 2026년 6월, 일반적인 App Store 구매에 대해 개발자가 직접 환불할 수는 없다고 밝혔습니다. 개발자가 할 수 있는 일은 CONSUMPTION_REQUEST에 응답하며 보내는 소비 데이터와 refundPreference뿐입니다.
- Apple의 Advanced Commerce API 사용을 승인받은 앱은 Request Transaction Refund 엔드포인트로 일회성 결제나 구독 거래의 환불을 App Store에 요청할 수 있습니다. Revoke Subscription과 Cancel a Subscription 엔드포인트도 함께 제공됩니다.
- Advanced Commerce API의 환불, 철회, 해지 엔드포인트를 호출하려면 개발자의 Account Holder가 Advanced Commerce API Addendum(부속 계약)에 서명해야 합니다. Apple은 최신 버전에 동의하지 않으면 호출이 오류를 반환한다고 설명합니다.
- Request Transaction Refund 엔드포인트의 refundType은 FULL, PRORATED, CUSTOM 중 하나입니다. 통화의 1000분의 1 단위로 지정하는 refundAmount는 CUSTOM일 때만 허용됩니다. Apple에 따르면 캐나다와 미국을 제외한 모든 지역에서 금액에 세금이 포함되어야 합니다.
- Apple의 refundRiskingPreference 필드는 기본값이 true입니다. 그래서 App Store는 개발자 본인의 환불 요청에 대해서도 CONSUMPTION_REQUEST를 보낼 수 있습니다. Apple은 12시간 이내에 응답할 것을 요구합니다.
- Advanced Commerce API의 환불, 철회, 해지 엔드포인트는 프로덕션에서 앱당 초당 5건으로 제한되며, 샌드박스는 그 10%입니다.
- Revoke Subscription 호출이 성공하면 Apple은 REFUND 알림을 보냅니다. 그리고 알림이 도착하기 전이 아니라 알림의 revocationDate를 기준으로 서비스를 종료하라고 안내합니다.
일반 iOS 개발자는 고객에게 환불해 줄 수 없습니다. 2026년 6월, 한 App Store Commerce Engineer는 개발자 포럼의 질문에 한 문장으로 답했습니다. 현재로서는 개발자가 직접 환불하는 것이 불가능하다고요. 예외는 하나뿐이고, 그것은 Advanced Commerce API 안에 있습니다. Apple이 승인한 앱은 Advanced Commerce API 환불 요청을 보내거나, 환불과 함께 구독을 철회하거나, 원하는 금액을 요청할 수 있습니다. 돈이 실제로 나가는지는 여전히 Apple이 결정합니다.
Advanced Commerce API란 무엇이고 누가 쓸 수 있나
Apple은 2025년 1월 23일 Advanced Commerce API를 출시했습니다. 맞춤형 일회성 구매, 구독, 선택형 애드온이 붙은 구독으로 이루어진 매우 큰 카탈로그의 Apple 앱 내 구입을 처리하는 API입니다. 모든 상품을 App Store Connect에서 만들 필요가 없습니다. SKU를 자체 서버에서 정의하고 구매 시점에 Apple로 보냅니다.
사용 권한은 앱 단위로 부여됩니다. 신청서를 작성해야 하며, Apple의 자격 요건 페이지는 앱의 핵심이어야 하는 비즈니스 모델 세 가지를 제시합니다.
- 오디오북, 클래스, 강좌, 미니 앱처럼 매우 큰 일회성 구매 카탈로그.
- 크리에이터별 콘텐츠가 각각 별도의 구독인, 매우 큰 구독 콘텐츠 카탈로그.
- 프리미엄 채널이나 스포츠처럼, 선택형 애드온이 하나의 구매로 함께 갱신되는 구독.
다른 프로그램에 이 API가 필요한 경우에도 Apple은 앱의 신청을 허용합니다. 호스팅된 미니 앱에서 발생한 적격 앱 내 구입 매출의 85%를 회원에게 지급하는 Mini Apps Partner Program이 이 API를 요구합니다.
환불 엔드포인트는 나중에 추가됐고, 서명이 필요하다
2025년 3월 24일 자 버전 1.1에서 Request Transaction Refund와 Revoke Subscription이 추가되었습니다. Apple의 프로그램 페이지에 따르면 구독 콘텐츠를 제공하는 앱은 해지 처리, 구매 후 콘텐츠 검증, 카탈로그 관리를 위해 Cancel, Revoke, Refund API를 사용할 자격도 있을 수 있습니다. 각 엔드포인트 페이지에는 같은 조건이 붙어 있습니다. Account Holder가 Advanced Commerce API Addendum에 서명해야 하고, 최신 버전에 동의하지 않았다면 호출이 오류를 반환합니다. 엔드포인트별 사용 목적을 정해 두는 것은 문서가 아니라 Addendum입니다.
세 엔드포인트 한눈에 비교
| Cancel a Subscription | Revoke Subscription | Request Transaction Refund | |
|---|---|---|---|
| 경로 | advancedCommerce/v1/subscription/cancel/{transactionId} | advancedCommerce/v1/subscription/revoke/{transactionId} | advancedCommerce/v1/transaction/requestRefund/{transactionId} |
| 대상 | 자동 갱신 구독 | 구독과 그에 속한 모든 항목 | 일회성 결제와 구독 거래 |
| 환불 | 없음 | FULL 또는 PRORATED | SKU별 FULL, PRORATED 또는 CUSTOM |
| 이용 권한 | 기간 종료까지 유지 | revocationDate에 종료 | revoke 플래그로 항목별 설정 |
| 프로덕션 요청 한도 | 초당 5건 | 초당 5건 | 초당 5건 |
Cancel a Subscription은 다음 결제를 막는다
Cancel은 자동 갱신을 끕니다. Apple에 따르면 고객은 현재 기간이 끝날 때까지 이용 권한을 유지합니다. 환불은 전혀 없습니다. 고객이 해지를 원하고 이미 결제한 기간을 다 쓴 경우에 맞는 호출입니다.
Revoke Subscription은 모든 것을 즉시 끝낸다
Revoke는 자동 갱신을 false로 바꾸고, 전액 또는 일할 환불과 함께 구독을 철회합니다. 요청 본문에는 refundReason, refundRiskingPreference, refundType, requestInfo가 들어갑니다. 그러면 Apple이 App Store Server Notifications V2 엔드포인트로 REFUND 알림을 보냅니다. Apple의 지침은 구체적입니다. 알림에 담긴 revocationDate를 기준으로 서비스를 끄고, 알림이 도착하기 전에는 끄지 마세요.
Request Transaction Refund는 항목 단위로 작동한다
가장 정밀한 도구입니다. 항목 목록을 보내고, 각 항목에 SKU, refundReason, refundType, revoke 플래그를 지정합니다. CUSTOM이면 통화의 1000분의 1 단위로 refundAmount도 보냅니다. 따라서 4990은 4.99를 뜻합니다. FULL이나 PRORATED에 금액을 보내면 Apple은 오류 4000155로 거부합니다. 응답에는 서명된 거래 정보가 담기고, 구독이라면 서명된 갱신 정보도 함께 담깁니다.
Apple이 받는 refundReason 값은 UNINTENDED_PURCHASE, FULFILLMENT_ISSUE, UNSATISFIED_WITH_PURCHASE, LEGAL, OTHER, MODIFY_ITEMS_REFUND입니다. 일곱 번째 값인 SIMULATE_REFUND_DECLINE은 샌드박스와 TestFlight 테스트 전용입니다. 이 값이 존재하는 이유는 App Store가 거절할 수 있기 때문입니다.
Apple은 당신의 환불 요청도 거절할 수 있다
이 엔드포인트의 이름은 정직합니다. 이것은 요청일 뿐입니다. 결정권이 실제로 어디에 있는지는 두 필드가 보여 줍니다.
refundRiskingPreference는 소비 데이터 확인을 부른다
Apple은 refundRiskingPreference를 App Store가 환불 결정의 근거로 개발자에게 소비 데이터를 요청할지 여부라고 설명합니다. 기본값은 true입니다. true이면 본인의 환불 요청에 대해 CONSUMPTION_REQUEST를 받고, Send Consumption Information으로 응답합니다. Apple은 CONSUMPTION_REQUEST를 받은 뒤 12시간 이내에 응답하라고 요구합니다. false로 두면 그 알림은 오지 않습니다.
거절을 알리는 오류
| 오류 | 코드 | Apple의 설명 |
|---|---|---|
| AlreadyRefundedError | 4030021 | 이미 환불된 거래 |
| PendingRefundError | 4000181 | 대기 중인 환불이 있는 거래 |
| TransactionNotRefundableError | 4030024 | 환불할 수 없는 거래 |
| TransactionCannotBeRefundedContactSupportError | 4030025 | 고객이 Apple 지원에 문의할 수 있음 |
| RefundAmountWithoutCustomError | 4000155 | CUSTOM 없이 금액을 보냄 |
대비해야 할 것은 PendingRefundError입니다. 흔한 원인은 고객 지원팀이 조치하기 전에 고객이 이미 Report a Problem으로 Apple에 요청한 경우입니다. Apple의 자격 요건은 어차피 이런 앱이 앱 안에서 환불 경로를 제공하도록 요구합니다. Report a Problem 링크든 beginRefundRequest API든 둘 중 하나입니다. 그래서 두 개의 문이 동시에 열려 있게 됩니다.

Advanced Commerce API 환불에 실제로 드는 돈
먼저 환불해 주는 편이 분쟁을 다투는 것보다 싸게 느껴집니다. 그래도 돈은 나갑니다. 그리고 이 API에서는 어떤 실수가 대규모로 반복되기 쉽습니다.
맞춤 금액에 포함되는 세금
Apple에 따르면 요청하는 refundAmount에는 캐나다와 미국을 제외한 모든 지역에서 세금이 포함되어야 합니다. 세전 SKU 가격으로 CUSTOM 환불액을 계산하는 팀은 그 외의 모든 스토어프런트에서 고객에게 덜 환불하게 되고, 한 건씩 바로잡느라 지원 인력의 시간을 씁니다.
돌아오지 않는 비용
- 정산금: 크리에이터 카탈로그나 미니 앱 호스트에서는 크리에이터 몫이 판매 시점에 지급되는 경우가 많습니다. 고객에게 환불해도 그 돈은 회수되지 않습니다.
- 콘텐츠 라이선스: 오디오북이나 강좌에 대해 권리자에게 내는 타이틀별 비용은 계약에 따라 이용 시점에 발생할 수 있고, 환불해도 되돌려지지 않습니다.
- 컴퓨팅: 해당 구매를 위해 처리한 스트리밍, 트랜스코딩, 각종 서버 작업은 이미 청구서에 올라 있습니다.
- API 호출: 음성부터 모델 추론까지 요청 단위로 과금되는 외부 서비스는 환불 후에도 과금된 그대로입니다.
한 항목만 의도했는데 전액 환불
Revoke Subscription은 애드온을 포함한 구독 전체를 환불하고 종료합니다. 고객이 애드온 하나에만 이의를 제기한다면, Request Transaction Refund로 그 SKU만 환불하고 해당 항목에만 revoke를 설정할 수 있습니다. 항목 하나에 대한 불만에 Revoke Subscription을 호출하면 기본 요금제 매출까지 돌려주게 됩니다.
기능을 켜기 전 구현 체크리스트
- Account Holder가 현재 버전의 Advanced Commerce API Addendum에 동의했는지 확인하고, 동의가 만료됐을 때 반환되는 오류에 알림을 걸어 두세요.
- 요청마다 새 requestReferenceId UUID를 생성하고, 같은 값은 시간이 초과된 호출을 재시도할 때만 다시 쓰세요.
- 환불 호출은 큐에 넣으세요. 한도는 앱당 초당 5건이며, 429 응답에는 UNIX 밀리초 단위의 Retry-After 헤더가 붙습니다.
- 샌드박스에서 SIMULATE_REFUND_DECLINE으로 거절을 테스트하고, 샌드박스 한도가 프로덕션의 10%라는 점을 기억하세요.
- refundRiskingPreference는 건마다 정하고, true로 둘 때는 12시간 응답 기한에 맞춰 소비 데이터 응답 처리를 준비해 두세요.
- 이용 권한은 REFUND 알림이 도착한 뒤, 그 revocationDate를 기준으로 종료하세요.
- 모든 요청의 사유, 금액, SKU를 기록해, Apple보다 먼저 자사의 환불률을 볼 수 있게 하세요.
자주 묻는 질문
- iOS 개발자가 고객에게 직접 환불할 수 있나요?
- 일반적인 App Store 구매라면 안 됩니다. 한 Apple 엔지니어는 2026년 6월, 개발자가 직접 환불하는 것은 불가능하다고 밝혔습니다. Advanced Commerce API 승인을 받고 Addendum에 서명한 앱은 Request Transaction Refund 엔드포인트로 환불을 요청할 수 있지만, 결정은 여전히 Apple이 합니다.
- Advanced Commerce API에서 Cancel과 Revoke는 어떻게 다른가요?
- Cancel은 자동 갱신을 끄고, 고객은 기간이 끝날 때까지 이용 권한을 유지하며 환불은 없습니다. Revoke는 구독과 그에 속한 모든 항목을 즉시 종료하고 전액 또는 일할 금액을 환불합니다. Revoke 후에는 Apple이 REFUND 알림을 보냅니다.
- Advanced Commerce API로 원하는 금액만 환불할 수 있나요?
- 네. refundType을 CUSTOM으로 설정하고 통화의 1000분의 1 단위로 refundAmount를 전달하세요. Apple에 따르면 금액에는 캐나다와 미국을 제외한 모든 지역에서 세금이 포함되어야 하며, FULL이나 PRORATED에 금액을 보내면 오류 4000155가 반환됩니다.
- 제가 직접 요청한 환불에도 CONSUMPTION_REQUEST가 오나요?
- 올 수 있습니다. refundRiskingPreference의 기본값은 true이므로 App Store는 CONSUMPTION_REQUEST를 통해 소비 데이터를 요청할 수 있고, Apple은 12시간 이내의 응답을 요구합니다. false로 설정하면 그 알림은 보내지 않는다고 Apple은 설명합니다.
- Advanced Commerce API 환불 요청이 실패한 이유는 무엇인가요?
- 오류 코드를 확인하세요. 4030021은 이미 환불된 거래, 4000181은 환불이 이미 대기 중, 4030024는 환불 불가, 4030025는 고객이 Apple 지원에 문의해야 함을 뜻합니다. Addendum에 서명하지 않았거나 버전이 오래된 경우에도 오류가 반환됩니다.
출처 및 추가 자료
- Apple Developer: Advanced Commerce API eligibility and requirements
- Advanced Commerce API: Request Transaction Refund
- Advanced Commerce API: RequestRefundItem
- Advanced Commerce API: refundRiskingPreference
- Advanced Commerce API: Revoke Subscription
- Advanced Commerce API: Rate limits
- Advanced Commerce API changelog
- App Store Server API: Send Consumption Information
- Apple Developer Forums: Refund option in App Store Server API
- Apple Developer: Mini Apps Partner Program
RefundHalt
App Store와 Google Play 환불 자동 처리
계속 읽기
과도한 환불 요청은 환불액보다 더 큰 손실을 부릅니다. 두 앱 스토어 모두 이를 품질 신호로 보기 때문입니다
Apple 가이드라인 5.6.4는 과도한 환불 요청을 앱이 품질 기준에 미달한다는 징후로 꼽고, Google의 개발자 배포 계약은 환불률을 근거로 신규 개발자의 앱을 삭제할 수 있게 합니다. 각 스토어가 무엇이라고 규정하는지, 삭제되면 무엇을 잃는지, 위험을 어떻게 피하는지 정리했습니다.
환불을 처리하기 전에 App Store 서버 알림을 검증하세요. 누구나 웹훅 URL로 요청을 보낼 수 있습니다
환불 알림은 서명을 확인하기 전까지는 하나의 HTTPS 요청에 불과합니다. App Store 서버 알림과 Google Play RTDN 메시지를 검증하는 방법, 각 스토어가 무엇에 서명하는지, 그리고 위조된 환불이나 잘못 거부된 환불이 어떤 비용을 초래하는지 설명합니다.