Roblox开发者产品购买异常:非200响应仍显示购买成功
Roblox开发者产品购买验证失败:返回NotProcessedYet仍显示购买成功的解决方案
问题场景
开发Roblox开发者产品购买系统时,通过向自定义服务器发送HTTP请求验证购买,预期当服务器返回的Code不为200时,返回Enum.ProductPurchaseDecision.NotProcessedYet阻止购买成功,但实际Roblox仍会标记购买成功,不符合需求。
核心问题分析
你的代码存在几个关键漏洞,导致Roblox无法正确识别你返回的决策:
- HTTP请求未做异常捕获:如果
PostAsync请求超时、失败或抛出错误,函数会直接崩溃,无法返回NotProcessedYet,Roblox会自动重试,最终可能默认标记购买成功。 - 分支返回不完整:仅处理了目标产品ID的情况,其他产品ID的分支没有返回值,Roblox会使用默认逻辑处理。
- 响应Code类型不明确:如果服务器返回的
Code是字符串类型(比如"404"而非数字404),response["Code"] == 200的判断会失效,错误地进入PurchaseGranted分支。
修复方案及代码修改
针对以上问题,修改代码如下:
local Players = game:GetService("Players") local MarketplaceService = game:GetService("MarketplaceService") local HTTPService = game:GetService("HttpService") local for1monthid = -- 替换为你的产品ID MarketplaceService.ProcessReceipt = function(receiptInfo) local plr = Players:GetPlayerByUserId(receiptInfo.PlayerId) if not plr then return Enum.ProductPurchaseDecision.NotProcessedYet end -- 仅处理目标产品ID if receiptInfo.ProductId == for1monthid then local url = "https://api.endpoint.com" local data = { userid = plr.UserId, receiptId = receiptInfo.ReceiptId -- 新增:传递收据ID用于重复验证 } local encodedData = HTTPService:JSONEncode(data) -- 用pcall捕获HTTP请求异常 local success, responseOrErr = pcall(function() return HTTPService:PostAsync(url, encodedData, Enum.HttpContentType.ApplicationJson, false) end) if not success then print("HTTP请求失败:" .. responseOrErr) return Enum.ProductPurchaseDecision.NotProcessedYet end -- 解析响应并处理类型问题 local decodedResponse success, decodedResponse = pcall(function() return HTTPService:JSONDecode(responseOrErr) end) if not success then print("响应解析失败:" .. decodedResponse) return Enum.ProductPurchaseDecision.NotProcessedYet end -- 同时处理数字和字符串类型的Code local responseCode = tonumber(decodedResponse["Code"]) if responseCode == 200 then print("验证通过,发放产品:" .. responseCode) -- 这里添加发放产品的逻辑(比如给玩家加道具/权限) return Enum.ProductPurchaseDecision.PurchaseGranted else print("验证失败,阻止购买:" .. decodedResponse["Code"]) return Enum.ProductPurchaseDecision.NotProcessedYet end end -- 处理未匹配的产品ID,默认返回NotProcessedYet return Enum.ProductPurchaseDecision.NotProcessedYet end
关键修改点说明
- 添加
pcall异常捕获:包裹PostAsync和JSONDecode,确保请求或解析失败时不会崩溃,稳定返回NotProcessedYet。 - 处理响应Code类型:用
tonumber()将响应中的Code转换为数字,避免字符串类型导致的判断错误。 - 完整分支返回:在函数末尾添加默认返回,覆盖所有未匹配产品ID的情况。
- 新增收据ID传递:将
receiptInfo.ReceiptId发送到服务器,用于验证是否重复购买,避免重复发放产品(最佳实践)。
内容的提问来源于stack exchange,提问作者omamelo
相关产品推荐
相关产品推荐

