Overview
In-app purchases (IAP) are real-money transactions where players purchase premium currency, items, or other content from app stores (Apple App Store, Google Play). The Keewano SDK provides dedicated methods to track both the monetary transaction and the virtual items granted from these purchases.
- Note
- Best Practice: Server-Side Validation
For optimal fraud prevention and accurate analytics, we strongly recommend calling these IAP tracking methods only after your server validates the purchase receipt with Apple/Google. This ensures your revenue data reflects genuine transactions and helps the Keewano AI Agents provide more accurate insights.
IAP vs Virtual Economy
It's important to understand the distinction between two types of transactions in your game:
- In-App Purchases (IAP): Real money → Virtual currency/items (tracked with ReportInAppPurchase and ReportInAppPurchaseItemsGranted)
- Virtual Economy: Virtual items → Other virtual items (tracked with ReportItemsExchange)
For example:
- Player buys "500 Crystals Pack" for $4.99 → IAP
- Player spends 100 Crystals to buy a sword → Virtual Economy (see In-Game Balance)
The Two IAP Methods
The Keewano SDK provides two separate methods for tracking in-app purchases:
1. ReportInAppPurchase - Track the Monetary Transaction
Use KeewanoSDK.ReportInAppPurchase() to log the real-money purchase event.
Definition KeewanoSDK.cs:18
static void ReportInAppPurchase(string productName, uint priceUsdCents)
Reports an in-app purchase event.
Definition KeewanoSDK.cs:290
Parameters:
- productId - The product identifier as defined in app stores (e.g., "com.mygame.crystals_500")
- priceInUsdCents - The price in US cents (e.g., $4.99 = 499)
When to call:
- ONLY after your server validates the purchase with Apple/Google
- ONCE per purchase (even if items are granted multiple times)
2. ReportInAppPurchaseItemsGranted - Track the Items Delivered
Use KeewanoSDK.ReportInAppPurchaseItemsGranted() to log the virtual items or currencies granted to the player from the purchase.
static void ReportInAppPurchaseItemsGranted(string productName, Item[] items)
Reports items granted from an in-app purchase.
Definition KeewanoSDK.cs:310
Represents a game item with a unique identifier and a quantity.
Definition KeewanoItems.cs:11
Parameters:
- productId - The same product identifier used in ReportInAppPurchase
- items - Array of items granted (can also use ReadOnlySpan<Item> for zero-copy performance)
When to call:
- ONLY after items are successfully granted to the player's account
- Every time items are granted (can be multiple times for monthly/daily packages)
Why Are These Two Methods Separated?
These methods are separated because the purchase event and item grant event may happen at different times:
Common Cases for Separation
- Asynchronous Server Validation: Purchase completes → server validates → items granted later
- Monthly Packages: Player purchases once, but receives items daily/weekly over a month
- Time-Limited Offers: Purchase validated immediately, but items granted when player claims them
- Login Rewards: Player purchases a "30-Day Login Bonus" pack → items granted each day they log in
- Failed Grants: Purchase validated successfully, but item grant fails (network issue, database error) → retry later
Example: Monthly Login Package
A player purchases a "Monthly Gems Package" for $9.99 that grants 100 gems every day for 30 days:
void OnMonthlyPackagePurchased()
{
}
void OnDailyLogin()
{
if (PlayerHasActiveMonthlyPackage())
{
}
}
The Complete Purchase Flow
Here's the recommended flow for handling in-app purchases:
Flow Diagram
sequenceDiagram
actor Player
participant Game
participant Store as App Store
participant Server as Your Server
participant API as Apple/Google API
participant SDK as KeewanoSDK
Player->>Game: 1. Click "Buy" button
activate Game
rect rgb(200, 230, 201)
note right of Game: Keewano Auto-Tracking
Game->>SDK: 2. (Automatic) ReportButtonClick()
end
Game->>Store: 3. Initiate purchase
deactivate Game
activate Store
Store->>Store: 4. Process payment
Store->>Game: 5. Purchase receipt
deactivate Store
rect rgb(255, 243, 224)
note right of Game: Server Validation Phase
activate Game
Game->>Server: 6. Validate receipt
activate Server
Server->>API: 7. Verify receipt
activate API
API-->>Server: 8. Valid confirmation
deactivate API
Server->>Server: 9. Grant items to player
Server-->>Game: 10. Confirm grant
deactivate Server
end
activate Store
Game->>Store: 11. Finalize/acknowledge purchase
Store-->>Game: 12. Purchase complete
deactivate Store
rect rgb(200, 230, 201)
note right of Game: Keewano Reporting Phase
Game->>SDK: 13. ReportInAppPurchase()
Game->>SDK: 14. ReportInAppPurchaseItemsGranted()
deactivate Game
end
Common Scenarios
Scenario 1: Immediate Grant (Synchronous)
The most common case where items are granted immediately after validation.
void OnPurchaseValidated(
string productId, uint priceUsdCents,
Keewano.
Item[] grantedItems)
{
}
Scenario 2: Delayed Grant (Asynchronous)
Purchase is validated first, items are granted later.
void OnPurchaseValidated(string productId, uint priceUsdCents)
{
}
void OnItemsGrantedFromPurchase(
string productId,
Keewano.
Item[] grantedItems)
{
}
Scenario 3: Monthly/Daily Packages
Player purchases once, receives items over time.
void OnVIPPassPurchased()
{
};
}
void OnDailyLogin()
{
if (PlayerHasActiveVIPPass())
{
};
}
}
Scenario 4: Bundle with Multiple Items
When a purchase grants multiple different items.
void OnStarterPackPurchased()
{
string productId = "com.mygame.starter_pack";
uint price = 999;
};
}
Scenario 5: Purchase Validated but Grant Fails
If the purchase is valid but item grant fails temporarily.
void OnPurchaseValidated(string productId, uint priceUsdCents)
{
bool success = TryGrantItemsToPlayerAccount(productId);
if (success)
{
}
else
{
}
}
static void LogError(string message)
Reports a technical issue encountered during gameplay.
Definition KeewanoSDK.cs:627
Best Practices
Server Validation is Critical
❌ NEVER do this:
void OnAppStoreCallback(Purchase purchase)
{
}
✅ ALWAYS do this:
void OnAppStoreCallback(Purchase purchase)
{
YourServerAPI.ValidatePurchase(purchase.receipt, OnValidationComplete);
}
void OnValidationComplete(ValidationResult result)
{
if (result.isValid)
{
}
}
- Note
- Server validation implementation is your responsibility. You must integrate with Apple's App Store Server API or Google Play Developer API to verify purchase receipts. This documentation shows when to call the Keewano SDK methods, not how to implement server validation.
Use Consistent Product IDs
Use the same product ID for both methods:
string productId = "com.mygame.crystals_500";
Only Report Actually Granted Items
Only call ReportInAppPurchaseItemsGranted() when items are successfully added to the player's account:
bool itemsGranted = AddItemsToPlayerInventory(items);
if (itemsGranted)
{
}
Prices Must Be in USD Cents
Always convert prices to USD cents, regardless of the player's local currency:
uint priceUsdCents = ConvertToUsdCents(localPrice, localCurrency);
Report Purchase Once Only
For packages where items are granted multiple times, only call ReportInAppPurchase() once when the purchase is made:
String Parameter Limits
Product IDs and item names are limited to 255 characters and will be trimmed if longer. Empty or null strings will skip the event.
See Also