Skip to main content

In-game purchases

Funox supports in-game purchases through an Xsolla integration. The Funox SDK provides a signed Xsolla token for the current player; you call Xsolla's Shop Builder API to list items and complete checkout.

Sign-in required

The player must be signed in to make a purchase. Verify with getUser() before showing your store.

High-level flow

  1. Player signs in to Funox.
  2. Game calls getXsollaUserToken() to get a short-lived Xsolla token.
  3. Game lists items via Xsolla's Shop Builder API using the token.
  4. Player picks an item and confirms purchase.
  5. Game opens the PayStation widget for checkout.
  6. Game (or your backend) checks order status before granting items.

getXsollaUserToken()

Returns a short-lived Xsolla token tied to the current Funox user.

JavaScript1 line
1const xsollaToken = await window.Funox.SDK.iap.getXsollaUserToken();

Get a fresh token before each purchase — tokens are short-lived.

Listing items

Use Xsolla's REST API. Funox stores your project ID in the Developer Portal.

JavaScript4 lines
1const items = await fetch(2  `https://store.xsolla.com/api/v2/project/${XSOLLA_PROJECT_ID}/items/virtual_items`,3  { headers: { Authorization: `Bearer ${xsollaToken}` } }4).then((r) => r.json());

Opening PayStation

JavaScript14 lines
1import { XPayStationWidget } from "@xsolla/paystation-widget";2 3XPayStationWidget.init({4  access_token: xsollaToken,5  sandbox: process.env.NODE_ENV !== "production",6  lightbox: {7    width: "740px",8    height: "760px",9    closeByClick: false,    // required10    closeByKeyboard: false, // required11  },12});13 14XPayStationWidget.open();

Tracking orders

Once a purchase completes, log it to Funox analytics:

JavaScript1 line
1window.Funox.SDK.analytics.trackOrder("xsolla", order);

Pass the order object Xsolla returns. We use this for revenue attribution.

Granting items

Do not grant items based on a client-side webhook alone. Use one of:

  • Your own backend that listens to Xsolla's webhooks.
  • Poll Xsolla's inventory API after purchase confirmation.

Order statuses returned by Xsolla:

  • new — created, not yet paid
  • done — payment completed
  • canceled — payment failed or cancelled

Grant items only on done.

Requirements

  • User must be signed in before launching PayStation.
  • Use Funox userId (from a verified token) when registering purchases server-side.
  • Provide a clear close button in your purchase confirmation UI.
  • Disable closeByClick and closeByKeyboard on the PayStation lightbox.
  • Test thoroughly in sandbox mode before launch.

Lootbox / region restrictions

Lootbox-style mechanics are restricted in:

  • Belgium, China, Netherlands, Serbia, Slovakia — sales not allowed.
  • Taiwan, South Korea, Japan — additional disclosure / odds requirements.

Disable lootbox SKUs in these regions or face removal from the platform.

Full example

JavaScript23 lines
1async function showStore() {2  const user = await window.Funox.SDK.user.getUser();3  if (!user) {4    await window.Funox.SDK.user.showAuthPrompt();5  }6 7  const xsollaToken = await window.Funox.SDK.iap.getXsollaUserToken();8  const items = await fetchItems(xsollaToken);9  renderItems(items);10}11 12async function buy(itemSku) {13  const xsollaToken = await window.Funox.SDK.iap.getXsollaUserToken();14  const paymentToken = await createPaymentToken(itemSku, xsollaToken);15 16  XPayStationWidget.init({17    access_token: paymentToken,18    sandbox: false,19    lightbox: { closeByClick: false, closeByKeyboard: false },20  });21 22  XPayStationWidget.open();23}