PlaySuper LogoPlaySuper
Web SDK

Core Usage

Sign players in, show coin balances, award coins from your server, open the store and react to store events with the PlaySuper Web SDK

Every method below is on the PlaySuper object. Methods that call PlaySuper return a promise; on failure they resolve to null (or false) and log the reason to the browser console with a [PlaySuper] prefix, rather than throwing.

Players

Players are identified by your game's player ID, the same one your game already uses. There is no PlaySuper login screen.

// Once per player, the first time they play (safe to repeat):
await PlaySuper.createPlayerWithUuid(myPlayerId);

// On every session:
const login = await PlaySuper.loginFederatedByStudio(myPlayerId);
if (login?.access_token) {
  // signed in
}

PlaySuper.isLoggedIn();   // true while a player is signed in
PlaySuper.logout();       // when the player signs out of your game

The session is remembered in the browser, so a returning player is still signed in after a reload. If your backend already obtained a PlaySuper player token, pass it with PlaySuper.setAuthToken(token) instead.

Coins

Show the balance

const balances = await PlaySuper.getBalance();
// [{ id: 'coin-id', name: 'Gems', url: 'https://…/gem.png', amount: 120 }]

Signed out, getBalance() lists your game's coins with an amount of 0.

Award and deduct coins from your server (v2 API)

Award and deduct coins only from your server, never from the browser. Anything your web page does can be repeated by the player with any amount, and the server secret these calls need must never be in the page.

Web integrations must use the v2 coin API: POST /v2/coins/:coinId/distribute and POST /v2/coins/:coinId/deduct. Do not use the v1 endpoints (/coins/:coinId/distribute and /coins/:coinId/deduct) from a web game: they accept the public API key alone, so they cannot tell your server apart from a player.

The Web SDK has no method to award or deduct coins. Your game reports what happened to your own backend; your backend checks it, decides the amount, and calls the v2 API. Every v2 call carries four headers:

HeaderValue
x-api-keyYour Game API key
x-api-secretYour server secret. Server only, never in the page.
x-game-uuidThe player, by the same ID you signed them in with
x-idempotency-keyUnique per coin movement, for example your event or order ID. A retry with the same key never moves coins twice.

Award coins:

curl -X POST "https://api.playsuper.club/v2/coins/YOUR_COIN_ID/distribute" \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-api-secret: YOUR_SERVER_SECRET" \
  -H "x-game-uuid: PLAYER_ID" \
  -H "x-idempotency-key: level-12-complete-PLAYER_ID" \
  -d '{ "amount": 100 }'

Deduct coins:

curl -X POST "https://api.playsuper.club/v2/coins/YOUR_COIN_ID/deduct" \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "x-api-secret: YOUR_SERVER_SECRET" \
  -H "x-game-uuid: PLAYER_ID" \
  -H "x-idempotency-key: shop-order-8841" \
  -d '{ "amount": 40 }'

Response 201:

{
  "message": "Coin distribution initiated",
  "transactionId": "txn-1a2b3c4d-5678-90ab-cdef-1234567890ab",
  "replayed": false
}

replayed: true means that idempotency key was already used: nothing moved, and the response carries the original transaction.

While you test, use your test key against https://dev.playsuper.club; there the v2 API works without a server secret. For production, ask PlaySuper to turn on server-side coins for your game at engineering@playsuper.club, then generate the server secret on the console's API Keys page. The API reference lists every error.

A server route in Node.js, as an example. The browser sends only which event happened; the server, not the page, decides how many coins it is worth:

// POST /api/level-complete, called by your game with your own player session.
app.post('/api/level-complete', requirePlayerSession, async (req, res) => {
  const { levelId } = req.body;
  const amount = REWARD_FOR_LEVEL[levelId]; // decided here, never sent by the browser
  if (!amount) return res.status(400).end();

  const r = await fetch(`https://api.playsuper.club/v2/coins/${COIN_ID}/distribute`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-api-key': process.env.PLAYSUPER_API_KEY,
      'x-api-secret': process.env.PLAYSUPER_SERVER_SECRET,
      'x-game-uuid': req.player.id,
      // One key per real event: a retry, or a double click, pays once.
      'x-idempotency-key': `level-${levelId}-${req.player.id}`,
    },
    body: JSON.stringify({ amount }),
  });
  res.status(r.ok ? 200 : 502).end();
});

Then refresh the balance you show with PlaySuper.getBalance().

Receive store purchases and refunds

When a player spends coins in the store, or gets coins back from a refund, PlaySuper calls your server with a webhook (COINS_DEBITED, COINS_REFUNDED, COINS_CREDITED). Each event carries the player ID, the coin, the change and the new balance. If your game keeps its own copy of the balance, update it from the webhook.

No backend? Your game can still sign players in, show balances, open the store and show touchpoints, but it cannot award or deduct coins: that needs a server. Keep no copy of the balance in the page; show getBalance(), and refresh it when the store reports a purchase (see Store events).

Open the store

button.addEventListener('click', () => PlaySuper.openStore());

Call openStore() from a click or tap handler. With storeMode: 'tab', browsers block a store opened any other way.

To open the store at a specific product or reward, pass its store link, for example the one a touchpoint gives you:

PlaySuper.openStore('https://store.playsuper.club/gcommerce/products/PRODUCT_ID');

Links that are not PlaySuper store links open in a new tab, without the player's credentials. You can also close the store from your code with PlaySuper.closeStore().

Store events

const offOpened = PlaySuper.on('storeOpened', () => pauseGame());
const offClosed = PlaySuper.on('storeClosed', () => resumeGame());
const offBought = PlaySuper.on('storeTransaction', () => refreshCoins());
EventWhen
storeOpenedThe store is shown
storeClosedThe player is back in your game (Continue playing, back button, Escape, or a click outside the panel)
storeTransactionThe player bought or redeemed something with coins. Refresh the balance you show; your server also receives the webhook

Each on call returns a function that removes the listener.

Analytics

The SDK sends the same events as the Unity SDK, with no code from you: game opened and closed, store opened and closed, and touchpoint impressions and clicks. Each event carries your game, the player once signed in, your appVersion, and the device's OS and model.

To attach your own attributes to every event, use user properties. Never put personal data (names, emails, phone numbers) in them:

PlaySuper.setUserProperties({ level: 12, vip: true });
PlaySuper.clearUserProperties();

Next step

Touchpoints: show reward widgets in your game.