Fighting Game · Guides & deep dives

V2 Premium Currency System

local minor-unit price, provider, region, display text id, and enabled state.

4sections3 minread

On this page

PremiumCurrencySystem.V2 is the gameplay-side bridge between platform store receipts and ServerCurrencyAuthority.V2. It does not replace App Store or Google Play server validation. Instead, it consumes the verified receipt result, checks that the product is allowed to grant premium currency, rejects unsafe receipts, and fulfills the purchase through the same auditable ledger path used by server-authored economy mutations.

Runtime Surface#

  • FV2PremiumCurrencyProduct maps a platform SKU to a premium currency grant, local minor-unit price, provider, region, display text id, and enabled state.
  • FV2PremiumCurrencyCatalog stores the purchasable product catalog and the accepted store environments such as production and sandbox.
  • FV2PremiumCurrencyReceipt is the server-verified purchase evidence. It includes product id, store SKU, transaction id, optional original transaction id, Google Play purchaseToken, signed payload, signature, receipt fingerprint, account binding, environment, quantity, claimed grant amount, refund state, and verification state.
  • FV2PremiumCurrencyStoreVerificationEndpoint describes the platform server API surface the commerce service must call before fulfillment.
  • ValidatePremiumCurrencyCatalog proves that real-money products only grant currencies flagged as premium in CurrencyDefinition.V2.
  • ValidatePremiumCurrencyReceipt rejects missing account bindings, missing signed receipt evidence, unverified receipts, refunded receipts, expired receipts, environment mismatches, replayed receipt fingerprints, disabled products, SKU/provider mismatches, non-premium currency grants, and claimed amount mismatches.
  • FulfillPremiumCurrencyPurchase builds a platform.iap ledger grant and applies it through ServerCurrencyAuthority.V2; it never writes balances directly.

Store Integration#

Apple receipts are represented by the App Store Server API transaction lookup: GET /inApps/v1/transactions/{transactionId}. The commerce service stores the verified signedTransactionInfo payload, transaction id, original transaction id when present, account binding, environment, and a stable receipt fingerprint before calling gameplay fulfillment.

Google Play receipts are represented by the Google Play Developer API purchases.products.get endpoint: GET /androidpublisher/v3/applications/{packageName}/purchases/products/{productId}/tokens/{token}. The commerce service passes the verified ProductPurchase payload, product id, order/transaction id, purchaseToken, account binding, environment, and receipt fingerprint into FV2PremiumCurrencyReceipt.

The gameplay layer treats bStoreVerified as a prerequisite. A receipt with the right shape but no server verification is rejected.

Fulfillment Rules#

  1. Premium currency products must have a product id, store SKU, provider, positive price, positive grant amount, region, ISO currency code, and a currency id present in CurrencyDefinition.V2.
  2. Real-money products may only grant currencies where IsPremiumLike() is true. The default catalog grants currency.gems.
  3. Receipt product id, SKU, provider, store environment, account id, platform account hash, payload, signature, transaction id, and receipt fingerprint are mandatory.
  4. Google Play fulfillment also requires purchaseToken.
  5. Refunded, expired, unverified, disabled-product, and mismatched-provider/SKU receipts fail before any ledger request is built.
  6. Claimed grant amount must equal (GrantAmountMinorUnits + BonusAmountMinorUnits) * Quantity.
  7. Receipt replay is blocked by deterministic transaction ids plus ledger tags for iap.receipt.<fingerprint> and iap.transaction.<transactionId>.
  8. Fulfillment uses SourceId = platform.iap, requires the source to be trusted by ServerCurrencyAuthority.V2, and records premium.currency audit tags on the immutable currency ledger.

Validation Commands#

Run these checks when touching premium currency behavior:

bash
python3 V2/ue/Tools/check-v2-premium-currency-system.py
python3 V2/ue/Tools/check-v2-server-currency-authority.py
python3 V2/ue/Tools/check-v2-currency-ledger.py
python3 V2/ue/Tools/check-v2-currency-definition.py
python3 V2/ue/Tools/check-v2-ci-workflow.py
python3 -m json.tool V2/ue/Content/V2/Gameplay/Economy/PremiumCurrencySystem_V2_Contract.json
python3 -m json.tool V2/ue/Build/Horde/v2-buildgraph-job.json
python3 V2/tools/validate-v2-docs.py

Official platform references:

  • Apple App Store Server API: https://developer.apple.com/documentation/appstoreserverapi
  • Apple Get Transaction Info: https://developer.apple.com/documentation/appstoreserverapi/get-transaction-info
  • Google Play purchases.products.get: https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.products/get
  • Google Play ProductPurchase: https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.products