Guides
The hosted shop
Open a ready-made shop page for your game, identify the player with a signed link or an e-mail code, and bring them back to your game after a purchase.
On this page
What you get
Every game can have a hosted shop: a public page at /shop/<your game slug> where a player sees their balance, buys packs, types a gift code or a creator code, and finds their latest purchases with the receipt. It is built for phones first, works in French, English and Dutch, and needs no code from you beyond a link.
Use it when your game runs on a phone, in an engine without a good checkout, or simply when you do not want to build a shop screen. The payment page, the VAT, the receipt and the withdrawal consent are the ones of GameCoin, as with any pack purchase.
What the player sees:
| Part | What it shows |
|---|---|
| Header | The shop name and tagline you chose, a link back to your game, the language switch (FR, EN, NL). |
| Balance | One card per currency, with the paid coins and the free coins told apart. |
| Code | A single field. A valid gift code is used at once and the balance updates. A creator code is kept for the next purchase and shown with its bonus. |
| Packs | Price in euros with VAT included, a badge (popular, best value, founder), the stock left and a countdown if you set an availability, and the states scheduled, sold out and ended. Before your launch the button says « pre-order ». |
| Purchases | The latest orders with their state and a link to the receipt. |
Note
The shop is part of the founder pack and codes features: see Founder packs and Gift codes and creator codes. Anything you set there appears in the shop.
Turn it on
In the dashboard (in French for now), open your game, then Boutique. Nothing is public until you tick Activer la boutique: until then the address answers « page not found », exactly as if it did not exist, whether the game is unknown, archived or has its shop switched off.
| Setting | Meaning |
|---|---|
| Activer la boutique | Turns the page on. |
| Nom affiché, Accroche | The name and the welcome sentence. The game name is used when the name is empty. |
| Couleur d'accent | One of eight colors. The contrast of the text on each color (white or dark, at least 4.5:1) is checked, so the shop stays readable. |
| URL de retour | Where the player goes back to after a purchase, in a web game. |
| Schémas d'application | Where the player goes back to in a phone app. |
| Indexation | Whether search engines may list the shop. Off by default. |
The page shows a live preview and a button that opens your shop in test. Changing the settings needs the role developer; the role support can read them.
Open the shop from your game
The shop knows who the player is from a player token: the short token (one hour) your backend creates with POST /players/{player}/tokens, or the one the browser SDK holds for an anonymous player. Put it in the link:
https://<your-gamecoin-host>/shop/<your-game-slug>?t=<player token>&locale=enCreate the token on your server and build the link:
curl -X POST "https://gamecoin.apilow.com/api/v1/players/ext%3Auser-42/tokens" \
-H "Authorization: Bearer $GAMECOIN_SECRET_KEY" \
-H "Idempotency-Key: shop-link-user-42-1" \
-H "Content-Type: application/json" \
-d '{}'const { token } = await gamecoin.players.createToken("ext:user-42");
const link = `https://<your-gamecoin-host>/shop/my-game?t=${encodeURIComponent(token)}&locale=en`;Open the link in the browser of the player: a button, a window.open, the system browser of a phone, or an in-app web view.
What happens, so that the token never lingers:
- The shop checks that the game has a shop and that the token is valid, unexpired and made for this game.
- It swaps the token for a shop session: a signed cookie that is
HttpOnly,SameSite=Lax, limited to the path/shop/<your game slug>and valid for one hour at most. The player is then sent to the shop without the token in the address. - The shop sends
Referrer-Policy: same-originandX-Robots-Tag: noindex, so the token is never sent as aRefererand the pages are not indexed.
The session is not an API token: it works only on the shop of that game. A link that is invalid, expired, made for another game, or for a player who is blocked, simply lands on the screen Retrouve ton compte with a notice. It never says which of these is the case.
The environment
The player token carries the environment: a test token opens the shop in test (a banner says so, and the payments are simulated), a live token opens it in live. Nothing else in the address can switch to live.
The language
The language is the one of the request: the locale parameter (fr, en or nl) when you give it, otherwise the Accept-Language header of the browser, otherwise French. Amounts and dates are written with the rules of that language.
When the player has no link
Without a valid token the shop shows Retrouve ton compte: the player types an e-mail address, receives a six-digit code, and gets back the player that is linked to that address. It is the e-mail sign-in of the browser SDK, with the same rules: a code lasts ten minutes, five tries, and the answer is the same whether the address is known or not.
Two things to know:
- The address must already be linked to a player from your game. The shop does not create players.
- Signing in to the shop does not change the secret that the game keeps on the device: the player stays signed in in the game.
For a game in test, add ?env=test to the address to open the screen in the test environment: https://<your-gamecoin-host>/shop/<your-game-slug>?env=test. Only test is accepted from the address.
Buy, pay and come back
A click on a pack creates the order (like POST /client/me/checkouts) and sends the player to the hosted payment page, where the country, the VAT and the withdrawal consent are confirmed. The shop asks for the return in both cases, success and cancel, so the player always comes back.
The return goes through /shop/<your game slug>/return, which sends the player to what you declared in the settings, in this order:
- A phone app. If the link of the shop carries
r=<scheme>and that scheme is in your Schémas d'application, the player is sent to<scheme>://shop/return?order=<order id>&status=<status>. Browsers on phones often block a redirect to an app scheme, so the player lands on a small page with a real button, Retourner dans le jeu, and the shop also tries to open the app by itself. - A web page. Otherwise, if you set an URL de retour, the player is redirected to it with
orderandstatusadded. - The shop. Otherwise the player goes back to the shop, which reads the order and tells the result at the top: confirmed, being confirmed (the page refreshes by itself), declined, canceled or expired.
Add the app scheme to the link when your game is an app:
https://<your-gamecoin-host>/shop/<your-game-slug>?t=<player token>&r=mygameThe values are strict: order must be an order identifier and status one of the order states, otherwise the player is simply sent back to the shop. A scheme you did not declare is ignored, and the settings refuse javascript:, data:, file:, http, https and the other schemes that are not apps. The address of the return always comes from your settings, never from the request, so the shop cannot be used to redirect a player to another site. Your URL de retour must be https (http only for localhost, to test).
Warning
status in the return address is only a hint. Anyone can type it. Confirm the purchase from your backend with GET /orders/{order} or from the order.fulfilled webhook before you rely on it.
Codes in the shop
The code field takes both kinds of code and the server decides:
- A creator code is kept for the next purchase (it lives in the shop session) and shown with its bonus, with the exact amount of free coins on each pack it covers. The player can remove it. It is checked again, with the pack, when the order is created.
- Otherwise the text is tried as a gift code: if it is valid it is used right away, the free coins and items are added and the balance updates. A gift code never gives paid coins.
A refused code always gets the same answer, whether it is unknown, expired, used up, disabled or already used by that player. The tries are limited per player and per address, whether they work or not. See Gift codes and creator codes.
Search engines
Shops are noindex by default. If you tick Indexation, only the page seen without signing in is open to search engines: a title and a description about your game, in the three languages, a canonical address, hreflang links, and a place in the sitemap for the games that are live. The page of a signed-in player (balance, purchases) is never indexed.
Each language has its own address, https://<your-gamecoin-host>/shop/<your-game-slug>?locale=fr, ?locale=en or ?locale=nl.
Embedded in a web page
The same page can run in an iframe, at /shop/<your game slug>/embed: no header and no footer, a transparent background, a height that follows its content, a light or dark theme. The easy way is the shop widget: one script, GameCoinShop.open({ gameSlug, token }), a modal that is accessible from the keyboard, and events for the balance and the purchases. It also explains how to add it to a GDevelop or Construct game.
What to know here:
- Who can frame it. Only the pages in the allowed origins of the game (« Réglages »). In
livethe list is mandatory; intestan empty list allowshttp://localhostandhttp://127.0.0.1. Every other page of GameCoin refuses to be framed. - The player. An iframe of another site cannot keep a cookie, so the embedded shop swaps the player token (
?t=) for a signed ticket of one hour that it sends back with each action. Without a valid token the shop says that the session has expired and tells the widget, which tells your game. - The payment. It opens in its own window, since the payment page cannot be shown in an iframe; the shop follows the order by itself and announces the end.
- The messages. The shop talks to your page with
postMessage:gamecoin:ready,gamecoin:balance,gamecoin:purchased,gamecoin:height,gamecoin:close(Escape inside the shop) andgamecoin:error. The target is always the exact origin of your page, and only if it is in the allowed origins; never*. Your page should use the widget rather than read them itself.
| You want to | Use |
|---|---|
| Send the player to a page of GameCoin and bring them back | The link of this page |
| Show the shop in a window over your web game, or inside a page | The shop widget |
| Draw your own shop screen | The browser SDK and your own buttons |
Limits and good practice
- The shop session lasts one hour. After that the player opens the shop again from the game, or signs in with the e-mail code.
- A player sees only their own balance, orders and codes. The shop never shows an e-mail address.
- The tokens you put in links are short-lived: create one when the player taps the button, not in advance.
- Keep
testandliveapart: the same slug serves both, and the player token says which one.