question

angelsinhbfs avatar image
angelsinhbfs asked

Negative virtual currency

during testing a tester was able to continue purchasing after they had run out of virtual currency for quite a while


10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brendan avatar image
brendan answered

Could you provide some specifics on the test case? What were the prices on the items, how quickly were the calls made, etc.? Also, what API methods are you using to make these purchases? Looking in your game's catalog, I'm not seeing any VC prices on the items.

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

angelsinhbfs avatar image
angelsinhbfs answered

ok he was making the purchases through a store which is why the vc prices werent there. I think the thing he was buying was 400-500 scrap [SC] he was doing things fairly quickly (approx 10 sec per purchase). I was on voice chat with him at the time and he started laughing saying that it was letting him keep purchasing after he had negative currency. When i tried to look at his profile i got a "Trouble loading profile" error message. I am using the following to make the purchase.
PlayFabClientAPI.PurchaseItem(new PurchaseItemRequest()
{
ItemId = ItemName.text,
StoreId = "MainShop",
VirtualCurrency = "SC",
Price = int.Parse(ScrapPrice.text)
}, OnVCPurchase, OnPlayfabError);

 

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brendan avatar image
brendan answered

Do you mind if I create a profile in your title, to do some testing? This does not reproduce in my test title, regardless of whether I use a Catalog price or a Store price.

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

angelsinhbfs avatar image
angelsinhbfs answered

go for it. The whole situation seemed weird, with the whole profile becoming unavailable while it was happening. I added some checks on my end before it ever calls to make the purchase, but it was definitely getting the updated information from playfab saying his current vc balance was negative when he was still making purchases.

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brendan avatar image
brendan answered

Sorry, but it doesn't reproduce in your title, either. I granted 10,000 Scrap to the account, then purchased an item from the Shop that cost 4,000 Scrap. I didn't wait as long as your tester - only a second or two, then purchased it again. On the third PurchaseItem call (again after only a couple of seconds), I got the expected "Insufficient Funds" error.

If you can reproduce this, can you provide a detailed step-by-step?

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

angelsinhbfs avatar image
angelsinhbfs answered

seems like it was just a one time glitch then hmm. I added some more code to check on my side just in case

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

angelsinhbfs avatar image
angelsinhbfs answered

it happened again, but only to -1700 this time. 

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brendan avatar image
brendan answered

Could you please provide the repro steps, so that we can try this on our side - specific items, balances, etc.?

10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Hamza Lazaar avatar image
Hamza Lazaar answered

This issue occurred in my game.

By default 1000 virtual currency is granted for each user.

I've looked at the purchases history of that account and I've found 3 purchases with 2 seconds difference between each -100, -1000 and -100.

so now the user has -200 balance.

@Brendan let me know how I can help to identify the root cause of this.

2 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

brendan avatar image brendan commented ·

What's the Title ID and PlayFab ID in question, so that we can have a look at the events?

0 Likes 0 ·
Hamza Lazaar avatar image Hamza Lazaar brendan commented ·

TitleID: 2169

PlayFabID: A87B7470F4AEDC76

0 Likes 0 ·
brendan avatar image
brendan answered
@Hamza Lazaar

Thanks, Hamza. The problem in this case appears to be that the client isn't waiting on the response from the previous call before making the subsequent ones. So, when call 1 (to subtract 100) was issued the balance was 1000. But since the client didn't wait for completion, when call 2 came in (to subtract 1000), call 1 wasn't done, and the balance still looked like 1000. When call 3 came in (100 more), it looked like 900 (call 1 was done, but not 2), and so it also ran.

2 comments
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Hamza Lazaar avatar image Hamza Lazaar commented ·

So you're considering this OK? I think it's problematic and should not happen.

I think virtual currency should not be negative and the server should have an atomic operation to update it which looks like it is not the case.

The purchases history of that user shows that there is a 2 seconds difference between each call.

In the example also, if call 1 and 3 were executed successively then call 2 should fail since the balance should not permit it.

Any way I added a loader animation to block user input until a purchase call is complete (successful or not) and I added an error log in case a negative balance is detected.

This is still not perfect as we can't prevent this from happening if there is an issue with the input or someone is tampering with our app/title.

0 Likes 0 ·
brendan avatar image brendan Hamza Lazaar commented ·

Specifically, what I'm saying is that we cannot guarantee atomicity on that call. So if simultaneous commands are sent (in this case, commands overlapping such that one is submitted before another has completed), it's possible for this to occur. An animation or similar technique to prevent a player from hammering on a call is definitely the right way to go.

0 Likes 0 ·

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.