Refund Abuse & Fraud Prevention

Người hoàn tiền nhiều lần khiến bạn mất tiền hai lần, và cả hai cửa hàng đều trao cho bạn công cụ để phát hiện họ

Một người yêu cầu hoàn tiền lần thứ tư không phải là khách hàng không hài lòng, họ đang thực hiện một quy trình lặp lại, và điều đó khiến bạn mất cả doanh thu bị hoàn lại cộng với toàn bộ chi phí bạn đã bỏ ra để thực hiện đơn hàng. Apple và Google đều cung cấp một trường định danh giúp biến những sự việc riêng lẻ đó thành một mô hình có thể nhìn thấy được.

5 min read
Người hoàn tiền nhiều lần khiến bạn mất tiền hai lần, và cả hai cửa hàng đều trao cho bạn công cụ để phát hiện họ

Một người yêu cầu hoàn tiền lần thứ tư không phải là khách hàng không hài lòng. Họ đang thực hiện một quy trình lặp lại, và điều đó khiến bạn mất doanh thu bị hoàn lại cộng với toàn bộ chi phí bạn đã bỏ ra để thực hiện đơn hàng. Apple và Google đều cung cấp một trường định danh, appAccountToken ở một phía và obfuscated account ID ở phía còn lại, giúp biến những sự việc riêng lẻ đó thành một mô hình có thể nhìn thấy được.

Những điểm chính cần nắm

  • Bằng chứng từ bạn chỉ đến được cửa hàng trong đúng hai trường hợp: CONSUMPTION_REQUEST của Apple, có thể trả lời trong vòng 12 giờ, và chargeback review của Google Play qua Review Refund API, có thể trả lời trong vòng 24 giờ. Mọi trường hợp khác đều được quyết định mà không có sự tham gia của bạn.

  • Trên Apple, một UUID do bạn tạo ra sẽ đi kèm với giao dịch mua dưới dạng appAccountToken. StoreKit gắn nó vào giao dịch, nghĩa là bất kỳ lần hoàn tiền nào sau đó cũng sẽ khớp với một tài khoản có thể xác định được trong bản ghi của riêng bạn.

  • Trường tương ứng của Google là một chuỗi đã băm không dài hơn 64 ký tự. Chính Google đọc trường này, dùng nó để phát hiện hành vi bất thường, chẳng hạn như một tài khoản duy nhất mua hàng trên một số lượng thiết bị phi lý trong một khoảng thời gian ngắn.

  • Dữ liệu cá nhân dạng văn bản thuần trong trường của Google sẽ khiến giao dịch mua bị chặn ngay lập tức. Yêu cầu bắt buộc là một giá trị đã mã hóa hoặc một mã băm một chiều. Một địa chỉ email thô thì không đáp ứng được điều đó.

  • voidedReason của Play phân biệt friendly_fraud và fraud với một trường hợp hoàn tiền thông thường do đổi ý, điều này cho bạn cơ sở để đưa những kẻ tái phạm vào hàng đợi xét duyệt (review queue) thay vì theo hướng mặc định là hoàn tiền rồi bỏ qua.

  • Google báo cáo đã chặn hơn 2 tỷ đô la các giao dịch gian lận và lạm dụng trong năm 2022. Những cơ chế bảo vệ đó hoạt động dựa trên các tín hiệu định danh, mà những tín hiệu này chỉ tồn tại nếu giao dịch mua của bạn mang theo chúng.

  • Quyền truy cập vẫn tồn tại sau khi hoàn tiền sẽ tiếp tục tiêu tốn dung lượng lưu trữ, năng lực tính toán và ngân sách API mà bạn không còn được trả tiền cho, và một người cố tình hoàn tiền chính là đang tạo ra kết quả đó một cách có chủ ý, lặp đi lặp lại.

Giới thiệu

Hoàn tiền là điều vẫn xảy ra, và một lần hoàn tiền đơn thuần chỉ là chi phí vận hành. Điều làm thay đổi cục diện là khi cùng một tài khoản quay lại lần thứ tư, sau khi đã tiêu dùng hàng hóa ở mỗi lần trước đó. Hành vi đó chỉ có thể nhận ra được nếu mọi giao dịch đều mang theo một định danh do bạn gán. Cả hai nền tảng đều cung cấp một định danh như vậy. Cả hai cũng mở ra một khung thời gian phản hồi hẹp trước khi kết quả được quyết định. Nếu bỏ qua định danh, hoặc lỡ mất khung thời gian đó, một người đang lợi dụng hệ thống sẽ không thể phân biệt được với một người lần đầu khiếu nại chính đáng. Điều gì phân biệt hai trường hợp này, và giá trị của sự phân biệt đó bằng tiền là bao nhiêu, sẽ được trình bày tiếp theo.

Lạm dụng hoàn tiền thực chất là một vấn đề định danh đội lốt hoàn tiền

Quyết định hoàn tiền thuộc về cửa hàng. Khách hàng sẽ yêu cầu, và trong hầu hết các luồng, cửa hàng sẽ đồng ý, mà không có sự tham gia nào từ bạn. Ảnh hưởng của bạn nằm ở chỗ khác: xác định liệu tài khoản cụ thể này có lịch sử làm việc này hay không, và liệu thứ họ đã mua có thực sự được giao và được sử dụng hay không. Cả hai câu hỏi đều là câu hỏi về định danh. Người dùng nào đứng sau giao dịch này, và họ đã làm gì trước đó. Những giao dịch mua không mang theo liên kết ổn định nào tới bản ghi người dùng của bạn khiến cả hai câu hỏi đều không thể trả lời, vì vậy mọi lần hoàn tiền đều diễn ra mà thiếu đi ngữ cảnh.

Đó là khoảng trống đáng để lấp đầy. Chính sách quy định cơ chế vận hành, và bạn không thể thay đổi chúng. Tuy nhiên, bằng chứng là thứ do bạn thu thập, và việc thu thập đó bắt đầu từ lúc thanh toán chứ không phải lúc hoàn tiền.

Hai khung thời gian mà những gì bạn gửi thực sự có ý nghĩa

Chỉ có hai luồng coi đầu vào của bạn là đầu vào thực sự. Khi khách hàng yêu cầu hoàn tiền cho một mặt hàng tiêu dùng hoặc một gói đăng ký tự động gia hạn, điều này sẽ kích hoạt CONSUMPTION_REQUEST của Apple, và bạn phải trả lời trong vòng 12 giờ. Khi khách hàng tranh chấp một giao dịch với ngân hàng của họ, điều này sẽ kích hoạt chargeback review của Google Play, có thể trả lời qua Review Refund API trong vòng 24 giờ. Ngoài hai trường hợp đó, quyết định diễn ra mà không có bạn: hoàn tiền tự phục vụ trong 48 giờ của Play, hoàn tiền do bộ phận hỗ trợ cấp, hoàn tiền tự động cho một giao dịch mua mà bạn chưa từng xác nhận.

Cả hai kênh này đều trở nên sắc bén hơn đáng kể khi giao dịch đã mang theo định danh của bạn. Thông tin tiêu dùng (consumption information) gửi cho Apple có thể bao gồm appAccountToken bên cạnh lịch sử chi tiêu của tài khoản đó, trong khi review của Google dựa trên một obfuscated account ID mà họ đã theo dõi từ khi giao dịch mua hoàn tất. Nơi không có định danh, sẽ không có lịch sử nào để gửi.

So sánh hai trường định danh

Cả hai công ty đều đi đến những giải pháp gần như giống nhau, dưới những tên gọi và những ràng buộc khác nhau. Mỗi giải pháp cho phép bạn gắn vào giao dịch mua một giá trị có thể khớp ngược lại với bản ghi người dùng của riêng bạn. Không giải pháp nào được kích hoạt sẵn cho bạn. Cả hai đều vô dụng nếu không được đặt vào đúng lúc giao dịch mua đang diễn ra.

Apple: appAccountToken

Tạo một UUID, truyền nó khi giao dịch mua bắt đầu, và StoreKit sẽ gắn nó vào giao dịch được tạo ra. Sau đó nó xuất hiện trong dữ liệu giao dịch mà server của bạn xác minh, và lại xuất hiện lần nữa trong thông tin tiêu dùng mà bạn trả về trong một CONSUMPTION_REQUEST. Vì giá trị này bắt nguồn từ chính bạn, nó khớp một giao dịch của cửa hàng với một dòng dữ liệu trong cơ sở dữ liệu mà không liên quan đến bất kỳ tên hay email nào. Chỉ chấp nhận UUID thật; bất cứ thứ gì khác sẽ bị từ chối. Apple sau đó đã ra mắt một endpoint Set App Account Token có khả năng ghi hoặc cập nhật token trên các giao dịch đã xảy ra từ trước, bao gồm cả việc đổi mã ưu đãi (offer-code redemptions) và các giao dịch mua ngoài ứng dụng tương tự.

Google Play: the obfuscated account ID

setObfuscatedAccountId là phiên bản của Google, một chuỗi tùy chọn gắn với tài khoản mua hàng. Tài liệu của Google nêu rõ mục đích của nó mà không vòng vo: Play sử dụng giá trị này để phát hiện hoạt động bất thường, với ví dụ được đưa ra là nhiều thiết bị thực hiện giao dịch trên một tài khoản trong một khoảng thời gian ngắn, và để chặn một số giao dịch gian lận trước khi chúng hoàn tất. Giới hạn là 64 ký tự, và dữ liệu cá nhân dạng văn bản thuần bị cấm. Đặt một email thô vào đó và giao dịch mua sẽ bị chặn, vì trường này yêu cầu một giá trị đã mã hóa hoặc một mã băm một chiều. Các ứng dụng mà một tài khoản chứa nhiều hồ sơ (profile) sẽ có một trường đi kèm, setObfuscatedProfileId.

  • appAccountToken là trường của Apple. Nó phải là một UUID và không thể là gì khác, mã của bạn đặt giá trị này trong lúc thanh toán, và nó sẽ không xuất hiện trừ khi bạn thêm vào. Apple dùng nó để gắn giao dịch với người dùng của bạn, và nó xuất hiện lại trong các payload giao dịch và tiêu dùng.

  • obfuscatedAccountId là trường của Google Play. Nó nhận một chuỗi đã băm tối đa 64 ký tự, mã của bạn đặt giá trị này trong lúc thanh toán, và trường này cũng không có mặc định. Google dùng nó trong cơ chế phát hiện hoạt động bất thường và dùng nó để chặn một số giao dịch gian lận trước khi chúng hoàn tất.

Có một sự bất đối xứng quan trọng cần lưu ý. Google hoàn toàn không cung cấp cách bổ sung dữ liệu về sau (backfill). Một giao dịch mua trên Play hoàn tất mà không có định danh sẽ vô danh vĩnh viễn, và việc gắn định danh cho các giao dịch mua trong tương lai là biện pháp khắc phục duy nhất. Endpoint Set App Account Token của Apple có thể sửa lại lịch sử, điều này khiến nó trở thành ngoại lệ hơn là quy luật chung.

Tính toán chi phí của một lần hoàn tiền từ người làm việc này lặp đi lặp lại

Doanh thu bị hoàn lại là phần dễ nhìn thấy, nhưng cũng là phần nhỏ hơn. Việc cấp một khoản hoàn tiền sẽ trả lại giá bán, và sổ sách của bạn ghi nhận điều đó. Thứ không xuất hiện trong dòng ghi đó là toàn bộ chi phí đã bỏ ra để tạo ra thứ mà khách hàng giờ đây đang giữ miễn phí.

Hãy xem xét một mặt hàng tiêu dùng khởi động công việc thực sự: hình ảnh được tạo ra, một loạt lệnh gọi tới nhà cung cấp mô hình, một video được xuất ra, một khoản thanh toán được giải ngân cho một nhà sáng tạo nội dung. Năng lực tính toán đó đã được mua tại đúng thời điểm sử dụng. Việc hoàn tiền lấy lại giá bán nhưng để lại hóa đơn của nhà cung cấp đúng nguyên như vậy. Người đã nhận ra rằng hàng hóa vẫn tồn tại lâu hơn khoản hoàn tiền sẽ đơn giản là lặp lại chuỗi hành động đó: mua, tiêu dùng, hoàn tiền, và mỗi lần lặp lại đều khiến bạn phải trả lại chi phí giao hàng một lần nữa.

Ngoài ra còn có việc nền tảng chuyển chi phí sang cho bạn. Kể từ ngày 3 tháng 8 năm 2026, Google Play sẽ gán cả giá mua và phí chargeback của ngân hàng cho nhà phát triển đối với các đơn hàng đặt từ ngày đó. Những tranh chấp mà trước đây chủ yếu là chi phí của Google giờ trở thành doanh thu bị mất của bạn cộng thêm một khoản phí, và một người thường xuyên thực hiện chargeback sẽ đẩy con số đó lên cao hơn với mỗi lần thực hiện. Các trường định danh chính là thứ giúp bạn có thể gửi cho Review Refund API một thứ gì đó đáng để đọc trong khung thời gian 24 giờ.

Google đưa ra một con số cho thấy quy mô của vấn đề: hơn 2 tỷ đô la giao dịch gian lận và lạm dụng đã bị chặn trong năm 2022. Con số đó tồn tại được là vì các tín hiệu nền tảng, trong đó có obfuscated account ID, thực sự đã được điền đầy đủ. Việc triển khai các giao dịch mua với những trường đó để trống đồng nghĩa với việc bạn chọn đứng ngoài vùng bảo vệ đó.

Phát hiện người hoàn tiền lặp lại trước khi cửa hàng ra quyết định

Gắn vào mọi giao dịch mua một định danh mà bạn kiểm soát

Không nền tảng nào nên nhìn thấy một giao dịch mua mà thiếu định danh này. Giao dịch mua qua StoreKit mang theo appAccountToken, giao dịch mua qua Play Billing mang theo setObfuscatedAccountId, và cả hai giá trị này đều bắt nguồn từ bản ghi người dùng của riêng bạn. Apple yêu cầu một UUID thực sự được ánh xạ tới tài khoản đó, Google yêu cầu khóa tài khoản được băm để không có thông tin cá nhân nào truyền đi ở dạng không mã hóa. Thời điểm thanh toán là lúc dành cho cả hai, và với Google, thời điểm đó không thể thương lượng lại sau này.

Duy trì một sổ sách được lập chỉ mục theo định danh đó

Ghi lại các lượt giao hàng, các sự kiện tiêu dùng, các giao dịch mua, và các lần hoàn tiền, tất cả đều được lưu dưới định danh đó. Khi đó, một CONSUMPTION_REQUEST hay một chargeback review sẽ đưa toàn bộ quá khứ của tài khoản đó, bao gồm cả các lần hoàn tiền trước đây, chỉ cách bạn một truy vấn duy nhất. Thông tin tiêu dùng của Apple cung cấp các trường chuyên dụng chính xác cho loại dữ liệu này: consumptionStatus, deliveryStatus, playTime, accountTenure, lifetimeDollarsPurchased, và refundPreference do bạn tự đặt.

Coi voidedReason như một quyết định định tuyến

Các giao dịch mua bị hủy (voided) trên Play mang theo một voidedReason giải thích nguyên nhân, và friendly_fraud cùng fraud được ghi nhận riêng biệt so với trường hợp đổi ý thông thường. Những trường hợp này xứng đáng có một hàng đợi xét duyệt và một chính sách cứng rắn hơn, thay vì cách xử lý tự động mà một lần hoàn tiền đầu tiên nhận được. Hướng dẫn của Google mô tả các phản ứng leo thang dần: một cảnh báo ban đầu, một biện pháp cứng rắn hơn khi tái diễn, và việc vô hiệu hóa giao dịch mua đối với những tài khoản tiếp tục vi phạm.

Không bao giờ để lỡ khung thời gian

Bằng chứng gửi muộn thì cũng giống như không tồn tại. Hãy tự động hóa phản hồi CONSUMPTION_REQUEST để nó được gửi đi một cách thoải mái trong vòng 12 giờ, và chargeback review trong vòng 24 giờ. Một lịch sử tài khoản hoàn hảo nhưng được gửi sau hạn chót là một lịch sử mà không ai ở cửa hàng sẽ mở ra xem.

  • Để phát hiện một tài khoản thực hiện giao dịch trên một số lượng thiết bị phi lý cùng lúc, hãy dựa vào cơ chế phát hiện hoạt động bất thường của Google Play, cơ chế này đọc obfuscated account ID.

  • Để xem lịch sử hoàn tiền trước đây của tài khoản này, hãy dựa vào bản ghi của riêng bạn, tức là sổ sách mà bạn đã lập chỉ mục theo định danh của một trong hai nền tảng.

  • Để xác nhận hàng hóa thực sự đã đến tay người mua và được sử dụng, hãy dựa vào Apple, nơi consumptionStatus và deliveryStatus nằm trong consumption info.

  • Để phát hiện một tranh chấp mà thực chất là người mua đang lừa gạt bạn, hãy dựa vào Google Play, nơi voidedReason trả về là friendly_fraud.

Nơi các nền tảng hỗ trợ, và nơi chúng dừng lại

Việc xác định rõ ràng về sự phân chia trách nhiệm là điều đáng làm, vì rất dễ cho rằng các cửa hàng tự xử lý vấn đề lạm dụng, trong khi họ hiếm khi công bố điểm mà họ dừng lại. Google thực sự có đọc obfuscated account ID để chặn một số gian lận trước khi mua hàng, và các hệ thống ở cấp nền tảng chặn được một khối lượng đáng kể. Apple giữ toàn quyền quyết định mọi khoản hoàn tiền cho riêng mình và coi thông tin tiêu dùng của bạn là bằng chứng chứ không phải là một lá phiếu. Điều mà không cửa hàng nào làm là giữ một danh sách những kẻ lạm dụng thay cho bạn, hoàn trả lại số dư cho một mặt hàng tiêu dùng đã bị hoàn tiền, hay từ chối một người hoàn tiền lặp lại thay bạn. Ở những trường hợp biên, định danh là thứ mà cửa hàng có thể hành động dựa trên đó. Còn ở mọi trường hợp khác, đó là việc của bạn.

Refund Sensor được thiết kế xoay quanh định danh đó vì chính lý do này. Một lần hoàn tiền, một chargeback review, và một consumption request thuộc về cùng một tài khoản sẽ được gộp lại thành một lịch sử duy nhất, nhờ đó một mô hình lặp lại trở nên rõ ràng ngay từ lần thứ hai, thay vì chỉ sau khi hóa đơn thứ tư đã được thanh toán.

Nơi các quy tắc này được ghi lại

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

Đây là cách mô tả một khách hàng liên tục yêu cầu hoàn tiền sau khi đã nhận và sử dụng thứ họ đã mua, vừa giữ lại lợi ích vừa lấy lại tiền đã trả. Trong bối cảnh app store, điều này thường xuất hiện dưới dạng một tài khoản hoàn tiền lặp đi lặp lại cho các mặt hàng tiêu dùng (consumables) hoặc các gói đăng ký, hoặc dưới dạng friendly fraud, khi một giao dịch hợp lệ bị tranh chấp qua ngân hàng thay vì qua cửa hàng.

Trên Apple, bạn tạo một UUID, truyền nó dưới dạng appAccountToken khi giao dịch mua bắt đầu, và StoreKit sẽ gắn nó vào giao dịch được tạo ra, từ đó nó xuất hiện lại trong cả dữ liệu giao dịch (transaction data) và dữ liệu tiêu dùng (consumption data). Trên Google, bạn gọi setObfuscatedAccountId bằng một giá trị đã băm (hashed) được tạo ra từ tài khoản đó. Cả hai cách tiếp cận đều giúp khớp một giao dịch của cửa hàng với bản ghi người dùng của riêng bạn mà không để lộ bất kỳ thông tin cá nhân nào.

Không bên nào làm vậy, ít nhất là không trực tiếp. Google đọc obfuscated account ID để nhận diện hoạt động bất thường và chặn một số gian lận trước khi mua hàng, còn Apple tiếp nhận lịch sử tài khoản được gửi trong một consumption request, nhưng không có công ty nào trả lại cho bạn một danh sách những kẻ tái phạm. Việc lập danh sách đó là việc của bạn, được xây dựng từ các bản ghi mà bạn đã lưu dưới các định danh này.

Nguyên nhân thường gặp là dữ liệu cá nhân ở dạng văn bản thuần (cleartext) trong obfuscated account ID. Việc đặt một địa chỉ email thô vào đó sẽ khiến Play chặn giao dịch mua ngay lập tức. Hãy cung cấp một giá trị đã mã hóa hoặc một mã băm một chiều (one-way hash) thay thế, và giữ trong giới hạn 64 ký tự.

Nó làm giảm bớt chứ không ngăn chặn hoàn toàn. CONSUMPTION_REQUEST là một trong chỉ hai luồng mà bằng chứng của bạn đến trước khi quyết định được đưa ra, và lịch sử tài khoản kết hợp với dữ liệu giao hàng và tiêu dùng giúp Apple nhận diện hành vi lạm dụng hoàn trả và friendly fraud. Tuy nhiên, Apple vẫn là bên quyết định, và các hành vi lạm dụng đến qua những luồng mà bạn không thể tranh chấp vẫn không bị ảnh hưởng.

#refund abuse#chargebacks#appaccounttoken#obfuscated account id#fraud prevention
Refund SensorRefund Sensor TeamRefund defense for App Store and Google Play developers