Engineering Schemas

In-App Purchase Event Schema Auditing: A Telemetry Checklist

Published on August 8, 2026 • By Tinnakorn Prasert
In-App Purchase Event Schema Auditing: A Telemetry Checklist

A major source of distorted customer lifetime value tracking stems from errors in client-side in-app purchase (IAP) event schemas. Simple oversights—such as submitting unnormalized local currencies or failing to implement transaction idempotency—can corrupt data warehouses and make acquisition campaigns appear wildly profitable or catastrophic.

Below is the technical checklist our consultants use during client telemetry code audits.


1. Currency & Revenue Normalization

Mobile apps are purchased in over 170 local currencies. If an event payload sends raw numerical values without ISO 4217 standard currency codes, warehouse ingestion layers will sum Japanese Yen, British Pounds, and Thai Baht into a single distorted revenue column.

Standardized Payload Schema

{
  "event_name": "in_app_purchase_completed",
  "transaction_id": "GPA.3341-9281-0029-19283",
  "product_id": "com.app.subscription.annual_premium_v2",
  "product_type": "auto_renewable_subscription",
  "revenue_local_amount": 119.00,
  "currency_code": "USD",
  "revenue_usd_equivalent": 119.00,
  "exchange_rate_applied": 1.0000,
  "is_introductory_offer": false,
  "paywall_source": "onboarding_step_4"
}
  • Ensure revenue_local_amount uses two decimal places (except for zero-decimal currencies like JPY/KRW).
  • Always log the raw store transaction_id or original_transaction_id alongside the event.

2. Enforcing Transaction Idempotency

When a user completes an in-app purchase on a poor mobile connection, the payment gateway may successfully charge the card while the client app experiences a timeout. Upon reconnecting, the app may retry the purchase completion handler multiple times.

  • Client Guard: Maintain a local SQLite/Key-Value cache of dispatched transaction identifiers. If an event with the same transaction_id was already successfully dispatched to the telemetry endpoint, suppress duplicate network events.
  • Warehouse Deduplication Query: Configure warehouse views with ROW_NUMBER() OVER (PARTITION BY transaction_id ORDER BY event_timestamp ASC) to filter out duplicate records during ETL transformations.

3. Separating Introductory Offers From Standard Renewals

A common reporting error occurs when introductory promotional rates (such as a $0.99 first month promotion) are recorded with the parent product SKU’s standard price ($9.99/mo).

  • Explicitly include the offer_type parameter: INTRODUCTORY_PRICE, PROMOTIONAL_OFFER, SUBSCRIPTION_OFFER_CODE, or STANDARD_RECURRING.
  • Store the actual amount charged at the moment of the transaction, not the recurring renewal catalog price.

4. Verification of StoreKit 2 Transaction JWS Verification

With iOS 15+ and StoreKit 2, all transactions are signed using JSON Web Signature (JWS). Client apps must verify cryptographic authenticity before dispatching analytics events to ensure mock jailbroken receipts are excluded from official revenue ledgers.

By enforcing strict event schemas and verifying server receipts, mobile engineering teams provide growth leaders with reliable data to scale acquisition investments with confidence.

Need Direct Audit Assistance?

Facing Discrepancies in Your App's LTV Reporting?

Our team reviews client-side event tracking, store billing webhooks, and cohort models to identify tracking leaks and incorrect retention forecasts.