I keep getting "Error occurred while processing a product purchase" even though everything works fine?

Hey everyone! I have this Nuke thing that when you purchase a DevProduct, the server launches a nuke and kills all people.


Video:


I have a script for a safe area and the purchase prompt. Another one which handles the happening of the nuke exploding (ProcessReceipt).
I keep getting this, even though everything works:
image


ProcessReceipt code:

local MarketplaceService = game:GetService("MarketplaceService")
local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")
local nuke = workspace.Nuke
local timer = 60
local timer2 = 0.54
local timer3 = 1
local count = nuke.Countdown.BillboardGui.TextLabel
local purchaseHistoryStore = DataStoreService:GetDataStore("NukePurchases")
--workspace.Nuke.ProductID.Value
local productFunctions = {}
productFunctions[1133829409] = function(receipt, player)
	nuke.Missle.Base.Anchored = true
	local p = nuke.Doors.Part1
	local p2 = nuke.Doors.Part2

	local MarketplaceService = game:GetService("MarketplaceService")
	count.Text = "⚠️"
	nuke.Button.Sound:Play()

	local clone = nuke.Missle:Clone()
	clone.Name = "clone"
	clone.Parent = nuke
	local RunService = game:GetService("RunService")
	local Folder = nuke:WaitForChild("clone")
	for _, part in pairs(Folder:GetChildren()) do
		part.Transparency = 1
		wait()
	end
	clone.SmoothBlockModelDec.Decal1.Transparency = 1
	clone.SmoothBlockModelDec.Decal2.Transparency = 1
	for i=1, 50 do
		p.CFrame=p.CFrame+Vector3.new(0,0,0.1)
		p2.CFrame=p2.CFrame+Vector3.new(0,0,-0.1)
		wait()
	end
	coroutine.resume(coroutine.create(function()
		local lights = nuke.Lights:GetChildren()
		for i = 1,22 do
			for i,v in pairs(lights) do
				v.SpotLight.Enabled = true
			end
			wait(timer2)
			for i,v in pairs(lights) do
				v.SpotLight.Enabled = false
			end
			wait(timer2)			
		end
	end))

	wait(2)

	nuke.Missle.Base.Fire.Enabled = true
	nuke.Missle.Base.Smoke.Enabled = true

	wait(3)

	nuke.Missle.PrimaryPart = nuke.Missle.Base	
	for i=1,320 do
		nuke.Missle:SetPrimaryPartCFrame(nuke.Missle:GetPrimaryPartCFrame()+Vector3.new(0,0.05*((1.1^(i/5))/3),0))
		wait()
	end
	for i=1, 50 do
		p.CFrame=p.CFrame+Vector3.new(0,0,-0.1)
		p2.CFrame=p2.CFrame+Vector3.new(0,0,0.1)
		wait()
	end
		for _, part in pairs(Folder:GetChildren()) do
		part.Transparency = 1
		wait()
	end
	wait()
	for i=1,100 do
		nuke.Missle:SetPrimaryPartCFrame(nuke.Missle:GetPrimaryPartCFrame()+Vector3.new(0,0.05*(1.1^((250-i)/5)/3),0))
		nuke.Missle:SetPrimaryPartCFrame(nuke.Missle:GetPrimaryPartCFrame()*CFrame.Angles(0,math.pi/100,0))
		nuke.Missle:SetPrimaryPartCFrame(nuke.Missle:GetPrimaryPartCFrame()+Vector3.new(0,0,-i/100))	
		wait()
	end
	for i=200,120,-1 do
		nuke.Missle:SetPrimaryPartCFrame(nuke.Missle:GetPrimaryPartCFrame()-Vector3.new(0,0.1*((1.1^(i/2.95))/4),0))
		wait()
	end	

	nuke.Missle.Tip.Transparency = 0.5
	nuke.Missle.Tip.CanCollide = false
	nuke.Missle.Tip.Mesh.Scale = Vector3.new(1,1,1)
	local boom = nuke.Button.Boom
	local boomclone = nuke.Button.Boom:Clone()
	boomclone.Parent = workspace
	boomclone:Play()
	local frame = nuke.Missle.Tip.CFrame
	nuke.Missle.Tip.Touched:Connect(function(obj)
		local h = obj.Parent:FindFirstChildWhichIsA("Humanoid")
		local safe = obj.Parent:FindFirstChild("Safe")
		if not safe and h then
			h.Health = 0
		end
	end)
	for i=1,400 do
		nuke.Missle.Tip.Size=nuke.Missle.Tip.Size+Vector3.new(3,3,3)
		nuke.Missle.Tip.CFrame=frame
		wait()
	end
	for _, part in pairs(Folder:GetChildren()) do
		part.Transparency = 0
		wait()
	end
	nuke.Missle:Destroy()
	boomclone:Destroy()
	nuke.Button.Sound:Stop()
	clone.Name = "Missle"
	clone.SmoothBlockModelDec.Decal1.Transparency = 0.5
	clone.SmoothBlockModelDec.Decal2.Transparency = 0.5
	count.Text = timer
	while timer > 0 do
		count.Text = timer
		wait(timer3)
		timer = timer - 1	
	end
	wait(timer3)
	count.Text = "Ready"
	
end



local function processReceipt(receiptInfo)


	local playerProductKey = receiptInfo.PlayerId .. "_" .. receiptInfo.PurchaseId
	local purchased = false
	local success, errorMessage = pcall(function()
		purchased = purchaseHistoryStore:GetAsync(playerProductKey)
	end)
	if success and purchased then
		return Enum.ProductPurchaseDecision.PurchaseGranted
	elseif not success then
		error("Data store error:" .. errorMessage)
	end


	local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
	if not player then

		return Enum.ProductPurchaseDecision.NotProcessedYet
	end


	local handler = productFunctions[receiptInfo.ProductId]


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


	local success, errorMessage = pcall(function()
		purchaseHistoryStore:SetAsync(playerProductKey, true)
	end)
	if not success then
		error("Cannot save purchase data: " .. errorMessage)
	end


	return Enum.ProductPurchaseDecision.NotProcessedYet
end

MarketplaceService.ProcessReceipt = processReceipt


And, the other script that handles the safe area and the prompting:

local MarketplaceService = game:GetService("MarketplaceService")
local productID = 1133829409

workspace.SafePlace.Touched:Connect(function(obj)
	local existSafe = obj.Parent:FindFirstChild("Safe")
	if obj.Parent:IsA("Model") then
		if not existSafe then
			local safeval = Instance.new("StringValue")
			safeval.Name = "Safe"
			safeval.Parent = obj.Parent
		end
	end
end)

workspace.SafePlace.TouchEnded:Connect(function(obj)
	local safeval = obj.Parent:FindFirstChild("Safe")
	if obj.Parent:IsA("Model") then
		if safeval then
			safeval:Destroy()
		end
	end
end)

script.Parent.Button.ClickDetector.MouseClick:Connect(function(player)
	if script.Parent.Countdown.BillboardGui.TextLabel.Text == "Ready" then
		MarketplaceService:PromptProductPurchase(player, productID)
	end
end)

(Safe area:

)
PS. I am using the ProcessReceipt from the Developer Hub.


Any help is appreciated, I have had this same issue haunt me for days lol, so it would mean alot if you atleast try to help me. Thanks!

Can you print the result of the pcall?

1 Like

It means that success and/or result is false/nil.

Try to print both values before the if statement to see which value is invalid.

3 Likes

iirc it should be

pcall(handler, processFunctions, receiptInfo, player)

If it still doesn’t work, try running the function in non-protected call, to see if it is the function being faulty or not.

1 Like

They do not have to pass processFunctions because they are not operating on an object.

3 Likes

image
image

1 Like

image
image
The result is nil, success is true.

1 Like

The result is nil because you did not return anything in the function.

4 Likes