fix(apple-iap): fall back to cached IAP records on App Store failures - #20965
Open
david1alvarez wants to merge 1 commit into
Open
fix(apple-iap): fall back to cached IAP records on App Store failures#20965david1alvarez wants to merge 1 commit into
david1alvarez wants to merge 1 commit into
Conversation
Because: * The App Store Server API intermittently fails, and app-store-server-api surfaces those as an AppStoreError carrying one of Apple's 5xxxxxx codes. * AppleIapPurchaseManager.getForUser rethrew everything but its not-found cases, so an Apple outage failed EligibilityService.checkEligibility and took cart setup and checkout down with it. * Treating a purchase we cannot verify as absent is worse than erroring: a customer with an active Apple subscription could buy an overlapping web subscription. This commit: * Adds AppleIapServiceUnavailableError, and maps Apple's server-range error codes plus the library's isRetryable and isRateLimitExceeded flags to it in AppleIapClient.convertError. * Adds AppleIapPurchaseManager.getStaleCachedForUser, which reads a customer's purchase records from Firestore without refreshing them against Apple. * Falls back to those records in EligibilityService.checkEligibility, so a purchase we cannot verify still blocks an overlapping web purchase. * Exports the Apple IAP error module from the payments-iap barrel, and passes the logger to EligibilityService in initSubplat. * Leaves the billing endpoint and the subscription management page erroring, so a customer sees a failure rather than an empty subscription list. Closes PAY-3841
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves resiliency of Apple IAP eligibility checks during intermittent App Store Server API outages by classifying Apple-side failures as a distinct error and falling back to cached Firestore purchase records for overlap protection (so an unverified Apple subscription doesn’t appear “absent” and allow an overlapping web purchase).
Changes:
- Introduces
AppleIapServiceUnavailableErrorand maps Apple server-range error codes (5xxxxxx) plusapp-store-server-apiretry/rate-limit signals to it inAppleIapClient. - Adds
AppleIapPurchaseManager.getStaleCachedForUserto read cached Apple purchase records from Firestore without calling Apple. - Updates
EligibilityService.checkEligibilityto fall back to cached Apple purchases when Apple is unavailable, and wires a logger throughinitSubplat; adds unit test coverage for the new behaviors.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| packages/fxa-auth-server/lib/payments/initSubplat.ts | Passes a logger into EligibilityService initialization to support new warning logging on Apple outages. |
| libs/payments/iap/src/lib/apple/apple-iap.error.ts | Adds AppleIapServiceUnavailableError to represent Apple-side/transient failures with structured info. |
| libs/payments/iap/src/lib/apple/apple-iap.client.ts | Detects Apple-side/transient App Store errors and converts them to AppleIapServiceUnavailableError. |
| libs/payments/iap/src/lib/apple/apple-iap.client.spec.ts | Adds tests ensuring retryable/server/rate-limit App Store errors map to AppleIapServiceUnavailableError and non-retryable client errors do not. |
| libs/payments/iap/src/lib/apple/apple-iap-purchase.manager.ts | Adds getStaleCachedForUser to return Firestore-cached purchases without contacting Apple. |
| libs/payments/iap/src/lib/apple/apple-iap-purchase.manager.spec.ts | Adds tests for getStaleCachedForUser and verifies AppleIapServiceUnavailableError is propagated to callers. |
| libs/payments/iap/src/index.ts | Exports Apple IAP error types from the library barrel for cross-package consumption. |
| libs/payments/eligibility/src/lib/eligibility.service.ts | Falls back to cached Apple purchases when Apple is unavailable (and logs a warning), preventing overlapping web purchases from slipping through. |
| libs/payments/eligibility/src/lib/eligibility.service.spec.ts | Adds tests covering the fallback-to-cache behavior and confirming non-retryable Apple errors are rethrown. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Because:
This commit:
Closes PAY-3841
Checklist
Put an
xin the boxes that apply