subscriptionBillingIssueListener
Fired when a subscription enters a state that needs user attention because of a payment problem — card declined, expired payment method, billing retry, or grace period. Unifies StoreKit 2 Message.billingIssue (iOS/iPadOS/Mac Catalyst 16.4+ and visionOS 1.0+) and Play Billing Purchase.isSuspended (Play Billing Library 8.1+) under a single cross-platform stream. Silent no-op on platforms that cannot emit (tvOS, watchOS, macOS, Meta Horizon, Amazon Appstore).
Listener Setup#
// iOS/iPadOS/Mac Catalyst 16.4+; visionOS 1.0+
func subscriptionBillingIssueListener(
_ listener: @escaping @Sendable (Purchase) -> Void
) -> SubscriptionThe emitted Purchase is a regular subscription payload — use productId, purchaseToken, and platform fields to prompt the user to update payment. Play deduplicates by purchaseToken per session; iOS fires per Message delivery.
On Apple platforms, StoreKit's system billing message is still presented through Message.display(in:). This listener is an additional notification for your app; it does not replace or suppress the default StoreKit UI.
Example#
import OpenIap
// iOS/iPadOS/Mac Catalyst 16.4+; visionOS 1.0+
let subscription = OpenIapModule.shared.subscriptionBillingIssueListener { purchase in
print("Billing issue on \(purchase.productId)")
Task { await showBillingIssueBanner(purchase) }
}
// Cleanup when the view disappears
OpenIapModule.shared.removeListener(subscription)See Subscription Billing Issue feature guide for platform coverage, signal sources, and UX recommendations.