feat: Add PaywallListener for purchase lifecycle callbacks#804
feat: Add PaywallListener for purchase lifecycle callbacks#804
Conversation
…Paywall Adds a PaywallListener interface with onPurchaseStarted, onPurchaseError, and onPurchaseCancelled callbacks, wired into both the regular and express purchase flows. Deprecates PresentPaywallParams.onPurchaseError in favor of listener.onPurchaseError. Adds toast notifications to the example app paywall launcher page to demonstrate the listener in action. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
45c02cc to
6a01732
Compare
…f PurchasesError Matches the signature of the deprecated PresentPaywallParams.onPurchaseError for consistency. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Deduplicates the try/catch-wrapped listener calls from both the regular and express purchase flows into notifyPurchaseStarted and notifyPurchaseError helper functions. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
| display: "flex", | ||
| flexDirection: "column", | ||
| gap: 8, | ||
| zIndex: 1000003, |
There was a problem hiding this comment.
This puts it on top of both the paywall and the purchase screens.
nicfix
left a comment
There was a problem hiding this comment.
Overall the approach makes sense, I just think the callbacks for the express purchase button should be passed to the presentExpressPurchaseButton method to make sure they are then passed to the right callbacks inside the component that renders it.
As they are now:
- The start purchase will be called every time a Express purchase button is rendered, not clicked
- The purchase cancelled works, but if we move it inside the presentExpressPurchaseButton we make it available to that method as well
src/main.ts
Outdated
| return {}; | ||
| } | ||
| let buttonUpdater: ExpressPurchaseButtonUpdater | null = null; | ||
| notifyPurchaseStarted(pkg); |
There was a problem hiding this comment.
This is not really the right spot for the ExpressPurchaseButton.
Basically it will be triggered by any rendering of the button in this place.
We should probably expose an explicit parameter to the presentExpressPurchaseButton and pass it down to the component that handles it.
There was a problem hiding this comment.
Ohhh my bad... I should have tested that flow 🥴. I will address this next week. Thanks for the feedback!!
There was a problem hiding this comment.
No worries, Express Purchase Button it's a bit tricky!
src/main.ts
Outdated
| if (paywallParams.onPurchaseError) { | ||
| paywallParams.onPurchaseError(err); | ||
| } | ||
| notifyPurchaseError(err); |
There was a problem hiding this comment.
We could pass this to the presentExpressPurchaseButton method as parameter so that it's handled by it instead of here.
Summary
PaywallListenerinterface withonPurchaseStarted,onPurchaseError, andonPurchaseCancelledoptional callbacks for observing purchase lifecycle events withinpresentPaywallPresentPaywallParams.onPurchaseErrorin favor oflistener.onPurchaseError(both still called when both are provided)Test plan
paywall-listener.test.ts(6 tests) passapi-extractor🤖 Generated with Claude Code