Cannot handle unfinished consumable in Transaction.currentEntitlements when testing Ask to Buy in Xcode

(This is the duplicate of https://developer.apple.com/forums/thread/718948 because I accidentally marked it as completed.)

I am trying to test Ask to Buy for consumable product. When the transaction was approved, the process stops at a breakpoint in Transaction.updates. However, when I call Transaction.currentEntitlements after that, I cannot handle transaction of consumables. Here is my code.

func newTransactionListenerTask() -> Task<Void, Never> {

    Task(priority: .background) {
        for await verificationResult in Transaction.updates {

            guard
                case .verified(let transaction) = verificationResult,
                transaction.revocationDate == nil
            else { return }
        
            // Breakpoint stops here
            await refreshPurchasedProducts()

            await transaction.finish()
        }
   }
}

func refreshPurchasedProducts() async {
    for await verificationResult in Transaction.currentEntitlements {

        guard case .verified(let transaction) = verificationResult else { return }

        switch transaction.productType {
        case .consumable:
            // This code is not called
            updateConsumablePurchaseCount(productID: transaction.productID)
        default:
            break
        }
    }
}

I do not call transaction.finish() if the purchase result is .pending as shown in the code below.

    func purchase(_ info: ConsumableProductInfo) async throws {
        let result: Product.PurchaseResult
        switch info {
        case .coffee:
            guard let coffeeProduct else { return }
            result = try await coffeeProduct.purchase()
        }
        switch result {
        case let .success(verificationResult):
            switch verificationResult {
            case let .verified(transaction):
                await refreshPurchasedProducts()
                await transaction.finish()
            case let .unverified(_, verificationError):
                throw verificationError
            }
        case .pending, .userCancelled:
            break
        @unknown default:
            break
        }
    }

When I test Ask to Buy I'm not calling transaction.finish() so I should be able to get the consumable transaction in Transaction.currentEntitlements, however I couldn't.

I found a blog post that is similar to this problem: https://iosexample.com/implementing-and-testing-in-app-purchases-with-storekit2-in-xcode-13-swift-5-5-and-ios-15/ It says that "In tests I've done transactions for consumables do not remain in the receipt, even if you omit to call finish()."

So I wonder if this is a bug or problem in my coding.

Answered by Frameworks Engineer in 741734022

Transaction.currentEntitlements never includes consumable in-app purchases, even if they are unfinished. The documentation says:

Consumable in-app purchases also don't appear in the current entitlements. To get transactions for unfinished consumables, use the unfinished or all sequences in Transaction.

For your specific use case, I would recommend checking Transaction.unfinished since that will include all unfinished transactions, including transactions for consumable in-app purchases.

Accepted Answer

Transaction.currentEntitlements never includes consumable in-app purchases, even if they are unfinished. The documentation says:

Consumable in-app purchases also don't appear in the current entitlements. To get transactions for unfinished consumables, use the unfinished or all sequences in Transaction.

For your specific use case, I would recommend checking Transaction.unfinished since that will include all unfinished transactions, including transactions for consumable in-app purchases.

Cannot handle unfinished consumable in Transaction.currentEntitlements when testing Ask to Buy in Xcode
 
 
Q