Tất cả bài viết
Cẩm nangĐọc trong 8 phút

Lý do hủy gói đăng ký thường đến tay bạn trước yêu cầu hoàn tiền, và Google Play cung cấp nhiều hơn Apple rất nhiều

Google Play ghi lại lý do hủy gói đăng ký từ khảo sát hủy, còn Apple chỉ gửi một mã hết hạn. Đây là những gì mỗi cửa hàng cho bạn biết, tín hiệu nào báo trước một yêu cầu hoàn tiền hoặc chargeback, và mỗi tín hiệu khiến bạn tốn bao nhiêu.

Một nhà phát triển ngồi bên bàn trong ánh sáng sớm, xem màn hình gói đăng ký trên điện thoại cạnh cuốn sổ đầy vạch đếm, đang phân loại các lý do hủy gói đăng ký

Điểm chính

  • Google Play hỏi người đăng ký vì sao họ rời đi khi họ hủy, và câu trả lời đến với nhà phát triển qua canceledStateContext.userInitiatedCancellation.cancelSurveyResult trong purchases.subscriptionsv2.
  • Khảo sát hủy của Google Play có năm câu trả lời mà nhà phát triển đọc được: dùng không đủ nhiều, sự cố kỹ thuật, liên quan đến chi phí, tìm được ứng dụng tốt hơn, và lý do khác. Văn bản tự do trong reasonUserInput chỉ có khi người dùng chọn lý do khác.
  • Thông báo SUBSCRIPTION_CANCELED từ Google Play chỉ mang purchase token. Lý do hủy phải được lấy bằng purchases.subscriptionsv2.get, và Google xóa mọi trường liên quan đến việc hủy nếu người dùng khôi phục gói đăng ký.
  • App Store Server API của Apple không có khảo sát hủy. Trường expirationIntent trả về một trong năm mã: khách hàng đã hủy, lỗi thanh toán, không đồng ý tăng giá hoặc chuyển đổi ưu đãi, sản phẩm không còn bán, hoặc lý do khác.
  • Thông báo DID_CHANGE_RENEWAL_STATUS của Apple với subtype AUTO_RENEW_DISABLED có thể có nghĩa là App Store đã tắt tự động gia hạn sau khi khách hàng yêu cầu hoàn tiền, chứ không chỉ là khách hàng tự tắt.
  • Lý do hủy không bao giờ cho nhà phát triển quyền quyết định về hoàn tiền. Chỉ có hai luồng yêu cầu bằng chứng: CONSUMPTION_REQUEST của Apple, phải trả lời trong 12 giờ, và quy trình xem xét chargeback của Google Play qua orders.reviewrefund, phải trả lời trong 24 giờ.
  • Người đăng ký Google Play hủy vì sự cố kỹ thuật là người có khả năng đòi lại tiền cao nhất. Với đơn hàng đặt sau August 3, 2026, một vụ chargeback họ thắng khiến nhà phát triển mất giá mua trừ phí dịch vụ của Play, cộng thêm phí ngân hàng.

Phần lớn người đăng ký cuối cùng được hoàn tiền đều hủy gói trước. Việc hủy đó đi kèm một lý do, và hai cửa hàng cung cấp cho bạn lượng thông tin rất khác nhau. Google Play chạy một khảo sát ngắn và chuyển câu trả lời đến máy chủ của bạn, kể cả văn bản tự do. Apple gửi một mã số cho biết gói đăng ký kết thúc như thế nào, chứ không phải vì sao khách hàng muốn rời đi. Đọc đúng cả hai, bạn sẽ thấy yêu cầu hoàn tiền đang đến khi vẫn còn kịp làm gì đó.

Google Play cho bạn biết gì về lý do hủy gói đăng ký

Khi người dùng hủy trong trung tâm gói đăng ký của Play, Google hỏi họ lý do. Câu trả lời nằm trong subscription resource mà bạn nhận được từ purchases.subscriptionsv2.get, bên dưới canceledStateContext. Object này chỉ tồn tại khi gói đăng ký ở trạng thái đã hủy hoặc đã hết hạn, và cho biết ai đã kết thúc gói: người dùng, hệ thống của Google, bạn, hoặc một thay thế như đổi gói.

Khi người dùng là người hủy, object userInitiatedCancellation có hai trường. cancelTime cho biết họ hủy lúc nào. cancelSurveyResult chứa câu trả lời khảo sát.

Lý do khảo sátMô tả của GoogleĐiều nó thường báo hiệu
CANCEL_SURVEY_REASON_NOT_ENOUGH_USAGEKhông dùng gói đăng ký đủ nhiềuMức dùng thấp, nên chi phí bỏ ra cho tài khoản ít
CANCEL_SURVEY_REASON_TECHNICAL_ISSUESSự cố kỹ thuật khi dùng ứng dụngTín hiệu hoàn tiền và chargeback mạnh nhất
CANCEL_SURVEY_REASON_COST_RELATEDVấn đề liên quan đến chi phíNhạy cảm về giá, đôi khi là lần gia hạn họ không ngờ tới
CANCEL_SURVEY_REASON_FOUND_BETTER_APPNgười dùng tìm được ứng dụng tốt hơnĐối thủ thắng, hiếm khi có tranh chấp
CANCEL_SURVEY_REASON_OTHERSLý do khácĐọc reasonUserInput, lời của chính người dùng
CANCEL_SURVEY_REASON_UNSPECIFIEDLý do khảo sát hủy không xác địnhKhông có câu trả lời để xử lý

Cột bên phải là cách chúng tôi diễn giải, không phải của Google. Hai cột đầu lấy trực tiếp từ tài liệu tham khảo API.

Thông báo không mang theo lý do

Một gói đăng ký bị hủy sẽ kích hoạt thông báo nhà phát triển theo thời gian thực SUBSCRIPTION_CANCELED, type 3. Google nói rõ các thông báo này chỉ cho biết trạng thái giao dịch đã thay đổi. Payload chỉ có purchase token và không có gì hữu ích khác, nên handler của bạn phải gọi purchases.subscriptionsv2.get để đọc câu trả lời khảo sát.

Góc nhìn trong Play Console

Bạn không cần viết code để xem số liệu tổng. Báo cáo gói đăng ký trong Play Console có thẻ Cancellations chia churn thành tự nguyện, không tự nguyện và khác, cùng thẻ Cancellation survey responses cho những người dùng chọn trả lời. Câu trả lời văn bản tự do từ người dùng chọn lý do khác có thể tải về dưới dạng CSV từ thẻ Other responses. Việc tải này cần quyền View financial data, cũng là quyền bạn cấp cho công cụ đọc đơn hàng của mình.

Apple cho bạn biết gì, và bỏ qua điều gì

Apple không chạy khảo sát hủy nào gửi kết quả về cho nhà phát triển. Trường gần nhất là expirationIntent trong thông tin gia hạn đã ký, và nó mô tả gói đăng ký kết thúc như thế nào, chứ không phải khách hàng nghĩ gì.

expirationIntentÝ nghĩa theo AppleSubtype EXPIRED tương ứng
1Khách hàng đã hủy gói đăng kýVOLUNTARY
2Lỗi thanh toán, ví dụ thông tin thanh toán không hợp lệBILLING_RETRY
3Không đồng ý với việc tăng giá hoặc chuyển đổi ưu đãi cần sự đồng ýPRICE_INCREASE
4Sản phẩm không còn bán vào lúc gia hạnPRODUCT_NOT_FOR_SALE
5Một lý do khácKhông có subtype

Mã 1 là mã duy nhất mô tả một lựa chọn của khách hàng, và nó cũng không nói gì về động cơ. Một khách hàng rời đi vì ứng dụng liên tục bị crash và một khách hàng chỉ đơn giản đã xong dự án trông giống hệt nhau.

Tín hiệu ẩn trong AUTO_RENEW_DISABLED

Có một thông báo của Apple đáng xem kỹ hơn. DID_CHANGE_RENEWAL_STATUS với subtype AUTO_RENEW_DISABLED thường có nghĩa là khách hàng đã tắt tự động gia hạn. Tài liệu của Apple bổ sung một trường hợp thứ hai: App Store cũng tắt tự động gia hạn sau khi khách hàng yêu cầu hoàn tiền.

Vậy trên iOS, một sự kiện tắt gia hạn có thể là dấu vết đầu tiên của một yêu cầu hoàn tiền. Nếu giao dịch là consumable hoặc gói đăng ký tự động gia hạn, CONSUMPTION_REQUEST có thể theo sau, và từ lúc đó bạn có 12 giờ để gửi dữ liệu tiêu thụ. Một sự kiện tắt gia hạn đến mà không có hành động nào hiển thị trong ứng dụng đáng được coi là lời cảnh báo sớm để chuẩn bị sẵn dữ liệu sử dụng của tài khoản đó.

Apple và Google đặt cạnh nhau

Google PlayApple App Store
Hỏi người dùng lý doCó, bằng khảo sát hủyKhông có khảo sát nào nhà phát triển thấy được
Lý do nằm ở đâucanceledStateContext trong purchases.subscriptionsv2expirationIntent trong thông tin gia hạn
Văn bản tự doreasonUserInput, chỉ với lý do khácKhông có
Ai đã hủyNgười dùng, hệ thống, nhà phát triển hoặc thay thếSuy ra từ mã và subtype
Thông báoSUBSCRIPTION_CANCELED, rồi gọi getDID_CHANGE_RENEWAL_STATUS, EXPIRED
Mất đi nếu người dùng đăng ký lạiCó, bị xóa khi khôi phụcThông tin gia hạn phản ánh trạng thái hiện tại
Bảng điều khiểnThẻ Cancellation survey responsesKhông có cho lý do
Những tấm thẻ khảo sát in sẵn được xếp thành từng chồng nhỏ trên bàn gỗ cạnh điện thoại và tách cà phê, giống cách một nhà phát triển nhóm các lý do hủy gói đăng ký

Khi nào việc hủy biến thành hoàn tiền

Hủy gói sẽ dừng lần thu tiền tiếp theo. Nó không trả lại lần thu gần nhất. Tiền có được trả lại hay không phụ thuộc vào luồng hoàn tiền mà khách hàng tìm đến tiếp theo, và phần lớn các luồng đó diễn ra mà không cần bạn.

  • Trên Google Play, người mua có thể tự nhận hoàn tiền trong vòng 48 giờ sau khi mua, và Google là bên quyết định.
  • Hoàn tiền qua bộ phận hỗ trợ của Google hoặc Apple do cửa hàng quyết định.
  • CONSUMPTION_REQUEST của Apple yêu cầu dữ liệu tiêu thụ của bạn, trong khung thời gian 12 giờ.
  • Quy trình xem xét chargeback của Google Play yêu cầu bằng chứng qua orders.reviewrefund, trong khung thời gian 24 giờ. Quyết định của ngân hàng về chargeback là cuối cùng.

Lý do hủy không thay đổi bất kỳ quy tắc nào trong số đó. Điều nó thay đổi là bạn biết sớm đến mức nào khách hàng nào đang không hài lòng, và bằng chứng của bạn đã sẵn sàng chưa khi một trong hai luồng yêu cầu bằng chứng xuất hiện.

Mỗi lý do khiến bạn tốn bao nhiêu

Câu trả lời khảo sát cũng là chỉ dấu sơ bộ về chi phí bạn đã bỏ ra để phục vụ một tài khoản, tức là số tiền bạn phải tự gánh sau khi hoàn tiền.

Sự cố kỹ thuật

Đây là lý do tốn kém nhất. Khách hàng đã dùng sản phẩm đủ nhiều để gặp sự cố, nên bạn đã trả tiền cho compute phía sau các phiên của họ, các lệnh gọi model API từ yêu cầu của họ, dung lượng lưu trữ cho những gì họ tạo ra, và mọi khoản chi trả cho nhà sáng tạo có nội dung họ đã dùng. Nếu sau đó họ được hoàn tiền, khoản tiền quay về họ còn các chi phí đó vẫn ở lại với bạn. Nếu họ tìm đến ngân hàng trên Google Play, một đơn hàng đặt sau August 3, 2026 khiến bạn mất giá mua trừ phí dịch vụ của Play, cộng thêm phí ngân hàng.

Liên quan đến chi phí

Một lời phàn nàn về giá khiến bạn tốn ít hơn vẻ ngoài của nó, trừ khi đằng sau là một lần gia hạn bất ngờ. Đó là câu chuyện chargeback kinh điển, vì vậy hãy kiểm tra xem việc hủy có diễn ra ngay sau một lần thu tiền gia hạn không, và lời nhắc gia hạn của bạn đã được gửi chưa.

Dùng không đủ nhiều

Mức dùng thấp nghĩa là chi phí phục vụ thấp, nên hoàn tiền ở đây chủ yếu trả lại số tiền bạn không tốn nhiều để kiếm được. Đây cũng là lý do mà dữ liệu tiêu thụ trung thực, nếu Apple yêu cầu, cho thấy chính xác khách hàng đã dùng gì và chưa dùng gì.

Tìm được ứng dụng tốt hơn

Những khách hàng này hiếm khi tranh chấp điều gì. Họ đã chuyển sang đối thủ. Lý do này hữu ích cho quyết định sản phẩm, nhưng gần như không bao giờ giúp ích cho việc bảo vệ trước hoàn tiền.

Quy trình đọc lý do hủy

  • Với mỗi SUBSCRIPTION_CANCELED từ Google Play, hãy gọi purchases.subscriptionsv2.get và lưu canceledStateContext cùng purchase token và cancelTime.
  • Lưu nguyên văn reasonUserInput khi lý do là khác. Đây là văn bản tự do duy nhất mà cả hai cửa hàng cung cấp cho bạn.
  • Với mỗi DID_CHANGE_RENEWAL_STATUS từ Apple có AUTO_RENEW_DISABLED, hãy ghi log sự kiện và lấy dữ liệu sử dụng của tài khoản đó, phòng khi CONSUMPTION_REQUEST theo sau.
  • Với mỗi thông báo EXPIRED từ Apple, hãy ghi lại subtype và expirationIntent để churn tự nguyện và lỗi thanh toán không bị lẫn vào nhau.
  • Với các lượt hủy trên Google Play nêu lý do sự cố kỹ thuật, hãy kiểm tra log lỗi của tài khoản đó và liên hệ khách hàng trước khi họ tìm đến ngân hàng.
  • Lưu log sử dụng theo từng tài khoản, để CONSUMPTION_REQUEST được trả lời trong vòng 12 giờ và quy trình xem xét chargeback trong vòng 24 giờ.

Câu hỏi thường gặp

Làm sao để biết vì sao một người đăng ký Google Play đã hủy?
Gọi purchases.subscriptionsv2.get và đọc canceledStateContext.userInitiatedCancellation.cancelSurveyResult. Trường reason chứa câu trả lời khảo sát, còn reasonUserInput chứa văn bản tự do khi người dùng chọn lý do khác. Play Console cũng hiển thị số liệu tổng trong thẻ Cancellation survey responses.
Apple có cho nhà phát triển biết vì sao khách hàng hủy gói đăng ký không?
Không. Apple không có khảo sát hủy nào mà nhà phát triển thấy được. Trường expirationIntent cho biết gói đăng ký kết thúc như thế nào, với các mã cho khách hàng đã hủy, lỗi thanh toán, không đồng ý tăng giá, sản phẩm không còn bán, hoặc lý do khác, nhưng không cho biết động cơ của khách hàng.
Thông báo SUBSCRIPTION_CANCELED có chứa lý do hủy không?
Không. Thông báo nhà phát triển theo thời gian thực của Google Play chỉ cho biết trạng thái giao dịch đã thay đổi. Hãy lấy gói đăng ký bằng purchases.subscriptionsv2.get để đọc lý do, và lưu lại ngay, vì Google xóa các trường liên quan đến việc hủy nếu người dùng khôi phục gói đăng ký.
Thông báo AUTO_RENEW_DISABLED của Apple có thể là dấu hiệu của yêu cầu hoàn tiền không?
Có. Tài liệu của Apple cho biết subtype AUTO_RENEW_DISABLED bao gồm cả trường hợp khách hàng tắt tự động gia hạn và trường hợp App Store tắt nó sau khi khách hàng yêu cầu hoàn tiền.
Tôi có thể thu hồi quyền truy cập khi người đăng ký hủy không?
Trên Google Play thì không, khi họ vẫn còn quyền sử dụng. Google cho biết người đăng ký đã hủy vẫn giữ quyền truy cập đến hết chu kỳ thanh toán, và gỡ quyền truy cập sớm là vi phạm chính sách gói đăng ký của Google Play. Hãy dùng expiryTime để quyết định khi nào quyền truy cập kết thúc.

Nguồn và tài liệu đọc thêm

RefundHalt

Chế độ tự động xử lý hoàn tiền cho App Store và Google Play

Đọc tiếp

Yêu cầu hoàn tiền tiếp theo đã đang trên đường đến.

Thiết lập RefundHalt trong khoảng thời gian bạn cần để đọc thêm một email hỗ trợ về khoản hoàn tiền mà mình chưa kịp phản biện.