Need a way to reject developer product purchases ENTIRELY or limit the amount of times a player can purchase a developer product

As a Roblox developer, it is currently too hard to give players a fair experience when buying products due to roblox service failures leading to multiple transactions on single use purchases. Sometimes a gamepass doesn’t suit the use for a one time purchase and if players manage to double transact, they will never be granted the purchase because the dev product can only be applied once.

If we were able to reject purchases outright instead of only marking “NotProcessedYet” it would allow us to actually handle invalid transactions rather than just making the player wait days to receive a refund.

If Roblox is able to address this issue, it would improve my development experience because it would allow players to get what they paid for, and if not that then a prompt refund.

Another option would be allowing a limit for the number of times a developer product could be purchased. Either way works for me…

From the API
The supported ProductPurchaseDecision values in Roblox are:

  1. NotProcessedYet: This value indicates that the purchase request has been sent but has not yet been processed. It could mean that the purchase is still being reviewed or that there is a delay in processing the purchase.
  2. PurchaseGranted: This value indicates that the purchase has been processed and granted to the user who initiated the purchase request. It means that the player has successfully received the benefit or item associated with the developer product.

These two values are used in conjunction with the MarketplaceService and the sale of developer products in Roblox. They help determine the status of a purchase and whether the player should receive the intended benefit or not.

We need Enum.ProductPurchaseDecision.PurchaseRejected so we can refund a player immediately OR single purchase dev products to prevent the issue entirely.

To be totally clear, gamepasses are not an option because things that have pre-requisites for the purchase cannot be applied to gamepasses since they are available outright on the website and there is no way to guard forced purchases from the client.

27 Likes

MarketplaceService.ProcessReceipt

3 Likes

Massive support. The lack of a PurchaseRejected option has led to numerous headaches, especially surrounding people thinking their purchase succeeded when really it didn’t due to a Datastore flaw/edge-case bug in our code/some other event.

If we were able to decline purchases, I’d be able to prevent receipts retrying over the next 72 hours when in reality, they will never pass at all due to the circumstances they were bought under, whether that was due to a bug or the game state changing.

Here’s a very simple case:

  • Player1 and Player2 are both ingame.
  • Player1 decides to gift Player2 something, or decides to instantly kill them. Both of these would happen via dev product.
  • In the time Player1 is opening their prompt, Player2 decides to abruptly leave the server.
    • This is more likely than you may think, especially for larger games. Mobile players or younger children tend to go through menus slowly and may not notice any changes in the leaderboard.
  • Now if Player1 still buys it, no matter what, their purchase will never succeed.

I want to be able to decline this purchase outright. There’s no reason it should ever go through and take the player’s money for a few days.

14 Likes

Would like to add more examples where a purchase rejection would be very useful:

  • A player buys an event-specific currency, but the purchase cannot be granted right away (say, due to DataStore issues) and returns NotProcessedYet. By the time the player returns to the game and ProcessReceipt is called again, the event is already over, and the currency they bought is no longer usable.

  • A developer product exists where only a set amount of copies can be “sold” (akin to limited UGC). When the prompt was shown to the player, the product was still “in stock”, but by the time the transaction hits the backend, it’s no longer available.

  • Less likely to happen but because mistakes happen - the developer may display a product to the player that they’re not eligible for (for example, a starter pack being mistakenly advertised to an experienced player, or a certain item they’re not allowed to buy due to PolicyService reasons)

3 Likes

I think with the new website visible developer products, I’m going to bump this again.

My opinion on this has flipped, theres places where you can somehow purchase a developer product when it isn’t even valid.

If the documentation is correct, a refund isn’t even given after the 72 hours, first of all, why?. Secondly, add the refund enum so people dont lose their Robux for edgecases.

3 Likes

I was about to say this, from what I understand, players are never refunded no matter the outcome of a developer product purchase. So, if they somehow triggered a purchase for (for example) a limited-time starter pack twice, then the developer is forced to unfairly give them the reward twice or just let the player lose their Robux.

Another example: if a player is buying a revive in a game, and for some reason while purchasing they are no longer able to revive, what should the developer do with the purchase? They can’t mark it as “NotProcessedYet”, because Roblox will only trigger that purchase again if they try to buy it again (which they won’t, since it already looks like they lost their robux to the end-user), or when they rejoin, which is an irrelevant time to trigger the purchase.

There’s clearly an issue here, and I also believe that adding an Enum.ProductPurchaseDecision.PurchaseRejected would be extremely beneficial.

1 Like

They should have separate “Revive tokens” that may be bought ahead-of-time in addition to ad-hoc purchases. If the Player purchases a Revive and the receipt only gets processed after their Revive window, it goes to their tokens. Maybe you don’t even need a separate currency, you could make Revives be purchase-able with your in-game currency and have failed Revives go back into that.

It lets the Player revive faster by pre-purchasing tokens, or by having tokens leftover if they were unable to Revive after the purchase. The act of purchasing a Developer Product can be immersion-breaking and also take several minutes if the Player has no balance and has to purchase Robux.

Why is it not a Game Pass?

I already do this in my games, but you’re missing the point here. If the player buys a certain developer product that is no longer fair to be applied or used, and there is practically no way for developers to “redo” the purchase at a later time, then there is no way to refund that player for essentially a faulty purchase. (remember, unprocessed devproduct purchases only retry if they attempt a purchase again in that server, or every time they rejoin, which are two very specific instances that don’t apply to a lot of usecases)

Limited-time starter packs require developer products so that they can stop being accessible after the time limit.

2 Likes

Can’t the Gamepass be taken offsale after the time period?

I suppose I agree with this, I was just describing an alternative to refunds

I believe they are referring to the type of starter packs that are only on-sale to each player for a limited amount of time from when that specific player joins, unfortunately globally putting the gamepass offsale doesn’t work for this use-case.


At this point, it unfortunately seems like Roblox is, whether intentionally or not, pushing for us to make our own premium currencies just so we can handle purchase logic properly. Previously, afaik, the documentation mentioned that failed purchases would be met with a refund after 72 hours have elapsed. Now that is no longer the case and hasn’t been for years (and apparently, I didn’t even know about it since there was seemingly no announcement about the change)?

Adding back the 72-hour refund as-is wouldn’t work well, now that we have on-site DevProduct purchases where a player may not join. However, we still have no way to explicitly refund invalid states that are being called. To prevent developers from going into debt from refunding sales that have already passed escrow, perhaps pending DevProduct sales can remain in the escrow until they reach a longer expiration time (where they are auto-refunded) or reach a final result. Better yet, Roblox could also give us an option to allow pending sales to be sent to a random server for processing in the case the player doesn’t join (although it would be breaking behaviour, so it should be just an option). It would also be most ideal if we could have the option to run the callback automatically without a game server as-so really low-traffic games (with zero-players, at times; irregular jumps in player-count) can get the same behaviour, although that should also just be an option to prevent breaking behaviour.

Sorta sounds like this is what the request should be centered on. Products are meant for multiple-time purchases.

It would be nice if they extended the functionality of gamepasses to allow them to only be purchased in game, and be hidden from the website.

Multiple transactions occuring from a single purchase sounds like a bug, if I’m understanding correctly. The ability to deny the purchase of a product would still be useful for other issues, such as the player leaving example.

As for limiting the amount of times a player can purchase a product, yeah that would be useful too. Would save you time from making a datastore to see how many times a player has purchased it lol.