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_amountuses two decimal places (except for zero-decimal currencies like JPY/KRW). - Always log the raw store
transaction_idororiginal_transaction_idalongside 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_idwas 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_typeparameter:INTRODUCTORY_PRICE,PROMOTIONAL_OFFER,SUBSCRIPTION_OFFER_CODE, orSTANDARD_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.