Game Shop: free to play, live data, every payment checked, blockchain and NFTs managed
Kugle is free to play: the shop is what pays the studio. One shop for four stores, seven ways to pay, and it changes without a new version of the game.
- Data, not code: every item is set up in the admin dashboard, in production and in development.
- Every payment checked by the server, with each store: the game is never trusted.
- On-chain when it matters: eggs and tokens go to the player's wallet, the rest stays a fast database.
In-app payments: every way to pay, all integrated
Seven ways to pay, each one integrated end to end: the purchase in the game, the server that checks it, the refunds that come back later. The game only asks; the server decides.
| Pays with | Integration | Checked by the server |
|---|---|---|
| App Store | Unity IAP (StoreKit), App Store Server Library | the signed transaction, against Apple's root certificates; server notifications for refunds |
| Google Play | Unity IAP (Play Billing), Google Play Developer API | the purchase token, then acknowledged (or Google refunds it after 3 days); real-time notifications |
| Steam | Steam microtransactions (ISteamMicroTxn), with a sandbox | the price in the player's currency, the order finalized by the server, re-checked every day, refunds flagged |
| Card, Apple Pay, Google Pay | Stripe Checkout | a signed webhook, then the waiting sale is completed |
| PayPal | PayPal Orders: create, then capture | the capture, and a signed webhook |
| GU on-chain | wallet transfer | the transfer matched to the waiting sale |
A confirmation that arrives twice never credits twice. The server also enforces the rules: stock, limit per player, cooldown between two tickets, "coming soon".
Show the code: one purchase, four currencies
public async buyItem(user: User, purchaseData: ShopPurchaseData): Promise<Sale> {
const shopItem = await this.shopDao.getItemByPackId(purchaseData.packId);
if (!shopItem) {
throw applicationError("Shop item not found", 404);
}
await this.assertItemIsPurchasable(user, shopItem); // stock, limit per player, coming soon
this.assertClaimCooldownElapsed(user, shopItem); // tickets: hours between two claims
const paymentOption = this.resolvePaymentOption(shopItem, purchaseData.paymentCurrency);
// Free items are given right away
if (paymentOption.price === 0) {
return this.finalizeImmediateSale(user, shopItem, () =>
this.shopDao.createSale(user, shopItem, purchaseData, paymentOption, true, undefined, SaleProvider.Free)
);
}
switch (paymentOption.currency) {
case PaymentCurrency.Ticket:
case PaymentCurrency.GUV:
// paid from the balance in the database: settled now
return this.buyWithLoot(user, shopItem, purchaseData, paymentOption);
case PaymentCurrency.GU:
case PaymentCurrency.USD:
// paid outside (on-chain, store, card): the sale waits for the confirmation
return await this.shopDao.createSale(user, shopItem, purchaseData, paymentOption);
}
}
What is sold
Two currencies, Diamonds and GU, plus tickets and real money. Seven kinds of items: food and power-ups, emotes, potions, tickets that refill on a timer, egg boosters of an edition, tokens (Heat, Carbon) and in-app packs.




Data, not code: the shop is set up live
An item is a document in the database: name, picture, price in each currency, stock, limit per player, "coming soon", order on the screen. The team creates and changes them in the admin dashboard, in PROD and in DEV: a new pack, a sale, a price test, the monthly event items. No build, no store review.
Every tab of the shop, in the dashboard: one row per item, its price in each currency, its stock, and the Switch that opens or closes the whole shop.




Live switches too: open or close the shop, and a Steam-friendly mode that hides everything blockchain in the Steam build (Steam does not allow it).
On-chain when it matters
An egg booster is minted from its edition's smart contract, straight into the player's wallet. When the player pays in Diamonds, the studio pays the transaction for them: no wallet to fund, no gas to understand. Players can also sell their Kugles to each other on a player marketplace.
In the dashboard: the numbers
Every sale is recorded with its currency and who took the payment: the dashboard shows the month's sales, the totals per currency and the detail per item.

The page of the dashboard, filled with example data, not Kugle's real figures.
The shop of Kugle: Unity and C# in the game, Node.js and TypeScript for the API, Solidity for the contracts, React for the dashboard. Contact me if you are interested.
See also
- Kugle Corp: the studio, and free to play run on numbers.
- Kugle: the game and its monetization.



