Repository navigation
Support custom products in the purchase controller - #23
Merged
Merged
Conversation
Custom products (store "Custom" on the dashboard) are bought through the game's own payment system. Android failed them in the bridge, and iOS sent them to PurchaseFromAppStore as if they were App Store products. Both now call IPurchaseController.PurchaseCustomProduct with the product ID, the customTransactionId Superwall generated and, on Android, any subscription it replaces. The method's default implementation fails the purchase, so existing controllers compile unchanged.
Maple review🟢 Confidence 10/10 · safe to merge. Request-shape and callback tests cover the new contract, replacement parsing, legacy-controller fallback, and thrown exceptions; real-device checkout remains unverified. Routes custom-product purchases to a dedicated C# controller callback on Android and iOS, preserving transaction IDs and Android replacement details. No merge-blocking defects found.
|
|
Warning The review of |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Custom products (store set to Custom on the Superwall dashboard) are sold through the game's own payment system: Stripe, Paddle, a web checkout or another store. With a purchase controller set, both native SDKs hand them to the controller, but the Unity bridges didn't support them:
"The Unity purchase controller does not handle custom products"), so C# never saw the request.PurchaseFromAppStorewith only the ID, so a controller tried to buy them from StoreKit with an ID Apple doesn't have.Changes
IPurchaseController.PurchaseCustomProduct(CustomProductPurchase purchase, Action<PurchaseResult> completion).CustomProductPurchasecarriesProductId,CustomTransactionId(Superwall's pre-generated transaction ID, to send back from the server ascustom_transaction_idfor revenue attribution) and, on Android,Replacement. The default implementation fails the purchase, so existing controllers compile and behave as before.isCustomProductproducts go topurchaseCustomProductwithfullIdentifier,customTransactionIdand any replacement. Play products are unchanged. The request JSON is built bygooglePlayPurchaseRequest/customProductPurchaseRequestso it can be unit-tested.StoreProduct.isCustomProductis internal in SuperwallKit, so the bridge usescustomTransactionId. It's public, andTransactionManager.prepareToPurchasesets it only for custom products, before calling the purchase controller. The routing is inpurchaseRequest(productIdentifier:customTransactionId:callbackId:).[Unreleased]changelog entry.Tests
All run locally:
PurchaseRequestTest, 4 new): JSON for custom products with and without a transaction ID and replacement, plus the unchanged Play shape. 21/21 pass on AGP 8.5.2 and 9.0.1,assembleReleasetoo.PurchaseRequestTests, 2 new): custom products go topurchaseCustomProduct, App Store products topurchaseFromAppStore. 12/12 pass on the simulator with SuperwallKit 4.19.1.BridgeContractTests, 4 new): a request reachesPurchaseCustomProductwith its fields and the reply reaches native; replacement parsing; a controller without the method repliesfailedand never reaches the store methods; a throwing controller repliesfailed. 54/54 pass inci~/csharp-harness, and theUNITY_IOS/UNITY_ANDROIDbuilds compile.Not tested end to end with a real custom product on a device; the test project has none set up.
🤖 Generated with Claude Code