Use this page with AI

Copy this into your coding assistant and add your request.

Read https://openiap.dev/docs/events/purchase-updated-listener and https://openiap.dev/llms.txt. Follow the reading instructions, detailed reference, and linked guides relevant to my task before making changes.
Inspect my existing project and reuse its framework and conventions. Ask me for missing product decisions. Implement the requested behavior and run the applicable checks.
Show the working result, the commands and actual test results, and any remaining limitations. Keep your explanation brief.

My request: [describe what customers should be able to do]
See an example request →

purchaseUpdatedListener

Fired when a purchase is successful or when a pending purchase is completed.

Duplicate Transaction Replays on iOS

StoreKit can replay the same unfinished transaction through more than one native path during a single connection session. By default, OpenIAP delivers one purchaseUpdated event per iOS transaction ID to purchase-success listeners, while still keeping distinct transactions separate. This prevents entitlement delivery from running twice for the same purchase.

For diagnostics, register the purchase update listener with dedupeTransactionIOS: false. The flag belongs to the purchase update listener only; purchase error listeners do not receive successful StoreKit transactions. Android ignores this iOS-only option.

Listener Setup

swift
let subscription = OpenIapModule.shared.purchaseUpdatedListener(
    { purchase in
        print("Purchase updated: \(purchase.productId)")
    },
    options: nil
)

Registers a listener for successful purchase events.

Opt In to iOS StoreKit Replays

swift
let subscription = OpenIapModule.shared.purchaseUpdatedListener(
    { purchase in
        print("StoreKit replay or first delivery: \(purchase.id)")
    },
    options: PurchaseUpdatedListenerOptions(
        dedupeTransactionIOS: false
    )
)
swift
import OpenIap

let subscription = OpenIapModule.shared.purchaseUpdatedListener { purchase in
    Task {
        print("Purchase updated: \(purchase.productId)")

        // Verify and deliver
        if await verifyPurchaseOnServer(purchase) {
            await deliverProduct(purchase.productId)
            try await OpenIapModule.shared.finishTransaction(
                purchase: purchase,
                isConsumable: false
            )
        }
    }
}

// Cleanup when done
OpenIapModule.shared.removeListener(subscription)

Event Payload

The purchase event delivers a Purchase object containing transaction details.

Purchase Update Flow

  1. Receive Purchase object via listener
  2. Validate receipt with backend service
  3. Deliver purchased content to user
  4. Finish transaction with finishTransaction (handles acknowledgment on both platforms)
  5. Update application state