Skip to content

Parse StoreProduct prices culture-invariantly (Android sent 199.99 as 19999 on pt-BR devices) - #11

Merged
ianrumac merged 1 commit into
superwall:mainfrom
bilck:fix/culture-invariant-number-parsing
Sep 9, 2026
Merged

ianrumac merged 1 commit into
superwall:mainfrom
bilck:fix/culture-invariant-number-parsing

Conversation

@bilck

@bilck bilck commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Problem

DeserializeStoreProduct parses price and trialPeriodPrice with Convert.ToDouble(object). The iOS
bridge sends those as JSON numbers, but the Android bridge sends product.price.toString(), a string such as
"199.99". Convert.ToDouble(string) uses the device's current culture, so on any device whose locale
treats . as a grouping separator (pt-BR, de-DE, es-ES, fr-FR, ...) "199.99" parses as 19999.

Observed on a Moto G24 Power set to Portuguese (Brazil): StoreProduct.Price came back as 19999 for a
R$ 199,99 yearly subscription, and every consumer that reports the numeric price (revenue analytics,
present/future value fields) inherited the 100x error. iOS on the same product returned 199.9.

Fix

A small ToDoubleInvariant(object) helper: JSON numbers pass through, strings parse with
NumberStyles.Float and CultureInfo.InvariantCulture, anything else falls back to
Convert.ToDouble(value, InvariantCulture). Both price fields use it. No bridge change is required, so the
fix also applies to apps that do not rebuild the Android library.

Verification

Device (Android, pt-BR locale): StoreProduct.Price is 199.99 after the change. iOS unaffected (number
path). The integer fields (periodDays, trialPeriodDays, ...) are untouched: integers have no decimal
separator to misread.

Checked against superwall-android 2.7.23 (SuperwallUnityBridge.kt serializeStoreProduct) and
SuperwallKit 4.16.3.

🤖 Generated with Claude Code

https://claude.ai/code/session_01LTHPGB4qyAwDVYmQHW87ex

The Android bridge sends price and trialPeriodPrice as strings (BigDecimal.toString()),
and Convert.ToDouble(object) parses strings with the device culture, so "199.99" became
19999 on pt-BR / de-DE devices. Parse with the invariant culture and accept both the JSON
number the iOS bridge sends and the string the Android bridge sends.
@ianrumac
ianrumac merged commit 8764216 into superwall:main Sep 9, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants