Một khách hàng yêu cầu Apple hoàn tiền. Mười hai giờ sau, một khung thời gian đóng lại trên máy chủ của bạn, và hầu hết các đội ngũ thậm chí không biết nó đã từng mở.
Khung thời gian đó thuộc về Apple CONSUMPTION_REQUEST — thông báo mà App Store gửi khi cần thông tin từ bạn trong lúc đánh giá một yêu cầu hoàn tiền. Đây không phải là khoản hoàn tiền. Cũng không phải là quyết định. Dù thế nào, Apple vẫn là bên đưa ra quyết định hoàn tiền cuối cùng. Điều thông báo này mang lại cho bạn là một cơ hội có giới hạn để mô tả những gì thực sự đã diễn ra với giao dịch mua.
Xử lý tốt việc này là bài toán backend, không phải bài toán hỗ trợ khách hàng. Thông báo phải đến nơi, giao dịch phải xác định được, trạng thái đồng ý phải được biết rõ, và phản hồi phải được gửi đi kịp thời.
Bài viết này đề cập ý nghĩa của thông báo, những gì Apple hiện yêu cầu (danh sách trường dữ liệu đã ngắn hơn nhiều so với trước), và cách xây dựng quy trình xung quanh nó. Về quy trình tổng thể, hướng dẫn của chúng tôi về quản lý hoàn tiền App Store sẽ cung cấp bối cảnh.
Những điểm chính
• CONSUMPTION_REQUEST là việc Apple yêu cầu thông tin trong quá trình đánh giá hoàn tiền. Đây không phải thông báo hoàn tiền.
• Apple đưa ra quyết định hoàn tiền cuối cùng. Phản hồi của bạn chỉ là một trong nhiều yếu tố đầu vào.
• Endpoint hiện tại nhận năm trường dữ liệu, ba trong số đó là bắt buộc — giảm từ mười hai trường ở phiên bản cũ.
• Sự đồng ý là bắt buộc. Apple từ chối các yêu cầu mà customerConsented không phải là true.
• Apple yêu cầu phản hồi trong vòng 12 giờ kể từ khi có thông báo.
• Vì khung thời gian ngắn và thông báo có thể đến bất kỳ giờ nào, bước này phù hợp với tự động hóa hơn là xử lý thủ công.
Apple CONSUMPTION_REQUEST là gì?
CONSUMPTION_REQUEST là một App Store Server Notification cho bạn biết rằng một khách hàng đã yêu cầu Apple hoàn tiền, và App Store đang mời bạn gửi thông tin tiêu thụ (consumption information) về giao dịch mua đó.
Yêu cầu thông tin tiêu thụ của Apple dành cho nhà phát triển tồn tại vì có một khoảng trống thông tin. Apple thấy giao dịch, tài khoản và lịch sử mua hàng. Nhưng Apple không thể thấy điều gì đã xảy ra bên trong ứng dụng của bạn — nội dung đã được giao hay chưa, có hoạt động không, khách hàng thực sự đã dùng bao nhiêu. Bạn thì có thể.
Một điều nó không phải: quyền phủ quyết. Phản hồi không chặn được việc hoàn tiền, và Apple nói rõ rằng họ cân nhắc nhiều yếu tố khác nhau.
Apple CONSUMPTION_REQUEST hoạt động như thế nào?
Trình tự diễn ra như sau:
Khách hàng yêu cầu hoàn tiền
↓
Apple bắt đầu đánh giá yêu cầu
↓
CONSUMPTION_REQUEST đến endpoint nhận thông báo của bạn
↓
Bạn xác minh thông báo và xác định giao dịch
↓
Bạn kiểm tra sự đồng ý và thu thập dữ liệu sử dụng thực tế
↓
Bạn gửi thông tin tiêu thụ, nếu đáp ứng các yêu cầu
↓
Apple đưa ra quyết định hoàn tiền
↓
REFUND hoặc REFUND_DECLINED được gửi đến; bạn cập nhật trạng thái
Đáng lưu ý: trên endpoint hiện tại của Apple, yêu cầu hoàn tiền cho bất kỳ loại sản phẩm nào cũng có thể kích hoạt thông báo này — consumable, non-consumable, non-renewing subscription hay auto-renewable subscription. Tài liệu cũ và hầu hết các bài viết bên thứ ba vẫn mô tả nó chỉ áp dụng cho consumable và auto-renewable subscription. Nếu handler của bạn lọc theo loại sản phẩm dựa trên thông tin đó, nó đang bỏ sót yêu cầu.
Apple yêu cầu nhà phát triển cung cấp thông tin gì?
Ít hơn trước đây. Đây là phần mà hầu hết hướng dẫn hiện có đều sai, nên cần nói cho chính xác. Endpoint Send Consumption Information hiện tại của Apple nhận năm trường dữ liệu — ba bắt buộc, hai tùy chọn.
Trường | Bắt buộc | Ý nghĩa đối với bạn |
customerConsented | Có | Phải là true. Nếu không, Apple từ chối yêu cầu. |
deliveryStatus | Có | Ứng dụng của bạn có giao thành công một giao dịch mua hoạt động bình thường hay không. |
sampleContentProvided | Có | Khách hàng có nhận được nội dung dùng thử trước khi mua hay không. |
consumptionPercentage | Không | Mức độ giao dịch mua đã được tiêu thụ, tính bằng milliunit. |
refundPreference | Không | Kết quả bạn mong muốn: hoàn toàn bộ, từ chối, hoặc hoàn theo tỷ lệ. |
Hai ràng buộc thường khiến người ta mắc lỗi. Nếu deliveryStatus là bất kỳ giá trị nào khác ngoài delivered, consumptionPercentage phải bằng 0, nếu không yêu cầu sẽ thất bại. Và milliunit không phải phần trăm — tiêu thụ một nửa là 50000, không phải 50.
Tùy chọn refund preference là tính năng mới hơn và đáng để hiểu rõ. Bạn có thể cho biết mình muốn khoản hoàn tiền được chấp thuận toàn bộ, bị từ chối, hay hoàn theo tỷ lệ. Đây là mong muốn, không phải chỉ thị — Apple cân nhắc nó cùng mọi yếu tố khác, và kết quả có thể khác với những gì bạn đề xuất.
Nếu Apple chấp thuận hoàn tiền theo tỷ lệ, phần bị thu hồi sẽ được trả về trong payload giao dịch, nên logic cấp quyền truy cập (entitlement) của bạn có thể cần xử lý thu hồi một phần thay vì coi mọi khoản hoàn tiền là toàn bộ hoặc không gì cả.
Tại sao Apple cần thông tin tiêu thụ?
Vì Apple đang quyết định một việc mà họ chỉ nhìn thấy một phần.
Apple biết cái gì được mua, khi nào, bởi tài khoản nào, và lịch sử tài khoản đó ra sao. Apple không biết máy chủ của bạn đã giao số coin hay chưa, tính năng được mở khóa có hoạt động không, hay khách hàng đã dùng sản phẩm rất nhiều trước khi đòi lại tiền. Bối cảnh đó nằm trong hệ thống của bạn.
Luồng hoàn tiền CONSUMPTION_REQUEST của Apple là cách Apple thu thập bối cảnh đó trước khi quyết định. Đó cũng là lý do tính chính xác quan trọng hơn việc biện hộ. Dữ liệu mô tả những gì đã xảy ra. Nó không phải là một vụ tranh luận để bạn thắng, và coi nó như vậy mang lại rủi ro thực sự mà không có lợi ích chắc chắn.
Cách nhà phát triển phản hồi CONSUMPTION_REQUEST
Tám bước. Phần lớn công việc diễn ra trước khi bất kỳ yêu cầu nào đến.
1. Nhận thông báo
Thông báo App Store CONSUMPTION_REQUEST được gửi đến URL máy chủ mà bạn cấu hình cho App Store Server Notifications V2. Nếu endpoint đó thiếu, chưa được xác minh, hoặc lỗi âm thầm, yêu cầu sẽ không bao giờ đến được với bạn. Tài liệu App Store Server Notifications của Apple hướng dẫn cách thiết lập và định dạng payload.
2. Xác minh thông báo
Thông báo đến dưới dạng payload JWS đã ký. Hãy xác minh chữ ký dựa trên chuỗi chứng chỉ của Apple trước khi xử lý bất cứ nội dung nào bên trong, và kiểm tra bundle ID có khớp với ứng dụng của bạn không. Một endpoint không xác minh, chấp nhận mọi thứ được gửi tới, là cách để người khác điều khiển logic hoàn tiền của bạn.
3. Xác định giao dịch
Payload sau khi giải mã chứa các mã định danh giao dịch. Bạn cần có bản ghi mua hàng đã lưu để đối chiếu. Không có bản ghi thì không tra cứu được — và không có cách nào nói điều gì hữu ích về mức tiêu thụ.
4. Khớp giao dịch với đúng người dùng
Bạn không thể mô tả mức sử dụng của khách hàng khi chưa biết đó là khách hàng nào. Việc ánh xạ đó chính là lý do appAccountToken tồn tại: một UUID mà ứng dụng của bạn gắn vào lúc mua, và được trả về trong payload thông báo. Không có nó, các đội ngũ phải khớp dựa trên thời điểm và phỏng đoán, vừa chậm vừa không đáng tin cậy đúng vào lúc tốc độ là điều quan trọng nhất.
5. Kiểm tra các yêu cầu về sự đồng ý được áp dụng
Apple rất rõ ràng ở điểm này: bạn phải có được sự đồng ý hợp lệ trước khi chia sẻ dữ liệu của khách hàng, và việc thu thập sự đồng ý đó là trách nhiệm của bạn, không phải của Apple. Thông báo không chứa cờ đồng ý nào, nên bạn phải biết điều đó từ hồ sơ của chính mình.
Nếu khách hàng chưa đồng ý, hướng dẫn của Apple là không phản hồi gì cả. Gửi yêu cầu với consent đặt là false không có tác dụng — App Store sẽ từ chối. Apple cũng nói rõ rằng lời nhắc App Tracking Transparency không phải là cơ chế cho việc này; đây là một sự đồng ý riêng biệt, được thu thập trong ứng dụng của bạn.
6. Thu thập thông tin sử dụng thực tế
Lấy trạng thái giao hàng và mức tiêu thụ từ hồ sơ thực tế của bạn. Nếu máy chủ của bạn theo dõi số dư consumable, bạn đã biết bao nhiêu đã được tiêu. Nếu việc mở khóa tính năng thất bại, log của bạn cũng biết điều đó. Đừng ước lượng — một con số tiêu thụ bịa ra là dữ liệu không chính xác gửi cho Apple dưới sự đồng ý mà bạn đã xin cho dữ liệu chính xác.
7. Gửi thông tin phù hợp
Phản hồi bằng một lệnh PUT tới endpoint consumption, dùng mã định danh giao dịch gốc từ thông báo. Hãy xử lý các phản hồi lỗi thay vì gửi rồi bỏ mặc: lỗi xác thực trả về HTTP 400 kèm loại lỗi cụ thể, và một lệnh gọi thất bại âm thầm trông y hệt một lệnh gọi thành công nếu không ai kiểm tra.
8. Ghi lại kết quả
Ghi log yêu cầu, giao dịch, nội dung bạn đã gửi, thời điểm gửi, và quyết định cuối cùng của Apple. Bản ghi đó là thứ giúp bạn trả lời câu hỏi hỗ trợ nhiều tuần sau, nhận ra các mẫu hình giữa các khoản hoàn tiền, và xác nhận trạng thái quyền truy cập của bạn là đúng. Khi khoản hoàn tiền được chấp thuận, hãy thu hồi quyền truy cập sau khi hoàn tiền — và sẵn sàng khôi phục nếu sau đó Apple đảo ngược quyết định.
Điều gì xảy ra nếu nhà phát triển bỏ lỡ CONSUMPTION_REQUEST?
Không có gì kịch tính, và đó chính là một phần của vấn đề.
Bỏ lỡ phản hồi nghĩa là bạn không cung cấp thông tin bổ sung mà Apple cho phép bạn gửi trong quy trình đó. Apple vẫn quyết định. Khoản hoàn tiền vẫn có thể được chấp thuận hoặc từ chối dựa trên thông tin Apple đã có. Không có lỗi, không có cảnh báo, và không có dấu hiệu rõ ràng nào cho thấy đã bỏ sót điều gì.
Những cách bỏ lỡ đều rất đời thường. Thông báo đến lúc 2 giờ sáng. Kỹ sư phụ trách handler đang nghỉ. Việc tra cứu giao dịch kéo dài vì mã định danh nằm ở một hệ thống còn dữ liệu sử dụng ở hệ thống khác. Ai đó nhìn thấy vào thứ Hai, rất lâu sau khi khung thời gian đã đóng.
Tại sao xử lý CONSUMPTION_REQUEST thủ công lại khó
Mọi ràng buộc trong quy trình này đều không có lợi cho xử lý thủ công.
Thông báo đến suốt ngày đêm. Khung thời gian là 12 giờ. Mỗi yêu cầu cần tra cứu giao dịch, khớp người dùng, kiểm tra sự đồng ý, tính toán mức sử dụng, một lệnh gọi API có ký, và một kết quả được ghi log — bảy bước, không bước nào thú vị, tất cả đều bị giới hạn thời gian.
Với một yêu cầu mỗi tuần, đó là chuyện phiền toái. Với ba mươi yêu cầu mỗi ngày, đó là công việc của một người — công việc không tạo ra gì khi làm tốt và gây thất thoát âm thầm khi làm muộn.
Tự động hóa thay đổi quy trình hoàn tiền như thế nào
Tự động hóa không cho bạn quyền tác động lên Apple. Điều này đáng nhắc lại, vì không ít nội dung marketing ngụ ý điều ngược lại. Quyết định của Apple vẫn là của Apple.
Điều tự động hóa làm được là khiến phía bạn trở nên nhất quán. Thông báo được giám sát và xác minh. Các yêu cầu liên quan được tách khỏi phần còn lại của luồng. Giao dịch được khớp với tài khoản. Dữ liệu phản hồi được tổng hợp từ hồ sơ thực, thời hạn được theo dõi, phản hồi được gửi và ghi log, và kết quả được đưa vào cập nhật quyền truy cập.
Không bước nào trong số đó cần đến phán đoán. Tất cả đều cần sự chú ý đúng thời điểm, điều mà phần mềm làm tốt hơn con người.
Phần mềm quản lý hoàn tiền App Store nên xử lý những gì?
Nếu bạn đang đánh giá phần mềm quản lý hoàn tiền App Store, câu hỏi hữu ích là liệu nó có lấp được những khoảng trống cụ thể nêu trên hay không.
Nó nên giám sát và xác minh App Store Server Notifications, để sự kiện không biến mất vào một endpoint đang lỗi. Nó nên theo dõi riêng các sự kiện CONSUMPTION_REQUEST, vì chúng cần cách xử lý khác với kết quả hoàn tiền. Nó nên khớp giao dịch với tài khoản, vì đó là nơi ngốn thời gian thủ công. Nó nên theo dõi khung thời gian phản hồi, vì đó là thời hạn mọi người hay bỏ lỡ.
Ngoài ra: quy trình dữ liệu tiêu thụ tôn trọng trạng thái đồng ý, lịch sử hoàn tiền có thể tìm kiếm, theo dõi kết quả, đồng bộ quyền truy cập bao gồm cả thu hồi một phần, và báo cáo đủ rõ ràng để thấy các mẫu hình. Điều quan trọng là độ bao phủ quy trình, không phải độ dài danh sách tính năng.
Các quy tắc này được ghi ở đâu
Ba nguồn tài liệu của Apple bao trùm mọi điều ở trên. Hãy đọc trực tiếp — lĩnh vực này mới thay đổi gần đây, và nhiều nội dung thứ cấp đang mô tả một phiên bản cũ của API.
Send Consumption Information — endpoint hiện tại. Đề cập yêu cầu về sự đồng ý, khung 12 giờ, body yêu cầu gồm năm trường, và việc thông tin tiêu thụ áp dụng cho mọi loại sản phẩm. Đây là endpoint cần xây dựng theo cho In-App Purchase tiêu chuẩn.
App Store Server Notifications — cách thông báo đến backend của bạn, định dạng payload đã ký, và các loại thông báo, bao gồm CONSUMPTION_REQUEST, REFUND và REFUND_DECLINED.
Send Consumption Information V1 — endpoint cũ hơn, với body yêu cầu mười hai trường mà một số đội ngũ vẫn đang kết nối. Ghi chú của chính Apple trên trang đó hướng In-App Purchase tiêu chuẩn sang endpoint hiện tại, và giới hạn V1 cho các giao dịch mua dùng Advanced Commerce API. Hữu ích để xác định tích hợp của bạn đang dùng endpoint nào, chứ không phải mục tiêu để xây dựng theo.
Lời kết
CONSUMPTION_REQUEST không phải quyết định hoàn tiền của Apple. Đó là một cơ hội ngắn, có giới hạn thời gian, để nói với Apple những gì hệ thống của bạn biết mà Apple thì không.
Một quy trình xử lý đáng tin cậy cần endpoint thông báo đã xác minh, giao dịch bạn có thể xác định, khách hàng bạn có thể ánh xạ, sự đồng ý bạn thực sự đã thu thập, dữ liệu sử dụng thực, phản hồi trong khung thời gian, và kết quả được ghi lại đủ tốt để cập nhật quyền truy cập sau đó.
Nếu bạn chỉ làm một việc sau khi đọc bài này, hãy kiểm tra xem tích hợp của bạn đang gọi endpoint nào. Nếu nó vẫn gửi mười hai trường tới đường dẫn V1 cho In-App Purchase tiêu chuẩn, đó là khoảng trống đáng đóng lại đầu tiên.
Nếu khối lượng hoàn tiền đã vượt quá khả năng xử lý thủ công
Khi hoạt động hoàn tiền đủ thường xuyên đến mức theo dõi thông báo bằng tay không còn thực tế, một hệ thống chuyên dụng có thể giám sát sự kiện, chuẩn bị và gửi phản hồi trong khung thời gian, theo dõi kết quả, và giữ quyền truy cập luôn đồng bộ. RefundSensor tự động hóa phía nhà phát triển trong quy trình đó — không phải quyết định của Apple, chỉ phần bạn chịu trách nhiệm.
Câu hỏi thường gặp
Đây là một App Store Server Notification cho máy chủ của bạn biết rằng một khách hàng đã yêu cầu hoàn tiền và Apple có thể muốn nhận thông tin tiêu thụ. Đây không phải là quyết định hoàn tiền.
Apple gửi thông báo này sau khi khách hàng yêu cầu hoàn tiền, trong lúc Apple đang xem xét yêu cầu đó. Nó có thể áp dụng cho nhiều loại sản phẩm khác nhau trên App Store.
Máy chủ của bạn nhận và xác minh thông báo, xác định giao dịch và khách hàng, kiểm tra sự đồng ý, rồi gửi thông tin tiêu thụ cần thiết cho Apple trong khung thời gian phản hồi.
Xác minh thông báo, kiểm tra sự đồng ý của khách hàng, cung cấp dữ liệu sử dụng và giao hàng chính xác, gửi cho Apple, và lưu lại bản ghi về phản hồi cùng kết quả cuối cùng.
Tài liệu hiện tại của Apple quy định khung thời gian phản hồi là 12 giờ. Nhà phát triển nên kiểm tra yêu cầu mới nhất của Apple trước khi triển khai.
Đây là thông tin về cách khách hàng đã sử dụng giao dịch mua. Tùy theo endpoint hiện tại, nó có thể bao gồm sự đồng ý, trạng thái giao hàng, nội dung dùng thử, dữ liệu tiêu thụ và kết quả hoàn tiền mong muốn.
Không. Apple đưa ra quyết định cuối cùng. Nhà phát triển có thể cung cấp thông tin tiêu thụ và nêu mong muốn về việc hoàn tiền, nhưng Apple là bên quyết định sau cùng.
Có. Nhà phát triển có thể tự động hóa việc xác minh thông báo, khớp giao dịch, kiểm tra sự đồng ý, chuẩn bị dữ liệu, theo dõi thời hạn và ghi log phản hồi.






