What does Transaction.RefundRequestError.failed mean?

Transaction.RefundRequestError.failed means the App Store could not take the refund request you submitted.

Quick facts#

Error Transaction.RefundRequestError.failed
Where StoreKit 2, Swift (Transaction.beginRefundRequest(in:))
Available since iOS 15.0, iPadOS 15.0, macOS 12.0, tvOS 17.0, watchOS 10.0, visionOS 1.0
What the vendor says The refund request submission failed.

Cause#

  • Apple says a submission can fail for many reasons, such as an invalid transaction identifier, or because the App Store cannot process the request for another reason.
  • It is different from duplicateRequest, which means a request for the transaction already exists.
  • The refund sheet needs a transaction the App Store knows, so passing the ID of an unverified or unrelated transaction fails.

Fix#

  1. Get the transaction with Transaction.latest(for:) and only offer the request for a .verified result.
  2. Pass that transaction's own id and a scene that is on screen.
  3. Tell the person the request could not be sent and let them try again later. Retrying at once is unlikely to help.
  4. Log the error and transaction ID. Refund requests can be tested in the sandbox, as Apple's refund testing guide describes.

Example#

Swift
import StoreKit
import UIKit

// A failed submission: say so, and offer a later retry.
@MainActor
func requestRefund(productID: String, in scene: UIWindowScene) async {
    guard let result = await Transaction.latest(for: productID), case .verified(let transaction) = result else {
        print("No verified transaction to refund")
        return
    }
    do {
        let status = try await transaction.beginRefundRequest(in: scene)
        print("Refund request status: \(status)")
    } catch Transaction.RefundRequestError.failed {
        print("The refund request could not be submitted; try again later")
    } catch {
        print("Refund request error: \(error)")
    }
}

Compile-checked: npm run check:snippets type-checks this snippet with swiftc against the Apple SDK (macOS target, checked 2026-10-03).

How the RevenueDot SDK reports it#

The RevenueDot purchases-ios fork wraps this in beginRefundRequest(forEntitlement:). It logs "Refund request submission failed" and reports the failure as ErrorCode.beginRefundRequestError (code 31).

Source#

Checked: 2026-10-03

Edit this page on GitHub ↗ View as Markdown Last updated