ProcessReceipt Script duplicates items after 2+ devproducts purchased

Hello Devforum! Tonight while scripting a developer product script I was getting weird results from my script. Currently, when a user purchases one dev product the script acts as it is supposed to. However, when a person purchases 2 or more developer products it duplicates the first purchase and gives them the second purchase too. Is there any way I can remove the duplication? In this instance, after the two purchases, a user has 2-speed coils and 1 gravity coil when they should have one of each. Below is the script I have in serverScriptStorage. Thanks for reading!

local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local speed = ReplicatedStorage:WaitForChild("speed")
local gravity = ReplicatedStorage:WaitForChild("gravity")

local productFunctions = {}

productFunctions[1232493084] = function(receipt, player) -- speed coil
	local char = game.Workspace:FindFirstChild(player.Name)
	local speedCoilClone = speed:Clone()
	speedCoilClone.Name = "Speedcoil"
	speedCoilClone.Parent = player.Backpack
end

productFunctions[1232495261] = function(receipt, player)
	local char = game.Workspace:FindFirstChild(player.Name)
	local gravityCoilClone = gravity:Clone()
	gravityCoilClone.Name = "Gravitycoil"
	gravityCoilClone.Parent = player.Backpack
end

local function processReceipt(receiptInfo)
	print(receiptInfo)
	local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
	if not player then 
		return Enum.ProductPurchaseDecision.NotProcessedYet
	end

	if player then
		local handler = productFunctions[receiptInfo.ProductId]
		local success, result = pcall(handler, receiptInfo, player)
		print(result)
		print(handler)
		if success == false or not result then
			warn("Error occurred while processing a product purchase")
			print("\nProductId:", receiptInfo.ProductId)
			print("\nPlayer:", player)
			return Enum.ProductPurchaseDecision.NotProcessedYet
		end

		return Enum.ProductPurchaseDecision.PurchaseGranted

	end
end

-- Set callback
MarketplaceService.ProcessReceipt = processReceipt


1 Like

You never return anything in the functions so the result variable is nil and the purchase is considered a failure.
Remove the not result check.

It seems like you got your code from the ProcessReceipt article. It’s fully documented to explain the decision behind each part of the script so you should be following the template it sets forth more carefully and try and learn about some of the decisions for the parts you don’t understand as well.

  • Product functions are given a player and when you’re given a player you should never be doing FindFirstChild on the Workspace for the player name. If any other instance is named the same as the player you could get the wrong model. Access it through their Character property. That being said, it’s not like you use the character for anything in any product functions, so just get rid of it.

  • Product functions are supposed to return true as pointed out above to tell the script calling these functions that the purchase was successful. Unlike the above advice, WHAT YOU SHOULD BE DOING is making the product functions return true. Don’t get rid of the not result check.

  • You do not need to have the “if player then” statement in. Your script will automatically terminate if the player doesn’t exist and tell ProcessReceipt to retry the purchase again later. The player will exist if this check doesn’t fail, so there’s no use in writing an opposing if statement.

4 Likes