Payments
On this page
Gully Pay is the payment gateway for every Gully product, games included. In-game purchases, paid calls and top-ups go through Gully Pay checkout and webhooks, not through a store's own crypto code or a separate card processor wired into the game.
There are two shapes of payment:
| Shape | When | How |
|---|---|---|
| x402 pay-per-call | small paid API calls: a level download, a hint, a premium match | X402Client in the game, your server verifies with Gully Pay |
| Checkout | buying items, passes, currency packs | Gully Pay hosted checkout, your server is told by a webhook |
Heads up
Mobile builds sold through the App Store or Google Play have their own rules on digital goods and crypto. Read Store policy before you add any payment to a mobile build.
#x402 pay-per-call
x402 uses the HTTP status 402 Payment Required. Your server answers a request with 402 and its payment requirements; the client pays on chain and retries with the payment in the X-PAYMENT header; your server verifies the payment with Gully Pay and serves the resource.
game ──GET /paid/level-7──────────────▶ your server
◀──402 + requirements──────────────
game ──pays on Gully Chain (ITransactionSender)
game ──GET /paid/level-7 + X-PAYMENT──▶ your server ──verify (API key)──▶ Gully Pay API
◀──200 + content───────────────────In Unity, X402Client does the whole client side:
using GullyLabs.GameSdk;
var x402 = new X402Client(); // PreferredNetwork = "gully-chain-testnet"
var result = await x402.GetAsync("https://your-backend.example/paid/level-7", mySender);Step by step, if you need control over each part:
X402Requirements req = X402Client.ParseRequirements(response); // from the 402
X402Accept option = x402.Choose(req); // picks the Gully Chain option
TransactionRequest tx = X402Client.BuildPaymentTx(option); // send it from the player's account#Verification happens on your server
The game never talks to the Gully Pay API with a key. Your resource server receives the X-PAYMENT header and verifies it by calling the Gully Pay API (https://gullypay.xyz/api, GullyChain.GullyPayApi) with its own Gully Pay API key. Only after Gully Pay confirms the payment does the server return the content.
Heads up
A Gully Pay API key in a game build can be extracted by anyone. Keep it on the server, in that server's secret store, never in the repo.
#Checkout for in-game purchases
For item and currency purchases, the flow is the standard Gully Pay merchant flow:
- Your game server creates a checkout for the player and the item.
- The game opens the hosted checkout page (
checkout.gullypay.xyz) in the system browser or a web view. - The player pays; Gully Pay settles on Gully Chain.
- Gully Pay calls your server's webhook; the server verifies the signature and grants the item (in Nakama storage, on chain, or both).
- The game refreshes the player's inventory from the server.
Grant items only from the verified webhook, never from a client-side "payment done" message.
#glUSD on the testnet
glUSD ("Gully USD") is Gully Pay's stablecoin. On Gully Chain Testnet it is minted 1:1 against USDC.e by a PSM (peg stability module) and is always redeemable 1:1 for USDC.e.
| Token | Address |
|---|---|
| glUSD | 0xDBE84bE6496Fb3d07F601548555ec7Acc4CeBa8F (opens in a new tab) |
| glUSD PSM | 0xe1Ae51036ede1b244c532A81FaC196f19fa5E28e (opens in a new tab) |
var bal = await Erc20.BalanceOfAsync(rpc, "0xDBE84bE6496Fb3d07F601548555ec7Acc4CeBa8F", player);Note
Testnet only. glUSD on this testnet is a technical preview with no value. It is not offered to the public as a redeemable dollar, and the mainnet plan is to work with a regulated issuer. Do not market glUSD balances to players as money.
#Rules
- All billing goes through Gully Pay.
- Prices shown in the game come from the server, not from constants in the build.
- Every grant is idempotent: a webhook can arrive twice.
- Keep a server-side record of each purchase for refunds and support.