local T={Client={}}local q="\080\114\111\100\117\099\116\080\117\114\099\104\097\115\101\115"local H="\080\114\111\109\112\116\080\117\114\099\104\097\115\101\070\105\110\105\115\104\101\100"local r=game:GetService("\077\097\114\107\101\116\112\108\097\099\101\083\101\114\118\105\099\101")local n="\080\108\097\121\101\114\082\101\099\101\105\112\116\115"local s local function W(T,H)H=tostring(H)local r=s.DataService:Get(T,q)if not r then r={}s.DataService:Set(T,q,r)end local n=r[H]r[H]=n and n+1 or 1 s.DataService:FlushKey(T,q)end local function a(q)local r=(game:GetService("\080\108\097\121\101\114\115")):GetPlayerByUserId(q.PlayerId)local a=tostring(q.PlayerId)local F=tostring(q.PurchaseId)local b=s.DataService:GetCustom(a,n,F)if not b then s.DataService:SetCustom(a,n,F,true)s.DataService:FlushCustom(a,n,F)end if r then W(r,q.ProductId)T:FireEvent(H,r,q)T:FireClientEvent(H,r,q)end return Enum.ProductPurchaseDecision.PurchaseGranted end function T.HasPurchased(r,T,H)local n=s.DataService:Get(T,q)return n and n[tostring(H)]~=nil end function T.OwnsGamePass(H,T,q)local n,s=pcall(function()return r:UserOwnsGamePassAsync(T.UserId,q)end)return n and s or false end function T.GetNumberPurchased(r,T,H)local n=0 local W=s.DataService:Get(T,q)if W then n=W[tostring(H)]or 0 end return n end function T.Client.GetNumberPurchased(H,T,q)return H.Server:GetNumberPurchased(T,q)end function T.Client.OwnsGamePass(H,T,q)return H.Server:OwnsGamePass(T,q)end function T.Client.HasPurchased(H,T,q)return H.Server:HasPurchased(T,q)end function T.Start(T)r.ProcessReceipt=a end function T.Init(T)s=T.Services T:RegisterEvent(H)T:RegisterClientEvent(H)end return T
-- Store Service
-- Crazyman32
-- December 1, 2015

-- Updated: December 31, 2016
-- Updated: March 2, 2017

--[[
	
	Server:
		
		StoreService:HasPurchased(player, productId)
		StoreService:OwnsGamePass(player, gamePassId)
		StoreService:GetNumberPurchased(player, productId)
		
		StoreService.PromptPurchaseFinished(player, receiptInfo)
	
	
	Client:
		
		StoreService:HasPurchased(productId)
		StoreService:OwnsGamePass(gamePassId)
		StoreService:GetNumberPurchased(productId)
	
		StoreService.PromptPurchaseFinished(receiptInfo)
	
--]]



local StoreService = {
	Client = {};
}

local PRODUCT_PURCHASES_KEY = "ProductPurchases"
local PROMPT_PURCHASE_FINISHED_EVENT = "PromptPurchaseFinished"

local marketplaceService = game:GetService("MarketplaceService")

local dataStoreScope = "PlayerReceipts"
local services


local function IncrementPurchase(player, productId)
	productId = tostring(productId)
	local productPurchases = services.DataService:Get(player, PRODUCT_PURCHASES_KEY)
	if (not productPurchases) then
		productPurchases = {}
		services.DataService:Set(player, PRODUCT_PURCHASES_KEY, productPurchases)
	end
	local n = productPurchases[productId]
	productPurchases[productId] = (n and (n + 1) or 1)
	services.DataService:FlushKey(player, PRODUCT_PURCHASES_KEY)
end


local function ProcessReceipt(receiptInfo)
	
	--[[
		ReceiptInfo:
			PlayerId               [Number]
			PlaceIdWherePurchased  [Number]
			PurchaseId             [String]
			ProductId              [Number]
			CurrencyType           [CurrencyType Enum]
			CurrencySpent          [Number]
	--]]
	
	local player = game:GetService("Players"):GetPlayerByUserId(receiptInfo.PlayerId)
	
	local dataStoreName = tostring(receiptInfo.PlayerId)
	local key = tostring(receiptInfo.PurchaseId)
	
	-- Check if unique purchase was already completed:
	local alreadyPurchased = services.DataService:GetCustom(dataStoreName, dataStoreScope, key)
	
	if (not alreadyPurchased) then
		-- Mark as purchased and save immediately:
		services.DataService:SetCustom(dataStoreName, dataStoreScope, key, true)
		services.DataService:FlushCustom(dataStoreName, dataStoreScope, key)
	end
	
	if (player) then
		IncrementPurchase(player, receiptInfo.ProductId)
		StoreService:FireEvent(PROMPT_PURCHASE_FINISHED_EVENT, player, receiptInfo)
		StoreService:FireClientEvent(PROMPT_PURCHASE_FINISHED_EVENT, player, receiptInfo)
	end
	
	return Enum.ProductPurchaseDecision.PurchaseGranted
	
end


function StoreService:HasPurchased(player, productId)
	local productPurchases = services.DataService:Get(player, PRODUCT_PURCHASES_KEY)
	return (productPurchases and productPurchases[tostring(productId)] ~= nil)
end


function StoreService:OwnsGamePass(player, gamePassId)
	local success, owns = pcall(function()
		return marketplaceService:UserOwnsGamePassAsync(player.UserId, gamePassId)
	end)
	return (success and owns or false)
end


-- Get the number of productId's purchased:
function StoreService:GetNumberPurchased(player, productId)
	local n = 0
	local productPurchases = services.DataService:Get(player, PRODUCT_PURCHASES_KEY)
	if (productPurchases) then
		n = (productPurchases[tostring(productId)] or 0)
	end
	return n
end


-- Get the number of productId's purchased:
function StoreService.Client:GetNumberPurchased(player, productId)
	return self.Server:GetNumberPurchased(player, productId)
end


function StoreService.Client:OwnsGamePass(player, gamePassId)
	return self.Server:OwnsGamePass(player, gamePassId)
end


-- Whether or not the productId has been purchased before:
function StoreService.Client:HasPurchased(player, productId)
	return self.Server:HasPurchased(player, productId)
end


function StoreService:Start()
	marketplaceService.ProcessReceipt = ProcessReceipt
end


function StoreService:Init()
	services = self.Services
	self:RegisterEvent(PROMPT_PURCHASE_FINISHED_EVENT)
	self:RegisterClientEvent(PROMPT_PURCHASE_FINISHED_EVENT)
end


return StoreService