We wanted payments to be simple.
For those unfamiliar, the original prototype for CubedPay aimed to allow for users to have a complete payment experience in the server. There would never be a need to bounce the user to a web browser or make them jump through hoops to finally obtain their item. (Make sure your username is CaSe SeNsItIvE, be online, 1 free inventory slot...)
Servers would run their own installation of CubedPay (then called Minepay, before we knew that the name was actually in use by someone else.) on their own servers, similar to how a host would purchase a license for WHMCS. The idea was that if a server never had to "call home" to us, allowing uptime to lie solely with the server. I'll talk more about why this didn't work out like we wanted later on.
Problem 1. No Client/Server Relationship
As open as Minecraft is, it isn't without problems. Minecraft offers no ability to prompt for user-input that's handled by the client, and wanting to do so would require the user to install a mod. This is a big no no, as it limits your possible user-base right away. (Who wants to install a mod to spend money?) Any possibility of tokenizing payment data from the client was off the table.
Possible Solution 1. Setup and Tokenize in Browser, Authorize In-Game
This second concept is what we were going to go with for the original idea, except for one difference. Users would only have to visit an external webpage once to save their PayPal or credit card (obviously tokenized) with the server. Future payments could be handled in-game with ease!
However... this required us to put too much trust into Minecraft servers, still.
This goes back to the problem of a missing client/server relationship in Minecraft. We couldn't actually ask the player if they were okay with a specific charge in a way the server current interfere with.
- Chat prompt? player.chat()
- Chest GUI? Throw your own InventoryClickEvent.
- Run a command? Do it for the player.
We couldn't confidently trust that the player was the one making the authorization. Even if we could, we couldn't be sure that the server wasn't intercepting a players' payment passcode. We had to face the fact that doing a payment entirely in-game could never safely happen. We settled on...
Solution 1. Checkout in Browser
This was the final, and current solution we decided to move towards. With the inability to trust a server, and no way to prompt the client in-game safely, we had to move the checkout to the browser.
But it had to be fast...
...and not filled with 200 required fields...
...and not require redirection to a 3rd-party payment provider.
We looked at all the popular payment providers and saw a trend. Every Minecraft payment provider had the same checkout experience.
- Visit webstore (likely from a non-smart and generic link in-game)
- Click a category or item
- Enter username
- Enter billing details
- Agree to Terms of Service
- Click payment provider
- Proceed to be redirected and probably have to enter personal details again
- Redirect back to webstore and be told that your item will be delivered in some specific amount of time that's almost never accurate
We didn't have to handle in-server payments in-game at all, we just had to make it smarter.
Instead of checkout taking 8 steps, we've streamlined it into 3:
- Visit webstore via smart and contextually aware URL in-game. Through our API, this checkout session is already aware of the player's character name, item being purchased, discounts, and any other referral data you want to pass to us.
- Agree to Terms of Service
- Click Pay (We just use whatever you used last time, by default.)
Through the magic of webhooks and sockets, we can tell you that the payment was completed in near-realtime. Without compromising the security and safety of users, we've increased the checkout speed to almost what it would be if it had been entirely in-game. No redirects, no re-entering details, no hassles to find the items you want.
So it may not be what we set out to be, but we think it's a pretty good alternative.
Problem 2. Decentralized Installations
We really loved the idea of having users maintain their own copies of CubedPay, but we quickly realized the significant issues with the idea:
- Lack of Update Control. Deploying new features, bug fixes, and security patches would be much more complex if everyone hosted it themselves. There would be numerous customers undoubtedly using outdated versions or not taking the time to update and patch issues.
- Possibility to inject malicious code. We were going to use IONCube Loader in the original prototype to help prevent users tampering with some source code, but we quickly realized how little that would help against someone determined to screw over their customers. We couldn't risk having software that would make it extremely easy to harvest payment data if someone chose to be malicious with our software.
- Piracy. We need to fund development somehow. Developing and maintaining a licensing system would have been much more hassle than it's worth, and it would have gone against our idea of requiring users to "call home" to keep licenses active.
Solution 2. Moving to "The Cloud"
We dropped the idea of going with the self-hosted approach earlier this year, and have focused on re-designing our platform on Google Cloud. This approach addresses all 3 issues above, and gives us the ability to offer some features that otherwise would not have been possible, like...
- ... a centralized account system
- ... a way to remember payment methods over multiple servers
- ... a way for users to see and manage their transactions from one place
- ... unmatched analytics and insights on your customers
- ... and much more.
We've changed a lot since our original prototype, but it definitely ended up being for the better, and it's going to be great when you can finally see it for yourself.