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:
- 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.
-
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.
-
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.
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:
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:
A false positive. The app believes it has a store connection it never opened.
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.
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.