Multiple developers have posted in the past asking why the PromptProductPurchaseFinished event of the MarketplaceService was deprecated. They subsequently asked if it could be restored, but failed to provide a good enough reason to do so. I have a scenario that I think justifies this or something similar. I detailed my own solution below. If you think you can solve it with API we have now, you are welcome suggest that too. But here goes:
I have a Developer Product which, when purchased, awards the player with one of 18 distinct goods. The player has the opportunity to browse through them before they decide they want to pay anything. After selecting which one they want, the prompt appears. To save from having to create 18 different products, I use the same product for all of them (they are all the same price and are sufficiently related). The problem arrises in the following scenario:
Player clicks Cancel, as they have decided they’d rather buy good 6.
Player selects good 6, and PromptProductPurchase is called a second time.
Player is satisfied with their life decisions and clicks Accept.
The ProcessReceipt callback is invoked, but the server is not sure whether to award them good 4 or good 6.
Is it safe to create a stack of goods prompted, and assume the top of the stack is always the good the player really wanted? This is my current solution, but I feel as though it is sloppy. How can I be absolutely certain without assigning them some kind of identification?
I am proposing that what would help me the most is the ability to assign metadata to a PromptProductPurchase call that is then passed to the ProcessReceipt invocation inside the dictionary it already receives, to remove any ambiguity of the purchase that may occur.
There’s a simple solution. When the player selects which good he wants to purchase, call a RemoteFunction letting the server know which one he has chosen. When the RemoteFunction call returns, then invoke PromptProductPurchase from the client. When ProcessReceipt is invoked, the server will know which option the player opted to purchase.
I just remembered the real issue I have with this, and the reason I referenced the PromptProductPurchaseFinished API in the first place: synchronization with dialogue.
It’s really hard to make dialogue flow well when we don’t know that the player has canceled the moment they do.
Problem: How can I prevent the player from clicking a bunch of different goods in a few seconds? Solution: Easy, remove the options once they click the first one.
Problem: When do I bring the other options back? Solution: Once they purchase.
Problem: What if they cancel? Solution: Make the transaction time out…? Is that a solution? Let’s assume that it is.
Problem: What if the player accepts after the time out period? Solution: I don’t have a perfect solution. This is where it gets tricky.
This won’t work for any case where you can not process the receipt immediately though. If you have to not grant a purchase because DataStores are down for example, you will not be able to grant that purchase when process receipt is called again in the future.
@TheGamer101 Before you prompt the player you can store the option he is choosing a the data store. If that operation fails then don’t prompt him and give him an error message.
@tbradm For that you just need a client-side event which fires when the player closes the prompt. We should add this. It should not contain information about whether the purchase succeeded because that won’t be known at the time.
Or do you mean for game passes only? In that case you shouldn’t be using PromptProductPurchaseFinished but PromptPurchaseFinished: (it’s in the name)
PromptPurchaseFinished doesn’t work for dev products, neither does ProcessReceipt for assets.
PromptProductPurchaseFinished only works for dev products, but shouldn’t be used.
once they bought the developer product and you get the receipt you give them the option to choose for their good. like: “You bought a ticket that can be used to buy a good”. once you click the good its added to your inventory and the receipt is handled.