---
title: "What does Transaction.RefundRequestError.duplicateRequest mean?"
description: "Transaction.RefundRequestError.duplicateRequest means the App Store already has a refund request for this purchase. Check the transaction first, then do not send it again."
url: https://revenuedot.app/docs/errors/storekit-refund-error-duplicate-request
---

# What does Transaction.RefundRequestError.duplicateRequest mean?

Transaction.RefundRequestError.duplicateRequest means the App Store has already received a refund request for this In-App Purchase.

## Quick facts

| | |
|---|---|
| Error | `Transaction.RefundRequestError.duplicateRequest` |
| Where | StoreKit 2, Swift (`Transaction.beginRefundRequest`) |
| Available since | iOS 15.0, iPadOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, visionOS 1.0 |
| What the vendor says | The App Store has already received a refund request for this In-App Purchase. |

## Cause

- Apple says StoreKit returns this error when the App Store already holds a refund request for the transaction and the decision is still pending, was denied or was approved.
- The person (or your code) called `beginRefundRequest` for a transaction that already has a request. Sending it again cannot change the outcome.
- Apple suggests checking the transaction's refund state before you call the method, to see whether the App Store has already refunded it.

## Fix

1. Before you offer a refund request, check the transaction's `revocationDate` and `revocationReason`. If the App Store has already refunded the purchase there is nothing to request.
2. Tell the person a request already exists, and that Apple makes the decision.
3. Do not call the method again for the same transaction.
4. Test refund requests in the sandbox or in Xcode first, as Apple's refund testing guide describes.

## Example

```swift
import StoreKit
import UIKit

// A second request for the same transaction cannot work: say so, and stop.
@MainActor
func requestRefund(productID: String, in scene: UIWindowScene) async {
    guard let result = await Transaction.latest(for: productID), case .verified(let transaction) = result else { return }
    // Apple suggests checking the refund state first: a revoked transaction is already refunded.
    if transaction.revocationDate != nil {
        print("The App Store already refunded this purchase")
        return
    }
    do {
        let status = try await transaction.beginRefundRequest(in: scene)
        print("Refund request status: \(status)")
    } catch Transaction.RefundRequestError.duplicateRequest {
        print("A refund request for this purchase already exists; Apple decides it")
    } catch {
        print("Refund request failed: \(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 a message for `duplicateRequest` and reports the failure as `ErrorCode.beginRefundRequestError` (code 31).

## Related

- [What does StoreKitError.unknown mean?](https://revenuedot.app/docs/errors/storekit-error-unknown.md)
- [What does storeProblemError (code 2) mean in the purchases SDK?](https://revenuedot.app/docs/errors/sdk-store-problem-error.md)
- [What does VerificationError.invalidSignature mean in StoreKit 2?](https://revenuedot.app/docs/errors/storekit-verification-error-invalid-signature.md)
- [Apple: Testing refund requests](https://developer.apple.com/documentation/storekit/testing-refund-requests)

## Source

- [Apple: Transaction.RefundRequestError.duplicateRequest](https://developer.apple.com/documentation/storekit/transaction/refundrequesterror/duplicaterequest)
- [Apple: Transaction.RefundRequestError](https://developer.apple.com/documentation/storekit/transaction/refundrequesterror)
- [RevenueDot purchases-ios: SK2BeginRefundRequestHelper.swift](https://github.com/revenuedot/purchases-ios/blob/revenuedot/main-patches/Sources/Purchasing/StoreKit2/SK2BeginRefundRequestHelper.swift)

Checked: 2026-10-03
