Hãy hình dung thế này. Một khách hàng mua gói hàng năm của bạn, sử dụng được một tuần, rồi yêu cầu Apple hoàn tiền. Bạn chỉ biết được điều này khi khoản thanh toán của mình bị giảm. Không ai hỏi ý kiến bạn cả. Ít nhất là có vẻ như vậy.
Thực ra, Apple thường có hỏi. Apple gửi đến máy chủ của bạn một thông báo gọi là CONSUMPTION_REQUEST, và muốn biết khách hàng đã thực sự sử dụng sản phẩm họ mua như thế nào. Nếu máy chủ của bạn không lắng nghe, Apple sẽ tự quyết định mà không có bạn. Hướng dẫn này sẽ trình bày từng bước quy trình hoàn tiền trên App Store dành cho nhà phát triển, đồng thời chỉ ra những điểm mà mọi người thường gặp vướng mắc. Để có cái nhìn rộng hơn về việc bảo vệ trước yêu cầu hoàn tiền trên iOS, trang bảo vệ hoàn tiền App Store của RefundSensor cũng đề cập đến vấn đề này.
Câu trả lời nhanh
Thông báo CONSUMPTION_REQUEST là cách Apple yêu cầu thông tin chi tiết về việc sử dụng khi khách hàng yêu cầu hoàn tiền. Nếu khách hàng đã đồng ý chia sẻ dữ liệu, máy chủ của bạn nên gọi Send Consumption Information Axz`PI trong vòng 12 giờ và báo cáo thông tin về việc giao hàng và sử dụng. Apple sẽ cân nhắc thông tin đó và đưa ra quyết định cuối cùng. Bạn không thể phê duyệt khoản hoàn tiền hay đảm bảo kết quả.
Apple CONSUMPTION_REQUEST là gì?
CONSUMPTION_REQUEST là một loại thông báo trong App Store Server Notifications V2. Apple gửi thông báo này mỗi khi khách hàng bắt đầu một yêu cầu hoàn tiền, và nó áp dụng cho mọi loại sản phẩm: hàng tiêu dùng (consumables), hàng không tiêu dùng (non-consumables), gói đăng ký không tự động gia hạn (non-renewing subscriptions), và gói đăng ký tự động gia hạn (auto-renewable subscriptions).
Hãy xem đây là một câu hỏi, không phải một mệnh lệnh. Apple không yêu cầu bạn hoàn tiền cho ai cả. Apple chỉ đang hỏi những gì bạn biết. Apple vẫn là bên đưa ra quyết định cuối cùng, và câu trả lời của bạn chỉ là một trong những yếu tố được xem xét.
Quy trình hoàn tiền của Apple hoạt động như thế nào
Có hai việc xảy ra ở đây, và mọi người thường nhầm lẫn giữa chúng. Việc nhận thông báo diễn ra tự động. Việc gửi lại thông tin sử dụng chỉ xảy ra nếu máy chủ của bạn thực hiện điều đó.
Khách hàng yêu cầu Apple hoàn tiền.
Apple gửi một CONSUMPTION_REQUEST đến URL thông báo V2 của bạn.
Máy chủ của bạn kiểm tra xem khách hàng đó có đồng ý chia sẻ dữ liệu sử dụng hay không.
Nếu có, máy chủ của bạn sẽ gửi thông tin chi tiết về việc sử dụng trong vòng 12 giờ.
Apple đưa ra quyết định. Nếu chấp thuận hoàn tiền, một thông báo REFUND sẽ được gửi tiếp theo.
Hướng dẫn triển khai từng bước
Dưới đây là quy trình thiết lập từ đầu đến cuối.
Thêm URL thông báo của bạn. Trong App Store Connect, nhập URL HTTPS của máy chủ bạn và chọn Version 2.
Phản hồi nhanh. Trả lời với mã trạng thái từ 200 đến 206. Mã 40x hoặc 50x sẽ khiến Apple thử lại.
Kiểm tra chữ ký. Các payload V2 đều được ký. Hãy xác minh trước khi đọc bất kỳ nội dung nào bên trong.
Xác định khách hàng. Đối chiếu giao dịch với một người dùng trong cơ sở dữ liệu riêng của bạn.
Kiểm tra sự đồng ý. Không có sự đồng ý, không phản hồi.
Gọi API. Gửi dữ liệu bằng một yêu cầu App Store Server API, được xác thực bằng khóa In-App Purchase từ App Store Connect.
Ghi lại. Lưu lại thông tin về những gì bạn đã gửi và thời điểm gửi.
Cách phản hồi yêu cầu hoàn tiền của Apple với tư cách nhà phát triển
Luôn bắt đầu bằng việc kiểm tra sự đồng ý. Sau đó, hãy cho Apple biết điều gì thực sự đã xảy ra. Giá trị ở đây đến từ dữ liệu cụ thể, trung thực, vì vậy đừng thổi phồng nó.
Hãy xét hai trường hợp.
Một người chơi mua một gói xu và tiêu gần hết trong một ngày. Hãy báo cáo mức sử dụng cao này. Yêu cầu Apple từ chối hoàn tiền là một lựa chọn hợp lý.
Một người đăng ký thanh toán cho một năm, nhưng máy chủ của bạn gặp sự cố và nội dung không bao giờ tải được. Hãy báo cáo rằng nội dung chưa được giao. Trong trường hợp này, chấp thuận hoàn tiền có thể là câu trả lời trung thực.
Lựa chọn hoàn tiền bạn đề xuất chỉ là một gợi ý. Apple không bắt buộc phải làm theo.
Giải thích Apple Send Consumption Information API
Send Consumption Information endpoint là một yêu cầu PUT gắn với một transaction ID (/inApps/v2/transactions/consumption/{transactionId}). Bạn gọi endpoint này sau khi nhận được CONSUMPTION_REQUEST, và Apple muốn nhận phản hồi trong vòng 12 giờ.
Nội dung là một đối tượng ConsumptionRequest gồm năm trường:
customerConsented: khách hàng có đồng ý chia sẻ dữ liệu không? Giá trị này phải là true. Nếu không, Apple sẽ từ chối yêu cầu với lỗi HTTP 400.
deliveryStatus: ứng dụng của bạn có giao thành công giao dịch mua hàng không?
sampleContentProvided: bạn có cung cấp bản dùng thử hoặc mẫu miễn phí trước đó không?
consumptionPercentage: mức độ đã sử dụng, tính theo milliunit.
refundPreference: kết quả mà bạn mong muốn.
Có một vài quy tắc khiến nhiều người mắc lỗi. Nếu deliveryStatus không phải là DELIVERED, hãy đặt consumptionPercentage thành 0, nếu không yêu cầu sẽ thất bại. Đối với gói đăng ký tự động gia hạn có GRANT_PRORATED, hãy bỏ qua consumptionPercentage, vì Apple sẽ tự tính toán giá trị này. Và việc xin sự đồng ý là trách nhiệm của bạn. Apple cũng nói rõ không được dùng lời nhắc App Tracking Transparency cho việc này.
Tích hợp App Store Server Notifications V2
App Store Server Notifications V2 là cách Apple liên lạc với máy chủ của bạn. Bạn sẽ cần một URL HTTPS bảo mật hỗ trợ TLS 1.2 trở lên.
CONSUMPTION_REQUEST chỉ là một trong nhiều loại thông báo. Những loại khác, chẳng hạn như REFUND và REFUND_REVERSED, cho bạn biết một trường hợp đã kết thúc như thế nào. Hãy dành riêng một trình xử lý cho từng loại để mã xử lý hoàn tiền không bị rối với mã xử lý gia hạn. Muốn xem phía App Store Connect hoạt động thực tế? Hướng dẫn thiết lập Apple của Refund Sensor đề cập đến các khóa và URL thông báo.
Những lỗi thường gặp cần tránh
Dừng lại ở bước nhận thông báo. Một CONSUMPTION_REQUEST không có tác dụng gì cho đến khi máy chủ của bạn gửi dữ liệu phản hồi.
Bỏ qua việc xin sự đồng ý. Không có sự đồng ý từ khách hàng nghĩa là không phản hồi.
Bỏ lỡ mốc 12 giờ. Những thông báo này thường đến vào ban đêm và cuối tuần. Hãy dùng hàng đợi (queue) và thiết lập cảnh báo.
Gửi các tổ hợp dữ liệu không hợp lệ. Một tỷ lệ sử dụng cho giao dịch mua chưa được giao sẽ bị từ chối.
Bỏ qua việc kiểm tra chữ ký. Hãy xác minh trước, tin tưởng sau.
Phản hồi chậm. Hãy trả về mã thành công nhanh chóng và xử lý các tác vụ nặng ở chế độ nền, nếu không Apple sẽ tiếp tục thử lại.
Không có cách xác định người dùng. Nếu bạn không thể liên kết một giao dịch với một khách hàng, bạn sẽ không có gì thực sự để báo cáo.
Cách tự động hóa quy trình hoàn tiền trên App Store
Không ai muốn ngồi canh đồng hồ 12 giờ bằng tay. Nếu bạn muốn tự động hóa quy trình hoàn tiền trên App Store, hãy chia công việc thành các phần nhỏ:
Nhận thông báo và trả về mã thành công ngay lập tức.
Đưa sự kiện vào một hàng đợi (queue).
Một worker sẽ xác minh sự kiện, tìm người dùng, và kiểm tra sự đồng ý.
Worker xây dựng yêu cầu từ dữ liệu sử dụng đã lưu trữ và gọi API.
Ghi lại kết quả, và cảnh báo cho ai đó nếu xảy ra lỗi.
Bạn sẽ có được những phản hồi nhất quán, một quy trình kiểm toán rõ ràng, và không ai phải thức dậy lúc 3 giờ sáng. Bạn có thể tự xây dựng quy trình này, hoặc giao toàn bộ pipeline cho một dịch vụ như RefundSensor.
Phương pháp hay nhất dành cho nhà phát triển
Lưu trữ dữ liệu sử dụng thực tế: phiên làm việc (sessions), số credit đã dùng, nội dung đã mở. Bạn không thể báo cáo những con số mà bạn chưa từng lưu lại.
Thêm một bước xin sự đồng ý rõ ràng vào điều khoản sử dụng hoặc quy trình onboarding, và ghi lại thời điểm sự đồng ý được đưa ra.
Viết ra quy tắc hoàn tiền của bạn một lần và đưa vào code, thay vì quyết định theo từng trường hợp riêng lẻ.
Kiểm thử bằng các thông báo sandbox trước khi triển khai thực tế.
Gắn một account token vào mỗi giao dịch mua để bạn có thể xác định người mua sau này. Hướng dẫn appAccountToken này giải thích cách thực hiện.
Xem lại kết quả hoàn tiền mỗi tháng một lần. Những đợt tăng bất thường có thể là dấu hiệu của một tính năng bị lỗi hoặc một paywall gây khó hiểu.
Kết luận
Quy trình hoàn tiền của Apple gồm hai phần. Apple gửi CONSUMPTION_REQUEST, và bạn lựa chọn có phản hồi hay không. Nếu khách hàng đã đồng ý, hãy gửi dữ liệu trung thực qua Send Consumption Information API trong vòng 12 giờ. Apple vẫn là bên quyết định cuối cùng.
Một bước khởi đầu tốt: xác nhận URL thông báo V2 của bạn đang hoạt động và máy chủ của bạn có thể đối chiếu một giao dịch với một người dùng. Hai bước kiểm tra này sẽ giúp bạn tránh được rất nhiều rắc rối về sau.
Câu hỏi thường gặp
Đây là một thông báo V2 mà Apple gửi khi khách hàng yêu cầu hoàn tiền. Nó yêu cầu bạn cung cấp thông tin chi tiết về việc sử dụng.
Apple yêu cầu phản hồi trong vòng 12 giờ kể từ khi nhận được thông báo.
Có. Nếu không có sự đồng ý, đừng phản hồi. Một yêu cầu có customerConsented được đặt thành bất kỳ giá trị nào khác true sẽ bị từ chối.
Không nhất thiết. Apple sử dụng dữ liệu của bạn để tham khảo khi ra quyết định, nhưng chính Apple mới là bên quyết định.
Hàng tiêu dùng (consumables), hàng không tiêu dùng (non-consumables), gói đăng ký không tự động gia hạn (non-renewing subscriptions), và gói đăng ký tự động gia hạn (auto-renewable subscriptions).



