Skip to content

[Bug] macOS: every store call falls through the iOS branch — purchases fail with "Unsupported platform" #353

Description

@kevenbauke

Library

openiap (Apple)

Library version

godot-iap 3.3.1, openiap-apple (native): 3.2.1

Affected platform

iOS

Store

App Store

Environment

Godot 4.7.1.stable.official.a13da4feb
macOS 26.5.2 (25F84)
Hardware Apple silicon (M5 Max), arm64 — not a simulator
Xcode 26.6 (17F113)
Swift 6.3.3 (swiftlang-6.3.3.1.3)
Export macOS, Apple silicon, Mac App Store distribution, sandboxed

What happened?

_platform is OS.get_name(), so "macOS" on a Mac. _init_native_plugin() is the only place that accounts for that:

# godot_iap.gd:99
if _platform == "iOS" or _platform == "macOS":

Every branch after it compares against "iOS" alone, so on macOS the plugin loads successfully and then takes a wrong path in each call. The three failures differ, and only the last one says anything:

  1. init_connection() returns true without contacting StoreKit. Neither branch matches, so it hits the else at line 309:
[GodotIap] Initializing native plugin...
[GodotIap] Platform: macOS
[GodotIap] Native plugin loaded via ClassDB (macOS)
[GodotIap] init_connection called
[GodotIap] No init method found, assuming connected     ← _is_connected = true

A false positive. The app believes it has a store connection it never opened.

  1. fetch_products() returns an empty list with no error. Both branches are skipped and it falls to line 480, return { "products": [], "subscriptions": [] } — indistinguishable from a SKU that doesn't exist in App Store Connect. This is what sent me chasing a store-configuration problem that wasn't there.

  2. request_purchase() fails outright. _request_purchase_raw() reaches its else at line 730:

return _purchase_failure("feature-not-supported", "Unsupported platform")

which is what the user sees when they press buy. get_active_subscriptions has the same explicit failure at line 1145; restore_purchases, finish_transaction, get_available_purchases, get_storefront, verify_purchase, deep_link_to_subscriptions and get_store all skip their Apple branch the same way.

The compound effect is that macOS looks healthy right up to the moment it matters — the extension loads, the connection reports success, and the only honest error arrives at the purchase itself. My own build reached TestFlight before I found it, because nothing before that point complains.

Expected behavior

macOS should behave as iOS does — connect to StoreKit, return products, and complete a purchase — since supported_platforms advertises it, the loader accepts it, and both platforms use the same native class with the same methods and payloads.

I have this fixed on a branch: an APPLE_PLATFORMS constant with an _is_apple() helper, used across the cross-platform surface (init_connection, end_connection, fetch_products, request_purchase, finish_transaction, restore_purchases, get_available_purchases, active subscriptions, get_storefront, verify_purchase, deep_link_to_subscriptions, get_store, purchase validation, product mapping, and _call_ios_async — the transport they all share). _platform keeps reporting the real OS, so logs stay truthful. The explicitly-named *_ios() helpers keep their iOS-only guards, since widening those is a naming decision rather than a bug fix.

Verified against a shipping game: before, requestPurchase → feature-not-supported: Unsupported platform; after, the call reaches StoreKit and returns a real StoreKit answer. iOS and Android are untouched — _is_apple() is true for exactly the platforms _platform == "iOS" was.

Reproduction steps

call init_connection() then request_purchase() on a macOS build with the plugin loaded. Runs from the editor as well as an exported app.

Logs or stack trace

Additional context

Reproduces both in the editor and in an exported app. Happy to open it as a PR, or to leave it with you if you'd rather patch it yourselves — just say which you prefer.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    godot-iapgodot-iap library🐛 bugSomething isn't working📱 iOSRelated to iOS

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions