WorldShopService

Provides functions related to purchasing products in the world through paid goods.

# Methods

[{"index":"WorldShopProduct GetProductAndWait(string productId) (Yield)","0":"Acquires the product information. Script executions are suspended during the operation. The release environment allows obtaining the badge information in Waiting, Ing, and End statuses, while the maker environment allows obtaining the badge information in Register, Waiting, Ing, and End statuses."}]

[{"index":"WorldShopProductPages GetProductsAndWait(WorldShopProductType productType, WorldShopProductStatus productStatus) (Yield)","0":"Obtains an entity that can check the information of products matching the search condition. Script executions are suspended during the operation. Searches all kinds of products when designating nil to productType and searches all products that can be searched when designating nil to productStatus. The release environment allows the search of products in Waiting, Ing, and End statuses, while the maker environment allows the search of products in Register, Waiting, Ing, and End statuses."}]

[{"index":"void PromptPurchase(string productId) (ClientOnly)","0":"Displays the product purchase window. If you are unable to purchase the item, the reason is displayed."}]

[{"index":"void SetProcessPurchaseCallback(func -> boolean callback) (ServerOnly)","0":"Specifies the callback that provides the product when a purchase is made.The callback should check the purchase information with the received WorldShopPurchaseInfo and return true if product payment is successful, otherwise false. If the purchase did not return true, the callback that issues a product will run again when the user re-enters the World."}]

[{"index":"boolean UserHasPassAndWait(string userId, string productId) (Yield)","0":"Checks if the user has a pass. Script executions are suspended during the operation. In the World being created, you start without a pass."}]

##### inherited from Service:

[{"index":"EventHandlerBase ConnectEvent(string key, IScriptFunction eventHandler)","0":"Links events. When a key-type event occurs in this service, a handler is notified. The handler receives event parameters."}]

[{"index":"EventHandlerBase ConnectEvent(Type eventType, IScriptFunction eventHandler)","0":"Links events. This service notifies a handler when an eventType event occurs. The handler receives event parameters."}]

[{"index":"boolean DisconnectEvent(string key, EventHandlerBase eventHandler)","0":"Disconnects the event with the key-type event and the handler."}]

[{"index":"boolean DisconnectEvent(Type eventType, EventHandlerBase eventHandler)","0":"Disconnects the eventType event from its handler."}]

[{"index":"void SendEvent(EventType sendEvent)","0":"Generates an event."}]

# Examples

#### SetProcessPurchaseCallback

The following is an example of registering a function to execute product delivery when a purchase occurs and registering this function in `WorldShopService`. Since the product delivery function must be registered when the world is created and maintained, it should be written as Logic. Since product delivery is done on the server, registering the function must also be performed on the server.
    
    
    @Component
    script PurchaseProcessor extends Component
        @ExecSpace("ServerOnly")
        method void OnBeginPlay()
        -- Register the product delivery callback.
        _WorldShopService:SetProcessPurchaseCallback(self.ProcessPurchase)
        end
    
        @ExecSpace("ServerOnly")
        method boolean ProcessPurchase(any purchaseInfo)
        log("Process purchase. PurchaseId: " .. purchaseInfo.PurchaseId .. ", UserId: " .. purchaseInfo.UserId .. ", ProductId: " .. purchaseInfo.ProductId .. ", OrderNumber: " .. tostring(purchaseInfo.OrderNumber))
        return true
        end
    end
    

#### SetProcessPurchaseCallback

The product delivery function should receive `WorldShopPurchaseInfo` as a parameter and return a boolean. `WorldShopPurchaseInfo` received as a parameter contains information about the purchase, such as the user and the product. Use this to decide whether to pay for the product or not. Returns true to complete the purchase as product delivery proceeds normally. If the product cannot be delivered and the normal purchase process cannot be performed, returns false. If a purchase returns false, it will try to deliver the product to the user who made the purchase the next time they connect to the world.
    
    
    @Component
    script PurchaseProcessor extends Component
        @ExecSpace("ServerOnly")
        method void OnBeginPlay()
        -- Configures the delivery function table by product ID.
        -- In this example, the delivery function receives a user Entity as a parameter and returns a boolean indicating whether the delivery was successful or not.
        self._T.productPurchaseFunctions = {}
    
        -- The product with ID "000000" pays 1000 coins to the user.
        self._T.productPurchaseFunctions["000000"] = function(userEntity) return self:GiveCoin1000(userEntity) end
    
        -- Register product delivery callback
        _WorldShopService:SetProcessPurchaseCallback(self.ProcessPurchase)
        end
    
        @ExecSpace("ServerOnly")
        method boolean ProcessPurchase(any purchaseInfo)
        local userEntity = _UserService:GetUserEntityByUserId(purchaseInfo.UserId)
    
        if not _EntityService:IsValid(userEntity) then
            -- Delivery failed because the Entity of the purchasing user could not be found.
            log_error("Process purchase failed. Cannot find user entity. UserId: " .. purchaseInfo.UserId)
            return false
        end
    
        local productPurchaseFunction = self._T.productPurchaseFunctions[purchaseInfo.ProductId]
    
        if productPurchaseFunction == nil then
            -- Failed to find delivery function for product ID.
            log_error("Process purchase failed. Cannot find product purchase function. ProductId: " .. purchaseInfo.ProductId)
            return false
        end
    
        -- Attempts to deliver the product.
        -- success: incdicates whether the function call was successful without errors.
        -- result: if the function call was successful, the function return value (whether the product was delivered or not). Error message if there was an error in the function call.
        local success, result = pcall(productPurchaseFunction, userEntity)
    
        if success and result then
            -- No error occurred, and delivery of the product was successful.
            -- Leaves a record so that you can check the purchase history later.
            _LogStorageService:LogPurchaseInfo(purchaseInfo, "Success")
            return true
        else
            -- Failed to deliver product.
         log_error("Process purchase failed. Product purchase function failed. PurchaseId: " .. purchaseInfo.PurchaseId .. ", UserId: " .. purchaseInfo.UserId .. ", ProductId: " .. purchaseInfo.ProductId .. ", OrderNumber: " .. tostring(purchaseInfo.OrderNumber) .. ", Result: " .. tostring(result))
        	return false
        end
        end
    
        @ExecSpace("ServerOnly")
        method boolean GiveCoin1000(EntityRef userEntity)
        local walletComponent = userEntity.WalletComponent
    
        if walletComponent == nil then
        	return false
        end
    
        -- Gives 1,000 Coins to users.
        walletComponent:AddCoin(1000)
    
        -- Product delivery successful
        return true
        end
    end
    

#### GetProductsAndWait

Use the `GetProductsAndWait()` function to search for products that meet your conditions. The `WorldShopProductPages` type Entity returned by this function allows you to obtain the results by dividing them into pages when there are many search results.
    
    
    @Component
    script OnSaleProductSearcher extends Component
        method void SearchOnSaleItems()
        -- Search for products whose product type is item and sales state is on sale.
        local pages = _WorldShopService:GetProductsAndWait(WorldShopProductType.Item, WorldShopProductStatus.Ing)
    
        while true do
        	local pageDatas = pages:GetCurrentPageDatas()
    
        	for _, product in ipairs(pageDatas) do
              -- Searched product info
              log("Product Id: " .. product.Id .. ", Name: " .. product.Name .. ", Price: " .. tostring(product.Price))
        	end
    
        	if pages.IsLastPage then
        		break
        	end
    
        	pages:MoveToNextPageAndWait()
        end
        end
    end
    

# SeeAlso

  * WorldShopPurchaseInfo
  * EntityService
  * LogStorageService
  * UserService
  * [Utilizing World Shop Services](/docs?postId=659)