-
-
Notifications
You must be signed in to change notification settings - Fork 24
chore(ios): upgrade OpenIAP to 1.1.9 and align error codes #191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Warning Rate limit exceeded@hyochan has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 3 minutes and 6 seconds before requesting another review. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (1)
WalkthroughBumps iOS Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant JS as App (JS)
participant TS as ExpoIap (TS)
participant iOS as ExpoIapModule (iOS)
participant Store as App Store
JS->>TS: requestPurchase({ sku, withOffer? })
TS->>iOS: requestPurchase(sku, offer?)
iOS->>iOS: Parse withOffer → OpenIapDiscountOffer (optional)
iOS->>Store: Initiate purchase (sku, offer?)
alt Success
Store-->>iOS: Transaction
iOS-->>TS: Success result
TS-->>JS: Resolve
else Error
Store-->>iOS: Error
iOS->>iOS: Wrap/Map → OpenIapError.make(...) / emptySkuList()
iOS-->>TS: Error { code, message }
TS->>TS: fromPlatformCode: passthrough E_* if valid
TS-->>JS: Reject with standardized ErrorCode
end
sequenceDiagram
autonumber
participant iOS as ExpoIapModule (iOS)
participant TS as ExpoIap (TS)
participant UI as UI Layer
iOS-->>TS: Error { code: "E_RECEIPT_FINISHED" }
TS->>TS: fromPlatformCode recognizes valid E_* → passthrough
TS->>UI: getUserFriendlyErrorMessage("E_RECEIPT_FINISHED")
UI-->>UI: "Receipt already finished"
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Possibly related PRs
Suggested labels
Poem
Pre-merge checks (3 passed)✅ Passed checks (3 passed)
✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Summary of Changes
Hello @hyochan, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request enhances the robustness and consistency of error handling within the application's in-app purchase module. It involves updating a core iOS dependency and standardizing error reporting mechanisms across both Swift and TypeScript components, ensuring that error codes are uniformly recognized and handled throughout the system.
Highlights
- OpenIAP Dependency Upgrade: The OpenIAP dependency for iOS has been upgraded from version 1.1.8 to 1.1.9 in the podspec.
- iOS Error Handling Unification: Legacy OpenIapFailure error types in Swift have been replaced with the unified OpenIapError model, ensuring consistent error reporting and better alignment with the new version.
- New Error Code Introduction: The E_RECEIPT_FINISHED error code has been added to the TypeScript error definitions and its corresponding user-friendly message mapping.
- Native Error Code Recognition: The JavaScript error utility now directly recognizes standardized string error codes (e.g., E_...) sent from native modules, improving error propagation and consistency.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command>
or @gemini-code-assist <command>
. Below is a summary of the supported commands.
Feature | Command | Description |
---|---|---|
Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/
folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #191 +/- ##
=======================================
Coverage 43.82% 43.82%
=======================================
Files 6 6
Lines 632 632
Branches 274 274
=======================================
Hits 277 277
Misses 350 350
Partials 5 5
Flags with carried forward coverage won't be shown. Click here to find out more. Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request successfully upgrades the OpenIAP dependency and aligns error handling across the module. The migration to the unified OpenIapError
model in the Swift code is a significant improvement for consistency and robustness. The corresponding changes in TypeScript to handle new error codes and recognize standardized string codes from the native side are well-implemented. Overall, these changes enhance the library's maintainability and error handling capabilities. I have one minor suggestion for a performance optimization.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
src/ExpoIap.types.ts (3)
160-195
: Add Android mapping for E_RECEIPT_FINISHED to avoid falling back to E_UNKNOWN.
Without this, toPlatformCode(E_RECEIPT_FINISHED, 'android') returns 'E_UNKNOWN'.Apply:
android: { [ErrorCode.E_UNKNOWN]: 'E_UNKNOWN', @@ [ErrorCode.E_RECEIPT_FAILED]: 'E_RECEIPT_FAILED', + [ErrorCode.E_RECEIPT_FINISHED]: 'E_RECEIPT_FINISHED', [ErrorCode.E_RECEIPT_FINISHED_FAILED]: 'E_RECEIPT_FINISHED_FAILED',
333-342
: Android fallback should return the standardized code string when unmapped.
Prevents accidental downgrades to 'E_UNKNOWN' for newly added codes.toPlatformCode: ( errorCode: ErrorCode, platform: 'ios' | 'android', ): string | number => { if (platform === 'ios') { const native = NATIVE_ERROR_CODES?.[errorCode]; if (native !== undefined) return native; } - const mapping = ErrorCodeMapping[platform] as Record< - ErrorCode, - string | number - >; - return mapping[errorCode] ?? (platform === 'ios' ? 0 : 'E_UNKNOWN'); + const mapping = ErrorCodeMapping[platform] as Record<ErrorCode, string | number>; + if (platform === 'android') { + // Fallback to standardized string to avoid drift + return (mapping[errorCode] as string | undefined) ?? errorCode; + } + return mapping[errorCode] ?? 0;
350-356
: Validate against dynamic iOS native codes too.
Currently isValidForPlatform ignores NATIVE_ERROR_CODES, so new iOS codes read from native are marked invalid.isValidForPlatform: ( errorCode: ErrorCode, platform: 'ios' | 'android', ): boolean => { - return errorCode in ErrorCodeMapping[platform]; + if (platform === 'ios') { + return ( + errorCode in ErrorCodeMapping.ios || + NATIVE_ERROR_CODES?.[errorCode] !== undefined + ); + } + return errorCode in ErrorCodeMapping.android; },
🧹 Nitpick comments (3)
src/ExpoIap.types.ts (1)
247-263
: Replace any with a typed native error shape for stricter safety.
Keeps to “no any types” guidance and clarifies expected payload from native.-export class PurchaseError implements Error { +type NativePurchaseErrorData = { + message?: string; + responseCode?: number; + debugMessage?: string; + code?: string | number; + productId?: string; +}; + +export class PurchaseError implements Error { @@ - static fromPlatformError( - errorData: any, + static fromPlatformError( + errorData: NativePurchaseErrorData, platform: 'ios' | 'android', ): PurchaseError {src/utils/errorMapping.ts (1)
77-79
: Added message for E_RECEIPT_FINISHED — good.
Consider also covering E_RECEIPT_FINISHED_FAILED for completeness.case ErrorCode.E_RECEIPT_FINISHED: return 'Receipt already finished'; + case ErrorCode.E_RECEIPT_FINISHED_FAILED: + return 'Failed to finish receipt';ios/ExpoIapModule.swift (1)
146-151
: Missing 'sku' mapped to E_PURCHASE_ERROR — acceptable; consider E_DEVELOPER_ERROR.
Semantically “invalid arguments” could map to E_DEVELOPER_ERROR, but not blocking.-throw OpenIapError.make(code: OpenIapError.E_PURCHASE_ERROR, message: "Missing required 'sku'") +throw OpenIapError.make(code: OpenIapError.E_DEVELOPER_ERROR, message: "Missing required 'sku'")
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
ios/ExpoIap.podspec
(1 hunks)ios/ExpoIapModule.swift
(6 hunks)src/ExpoIap.types.ts
(2 hunks)src/utils/errorMapping.ts
(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx}
: Platform-specific functions must use suffixes: IOS -> functionNameIOS, Android -> functionNameAndroid
Cross-platform functions must not use platform suffixes and should abstract differences internally (e.g., via Platform.select)
Explicit type definitions for all public APIs
Provide function overloads to improve IntelliSense for public APIs when appropriate
Use discriminated unions for platform-specific types and conditional returns
Noany
types in production code; maintain strict type safety
Naming: PascalCase for interfaces, types, enums, and classes
Naming: camelCase for functions, variables, methods, and properties
Use a result-style error handling pattern returning {success: true|false, ...}
Use Platform.select to handle platform differences in cross-platform code
Provide TypeScript-first API with unified structures across iOS and Android
Use type guards (e.g., isPurchaseResult) for advanced runtime type checks
Add JSDoc comments for all public APIs; document why, platform differences, and examples
Receipt validation should use platform-specific parameters (iOS: SKU only; Android: packageName, productToken, accessToken)
**/*.{ts,tsx}
: Platform-specific functions must use platform suffixes: functionNameIOS() for iOS and functionNameAndroid() for Android
Cross-platform functions that abstract platform differences should not have platform suffixes and should use Platform.select()
Use platform-specific type names with suffixes (e.g., ProductIOS, ProductAndroid, PurchaseErrorIOS)
Use cross-platform type names without suffixes (e.g., Product, Purchase, PurchaseError) when types are shared
Include proper error handling in implementations (e.g., try/catch with meaningful errors) for public APIs
Add JSDoc comments for all public API functions and types
Use Platform.select({...}) for platform branching in implementation code
Receipt validation must use platform-specific parameters: iOS only needs SKU; Android requires packageName, productToken, and a...
Files:
src/utils/errorMapping.ts
src/ExpoIap.types.ts
src/**/*.ts
📄 CodeRabbit inference engine (.cursorrules)
File names should be kebab-case (except React component files)
Files:
src/utils/errorMapping.ts
src/ExpoIap.types.ts
ios/ExpoIap.podspec
📄 CodeRabbit inference engine (CLAUDE.md)
Do not modify platform versions in ios/ExpoIap.podspec; iOS and tvOS MUST remain at 13.4
Files:
ios/ExpoIap.podspec
src/ExpoIap.types.ts
📄 CodeRabbit inference engine (.cursorrules)
Core public type definitions should be in src/ExpoIap.types.ts
Files:
src/ExpoIap.types.ts
ios/**/*.swift
📄 CodeRabbit inference engine (CLAUDE.md)
ios/**/*.swift
: Use status.loadings.purchasing.contains(productId) to check if a specific product is being purchased
Use status.isLoading to check if any operation is in progress
Files:
ios/ExpoIapModule.swift
🧠 Learnings (7)
📓 Common learnings
Learnt from: CR
PR: hyochan/expo-iap#0
File: .cursorrules:0-0
Timestamp: 2025-08-27T12:21:23.121Z
Learning: Applies to src/types/ExpoIapIos.types.ts : iOS-specific type definitions belong in src/types/ExpoIapIos.types.ts
Learnt from: CR
PR: hyochan/expo-iap#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T03:20:18.305Z
Learning: Applies to **/*.{ts,tsx} : General IAP types must use Iap prefix (e.g., IapPurchase; not IAPPurchase)
Learnt from: CR
PR: hyochan/expo-iap#0
File: .cursorrules:0-0
Timestamp: 2025-08-27T12:21:23.121Z
Learning: Applies to src/ExpoIapModule.ts : Native module interface should be in src/ExpoIapModule.ts
Learnt from: CR
PR: hyochan/expo-iap#0
File: .cursorrules:0-0
Timestamp: 2025-08-27T12:21:23.121Z
Learning: Applies to src/types/ExpoIapAndroid.types.ts : Android-specific type definitions belong in src/types/ExpoIapAndroid.types.ts
Learnt from: CR
PR: hyochan/expo-iap#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T03:20:18.305Z
Learning: Applies to ios/ExpoIap.podspec : Do not modify platform versions in ios/ExpoIap.podspec; iOS and tvOS MUST remain at 13.4
Learnt from: CR
PR: hyochan/expo-iap#0
File: .cursorrules:0-0
Timestamp: 2025-08-27T12:21:23.121Z
Learning: Applies to src/ExpoIap.types.ts : Core public type definitions should be in src/ExpoIap.types.ts
📚 Learning: 2025-09-08T03:20:18.305Z
Learnt from: CR
PR: hyochan/expo-iap#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T03:20:18.305Z
Learning: Applies to ios/ExpoIap.podspec : Do not modify platform versions in ios/ExpoIap.podspec; iOS and tvOS MUST remain at 13.4
Applied to files:
ios/ExpoIap.podspec
📚 Learning: 2025-08-27T12:21:23.121Z
Learnt from: CR
PR: hyochan/expo-iap#0
File: .cursorrules:0-0
Timestamp: 2025-08-27T12:21:23.121Z
Learning: Applies to src/ExpoIap.types.ts : Core public type definitions should be in src/ExpoIap.types.ts
Applied to files:
src/ExpoIap.types.ts
📚 Learning: 2025-08-27T12:21:23.121Z
Learnt from: CR
PR: hyochan/expo-iap#0
File: .cursorrules:0-0
Timestamp: 2025-08-27T12:21:23.121Z
Learning: Applies to src/types/ExpoIapIos.types.ts : iOS-specific type definitions belong in src/types/ExpoIapIos.types.ts
Applied to files:
src/ExpoIap.types.ts
ios/ExpoIapModule.swift
📚 Learning: 2025-08-27T12:21:23.121Z
Learnt from: CR
PR: hyochan/expo-iap#0
File: .cursorrules:0-0
Timestamp: 2025-08-27T12:21:23.121Z
Learning: Applies to src/types/ExpoIapAndroid.types.ts : Android-specific type definitions belong in src/types/ExpoIapAndroid.types.ts
Applied to files:
src/ExpoIap.types.ts
📚 Learning: 2025-08-27T12:21:23.121Z
Learnt from: CR
PR: hyochan/expo-iap#0
File: .cursorrules:0-0
Timestamp: 2025-08-27T12:21:23.121Z
Learning: Applies to src/ExpoIapModule.ts : Native module interface should be in src/ExpoIapModule.ts
Applied to files:
src/ExpoIap.types.ts
ios/ExpoIapModule.swift
📚 Learning: 2025-09-08T03:20:18.305Z
Learnt from: CR
PR: hyochan/expo-iap#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T03:20:18.305Z
Learning: Implementations must conform to OpenIAP specification (APIs, Types, Events, Errors) per official docs
Applied to files:
ios/ExpoIapModule.swift
🔇 Additional comments (7)
ios/ExpoIap.podspec (1)
24-24
: Dependency bump to 1.1.9 looks good; platform mins unchanged (13.4) per policy.
No other podspec concerns.src/ExpoIap.types.ts (1)
298-303
: Short-circuit for standardized string codes — LGTM.
Accepting 'E_*' strings directly reduces drift between native and TS.ios/ExpoIapModule.swift (5)
108-111
: Empty SKU list -> OpenIapError.emptySkuList() — LGTM.
Aligned with OpenIAP 1.1.9 error model.
199-204
: Re-throw native OpenIapError unchanged; wrap others — LGTM.
Prevents double-wrapping and preserves native code/message.
281-283
: Receipt validation fallback -> E_RECEIPT_FAILED — LGTM.
Consistent with TS ErrorCode.
407-409
: currentEntitlementIOS -> E_SKU_NOT_FOUND on failure — LGTM.
Adds useful productId context to the error.
419-421
: latestTransactionIOS -> E_SKU_NOT_FOUND on failure — LGTM.
Consistent with entitlement path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (2)
src/ExpoIap.types.ts (2)
99-101
: E_RECEIPT_FINISHED enum added — LGTMEnum addition is correct and matches PR intent.
147-148
: Missing mapping flagged earlier appears resolvedPrior comment about adding E_RECEIPT_FINISHED to platform mappings is now addressed here. Nice.
Also applies to: 174-175
🧹 Nitpick comments (3)
src/ExpoIap.types.ts (3)
128-132
: Good call on using a Set for O(1) lookups; tighten the typingMake it a ReadonlySet to preserve type safety and prevent mutation.
-// Fast lookup set for validating standardized error code strings -const OPENIAP_ERROR_CODE_SET: Set<string> = new Set( - Object.values(ErrorCode) as string[], -); +// Fast lookup set for validating standardized error code strings +const OPENIAP_ERROR_CODE_SET: ReadonlySet<ErrorCode> = new Set( + Object.values(ErrorCode) as ErrorCode[], +);Optionally add a type guard (outside this range) to avoid casts:
export const isErrorCode = (v: unknown): v is ErrorCode => typeof v === 'string' && (OPENIAP_ERROR_CODE_SET as Set<ErrorCode>).has(v as ErrorCode);
305-310
: Fast-path for standardized string codes — LGTM; minor type-safety nitThis is correct and efficient. If adding the type guard above, you can drop the cast.
- if (typeof platformCode === 'string' && platformCode.startsWith('E_')) { - if (OPENIAP_ERROR_CODE_SET.has(platformCode)) { - return platformCode as ErrorCode; - } - } + if (isErrorCode(platformCode)) { + return platformCode; + }
291-293
: Return type should include number for iOS native codesNative iOS codes are numeric; widen the return type.
- getNativeErrorCode: (errorCode: ErrorCode): string => { + getNativeErrorCode: (errorCode: ErrorCode): string | number => { return NATIVE_ERROR_CODES[errorCode] || errorCode; },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
src/ExpoIap.types.ts
(5 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (.cursorrules)
**/*.{ts,tsx}
: Platform-specific functions must use suffixes: IOS -> functionNameIOS, Android -> functionNameAndroid
Cross-platform functions must not use platform suffixes and should abstract differences internally (e.g., via Platform.select)
Explicit type definitions for all public APIs
Provide function overloads to improve IntelliSense for public APIs when appropriate
Use discriminated unions for platform-specific types and conditional returns
Noany
types in production code; maintain strict type safety
Naming: PascalCase for interfaces, types, enums, and classes
Naming: camelCase for functions, variables, methods, and properties
Use a result-style error handling pattern returning {success: true|false, ...}
Use Platform.select to handle platform differences in cross-platform code
Provide TypeScript-first API with unified structures across iOS and Android
Use type guards (e.g., isPurchaseResult) for advanced runtime type checks
Add JSDoc comments for all public APIs; document why, platform differences, and examples
Receipt validation should use platform-specific parameters (iOS: SKU only; Android: packageName, productToken, accessToken)
**/*.{ts,tsx}
: Platform-specific functions must use platform suffixes: functionNameIOS() for iOS and functionNameAndroid() for Android
Cross-platform functions that abstract platform differences should not have platform suffixes and should use Platform.select()
Use platform-specific type names with suffixes (e.g., ProductIOS, ProductAndroid, PurchaseErrorIOS)
Use cross-platform type names without suffixes (e.g., Product, Purchase, PurchaseError) when types are shared
Include proper error handling in implementations (e.g., try/catch with meaningful errors) for public APIs
Add JSDoc comments for all public API functions and types
Use Platform.select({...}) for platform branching in implementation code
Receipt validation must use platform-specific parameters: iOS only needs SKU; Android requires packageName, productToken, and a...
Files:
src/ExpoIap.types.ts
src/ExpoIap.types.ts
📄 CodeRabbit inference engine (.cursorrules)
Core public type definitions should be in src/ExpoIap.types.ts
Files:
src/ExpoIap.types.ts
src/**/*.ts
📄 CodeRabbit inference engine (.cursorrules)
File names should be kebab-case (except React component files)
Files:
src/ExpoIap.types.ts
🧠 Learnings (6)
📓 Common learnings
Learnt from: CR
PR: hyochan/expo-iap#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-08T03:20:18.305Z
Learning: Implementations must conform to OpenIAP specification (APIs, Types, Events, Errors) per official docs
📚 Learning: 2025-08-27T12:21:23.121Z
Learnt from: CR
PR: hyochan/expo-iap#0
File: .cursorrules:0-0
Timestamp: 2025-08-27T12:21:23.121Z
Learning: Applies to src/types/ExpoIapAndroid.types.ts : Android-specific type definitions belong in src/types/ExpoIapAndroid.types.ts
Applied to files:
src/ExpoIap.types.ts
📚 Learning: 2025-08-27T12:21:23.121Z
Learnt from: CR
PR: hyochan/expo-iap#0
File: .cursorrules:0-0
Timestamp: 2025-08-27T12:21:23.121Z
Learning: Applies to src/types/ExpoIapIos.types.ts : iOS-specific type definitions belong in src/types/ExpoIapIos.types.ts
Applied to files:
src/ExpoIap.types.ts
📚 Learning: 2025-08-27T12:21:23.121Z
Learnt from: CR
PR: hyochan/expo-iap#0
File: .cursorrules:0-0
Timestamp: 2025-08-27T12:21:23.121Z
Learning: Applies to src/ExpoIap.types.ts : Core public type definitions should be in src/ExpoIap.types.ts
Applied to files:
src/ExpoIap.types.ts
📚 Learning: 2025-08-27T12:21:45.068Z
Learnt from: CR
PR: hyochan/expo-iap#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-08-27T12:21:45.068Z
Learning: Applies to **/*.{ts,tsx} : Receipt validation must use platform-specific parameters: iOS only needs SKU; Android requires packageName, productToken, and accessToken (use validateReceiptIOS/validateReceiptAndroid accordingly)
Applied to files:
src/ExpoIap.types.ts
📚 Learning: 2025-08-27T12:21:23.121Z
Learnt from: CR
PR: hyochan/expo-iap#0
File: .cursorrules:0-0
Timestamp: 2025-08-27T12:21:23.121Z
Learning: Applies to **/*.{ts,tsx} : Receipt validation should use platform-specific parameters (iOS: SKU only; Android: packageName, productToken, accessToken)
Applied to files:
src/ExpoIap.types.ts
🔇 Additional comments (2)
src/ExpoIap.types.ts (2)
174-176
: Android mapping added for E_RECEIPT_FINISHED — LGTMString code passthrough aligns with Android side and your JS handling.
147-149
: iOS mapping for E_RECEIPT_FINISHED — confirm native parity
Mapping to 24 is in ErrorCodeMapping. I couldn’t locate the iOS native definition in this repo—please verify thatExpoIapModule.ERROR_CODES.E_RECEIPT_FINISHED
is 24 in the iOS implementation.
Upgrade OpenIAP Apple to 1.1.9 and align iOS error handling with the unified OpenIapError model. Replace legacy error type usages in Swift and add missing E_RECEIPT_FINISHED in TypeScript to stay in sync with Open IAP docs. Ensure direct string codes from native are recognized in JS.\n\nNo breaking changes. Includes https://github.com/hyodotdev/openiap-apple/releases/tag/1.1.9.
Summary by CodeRabbit
New Features
Bug Fixes
Chores