TeamGames Storefront Java SDK
Welcome! This guide walks you through the Java helpers that ship with the TeamGames platform. It is written for developers who are new to the SDK and want a practical, end‑to‑end integration path.
1. Before You Start
Java 8 or newer
All helpers compile against Java 8 bytecode.
TeamGames API key (TEAMGAMES_API_KEY)
Authenticates every request. Grab it from the TeamGames dashboard.
Internet access to https://api.teamgames.io/
The helpers point to this domain by default.
Tip: Export your API key once in your shell profile (
export TEAMGAMES_API_KEY=...) so every demo and integration code picks it up automatically.
2. Core Building Blocks
StoreCatalogClient
Facade
Fetches the product catalog (sync or async).
StoreCheckoutClient
Facade
Builds carts and submits checkout requests.
StoreClaimClient
Facade
Retrieves undelivered purchases and marks them delivered.
StoreCatalog / StoreCheckout / Transaction
Builders & DTOs
Provide strongly typed requests/responses underneath each facade.
JsonPost / Post
HTTP helpers
Handle headers, environment switching, pooled connections, and timeouts.
Thread.executor
Shared executor
Default async runner used across clients (override with your own pools if needed).
Usage pattern:
Instantiate a client once per API key.
Call
newRequest()(or equivalent) to get a single-use builder.Configure the request (username, cart items, preview flag).
Execute synchronously (
execute(),fetch(),submit()) or asynchronously (executeAsync(), etc.).
3. Deliver Purchases (Claim API)
import com.teamgames.endpoints.store.StoreClaimClient;
import com.teamgames.endpoints.store.Transaction;
StoreClaimClient claimClient = new StoreClaimClient(apiKey);
Transaction.ClaimResponse claimResponse = claimClient.newRequest()
.playerName("Player123")
.useV4Endpoint() // structured envelope (recommended)
.preview(false) // set to true for dry runs
.includeRawTransactions(false) // opt-in when you need audit metadata
.execute();
if ("SUCCESS".equals(claimResponse.status)) {
for (Transaction tx : claimResponse.data.claims) {
System.out.printf("Grant product %s (id=%s) x %d%n",
tx.product_name,
tx.product_id_string,
tx.product_amount);
}
} else if ("PREVIEW".equals(claimResponse.status)) {
System.out.println("Preview only: " + claimResponse.message);
} else {
System.out.println("Claim error: " + claimResponse.code + " :: " + claimResponse.message);
}Need audit info? Flip .includeRawTransactions(true) (or inspect claimResponse.data.rawTransactions) to fetch the raw database rows as JsonObject[]:
for (com.teamgames.lib.gson.JsonObject raw : claimResponse.data.rawTransactions) {
String invoice = raw.has("invoice") ? raw.get("invoice").getAsString() : null;
String gateway = raw.has("paymenttype") ? raw.get("paymenttype").getAsString() : null;
System.out.printf("Invoice %s paid via %s%n", invoice, gateway);
}
ClaimResponse.codewill beSUCCESS,NO_ITEMS,RATE_LIMIT,SERVER_NOT_FOUND, etc. Show those messages to your players for friendlier feedback.
Prefer async? The same flow works with executeAsync()—reuse the shared executor or plug in your own:
claimClient.newRequest()
.playerName("Player123")
.useV4Endpoint()
.preview(false)
.includeRawTransactions(false)
.executeAsync()
.thenAccept(response -> {
if ("SUCCESS".equals(response.status)) {
for (Transaction tx : response.data.claims) {
System.out.printf("Grant product %s (id=%s) x %d%n",
tx.product_name,
tx.product_id_string,
tx.product_amount);
}
} else {
System.out.println("Claim status: " + response.code + " :: " + response.message);
}
})
.exceptionally(ex -> {
ex.printStackTrace();
return null;
});4. Optional: Build a Custom Storefront UI
Want to mirror the web store inside your game launcher or website? Use the catalog and checkout helpers below. Skip this section if you only need to fulfill purchases.
4.1 Fetch the Product Catalog
import com.teamgames.endpoints.store.StoreCatalogClient;
String apiKey = System.getenv("TEAMGAMES_API_KEY");
StoreCatalogClient catalogClient = new StoreCatalogClient(apiKey);
StoreCatalog.CatalogResponse catalog = catalogClient.fetch();
System.out.println("Products available: " + catalog.products.length);Need async?
catalogClient.fetchAsync()
.thenAccept(result -> System.out.println("Fetched " + result.products.length + " products"))
.exceptionally(ex -> { ex.printStackTrace(); return null; });4.2 Build and Submit Checkout
import com.teamgames.endpoints.store.StoreCheckoutClient;
import com.teamgames.endpoints.store.StoreCheckout;
StoreCheckoutClient checkoutClient = new StoreCheckoutClient(apiKey);
StoreCheckoutClient.CheckoutRequest checkout = checkoutClient.newRequest()
.username("Player123");
checkout.addItem(42, 1); // product id, quantity
checkout.addItem(84, 3);
StoreCheckout.CheckoutResponse response = checkout.submit();
if ("SUCCESS".equals(response.status)) {
System.out.println("Redirect player to: " + response.redirect);
} else {
System.out.println("Checkout failed: " + response.code + " :: " + response.message);
}Async submission works the same way using submitAsync() (optionally with your own executor).
5. Going Async
Every client exposes *Async() variants. By default they use Thread.executor, a shared thread pool that ships with the SDK. To control concurrency:
ExecutorService gameExecutor = Executors.newFixedThreadPool(4);
claimClient.newRequest()
.playerName("Player123")
.useV4Endpoint()
.executeAsync(gameExecutor)
.thenAccept(response -> grantItems(response))
.exceptionally(ex -> { log.error("Claim failed", ex); return null; });Remember: each newRequest() builder is single-use. Create a fresh one for every call.
6. HTTP Configuration & Connection Pooling
The SDK reuses HTTP connections and sets sensible defaults:
Connect timeout
10 seconds
-Dteamgames.http.connectTimeoutMs=5000
Read timeout
15 seconds
-Dteamgames.http.readTimeoutMs=15000
Keep-alive
Enabled
-Dteamgames.http.keepAlive=false to disable
Max pooled connections
50
-Dteamgames.http.maxConnections=100
Add the flags to your JVM or application server startup command. Keep-alive dramatically improves performance on busy servers—leave it on unless a proxy requires otherwise.
7. Troubleshooting
IllegalArgumentException: API key must not be null
Forgot to set the env variable
export TEAMGAMES_API_KEY=... (or call .setApiKey(...)).
HTTP 401 or SERVER_NOT_FOUND
Wrong/rotated API key
Refresh the key in the dashboard and redeploy.
NO_ITEMS on claim
Nothing pending for that player
Verify the username matches checkout exactly; try preview mode first.
RATE_LIMIT on claim
Player is requesting too fast
Cache the last claim timestamp and wait ~10 seconds.
JsonSyntaxException
Unexpected payload (network proxy, HTML error page)
Log the raw response body and HTTP status; fire a support ticket if TeamGames API is down.
Still stuck? Check the SDK tests (StoreClaimClientTest, TestStoreCommand) for working examples, or open an issue with logs attached.
8. Where to Go Next
REST endpoints — Need raw HTTP details or building a non-Java integration? See
docs/storefront-rest-endpoints.md.Server delivery guide — Step-by-step instructions for handing out items in-game:
docs/store-server-integration.md.Checkout deep dive — Advanced validation and error handling:
docs/store-checkout-api.md.
Happy shipping! If the docs miss something you expected, please let the team know so the next developer has an even smoother journey.
Last updated
Was this helpful?