Code
20
SDK error · code 20
What it means
paymentPendingError (code 20) means the purchase has started but is not paid yet. A parent must approve it (Ask to Buy), a bank must confirm it, or a delayed Google Play payment method must settle. It is not a failure. Tell the customer it is pending, keep listening for customer info updates, and grant access only when the entitlement turns active.
Code
20
iOS (Swift)
ErrorCode.payment
Android (Kotlin)
PurchasesErrorCode.Payment
Causes
.pending, which Apple describes as a purchase that requires action from the customer. The SDK throws paymentPendingError (StoreKit2TransactionListener.swift).deferred state, which Apple describes as pending external action such as Ask to Buy.PENDING. The SDK raises this error instead of posting the purchase (PostReceiptHelper.kt). Google says to grant entitlement only when the state is PURCHASED (Google docs).| Backend code | Meaning |
|---|---|
| 7651 | Payment not complete (Android mapping). |
Fix
Tell the customer "Your purchase is waiting for approval" and close the paywall. Do not show a failure.
On iOS, implement purchases(_:receivedUpdated:) on PurchasesDelegate. On Android, set an UpdatedCustomerInfoListener. Both fire when the pending purchase completes.
Call getCustomerInfo when the app returns to the foreground. A purchase can complete while the app is closed, and StoreKit delivers a pending purchase that succeeds through Transaction.updates (Apple docs).
On Android, acknowledge only after the state is PURCHASED. Google starts the three-day acknowledgement window at that moment (Google docs).
In your app
CustomerInfo shows the entitlement active.// Swift
do {
let result = try await Purchases.shared.purchase(package: package)
} catch let error as ErrorCode where error == .paymentPendingError {
// handle payment pending
}
// Kotlin
if (error.code == PurchasesErrorCode.PaymentPendingError) { /* ... */ } On RevenueDot: The Android SDK does not post pending purchases, so RevenueDot normally never sees them. If a pending Google purchase does reach POST /v1/receipts, RevenueDot answers 503 with code 7101, so the SDK posts it again later, and a cancelled pending purchase gets 400 with 7103.
FAQ
Ask to Buy lets a parent approve a child's purchase. The SDK reports the waiting state as paymentPendingError, and customer info updates once the parent approves.
Only when the entitlement is active in CustomerInfo. Google says to grant entitlement only for a PURCHASED state, not PENDING (Google docs).
In React Native, compare error.code with PURCHASES_ERROR_CODE.PAYMENT_PENDING_ERROR. In Flutter, convert the PlatformException with PurchasesErrorHelper.getErrorCode(e) and compare the result with PurchasesErrorCode.paymentPendingError.
Get started
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