Skip to content

[Bug]: iOS SDK sends invalid "purchases" delta with localized amount ("12,99"), causing OSRequestUpdateProperties to fail with 400 #1617

@norinCreative

Description

@norinCreative

What happened?

When calling OneSignal.User.addTag (or any update to user properties), the iOS SDK automatically includes a deltas.purchases block in the OSRequestUpdateProperties request.
The problem: the SDK sends an invalid amount value, such as a localized string "12,99" instead of a valid number (12.99).
Because of this, the server returns:

400 Bad Request
Invalid number found in purchase amount

As a result, the entire update request fails, and no tags are saved.

Steps to reproduce?

1. On the device, go to Settings → General → Language & Region → Number Format and set it to the European style: 1.234.567,89 (comma as the decimal separator).
2. Install and run an app using OneSignal iOS SDK 5.2.15
3. Ensure the device has an active or restored in-app subscription (so the SDK has purchase data to send).
4. Initialize OneSignal normally.
5. Call:

OneSignal.User.addTag("onboardingState", "uncompleted")

6. Observe the outgoing request:

"deltas": {
  "purchases": [
    {
      "count": 6,
      "iso": "USD",
      "sku": "com.example.app.6months",
      "amount": "12,99"
    }
  ]
}

7. The server responds with HTTP 400, and the tag is not applied.

What did you expect to happen?

• The amount field should always use a valid numeric format (12.99), independent of device locale.
• Localized formatting should never affect purchase metadata.
• Invalid purchase data should not prevent unrelated updates (like user tags).

OneSignal iOS SDK version

Release 5.2.15

iOS version

18

Specific iOS version

* iOS 26.1
* iOS 18.5

Relevant log output

Request:

VERBOSE: HTTP Request (OneSignalUser.OSRequestUpdateProperties) with URL: https://api.onesignal.com/apps/fd7b372b-0c9a-4e0d-b8cd-0bf58a9f4acb/users/by/onesignal_id/106011a0-0bf0-4477-aff5-dc782acdd1c9, with parameters: {
  "refresh_device_metadata" : false,
  "properties" : {
    "tags" : {
      "onboardingState" : "uncompleted"
    }
  },
  "deltas" : {
    "purchases" : [
      {
        "count" : 6,
        "iso" : "USD",
        "sku" : "com.myCompany.myApp.6months",
        "amount" : "12,99"
      }
    ]
  }
} and headers: {
    "OneSignal-Subscription-Id" = "bc95e7e3-8803-47c4-a9eb-d739589e715a";
}


Result:

VERBOSE: network response (OneSignalUser.OSRequestUpdateProperties) with URL https://api.onesignal.com/apps/fd7b372b-0c9a-4e0d-b8cd-0bf58a9f4acb/users/by/onesignal_id/106011a0-0bf0-4477-aff5-dc782acdd1c9: {
    errors =     (
                {
            code = "request-4";
            title = "Invalid number found in purchase amount";
        }
    );
    headers =     {
        "Access-Control-Allow-Origin" = "*";
        "Alt-Svc" = "h3=\":443\"; ma=86400";
        "Content-Length" = 83;
        "Content-Type" = "application/json; charset=utf-8";
        Date = "Sun, 30 Nov 2025 13:48:48 GMT";
        Priority = "u=3,i=?0";
        Server = cloudflare;
        "Strict-Transport-Security" = "max-age=15552000; includeSubDomains";
        Via = "1.1 google";
        "access-control-allow-headers" = "SDK-Version,Content-Type,Origin,Authorization,OneSignal-Subscription-Id";
        "cf-cache-status" = DYNAMIC;
        "cf-ray" = "9a6acdf25f3cd624-LCA";
        "server-timing" = cfExtPri;
        traceparent = "00-bd1a92f5036503589242a78742941a7a-18d50805e3eccea9-00";
    };
    httpStatusCode = 400;
}

Code of Conduct

  • I agree to follow this project's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions