SDK error · code 31

beginRefundRequestError (error code 31): Begin refund request error

What it means

beginRefundRequestError (code 31) means the iOS in-app refund request could not start: the SDK found no verified transaction for the product, the entitlement is missing or ambiguous, customer info failed to load, or StoreKit refused the request. Pass the right entitlement ID, make sure the customer owns a verified purchase, and read the message for the exact reason.

Code

31

iOS (Swift)

ErrorCode.beginRefundRequestError

Android (Kotlin)

No matching code in the Android SDK; see the causes below.

Causes

Why the SDK returns beginRefundRequestError

  • No entitlement matches the ID you passed, or no entitlement is active, or several are active and you passed none (BeginRefundRequestHelper.swift).
  • The SDK could not fetch customer info to find the entitlement's product.
  • StoreKit 2 has no transaction for the product, or the latest transaction is unverified (SK2BeginRefundRequestHelper.swift).
  • StoreKit refused the request with a RefundRequestError, such as a duplicate request or a failure.
  • Android has no member for this code.

Fix

How to fix beginRefundRequestError

  1. 01

    Pass the entitlement ID

    Call beginRefundRequest(forEntitlement:) with the ID of the entitlement you mean. beginRefundRequestForActiveEntitlement() needs exactly one active entitlement.

  2. 02

    Check the customer owns the purchase

    The customer must be signed in to the account that bought, with a verified transaction. See Transaction.beginRefundRequest-63bvd).

  3. 03

    Fetch customer info first

    Make sure getCustomerInfo succeeds, because the SDK reads the product from it.

  4. 04

    Do not request twice

    A second request for the same transaction can fail as a duplicate. Disable the button after the first tap.

In your app

How to handle it in code

  • Do not retry in a loop. Fix the entitlement or the account first.
  • Show "We could not open the refund request. Please contact support" and offer your support channel.
  • A refund request does not remove access. Access ends only when Apple processes the refund.
Match the errorSwift
// Swift
do {
  let result = try await Purchases.shared.purchase(package: package)
} catch let error as ErrorCode where error == .beginRefundRequestError {
  // handle begin refund request error
}

On RevenueDot: The SDK reads the entitlement and its product from the customer info RevenueDot serves, so a customer info that lacks the entitlement produces this error. The refund sheet itself is Apple's. See Why is my entitlement not active?.

FAQ

beginRefundRequestError: questions people ask

What does beginRefundRequestError mean?

The iOS refund request could not start. The message says why: no matching entitlement, several active entitlements, no verified transaction, or a StoreKit refusal.

Does the refund request revoke access immediately?

No. The request goes to Apple. Access changes only when the refund is granted, and the store then reports it to your server.

How do I check for beginRefundRequestError in React Native and Flutter?

In React Native, compare error.code with PURCHASES_ERROR_CODE.BEGIN_REFUND_REQUEST_ERROR. In Flutter, convert the PlatformException with PurchasesErrorHelper.getErrorCode(e) and compare the result with PurchasesErrorCode.beginRefundRequestError.

Get started

Keep the RevenueCat SDK. Change the backend.

RevenueDot answers the same SDK calls with the same error codes. Start free on RevenueDot Cloud, free up to $10,000 a month in tracked revenue.

Already have an account? Sign in · Prefer your own servers? Self-host free