@nosslabs/iap 8.0.0 → 8.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/errors.ts","../src/lib/platform.ts","../src/lib/iso-country.ts","../src/adapters/native/capgo/native-adapter.ts","../src/adapters/backend/index.ts","../src/adapters/backend/http-adapter.ts","../src/adapters/backend/http-client.ts","../src/lib/redact.ts","../src/types/config.ts","../src/types/entitlement.ts","../src/adapters/backend/types.ts","../src/adapters/native/index.ts","../src/adapters/native/web/web-stub.ts","../src/adapters/storage/index.ts","../src/adapters/storage/memory-adapter.ts","../src/adapters/storage/preferences-adapter.ts","../src/core/app-resume-listener.ts","../src/core/entitlement-cache.ts","../src/core/purchase-flow.ts","../src/lib/uuid.ts","../src/core/verify-helpers.ts","../src/core/recovery-flow.ts","../src/core/restore-flow.ts","../src/core/unfinished-transactions.ts","../src/events/emitter.ts","../src/createIAP.ts","../src/lib/logger.ts","../src/index.ts","../src/version.ts"],"names":["IAPError","IAPErrorCode","Capacitor","PURCHASE_TYPE","NativePurchases","z","Preferences","entitlements"],"mappings":"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AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;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","file":"index.cjs","sourcesContent":["export const IAPErrorCode = {\n // Configuration\n INVALID_CONFIG: 'INVALID_CONFIG',\n NOT_INITIALIZED: 'NOT_INITIALIZED',\n\n // Native plugin\n PLATFORM_NOT_SUPPORTED: 'PLATFORM_NOT_SUPPORTED',\n BILLING_NOT_AVAILABLE: 'BILLING_NOT_AVAILABLE',\n PRODUCT_NOT_FOUND: 'PRODUCT_NOT_FOUND',\n USER_CANCELLED: 'USER_CANCELLED',\n PURCHASE_PENDING: 'PURCHASE_PENDING',\n ALREADY_PURCHASED: 'ALREADY_PURCHASED',\n STORE_ERROR: 'STORE_ERROR',\n UNACKNOWLEDGED_PENDING: 'UNACKNOWLEDGED_PENDING',\n\n // Concurrency\n ALREADY_IN_PROGRESS: 'ALREADY_IN_PROGRESS',\n\n // Backend\n BACKEND_UNAVAILABLE: 'BACKEND_UNAVAILABLE',\n BACKEND_TIMEOUT: 'BACKEND_TIMEOUT',\n BACKEND_AUTH_FAILED: 'BACKEND_AUTH_FAILED',\n /** Backend reachable but the response was rejected (non-transient 4xx other\n * than auth, malformed JSON, schema violation, 204 No Content on a JSON\n * endpoint). Fix the request shape or the backend; do not retry. */\n BACKEND_BAD_RESPONSE: 'BACKEND_BAD_RESPONSE',\n VERIFICATION_REJECTED: 'VERIFICATION_REJECTED',\n\n // Storage\n STORAGE_ERROR: 'STORAGE_ERROR',\n\n // appUserId pre-attach\n /**\n * The supplied `appUserId` (literal or fetcher-returned) is not a valid\n * UUID v4. Apple requires a UUID for `appAccountToken`; we enforce the\n * same constraint cross-platform for a consistent contract.\n */\n INVALID_APP_USER_ID: 'INVALID_APP_USER_ID',\n /**\n * The async `appUserId` fetcher threw or rejected. Original error is\n * attached as `cause` so the caller can introspect (network failure,\n * backend 5xx, etc.).\n */\n APP_USER_ID_FETCH_FAILED: 'APP_USER_ID_FETCH_FAILED',\n} as const;\n\nexport type IAPErrorCode = (typeof IAPErrorCode)[keyof typeof IAPErrorCode];\n\nconst RECOVERABLE_CODES = new Set<IAPErrorCode>([\n IAPErrorCode.BACKEND_UNAVAILABLE,\n IAPErrorCode.BACKEND_TIMEOUT,\n IAPErrorCode.STORAGE_ERROR,\n IAPErrorCode.UNACKNOWLEDGED_PENDING,\n]);\n\n/**\n * Per-code remediation hints. Each line answers \"what does the consumer\n * usually need to check or change to resolve this?\" — short enough to\n * append to a thrown error's message without burying the original detail.\n *\n * Style: imperative, action-first, ends with a period. No links (those\n * live in the docs; consumers grep for the code and find them).\n */\nconst HINTS: Readonly<Record<IAPErrorCode, string>> = {\n // Configuration\n INVALID_CONFIG:\n 'Check the field paths reported above against the IAPConfig schema (see /api/types).',\n NOT_INITIALIZED:\n 'Call iap.initialize() before this method, or recreate the instance after destroy().',\n\n // Native plugin\n PLATFORM_NOT_SUPPORTED:\n 'In-app purchases run on iOS/Android only. Web is no-op by design — guard your purchase UI behind Capacitor.isNativePlatform().',\n BILLING_NOT_AVAILABLE:\n 'The store billing service is unavailable. Confirm @capgo/native-purchases is installed and `npx cap sync` has run; check the device sandbox/test account is signed in.',\n PRODUCT_NOT_FOUND:\n 'Ensure the productId is registered in App Store Connect / Play Console AND in your createIAP({ products }) config.',\n USER_CANCELLED: 'No action needed — the user dismissed the native purchase sheet.',\n PURCHASE_PENDING:\n 'Android only: payment is awaiting external clearance (e.g. cash payment, bank verification). The backend will receive a Google RTDN webhook when it clears; call iap.refresh() afterward.',\n ALREADY_PURCHASED:\n 'The user already owns this non-consumable. Use iap.restorePurchases() to re-grant entitlement, or query iap.hasEntitlement(key) before showing the purchase CTA.',\n STORE_ERROR:\n 'Native store reported an error. Check device connectivity, sandbox account state, and the cause field for the underlying plugin error.',\n UNACKNOWLEDGED_PENDING:\n 'A Google purchase has been unacknowledged for >2 days and is at risk of auto-refund. Verify the backend can be reached and call iap.refresh() to retry acknowledgement.',\n\n // Concurrency\n ALREADY_IN_PROGRESS:\n 'Await the in-flight iap.purchase(productId) before starting another for the same product.',\n\n // Backend\n BACKEND_UNAVAILABLE:\n 'Backend is unreachable or returning 5xx. Retry will happen automatically per config.retries; if persistent, check your server.',\n BACKEND_TIMEOUT:\n 'Backend did not respond within timeoutMs. Increase config.backend.timeoutMs or check server response time.',\n BACKEND_AUTH_FAILED:\n 'Backend returned 401/403. Check that getAuthHeaders() returns a valid Bearer token and that the backend recognizes it.',\n BACKEND_BAD_RESPONSE:\n 'Backend response did not match the expected shape. Confirm /api/iap/* endpoints follow the contract documented at /guide/backend-contract.',\n VERIFICATION_REJECTED:\n 'Backend rejected the transaction (valid:false). The transaction stays in unfinished_transactions for retry; the user may have switched accounts or the receipt may be invalid.',\n\n // Storage\n STORAGE_ERROR:\n 'Capacitor Preferences write failed. Check device storage availability; the in-memory state is still updated, only persistence failed.',\n\n // appUserId pre-attach\n INVALID_APP_USER_ID:\n 'appUserId must be a UUID v4 (e.g. crypto.randomUUID()). Apple requires this for appAccountToken; we enforce the same on Android for consistency.',\n APP_USER_ID_FETCH_FAILED:\n 'The async appUserId fetcher threw or rejected. Inspect the cause field for the underlying error (network failure, backend non-2xx, parse failure).',\n};\n\n/** Public accessor for the hint text — exported so docs / consumer error UIs can render it. */\nexport function errorHint(code: IAPErrorCode): string {\n return HINTS[code];\n}\n\ninterface IAPErrorOptions {\n code: IAPErrorCode;\n message: string;\n cause?: unknown;\n recoverable?: boolean;\n /**\n * Whether to append the per-code remediation hint to the message.\n * Defaults to `true`. Set `false` only if the caller already includes a\n * hint in `message` (avoids double-tagging).\n */\n includeHint?: boolean;\n}\n\nexport class IAPError extends Error {\n readonly code: IAPErrorCode;\n readonly recoverable: boolean;\n override readonly cause?: unknown;\n\n constructor(options: IAPErrorOptions) {\n const hint = options.includeHint === false ? '' : (HINTS[options.code] ?? '');\n const fullMessage = hint ? `${options.message}\\n\\nHint: ${hint}` : options.message;\n super(fullMessage);\n this.name = 'IAPError';\n this.code = options.code;\n this.cause = options.cause;\n this.recoverable = options.recoverable ?? RECOVERABLE_CODES.has(options.code);\n\n Object.setPrototypeOf(this, IAPError.prototype);\n }\n}\n\nexport function isIAPError(error: unknown): error is IAPError {\n return error instanceof IAPError;\n}\n\n/**\n * Coerce an unknown thrown value into an `IAPError`.\n *\n * - If `error` is already an `IAPError`, return it unchanged (preserves\n * the original code, recoverable flag, and cause chain).\n * - Otherwise wrap with the supplied fallback `code` and `message` and\n * attach the original as `cause`.\n *\n * Used by orchestrators and adapters that catch `unknown` from the JS\n * runtime and need to surface a typed error without losing context.\n */\nexport function toIAPError(\n error: unknown,\n fallbackMessage: string,\n fallbackCode: IAPErrorCode,\n): IAPError {\n if (isIAPError(error)) return error;\n return new IAPError({\n code: fallbackCode,\n message: fallbackMessage,\n cause: error,\n });\n}\n","import { Capacitor } from '@capacitor/core';\n\nexport type RuntimePlatform = 'ios' | 'android' | 'web';\n\nexport function getPlatform(): RuntimePlatform {\n const platform = Capacitor.getPlatform();\n if (platform === 'ios' || platform === 'android') return platform;\n return 'web';\n}\n\nexport function isNative(): boolean {\n const platform = getPlatform();\n return platform === 'ios' || platform === 'android';\n}\n","/**\n * ISO 3166-1 country-code normalization.\n *\n * Apple's StoreKit storefront `countryCode` is **alpha-3** (`\"USA\"`), while\n * Google Play's `BillingConfig.countryCode` is **alpha-2** (`\"US\"`). The\n * storefront layer normalizes to a single scheme (alpha-2 — what Android, both\n * server APIs, and Apple's external-purchase Info.plist keys all use) so\n * consumers compare one consistent value across platforms instead of inheriting\n * the per-platform split every other SDK leaks. Static, dependency-free, no\n * network.\n */\n\n/** ISO 3166-1 alpha-3 → alpha-2. Current assignments (as of 2026). */\nconst ALPHA3_TO_ALPHA2: Record<string, string> = {\n ABW: 'AW',\n AFG: 'AF',\n AGO: 'AO',\n AIA: 'AI',\n ALA: 'AX',\n ALB: 'AL',\n AND: 'AD',\n ARE: 'AE',\n ARG: 'AR',\n ARM: 'AM',\n ASM: 'AS',\n ATA: 'AQ',\n ATF: 'TF',\n ATG: 'AG',\n AUS: 'AU',\n AUT: 'AT',\n AZE: 'AZ',\n BDI: 'BI',\n BEL: 'BE',\n BEN: 'BJ',\n BES: 'BQ',\n BFA: 'BF',\n BGD: 'BD',\n BGR: 'BG',\n BHR: 'BH',\n BHS: 'BS',\n BIH: 'BA',\n BLM: 'BL',\n BLR: 'BY',\n BLZ: 'BZ',\n BMU: 'BM',\n BOL: 'BO',\n BRA: 'BR',\n BRB: 'BB',\n BRN: 'BN',\n BTN: 'BT',\n BVT: 'BV',\n BWA: 'BW',\n CAF: 'CF',\n CAN: 'CA',\n CCK: 'CC',\n CHE: 'CH',\n CHL: 'CL',\n CHN: 'CN',\n CIV: 'CI',\n CMR: 'CM',\n COD: 'CD',\n COG: 'CG',\n COK: 'CK',\n COL: 'CO',\n COM: 'KM',\n CPV: 'CV',\n CRI: 'CR',\n CUB: 'CU',\n CUW: 'CW',\n CXR: 'CX',\n CYM: 'KY',\n CYP: 'CY',\n CZE: 'CZ',\n DEU: 'DE',\n DJI: 'DJ',\n DMA: 'DM',\n DNK: 'DK',\n DOM: 'DO',\n DZA: 'DZ',\n ECU: 'EC',\n EGY: 'EG',\n ERI: 'ER',\n ESH: 'EH',\n ESP: 'ES',\n EST: 'EE',\n ETH: 'ET',\n FIN: 'FI',\n FJI: 'FJ',\n FLK: 'FK',\n FRA: 'FR',\n FRO: 'FO',\n FSM: 'FM',\n GAB: 'GA',\n GBR: 'GB',\n GEO: 'GE',\n GGY: 'GG',\n GHA: 'GH',\n GIB: 'GI',\n GIN: 'GN',\n GLP: 'GP',\n GMB: 'GM',\n GNB: 'GW',\n GNQ: 'GQ',\n GRC: 'GR',\n GRD: 'GD',\n GRL: 'GL',\n GTM: 'GT',\n GUF: 'GF',\n GUM: 'GU',\n GUY: 'GY',\n HKG: 'HK',\n HMD: 'HM',\n HND: 'HN',\n HRV: 'HR',\n HTI: 'HT',\n HUN: 'HU',\n IDN: 'ID',\n IMN: 'IM',\n IND: 'IN',\n IOT: 'IO',\n IRL: 'IE',\n IRN: 'IR',\n IRQ: 'IQ',\n ISL: 'IS',\n ISR: 'IL',\n ITA: 'IT',\n JAM: 'JM',\n JEY: 'JE',\n JOR: 'JO',\n JPN: 'JP',\n KAZ: 'KZ',\n KEN: 'KE',\n KGZ: 'KG',\n KHM: 'KH',\n KIR: 'KI',\n KNA: 'KN',\n KOR: 'KR',\n KWT: 'KW',\n LAO: 'LA',\n LBN: 'LB',\n LBR: 'LR',\n LBY: 'LY',\n LCA: 'LC',\n LIE: 'LI',\n LKA: 'LK',\n LSO: 'LS',\n LTU: 'LT',\n LUX: 'LU',\n LVA: 'LV',\n MAC: 'MO',\n MAF: 'MF',\n MAR: 'MA',\n MCO: 'MC',\n MDA: 'MD',\n MDG: 'MG',\n MDV: 'MV',\n MEX: 'MX',\n MHL: 'MH',\n MKD: 'MK',\n MLI: 'ML',\n MLT: 'MT',\n MMR: 'MM',\n MNE: 'ME',\n MNG: 'MN',\n MNP: 'MP',\n MOZ: 'MZ',\n MRT: 'MR',\n MSR: 'MS',\n MTQ: 'MQ',\n MUS: 'MU',\n MWI: 'MW',\n MYS: 'MY',\n MYT: 'YT',\n NAM: 'NA',\n NCL: 'NC',\n NER: 'NE',\n NFK: 'NF',\n NGA: 'NG',\n NIC: 'NI',\n NIU: 'NU',\n NLD: 'NL',\n NOR: 'NO',\n NPL: 'NP',\n NRU: 'NR',\n NZL: 'NZ',\n OMN: 'OM',\n PAK: 'PK',\n PAN: 'PA',\n PCN: 'PN',\n PER: 'PE',\n PHL: 'PH',\n PLW: 'PW',\n PNG: 'PG',\n POL: 'PL',\n PRI: 'PR',\n PRK: 'KP',\n PRT: 'PT',\n PRY: 'PY',\n PSE: 'PS',\n PYF: 'PF',\n QAT: 'QA',\n REU: 'RE',\n ROU: 'RO',\n RUS: 'RU',\n RWA: 'RW',\n SAU: 'SA',\n SDN: 'SD',\n SEN: 'SN',\n SGP: 'SG',\n SGS: 'GS',\n SHN: 'SH',\n SJM: 'SJ',\n SLB: 'SB',\n SLE: 'SL',\n SLV: 'SV',\n SMR: 'SM',\n SOM: 'SO',\n SPM: 'PM',\n SRB: 'RS',\n SSD: 'SS',\n STP: 'ST',\n SUR: 'SR',\n SVK: 'SK',\n SVN: 'SI',\n SWE: 'SE',\n SWZ: 'SZ',\n SXM: 'SX',\n SYC: 'SC',\n SYR: 'SY',\n TCA: 'TC',\n TCD: 'TD',\n TGO: 'TG',\n THA: 'TH',\n TJK: 'TJ',\n TKL: 'TK',\n TKM: 'TM',\n TLS: 'TL',\n TON: 'TO',\n TTO: 'TT',\n TUN: 'TN',\n TUR: 'TR',\n TUV: 'TV',\n TWN: 'TW',\n TZA: 'TZ',\n UGA: 'UG',\n UKR: 'UA',\n UMI: 'UM',\n URY: 'UY',\n USA: 'US',\n UZB: 'UZ',\n VAT: 'VA',\n VCT: 'VC',\n VEN: 'VE',\n VGB: 'VG',\n VIR: 'VI',\n VNM: 'VN',\n VUT: 'VU',\n WLF: 'WF',\n WSM: 'WS',\n YEM: 'YE',\n ZAF: 'ZA',\n ZMB: 'ZM',\n ZWE: 'ZW',\n};\n\n/**\n * Normalize an ISO 3166-1 country code to alpha-2.\n *\n * - A 2-letter code (Google Play already returns alpha-2) is passed through,\n * uppercased.\n * - A 3-letter code (Apple StoreKit returns alpha-3) is mapped to alpha-2.\n * - Anything else — empty, malformed, or an unrecognized alpha-3 — returns\n * `null`, letting the caller decide on a fallback.\n */\nexport function toAlpha2(code: string): string | null {\n if (!code) return null;\n const normalized = code.trim().toUpperCase();\n if (normalized.length === 2) return normalized;\n if (normalized.length === 3) return ALPHA3_TO_ALPHA2[normalized] ?? null;\n return null;\n}\n","import { Capacitor } from '@capacitor/core';\nimport {\n NativePurchases,\n PURCHASE_TYPE,\n type Product as PluginProduct,\n type Transaction as PluginTransaction,\n} from '@capgo/native-purchases';\nimport { IAPError, IAPErrorCode } from '../../../lib/errors.js';\nimport { toAlpha2 } from '../../../lib/iso-country.js';\nimport { getPlatform } from '../../../lib/platform.js';\nimport type { Product, ProductType } from '../../../types/product.js';\nimport type { Storefront } from '../../../types/storefront.js';\nimport type { NativeTransaction, Platform } from '../../../types/transaction.js';\nimport type { NativeAdapter, NativePurchaseOptions } from '../types.js';\n\n/** Raw storefront shape the plugin `getStorefront` resolves to. */\ntype NativeStorefront = { countryCode?: string; storefrontId?: string };\n\n/**\n * The plugin surface for `getStorefront`, declared locally because some\n * installed `@capgo/native-purchases` builds predate it. Availability is\n * detected via the Capacitor plugin header (see {@link nativeStorefrontRegistered}),\n * NOT by inspecting this optional method: on a device `registerPlugin` returns\n * a Proxy that fabricates a function for any property name, so a `typeof\n * np.getStorefront === 'function'` check is always true and would not detect\n * an older plugin.\n */\ntype StorefrontCapablePlugin = {\n getStorefront?: () => Promise<NativeStorefront>;\n};\n\n/** Minimal shape of the Capacitor plugin-header registry we read. */\ntype CapacitorPluginHeaders = {\n PluginHeaders?: ReadonlyArray<{ name: string; methods?: ReadonlyArray<{ name: string }> }>;\n};\n\n/**\n * Whether the *native* `@capgo/native-purchases` build actually registered a\n * `getStorefront` method. Reads the Capacitor plugin header (the list the\n * native bridge injects) so older plugins resolve `null` without crossing the\n * bridge (which would log a native \"not implemented\" error on every call), and\n * the method lights up automatically once capgo ships it.\n */\nfunction nativeStorefrontRegistered(): boolean {\n const headers = (Capacitor as CapacitorPluginHeaders).PluginHeaders;\n return (\n headers\n ?.find((h) => h.name === 'NativePurchases')\n ?.methods?.some((m) => m.name === 'getStorefront') ?? false\n );\n}\n\n/**\n * Capacitor 8 adapter for the `@capgo/native-purchases` `^8` line (this is the\n * `8.x` line of `@nosslabs/iap`; Cap-7 consumers stay on `7.x`). The v8 plugin\n * is additive over the 7.16.x surface captured in\n * `docs/internal/plugin-v7-api.md` — every method below keeps its 7.16.2\n * signature — so that capture still describes what this adapter calls.\n *\n * Plugin contract (relevant bits):\n * - `purchaseProduct({ ..., autoAcknowledgePurchases: false })` defers finishing on\n * both iOS and Android (since v7) — this is the foundation of the\n * \"never grant entitlement before backend confirms\" guarantee, with no\n * iOS-specific finish-before-verify race.\n * - `acknowledgePurchase({ purchaseToken })` is cross-platform (since v7.14.0).\n * For iOS, pass the `transactionId` as a string in the `purchaseToken` arg —\n * under the hood it calls `Transaction.finish()`. Stateless: no transaction\n * object to retain, so this adapter holds no internal state and needs no\n * long-lived listeners.\n * - `getPurchases()` returns owned transactions, but with a platform quirk\n * worth knowing: on iOS it bundles `Transaction.currentEntitlements`\n * *plus* `Transaction.all` (full history including expired/revoked\n * subscriptions); on Android it returns Google Play's owned set, and\n * {@link CapgoNativeAdapter.getOwnedTransactions} filters out PENDING\n * purchases (`purchaseState !== '1'`). The library passes whatever\n * survives that filter to `backend.restore()`; the backend is the source\n * of truth for \"is this receipt currently valid\" and is expected to\n * tolerate historical iOS entries gracefully.\n */\nexport class CapgoNativeAdapter implements NativeAdapter {\n async isAvailable(): Promise<boolean> {\n try {\n const result = await NativePurchases.isBillingSupported();\n return result.isBillingSupported;\n } catch {\n return false;\n }\n }\n\n async getProducts(requests: Array<{ id: string; type: ProductType }>): Promise<Product[]> {\n if (requests.length === 0) return [];\n\n const inappIds: string[] = [];\n const subsIds: string[] = [];\n const requestById = new Map<string, ProductType>();\n\n for (const req of requests) {\n requestById.set(req.id, req.type);\n if (req.type === 'subscription') {\n subsIds.push(req.id);\n } else {\n inappIds.push(req.id);\n }\n }\n\n const [inapp, subs] = await Promise.all([\n inappIds.length > 0\n ? NativePurchases.getProducts({\n productIdentifiers: inappIds,\n productType: PURCHASE_TYPE.INAPP,\n })\n : Promise.resolve({ products: [] as PluginProduct[] }),\n subsIds.length > 0\n ? NativePurchases.getProducts({\n productIdentifiers: subsIds,\n productType: PURCHASE_TYPE.SUBS,\n })\n : Promise.resolve({ products: [] as PluginProduct[] }),\n ]);\n\n const all = [...inapp.products, ...subs.products];\n return all.map((p) => normalizeProduct(p, requestById.get(p.identifier) ?? 'product'));\n }\n\n async purchaseProduct(opts: NativePurchaseOptions): Promise<NativeTransaction> {\n const purchaseType = mapToPluginPurchaseType(opts.productType);\n const isConsumable = opts.productType === 'consumable';\n\n let tx: PluginTransaction;\n try {\n tx = await NativePurchases.purchaseProduct({\n productIdentifier: opts.productId,\n productType: purchaseType,\n planIdentifier: opts.androidPlanId,\n appAccountToken: opts.appAccountToken,\n isConsumable,\n autoAcknowledgePurchases: false,\n });\n } catch (error) {\n throw mapPurchaseError(error, opts.productId);\n }\n\n return normalizeTransaction(tx, opts.productType);\n }\n\n async getOwnedTransactions(): Promise<NativeTransaction[]> {\n const result = await NativePurchases.getPurchases();\n return (\n result.purchases\n // Drop Android PENDING purchases (purchaseState '0'); iOS has no\n // purchaseState. A pending Play purchase isn't owned yet — sending\n // it to the backend's /restore would only get rejected. (iOS-side\n // expired/revoked subs are NOT filtered here — they're part of\n // `Transaction.all` per the class-level JSDoc; the backend decides.)\n .filter((tx) => tx.purchaseState === undefined || tx.purchaseState === '1')\n .map((tx) => normalizeTransaction(tx, inferProductType(tx)))\n );\n }\n\n async acknowledge(transaction: NativeTransaction): Promise<void> {\n try {\n await NativePurchases.acknowledgePurchase({\n purchaseToken: transaction.token,\n });\n } catch (error) {\n throw new IAPError({\n code: IAPErrorCode.STORE_ERROR,\n message: `Failed to acknowledge transaction for ${transaction.productId}.`,\n cause: error,\n recoverable: true,\n });\n }\n }\n\n async manageSubscriptions(): Promise<void> {\n try {\n await NativePurchases.manageSubscriptions();\n } catch (error) {\n // No `recoverable: true` here (unlike acknowledge()): this is a UI\n // navigation action, not a transaction-lifecycle step, so there's\n // nothing for the recovery loop to retry.\n throw new IAPError({\n code: IAPErrorCode.STORE_ERROR,\n message: 'Failed to open the native subscription management UI.',\n cause: error,\n });\n }\n }\n\n /**\n * Read the current storefront from the native plugin — which is expected to\n * source it from StoreKit 2 `Storefront.current` on iOS (alpha-3) and\n * `getBillingConfigAsync()` on Android (alpha-2) — normalizing `countryCode`\n * to alpha-2. Silent like {@link CapgoNativeAdapter.isAvailable}: any\n * unavailability — older plugin (no native method registered), native\n * rejection, or empty country — resolves to `null` rather than throwing.\n */\n async getStorefront(): Promise<Storefront | null> {\n if (!nativeStorefrontRegistered()) return null;\n const np = NativePurchases as typeof NativePurchases & StorefrontCapablePlugin;\n try {\n const raw = await np.getStorefront?.();\n return raw ? normalizeStorefront(raw) : null;\n } catch {\n return null;\n }\n }\n\n async dispose(): Promise<void> {\n // No-op: this adapter owns no long-lived listeners or timers.\n }\n}\n\nfunction normalizeStorefront(raw: NativeStorefront): Storefront | null {\n const code = raw?.countryCode?.trim();\n if (!code) return null;\n\n const platform: Platform = getPlatform() === 'android' ? 'google' : 'apple';\n return {\n // alpha-2 when recognized; otherwise the uppercased raw code as a\n // best-effort fallback (see `Storefront.countryCode`).\n countryCode: toAlpha2(code) ?? code.toUpperCase(),\n countryCodeRaw: code,\n storefrontId: raw.storefrontId,\n platform,\n };\n}\n\nfunction normalizeProduct(p: PluginProduct, type: ProductType): Product {\n const priceMicros = Math.round(p.price * 1_000_000).toString();\n return {\n id: p.identifier,\n type,\n title: p.title,\n description: p.description,\n priceString: p.priceString,\n priceMicros,\n currency: p.currencyCode,\n };\n}\n\nfunction normalizeTransaction(tx: PluginTransaction, productType: ProductType): NativeTransaction {\n const platform = inferPlatform(tx);\n const token = platform === 'google' ? (tx.purchaseToken ?? tx.transactionId) : tx.transactionId;\n\n const native: NativeTransaction = {\n platform,\n productId: tx.productIdentifier,\n token,\n productType,\n raw: tx,\n };\n\n // packageName is not exposed by the plugin's Transaction shape; consumers\n // pass it via Capacitor app config and it's added by the backend HTTP layer\n // before sending to /verify/google.\n\n return native;\n}\n\nfunction inferPlatform(tx: PluginTransaction): Platform {\n if (\n tx.purchaseToken !== undefined ||\n tx.purchaseState !== undefined ||\n tx.orderId !== undefined\n ) {\n return 'google';\n }\n if (tx.receipt !== undefined || tx.jwsRepresentation !== undefined) {\n return 'apple';\n }\n // Fall back to runtime platform.\n return getPlatform() === 'android' ? 'google' : 'apple';\n}\n\n// The plugin's Transaction only carries 'inapp' | 'subs', so this never\n// resolves to 'consumable' — fine, since getOwnedTransactions() consumers\n// (restore-flow) key on platform/token/packageName, not the consumable bit.\nfunction inferProductType(tx: PluginTransaction): ProductType {\n if (tx.productType === 'subs') return 'subscription';\n return 'product';\n}\n\nfunction mapToPluginPurchaseType(type: ProductType): PURCHASE_TYPE {\n return type === 'subscription' ? PURCHASE_TYPE.SUBS : PURCHASE_TYPE.INAPP;\n}\n\n/**\n * Translate a `purchaseProduct()` rejection into a coded {@link IAPError} so\n * the purchase orchestrator can route it to the right `PurchaseResult` status.\n *\n * `@capgo/native-purchases` rejects with plain message strings — the\n * signals we can distinguish (verified against the plugin's native source):\n * - iOS: `\"User cancelled\"`, `\"Transaction pending\"`,\n * `\"Cannot find product for id <id>\"`.\n * - Android: `\"Purchase is pending\"`, `\"Product not found\"`. Note Android\n * does NOT distinguish user-cancel from other billing errors — both\n * surface as `\"Purchase is not purchased\"`, which falls through to\n * `STORE_ERROR`. The error-handling docs note this asymmetry for\n * consumer UX (treat Android `failed` similarly to `cancelled`).\n */\nfunction mapPurchaseError(error: unknown, productId: string): IAPError {\n if (error instanceof IAPError) return error;\n const message = error instanceof Error ? error.message : String(error);\n const lower = message.toLowerCase();\n\n if (lower.includes('cancel')) {\n return new IAPError({\n code: IAPErrorCode.USER_CANCELLED,\n message: `Purchase of \"${productId}\" was cancelled.`,\n cause: error,\n });\n }\n if (lower.includes('pending')) {\n return new IAPError({\n code: IAPErrorCode.PURCHASE_PENDING,\n message: `Purchase of \"${productId}\" is pending external clearance.`,\n cause: error,\n });\n }\n // iOS uses `\"Cannot find product for id <id>\"`; Android uses\n // `\"Product not found\"`. Match both shapes.\n if (lower.includes('product not found') || lower.includes('cannot find product')) {\n return new IAPError({\n code: IAPErrorCode.PRODUCT_NOT_FOUND,\n message: `Product \"${productId}\" was not found in the store catalog.`,\n cause: error,\n });\n }\n return new IAPError({\n code: IAPErrorCode.STORE_ERROR,\n message: `Native purchase of \"${productId}\" failed.`,\n cause: error,\n });\n}\n","import { IAPError, IAPErrorCode } from '../../lib/errors.js';\nimport type { Logger } from '../../lib/logger.js';\nimport type { BackendConfig } from '../../types/config.js';\nimport type { EntitlementBase } from '../../types/entitlement.js';\nimport { HttpBackendAdapter } from './http-adapter.js';\nimport { type BackendAdapter, isBackendAdapter } from './types.js';\n\nexport interface BackendAdapterOptions {\n config: BackendConfig;\n logger: Logger;\n /** Test/override hook. Otherwise uses globalThis.fetch. */\n fetch?: typeof fetch;\n}\n\n/**\n * Build the active `BackendAdapter`.\n *\n * - If `config.adapter` is provided, validates the shape and returns it directly.\n * - Otherwise, builds an {@link HttpBackendAdapter} from the HTTP-specific config.\n *\n * Schema-level validation already enforces that HTTP fields are present when\n * no adapter is provided (see `backendConfigSchema.superRefine`); this\n * function still re-checks at runtime for defense-in-depth.\n */\nexport function selectBackendAdapter<TEntitlement extends EntitlementBase = EntitlementBase>(\n options: BackendAdapterOptions,\n): BackendAdapter<TEntitlement> {\n const { config, logger, fetch: fetchImpl } = options;\n\n if (config.adapter !== undefined) {\n if (!isBackendAdapter(config.adapter)) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'backend.adapter must implement BackendAdapter (verifyApple, verifyGoogle, getEntitlements, restore).',\n });\n }\n return config.adapter as BackendAdapter<TEntitlement>;\n }\n\n // HTTP path — schema already required these fields, but re-check.\n if (!config.baseUrl || !config.endpoints || !config.getAuthHeaders) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'backend HTTP fields (baseUrl, endpoints, getAuthHeaders) are required when no custom adapter is provided.',\n });\n }\n\n return new HttpBackendAdapter<TEntitlement>({\n baseUrl: config.baseUrl,\n endpoints: config.endpoints,\n getAuthHeaders: config.getAuthHeaders,\n requestTransform: config.requestTransform,\n responseTransform: config.responseTransform,\n timeoutMs: config.timeoutMs,\n retries: config.retries,\n logger,\n ...(fetchImpl ? { fetch: fetchImpl } : {}),\n });\n}\n\nexport { HttpBackendAdapter } from './http-adapter.js';\nexport { HttpClient } from './http-client.js';\n","import { IAPError, IAPErrorCode } from '../../lib/errors.js';\nimport type { Logger } from '../../lib/logger.js';\nimport type { BackendConfig } from '../../types/config.js';\nimport type { EntitlementBase } from '../../types/entitlement.js';\nimport type { ConfiguredProduct } from '../../types/product.js';\nimport { HttpClient } from './http-client.js';\nimport {\n type BackendAdapter,\n type RestoreRequest,\n type RestoreResponse,\n type VerifyAppleRequest,\n type VerifyGoogleRequest,\n type VerifyResponse,\n entitlementsResponseSchema,\n productManifestResponseSchema,\n restoreResponseSchema,\n verifyResponseSchema,\n} from './types.js';\n\nexport interface HttpBackendAdapterOptions {\n baseUrl: string;\n endpoints: {\n /**\n * Optional. Required only when the consumer's app actually invokes\n * `verifyApple` (iOS purchases). Android-only configs may omit it; the\n * adapter throws `INVALID_CONFIG` if `verifyApple()` is called without\n * this set. At least one of `verifyApple` or `verifyGoogle` must be set\n * for any usable config.\n */\n verifyApple?: string;\n /**\n * Optional. Required only when the consumer's app actually invokes\n * `verifyGoogle` (Android purchases). iOS-only configs may omit it; the\n * adapter throws `INVALID_CONFIG` if `verifyGoogle()` is called without\n * this set. At least one of `verifyApple` or `verifyGoogle` must be set\n * for any usable config.\n */\n verifyGoogle?: string;\n entitlements: string;\n restore: string;\n products?: string;\n };\n getAuthHeaders: () => Record<string, string> | Promise<Record<string, string>>;\n requestTransform?: BackendConfig['requestTransform'];\n responseTransform?: BackendConfig['responseTransform'];\n timeoutMs: number;\n retries: number;\n fetch?: typeof fetch;\n logger: Logger;\n}\n\n/**\n * Default `BackendAdapter` implementation: HTTP/JSON via `fetch`.\n *\n * The four methods translate to HTTP calls against the consumer's backend:\n * - `verifyApple` → POST `endpoints.verifyApple`\n * - `verifyGoogle` → POST `endpoints.verifyGoogle`\n * - `getEntitlements` → GET `endpoints.entitlements`\n * - `restore` → POST `endpoints.restore`\n *\n * The recommended request/response shape mirrors Attesto's normalized\n * transaction one hop downstream (see PLAN.md §5.8). Consumers whose\n * backend uses a different shape can supply `requestTransform` /\n * `responseTransform` to map between the library's defaults and theirs.\n */\nexport class HttpBackendAdapter<TEntitlement extends EntitlementBase = EntitlementBase>\n implements BackendAdapter<TEntitlement>\n{\n private readonly http: HttpClient;\n private readonly endpoints: HttpBackendAdapterOptions['endpoints'];\n\n constructor(opts: HttpBackendAdapterOptions) {\n this.endpoints = opts.endpoints;\n const httpClientOpts: ConstructorParameters<typeof HttpClient>[0] = {\n baseUrl: opts.baseUrl,\n getAuthHeaders: opts.getAuthHeaders,\n timeoutMs: opts.timeoutMs,\n retries: opts.retries,\n logger: opts.logger,\n ...(opts.requestTransform ? { requestTransform: opts.requestTransform } : {}),\n ...(opts.responseTransform ? { responseTransform: opts.responseTransform } : {}),\n ...(opts.fetch ? { fetch: opts.fetch } : {}),\n };\n this.http = new HttpClient(httpClientOpts);\n }\n\n async verifyApple(req: VerifyAppleRequest): Promise<VerifyResponse<TEntitlement>> {\n if (!this.endpoints.verifyApple) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'HttpBackendAdapter.verifyApple() requires backend.endpoints.verifyApple to be configured. Set it on iOS-supporting builds, or skip Apple purchases on this build.',\n });\n }\n const result = await this.http.request(\n { method: 'POST', path: this.endpoints.verifyApple, body: req },\n verifyResponseSchema,\n );\n return result as VerifyResponse<TEntitlement>;\n }\n\n async verifyGoogle(req: VerifyGoogleRequest): Promise<VerifyResponse<TEntitlement>> {\n if (!this.endpoints.verifyGoogle) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'HttpBackendAdapter.verifyGoogle() requires backend.endpoints.verifyGoogle to be configured. Set it on Android-supporting builds, or skip Google purchases on this build.',\n });\n }\n const result = await this.http.request(\n { method: 'POST', path: this.endpoints.verifyGoogle, body: req },\n verifyResponseSchema,\n );\n return result as VerifyResponse<TEntitlement>;\n }\n\n async getEntitlements(): Promise<TEntitlement[]> {\n const result = await this.http.request(\n { method: 'GET', path: this.endpoints.entitlements },\n entitlementsResponseSchema,\n );\n return result.entitlements as TEntitlement[];\n }\n\n async restore(req: RestoreRequest): Promise<RestoreResponse<TEntitlement>> {\n // Empty-array guard lives in `RestoreOrchestrator` (transport-agnostic);\n // see Phase 3 review L7. If a consumer calls this adapter directly with\n // an empty list, the backend's response is whatever it returns — usually\n // a 400 the HttpClient surfaces as `BACKEND_BAD_RESPONSE`.\n const result = await this.http.request(\n { method: 'POST', path: this.endpoints.restore, body: req },\n restoreResponseSchema,\n );\n return result as RestoreResponse<TEntitlement>;\n }\n\n async listProducts(): Promise<ConfiguredProduct[]> {\n if (!this.endpoints.products) {\n // Defensive: createIAP only calls listProducts() when this is set, but\n // a consumer who reaches into the adapter directly gets a clear error.\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'HttpBackendAdapter.listProducts() requires backend.endpoints.products to be configured.',\n });\n }\n const result = await this.http.request(\n { method: 'GET', path: this.endpoints.products },\n productManifestResponseSchema,\n );\n return result.products;\n }\n}\n","import type { z } from 'zod';\nimport { IAPError, IAPErrorCode } from '../../lib/errors.js';\nimport type { Logger } from '../../lib/logger.js';\nimport { redactHeaders } from '../../lib/redact.js';\n\nexport interface HttpRequest {\n method: 'GET' | 'POST';\n /**\n * Path appended to baseUrl. Leading slash is optional — both `'/foo'` and\n * `'foo'` are normalized at request time, and any trailing slash on `baseUrl`\n * is stripped, so all four corner cases produce the same joined URL.\n */\n path: string;\n /** JSON-serializable body (for POST). */\n body?: unknown;\n /** Extra headers, merged on top of auth headers + Content-Type. */\n headers?: Record<string, string>;\n}\n\nexport interface HttpClientOptions {\n baseUrl: string;\n /** Called before every request. Returns headers to merge in (e.g. `{ Authorization: 'Bearer ...' }`). */\n getAuthHeaders: () => Record<string, string> | Promise<Record<string, string>>;\n /** Per-attempt timeout in ms. */\n timeoutMs: number;\n /** Number of retry attempts on transient errors (5xx, 408, 429, network). */\n retries: number;\n /** Optional pre-send transform. Lets consumer rewrite path/body/headers. */\n requestTransform?: (req: HttpRequest) => HttpRequest | Promise<HttpRequest>;\n /** Optional response transform. Runs on the parsed JSON before validation. */\n responseTransform?: (raw: unknown) => unknown | Promise<unknown>;\n /** Override `globalThis.fetch` for tests. */\n fetch?: typeof fetch;\n logger: Logger;\n}\n\n/** Backoff schedule for transient retries (ms). Caps at 4s on attempt 3+. */\nconst RETRY_BACKOFF_MS = [1_000, 2_000, 4_000];\n\n/**\n * Generic HTTP client for the consumer backend.\n *\n * - **Timeout**: per-attempt via `AbortController` (native fetch has no timeout option).\n * - **Retry policy**: 5xx, 408, 429, and network errors retry with exponential backoff.\n * Other 4xx fail immediately (caller's responsibility to fix).\n * - **Auth + transforms**: `getAuthHeaders()` runs once per request; `requestTransform`\n * and `responseTransform` are escape hatches for consumers whose backend uses a\n * different shape than the library's default.\n * - **Logging**: requests are logged at debug level with sensitive headers redacted\n * via `redactHeaders()` (PLAN.md §13 — never log raw bearer tokens).\n *\n * Consumers don't construct this directly — `HttpBackendAdapter` wraps it.\n */\nexport class HttpClient {\n private readonly fetchImpl: typeof fetch;\n\n constructor(private readonly opts: HttpClientOptions) {\n const provided = opts.fetch;\n if (provided) {\n this.fetchImpl = provided;\n } else if (typeof globalThis.fetch === 'function') {\n this.fetchImpl = globalThis.fetch.bind(globalThis);\n } else {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message: 'globalThis.fetch is unavailable; pass a fetch implementation via config.',\n });\n }\n }\n\n /**\n * Execute the request and parse the response with the given zod schema.\n * Returns the validated, transformed result.\n */\n async request<T>(req: HttpRequest, schema: z.ZodType<T>): Promise<T> {\n const transformed = this.opts.requestTransform ? await this.opts.requestTransform(req) : req;\n\n const base = this.opts.baseUrl.replace(/\\/+$/, '');\n const path = transformed.path.startsWith('/') ? transformed.path : `/${transformed.path}`;\n const url = `${base}${path}`;\n const auth = await this.opts.getAuthHeaders();\n const headers: Record<string, string> = {\n 'content-type': 'application/json',\n accept: 'application/json',\n ...auth,\n ...(transformed.headers ?? {}),\n };\n\n let lastError: IAPError | undefined;\n const maxAttempts = this.opts.retries + 1;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await this.singleAttempt<T>(url, transformed, headers, schema);\n } catch (error) {\n if (!(error instanceof IAPError) || !error.recoverable) {\n throw error;\n }\n lastError = error;\n const remaining = maxAttempts - attempt;\n if (remaining <= 0) break;\n const delayMs =\n RETRY_BACKOFF_MS[attempt - 1] ?? RETRY_BACKOFF_MS[RETRY_BACKOFF_MS.length - 1] ?? 4_000;\n this.opts.logger.debug(\n `HTTP ${transformed.method} ${transformed.path} retry ${attempt}/${this.opts.retries} after ${delayMs}ms (${error.code})`,\n );\n await sleep(delayMs);\n }\n }\n throw (\n lastError ??\n new IAPError({\n code: IAPErrorCode.BACKEND_UNAVAILABLE,\n message: 'Backend request failed with no recorded error.',\n })\n );\n }\n\n private async singleAttempt<T>(\n url: string,\n req: HttpRequest,\n headers: Record<string, string>,\n schema: z.ZodType<T>,\n ): Promise<T> {\n this.opts.logger.debug(`HTTP ${req.method} ${req.path}`, { headers: redactHeaders(headers) });\n\n let response: Response;\n try {\n response = await this.fetchWithTimeout(url, {\n method: req.method,\n headers,\n body: req.body !== undefined ? JSON.stringify(req.body) : undefined,\n });\n } catch (cause) {\n // AbortError → timeout; everything else → network error.\n const isAbort = (cause as { name?: string } | null)?.name === 'AbortError';\n throw new IAPError({\n code: isAbort ? IAPErrorCode.BACKEND_TIMEOUT : IAPErrorCode.BACKEND_UNAVAILABLE,\n message: isAbort\n ? `Backend request timed out after ${this.opts.timeoutMs}ms.`\n : 'Network error while calling backend.',\n cause,\n recoverable: true,\n });\n }\n\n if (response.status === 401 || response.status === 403) {\n throw new IAPError({\n code: IAPErrorCode.BACKEND_AUTH_FAILED,\n message: `Backend auth failed (${response.status}).`,\n });\n }\n\n if (!response.ok) {\n const transient =\n response.status === 408 || response.status === 429 || response.status >= 500;\n throw new IAPError({\n // Transient failures (5xx, 408, 429) → BACKEND_UNAVAILABLE so the\n // retry loop picks them up. Non-transient (other 4xx after auth has\n // been ruled out) → BACKEND_BAD_RESPONSE so the orchestrator can\n // surface \"fix the request\" rather than \"try again later\".\n code: transient ? IAPErrorCode.BACKEND_UNAVAILABLE : IAPErrorCode.BACKEND_BAD_RESPONSE,\n message: `Backend returned ${response.status} ${response.statusText}.`,\n recoverable: transient,\n });\n }\n\n // 204 No Content on a JSON endpoint is a contract violation — PLAN.md §5.8\n // defines explicit JSON shapes for every endpoint, so we fail loudly with\n // a precise error rather than the misleading \"not valid JSON\" path below.\n if (response.status === 204 || response.headers.get('content-length') === '0') {\n throw new IAPError({\n code: IAPErrorCode.BACKEND_BAD_RESPONSE,\n message: `Backend returned ${response.status} with empty body; expected JSON for ${req.path}.`,\n });\n }\n\n let raw: unknown;\n try {\n raw = await response.json();\n } catch (cause) {\n throw new IAPError({\n code: IAPErrorCode.BACKEND_BAD_RESPONSE,\n message: 'Backend response was not valid JSON.',\n cause,\n });\n }\n\n const transformed = this.opts.responseTransform ? await this.opts.responseTransform(raw) : raw;\n\n const parsed = schema.safeParse(transformed);\n if (!parsed.success) {\n throw new IAPError({\n code: IAPErrorCode.BACKEND_BAD_RESPONSE,\n message: `Backend response failed validation: ${parsed.error.issues\n .map((i) => `${i.path.join('.') || '<root>'}: ${i.message}`)\n .join('; ')}`,\n cause: parsed.error,\n });\n }\n return parsed.data;\n }\n\n private async fetchWithTimeout(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.opts.timeoutMs);\n try {\n return await this.fetchImpl(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/**\n * Logging redaction utilities.\n *\n * The library NEVER logs full purchase tokens, JWS payloads, receipts,\n * or auth headers (PLAN.md §13). These helpers produce safe-to-log\n * representations that preserve enough information for debugging\n * without leaking sensitive data.\n */\n\nconst VISIBLE_PREFIX_CHARS = 8;\nconst ELLIPSIS = '…';\n\n/**\n * Mask a token-like string. Returns the first 8 characters followed by\n * an ellipsis. Returns the input unchanged if it's already shorter than\n * 8 characters (no privacy gain to masking) or empty.\n *\n * @example\n * maskToken('GPA.1234-5678-9012-34567') → 'GPA.1234…'\n * maskToken('2000000123456789') → '20000001…'\n * maskToken('short') → 'short'\n * maskToken('') → ''\n */\nexport function maskToken(token: string | null | undefined): string {\n if (!token) return '';\n if (token.length <= VISIBLE_PREFIX_CHARS) return token;\n return token.slice(0, VISIBLE_PREFIX_CHARS) + ELLIPSIS;\n}\n\n/**\n * Mask a credential (auth header value, cookie, API key). Unlike\n * {@link maskToken}, this NEVER returns the input unchanged — short\n * sandbox/test tokens (e.g. `secret12`) must still be redacted. Any\n * non-empty value collapses to either `prefix…` (for ≥8 chars) or just\n * `…` (for shorter values). Empty input returns empty.\n *\n * Use this for anything that grants access if leaked.\n */\nfunction maskCredential(value: string | null | undefined): string {\n if (!value) return '';\n if (value.length <= VISIBLE_PREFIX_CHARS) return ELLIPSIS;\n return value.slice(0, VISIBLE_PREFIX_CHARS) + ELLIPSIS;\n}\n\nconst SENSITIVE_HEADER_PATTERNS = [\n /^authorization$/i,\n /^cookie$/i,\n /^x-api-key$/i,\n /^x-auth-token$/i,\n];\n\n/**\n * Return a copy of a headers map with sensitive values masked.\n * Header NAMES are preserved (case-insensitive match against known\n * sensitive patterns); only the value is redacted.\n *\n * @example\n * redactHeaders({ Authorization: 'Bearer abc123def456', 'X-Trace-Id': 'xyz' })\n * → { Authorization: 'Bearer a…', 'X-Trace-Id': 'xyz' }\n */\nexport function redactHeaders(headers: Record<string, string>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [name, value] of Object.entries(headers)) {\n out[name] = isSensitiveHeader(name) ? redactHeaderValue(value) : value;\n }\n return out;\n}\n\nfunction isSensitiveHeader(name: string): boolean {\n return SENSITIVE_HEADER_PATTERNS.some((pattern) => pattern.test(name));\n}\n\nfunction redactHeaderValue(value: string): string {\n // Bearer tokens and API keys: mask the credential portion but keep the scheme.\n // Use maskCredential (not maskToken) so short sandbox tokens are still hidden.\n const bearerMatch = value.match(/^(Bearer|Basic|Token)\\s+(.+)$/i);\n if (bearerMatch) {\n const [, scheme, credential] = bearerMatch;\n return `${scheme} ${maskCredential(credential ?? '')}`;\n }\n return maskCredential(value);\n}\n","import { z } from 'zod';\nimport type { HttpRequest } from '../adapters/backend/http-client.js';\n\nexport const productTypeSchema = z.enum(['subscription', 'product', 'consumable']);\n\nconst configuredProductSchema = z.object({\n id: z.string().min(1),\n type: productTypeSchema,\n /**\n * Optional. Used only by the Android native adapter to disambiguate which\n * base plan to purchase for multi-plan subscription products (Google Play\n * Billing). iOS ignores it. When omitted on Android, the native adapter\n * falls back to `native.getOffer()` (the default offer) — fine for\n * single-plan subscriptions and for non-subscription products.\n *\n * Recommended to set explicitly when a single subscription product has\n * multiple base plans (e.g. monthly + yearly under one product id).\n */\n androidPlanId: z.string().min(1).optional(),\n});\n\n/**\n * Array form. Reused by `productManifestResponseSchema` (HTTP) and by the\n * runtime guard in `createIAP.initialize()` for backend-supplied manifests.\n */\nexport const configuredProductsArraySchema = z.array(configuredProductSchema).min(1);\n\nconst backendEndpointsSchema = z\n .object({\n /**\n * Optional. Set when the consumer supports iOS purchases. iOS-less\n * (e.g. Android-only) configs may omit it; the HTTP adapter will throw\n * `INVALID_CONFIG` at runtime if `verifyApple()` is invoked without this\n * endpoint configured. At least one of `verifyApple` or `verifyGoogle`\n * must be set.\n */\n verifyApple: z.string().min(1).optional(),\n /**\n * Optional. Set when the consumer supports Android purchases.\n * Android-less (e.g. iOS-only) configs may omit it; the HTTP adapter will\n * throw `INVALID_CONFIG` at runtime if `verifyGoogle()` is invoked\n * without this endpoint configured. At least one of `verifyApple` or\n * `verifyGoogle` must be set.\n */\n verifyGoogle: z.string().min(1).optional(),\n entitlements: z.string().min(1),\n restore: z.string().min(1),\n /**\n * Optional. When set, the library fetches the SKU manifest from this\n * endpoint during `initialize()` if `products` is omitted from config.\n * See `docs/guide/backend-contract.md` for the response shape.\n */\n products: z.string().min(1).optional(),\n })\n .superRefine((data, ctx) => {\n if (!data.verifyApple && !data.verifyGoogle) {\n // Attach to the object root rather than one of the two fields — the\n // constraint is cross-field, so naming a single path is misleading\n // (a developer reading \"verifyApple: ...\" may add only that and miss\n // that verifyGoogle would also satisfy the constraint).\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n 'At least one of backend.endpoints.verifyApple or backend.endpoints.verifyGoogle must be set.',\n path: [],\n });\n }\n });\n\nconst backendConfigSchema = z\n .object({\n /**\n * Custom backend transport. If provided, all HTTP-specific fields below\n * are ignored and the library uses this object directly for backend\n * operations. Must implement `BackendAdapter`.\n */\n adapter: z.unknown().optional(),\n\n // ----- HTTP-specific fields (used when `adapter` is not provided) -----\n baseUrl: z.string().url().optional(),\n endpoints: backendEndpointsSchema.optional(),\n /**\n * Returns auth headers to merge into every backend request. Called fresh\n * per request so token refresh works automatically. Type is checked at\n * runtime via shape guard, not zod (zod can't validate function contracts).\n */\n getAuthHeaders: z.unknown().optional(),\n /** Pre-send request transform. See {@link BackendConfig} for the typed shape. */\n requestTransform: z.unknown().optional(),\n /** Post-receive response transform. See {@link BackendConfig} for the typed shape. */\n responseTransform: z.unknown().optional(),\n entitlementSchema: z.unknown().optional(),\n\n // ----- Common (apply to both HTTP and custom adapters where relevant) -----\n timeoutMs: z.number().int().positive().default(10_000),\n retries: z.number().int().min(0).max(5).default(2),\n })\n .superRefine((data, ctx) => {\n // When no custom adapter, HTTP fields are required.\n if (data.adapter !== undefined) return;\n if (!data.baseUrl) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'backend.baseUrl is required when no custom adapter is provided.',\n path: ['baseUrl'],\n });\n }\n if (!data.endpoints) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'backend.endpoints is required when no custom adapter is provided.',\n path: ['endpoints'],\n });\n }\n if (typeof data.getAuthHeaders !== 'function') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n 'backend.getAuthHeaders must be a function (() => Record<string, string> | Promise<Record<string, string>>) when no custom adapter is provided.',\n path: ['getAuthHeaders'],\n });\n }\n });\n\nconst storageConfigSchema = z.object({\n type: z.enum(['preferences', 'memory', 'custom']).default('preferences'),\n namespace: z.string().min(1).default('nosslabs_iap'),\n adapter: z.unknown().optional(),\n});\n\nconst optionsConfigSchema = z.object({\n refreshOnResume: z.boolean().default(true),\n entitlementCacheTtlMs: z\n .number()\n .int()\n .positive()\n .default(60 * 60 * 1000),\n recoverUnfinishedTransactions: z.boolean().default(true),\n /**\n * Cap on how many unfinished transactions recovery inspects per launch.\n * Defends against pathological growth if the consumer's backend has been\n * down for an extended period and the unfinished list keeps growing.\n * Excess entries stay in storage and are processed on subsequent launches.\n */\n recoveryMaxBatch: z.number().int().positive().default(50),\n /**\n * List of backend `valid:false` error codes that recovery should treat as\n * permanent — entries with a matching error are removed from storage\n * instead of retried on every launch. When omitted (the default), iap\n * uses `DEFAULT_PERMANENT_ERROR_CODES` (`['TRANSACTION_NOT_FOUND',\n * 'PRODUCT_MISMATCH']`).\n *\n * REPLACES the default when provided — pass `[...DEFAULT_PERMANENT_ERROR_CODES,\n * 'YOUR_CODE']` to extend, or `[]` to disable the feature entirely\n * (revert to retry-forever behavior). Export the constant from\n * `@nosslabs/iap` for the spread form.\n */\n permanentErrorCodes: z.array(z.string()).optional(),\n productPriceCacheTtlMs: z\n .number()\n .int()\n .positive()\n .default(24 * 60 * 60 * 1000),\n logLevel: z.enum(['silent', 'error', 'warn', 'info', 'debug']).default('info'),\n logger: z.unknown().optional(),\n});\n\nexport const iapConfigSchema = z\n .object({\n /**\n * Static SKU manifest. Optional: when omitted, the library calls\n * `backend.adapter.listProducts()` (custom adapter) or GETs\n * `backend.endpoints.products` (HTTP) during `initialize()`. Configs\n * without either path throw `INVALID_CONFIG` at parse time.\n */\n products: z.array(configuredProductSchema).min(1).optional(),\n backend: backendConfigSchema,\n storage: storageConfigSchema.default({ type: 'preferences', namespace: 'nosslabs_iap' }),\n options: optionsConfigSchema.default({\n refreshOnResume: true,\n entitlementCacheTtlMs: 60 * 60 * 1000,\n recoverUnfinishedTransactions: true,\n recoveryMaxBatch: 50,\n productPriceCacheTtlMs: 24 * 60 * 60 * 1000,\n logLevel: 'info',\n }),\n })\n .superRefine((data, ctx) => {\n if (data.products !== undefined) return;\n // No static products → the backend must be able to supply them.\n // Adapter takes precedence: if `adapter` is provided, the HTTP fields are\n // ignored everywhere else, so we ignore them here too. The HTTP path is\n // only consulted when no custom adapter is set.\n const adapter = data.backend.adapter as { listProducts?: unknown } | undefined;\n const adapterCanList = adapter && typeof adapter.listProducts === 'function';\n const httpCanList = !data.backend.adapter && data.backend.endpoints?.products;\n if (!adapterCanList && !httpCanList) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n 'products is required unless the backend can supply it: set backend.endpoints.products (HTTP) or implement listProducts() on a custom adapter.',\n path: ['products'],\n });\n }\n });\n\ntype RawBackendConfig = z.infer<typeof backendConfigSchema>;\ntype RawBackendConfigInput = z.input<typeof backendConfigSchema>;\n\n/**\n * Replace the schema's `unknown` typings for function-shaped fields with\n * their precise TS contracts. The schema captures the *structural* shape\n * and runtime validates \"is a function\" via `superRefine`; this overlay\n * gives consumers proper IDE autocomplete and removes the need for\n * `as never` casts inside the HTTP adapter.\n *\n * Zod's `z.function()` would type these as `(...args: unknown[]) => unknown`\n * which is too wide, and zod can't validate a function *contract* at runtime\n * anyway — only the existence of a function reference.\n */\ntype FunctionTypedBackendOverlay = {\n getAuthHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n requestTransform?: (req: HttpRequest) => HttpRequest | Promise<HttpRequest>;\n responseTransform?: (raw: unknown) => unknown | Promise<unknown>;\n};\n\nexport type BackendConfig = Omit<\n RawBackendConfig,\n 'getAuthHeaders' | 'requestTransform' | 'responseTransform'\n> &\n FunctionTypedBackendOverlay;\n\nexport type BackendConfigInput = Omit<\n RawBackendConfigInput,\n 'getAuthHeaders' | 'requestTransform' | 'responseTransform'\n> &\n FunctionTypedBackendOverlay;\n\ntype RawIAPConfig = z.infer<typeof iapConfigSchema>;\ntype RawIAPConfigInput = z.input<typeof iapConfigSchema>;\n\nexport type IAPConfig = Omit<RawIAPConfig, 'backend'> & { backend: BackendConfig };\nexport type IAPConfigInput = Omit<RawIAPConfigInput, 'backend'> & {\n backend: BackendConfigInput;\n};\nexport type StorageConfig = z.infer<typeof storageConfigSchema>;\nexport type OptionsConfig = z.infer<typeof optionsConfigSchema>;\n","import { z } from 'zod';\n\nexport const entitlementBaseSchema = z.object({\n key: z.string().min(1),\n productId: z.string().min(1),\n expiresAt: z.string().nullable(),\n});\n\n/**\n * Minimum shape every entitlement returned by the backend must satisfy.\n * Consumer-defined fields pass through unvalidated unless the consumer\n * supplies their own schema via `config.backend.entitlementSchema`.\n */\nexport type EntitlementBase = z.infer<typeof entitlementBaseSchema>;\n\n/** Default shape used when no `TEntitlement` type parameter is given. */\nexport type DefaultEntitlement = EntitlementBase;\n","import { z } from 'zod';\nimport { configuredProductsArraySchema } from '../../types/config.js';\nimport type { EntitlementBase } from '../../types/entitlement.js';\nimport { entitlementBaseSchema } from '../../types/entitlement.js';\nimport type { ConfiguredProduct, ProductType } from '../../types/product.js';\n\n// ----- Request types (constructed by the library; static TS types are sufficient) -----\n\nexport interface VerifyAppleRequest {\n productId: string;\n /** Apple StoreKit transaction id (numeric string). */\n transactionId: string;\n type: ProductType;\n}\n\nexport interface VerifyGoogleRequest {\n productId: string;\n /** Google Play `purchaseToken`. */\n purchaseToken: string;\n /** Application package name (e.g. `com.example.app`). */\n packageName: string;\n type: ProductType;\n}\n\n/** A single entry in a restore batch. Discriminated by `platform`. */\nexport type RestoreRequestTransaction =\n | {\n platform: 'apple';\n productId: string;\n transactionId: string;\n }\n | {\n platform: 'google';\n productId: string;\n purchaseToken: string;\n packageName: string;\n };\n\nexport interface RestoreRequest {\n transactions: RestoreRequestTransaction[];\n}\n\n// ----- Response schemas (validated; consumer fields ride along via .passthrough()) -----\n\n/**\n * Validates the EntitlementBase shape but lets consumer-defined fields pass\n * through unstripped. The HttpBackendAdapter casts results to TEntitlement\n * at the public boundary — same pattern as EntitlementCache.\n */\nconst passthroughEntitlementSchema = entitlementBaseSchema.passthrough();\n\nconst verifiedTransactionSchema = z\n .object({\n id: z.string(),\n productId: z.string(),\n /** ISO 8601 timestamp; null for non-expiring transactions. */\n expiresAt: z.string().nullable().optional(),\n })\n .passthrough();\n\nconst verifySuccessSchema = z\n .object({\n valid: z.literal(true),\n entitlements: z.array(passthroughEntitlementSchema),\n transaction: verifiedTransactionSchema,\n })\n .passthrough();\n\nconst verifyFailureSchema = z\n .object({\n valid: z.literal(false),\n /** Stable machine-readable code, e.g. \"TRANSACTION_NOT_FOUND\". */\n error: z.string(),\n /** Optional human-readable detail. */\n message: z.string().optional(),\n })\n .passthrough();\n\nexport const verifyResponseSchema = z.discriminatedUnion('valid', [\n verifySuccessSchema,\n verifyFailureSchema,\n]);\n\nconst restoreSuccessSchema = z\n .object({\n valid: z.literal(true),\n entitlements: z.array(passthroughEntitlementSchema),\n })\n .passthrough();\n\nexport const restoreResponseSchema = z.discriminatedUnion('valid', [\n restoreSuccessSchema,\n verifyFailureSchema,\n]);\n\nexport const entitlementsResponseSchema = z\n .object({ entitlements: z.array(passthroughEntitlementSchema) })\n .passthrough();\n\n/**\n * Backend product-manifest response. Mirrors the entitlements envelope\n * shape (`{ entitlements: [...] }`) for API consistency. The inner array\n * is validated against the same `configuredProductSchema` used at config\n * parse time, so a backend that drifts from the schema fails loudly.\n */\nexport const productManifestResponseSchema = z\n .object({ products: configuredProductsArraySchema })\n .passthrough();\n\n// ----- Public response types (plain TS; runtime schemas above passthrough extras at parse time) -----\n//\n// Defined as plain TS interfaces rather than `z.infer<...>` because Zod's\n// `.passthrough()` adds `[k: string]: unknown` to the inferred type, which\n// TS treats as overriding named property types — so consumer code reading\n// `result.entitlements` would receive `unknown`. The runtime schemas above\n// still passthrough at parse time, so backend-defined extras ARE preserved\n// on the resolved object — consumers who want them just cast.\n//\n// The transaction echo's shape is inlined (rather than referencing the\n// separate `VerifiedTransaction` in `src/types/transaction.ts`) because the\n// purchase orchestrator does its own `as VerifiedTransaction` cast when\n// surfacing the value in `PurchaseResult` — the public type there is the\n// canonical one.\n\n/** Public response type for `verifyApple` / `verifyGoogle`, generic over the consumer's entitlement shape. */\nexport type VerifyResponse<TEntitlement extends EntitlementBase = EntitlementBase> =\n | {\n valid: true;\n entitlements: TEntitlement[];\n transaction: { id: string; productId: string; expiresAt?: string | null };\n }\n | { valid: false; error: string; message?: string };\n\n/**\n * Restore response. Distinct from {@link VerifyResponse} because the\n * orchestrator never reads `transaction` on the restore path — the schema\n * accordingly omits any required transaction echo. Backends that include\n * a `transaction` (or any other field) on the success branch ride through\n * unmodified via top-level passthrough; consumers cast to read them.\n */\nexport type RestoreResponse<TEntitlement extends EntitlementBase = EntitlementBase> =\n | { valid: true; entitlements: TEntitlement[] }\n | { valid: false; error: string; message?: string };\n\n// ----- BackendAdapter interface (transport-agnostic) -----\n\n/**\n * Abstracts the consumer's backend so the orchestrator (Phase 4+) doesn't\n * depend on `fetch`. The default `HttpBackendAdapter` is HTTP/JSON via\n * `fetch`; consumers on GraphQL, gRPC-web, Supabase, Firebase, etc. supply\n * their own implementation via `config.backend.adapter`.\n *\n * All methods MUST validate response shape. Failures should throw IAPError\n * (HTTP impl uses BACKEND_UNAVAILABLE / BACKEND_TIMEOUT / BACKEND_AUTH_FAILED\n * / VERIFICATION_REJECTED depending on cause) — the orchestrator relies on\n * `IAPError.recoverable` to decide whether to surface a transient error or\n * abort the purchase flow.\n */\nexport interface BackendAdapter<TEntitlement extends EntitlementBase = EntitlementBase> {\n verifyApple(req: VerifyAppleRequest): Promise<VerifyResponse<TEntitlement>>;\n verifyGoogle(req: VerifyGoogleRequest): Promise<VerifyResponse<TEntitlement>>;\n /** GET current entitlements; library uses this for refresh + warm cache. */\n getEntitlements(): Promise<TEntitlement[]>;\n /**\n * Batch re-verify. Backend returns consolidated entitlements.\n *\n * Returns {@link RestoreResponse} (not {@link VerifyResponse}) — the orchestrator\n * does not consume any per-transaction echo on restore, so the response\n * shape intentionally omits the required `transaction` field that verify\n * has. Backends may still attach a `transaction` (or any other extras)\n * — they ride through via the schema's top-level passthrough.\n */\n restore(req: RestoreRequest): Promise<RestoreResponse<TEntitlement>>;\n /**\n * Optional: return the SKU manifest the app should register.\n *\n * When implemented, the library calls this during `initialize()` if the\n * consumer omitted `products` from `createIAP()` config — letting the\n * backend curate which SKUs are surfaced (feature flags, A/B mixes,\n * regional catalogs). Returned ids MUST still be pre-registered in App\n * Store Connect / Google Play Console; the manifest is a curated subset,\n * not a registration.\n */\n listProducts?(): Promise<ConfiguredProduct[]>;\n}\n\n/** Type guard; consumers passing a custom adapter via config get a runtime check. */\nexport function isBackendAdapter(value: unknown): value is BackendAdapter {\n if (!value || typeof value !== 'object') return false;\n const candidate = value as Partial<BackendAdapter>;\n return (\n typeof candidate.verifyApple === 'function' &&\n typeof candidate.verifyGoogle === 'function' &&\n typeof candidate.getEntitlements === 'function' &&\n typeof candidate.restore === 'function'\n );\n}\n","import { getPlatform } from '../../lib/platform.js';\nimport type { NativeAdapter } from './types.js';\nimport { WebStubAdapter } from './web/web-stub.js';\n\n/**\n * Select the appropriate native adapter for the runtime platform.\n *\n * - iOS / Android → capgo adapter wrapping `@capgo/native-purchases` (^8.0.0,\n * the Capacitor 8 line), reached via dynamic import so the adapter's *code*\n * doesn't run on web.\n * - web → no-op stub (purchases reject with PLATFORM_NOT_SUPPORTED).\n *\n * The deferral is execution-only, not module-graph: `tsup` builds with\n * `splitting: false`, so esbuild inlines this dynamic import into the single\n * chunk and hoists `@capgo/native-purchases` to a static top-level import in\n * both `dist/index.js` and `dist/index.cjs`. The plugin's `registerPlugin`\n * side effect therefore still fires at import time, including on web. Enabling\n * `splitting` for the ESM build would emit a separate chunk and make the\n * deferral real; until then, don't rely on this to keep the plugin out of a web\n * bundle. (`@capacitor/app`, imported dynamically in `app-resume-listener.ts`,\n * *is* genuinely deferred — it isn't reachable from this static graph.)\n *\n * Async because the capgo module is loaded lazily; web returns synchronously\n * but is still wrapped in a Promise for a uniform call signature.\n */\nexport async function selectNativeAdapter(): Promise<NativeAdapter> {\n const platform = getPlatform();\n if (platform === 'ios' || platform === 'android') {\n const mod = await import('./capgo/native-adapter.js');\n return new mod.CapgoNativeAdapter();\n }\n return new WebStubAdapter();\n}\n\nexport type { NativeAdapter, NativePurchaseOptions } from './types.js';\n","import { IAPError, IAPErrorCode } from '../../../lib/errors.js';\nimport type { Product, ProductType } from '../../../types/product.js';\nimport type { Storefront } from '../../../types/storefront.js';\nimport type { NativeTransaction } from '../../../types/transaction.js';\nimport type { NativeAdapter, NativePurchaseOptions } from '../types.js';\n\nexport class WebStubAdapter implements NativeAdapter {\n async isAvailable(): Promise<boolean> {\n return false;\n }\n\n async getProducts(_requests: Array<{ id: string; type: ProductType }>): Promise<Product[]> {\n return [];\n }\n\n async purchaseProduct(_opts: NativePurchaseOptions): Promise<NativeTransaction> {\n throw new IAPError({\n code: IAPErrorCode.PLATFORM_NOT_SUPPORTED,\n message: 'In-app purchases are not supported on the web platform.',\n });\n }\n\n async getOwnedTransactions(): Promise<NativeTransaction[]> {\n return [];\n }\n\n async acknowledge(_transaction: NativeTransaction): Promise<void> {\n // No-op on web.\n }\n\n async manageSubscriptions(): Promise<void> {\n throw new IAPError({\n code: IAPErrorCode.PLATFORM_NOT_SUPPORTED,\n message: 'Subscription management is not supported on the web platform.',\n });\n }\n\n async getStorefront(): Promise<Storefront | null> {\n // No App Store / Play storefront on web — entitlement queries still work.\n return null;\n }\n}\n","import { IAPError, IAPErrorCode } from '../../lib/errors.js';\nimport type { StorageConfig } from '../../types/config.js';\nimport { MemoryAdapter } from './memory-adapter.js';\nimport { PreferencesAdapter } from './preferences-adapter.js';\nimport type { StorageAdapter } from './types.js';\n\n/**\n * Build the storage adapter for the configured `storage.type`.\n *\n * - `'preferences'` → Capacitor Preferences (native + localStorage on web)\n * - `'memory'` → in-memory map (tests, ephemeral environments)\n * - `'custom'` → user-supplied adapter via `storage.adapter`\n */\nexport function selectStorageAdapter(config: StorageConfig): StorageAdapter {\n if (config.type === 'memory') {\n return new MemoryAdapter(config.namespace);\n }\n if (config.type === 'custom') {\n if (!isStorageAdapter(config.adapter)) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'storage.type is \"custom\" but storage.adapter is missing or does not implement StorageAdapter.',\n });\n }\n return config.adapter;\n }\n return new PreferencesAdapter(config.namespace);\n}\n\nfunction isStorageAdapter(value: unknown): value is StorageAdapter {\n if (!value || typeof value !== 'object') return false;\n const candidate = value as Partial<StorageAdapter>;\n return (\n typeof candidate.get === 'function' &&\n typeof candidate.set === 'function' &&\n typeof candidate.remove === 'function' &&\n typeof candidate.clear === 'function'\n );\n}\n\nexport type { StorageAdapter } from './types.js';\n","import type { StorageAdapter } from './types.js';\n\n/**\n * In-memory storage adapter. Used as the default for tests and on web\n * dev environments where Capacitor Preferences is unnecessary.\n *\n * Each instance owns its own Map — no global state. Namespace prefix is\n * prepended to keys so multiple instances against shared backing storage\n * (e.g., on the same device when used as a fallback) don't collide.\n */\nexport class MemoryAdapter implements StorageAdapter {\n private readonly store = new Map<string, string>();\n private readonly prefix: string;\n\n constructor(namespace: string) {\n this.prefix = `${namespace}.`;\n }\n\n async get(key: string): Promise<string | null> {\n return this.store.get(this.prefix + key) ?? null;\n }\n\n async set(key: string, value: string): Promise<void> {\n this.store.set(this.prefix + key, value);\n }\n\n async remove(key: string): Promise<void> {\n this.store.delete(this.prefix + key);\n }\n\n async clear(): Promise<void> {\n for (const key of [...this.store.keys()]) {\n if (key.startsWith(this.prefix)) this.store.delete(key);\n }\n }\n}\n","import { Preferences } from '@capacitor/preferences';\nimport { IAPError, IAPErrorCode } from '../../lib/errors.js';\nimport type { StorageAdapter } from './types.js';\n\n/**\n * Storage adapter backed by `@capacitor/preferences`.\n *\n * On iOS/Android, Preferences uses native key-value stores\n * (NSUserDefaults / SharedPreferences). On web it transparently falls\n * back to `localStorage`, which means cached entitlements and\n * unfinished transactions survive page reloads in browser dev too.\n *\n * Keys are prefixed with `${namespace}.` to avoid collisions with other\n * Preferences consumers in the same app.\n */\nexport class PreferencesAdapter implements StorageAdapter {\n private readonly prefix: string;\n private readonly knownKeys = new Set<string>();\n\n constructor(namespace: string) {\n this.prefix = `${namespace}.`;\n }\n\n async get(key: string): Promise<string | null> {\n try {\n const result = await Preferences.get({ key: this.prefix + key });\n return result.value;\n } catch (cause) {\n throw wrap(cause, `Preferences.get failed for \"${key}\".`);\n }\n }\n\n async set(key: string, value: string): Promise<void> {\n try {\n await Preferences.set({ key: this.prefix + key, value });\n this.knownKeys.add(key);\n } catch (cause) {\n throw wrap(cause, `Preferences.set failed for \"${key}\".`);\n }\n }\n\n async remove(key: string): Promise<void> {\n try {\n await Preferences.remove({ key: this.prefix + key });\n this.knownKeys.delete(key);\n } catch (cause) {\n throw wrap(cause, `Preferences.remove failed for \"${key}\".`);\n }\n }\n\n async clear(): Promise<void> {\n // We can't ask Preferences to clear-by-prefix, so we remove the keys\n // we know about. Phase 2/3/4/6 each only touch a small fixed set.\n const keys = [...this.knownKeys];\n this.knownKeys.clear();\n await Promise.all(keys.map((k) => Preferences.remove({ key: this.prefix + k })));\n }\n}\n\nfunction wrap(cause: unknown, message: string): IAPError {\n return new IAPError({\n code: IAPErrorCode.STORAGE_ERROR,\n message,\n cause,\n recoverable: true,\n });\n}\n","import type { Logger } from '../lib/logger.js';\n\nexport interface AppResumeListenerOptions {\n logger: Logger;\n /** Called whenever the app becomes active. Return value is awaited but\n * never propagated — failures are logged via `logger.warn`. */\n onResume: () => void | Promise<void>;\n}\n\nexport interface AppResumeListenerHandle {\n remove(): Promise<void>;\n}\n\n/**\n * Attach an `App.addListener('appStateChange')` listener via `@capacitor/app`\n * so the library can refresh entitlements when the app returns from\n * background. `@capacitor/app` is an OPTIONAL peer dep — when consumers\n * disable `options.refreshOnResume`, they don't have to install it.\n *\n * Returns `null` when `@capacitor/app` is unavailable or the runtime\n * cannot register the listener (e.g. web). Call sites should treat null\n * as \"no listener attached\" and continue.\n */\nexport async function attachAppResumeListener(\n opts: AppResumeListenerOptions,\n): Promise<AppResumeListenerHandle | null> {\n let mod: typeof import('@capacitor/app');\n try {\n mod = await import('@capacitor/app');\n } catch (error) {\n opts.logger.warn(\n 'refreshOnResume requested but @capacitor/app is not installed; resume listener disabled.',\n error,\n );\n return null;\n }\n\n let handle: { remove(): Promise<void> };\n try {\n handle = await mod.App.addListener('appStateChange', ({ isActive }) => {\n if (!isActive) return;\n void Promise.resolve(opts.onResume()).catch((error) => {\n opts.logger.warn('refreshOnResume handler threw.', error);\n });\n });\n } catch (error) {\n opts.logger.warn(\n 'Failed to attach App appStateChange listener; resume refresh disabled.',\n error,\n );\n return null;\n }\n\n return {\n async remove() {\n try {\n await handle.remove();\n } catch (error) {\n opts.logger.warn('Failed to remove App appStateChange listener.', error);\n }\n },\n };\n}\n","import type { StorageAdapter } from '../adapters/storage/types.js';\nimport { IAPError, IAPErrorCode } from '../lib/errors.js';\nimport type { Logger } from '../lib/logger.js';\nimport { entitlementBaseSchema } from '../types/entitlement.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\n\nconst ENTITLEMENTS_KEY = 'entitlements';\n\ninterface CacheEnvelope<T> {\n entitlements: T[];\n cachedAt: number;\n}\n\nexport interface CacheLoadResult<T extends EntitlementBase> {\n entitlements: T[];\n cachedAt: number;\n}\n\n/**\n * Persists the consumer's entitlements list to a {@link StorageAdapter}\n * with a cachedAt timestamp so refresh logic (Phase 6) can reason\n * about staleness.\n *\n * Generic over `TEntitlement` so consumer-defined fields pass through.\n * Validates only the {@link EntitlementBase} subset on read; if the\n * stored payload is structurally wrong we drop the cache rather than\n * crash, since stale or corrupt cache should never block the app.\n */\nexport class EntitlementCache<TEntitlement extends EntitlementBase> {\n constructor(\n private readonly storage: StorageAdapter,\n private readonly logger: Logger,\n ) {}\n\n async load(): Promise<CacheLoadResult<TEntitlement> | null> {\n let raw: string | null;\n try {\n raw = await this.storage.get(ENTITLEMENTS_KEY);\n } catch (cause) {\n this.logger.warn('Storage read failed; treating cache as empty.', cause);\n return null;\n }\n if (!raw) return null;\n\n let parsed: CacheEnvelope<unknown>;\n try {\n parsed = JSON.parse(raw) as CacheEnvelope<unknown>;\n } catch (cause) {\n this.logger.warn('Cached entitlements payload is not valid JSON; clearing.', cause);\n await this.safeRemove();\n return null;\n }\n\n if (\n !parsed ||\n typeof parsed !== 'object' ||\n typeof parsed.cachedAt !== 'number' ||\n !Array.isArray(parsed.entitlements)\n ) {\n this.logger.warn('Cached entitlements envelope has unexpected shape; clearing.');\n await this.safeRemove();\n return null;\n }\n\n const validated: TEntitlement[] = [];\n for (const item of parsed.entitlements) {\n const result = entitlementBaseSchema.safeParse(item);\n if (!result.success) {\n this.logger.warn('Dropping cached entitlement that fails base validation.', result.error);\n continue;\n }\n validated.push(item as TEntitlement);\n }\n\n return { entitlements: validated, cachedAt: parsed.cachedAt };\n }\n\n /** Returns the `cachedAt` timestamp written so callers can keep their\n * in-memory copy of the timestamp in sync with disk. */\n async save(entitlements: TEntitlement[]): Promise<number> {\n const cachedAt = Date.now();\n const envelope: CacheEnvelope<TEntitlement> = {\n entitlements,\n cachedAt,\n };\n try {\n await this.storage.set(ENTITLEMENTS_KEY, JSON.stringify(envelope));\n } catch (cause) {\n throw new IAPError({\n code: IAPErrorCode.STORAGE_ERROR,\n message: 'Failed to persist entitlement cache.',\n cause,\n recoverable: true,\n });\n }\n return cachedAt;\n }\n\n async clear(): Promise<void> {\n await this.safeRemove();\n }\n\n private async safeRemove(): Promise<void> {\n try {\n await this.storage.remove(ENTITLEMENTS_KEY);\n } catch (cause) {\n this.logger.warn('Failed to remove corrupt entitlement cache.', cause);\n }\n }\n}\n\n/**\n * Shallow-equal comparator on the {@link EntitlementBase} fields.\n * Used by the orchestrators to skip emitting `entitlements-changed` when\n * a refresh / recovery / restore returns content-identical lists — avoids\n * spurious re-renders in reactive consumer stores.\n *\n * \"Content-identical\" means: same length, same `(key, productId, expiresAt)`\n * triples in the same order. Consumer-defined fields are NOT compared\n * because the library doesn't know their shape — if you need finer-grained\n * change detection, subscribe and run your own equality check on payload.\n */\nexport function entitlementsEqual(a: EntitlementBase[], b: EntitlementBase[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const x = a[i];\n const y = b[i];\n if (!x || !y) return false;\n if (x.key !== y.key || x.productId !== y.productId || x.expiresAt !== y.expiresAt) {\n return false;\n }\n }\n return true;\n}\n","import type { BackendAdapter, VerifyResponse } from '../adapters/backend/types.js';\nimport type { NativeAdapter } from '../adapters/native/types.js';\nimport type { TypedEventEmitter } from '../events/emitter.js';\nimport { IAPError, IAPErrorCode, toIAPError } from '../lib/errors.js';\nimport type { Logger } from '../lib/logger.js';\nimport { isValidUuidV4 } from '../lib/uuid.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport type { ConfiguredProduct } from '../types/product.js';\nimport type {\n AppUserId,\n AppUserIdFetcherContext,\n PurchaseOptions,\n PurchaseResult,\n} from '../types/results.js';\nimport type { NativeTransaction, VerifiedTransaction } from '../types/transaction.js';\nimport type { EntitlementCache } from './entitlement-cache.js';\nimport type { UnfinishedTransactionsStore } from './unfinished-transactions.js';\nimport { verifyNativeTransaction } from './verify-helpers.js';\n\ninterface PurchaseOrchestratorDeps<TEntitlement extends EntitlementBase> {\n /** Native adapter (capgo on iOS/Android, web stub on web). Always non-null\n * by the time the orchestrator is invoked — initialize() ensures it. */\n nativeAdapter: NativeAdapter;\n backend: BackendAdapter<TEntitlement>;\n cache: EntitlementCache<TEntitlement>;\n unfinished: UnfinishedTransactionsStore;\n emitter: TypedEventEmitter<TEntitlement>;\n logger: Logger;\n /** Resolved product catalog from config. Used to look up productType. */\n products: ConfiguredProduct[];\n /**\n * Returns the current entitlements list. Read fresh from state each call so\n * concurrent refreshes are reflected in the `previous` payload of\n * entitlements-changed events.\n */\n getCurrentEntitlements: () => TEntitlement[];\n /**\n * Replace the current entitlements list. Implementation must freeze entries\n * (createIAP's `freezeAll`).\n */\n setEntitlements: (next: TEntitlement[]) => void;\n /**\n * Mark the persisted cache as written at the given timestamp. Keeps the\n * in-memory `cachedAt` in sync with disk so Phase 6 TTL evaluation doesn't\n * see a spurious \"stale\" reading after a purchase.\n */\n setCachePersisted: (cachedAt: number) => void;\n /**\n * Resolves the auth headers the library uses for backend requests.\n * Forwarded to function-form `appUserId` fetchers as `ctx.authHeaders`\n * so consumers whose UUID-minting endpoint shares auth with their IAP\n * backend can reuse it without redefining a helper. For consumers\n * using a custom `BackendAdapter` (no `getAuthHeaders` configured),\n * this returns `{}`. Awaited fresh per purchase so token refresh\n * keeps working.\n */\n getAuthHeaders: () => Promise<Record<string, string>>;\n}\n\n/**\n * Coordinates the purchase flow across the native, backend, storage, and\n * eventing layers. The implementation is the literal expression of\n * PLAN.md §5.4 — read that section alongside this code.\n *\n * Safety guarantees:\n * 1. **At-least-once delivery to backend** — write to `unfinished` BEFORE\n * calling `backend.verifyApple/Google()`. App death between these two\n * points is recovered on next launch via `unfinished.list()`.\n * 2. **Never `acknowledge()` before backend confirms** — `nativeAdapter.acknowledge()`\n * is only called after `backend.verifyApple/Google()` returns `valid: true`.\n * On any failure path the transaction is left in the `unfinished` store (or\n * still owned at the store level) so it's retried on the next launch via\n * the recovery flow.\n * 3. **Per-product lock** — concurrent `purchase('premium_monthly')` calls are\n * rejected: the `inFlight` set throws `ALREADY_IN_PROGRESS` on the second.\n *\n * The 5 result statuses (PLAN.md §5.4):\n * - `success` — backend returned `valid: true`; entitlements + cache updated.\n * - `cancelled` — user cancelled the native sheet (USER_CANCELLED).\n * - `pending` — Android-only; payment pending platform-side. Not yet acked.\n * - `verification_failed` — backend returned `valid: false`. Persisted to\n * `unfinished` for retry on next refresh.\n * - `failed` — native or transport error. May or may not be persisted depending\n * on whether a NativeTransaction was produced.\n */\nexport class PurchaseOrchestrator<TEntitlement extends EntitlementBase = EntitlementBase> {\n private readonly inFlight = new Set<string>();\n\n constructor(private readonly deps: PurchaseOrchestratorDeps<TEntitlement>) {}\n\n async purchase(opts: PurchaseOptions): Promise<PurchaseResult<TEntitlement>> {\n const { productId, appUserId } = opts;\n if (this.inFlight.has(productId)) {\n throw new IAPError({\n code: IAPErrorCode.ALREADY_IN_PROGRESS,\n message: `A purchase of \"${productId}\" is already in progress.`,\n });\n }\n const product = this.deps.products.find((p) => p.id === productId);\n if (!product) {\n throw new IAPError({\n code: IAPErrorCode.PRODUCT_NOT_FOUND,\n message: `Product \"${productId}\" is not in the configured catalog.`,\n });\n }\n\n // Resolve and validate appUserId BEFORE marking inFlight or emitting\n // purchase-started — these throws are pre-flight (caller bug or\n // backend-fetcher failure), not purchase outcomes. They surface\n // synchronously to the awaiter without polluting the event stream.\n //\n // For function-form fetchers, eagerly resolve `getAuthHeaders()` so\n // we can pass it via ctx. String-form supplies skip the await. The\n // ctx is always populated (with `{}` when no headers are wired) so\n // fetchers that destructure `({ authHeaders })` never see undefined.\n let resolvedAppUserId: string | undefined;\n if (appUserId !== undefined) {\n const ctx: AppUserIdFetcherContext =\n typeof appUserId === 'function'\n ? { authHeaders: await this.deps.getAuthHeaders() }\n : { authHeaders: {} };\n resolvedAppUserId = await resolveAppUserId(appUserId, ctx);\n }\n\n this.inFlight.add(productId);\n this.deps.emitter.emit('purchase-started', { productId });\n\n try {\n return await this.runFlow(product, resolvedAppUserId);\n } finally {\n this.inFlight.delete(productId);\n }\n }\n\n private async runFlow(\n product: ConfiguredProduct,\n appUserId: string | undefined,\n ): Promise<PurchaseResult<TEntitlement>> {\n const { nativeAdapter, logger } = this.deps;\n let nativeTx: NativeTransaction;\n\n // ----- 1. Native purchase -----\n try {\n nativeTx = await nativeAdapter.purchaseProduct({\n productId: product.id,\n productType: product.type,\n ...(product.androidPlanId ? { androidPlanId: product.androidPlanId } : {}),\n ...(appUserId ? { appAccountToken: appUserId } : {}),\n });\n } catch (error) {\n return this.handleNativeError(product.id, error);\n }\n\n // ----- 2. Persist BEFORE verifying — at-least-once invariant -----\n try {\n await this.deps.unfinished.add(nativeTx);\n } catch (error) {\n logger.warn(\n `Failed to persist unfinished entry for \"${product.id}\"; verification will still proceed.`,\n error,\n );\n }\n\n // ----- 3. Backend verification -----\n let verifyResult: VerifyResponse<TEntitlement>;\n try {\n verifyResult = await verifyNativeTransaction(this.deps.backend, nativeTx);\n } catch (error) {\n return this.handleVerifyError(product.id, error);\n }\n\n // ----- 4. Branch on backend response -----\n if (!verifyResult.valid) {\n return this.handleVerificationRejected(product.id, verifyResult);\n }\n\n // ----- 5. Backend says valid: ack natively + update cache + emit -----\n return this.finalizeSuccess(product.id, nativeTx, verifyResult);\n }\n\n private async finalizeSuccess(\n productId: string,\n nativeTx: NativeTransaction,\n response: Extract<VerifyResponse<TEntitlement>, { valid: true }>,\n ): Promise<PurchaseResult<TEntitlement>> {\n const { nativeAdapter, cache, unfinished, emitter, logger } = this.deps;\n const transaction = response.transaction as VerifiedTransaction;\n const entitlements = response.entitlements;\n\n // Acknowledge the native transaction. Failure here is recoverable —\n // entitlement state on the backend says we're good, and the store still\n // reports the purchase as owned/unfinished, so a later restore()/refresh()\n // re-acks it (on Android, before the 3-day auto-refund window closes).\n try {\n await nativeAdapter.acknowledge(nativeTx);\n } catch (error) {\n logger.warn(`acknowledge() failed for \"${productId}\"; entitlements still updated.`, error);\n }\n\n // Persist entitlements (best-effort) and clear the unfinished entry.\n const previous = this.deps.getCurrentEntitlements();\n try {\n const cachedAt = await cache.save(entitlements);\n this.deps.setCachePersisted(cachedAt);\n } catch (error) {\n logger.warn(\n `Failed to persist entitlements after purchase of \"${productId}\"; in-memory state still updated.`,\n error,\n );\n }\n this.deps.setEntitlements(entitlements);\n\n try {\n await unfinished.remove(nativeTx.token);\n } catch (error) {\n logger.warn(\n `Failed to remove \"${productId}\" from unfinished list; will be skipped on next recovery.`,\n error,\n );\n }\n\n emitter.emit('purchase-success', { productId, transaction });\n emitter.emit('entitlements-changed', {\n entitlements: this.deps.getCurrentEntitlements(),\n previous,\n });\n\n return {\n status: 'success',\n productId,\n transaction,\n entitlements: this.deps.getCurrentEntitlements(),\n };\n }\n\n private handleVerificationRejected(\n productId: string,\n response: Extract<VerifyResponse<TEntitlement>, { valid: false }>,\n ): PurchaseResult<TEntitlement> {\n // Compose both the human-readable message and the stable machine code\n // so consumers can grep for either. PLAN.md §5.8 marks `error` as the\n // stable identifier — preserve it even when message is present.\n const detail = response.message\n ? `${response.message} [${response.error}]`\n : `Backend rejected the transaction (${response.error}).`;\n const error = new IAPError({\n code: IAPErrorCode.VERIFICATION_REJECTED,\n message: detail,\n });\n this.deps.emitter.emit('verification-failed', { productId, error });\n return { status: 'verification_failed', productId, error };\n }\n\n private handleNativeError(productId: string, error: unknown): PurchaseResult<TEntitlement> {\n const iapError = toIAPError(\n error,\n `Native purchase of \"${productId}\" failed.`,\n IAPErrorCode.STORE_ERROR,\n );\n\n if (iapError.code === IAPErrorCode.USER_CANCELLED) {\n this.deps.emitter.emit('purchase-cancelled', { productId });\n return { status: 'cancelled', productId };\n }\n\n if (iapError.code === IAPErrorCode.PURCHASE_PENDING) {\n this.deps.emitter.emit('purchase-pending', { productId });\n return { status: 'pending', productId };\n }\n\n this.deps.emitter.emit('purchase-failed', { productId, error: iapError });\n return { status: 'failed', productId, error: iapError };\n }\n\n private handleVerifyError(productId: string, error: unknown): PurchaseResult<TEntitlement> {\n const iapError = toIAPError(\n error,\n `Backend verification of \"${productId}\" failed.`,\n IAPErrorCode.BACKEND_UNAVAILABLE,\n );\n // Transport / auth errors leave the unfinished entry in place for retry.\n // We surface verification_failed so the consumer UI shows a \"we'll retry\"\n // message; a hard `failed` would suggest the user should restart the flow.\n this.deps.emitter.emit('verification-failed', { productId, error: iapError });\n return { status: 'verification_failed', productId, error: iapError };\n }\n}\n\n/**\n * Resolve an `appUserId` supply to a validated UUID v4 string.\n *\n * - String input: validate directly.\n * - Async fetcher: invoke once (fresh per purchase — iap caches nothing,\n * the backend owns mint-or-lookup idempotency), then validate the\n * resolved value. Wraps fetcher rejections in\n * `IAPError(APP_USER_ID_FETCH_FAILED, cause)` so callers can\n * distinguish \"fetcher exploded\" from \"fetcher returned junk\".\n *\n * Function-form fetchers always receive `ctx`. Zero-arg fetchers\n * (`async () => '...'`) ignore the extra argument at runtime — JS\n * standard behavior — so 0.2.x callers continue to work unchanged.\n *\n * Throws synchronously (or via Promise rejection) on invalid input;\n * never returns a non-UUID string.\n */\nasync function resolveAppUserId(supply: AppUserId, ctx: AppUserIdFetcherContext): Promise<string> {\n let resolved: string;\n if (typeof supply === 'function') {\n try {\n // Cast to the ctx-form signature so the call typechecks for both\n // shapes in the union; zero-arg fetchers ignore the extra arg.\n resolved = await (supply as (ctx: AppUserIdFetcherContext) => Promise<string>)(ctx);\n } catch (cause) {\n throw new IAPError({\n code: IAPErrorCode.APP_USER_ID_FETCH_FAILED,\n message: 'The async appUserId fetcher threw or rejected.',\n cause,\n });\n }\n } else {\n resolved = supply;\n }\n if (typeof resolved !== 'string' || !isValidUuidV4(resolved)) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_APP_USER_ID,\n message: `appUserId must be a UUID v4; received ${\n typeof resolved === 'string' ? `\"${resolved}\"` : typeof resolved\n }.`,\n });\n }\n return resolved;\n}\n","/**\n * RFC 4122 v4 UUID validator.\n *\n * Apple's `appAccountToken` field on a StoreKit purchase MUST be a UUID\n * (Apple validates server-side and rejects non-UUIDs). Google's\n * `obfuscatedAccountId` accepts any string up to 64 chars, but iap\n * enforces UUID v4 on both platforms to give consumers a single,\n * predictable contract.\n *\n * Strict v4: rejects v1/v3/v5 UUIDs (different version nibbles), nil UUID,\n * surrounding whitespace, and non-canonical lengths. The version nibble\n * (`4xxx`) and variant nibble (`[89ab]xxx`) match the RFC 4122 v4 spec.\n */\nconst UUID_V4_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\nexport function isValidUuidV4(value: string): boolean {\n return UUID_V4_REGEX.test(value);\n}\n","import type { BackendAdapter, VerifyResponse } from '../adapters/backend/types.js';\nimport { IAPError, IAPErrorCode } from '../lib/errors.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport type { NativeTransaction } from '../types/transaction.js';\n\n/**\n * Route a native transaction to the right per-platform verify endpoint.\n *\n * - Apple → `backend.verifyApple({ productId, transactionId, type })`\n * - Google → `backend.verifyGoogle({ productId, purchaseToken, packageName, type })`\n *\n * Throws `IAPError(STORE_ERROR)` if a Google transaction is missing a\n * `packageName` (the verify request body cannot be built without it).\n *\n * Used by the purchase orchestrator and the recovery orchestrator;\n * restore uses `backend.restore()` (batched, different shape).\n */\nexport async function verifyNativeTransaction<TEntitlement extends EntitlementBase>(\n backend: BackendAdapter<TEntitlement>,\n tx: NativeTransaction,\n): Promise<VerifyResponse<TEntitlement>> {\n if (tx.platform === 'apple') {\n return backend.verifyApple({\n productId: tx.productId,\n transactionId: tx.token,\n type: tx.productType,\n });\n }\n if (!tx.packageName) {\n throw new IAPError({\n code: IAPErrorCode.STORE_ERROR,\n message: `Google transaction for \"${tx.productId}\" has no packageName; cannot verify.`,\n });\n }\n return backend.verifyGoogle({\n productId: tx.productId,\n purchaseToken: tx.token,\n packageName: tx.packageName,\n type: tx.productType,\n });\n}\n","import type { BackendAdapter } from '../adapters/backend/types.js';\nimport type { NativeAdapter } from '../adapters/native/types.js';\nimport type { TypedEventEmitter } from '../events/emitter.js';\nimport type { Logger } from '../lib/logger.js';\nimport { maskToken } from '../lib/redact.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport type { NativeTransaction } from '../types/transaction.js';\nimport { type EntitlementCache, entitlementsEqual } from './entitlement-cache.js';\nimport type {\n UnfinishedTransaction,\n UnfinishedTransactionsStore,\n} from './unfinished-transactions.js';\nimport { verifyNativeTransaction } from './verify-helpers.js';\n\n/**\n * Backend `valid:false` error codes that are treated as permanent by default\n * (entry removed from `unfinished_transactions` instead of retried forever).\n *\n * Conservative on purpose: only the two codes the documented recipe\n * contract identifies as unambiguous \"domain-not-found\" answers. Consumers\n * with custom backend error vocabularies extend via\n * `options.permanentErrorCodes`.\n *\n * Distinct from the `RECOVERABLE_CODES` set in `lib/errors.ts`: that one\n * classifies iap-internal `IAPErrorCode`s for transport/storage retry\n * semantics; this one classifies opaque error strings the consumer's\n * backend returns in `valid:false` responses.\n */\nexport const DEFAULT_PERMANENT_ERROR_CODES: readonly string[] = [\n 'TRANSACTION_NOT_FOUND',\n 'PRODUCT_MISMATCH',\n] as const;\n\ninterface RecoveryOrchestratorDeps<TEntitlement extends EntitlementBase> {\n nativeAdapter: NativeAdapter;\n backend: BackendAdapter<TEntitlement>;\n cache: EntitlementCache<TEntitlement>;\n unfinished: UnfinishedTransactionsStore;\n emitter: TypedEventEmitter<TEntitlement>;\n logger: Logger;\n getCurrentEntitlements: () => TEntitlement[];\n setEntitlements: (next: TEntitlement[]) => void;\n setCachePersisted: (cachedAt: number) => void;\n /** Cap on entries inspected per launch (config.options.recoveryMaxBatch). */\n maxBatch: number;\n /**\n * Backend `valid:false` error codes treated as permanent. Entries with a\n * matching error are removed from storage instead of retried next launch.\n * Resolved from `config.options.permanentErrorCodes` (or the default set\n * when omitted) at orchestrator construction in `createIAP`.\n */\n permanentErrorCodes: ReadonlySet<string>;\n}\n\ninterface RecoveryResult {\n /** Number of entries that were verified, acknowledged, and removed. */\n recovered: number;\n /** Number of entries left in the list (transient errors, valid:false, etc.). */\n failures: number;\n /**\n * Number of entries removed from the list because the backend's\n * `valid:false` response carried a permanent error code (per\n * `options.permanentErrorCodes`). These will NOT retry on next launch.\n */\n droppedPermanent: number;\n /** Total entries inspected. */\n inspected: number;\n}\n\n/**\n * Re-attempts verification + acknowledgement for unfinished transactions\n * that survived from a prior session (app killed mid-purchase, network\n * outage during verify, etc.). Runs once per `initialize()` call before\n * `ready` fires.\n *\n * Best-effort by design — never throws. Each entry is processed\n * independently; one failure does not abort the rest. Entries that fail\n * stay in storage for the next launch's recovery.\n *\n * Per-entry sequence:\n * 1. `verifyNativeTransaction` — reuse the shared platform router.\n * 2. If `valid: false` → log debug, increment `failures`, leave in list.\n * 3. If `valid: true`:\n * a. `nativeAdapter.acknowledge()` — best-effort; ack failure means\n * we don't yet remove from the list (next launch will retry).\n * b. `unfinished.remove(token)` — clear the entry.\n * c. Stash the response's `entitlements` as the latest seen.\n * 4. Transport / verify throw → log warn, increment `failures`, leave.\n *\n * After processing all entries, if at least one succeeded, the latest\n * verified `entitlements` array is applied as the new state (cache.save +\n * setEntitlements + emit `entitlements-changed`). Multiple verifies for\n * the same user normally return the same consolidated list — last-wins\n * is the simplest correct strategy.\n */\nexport class RecoveryOrchestrator<TEntitlement extends EntitlementBase = EntitlementBase> {\n constructor(private readonly deps: RecoveryOrchestratorDeps<TEntitlement>) {}\n\n async recoverUnfinishedTransactions(): Promise<RecoveryResult> {\n const { unfinished, logger, maxBatch } = this.deps;\n const allEntries = await unfinished.list();\n if (allEntries.length === 0) {\n return { recovered: 0, failures: 0, droppedPermanent: 0, inspected: 0 };\n }\n\n // L2: cap inspected entries per launch. Excess entries stay in storage\n // and are processed on subsequent launches.\n const entries = allEntries.slice(0, maxBatch);\n if (allEntries.length > maxBatch) {\n logger.info(\n `Recovery: inspecting ${entries.length}/${allEntries.length} entries; remaining ${allEntries.length - entries.length} will be processed on subsequent launches.`,\n );\n } else {\n logger.debug(`Recovery: inspecting ${entries.length} unfinished transaction(s).`);\n }\n\n // L1: parallelize per-entry verify→ack→remove via Promise.allSettled.\n // Within an entry the steps are sequential (the orchestrator's safety\n // invariants rely on it); across entries they're independent.\n const settled = await Promise.allSettled(entries.map((entry) => this.processEntry(entry)));\n\n let recovered = 0;\n let failures = 0;\n let droppedPermanent = 0;\n let latestEntitlements: TEntitlement[] | null = null;\n\n // Iterate in input order so latestEntitlements is the LAST successful\n // entry's response (deterministic last-write-wins). NOTE: parallel\n // verifies for the same user are expected to return the same consolidated\n // list — replicas that drift mid-rollout could yield different lists; in\n // that case the input-order tiebreak is arbitrary but stable. If your\n // backend cannot guarantee read-after-write across replicas, prefer a\n // single iap.refresh() over multi-entry recovery.\n for (const result of settled) {\n if (result.status === 'rejected') {\n // processEntry catches its own throws; this branch only fires on a\n // truly unexpected runtime error (e.g. logger threw). Count as failure.\n failures += 1;\n continue;\n }\n if (result.value.kind === 'recovered') {\n recovered += 1;\n latestEntitlements = result.value.entitlements;\n } else if (result.value.kind === 'dropped-permanent') {\n droppedPermanent += 1;\n } else {\n failures += 1;\n }\n }\n\n if (latestEntitlements !== null) {\n await this.applyEntitlements(latestEntitlements);\n }\n\n logger.debug(\n `Recovery: ${recovered} recovered, ${droppedPermanent} dropped (permanent), ${failures} left in list (will retry next launch).`,\n );\n\n return { recovered, failures, droppedPermanent, inspected: entries.length };\n }\n\n private async processEntry(\n entry: UnfinishedTransaction,\n ): Promise<\n | { kind: 'recovered'; entitlements: TEntitlement[] }\n | { kind: 'failed' }\n | { kind: 'dropped-permanent' }\n > {\n const { nativeAdapter, unfinished, logger, emitter, permanentErrorCodes } = this.deps;\n const tx = entryToNativeTransaction(entry);\n const tokenLabel = maskToken(entry.token);\n\n try {\n const response = await verifyNativeTransaction(this.deps.backend, tx);\n\n if (!response.valid) {\n if (permanentErrorCodes.has(response.error)) {\n logger.info(\n `Recovery: dropping permanently-invalid token=${tokenLabel} productId=${entry.productId} (${response.error}).`,\n );\n\n // Best-effort native ack — clears StoreKit's queue. Failure here\n // doesn't block removal: the entry is permanently invalid, native\n // ack failure is rare and transient, and even an orphaned native\n // tx won't re-enter unfinished storage (no init-time sync exists,\n // only `purchase-flow.ts` writes to this store).\n try {\n await nativeAdapter.acknowledge(tx);\n } catch (error) {\n logger.warn(\n `Recovery: best-effort acknowledge() failed for productId=${entry.productId}; proceeding with removal anyway.`,\n error,\n );\n }\n\n try {\n await unfinished.remove(entry.token);\n } catch (error) {\n logger.warn(\n `Recovery: unfinished.remove() failed for productId=${entry.productId} after permanent classification; will dedupe on next launch.`,\n error,\n );\n }\n\n emitter.emit('recovery-dropped-permanent', {\n productId: entry.productId,\n token: entry.token,\n error: response.error,\n ...(response.message !== undefined ? { message: response.message } : {}),\n });\n\n return { kind: 'dropped-permanent' };\n }\n\n logger.debug(\n `Recovery: backend rejected token=${tokenLabel} productId=${entry.productId} (${response.error}); leaving in list for retry.`,\n );\n return { kind: 'failed' };\n }\n\n // Ack natively. Failure means we don't yet remove — next launch retries.\n try {\n await nativeAdapter.acknowledge(tx);\n } catch (error) {\n logger.warn(\n `Recovery: acknowledge() failed for productId=${entry.productId}; entry retained for next launch.`,\n error,\n );\n return { kind: 'failed' };\n }\n\n // Remove from unfinished. A failure here is logged but treated as\n // success for entitlement purposes — the cache write below still\n // happens, and the next recovery's idempotent verify will be a\n // no-op (token already verified by backend).\n try {\n await unfinished.remove(entry.token);\n } catch (error) {\n logger.warn(\n `Recovery: unfinished.remove() failed for productId=${entry.productId}; will dedupe on next launch.`,\n error,\n );\n }\n\n return { kind: 'recovered', entitlements: response.entitlements };\n } catch (error) {\n logger.warn(\n `Recovery: verify failed for productId=${entry.productId}; will retry next launch.`,\n error,\n );\n return { kind: 'failed' };\n }\n }\n\n private async applyEntitlements(entitlements: TEntitlement[]): Promise<void> {\n const { cache, emitter, logger } = this.deps;\n const previous = this.deps.getCurrentEntitlements();\n\n // L3: structural-compare BEFORE write so a future setter that normalizes\n // the array (sort, dedupe, freeze) can't make the equality check lie.\n const unchanged = entitlementsEqual(previous, entitlements);\n\n try {\n const cachedAt = await cache.save(entitlements);\n this.deps.setCachePersisted(cachedAt);\n } catch (error) {\n logger.warn('Recovery: cache.save failed; in-memory state still updated.', error);\n }\n this.deps.setEntitlements(entitlements);\n\n if (unchanged) return;\n\n emitter.emit('entitlements-changed', {\n entitlements: this.deps.getCurrentEntitlements(),\n previous,\n });\n }\n}\n\nfunction entryToNativeTransaction(entry: UnfinishedTransaction): NativeTransaction {\n const tx: NativeTransaction = {\n platform: entry.platform,\n productId: entry.productId,\n token: entry.token,\n productType: entry.productType,\n };\n if (entry.packageName) tx.packageName = entry.packageName;\n return tx;\n}\n","import type {\n BackendAdapter,\n RestoreRequest,\n RestoreRequestTransaction,\n RestoreResponse,\n} from '../adapters/backend/types.js';\nimport type { NativeAdapter } from '../adapters/native/types.js';\nimport type { TypedEventEmitter } from '../events/emitter.js';\nimport { IAPError, IAPErrorCode, toIAPError } from '../lib/errors.js';\nimport type { Logger } from '../lib/logger.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport type { RestoreResult } from '../types/results.js';\nimport type { NativeTransaction } from '../types/transaction.js';\nimport { type EntitlementCache, entitlementsEqual } from './entitlement-cache.js';\nimport type { UnfinishedTransactionsStore } from './unfinished-transactions.js';\n\ninterface RestoreOrchestratorDeps<TEntitlement extends EntitlementBase> {\n nativeAdapter: NativeAdapter;\n backend: BackendAdapter<TEntitlement>;\n cache: EntitlementCache<TEntitlement>;\n unfinished: UnfinishedTransactionsStore;\n emitter: TypedEventEmitter<TEntitlement>;\n logger: Logger;\n getCurrentEntitlements: () => TEntitlement[];\n setEntitlements: (next: TEntitlement[]) => void;\n setCachePersisted: (cachedAt: number) => void;\n}\n\n/**\n * Coordinates `iap.restorePurchases()` per PLAN.md §5.5.\n *\n * Sequence:\n * 1. Emit `restore-started`.\n * 2. `nativeAdapter.getOwnedTransactions()` (delegates to the capgo plugin's\n * `getPurchases()`).\n * 3. If empty → emit `restore-completed` with current entitlements,\n * return `{ restored: 0, entitlements: <current> }`. No backend call.\n * This covers fresh-install-no-purchases. The empty-array guard lives\n * here (orchestrator level) rather than in the HTTP adapter so all\n * transport implementations benefit automatically.\n * 4. POST batch to `backend.restore()`.\n * 5. On `valid: true`:\n * - Acknowledge each native transaction (best-effort; an ack failure just\n * means the store keeps reporting it as owned and the next\n * restore()/refresh() retries).\n * - Persist consolidated entitlements via `cache.save()`.\n * - Replace state.\n * - Remove from `unfinished_transactions` (defensive — purchase flow may\n * have left an entry there for one of these tokens after a crash).\n * - Emit `restore-completed` then `entitlements-changed`.\n * 6. On `valid: false` or backend throw: throw `IAPError` (orchestrator\n * surface is throw-on-fail, unlike `purchase()` which returns a\n * discriminated union; restore is consumer-initiated and a thrown\n * error is the right shape for \"Restore Purchases\" buttons).\n */\nexport class RestoreOrchestrator<TEntitlement extends EntitlementBase = EntitlementBase> {\n constructor(private readonly deps: RestoreOrchestratorDeps<TEntitlement>) {}\n\n async restorePurchases(): Promise<RestoreResult<TEntitlement>> {\n const { nativeAdapter, backend, cache, unfinished, emitter, logger } = this.deps;\n\n emitter.emit('restore-started', undefined);\n\n let owned: NativeTransaction[];\n try {\n owned = await nativeAdapter.getOwnedTransactions();\n } catch (cause) {\n throw toIAPError(cause, 'Failed to fetch owned transactions.', IAPErrorCode.STORE_ERROR);\n }\n\n if (owned.length === 0) {\n const entitlements = this.deps.getCurrentEntitlements();\n emitter.emit('restore-completed', { restored: 0, entitlements });\n return { restored: 0, entitlements };\n }\n\n const request: RestoreRequest = {\n transactions: owned.map((tx) => this.toRestoreEntry(tx)),\n };\n\n let response: RestoreResponse<TEntitlement>;\n try {\n response = await backend.restore(request);\n } catch (cause) {\n throw toIAPError(cause, 'Backend restore call failed.', IAPErrorCode.BACKEND_UNAVAILABLE);\n }\n\n if (!response.valid) {\n // Compose both the human-readable message and the stable machine code\n // so consumers can grep for either. PLAN.md §5.8 marks `error` as the\n // stable identifier — preserve it even when message is present.\n const detail = response.message\n ? `${response.message} [${response.error}]`\n : `Backend rejected restore (${response.error}).`;\n throw new IAPError({\n code: IAPErrorCode.VERIFICATION_REJECTED,\n message: detail,\n });\n }\n\n // Acknowledge each native transaction. Failures are best-effort —\n // backend says these are valid; if acknowledge() fails the store still\n // reports the purchase as owned, so the next refresh()/restore() retries.\n for (const tx of owned) {\n try {\n await nativeAdapter.acknowledge(tx);\n } catch (error) {\n logger.warn(`acknowledge() failed for \"${tx.productId}\" during restore.`, error);\n }\n }\n\n const entitlements = response.entitlements;\n const previous = this.deps.getCurrentEntitlements();\n\n try {\n const cachedAt = await cache.save(entitlements);\n this.deps.setCachePersisted(cachedAt);\n } catch (error) {\n logger.warn(\n 'Failed to persist entitlements after restore; in-memory state still updated.',\n error,\n );\n }\n this.deps.setEntitlements(entitlements);\n\n // Drain the unfinished list of any tokens we just verified.\n for (const tx of owned) {\n try {\n await unfinished.remove(tx.token);\n } catch (error) {\n logger.warn(\n `Failed to remove \"${tx.productId}\" from unfinished list during restore.`,\n error,\n );\n }\n }\n\n const next = this.deps.getCurrentEntitlements();\n emitter.emit('restore-completed', { restored: owned.length, entitlements: next });\n\n // L3: skip the emit when content is unchanged (avoids spurious re-renders\n // in reactive consumer stores that subscribe to entitlements-changed).\n if (!entitlementsEqual(previous, next)) {\n emitter.emit('entitlements-changed', { entitlements: next, previous });\n }\n\n return { restored: owned.length, entitlements: next };\n }\n\n private toRestoreEntry(tx: NativeTransaction): RestoreRequestTransaction {\n if (tx.platform === 'apple') {\n return {\n platform: 'apple',\n productId: tx.productId,\n transactionId: tx.token,\n };\n }\n if (!tx.packageName) {\n throw new IAPError({\n code: IAPErrorCode.STORE_ERROR,\n message: `Google owned transaction for \"${tx.productId}\" has no packageName; cannot restore.`,\n });\n }\n return {\n platform: 'google',\n productId: tx.productId,\n purchaseToken: tx.token,\n packageName: tx.packageName,\n };\n }\n}\n","import { z } from 'zod';\nimport type { StorageAdapter } from '../adapters/storage/types.js';\nimport { IAPError, IAPErrorCode } from '../lib/errors.js';\nimport type { Logger } from '../lib/logger.js';\nimport { productTypeSchema } from '../types/config.js';\nimport type { NativeTransaction } from '../types/transaction.js';\n\nconst STORE_KEY = 'unfinished_transactions';\n\nconst unfinishedEntrySchema = z.object({\n platform: z.enum(['apple', 'google']),\n productId: z.string().min(1),\n token: z.string().min(1),\n productType: productTypeSchema,\n packageName: z.string().optional(),\n /** ISO 8601 timestamp the entry was first persisted. */\n recordedAt: z.string(),\n});\n\nconst envelopeSchema = z.array(unfinishedEntrySchema);\n\nexport type UnfinishedTransaction = z.infer<typeof unfinishedEntrySchema>;\n\n/**\n * Persistent store for transactions that have completed natively (the user's\n * purchase succeeded with the platform store) but have NOT yet been verified\n * by the consumer backend.\n *\n * Lifecycle:\n * 1. Purchase orchestrator writes the entry BEFORE calling backend verify.\n * 2. On backend success, the orchestrator removes the entry and acks natively.\n * 3. If the app dies between (1) and acking, recovery on next `initialize()`\n * reads this list and re-attempts verification (Phase 6).\n *\n * Same tolerance pattern as {@link EntitlementCache}: malformed JSON is dropped\n * silently and reported as an empty list rather than crashing initialize.\n */\nexport class UnfinishedTransactionsStore {\n /**\n * Serializes mutating operations (`add` / `remove`) so concurrent callers\n * don't race the read-modify-write on the storage key. Phase 6's\n * parallel recovery exposed this — multiple `remove()` calls in flight\n * could each `list()` the same snapshot and overwrite each other's\n * `persist()`.\n */\n private mutationLock: Promise<void> = Promise.resolve();\n\n constructor(\n private readonly storage: StorageAdapter,\n private readonly logger: Logger,\n ) {}\n\n /** Returns the current list, or `[]` if empty / corrupt. */\n async list(): Promise<UnfinishedTransaction[]> {\n let raw: string | null;\n try {\n raw = await this.storage.get(STORE_KEY);\n } catch (cause) {\n this.logger.warn('Storage read failed; treating unfinished list as empty.', cause);\n return [];\n }\n if (!raw) return [];\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (cause) {\n this.logger.warn('unfinished_transactions payload is not valid JSON; clearing.', cause);\n await this.safeClear();\n return [];\n }\n\n const result = envelopeSchema.safeParse(parsed);\n if (!result.success) {\n this.logger.warn('unfinished_transactions has unexpected shape; clearing.', result.error);\n await this.safeClear();\n return [];\n }\n return result.data;\n }\n\n /**\n * Append a transaction to the list. Idempotent: if a same-token entry\n * already exists, this is a no-op (avoids dupes when restore + active\n * purchase race for the same StoreKit replay).\n */\n async add(tx: NativeTransaction): Promise<void> {\n return this.runExclusive(async () => {\n const current = await this.list();\n if (current.some((e) => e.token === tx.token)) return;\n const entry: UnfinishedTransaction = {\n platform: tx.platform,\n productId: tx.productId,\n token: tx.token,\n productType: tx.productType,\n ...(tx.packageName ? { packageName: tx.packageName } : {}),\n recordedAt: new Date().toISOString(),\n };\n await this.persist([...current, entry]);\n });\n }\n\n /** Remove the entry with the given token. No-op if not present. */\n async remove(token: string): Promise<void> {\n return this.runExclusive(async () => {\n const current = await this.list();\n const next = current.filter((e) => e.token !== token);\n if (next.length === current.length) return;\n await this.persist(next);\n });\n }\n\n /** Clear every unfinished entry. */\n async clear(): Promise<void> {\n return this.runExclusive(() => this.safeClear());\n }\n\n /**\n * Run `fn` with exclusive access to the storage key. Implements a simple\n * promise chain — every mutation awaits the previous one's completion.\n * Reads (`list()`) are NOT serialized because they're tolerant of stale\n * snapshots (callers either compose or accept the read-once semantic).\n */\n private async runExclusive<T>(fn: () => Promise<T>): Promise<T> {\n const prev = this.mutationLock;\n let release!: () => void;\n this.mutationLock = new Promise((resolve) => {\n release = resolve;\n });\n try {\n await prev;\n return await fn();\n } finally {\n release();\n }\n }\n\n private async persist(entries: UnfinishedTransaction[]): Promise<void> {\n try {\n await this.storage.set(STORE_KEY, JSON.stringify(entries));\n } catch (cause) {\n throw new IAPError({\n code: IAPErrorCode.STORAGE_ERROR,\n message: 'Failed to persist unfinished transactions list.',\n cause,\n recoverable: true,\n });\n }\n }\n\n private async safeClear(): Promise<void> {\n try {\n await this.storage.remove(STORE_KEY);\n } catch (cause) {\n this.logger.warn('Failed to clear unfinished_transactions key.', cause);\n }\n }\n}\n","import type { EntitlementBase } from '../types/entitlement.js';\nimport type { EventMap, EventName, EventPayload, Unsubscribe } from '../types/events.js';\n\ntype AnyHandler = (payload: unknown) => void;\n\n/**\n * Tiny typed event emitter. No external dep — just a Map of name → Set<handler>.\n * Generic over the consumer's entitlement type so payloads are statically checked.\n */\nexport class TypedEventEmitter<TEntitlement extends EntitlementBase = EntitlementBase> {\n private readonly handlers = new Map<string, Set<AnyHandler>>();\n\n on<K extends EventName<TEntitlement>>(\n event: K,\n handler: (payload: EventPayload<K, TEntitlement>) => void,\n ): Unsubscribe {\n const key = event as string;\n let set = this.handlers.get(key);\n if (!set) {\n set = new Set();\n this.handlers.set(key, set);\n }\n set.add(handler as AnyHandler);\n return () => {\n const current = this.handlers.get(key);\n if (current) current.delete(handler as AnyHandler);\n };\n }\n\n emit<K extends EventName<TEntitlement>>(event: K, payload: EventPayload<K, TEntitlement>): void {\n const set = this.handlers.get(event as string);\n if (!set) return;\n for (const handler of [...set]) {\n try {\n handler(payload);\n } catch {\n // Handlers must not break the emitter. Swallow to keep other listeners alive.\n }\n }\n }\n\n removeAll(): void {\n this.handlers.clear();\n }\n\n /** Number of listeners for a given event — used by tests. */\n listenerCount(event: keyof EventMap<TEntitlement>): number {\n return this.handlers.get(event as string)?.size ?? 0;\n }\n}\n","import { z } from 'zod';\nimport { selectBackendAdapter } from './adapters/backend/index.js';\nimport type { BackendAdapter } from './adapters/backend/types.js';\nimport { selectNativeAdapter } from './adapters/native/index.js';\nimport type { NativeAdapter } from './adapters/native/types.js';\nimport { selectStorageAdapter } from './adapters/storage/index.js';\nimport type { StorageAdapter } from './adapters/storage/types.js';\nimport {\n type AppResumeListenerHandle,\n attachAppResumeListener,\n} from './core/app-resume-listener.js';\nimport { EntitlementCache, entitlementsEqual } from './core/entitlement-cache.js';\nimport { PurchaseOrchestrator } from './core/purchase-flow.js';\nimport { DEFAULT_PERMANENT_ERROR_CODES, RecoveryOrchestrator } from './core/recovery-flow.js';\nimport { RestoreOrchestrator } from './core/restore-flow.js';\nimport { UnfinishedTransactionsStore } from './core/unfinished-transactions.js';\nimport { TypedEventEmitter } from './events/emitter.js';\nimport { IAPError, IAPErrorCode } from './lib/errors.js';\nimport { type LogLevel, type Logger, createDefaultLogger, isLogger } from './lib/logger.js';\nimport { getPlatform, isNative } from './lib/platform.js';\nimport {\n type IAPConfig,\n type IAPConfigInput,\n configuredProductsArraySchema,\n iapConfigSchema,\n} from './types/config.js';\nimport type { EntitlementBase } from './types/entitlement.js';\nimport type { EventName, EventPayload, Unsubscribe } from './types/events.js';\nimport type { ConfiguredProduct, Product } from './types/product.js';\nimport type { PurchaseOptions, PurchaseResult, RestoreResult } from './types/results.js';\nimport type { Storefront } from './types/storefront.js';\n\nexport interface IAP<TEntitlement extends EntitlementBase = EntitlementBase> {\n initialize(): Promise<void>;\n /**\n * Refresh entitlements from the consumer backend.\n *\n * Fetches via the configured `BackendAdapter` (HTTP default or custom),\n * freezes results, persists them via the storage adapter, and emits\n * `entitlements-changed`.\n */\n refresh(): Promise<void>;\n /**\n * Tear down. Removes event listeners and disposes the native adapter.\n *\n * NOTE 1: persisted entitlement cache is NOT cleared. If you're handling\n * a logout for a multi-user app, also call your storage adapter's\n * `clear()` (or the consumer-supplied equivalent) before the next user\n * logs in, otherwise their first read will see the previous user's\n * cached entitlements until `refresh()` returns.\n *\n * NOTE 2: calling `destroy()` while a `purchase()` is in flight may\n * leave the result in an inconsistent state — the backend may have\n * recorded the entitlement but the native `acknowledge()` call may not\n * have run yet. On Android this means Google auto-refunds in 3 days\n * (the unfinished-transaction recovery on the next launch re-acks, but\n * only if it runs within that window). Avoid by awaiting the in-flight\n * `purchase()` before calling `destroy()`.\n */\n destroy(): Promise<void>;\n\n /**\n * Start a purchase. Throws `IAPError` only on impossible states\n * (NOT_INITIALIZED, ALREADY_IN_PROGRESS, PRODUCT_NOT_FOUND,\n * INVALID_APP_USER_ID, APP_USER_ID_FETCH_FAILED); all other\n * outcomes — user cancellation, backend rejection, native errors — are\n * surfaced via the `PurchaseResult` discriminated union so the caller\n * can render the right UI without try/catch gymnastics.\n *\n * `opts.appUserId` is optional. When provided (string or async fetcher\n * returning a string), the resolved value is validated as a UUID v4\n * and forwarded to StoreKit's `appAccountToken` (iOS) / Play\n * Billing's `obfuscatedAccountId` (Android) — making it available on\n * Attesto's verify response and outbound webhook payload as\n * `appUserId` so backends can join on user identity directly. See\n * `PurchaseOptions` and `AppUserId` for full semantics.\n *\n * Emits `purchase-started`, then exactly one of: `purchase-success`\n * (+ `entitlements-changed`), `purchase-cancelled`, `purchase-pending`,\n * `verification-failed`, or `purchase-failed`.\n */\n purchase(opts: PurchaseOptions): Promise<PurchaseResult<TEntitlement>>;\n\n /**\n * Re-verify every owned transaction with the consumer backend and\n * refresh entitlements from the consolidated response. Wire this to a\n * \"Restore Purchases\" button.\n *\n * Returns `{ restored, entitlements }` where `restored` is the number\n * of native transactions submitted (0 on a fresh install with no\n * purchases). Throws `IAPError` on backend rejection or transport\n * failure — wrap the call in try/catch in the consumer's button\n * handler.\n *\n * Emits `restore-started`, then on success `restore-completed` +\n * `entitlements-changed` (the latter only when the entitlements list\n * actually changed). On failure no completion event fires; the thrown\n * error is the only signal.\n *\n * NOTE on the empty-owned-list case: when the platform store reports\n * no owned transactions (fresh install, signed-out Apple ID, etc.),\n * the library short-circuits — it does NOT call the backend and\n * preserves whatever entitlements were already cached in memory. If\n * you suspect cache staleness (e.g. user just signed in to a new\n * Apple ID), call `iap.refresh()` afterward to reconcile against the\n * backend's view of the user's entitlements.\n */\n restorePurchases(): Promise<RestoreResult<TEntitlement>>;\n\n /**\n * Get product info merged with native pricing. Returns one entry per\n * product the platform store knows about; products configured but not\n * yet ingested by the store are silently skipped (no error).\n */\n getProducts(): Promise<Product[]>;\n\n /**\n * Read the current storefront — the country the user's App Store / Google\n * Play account is registered to. Use it to drive region-dependent UI:\n * regional offers/pricing, and gating external-payment links whose\n * eligibility the platform itself keys to storefront country (not device\n * locale).\n *\n * `countryCode` is normalized to ISO 3166-1 alpha-2 across platforms (raw\n * native code preserved on `countryCodeRaw`). Resolves `null` when no\n * storefront is available — on web, when the installed\n * `@capgo/native-purchases` doesn't register the native method, when the\n * native call fails, or when the store reports an empty country (e.g. EU\n * alternative distribution).\n *\n * Read live — do not cache. Treat the value as a UX/targeting hint; for\n * compliance- or entitlement-sensitive enforcement, trust the server-side\n * signed storefront from your backend instead.\n */\n getStorefront(): Promise<Storefront | null>;\n\n hasEntitlement(key: string): boolean;\n /** Returns a defensive shallow copy. Each entitlement is frozen. */\n getEntitlements(): TEntitlement[];\n /** Returns a frozen entitlement reference, or null if missing. */\n getEntitlement(key: string): TEntitlement | null;\n\n on<K extends EventName<TEntitlement>>(\n event: K,\n handler: (payload: EventPayload<K, TEntitlement>) => void,\n ): Unsubscribe;\n}\n\ninterface IAPInternalState<TEntitlement extends EntitlementBase> {\n config: IAPConfig;\n /** Populated by initialize(); null beforehand. Lazy to avoid loading\n * `@capgo/native-purchases` on web platforms (PLAN.md §9 / review C4). */\n adapter: NativeAdapter | null;\n /** Backend transport. Constructed eagerly in the factory so config errors\n * surface immediately; methods are not invoked until refresh()/purchase(). */\n backend: BackendAdapter<TEntitlement>;\n storage: StorageAdapter;\n cache: EntitlementCache<TEntitlement>;\n unfinished: UnfinishedTransactionsStore;\n /** Constructed lazily in initialize() once the native adapter is resolved. */\n orchestrator: PurchaseOrchestrator<TEntitlement> | null;\n /** Constructed alongside the orchestrator in initialize(). */\n restorer: RestoreOrchestrator<TEntitlement> | null;\n /** Constructed alongside the orchestrator; recovery runs once at init. */\n recoverer: RecoveryOrchestrator<TEntitlement> | null;\n /** App resume listener handle; null when refreshOnResume is disabled, on\n * web, or when @capacitor/app isn't installed. */\n resumeListener: AppResumeListenerHandle | null;\n emitter: TypedEventEmitter<TEntitlement>;\n logger: Logger;\n initialized: boolean;\n destroyed: boolean;\n entitlements: TEntitlement[];\n /** Timestamp of the last cache write, used for TTL-based background refresh. */\n cachedAt: number | null;\n /**\n * Resolved SKU manifest. Populated in `initialize()` from either the\n * static `config.products` or `backend.listProducts()`. Read by\n * `getProducts()`, `purchase()`, and the orchestrators.\n */\n products: ConfiguredProduct[];\n}\n\nexport function createIAP<TEntitlement extends EntitlementBase = EntitlementBase>(\n input: IAPConfigInput,\n): IAP<TEntitlement> {\n const config = parseConfig(input);\n const logger = resolveLogger(config.options.logLevel, config.options.logger);\n const storage = selectStorageAdapter(config.storage);\n const cache = new EntitlementCache<TEntitlement>(storage, logger);\n const unfinished = new UnfinishedTransactionsStore(storage, logger);\n const backend = selectBackendAdapter<TEntitlement>({ config: config.backend, logger });\n const emitter = new TypedEventEmitter<TEntitlement>();\n\n // Validate the static manifest eagerly so config typos surface synchronously.\n // The dynamic-manifest path validates inside initialize() once the backend\n // returns the response.\n if (config.products) {\n ensureUniqueProductIds(config.products);\n }\n\n const state: IAPInternalState<TEntitlement> = {\n config,\n adapter: null,\n backend,\n storage,\n cache,\n unfinished,\n orchestrator: null,\n restorer: null,\n recoverer: null,\n resumeListener: null,\n emitter,\n logger,\n initialized: false,\n destroyed: false,\n entitlements: [],\n cachedAt: null,\n products: Object.freeze([...(config.products ?? [])]) as ConfiguredProduct[],\n };\n\n // Refresh implementation lives outside the returned object literal so\n // internal callers (the app-resume listener, the TTL microtask) can invoke\n // it directly without going through `this.refresh()` — that pattern would\n // break if a consumer destructured `initialize` from the iap object. The\n // public `refresh` method below just delegates to this function.\n async function refreshEntitlements(): Promise<void> {\n requireInitialized(state);\n const previous = state.entitlements;\n const fetched = await state.backend.getEntitlements();\n const next = freezeAll(fetched);\n\n // Persist + replace state in a single transition. If save() fails the\n // in-memory state still reflects what the backend returned (best-effort\n // cache; the next session will re-fetch on its own refresh).\n try {\n state.cachedAt = await state.cache.save(next);\n } catch (error) {\n state.logger.warn(\n 'Failed to persist refreshed entitlements; in-memory state still updated.',\n error,\n );\n }\n\n state.entitlements = next;\n // L3: skip the emit when content is unchanged.\n if (!entitlementsEqual(previous, next)) {\n state.emitter.emit('entitlements-changed', { entitlements: next, previous });\n }\n }\n\n return {\n async initialize() {\n if (state.destroyed) {\n throw new IAPError({\n code: IAPErrorCode.NOT_INITIALIZED,\n message: 'IAP instance has been destroyed; create a new one with createIAP().',\n });\n }\n if (state.initialized) {\n state.logger.debug('initialize() called more than once; ignoring.');\n return;\n }\n\n const platform = getPlatform();\n if (!isNative()) {\n state.logger.info(\n 'Native purchases unavailable on web; entitlement queries still functional.',\n );\n } else {\n state.logger.debug(`Initializing on platform=${platform}`);\n }\n\n // Resolve the SKU manifest. If the consumer omitted `products` from\n // config, the schema's superRefine has already guaranteed that the\n // backend can supply one — call listProducts() and validate the\n // response against the same schema config-time `products` would have\n // gone through. Failures throw verbatim (the adapter is responsible\n // for mapping transport errors to IAPError).\n if (!state.config.products) {\n if (typeof state.backend.listProducts !== 'function') {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'config.products is omitted but backend adapter does not implement listProducts(). This is a library bug; the schema should have caught it.',\n });\n }\n const fetched = await state.backend.listProducts();\n // Redundant validation on the HTTP path (HttpBackendAdapter already\n // parses with productManifestResponseSchema), but the only validation\n // gate for custom adapters that don't go through HttpClient.\n const validated = configuredProductsArraySchema.safeParse(fetched);\n if (!validated.success) {\n throw new IAPError({\n code: IAPErrorCode.BACKEND_BAD_RESPONSE,\n message: `backend.listProducts() returned an invalid manifest: ${validated.error.issues\n .map((i) => `${i.path.join('.') || '<root>'}: ${i.message}`)\n .join('; ')}`,\n cause: validated.error,\n });\n }\n ensureUniqueProductIds(validated.data);\n state.products = Object.freeze([...validated.data]) as ConfiguredProduct[];\n state.logger.debug(`Resolved ${validated.data.length} product(s) from backend manifest.`);\n }\n\n // Lazy adapter construction — this is the dynamic-import boundary so\n // web builds don't pull in `@capgo/native-purchases`.\n state.adapter = await selectNativeAdapter();\n\n // Now that the native adapter is resolved, wire the orchestrators.\n // Both share the same getter/setter triplet into createIAP's state.\n // The HTTP-config `getAuthHeaders` is hoisted here so the purchase\n // orchestrator can forward it to function-form `appUserId` fetchers\n // as `ctx.authHeaders`. Custom-adapter consumers don't have one\n // configured at the IAP-config level, so we resolve to `{}` for\n // them (their fetcher closes over their own auth state).\n const configGetAuthHeaders = state.config.backend.getAuthHeaders;\n const getAuthHeaders: () => Promise<Record<string, string>> = configGetAuthHeaders\n ? async () => configGetAuthHeaders()\n : async () => ({});\n const sharedDeps = {\n nativeAdapter: state.adapter,\n backend: state.backend,\n cache: state.cache,\n unfinished: state.unfinished,\n emitter: state.emitter,\n logger: state.logger,\n getCurrentEntitlements: () => state.entitlements,\n setEntitlements: (next: TEntitlement[]) => {\n state.entitlements = freezeAll(next);\n },\n setCachePersisted: (cachedAt: number) => {\n state.cachedAt = cachedAt;\n },\n getAuthHeaders,\n };\n\n state.orchestrator = new PurchaseOrchestrator<TEntitlement>({\n ...sharedDeps,\n products: state.products,\n });\n state.restorer = new RestoreOrchestrator<TEntitlement>(sharedDeps);\n state.recoverer = new RecoveryOrchestrator<TEntitlement>({\n ...sharedDeps,\n maxBatch: state.config.options.recoveryMaxBatch,\n permanentErrorCodes: new Set(\n state.config.options.permanentErrorCodes ?? DEFAULT_PERMANENT_ERROR_CODES,\n ),\n });\n\n try {\n await state.adapter.isAvailable();\n } catch (error) {\n state.logger.warn('Native adapter availability check threw; continuing.', error);\n }\n\n const cached = await state.cache.load();\n if (cached) {\n state.entitlements = freezeAll(cached.entitlements);\n state.cachedAt = cached.cachedAt;\n state.logger.debug(\n `Loaded ${cached.entitlements.length} cached entitlement(s) from ${new Date(cached.cachedAt).toISOString()}.`,\n );\n }\n\n // Run recovery for unfinished transactions. Best-effort, never throws.\n // Successful recoveries update entitlements before `ready` fires so\n // the consumer's first read sees the latest state.\n if (state.config.options.recoverUnfinishedTransactions && isNative()) {\n try {\n const result = await state.recoverer.recoverUnfinishedTransactions();\n if (result.inspected > 0) {\n state.logger.info(\n `Recovery inspected ${result.inspected} unfinished transaction(s): ${result.recovered} recovered, ${result.failures} retained.`,\n );\n }\n } catch (error) {\n // Recovery should swallow internally; this catches the\n // unexpected case where it didn't.\n state.logger.warn('Recovery threw unexpectedly; continuing initialize.', error);\n }\n }\n\n // Wire the app-resume listener. Lazy-imports @capacitor/app so consumers\n // who disable refreshOnResume aren't forced to install it.\n if (state.config.options.refreshOnResume && isNative()) {\n state.resumeListener = await attachAppResumeListener({\n logger: state.logger,\n onResume: async () => {\n // Best-effort: warn-and-swallow so a transient backend hiccup\n // doesn't poison subsequent foreground events.\n try {\n await refreshEntitlements();\n } catch (error) {\n state.logger.warn('refreshOnResume: refresh() failed.', error);\n }\n },\n });\n }\n\n // TTL-based stale-cache check: if we loaded cached entitlements that\n // are older than the configured TTL, schedule a background refresh\n // to fire after `ready`. Reads still return the cached value\n // immediately — PLAN.md §7 \"still returns the cached value but the\n // library schedules a refresh\".\n if (\n state.cachedAt !== null &&\n Date.now() - state.cachedAt > state.config.options.entitlementCacheTtlMs\n ) {\n state.logger.debug('Cache exceeds TTL; scheduling background refresh.');\n queueMicrotask(() => {\n // Guard against destroy()-during-init: if the consumer tore down\n // before the microtask drained, refresh() would throw NOT_INITIALIZED\n // and emit a confusing warn. Quietly skip instead.\n if (!state.initialized || state.destroyed) return;\n refreshEntitlements().catch((error) => {\n state.logger.warn('TTL background refresh failed.', error);\n });\n });\n }\n\n state.initialized = true;\n state.emitter.emit('ready', undefined);\n },\n\n refresh: refreshEntitlements,\n\n async destroy() {\n if (state.destroyed) return;\n state.destroyed = true;\n state.initialized = false;\n state.entitlements = [];\n state.cachedAt = null;\n state.emitter.removeAll();\n\n if (state.resumeListener) {\n try {\n await state.resumeListener.remove();\n } catch (error) {\n state.logger.warn('Resume listener remove threw; continuing teardown.', error);\n }\n state.resumeListener = null;\n }\n\n if (state.adapter?.dispose) {\n try {\n await state.adapter.dispose();\n } catch (error) {\n state.logger.warn('Adapter dispose threw; continuing teardown.', error);\n }\n }\n state.adapter = null;\n state.orchestrator = null;\n state.restorer = null;\n state.recoverer = null;\n },\n\n async purchase(opts) {\n requireInitialized(state);\n // orchestrator is set in initialize() alongside the native adapter,\n // so it's always present once initialized=true.\n if (!state.orchestrator) {\n throw new IAPError({\n code: IAPErrorCode.NOT_INITIALIZED,\n message: 'Purchase orchestrator not constructed; this is a library bug.',\n });\n }\n return state.orchestrator.purchase(opts);\n },\n\n async restorePurchases() {\n requireInitialized(state);\n if (!state.restorer) {\n throw new IAPError({\n code: IAPErrorCode.NOT_INITIALIZED,\n message: 'Restore orchestrator not constructed; this is a library bug.',\n });\n }\n return state.restorer.restorePurchases();\n },\n\n async getProducts() {\n requireInitialized(state);\n // requireInitialized() guarantees state.adapter is set; the explicit\n // null-check below matches the same defensive pattern used by purchase().\n if (!state.adapter) {\n throw new IAPError({\n code: IAPErrorCode.NOT_INITIALIZED,\n message: 'Native adapter not constructed; this is a library bug.',\n });\n }\n return state.adapter.getProducts(state.products.map((p) => ({ id: p.id, type: p.type })));\n },\n\n async getStorefront() {\n requireInitialized(state);\n // Adapter is guaranteed set once initialized (see getProducts()); the\n // `?.` on getStorefront covers adapters that don't implement the\n // optional method, and `?? null` keeps the contract total.\n return state.adapter?.getStorefront?.() ?? null;\n },\n\n hasEntitlement(key) {\n return state.entitlements.some((e) => e.key === key);\n },\n\n getEntitlements() {\n return [...state.entitlements];\n },\n\n getEntitlement(key) {\n return state.entitlements.find((e) => e.key === key) ?? null;\n },\n\n on(event, handler) {\n return state.emitter.on(event, handler);\n },\n };\n}\n\nfunction freezeAll<T extends object>(items: T[]): T[] {\n return items.map((item) => Object.freeze({ ...item }));\n}\n\nfunction parseConfig(input: IAPConfigInput): IAPConfig {\n try {\n // Schema's `superRefine` has runtime-validated that the function-typed\n // fields ARE functions (or that an adapter is provided instead). The\n // overlay type on IAPConfig narrows them from `unknown` to their proper\n // contracts. Cast at this boundary, not at every use site.\n const parsed = iapConfigSchema.parse(input);\n return parsed as unknown as IAPConfig;\n } catch (error) {\n if (error instanceof z.ZodError) {\n const issues = error.issues\n .map((i) => ` - ${i.path.join('.') || '<root>'}: ${i.message}`)\n .join('\\n');\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message: `Invalid IAP configuration:\\n${issues}`,\n cause: error,\n });\n }\n throw error;\n }\n}\n\nfunction ensureUniqueProductIds(products: ConfiguredProduct[]): void {\n const seen = new Set<string>();\n for (const product of products) {\n if (seen.has(product.id)) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message: `Duplicate product id \"${product.id}\" in product manifest.`,\n });\n }\n seen.add(product.id);\n }\n}\n\nfunction resolveLogger(level: LogLevel, candidate: unknown): Logger {\n if (isLogger(candidate)) return candidate;\n return createDefaultLogger(level);\n}\n\nfunction requireInitialized<TEntitlement extends EntitlementBase>(\n state: IAPInternalState<TEntitlement>,\n): void {\n if (!state.initialized) {\n throw new IAPError({\n code: IAPErrorCode.NOT_INITIALIZED,\n message: 'Call iap.initialize() before this method.',\n });\n }\n}\n","export type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug';\n\nexport interface Logger {\n error(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n debug(message: string, ...args: unknown[]): void;\n}\n\nconst LEVEL_PRIORITY: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n};\n\nconst PREFIX = '[@nosslabs/iap]';\n\n/**\n * Default logger that writes to console at or above the configured level.\n * Consumers can pass a custom logger (Sentry, Datadog, etc.) via config.\n */\nexport function createDefaultLogger(level: LogLevel): Logger {\n const minPriority = LEVEL_PRIORITY[level];\n const enabled = (l: LogLevel) => LEVEL_PRIORITY[l] <= minPriority;\n\n return {\n error(message, ...args) {\n if (enabled('error')) console.error(PREFIX, message, ...args);\n },\n warn(message, ...args) {\n if (enabled('warn')) console.warn(PREFIX, message, ...args);\n },\n info(message, ...args) {\n if (enabled('info')) console.info(PREFIX, message, ...args);\n },\n debug(message, ...args) {\n if (enabled('debug')) console.debug(PREFIX, message, ...args);\n },\n };\n}\n\nexport function isLogger(value: unknown): value is Logger {\n if (!value || typeof value !== 'object') return false;\n const candidate = value as Partial<Logger>;\n return (\n typeof candidate.error === 'function' &&\n typeof candidate.warn === 'function' &&\n typeof candidate.info === 'function' &&\n typeof candidate.debug === 'function'\n );\n}\n","export { createIAP, type IAP } from './createIAP.js';\nexport { DEFAULT_PERMANENT_ERROR_CODES } from './core/recovery-flow.js';\nexport { IAPError, IAPErrorCode, errorHint, isIAPError } from './lib/errors.js';\nexport { VERSION } from './version.js';\n\nexport type {\n IAPConfig,\n IAPConfigInput,\n BackendConfig,\n BackendConfigInput,\n StorageConfig,\n OptionsConfig,\n} from './types/config.js';\n\nexport type { ConfiguredProduct, Product, ProductType } from './types/product.js';\n\nexport type { Storefront } from './types/storefront.js';\n\nexport type {\n EntitlementBase,\n DefaultEntitlement,\n} from './types/entitlement.js';\n\nexport type {\n NativeTransaction,\n VerifiedTransaction,\n Platform,\n} from './types/transaction.js';\n\nexport type {\n AppUserId,\n AppUserIdFetcherContext,\n PurchaseOptions,\n PurchaseResult,\n RestoreResult,\n} from './types/results.js';\n\nexport type {\n EventMap,\n EventName,\n EventPayload,\n Unsubscribe,\n} from './types/events.js';\n\nexport type { Logger, LogLevel } from './lib/logger.js';\n\n// Backend layer (Phase 3) — consumers building a custom transport implement\n// BackendAdapter and pass it via config.backend.adapter. The default HTTP\n// implementation is also exported for advanced use (e.g. custom test setups).\nexport type {\n BackendAdapter,\n RestoreRequest,\n RestoreRequestTransaction,\n RestoreResponse,\n VerifyAppleRequest,\n VerifyGoogleRequest,\n VerifyResponse,\n} from './adapters/backend/types.js';\nexport { HttpBackendAdapter, HttpClient } from './adapters/backend/index.js';\nexport type { HttpRequest } from './adapters/backend/http-client.js';\n","/**\n * Library version, injected at build time from `package.json` (see the\n * `define` in tsup.config.ts, mirrored in vitest.config.ts).\n *\n * Exported for consumers to read — nothing inside the library consumes it. (An\n * earlier comment claimed the logger stamped it onto error reports; it never\n * did. `src/lib/logger.ts` uses a fixed `[@nosslabs/iap]` prefix.)\n */\nexport const VERSION: string = __PKG_VERSION__;\n"]}
1
+ {"version":3,"sources":["../src/lib/errors.ts","../src/lib/platform.ts","../src/adapters/native/capgo/map-purchase-error.ts","../src/lib/subscription-period.ts","../src/adapters/native/capgo/normalize-product.ts","../src/lib/jws.ts","../src/adapters/native/capgo/normalize-transaction.ts","../src/lib/iso-country.ts","../src/adapters/native/capgo/storefront.ts","../src/adapters/native/capgo/watch-transactions.ts","../src/adapters/native/capgo/native-adapter.ts","../src/adapters/backend/index.ts","../src/adapters/backend/http-adapter.ts","../src/adapters/backend/http-client.ts","../src/lib/redact.ts","../src/lib/uuid.ts","../src/types/config.ts","../src/types/entitlement.ts","../src/adapters/backend/types.ts","../src/core/local-verification.ts","../src/adapters/backend/local-adapter.ts","../src/adapters/storage/index.ts","../src/adapters/storage/memory-adapter.ts","../src/adapters/storage/preferences-adapter.ts","../src/core/entitlement-cache.ts","../src/core/storage-keys.ts","../src/core/iap-state.ts","../src/adapters/native/index.ts","../src/adapters/native/web/web-stub.ts","../src/core/initialize.ts","../src/core/app-resume-listener.ts","../src/core/attach-transaction-watch.ts","../src/core/purchase-flow.ts","../src/core/finalize-transaction.ts","../src/core/resolve-pending.ts","../src/core/store-purchase.ts","../src/core/verify-helpers.ts","../src/core/recovery-flow.ts","../src/core/restore-flow.ts","../src/core/transaction-updates.ts","../src/core/mutation-lock.ts","../src/core/pending-purchases.ts","../src/core/reset.ts","../src/core/unfinished-transactions.ts","../src/events/emitter.ts","../src/createIAP.ts","../src/lib/logger.ts","../src/index.ts","../src/version.ts"],"names":["IAPError","IAPErrorCode","Capacitor","NativePurchases","PURCHASE_TYPE","z","resolveAppUserId","entitlements","STORE_KEY"],"mappings":"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AK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EAAK,IAAA;AAAA,MACL,GAAA,EA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","file":"index.cjs","sourcesContent":["export const IAPErrorCode = {\n // Configuration\n INVALID_CONFIG: 'INVALID_CONFIG',\n NOT_INITIALIZED: 'NOT_INITIALIZED',\n\n // Native plugin\n PLATFORM_NOT_SUPPORTED: 'PLATFORM_NOT_SUPPORTED',\n BILLING_NOT_AVAILABLE: 'BILLING_NOT_AVAILABLE',\n PRODUCT_NOT_FOUND: 'PRODUCT_NOT_FOUND',\n USER_CANCELLED: 'USER_CANCELLED',\n PURCHASE_PENDING: 'PURCHASE_PENDING',\n ALREADY_PURCHASED: 'ALREADY_PURCHASED',\n STORE_ERROR: 'STORE_ERROR',\n UNACKNOWLEDGED_PENDING: 'UNACKNOWLEDGED_PENDING',\n\n // Concurrency\n ALREADY_IN_PROGRESS: 'ALREADY_IN_PROGRESS',\n\n // Backend\n BACKEND_UNAVAILABLE: 'BACKEND_UNAVAILABLE',\n BACKEND_TIMEOUT: 'BACKEND_TIMEOUT',\n BACKEND_AUTH_FAILED: 'BACKEND_AUTH_FAILED',\n /** Backend reachable but the response was rejected (non-transient 4xx other\n * than auth, malformed JSON, schema violation, 204 No Content on a JSON\n * endpoint). Fix the request shape or the backend; do not retry. */\n BACKEND_BAD_RESPONSE: 'BACKEND_BAD_RESPONSE',\n VERIFICATION_REJECTED: 'VERIFICATION_REJECTED',\n\n // Storage\n STORAGE_ERROR: 'STORAGE_ERROR',\n\n // appUserId pre-attach\n /**\n * The supplied `appUserId` (literal or fetcher-returned) is not a valid\n * RFC 9562 UUID. Apple requires a UUID for `appAccountToken`; we enforce\n * the same constraint cross-platform for a consistent contract. Any\n * version is accepted — see `isValidUuid` for what is still refused.\n */\n INVALID_APP_USER_ID: 'INVALID_APP_USER_ID',\n /**\n * The async `appUserId` fetcher threw or rejected. Original error is\n * attached as `cause` so the caller can introspect (network failure,\n * backend 5xx, etc.).\n */\n APP_USER_ID_FETCH_FAILED: 'APP_USER_ID_FETCH_FAILED',\n} as const;\n\nexport type IAPErrorCode = (typeof IAPErrorCode)[keyof typeof IAPErrorCode];\n\nconst RECOVERABLE_CODES = new Set<IAPErrorCode>([\n IAPErrorCode.BACKEND_UNAVAILABLE,\n IAPErrorCode.BACKEND_TIMEOUT,\n IAPErrorCode.STORAGE_ERROR,\n IAPErrorCode.UNACKNOWLEDGED_PENDING,\n]);\n\n/**\n * Per-code remediation hints. Each line answers \"what does the consumer\n * usually need to check or change to resolve this?\" — short enough to\n * append to a thrown error's message without burying the original detail.\n *\n * Style: imperative, action-first, ends with a period. No links (those\n * live in the docs; consumers grep for the code and find them).\n */\nconst HINTS: Readonly<Record<IAPErrorCode, string>> = {\n // Configuration\n INVALID_CONFIG:\n 'Check the field paths reported above against the IAPConfig schema (see /api/types).',\n NOT_INITIALIZED:\n 'Call iap.initialize() before this method, or recreate the instance after destroy().',\n\n // Native plugin\n PLATFORM_NOT_SUPPORTED:\n 'In-app purchases run on iOS/Android only. Web is no-op by design — guard your purchase UI behind Capacitor.isNativePlatform().',\n BILLING_NOT_AVAILABLE:\n 'The store billing service is unavailable. Confirm @capgo/native-purchases is installed and `npx cap sync` has run; check the device sandbox/test account is signed in.',\n PRODUCT_NOT_FOUND:\n 'Ensure the productId is registered in App Store Connect / Play Console AND in your createIAP({ products }) config.',\n USER_CANCELLED: 'No action needed — the user dismissed the native purchase sheet.',\n PURCHASE_PENDING:\n 'Android only: payment is awaiting external clearance (e.g. cash payment, bank verification). The backend will receive a Google RTDN webhook when it clears; call iap.refresh() afterward.',\n ALREADY_PURCHASED:\n 'The user already owns this non-consumable. Use iap.restorePurchases() to re-grant entitlement, or query iap.hasEntitlement(key) before showing the purchase CTA.',\n STORE_ERROR:\n 'Native store reported an error. Check device connectivity, sandbox account state, and the cause field for the underlying plugin error.',\n UNACKNOWLEDGED_PENDING:\n 'A Google purchase has been unacknowledged for >2 days and is at risk of auto-refund. Verify the backend can be reached and call iap.refresh() to retry acknowledgement.',\n\n // Concurrency\n ALREADY_IN_PROGRESS:\n 'Await the in-flight iap.purchase(productId) before starting another for the same product.',\n\n // Backend\n BACKEND_UNAVAILABLE:\n 'Backend is unreachable or returning 5xx. Retry will happen automatically per config.retries; if persistent, check your server.',\n BACKEND_TIMEOUT:\n 'Backend did not respond within timeoutMs. Increase config.backend.timeoutMs or check server response time.',\n BACKEND_AUTH_FAILED:\n 'Backend returned 401/403. Check that getAuthHeaders() returns a valid Bearer token and that the backend recognizes it.',\n BACKEND_BAD_RESPONSE:\n 'Backend response did not match the expected shape. Confirm /api/iap/* endpoints follow the contract documented at /guide/backend-contract.',\n VERIFICATION_REJECTED:\n 'Backend rejected the transaction (valid:false). The transaction stays in unfinished_transactions for retry; the user may have switched accounts or the receipt may be invalid.',\n\n // Storage\n STORAGE_ERROR:\n 'Capacitor Preferences write failed. Check device storage availability; the in-memory state is still updated, only persistence failed.',\n\n // appUserId pre-attach\n INVALID_APP_USER_ID:\n 'appUserId must be an RFC 9562 UUID of any version (e.g. crypto.randomUUID(), or a UUIDv5 over a stable name). Apple requires a UUID for appAccountToken; we enforce the same on Android for consistency. Refused: the nil and max UUIDs, and non-RFC version/variant nibbles — so an id that merely looks like a UUID (a hyphen-formatted hash) will not pass.',\n APP_USER_ID_FETCH_FAILED:\n 'The async appUserId fetcher threw or rejected. Inspect the cause field for the underlying error (network failure, backend non-2xx, parse failure).',\n};\n\n/** Public accessor for the hint text — exported so docs / consumer error UIs can render it. */\nexport function errorHint(code: IAPErrorCode): string {\n return HINTS[code];\n}\n\ninterface IAPErrorOptions {\n code: IAPErrorCode;\n message: string;\n cause?: unknown;\n recoverable?: boolean;\n /**\n * Whether to append the per-code remediation hint to the message.\n * Defaults to `true`. Set `false` only if the caller already includes a\n * hint in `message` (avoids double-tagging).\n */\n includeHint?: boolean;\n}\n\nexport class IAPError extends Error {\n readonly code: IAPErrorCode;\n readonly recoverable: boolean;\n override readonly cause?: unknown;\n\n constructor(options: IAPErrorOptions) {\n const hint = options.includeHint === false ? '' : (HINTS[options.code] ?? '');\n const fullMessage = hint ? `${options.message}\\n\\nHint: ${hint}` : options.message;\n super(fullMessage);\n this.name = 'IAPError';\n this.code = options.code;\n this.cause = options.cause;\n this.recoverable = options.recoverable ?? RECOVERABLE_CODES.has(options.code);\n\n Object.setPrototypeOf(this, IAPError.prototype);\n }\n}\n\nexport function isIAPError(error: unknown): error is IAPError {\n return error instanceof IAPError;\n}\n\n/**\n * Coerce an unknown thrown value into an `IAPError`.\n *\n * - If `error` is already an `IAPError`, return it unchanged (preserves\n * the original code, recoverable flag, and cause chain).\n * - Otherwise wrap with the supplied fallback `code` and `message` and\n * attach the original as `cause`.\n *\n * Used by orchestrators and adapters that catch `unknown` from the JS\n * runtime and need to surface a typed error without losing context.\n */\nexport function toIAPError(\n error: unknown,\n fallbackMessage: string,\n fallbackCode: IAPErrorCode,\n): IAPError {\n if (isIAPError(error)) return error;\n return new IAPError({\n code: fallbackCode,\n message: fallbackMessage,\n cause: error,\n });\n}\n","import { Capacitor } from '@capacitor/core';\n\nexport type RuntimePlatform = 'ios' | 'android' | 'web';\n\nexport function getPlatform(): RuntimePlatform {\n const platform = Capacitor.getPlatform();\n if (platform === 'ios' || platform === 'android') return platform;\n return 'web';\n}\n\nexport function isNative(): boolean {\n const platform = getPlatform();\n return platform === 'ios' || platform === 'android';\n}\n","import { IAPError, IAPErrorCode } from '../../../lib/errors.js';\n\n/**\n * Translate a `purchaseProduct()` rejection into a coded {@link IAPError} so\n * the purchase orchestrator can route it to the right `PurchaseResult` status.\n *\n * `@capgo/native-purchases` rejects with plain message strings — the\n * signals we can distinguish (verified against the plugin's native source):\n * - iOS: `\"User cancelled\"`, `\"Transaction pending\"`,\n * `\"Cannot find product for id <id>\"`.\n * - Android: `\"Purchase is pending\"`, `\"Product not found\"`. Note Android\n * does NOT distinguish user-cancel from other billing errors — both\n * surface as `\"Purchase is not purchased\"`, which falls through to\n * `STORE_ERROR`. The error-handling docs note this asymmetry for\n * consumer UX (treat Android `failed` similarly to `cancelled`).\n */\nexport function mapPurchaseError(error: unknown, productId: string): IAPError {\n if (error instanceof IAPError) return error;\n const message = error instanceof Error ? error.message : String(error);\n const lower = message.toLowerCase();\n\n if (lower.includes('cancel')) {\n return new IAPError({\n code: IAPErrorCode.USER_CANCELLED,\n message: `Purchase of \"${productId}\" was cancelled.`,\n cause: error,\n });\n }\n if (lower.includes('pending')) {\n return new IAPError({\n code: IAPErrorCode.PURCHASE_PENDING,\n message: `Purchase of \"${productId}\" is pending external clearance.`,\n cause: error,\n });\n }\n // iOS uses `\"Cannot find product for id <id>\"`; Android uses\n // `\"Product not found\"`. Match both shapes.\n if (lower.includes('product not found') || lower.includes('cannot find product')) {\n return new IAPError({\n code: IAPErrorCode.PRODUCT_NOT_FOUND,\n message: `Product \"${productId}\" was not found in the store catalog.`,\n cause: error,\n });\n }\n return new IAPError({\n code: IAPErrorCode.STORE_ERROR,\n message: `Native purchase of \"${productId}\" failed.`,\n cause: error,\n });\n}\n","/**\n * Normalizes `@capgo/native-purchases`' subscription-period shape into an\n * ISO 8601 duration string (`P1M`, `P7D`, …).\n *\n * The plugin reports `{ numberOfUnits, unit, unitString? }`, reconstructed\n * from a different source on each platform — StoreKit's\n * `Product.SubscriptionPeriod` on iOS, a parsed Play billing period on\n * Android — so the input is normalized here rather than in core flows.\n *\n * ISO 8601 is the exchange format because it is what Google Play speaks\n * natively, what Apple's App Store Server API emits, and what a consumer can\n * hand to any date library without a per-platform legend.\n */\n\n/**\n * Unit integers. Both platforms emit 0-3 with the same meaning; iOS also\n * emits -1 for a StoreKit unit it does not recognise (Android never does).\n *\n * A `Map`, not an object literal: the key comes off a native bridge, and a\n * plain object would resolve inherited names — a `unitString` of\n * \"constructor\" would otherwise yield the Object constructor and render as\n * \"P1function Object() { [native code] }\".\n */\nconst UNIT_BY_INT: ReadonlyMap<number, string> = new Map([\n [0, 'D'],\n [1, 'W'],\n [2, 'M'],\n [3, 'Y'],\n]);\n\n/** `unitString`, added by the plugin in 8.3.8. Preferred when present. */\nconst UNIT_BY_NAME: ReadonlyMap<string, string> = new Map([\n ['day', 'D'],\n ['week', 'W'],\n ['month', 'M'],\n ['year', 'Y'],\n]);\n\n/**\n * The plugin's period shape, typed loosely on purpose: the value crosses a\n * native bridge, and the plugin's own declarations overstate what is always\n * present (Android sets no top-level `subscriptionPeriod` on a product at\n * all, though the type says it is required).\n */\ninterface NativeSubscriptionPeriod {\n numberOfUnits?: unknown;\n unit?: unknown;\n unitString?: unknown;\n}\n\n/**\n * Convert a native subscription period to an ISO 8601 duration, or `null`\n * when the input does not describe one.\n *\n * `null` covers every \"no usable period\" case, which a caller should treat\n * identically: absent (Android products), the `{ numberOfUnits: 0, unit: 0 }`\n * placeholder both platforms emit for non-subscriptions, an unrecognised\n * unit, or a malformed value.\n */\nexport function toIso8601Duration(period: unknown): string | null {\n if (!period || typeof period !== 'object' || Array.isArray(period)) return null;\n\n const { numberOfUnits, unit, unitString } = period as NativeSubscriptionPeriod;\n\n if (typeof numberOfUnits !== 'number' || !Number.isInteger(numberOfUnits) || numberOfUnits <= 0) {\n return null;\n }\n\n // `unitString` is the explicit field and wins; the integer is the legacy\n // fallback for plugin builds predating 8.3.8, and for the \"unknown\"\n // string, which may still arrive alongside a usable integer.\n const designator =\n (typeof unitString === 'string' ? UNIT_BY_NAME.get(unitString) : undefined) ??\n (typeof unit === 'number' ? UNIT_BY_INT.get(unit) : undefined);\n\n if (!designator) return null;\n\n return `P${numberOfUnits}${designator}`;\n}\n","import type {\n SKProductDiscount as PluginDiscount,\n Product as PluginProduct,\n} from '@capgo/native-purchases';\nimport { toIso8601Duration } from '../../../lib/subscription-period.js';\nimport type {\n ConfiguredProduct,\n Product,\n ProductType,\n SubscriptionOffer,\n SubscriptionOfferPayment,\n SubscriptionOfferType,\n} from '../../../types/product.js';\n\n/**\n * The plugin's `Product`, retyped with what it *actually* delivers.\n *\n * `@capgo/native-purchases` declares `subscriptionPeriod` and\n * `subscriptionGroupIdentifier` as required, but its Android side sets\n * neither — so `p.subscriptionPeriod.unitString` is a TypeError on a real\n * device while typechecking clean. Narrowing them here is the only place\n * that lie is contained.\n */\ntype DeliveredProduct = Omit<\n PluginProduct,\n 'subscriptionPeriod' | 'subscriptionGroupIdentifier' | 'introductoryPrice' | 'discounts'\n> & {\n subscriptionPeriod?: unknown;\n subscriptionGroupIdentifier?: string;\n introductoryPrice?: PluginDiscount | null;\n discounts?: PluginDiscount[];\n};\n\n/**\n * Match the plugin's product payloads back to what the consumer asked for,\n * and return one {@link Product} per request.\n *\n * Two Android quirks make this more than a map():\n *\n * 1. **`identifier` is not the product id for a subscription.** capgo reports\n * `identifier` = the base plan id and `planIdentifier` = the Play product\n * id, while iap queries by product id (what `config.products[].id` holds).\n * Keying on `identifier` alone misses every Android subscription, so the\n * type falls back to `'product'` and the returned `id` is a base plan the\n * consumer never configured — `getProducts().find(p => p.id === …)` then\n * never matches. Resolve through either key, and report the configured id.\n *\n * 2. **One payload per offer.** capgo emits a separate entry for every offer\n * on a base plan, and only the base-plan entry (`offerId === null`) carries\n * `introductoryPrice`/`discounts`. Returned as-is that is several products\n * sharing one id, most with no offers — so collapse to one, preferring the\n * base plan the consumer named and the entry that actually has the offers.\n *\n * A payload matching no request is dropped: an entry the consumer did not ask\n * for is not actionable, and mistyping it is worse than omitting it.\n */\nexport function resolveProducts(\n payloads: PluginProduct[],\n requests: ConfiguredProduct[],\n): Product[] {\n const products: Product[] = [];\n\n for (const request of requests) {\n const candidates = payloads.filter((payload) => {\n const p = payload as DeliveredProduct;\n return p.identifier === request.id || p.planIdentifier === request.id;\n });\n if (candidates.length === 0) continue;\n\n products.push(normalizeProduct(pickCandidate(candidates, request.androidPlanId), request));\n }\n\n return products;\n}\n\n/**\n * Choose among several payloads for one product: the base plan the consumer\n * configured if it is here, then the entry carrying the offers (the base\n * plan, `offerId === null`), else the first the store gave.\n */\nfunction pickCandidate(candidates: PluginProduct[], androidPlanId?: string): PluginProduct {\n const named =\n androidPlanId !== undefined\n ? candidates.find((c) => (c as DeliveredProduct).identifier === androidPlanId)\n : undefined;\n const basePlan = candidates.find((c) => ((c as DeliveredProduct).offerId ?? null) === null);\n // `candidates` is non-empty at both call sites; the index is for the checker.\n return named ?? basePlan ?? (candidates[0] as PluginProduct);\n}\n\nfunction normalizeProduct(raw: PluginProduct, request: { id: string; type: ProductType }): Product {\n const p = raw as DeliveredProduct;\n return {\n // The id the consumer configured, so a Product round-trips to\n // `purchase({ productId })`. On Android `p.identifier` is a base plan,\n // which is reported separately as `androidBasePlanId`.\n id: request.id,\n type: request.type,\n title: p.title,\n description: p.description,\n priceString: p.priceString,\n priceMicros: toMicros(p.price),\n currency: p.currencyCode,\n\n // `toIso8601Duration` returns null for the `{ numberOfUnits: 0, unit: 0 }`\n // placeholder a non-subscription carries, and for Android's absent value.\n subscriptionPeriod: toIso8601Duration(p.subscriptionPeriod),\n // capgo sends \"\" rather than null for a product with no group.\n subscriptionGroupId: p.subscriptionGroupIdentifier || null,\n introductoryOffer: p.introductoryPrice ? normalizeOffer(p.introductoryPrice) : null,\n promotionalOffers: (p.discounts ?? []).map(normalizeOffer),\n androidOfferToken: p.offerToken ?? null,\n androidOfferId: p.offerId ?? null,\n // Android only: the base plan this entry describes. Null on iOS, where\n // `identifier` is the product id and there is no base-plan concept.\n androidBasePlanId: p.planIdentifier !== undefined ? p.identifier : null,\n };\n}\n\n/** Price in micro-units as a string, avoiding float precision loss on render. */\nfunction toMicros(price: number | undefined): string {\n // `Math.round(undefined * 1e6).toString()` is the string \"NaN\", which\n // looks like a price and poisons any arithmetic done with it. A price\n // the store did not send is \"0\"; `priceString` stays the thing to show.\n if (typeof price !== 'number' || !Number.isFinite(price)) return '0';\n return Math.round(price * 1_000_000).toString();\n}\n\nfunction normalizeOffer(discount: PluginDiscount): SubscriptionOffer {\n return {\n // An iOS introductory offer and an Android base-plan intro phase both\n // arrive with an empty identifier; neither is named by its store.\n id: discount.identifier || null,\n type: mapOfferType(discount.type),\n payment: mapOfferPayment(discount.paymentMode),\n priceString: discount.priceString,\n priceMicros: toMicros(discount.price),\n currency: discount.currencyCode,\n period: toIso8601Duration(discount.subscriptionPeriod),\n periodCount: discount.numberOfPeriods,\n };\n}\n\n/** capgo's offer-type integers: introductory=0, promotional=1, winBack=2. */\nfunction mapOfferType(type: number): SubscriptionOfferType {\n switch (type) {\n case 0:\n return 'introductory';\n case 1:\n return 'promotional';\n case 2:\n return 'win-back';\n default:\n // capgo emits -1 for a StoreKit offer type it does not know.\n return 'unknown';\n }\n}\n\n/**\n * Map capgo's `paymentMode` integer.\n *\n * **Read the legend from capgo's code, not from its comment.** capgo's iOS\n * source labels this mapping \"SKProductDiscount.PaymentMode-compatible:\n * freeTrial=0, payUpFront=1, payAsYouGo=2\" — but Apple's actual\n * `SKProductDiscount.PaymentMode` is payAsYouGo=0, payUpFront=1,\n * freeTrial=2. The comment is wrong about Apple; the numbers it emits are\n * what ships, and capgo's Android side independently uses the same order\n * (price 0 → 0, non-recurring → 1, otherwise → 2).\n *\n * So both platforms agree with each other and disagree with the name in the\n * comment. Mapping from Apple's documented legend would report every free\n * trial as pay-as-you-go.\n */\nfunction mapOfferPayment(paymentMode: number): SubscriptionOfferPayment {\n switch (paymentMode) {\n case 0:\n return 'free-trial';\n case 1:\n return 'pay-up-front';\n case 2:\n return 'pay-as-you-go';\n default:\n return 'unknown';\n }\n}\n","/**\n * Reads the claims out of the payload segment of a JWS (JSON Web Signature).\n *\n * Used for one thing: StoreKit 2's `jwsRepresentation`, which carries fields\n * the plugin does not surface as its own — most importantly\n * `originalTransactionId`, the purchase reference that survives renewals\n * (`transactionId` does not).\n *\n * **This performs no cryptographic verification, and must never be mistaken\n * for one.** It decodes; it does not check. That is sound here only because\n * of where the value comes from: `@capgo/native-purchases` resolves a\n * purchase solely for a StoreKit 2 `VerificationResult.verified`, so Apple's\n * signature check has already run in native code before the JWS reaches the\n * WebView. The claims are trustworthy by provenance.\n *\n * It follows that this must not be used on a JWS from anywhere else — a\n * value a consumer received over the network, say. For that, the signature\n * has to be verified server-side against Apple's certificate chain, which is\n * what the backend / Attesto path is for.\n *\n * Never log the return value: a JWS payload is receipt data (PLAN.md §16).\n */\n\n/** Decode a base64url segment to a UTF-8 string, or `null` if it will not. */\nfunction decodeBase64UrlSegment(segment: string): string | null {\n // base64url → base64, then restore the padding atob() requires.\n const base64 = segment.replace(/-/g, '+').replace(/_/g, '/');\n const padded = base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), '=');\n\n let binary: string;\n try {\n binary = atob(padded);\n } catch {\n return null;\n }\n\n // atob() yields one char per byte; anything above U+00FF in the original\n // JSON would be mangled by reading that string directly, so round-trip\n // through the bytes.\n try {\n const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));\n return new TextDecoder('utf-8', { fatal: true }).decode(bytes);\n } catch {\n return null;\n }\n}\n\n/**\n * Return the JWS payload's claims as a plain object, or `null` when the\n * input is not a JWS carrying a JSON object payload.\n *\n * Total by design — every malformed, truncated, non-base64, non-JSON or\n * non-object input resolves to `null` rather than throwing, because the\n * value crosses a native bridge and a bad one must never break a purchase.\n */\nexport function readJwsClaims(jws: string): Record<string, unknown> | null {\n if (typeof jws !== 'string' || jws.length === 0) return null;\n\n const segments = jws.split('.');\n if (segments.length !== 3) return null;\n\n const payload = segments[1];\n if (!payload) return null;\n\n const json = decodeBase64UrlSegment(payload);\n if (json === null) return null;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(json);\n } catch {\n return null;\n }\n\n // Callers index the result by claim name, so an array or a primitive is\n // no more useful than nothing.\n if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return null;\n\n return parsed as Record<string, unknown>;\n}\n","import type { Transaction as PluginTransaction } from '@capgo/native-purchases';\nimport { readJwsClaims } from '../../../lib/jws.js';\nimport { getPlatform } from '../../../lib/platform.js';\nimport type { ConfiguredProduct, ProductType } from '../../../types/product.js';\nimport type {\n NativeTransaction,\n Platform,\n SubscriptionRenewal,\n SubscriptionState,\n} from '../../../types/transaction.js';\n\nexport function normalizeTransaction(\n tx: PluginTransaction,\n productType: ProductType,\n packageName?: string,\n): NativeTransaction {\n const platform = inferPlatform(tx);\n const token = platform === 'google' ? (tx.purchaseToken ?? tx.transactionId) : tx.transactionId;\n\n const native: NativeTransaction = {\n platform,\n productId: tx.productIdentifier,\n token,\n purchaseReference: purchaseReferenceFor(tx, platform, token),\n productType,\n // Lower-cased so it compares equal to what the caller supplied:\n // StoreKit returns `UUID.uuidString`, which Swift renders uppercase,\n // while `crypto.randomUUID()` and iap's case-insensitive validator both\n // deal in lowercase. Returned raw, the binding would never `===` the\n // value that was sent — the one comparison this field exists for.\n appUserId: tx.appAccountToken?.toLowerCase() ?? null,\n subscription: normalizeSubscription(tx, productType),\n raw: tx,\n };\n\n // The plugin's Transaction shape has no packageName, and Google's\n // verification APIs are keyed on it — so it comes from\n // `config.android.packageName` and is stamped on here. Without it the\n // verify and restore requests cannot be built at all, which is why\n // omitting it is a config error rather than a silent degradation.\n if (native.platform === 'google' && packageName) {\n native.packageName = packageName;\n }\n\n return native;\n}\n\n/**\n * The reference that survives renewals.\n *\n * Google's `purchaseToken` already is one. Apple's `transactionId` is not —\n * it changes on every renewal — and the plugin does not expose\n * `originalTransactionId` as a field, so it is read out of the signed JWS\n * payload. That decode is for data only; Apple's signature was already\n * verified natively (see {@link readJwsClaims}).\n *\n * Falls back to `token` whenever the claim is unavailable, so the field is\n * always populated and a malformed JWS can never fail a purchase.\n */\nfunction purchaseReferenceFor(tx: PluginTransaction, platform: Platform, token: string): string {\n if (platform === 'google' || !tx.jwsRepresentation) return token;\n\n const claims = readJwsClaims(tx.jwsRepresentation);\n const original = claims?.originalTransactionId;\n return typeof original === 'string' && original.length > 0 ? original : token;\n}\n\n/**\n * capgo's `subscriptionState` strings, hyphenated to iap's own vocabulary.\n *\n * A `Map`, not an object literal: the key arrives off a native bridge, and\n * a plain object resolves inherited names — looking up 'constructor' would\n * return a function, so the `?? 'unknown'` fallback would not fire and\n * `state` would be a function at runtime while typed as a string union.\n */\nconst SUBSCRIPTION_STATES: ReadonlyMap<string, SubscriptionState> = new Map([\n ['subscribed', 'subscribed'],\n ['expired', 'expired'],\n ['revoked', 'revoked'],\n ['inGracePeriod', 'in-grace-period'],\n ['inBillingRetryPeriod', 'in-billing-retry'],\n ['unknown', 'unknown'],\n]);\n\n/**\n * Renewal detail, or `null` when there is none to report.\n *\n * In practice this is iOS-only: on Android the plugin exposes no\n * subscription state, no expiry and no renewal info, and always sends\n * `willCancel: null` — so every field would be null, and a renewal object\n * full of nulls is worse than none. Returning `null` says \"ask the server\",\n * which is the correct answer on Android.\n */\nfunction normalizeSubscription(\n tx: PluginTransaction,\n productType: ProductType,\n): SubscriptionRenewal | null {\n if (productType !== 'subscription') return null;\n\n const renewalInfo = tx.renewalInfo;\n const state = tx.subscriptionState\n ? (SUBSCRIPTION_STATES.get(tx.subscriptionState) ?? 'unknown')\n : null;\n\n // `willAutoRenew` is the direct answer; `willCancel` is its inverse and\n // the only signal older builds and some states provide.\n const autoRenewing =\n renewalInfo?.willAutoRenew ?? (typeof tx.willCancel === 'boolean' ? !tx.willCancel : null);\n\n const renewal: SubscriptionRenewal = {\n state,\n autoRenewing,\n renewsAt: renewalInfo?.renewalDate ?? null,\n renewalProductId: renewalInfo?.autoRenewProductId ?? null,\n expiresAt: tx.expirationDate ?? null,\n };\n\n // Nothing was reported — say so, rather than handing back all-nulls.\n const reportedNothing =\n renewal.state === null &&\n renewal.autoRenewing === null &&\n renewal.renewsAt === null &&\n renewal.renewalProductId === null &&\n renewal.expiresAt === null;\n\n return reportedNothing ? null : renewal;\n}\n\nfunction inferPlatform(tx: PluginTransaction): Platform {\n if (\n tx.purchaseToken !== undefined ||\n tx.purchaseState !== undefined ||\n tx.orderId !== undefined\n ) {\n return 'google';\n }\n if (tx.receipt !== undefined || tx.jwsRepresentation !== undefined) {\n return 'apple';\n }\n // Fall back to runtime platform.\n return getPlatform() === 'android' ? 'google' : 'apple';\n}\n\n/**\n * The product type of a transaction the *store* reported.\n *\n * The **store's family is authoritative**, and the catalog only refines\n * within it. The store knows whether it sold a subscription, because the\n * payload comes out of the subscription query or the in-app one. What it\n * cannot say is which kind of in-app purchase: `'inapp'` covers consumables\n * and one-time purchases alike, and that difference decides whether iap\n * acknowledges the transaction or consumes it. A consumable mistyped as\n * `'product'` is acknowledged but never consumed, so Play keeps reporting it\n * owned and `purchase()` of it fails `ALREADY_PURCHASED` for good — the user\n * paid for something they can never buy again.\n *\n * The order matters the other way round too, and more dangerously. Letting\n * the catalog override `'subs'` would let one wrong `type` — in a hand-written\n * config, or in a stale `backend.listProducts()` manifest, which is validated\n * for shape only — turn a subscription into a `'product'`. `normalizeTransaction`\n * drops the whole `subscription` block for a non-subscription, so the\n * transaction would arrive with no expiry and no renewal state, and an\n * on-device check would read \"does not expire\" and grant an expired\n * subscription indefinitely.\n */\nexport function inferProductType(\n tx: PluginTransaction,\n configured?: readonly ConfiguredProduct[],\n): ProductType {\n if (tx.productType === 'subs') return 'subscription';\n\n const declared = configured?.find((p) => p.id === tx.productIdentifier)?.type;\n // Only `'consumable'` is a refinement of `'inapp'`. Anything else the\n // catalog says — including `'subscription'`, which the store has just\n // contradicted — leaves the store's answer standing.\n return declared === 'consumable' ? 'consumable' : 'product';\n}\n","/**\n * ISO 3166-1 country-code normalization.\n *\n * Apple's StoreKit storefront `countryCode` is **alpha-3** (`\"USA\"`), while\n * Google Play's `BillingConfig.countryCode` is **alpha-2** (`\"US\"`). The\n * storefront layer normalizes to a single scheme (alpha-2 — what Android, both\n * server APIs, and Apple's external-purchase Info.plist keys all use) so\n * consumers compare one consistent value across platforms instead of inheriting\n * the per-platform split every other SDK leaks. Static, dependency-free, no\n * network.\n */\n\n/** ISO 3166-1 alpha-3 → alpha-2. Current assignments (as of 2026). */\nconst ALPHA3_TO_ALPHA2: Record<string, string> = {\n ABW: 'AW',\n AFG: 'AF',\n AGO: 'AO',\n AIA: 'AI',\n ALA: 'AX',\n ALB: 'AL',\n AND: 'AD',\n ARE: 'AE',\n ARG: 'AR',\n ARM: 'AM',\n ASM: 'AS',\n ATA: 'AQ',\n ATF: 'TF',\n ATG: 'AG',\n AUS: 'AU',\n AUT: 'AT',\n AZE: 'AZ',\n BDI: 'BI',\n BEL: 'BE',\n BEN: 'BJ',\n BES: 'BQ',\n BFA: 'BF',\n BGD: 'BD',\n BGR: 'BG',\n BHR: 'BH',\n BHS: 'BS',\n BIH: 'BA',\n BLM: 'BL',\n BLR: 'BY',\n BLZ: 'BZ',\n BMU: 'BM',\n BOL: 'BO',\n BRA: 'BR',\n BRB: 'BB',\n BRN: 'BN',\n BTN: 'BT',\n BVT: 'BV',\n BWA: 'BW',\n CAF: 'CF',\n CAN: 'CA',\n CCK: 'CC',\n CHE: 'CH',\n CHL: 'CL',\n CHN: 'CN',\n CIV: 'CI',\n CMR: 'CM',\n COD: 'CD',\n COG: 'CG',\n COK: 'CK',\n COL: 'CO',\n COM: 'KM',\n CPV: 'CV',\n CRI: 'CR',\n CUB: 'CU',\n CUW: 'CW',\n CXR: 'CX',\n CYM: 'KY',\n CYP: 'CY',\n CZE: 'CZ',\n DEU: 'DE',\n DJI: 'DJ',\n DMA: 'DM',\n DNK: 'DK',\n DOM: 'DO',\n DZA: 'DZ',\n ECU: 'EC',\n EGY: 'EG',\n ERI: 'ER',\n ESH: 'EH',\n ESP: 'ES',\n EST: 'EE',\n ETH: 'ET',\n FIN: 'FI',\n FJI: 'FJ',\n FLK: 'FK',\n FRA: 'FR',\n FRO: 'FO',\n FSM: 'FM',\n GAB: 'GA',\n GBR: 'GB',\n GEO: 'GE',\n GGY: 'GG',\n GHA: 'GH',\n GIB: 'GI',\n GIN: 'GN',\n GLP: 'GP',\n GMB: 'GM',\n GNB: 'GW',\n GNQ: 'GQ',\n GRC: 'GR',\n GRD: 'GD',\n GRL: 'GL',\n GTM: 'GT',\n GUF: 'GF',\n GUM: 'GU',\n GUY: 'GY',\n HKG: 'HK',\n HMD: 'HM',\n HND: 'HN',\n HRV: 'HR',\n HTI: 'HT',\n HUN: 'HU',\n IDN: 'ID',\n IMN: 'IM',\n IND: 'IN',\n IOT: 'IO',\n IRL: 'IE',\n IRN: 'IR',\n IRQ: 'IQ',\n ISL: 'IS',\n ISR: 'IL',\n ITA: 'IT',\n JAM: 'JM',\n JEY: 'JE',\n JOR: 'JO',\n JPN: 'JP',\n KAZ: 'KZ',\n KEN: 'KE',\n KGZ: 'KG',\n KHM: 'KH',\n KIR: 'KI',\n KNA: 'KN',\n KOR: 'KR',\n KWT: 'KW',\n LAO: 'LA',\n LBN: 'LB',\n LBR: 'LR',\n LBY: 'LY',\n LCA: 'LC',\n LIE: 'LI',\n LKA: 'LK',\n LSO: 'LS',\n LTU: 'LT',\n LUX: 'LU',\n LVA: 'LV',\n MAC: 'MO',\n MAF: 'MF',\n MAR: 'MA',\n MCO: 'MC',\n MDA: 'MD',\n MDG: 'MG',\n MDV: 'MV',\n MEX: 'MX',\n MHL: 'MH',\n MKD: 'MK',\n MLI: 'ML',\n MLT: 'MT',\n MMR: 'MM',\n MNE: 'ME',\n MNG: 'MN',\n MNP: 'MP',\n MOZ: 'MZ',\n MRT: 'MR',\n MSR: 'MS',\n MTQ: 'MQ',\n MUS: 'MU',\n MWI: 'MW',\n MYS: 'MY',\n MYT: 'YT',\n NAM: 'NA',\n NCL: 'NC',\n NER: 'NE',\n NFK: 'NF',\n NGA: 'NG',\n NIC: 'NI',\n NIU: 'NU',\n NLD: 'NL',\n NOR: 'NO',\n NPL: 'NP',\n NRU: 'NR',\n NZL: 'NZ',\n OMN: 'OM',\n PAK: 'PK',\n PAN: 'PA',\n PCN: 'PN',\n PER: 'PE',\n PHL: 'PH',\n PLW: 'PW',\n PNG: 'PG',\n POL: 'PL',\n PRI: 'PR',\n PRK: 'KP',\n PRT: 'PT',\n PRY: 'PY',\n PSE: 'PS',\n PYF: 'PF',\n QAT: 'QA',\n REU: 'RE',\n ROU: 'RO',\n RUS: 'RU',\n RWA: 'RW',\n SAU: 'SA',\n SDN: 'SD',\n SEN: 'SN',\n SGP: 'SG',\n SGS: 'GS',\n SHN: 'SH',\n SJM: 'SJ',\n SLB: 'SB',\n SLE: 'SL',\n SLV: 'SV',\n SMR: 'SM',\n SOM: 'SO',\n SPM: 'PM',\n SRB: 'RS',\n SSD: 'SS',\n STP: 'ST',\n SUR: 'SR',\n SVK: 'SK',\n SVN: 'SI',\n SWE: 'SE',\n SWZ: 'SZ',\n SXM: 'SX',\n SYC: 'SC',\n SYR: 'SY',\n TCA: 'TC',\n TCD: 'TD',\n TGO: 'TG',\n THA: 'TH',\n TJK: 'TJ',\n TKL: 'TK',\n TKM: 'TM',\n TLS: 'TL',\n TON: 'TO',\n TTO: 'TT',\n TUN: 'TN',\n TUR: 'TR',\n TUV: 'TV',\n TWN: 'TW',\n TZA: 'TZ',\n UGA: 'UG',\n UKR: 'UA',\n UMI: 'UM',\n URY: 'UY',\n USA: 'US',\n UZB: 'UZ',\n VAT: 'VA',\n VCT: 'VC',\n VEN: 'VE',\n VGB: 'VG',\n VIR: 'VI',\n VNM: 'VN',\n VUT: 'VU',\n WLF: 'WF',\n WSM: 'WS',\n YEM: 'YE',\n ZAF: 'ZA',\n ZMB: 'ZM',\n ZWE: 'ZW',\n};\n\n/**\n * Normalize an ISO 3166-1 country code to alpha-2.\n *\n * - A 2-letter code (Google Play already returns alpha-2) is passed through,\n * uppercased.\n * - A 3-letter code (Apple StoreKit returns alpha-3) is mapped to alpha-2.\n * - Anything else — empty, malformed, or an unrecognized alpha-3 — returns\n * `null`, letting the caller decide on a fallback.\n */\nexport function toAlpha2(code: string): string | null {\n if (!code) return null;\n const normalized = code.trim().toUpperCase();\n if (normalized.length === 2) return normalized;\n if (normalized.length === 3) return ALPHA3_TO_ALPHA2[normalized] ?? null;\n return null;\n}\n","import { Capacitor } from '@capacitor/core';\nimport { NativePurchases } from '@capgo/native-purchases';\nimport { toAlpha2 } from '../../../lib/iso-country.js';\nimport { getPlatform } from '../../../lib/platform.js';\nimport type { Storefront } from '../../../types/storefront.js';\nimport type { Platform } from '../../../types/transaction.js';\n\n/** Raw storefront shape the plugin `getStorefront` resolves to. */\ntype NativeStorefront = { countryCode?: string; storefrontId?: string };\n\n/**\n * The plugin surface for `getStorefront`, declared locally because some\n * installed `@capgo/native-purchases` builds predate it. Availability is\n * detected via the Capacitor plugin header (see {@link nativeStorefrontRegistered}),\n * NOT by inspecting this optional method: on a device `registerPlugin` returns\n * a Proxy that fabricates a function for any property name, so a `typeof\n * np.getStorefront === 'function'` check is always true and would not detect\n * an older plugin.\n */\ntype StorefrontCapablePlugin = {\n getStorefront?: () => Promise<NativeStorefront>;\n};\n\n/** Minimal shape of the Capacitor plugin-header registry we read. */\ntype CapacitorPluginHeaders = {\n PluginHeaders?: ReadonlyArray<{ name: string; methods?: ReadonlyArray<{ name: string }> }>;\n};\n\n/**\n * Whether the *native* `@capgo/native-purchases` build actually registered a\n * `getStorefront` method. Reads the Capacitor plugin header (the list the\n * native bridge injects) so older plugins resolve `null` without crossing the\n * bridge (which would log a native \"not implemented\" error on every call), and\n * the method lights up automatically once capgo ships it.\n */\nexport function nativeStorefrontRegistered(): boolean {\n const headers = (Capacitor as CapacitorPluginHeaders).PluginHeaders;\n return (\n headers\n ?.find((h) => h.name === 'NativePurchases')\n ?.methods?.some((m) => m.name === 'getStorefront') ?? false\n );\n}\n\nexport function normalizeStorefront(raw: NativeStorefront): Storefront | null {\n const code = raw?.countryCode?.trim();\n if (!code) return null;\n\n const platform: Platform = getPlatform() === 'android' ? 'google' : 'apple';\n return {\n // alpha-2 when recognized; otherwise the uppercased raw code as a\n // best-effort fallback (see `Storefront.countryCode`).\n countryCode: toAlpha2(code) ?? code.toUpperCase(),\n countryCodeRaw: code,\n storefrontId: raw.storefrontId,\n platform,\n };\n}\n\n/**\n * Read the current storefront from the native plugin — which sources it from\n * StoreKit 2 `Storefront.current` on iOS and `getBillingConfigAsync()` on\n * Android — normalizing `countryCode` to alpha-2.\n *\n * Silent by design: every form of unavailability — an older plugin with no\n * native method registered, a native rejection, an empty country — resolves\n * to `null` rather than throwing.\n */\nexport async function readStorefront(): Promise<Storefront | null> {\n if (!nativeStorefrontRegistered()) return null;\n const np = NativePurchases as typeof NativePurchases & StorefrontCapablePlugin;\n try {\n const raw = await np.getStorefront?.();\n return raw ? normalizeStorefront(raw) : null;\n } catch {\n return null;\n }\n}\n","import { NativePurchases } from '@capgo/native-purchases';\nimport type { Logger } from '../../../lib/logger.js';\nimport { getPlatform } from '../../../lib/platform.js';\nimport type { ConfiguredProduct } from '../../../types/product.js';\nimport type { NativeTransaction } from '../../../types/transaction.js';\nimport type { TransactionWatchHandle } from '../types.js';\nimport { inferProductType, normalizeTransaction } from './normalize-transaction.js';\n\n/**\n * Subscribe to the plugin's transaction feed.\n *\n * **iOS only, in practice.** The plugin emits `transactionUpdated` from\n * Apple's `Transaction.updates` and has no Android equivalent — the Android\n * side notifies no listeners at all (asserted in\n * `tests/unit/native-plugin-contract.test.ts`). The listener is registered on\n * both platforms anyway: it costs nothing on Android, and it lights up on its\n * own if capgo ever adds the event.\n *\n * Also subscribes to `transactionVerificationFailed`, which fires when\n * StoreKit hands the plugin an unverified transaction. That one is logged\n * rather than surfaced as an event: its payload carries a transaction id and\n * an error string but **no product id**, and iap's `verification-failed`\n * event requires one. A half-populated event would be worse than a log.\n */\nexport async function watchCapgoTransactions(\n onUpdate: (transaction: NativeTransaction) => void,\n logger: Logger,\n packageName?: string,\n /**\n * The catalog, so this feed's transactions carry the same `productType`\n * the owned-set path gives them — which reaches the backend's verify\n * request and the `transaction-updated` event.\n *\n * It does not change acknowledge-vs-consume today: this feed is iOS-only\n * in practice (above), and iOS always acknowledges. It would, if capgo\n * ever adds the Android event.\n */\n getConfiguredProducts?: () => readonly ConfiguredProduct[],\n): Promise<TransactionWatchHandle | null> {\n const handles: Array<{ remove(): Promise<void> }> = [];\n\n try {\n handles.push(\n await NativePurchases.addListener('transactionUpdated', (tx) => {\n // This runs on a native callback. A throw here has nowhere useful to\n // go — it would surface as an unhandled rejection in the bridge, or\n // be swallowed — so it stops at the boundary.\n try {\n onUpdate(\n normalizeTransaction(tx, inferProductType(tx, getConfiguredProducts?.()), packageName),\n );\n } catch (error) {\n logger.warn('transactionUpdated handler threw; ignoring the update.', error);\n }\n }),\n );\n } catch (error) {\n logger.warn(\n 'Could not subscribe to native transaction updates; renewals and refunds will be picked up at the next launch or resume instead.',\n error,\n );\n return null;\n }\n\n try {\n handles.push(\n await NativePurchases.addListener('transactionVerificationFailed', (payload) => {\n // Never log the transaction id: it is a receipt identifier.\n logger.warn(\n `The store reported a transaction that failed Apple's verification; ignoring it. Reason: ${payload.error}`,\n );\n }),\n );\n } catch (error) {\n // Non-fatal: the update listener above is the one that matters.\n logger.debug('Could not subscribe to transactionVerificationFailed.', error);\n }\n\n return {\n async remove() {\n for (const handle of handles) {\n try {\n await handle.remove();\n } catch (error) {\n logger.warn('Failed to remove a native transaction listener.', error);\n }\n }\n },\n };\n}\n\n/**\n * Product ids with a purchase awaiting clearance, or `null` when the\n * platform cannot say.\n *\n * Android only, and the state check here is the inverse of the one\n * {@link CapgoNativeAdapter.getOwnedTransactions} applies — a pending\n * purchase is precisely one the store has but does not call owned.\n *\n * **Do not read the state constants from the plugin's `.d.ts`.** It says\n * `\"0\": Payment pending`, which is wrong. The value is Play's own\n * `Purchase.PurchaseState` int, stringified verbatim by the plugin\n * (`String.valueOf(purchase.getPurchaseState())`), and in\n * `com.android.billingclient:billing` that enum is\n * `UNSPECIFIED_STATE = 0, PURCHASED = 1, PENDING = 2`. Filtering on `'0'`\n * matches nothing Play ever emits — `getPurchaseState()` returns only 1 or 2 —\n * so it would report every pending purchase as having vanished.\n *\n * Expressed as \"has it, does not own it\" rather than `=== '2'` so that\n * `UNSPECIFIED_STATE`, and any state Play adds later, also count as\n * not-yet-granted rather than as gone.\n *\n * iOS resolves `null`, not `[]`, and the difference matters: StoreKit gives\n * no way to enumerate deferred purchases, so \"nothing pending\" is not\n * something iap can observe there. Returning `[]` would let the caller\n * conclude a deferred purchase had been cancelled while the parent was\n * still deciding.\n */\nexport async function getCapgoPendingProductIds(logger: Logger): Promise<string[] | null> {\n if (getPlatform() !== 'android') return null;\n\n try {\n const result = await NativePurchases.getPurchases();\n return result.purchases\n .filter((tx) => tx.purchaseState !== undefined && tx.purchaseState !== '1')\n .map((tx) => tx.productIdentifier);\n } catch (error) {\n // Cannot tell, which is not the same as nothing pending.\n logger.warn('Could not read pending purchases from the store.', error);\n return null;\n }\n}\n","import {\n NativePurchases,\n PURCHASE_TYPE,\n type Product as PluginProduct,\n type Transaction as PluginTransaction,\n} from '@capgo/native-purchases';\nimport { IAPError, IAPErrorCode } from '../../../lib/errors.js';\nimport type { Logger } from '../../../lib/logger.js';\nimport type { ConfiguredProduct, Product, ProductType } from '../../../types/product.js';\nimport type { Storefront } from '../../../types/storefront.js';\nimport type { NativeTransaction } from '../../../types/transaction.js';\nimport type { NativeAdapter, NativePurchaseOptions, TransactionWatchHandle } from '../types.js';\nimport { mapPurchaseError } from './map-purchase-error.js';\nimport { resolveProducts } from './normalize-product.js';\nimport { inferProductType, normalizeTransaction } from './normalize-transaction.js';\nimport { readStorefront } from './storefront.js';\nimport { getCapgoPendingProductIds, watchCapgoTransactions } from './watch-transactions.js';\n\n/**\n * Capacitor 8 adapter for the `@capgo/native-purchases` `^8` line (this is the\n * `8.x` line of `@nosslabs/iap`; Cap-7 consumers stay on `7.x`). The v8 plugin\n * is additive over the 7.16.x surface captured in\n * `docs/internal/plugin-v7-api.md` — every method that capture lists keeps\n * its 7.16.2 signature. It is no longer the *whole* of what this adapter\n * calls, though: `getStorefront()` and `consumePurchase()` are both v8-only\n * additions absent from it, and the peer range's floor is the version that\n * added the second (`8.2.0`).\n *\n * Plugin contract (relevant bits):\n * - `purchaseProduct({ ..., autoAcknowledgePurchases: false })` defers finishing on\n * both iOS and Android (since v7) — this is the foundation of the\n * \"never grant entitlement before backend confirms\" guarantee, with no\n * iOS-specific finish-before-verify race.\n * - `acknowledgePurchase({ purchaseToken })` is cross-platform (since v7.14.0).\n * - `consumePurchase({ purchaseToken })` (since 8.2.0) is Android-only and\n * both acknowledges and releases ownership, which is the only way a\n * consumable can be bought again. iap never passes the plugin's\n * `isConsumable` flag, because the plugin acts on it inside the purchase\n * callback regardless of `autoAcknowledgePurchases` — see\n * {@link CapgoNativeAdapter.purchaseProduct}.\n * For iOS, pass the `transactionId` as a string in the `purchaseToken` arg —\n * under the hood it calls `Transaction.finish()`. Stateless: no transaction\n * object to retain, so this adapter holds no internal state and needs no\n * long-lived listeners.\n * - `getPurchases()` returns owned transactions, but with a platform quirk\n * worth knowing: on iOS it bundles `Transaction.currentEntitlements`\n * *plus* `Transaction.all` (full history including expired/revoked\n * subscriptions); on Android it returns Google Play's owned set, and\n * {@link CapgoNativeAdapter.getOwnedTransactions} filters out PENDING\n * purchases (`purchaseState !== '1'`). The library passes whatever\n * survives that filter to `backend.restore()`; the backend is the source\n * of truth for \"is this receipt currently valid\" and is expected to\n * tolerate historical iOS entries gracefully.\n */\nexport class CapgoNativeAdapter implements NativeAdapter {\n /**\n * @param logger used by the best-effort paths that swallow their failures.\n * @param packageName the app's Android applicationId, from\n * `config.android.packageName`. Stamped onto every Google transaction\n * because the plugin does not report it and Google's verification\n * APIs are keyed on it.\n * @param getConfiguredProducts the catalog, for typing a transaction the\n * store reported — the plugin's payload cannot distinguish a consumable\n * from a one-time purchase, since Play calls both `'inapp'`.\n */\n constructor(\n private readonly logger: Logger,\n private readonly packageName?: string,\n private readonly getConfiguredProducts?: () => readonly ConfiguredProduct[],\n ) {}\n\n /**\n * The configured catalog, for typing a transaction the store reported.\n *\n * An empty one is not benign: every store-reported consumable would type\n * as `'product'`, be acknowledged rather than consumed, and stay owned —\n * which is the bug the catalog exists to prevent, reachable by\n * misconfiguration rather than by code. Warned once, since\n * `getOwnedTransactions` runs on every refresh.\n */\n private configured(): readonly ConfiguredProduct[] {\n const products = this.getConfiguredProducts?.() ?? [];\n if (products.length === 0 && !this.warnedAboutEmptyCatalog) {\n this.warnedAboutEmptyCatalog = true;\n this.logger.warn(\n 'The native adapter has no configured products, so a purchase the store reports cannot be recognised as a consumable and will be acknowledged rather than consumed — leaving it owned and unbuyable. This is a wiring problem inside iap; please report it.',\n );\n }\n return products;\n }\n\n private warnedAboutEmptyCatalog = false;\n\n async isAvailable(): Promise<boolean> {\n try {\n const result = await NativePurchases.isBillingSupported();\n return result.isBillingSupported;\n } catch {\n return false;\n }\n }\n\n async getProducts(requests: ConfiguredProduct[]): Promise<Product[]> {\n if (requests.length === 0) return [];\n\n const inappIds: string[] = [];\n const subsIds: string[] = [];\n\n for (const req of requests) {\n if (req.type === 'subscription') {\n subsIds.push(req.id);\n } else {\n inappIds.push(req.id);\n }\n }\n\n const [inapp, subs] = await Promise.all([\n inappIds.length > 0\n ? NativePurchases.getProducts({\n productIdentifiers: inappIds,\n productType: PURCHASE_TYPE.INAPP,\n })\n : Promise.resolve({ products: [] as PluginProduct[] }),\n subsIds.length > 0\n ? NativePurchases.getProducts({\n productIdentifiers: subsIds,\n productType: PURCHASE_TYPE.SUBS,\n })\n : Promise.resolve({ products: [] as PluginProduct[] }),\n ]);\n\n const all = [...inapp.products, ...subs.products];\n return resolveProducts(all, requests);\n }\n\n async purchaseProduct(opts: NativePurchaseOptions): Promise<NativeTransaction> {\n const purchaseType = mapToPluginPurchaseType(opts.productType);\n\n let tx: PluginTransaction;\n try {\n tx = await NativePurchases.purchaseProduct({\n productIdentifier: opts.productId,\n productType: purchaseType,\n planIdentifier: opts.androidPlanId,\n appAccountToken: opts.appAccountToken,\n // `false` even for a consumable, and this is load-bearing.\n //\n // `autoAcknowledgePurchases: false` does **not** cover the\n // consumable case: the plugin's `PurchaseActionDecider` returns\n // CONSUME whenever `isConsumable` is set, and its caller consumes\n // without consulting `autoAcknowledgePurchases` — that flag is only\n // read on the ACKNOWLEDGE branch. (Checked in the plugin's Java,\n // not its docs, and guarded by a test in\n // `tests/unit/native-plugin-contract.test.ts`.)\n //\n // So passing `true` here would have the plugin consume inside the\n // purchase callback, before iap has verified anything — breaking\n // acknowledge-only-after-verification for exactly the product type\n // where it cannot be undone, since Billing 8.x drops a consumed\n // purchase from `getPurchases()` entirely. iap consumes itself,\n // after verification, via {@link CapgoNativeAdapter.consume}.\n isConsumable: false,\n autoAcknowledgePurchases: false,\n });\n } catch (error) {\n throw mapPurchaseError(error, opts.productId);\n }\n\n return normalizeTransaction(tx, opts.productType, this.packageName);\n }\n\n async getOwnedTransactions(): Promise<NativeTransaction[]> {\n const result = await NativePurchases.getPurchases();\n return (\n result.purchases\n // Keep only Android PURCHASED purchases; iOS has no purchaseState.\n // A pending Play purchase isn't owned yet — sending it to the\n // backend's /restore would only get rejected. Note Play's enum is\n // UNSPECIFIED_STATE=0, PURCHASED=1, PENDING=2 — the plugin's own\n // .d.ts claims 0 means pending and is wrong; keeping only '1' is\n // correct regardless. (iOS-side\n // expired/revoked subs are NOT filtered here — they're part of\n // `Transaction.all` per the class-level JSDoc; the backend decides.)\n .filter((tx) => tx.purchaseState === undefined || tx.purchaseState === '1')\n .map((tx) =>\n normalizeTransaction(tx, inferProductType(tx, this.configured()), this.packageName),\n )\n );\n }\n\n async acknowledge(transaction: NativeTransaction): Promise<void> {\n try {\n await NativePurchases.acknowledgePurchase({\n purchaseToken: transaction.token,\n });\n } catch (error) {\n throw new IAPError({\n code: IAPErrorCode.STORE_ERROR,\n message: `Failed to acknowledge transaction for ${transaction.productId}.`,\n cause: error,\n recoverable: true,\n });\n }\n }\n\n /**\n * Consume an Android consumable, releasing ownership so it can be bought\n * again. See {@link NativeAdapter.consume} for why acknowledging is not\n * enough.\n *\n * The plugin rejects this on iOS and web, so the core calls it only for\n * Google transactions.\n */\n async consume(transaction: NativeTransaction): Promise<void> {\n try {\n await NativePurchases.consumePurchase({\n purchaseToken: transaction.token,\n });\n } catch (error) {\n throw new IAPError({\n code: IAPErrorCode.STORE_ERROR,\n message: `Failed to consume transaction for ${transaction.productId}.`,\n cause: error,\n // Retried by the recovery loop like a failed acknowledge: until it\n // succeeds, Play still reports the product owned and the user\n // cannot buy it again.\n recoverable: true,\n });\n }\n }\n\n async manageSubscriptions(): Promise<void> {\n try {\n await NativePurchases.manageSubscriptions();\n } catch (error) {\n // No `recoverable: true` here (unlike acknowledge()): this is a UI\n // navigation action, not a transaction-lifecycle step, so there's\n // nothing for the recovery loop to retry.\n throw new IAPError({\n code: IAPErrorCode.STORE_ERROR,\n message: 'Failed to open the native subscription management UI.',\n cause: error,\n });\n }\n }\n\n /**\n * Read the current storefront from the native plugin — which is expected to\n * source it from StoreKit 2 `Storefront.current` on iOS (alpha-3) and\n * `getBillingConfigAsync()` on Android (alpha-2) — normalizing `countryCode`\n * to alpha-2. Silent like {@link CapgoNativeAdapter.isAvailable}: any\n * unavailability — older plugin (no native method registered), native\n * rejection, or empty country — resolves to `null` rather than throwing.\n */\n async getStorefront(): Promise<Storefront | null> {\n return readStorefront();\n }\n\n /**\n * Subscribe to Apple's `Transaction.updates`. See\n * {@link watchCapgoTransactions} — iOS only in practice, and silent\n * about its own failures, since a missing listener degrades to\n * reconciliation rather than breaking anything.\n */\n async watchTransactions(\n onUpdate: (transaction: NativeTransaction) => void,\n ): Promise<TransactionWatchHandle | null> {\n return watchCapgoTransactions(onUpdate, this.logger, this.packageName, () => this.configured());\n }\n\n /** Android only; `null` on iOS. See {@link getCapgoPendingProductIds}. */\n async getPendingProductIds(): Promise<string[] | null> {\n return getCapgoPendingProductIds(this.logger);\n }\n\n async dispose(): Promise<void> {\n // No-op: this adapter owns no long-lived listeners or timers.\n }\n}\n\nfunction mapToPluginPurchaseType(type: ProductType): PURCHASE_TYPE {\n return type === 'subscription' ? PURCHASE_TYPE.SUBS : PURCHASE_TYPE.INAPP;\n}\n","import type { LocallyVerifiedPurchase } from '../../core/local-verification.js';\nimport { IAPError, IAPErrorCode } from '../../lib/errors.js';\nimport type { Logger } from '../../lib/logger.js';\nimport type { IAPConfig } from '../../types/config.js';\nimport type { EntitlementBase } from '../../types/entitlement.js';\nimport type { ConfiguredProduct } from '../../types/product.js';\nimport type { NativeAdapter } from '../native/types.js';\nimport { HttpBackendAdapter } from './http-adapter.js';\nimport { LocalVerificationAdapter } from './local-adapter.js';\nimport { type BackendAdapter, isBackendAdapter } from './types.js';\n\nexport interface BackendAdapterOptions {\n config: IAPConfig;\n logger: Logger;\n /**\n * Resolved lazily for local mode, which reads what the store owns. The\n * native adapter is constructed in `initialize()`, after this.\n */\n getNativeAdapter?: () => NativeAdapter | null;\n getProducts?: () => readonly ConfiguredProduct[];\n /** Current entitlements, so an ambiguous store answer preserves them. */\n getCurrentEntitlements?: () => EntitlementBase[];\n /** Test/override hook. Otherwise uses globalThis.fetch. */\n fetch?: typeof fetch;\n}\n\n/**\n * Build the active `BackendAdapter`.\n *\n * - If `config.adapter` is provided, validates the shape and returns it directly.\n * - Otherwise, builds an {@link HttpBackendAdapter} from the HTTP-specific config.\n *\n * Schema-level validation already enforces that HTTP fields are present when\n * no adapter is provided (see `backendConfigSchema.superRefine`); this\n * function still re-checks at runtime for defense-in-depth.\n */\nexport function selectBackendAdapter<TEntitlement extends EntitlementBase = EntitlementBase>(\n options: BackendAdapterOptions,\n): BackendAdapter<TEntitlement> {\n const { config: iapConfig, logger, fetch: fetchImpl } = options;\n\n // Local mode: verify on the device. Still an adapter, so the purchase and\n // recovery flows above it are unchanged — see `LocalVerificationAdapter`.\n if (iapConfig.verification) {\n const verification = iapConfig.verification;\n return new LocalVerificationAdapter<TEntitlement>({\n getNativeAdapter: options.getNativeAdapter ?? (() => null),\n getProducts: options.getProducts ?? (() => iapConfig.products ?? []),\n entitlements: verification.entitlements as (\n purchase: LocallyVerifiedPurchase,\n ) => TEntitlement[],\n // Passed only when the app actually binds purchases: the adapter\n // reads \"no resolver\" as \"no binding required\", and a resolver\n // returning null as \"required, but nobody is signed in\".\n ...(verification.appUserId === undefined\n ? {}\n : { getAppUserId: resolveAppUserId(verification.appUserId) }),\n getCurrentEntitlements: () => (options.getCurrentEntitlements?.() ?? []) as TEntitlement[],\n graceMs: iapConfig.options.entitlementGraceMs,\n logger,\n });\n }\n\n const config = iapConfig.backend;\n if (!config) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'Neither backend nor verification is configured; the schema should have caught this. This is a library bug.',\n });\n }\n\n if (config.adapter !== undefined) {\n if (!isBackendAdapter(config.adapter)) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'backend.adapter must implement BackendAdapter (verifyApple, verifyGoogle, getEntitlements, restore).',\n });\n }\n return config.adapter as BackendAdapter<TEntitlement>;\n }\n\n // HTTP path — schema already required these fields, but re-check.\n if (!config.baseUrl || !config.endpoints || !config.getAuthHeaders) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'backend HTTP fields (baseUrl, endpoints, getAuthHeaders) are required when no custom adapter is provided.',\n });\n }\n\n return new HttpBackendAdapter<TEntitlement>({\n baseUrl: config.baseUrl,\n endpoints: config.endpoints,\n getAuthHeaders: config.getAuthHeaders,\n requestTransform: config.requestTransform,\n responseTransform: config.responseTransform,\n timeoutMs: config.timeoutMs,\n retries: config.retries,\n logger,\n ...(fetchImpl ? { fetch: fetchImpl } : {}),\n });\n}\n\n/**\n * Normalise `verification.appUserId`'s two forms into one resolver.\n *\n * The function form exists so the binding can follow the session — a fixed\n * string is captured at `createIAP()` time and is the previous user's after\n * a login change, which refuses every purchase made afterwards.\n */\nfunction resolveAppUserId(appUserId: string | (() => string | null)): () => string | null {\n return typeof appUserId === 'function' ? appUserId : () => appUserId;\n}\n\nexport { HttpBackendAdapter } from './http-adapter.js';\nexport { HttpClient } from './http-client.js';\n","import { IAPError, IAPErrorCode } from '../../lib/errors.js';\nimport type { Logger } from '../../lib/logger.js';\nimport type { BackendConfig } from '../../types/config.js';\nimport type { EntitlementBase } from '../../types/entitlement.js';\nimport type { ConfiguredProduct } from '../../types/product.js';\nimport { HttpClient } from './http-client.js';\nimport {\n type BackendAdapter,\n type RestoreRequest,\n type RestoreResponse,\n type VerifyAppleRequest,\n type VerifyGoogleRequest,\n type VerifyResponse,\n entitlementsResponseSchema,\n productManifestResponseSchema,\n restoreResponseSchema,\n verifyResponseSchema,\n} from './types.js';\n\nexport interface HttpBackendAdapterOptions {\n baseUrl: string;\n endpoints: {\n /**\n * Optional. Required only when the consumer's app actually invokes\n * `verifyApple` (iOS purchases). Android-only configs may omit it; the\n * adapter throws `INVALID_CONFIG` if `verifyApple()` is called without\n * this set. At least one of `verifyApple` or `verifyGoogle` must be set\n * for any usable config.\n */\n verifyApple?: string;\n /**\n * Optional. Required only when the consumer's app actually invokes\n * `verifyGoogle` (Android purchases). iOS-only configs may omit it; the\n * adapter throws `INVALID_CONFIG` if `verifyGoogle()` is called without\n * this set. At least one of `verifyApple` or `verifyGoogle` must be set\n * for any usable config.\n */\n verifyGoogle?: string;\n entitlements: string;\n restore: string;\n products?: string;\n };\n getAuthHeaders: () => Record<string, string> | Promise<Record<string, string>>;\n requestTransform?: BackendConfig['requestTransform'];\n responseTransform?: BackendConfig['responseTransform'];\n timeoutMs: number;\n retries: number;\n fetch?: typeof fetch;\n logger: Logger;\n}\n\n/**\n * Default `BackendAdapter` implementation: HTTP/JSON via `fetch`.\n *\n * The four methods translate to HTTP calls against the consumer's backend:\n * - `verifyApple` → POST `endpoints.verifyApple`\n * - `verifyGoogle` → POST `endpoints.verifyGoogle`\n * - `getEntitlements` → GET `endpoints.entitlements`\n * - `restore` → POST `endpoints.restore`\n *\n * The recommended request/response shape mirrors Attesto's normalized\n * transaction one hop downstream (see PLAN.md §5.8). Consumers whose\n * backend uses a different shape can supply `requestTransform` /\n * `responseTransform` to map between the library's defaults and theirs.\n */\nexport class HttpBackendAdapter<TEntitlement extends EntitlementBase = EntitlementBase>\n implements BackendAdapter<TEntitlement>\n{\n private readonly http: HttpClient;\n private readonly endpoints: HttpBackendAdapterOptions['endpoints'];\n\n constructor(opts: HttpBackendAdapterOptions) {\n this.endpoints = opts.endpoints;\n const httpClientOpts: ConstructorParameters<typeof HttpClient>[0] = {\n baseUrl: opts.baseUrl,\n getAuthHeaders: opts.getAuthHeaders,\n timeoutMs: opts.timeoutMs,\n retries: opts.retries,\n logger: opts.logger,\n ...(opts.requestTransform ? { requestTransform: opts.requestTransform } : {}),\n ...(opts.responseTransform ? { responseTransform: opts.responseTransform } : {}),\n ...(opts.fetch ? { fetch: opts.fetch } : {}),\n };\n this.http = new HttpClient(httpClientOpts);\n }\n\n async verifyApple(req: VerifyAppleRequest): Promise<VerifyResponse<TEntitlement>> {\n if (!this.endpoints.verifyApple) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'HttpBackendAdapter.verifyApple() requires backend.endpoints.verifyApple to be configured. Set it on iOS-supporting builds, or skip Apple purchases on this build.',\n });\n }\n const result = await this.http.request(\n { method: 'POST', path: this.endpoints.verifyApple, body: req },\n verifyResponseSchema,\n );\n return result as VerifyResponse<TEntitlement>;\n }\n\n async verifyGoogle(req: VerifyGoogleRequest): Promise<VerifyResponse<TEntitlement>> {\n if (!this.endpoints.verifyGoogle) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'HttpBackendAdapter.verifyGoogle() requires backend.endpoints.verifyGoogle to be configured. Set it on Android-supporting builds, or skip Google purchases on this build.',\n });\n }\n const result = await this.http.request(\n { method: 'POST', path: this.endpoints.verifyGoogle, body: req },\n verifyResponseSchema,\n );\n return result as VerifyResponse<TEntitlement>;\n }\n\n async getEntitlements(): Promise<TEntitlement[]> {\n const result = await this.http.request(\n { method: 'GET', path: this.endpoints.entitlements },\n entitlementsResponseSchema,\n );\n return result.entitlements as TEntitlement[];\n }\n\n async restore(req: RestoreRequest): Promise<RestoreResponse<TEntitlement>> {\n // Empty-array guard lives in `RestoreOrchestrator` (transport-agnostic);\n // see Phase 3 review L7. If a consumer calls this adapter directly with\n // an empty list, the backend's response is whatever it returns — usually\n // a 400 the HttpClient surfaces as `BACKEND_BAD_RESPONSE`.\n const result = await this.http.request(\n { method: 'POST', path: this.endpoints.restore, body: req },\n restoreResponseSchema,\n );\n return result as RestoreResponse<TEntitlement>;\n }\n\n async listProducts(): Promise<ConfiguredProduct[]> {\n if (!this.endpoints.products) {\n // Defensive: createIAP only calls listProducts() when this is set, but\n // a consumer who reaches into the adapter directly gets a clear error.\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'HttpBackendAdapter.listProducts() requires backend.endpoints.products to be configured.',\n });\n }\n const result = await this.http.request(\n { method: 'GET', path: this.endpoints.products },\n productManifestResponseSchema,\n );\n return result.products;\n }\n}\n","import type { z } from 'zod';\nimport { IAPError, IAPErrorCode } from '../../lib/errors.js';\nimport type { Logger } from '../../lib/logger.js';\nimport { redactHeaders } from '../../lib/redact.js';\n\nexport interface HttpRequest {\n method: 'GET' | 'POST';\n /**\n * Path appended to baseUrl. Leading slash is optional — both `'/foo'` and\n * `'foo'` are normalized at request time, and any trailing slash on `baseUrl`\n * is stripped, so all four corner cases produce the same joined URL.\n */\n path: string;\n /** JSON-serializable body (for POST). */\n body?: unknown;\n /** Extra headers, merged on top of auth headers + Content-Type. */\n headers?: Record<string, string>;\n}\n\nexport interface HttpClientOptions {\n baseUrl: string;\n /** Called before every request. Returns headers to merge in (e.g. `{ Authorization: 'Bearer ...' }`). */\n getAuthHeaders: () => Record<string, string> | Promise<Record<string, string>>;\n /** Per-attempt timeout in ms. */\n timeoutMs: number;\n /** Number of retry attempts on transient errors (5xx, 408, 429, network). */\n retries: number;\n /** Optional pre-send transform. Lets consumer rewrite path/body/headers. */\n requestTransform?: (req: HttpRequest) => HttpRequest | Promise<HttpRequest>;\n /** Optional response transform. Runs on the parsed JSON before validation. */\n responseTransform?: (raw: unknown) => unknown | Promise<unknown>;\n /** Override `globalThis.fetch` for tests. */\n fetch?: typeof fetch;\n logger: Logger;\n}\n\n/** Backoff schedule for transient retries (ms). Caps at 4s on attempt 3+. */\nconst RETRY_BACKOFF_MS = [1_000, 2_000, 4_000];\n\n/**\n * Generic HTTP client for the consumer backend.\n *\n * - **Timeout**: per-attempt via `AbortController` (native fetch has no timeout option).\n * - **Retry policy**: 5xx, 408, 429, and network errors retry with exponential backoff.\n * Other 4xx fail immediately (caller's responsibility to fix).\n * - **Auth + transforms**: `getAuthHeaders()` runs once per request; `requestTransform`\n * and `responseTransform` are escape hatches for consumers whose backend uses a\n * different shape than the library's default.\n * - **Logging**: requests are logged at debug level with sensitive headers redacted\n * via `redactHeaders()` (PLAN.md §13 — never log raw bearer tokens).\n *\n * Consumers don't construct this directly — `HttpBackendAdapter` wraps it.\n */\nexport class HttpClient {\n private readonly fetchImpl: typeof fetch;\n\n constructor(private readonly opts: HttpClientOptions) {\n const provided = opts.fetch;\n if (provided) {\n this.fetchImpl = provided;\n } else if (typeof globalThis.fetch === 'function') {\n this.fetchImpl = globalThis.fetch.bind(globalThis);\n } else {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message: 'globalThis.fetch is unavailable; pass a fetch implementation via config.',\n });\n }\n }\n\n /**\n * Execute the request and parse the response with the given zod schema.\n * Returns the validated, transformed result.\n */\n async request<T>(req: HttpRequest, schema: z.ZodType<T>): Promise<T> {\n const transformed = this.opts.requestTransform ? await this.opts.requestTransform(req) : req;\n\n const base = this.opts.baseUrl.replace(/\\/+$/, '');\n const path = transformed.path.startsWith('/') ? transformed.path : `/${transformed.path}`;\n const url = `${base}${path}`;\n const auth = await this.opts.getAuthHeaders();\n const headers: Record<string, string> = {\n 'content-type': 'application/json',\n accept: 'application/json',\n ...auth,\n ...(transformed.headers ?? {}),\n };\n\n let lastError: IAPError | undefined;\n const maxAttempts = this.opts.retries + 1;\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n try {\n return await this.singleAttempt<T>(url, transformed, headers, schema);\n } catch (error) {\n if (!(error instanceof IAPError) || !error.recoverable) {\n throw error;\n }\n lastError = error;\n const remaining = maxAttempts - attempt;\n if (remaining <= 0) break;\n const delayMs =\n RETRY_BACKOFF_MS[attempt - 1] ?? RETRY_BACKOFF_MS[RETRY_BACKOFF_MS.length - 1] ?? 4_000;\n this.opts.logger.debug(\n `HTTP ${transformed.method} ${transformed.path} retry ${attempt}/${this.opts.retries} after ${delayMs}ms (${error.code})`,\n );\n await sleep(delayMs);\n }\n }\n throw (\n lastError ??\n new IAPError({\n code: IAPErrorCode.BACKEND_UNAVAILABLE,\n message: 'Backend request failed with no recorded error.',\n })\n );\n }\n\n private async singleAttempt<T>(\n url: string,\n req: HttpRequest,\n headers: Record<string, string>,\n schema: z.ZodType<T>,\n ): Promise<T> {\n this.opts.logger.debug(`HTTP ${req.method} ${req.path}`, { headers: redactHeaders(headers) });\n\n let response: Response;\n try {\n response = await this.fetchWithTimeout(url, {\n method: req.method,\n headers,\n body: req.body !== undefined ? JSON.stringify(req.body) : undefined,\n });\n } catch (cause) {\n // AbortError → timeout; everything else → network error.\n const isAbort = (cause as { name?: string } | null)?.name === 'AbortError';\n throw new IAPError({\n code: isAbort ? IAPErrorCode.BACKEND_TIMEOUT : IAPErrorCode.BACKEND_UNAVAILABLE,\n message: isAbort\n ? `Backend request timed out after ${this.opts.timeoutMs}ms.`\n : 'Network error while calling backend.',\n cause,\n recoverable: true,\n });\n }\n\n if (response.status === 401 || response.status === 403) {\n throw new IAPError({\n code: IAPErrorCode.BACKEND_AUTH_FAILED,\n message: `Backend auth failed (${response.status}).`,\n });\n }\n\n if (!response.ok) {\n const transient =\n response.status === 408 || response.status === 429 || response.status >= 500;\n throw new IAPError({\n // Transient failures (5xx, 408, 429) → BACKEND_UNAVAILABLE so the\n // retry loop picks them up. Non-transient (other 4xx after auth has\n // been ruled out) → BACKEND_BAD_RESPONSE so the orchestrator can\n // surface \"fix the request\" rather than \"try again later\".\n code: transient ? IAPErrorCode.BACKEND_UNAVAILABLE : IAPErrorCode.BACKEND_BAD_RESPONSE,\n message: `Backend returned ${response.status} ${response.statusText}.`,\n recoverable: transient,\n });\n }\n\n // 204 No Content on a JSON endpoint is a contract violation — PLAN.md §5.8\n // defines explicit JSON shapes for every endpoint, so we fail loudly with\n // a precise error rather than the misleading \"not valid JSON\" path below.\n if (response.status === 204 || response.headers.get('content-length') === '0') {\n throw new IAPError({\n code: IAPErrorCode.BACKEND_BAD_RESPONSE,\n message: `Backend returned ${response.status} with empty body; expected JSON for ${req.path}.`,\n });\n }\n\n let raw: unknown;\n try {\n raw = await response.json();\n } catch (cause) {\n throw new IAPError({\n code: IAPErrorCode.BACKEND_BAD_RESPONSE,\n message: 'Backend response was not valid JSON.',\n cause,\n });\n }\n\n const transformed = this.opts.responseTransform ? await this.opts.responseTransform(raw) : raw;\n\n const parsed = schema.safeParse(transformed);\n if (!parsed.success) {\n throw new IAPError({\n code: IAPErrorCode.BACKEND_BAD_RESPONSE,\n message: `Backend response failed validation: ${parsed.error.issues\n .map((i) => `${i.path.join('.') || '<root>'}: ${i.message}`)\n .join('; ')}`,\n cause: parsed.error,\n });\n }\n return parsed.data;\n }\n\n private async fetchWithTimeout(url: string, init: RequestInit): Promise<Response> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), this.opts.timeoutMs);\n try {\n return await this.fetchImpl(url, { ...init, signal: controller.signal });\n } finally {\n clearTimeout(timer);\n }\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/**\n * Logging redaction utilities.\n *\n * The library NEVER logs full purchase tokens, JWS payloads, receipts,\n * or auth headers (PLAN.md §13). These helpers produce safe-to-log\n * representations that preserve enough information for debugging\n * without leaking sensitive data.\n */\n\nconst VISIBLE_PREFIX_CHARS = 8;\nconst ELLIPSIS = '…';\n\n/**\n * Mask a token-like string. Returns the first 8 characters followed by\n * an ellipsis. Returns the input unchanged if it's already shorter than\n * 8 characters (no privacy gain to masking) or empty.\n *\n * @example\n * maskToken('GPA.1234-5678-9012-34567') → 'GPA.1234…'\n * maskToken('2000000123456789') → '20000001…'\n * maskToken('short') → 'short'\n * maskToken('') → ''\n */\nexport function maskToken(token: string | null | undefined): string {\n if (!token) return '';\n if (token.length <= VISIBLE_PREFIX_CHARS) return token;\n return token.slice(0, VISIBLE_PREFIX_CHARS) + ELLIPSIS;\n}\n\n/**\n * Mask a credential (auth header value, cookie, API key). Unlike\n * {@link maskToken}, this NEVER returns the input unchanged — short\n * sandbox/test tokens (e.g. `secret12`) must still be redacted. Any\n * non-empty value collapses to either `prefix…` (for ≥8 chars) or just\n * `…` (for shorter values). Empty input returns empty.\n *\n * Use this for anything that grants access if leaked.\n */\nfunction maskCredential(value: string | null | undefined): string {\n if (!value) return '';\n if (value.length <= VISIBLE_PREFIX_CHARS) return ELLIPSIS;\n return value.slice(0, VISIBLE_PREFIX_CHARS) + ELLIPSIS;\n}\n\nconst SENSITIVE_HEADER_PATTERNS = [\n /^authorization$/i,\n /^cookie$/i,\n /^x-api-key$/i,\n /^x-auth-token$/i,\n];\n\n/**\n * Return a copy of a headers map with sensitive values masked.\n * Header NAMES are preserved (case-insensitive match against known\n * sensitive patterns); only the value is redacted.\n *\n * @example\n * redactHeaders({ Authorization: 'Bearer abc123def456', 'X-Trace-Id': 'xyz' })\n * → { Authorization: 'Bearer a…', 'X-Trace-Id': 'xyz' }\n */\nexport function redactHeaders(headers: Record<string, string>): Record<string, string> {\n const out: Record<string, string> = {};\n for (const [name, value] of Object.entries(headers)) {\n out[name] = isSensitiveHeader(name) ? redactHeaderValue(value) : value;\n }\n return out;\n}\n\nfunction isSensitiveHeader(name: string): boolean {\n return SENSITIVE_HEADER_PATTERNS.some((pattern) => pattern.test(name));\n}\n\nfunction redactHeaderValue(value: string): string {\n // Bearer tokens and API keys: mask the credential portion but keep the scheme.\n // Use maskCredential (not maskToken) so short sandbox tokens are still hidden.\n const bearerMatch = value.match(/^(Bearer|Basic|Token)\\s+(.+)$/i);\n if (bearerMatch) {\n const [, scheme, credential] = bearerMatch;\n return `${scheme} ${maskCredential(credential ?? '')}`;\n }\n return maskCredential(value);\n}\n","/**\n * RFC 9562 UUID validator.\n *\n * Apple's `appAccountToken` on a StoreKit purchase MUST be a UUID — Apple\n * validates it server-side and rejects anything else. Google's\n * `obfuscatedAccountId` accepts any string up to 64 characters, but iap\n * enforces the UUID shape on both platforms so consumers have one\n * predictable contract.\n *\n * **Any version (1-8) is accepted**, not only v4. Deterministic identifiers\n * are a legitimate and common choice: a UUIDv5 over a stable name yields the\n * same binding on every device with no mapping to store, and v7 is the\n * current recommendation for time-ordered ids. Restricting to v4 forced\n * consumers who already had a deterministic identity to mint a second one\n * and keep the two in step.\n *\n * What is still refused:\n *\n * - **The nil and max UUIDs.** Both are valid RFC 9562 constructs and both\n * deliberately carry no version or variant — they mean \"no identifier\".\n * Accepting one would bind a purchase to nothing while looking\n * well-formed, which is worse than a clear rejection.\n * - **Non-RFC variants.** The variant nibble must be 8, 9, a or b. The\n * 0-7 range is legacy NCS and c-f is Microsoft/reserved, so neither is an\n * RFC 9562 UUID.\n *\n * Those last two are **iap's choice, not Apple's requirement.** Foundation's\n * `UUID(uuidString:)` — what `appAccountToken` is built from — parses any\n * 36-character hyphenated hex string without checking the version or variant\n * nibbles, and accepts the nil UUID. So this validator is stricter than the\n * platform, deliberately: one spelling and one shape keeps the binding\n * comparable and keeps \"is this a UUID\" from meaning four different things.\n *\n * The practical cost is worth naming. An identifier that merely *looks* like\n * a UUID — an md5 digest formatted with hyphens, say — has effectively\n * random version and variant nibbles and will usually be refused here, where\n * Apple would have taken it. A proper RFC v3/v5 implementation sets both\n * nibbles, so a deterministic UUIDv5 binding is unaffected.\n * - **Non-canonical spellings.** No braces, no `urn:uuid:` prefix, no\n * surrounding whitespace, no missing hyphens. One spelling keeps string\n * comparison meaningful — see the note on casing below.\n *\n * **On casing:** this accepts either, because both platforms and every\n * generator in common use disagree about it. iap normalizes the binding it\n * reads back off a transaction to lowercase (StoreKit returns an uppercase\n * `uuidString`), so `StorePurchase.appUserId` compares equal to whatever was\n * passed to `purchase({ appUserId })`.\n */\nconst UUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;\n\nexport function isValidUuid(value: unknown): value is string {\n return typeof value === 'string' && UUID_REGEX.test(value);\n}\n","import { z } from 'zod';\nimport type { HttpRequest } from '../adapters/backend/http-client.js';\nimport type { LocallyVerifiedPurchase } from '../core/local-verification.js';\nimport { isValidUuid } from '../lib/uuid.js';\nimport type { EntitlementBase } from './entitlement.js';\n\nexport const productTypeSchema = z.enum(['subscription', 'product', 'consumable']);\n\nconst configuredProductSchema = z.object({\n id: z.string().min(1),\n type: productTypeSchema,\n /**\n * Optional. Used only by the Android native adapter to disambiguate which\n * base plan to purchase for multi-plan subscription products (Google Play\n * Billing). iOS ignores it. When omitted on Android, the native adapter\n * falls back to `native.getOffer()` (the default offer) — fine for\n * single-plan subscriptions and for non-subscription products.\n *\n * Recommended to set explicitly when a single subscription product has\n * multiple base plans (e.g. monthly + yearly under one product id).\n */\n androidPlanId: z.string().min(1).optional(),\n});\n\n/**\n * Array form. Reused by `productManifestResponseSchema` (HTTP) and by the\n * runtime guard in `createIAP.initialize()` for backend-supplied manifests.\n */\nexport const configuredProductsArraySchema = z.array(configuredProductSchema).min(1);\n\nconst backendEndpointsSchema = z\n .object({\n /**\n * Optional. Set when the consumer supports iOS purchases. iOS-less\n * (e.g. Android-only) configs may omit it; the HTTP adapter will throw\n * `INVALID_CONFIG` at runtime if `verifyApple()` is invoked without this\n * endpoint configured. At least one of `verifyApple` or `verifyGoogle`\n * must be set.\n */\n verifyApple: z.string().min(1).optional(),\n /**\n * Optional. Set when the consumer supports Android purchases.\n * Android-less (e.g. iOS-only) configs may omit it; the HTTP adapter will\n * throw `INVALID_CONFIG` at runtime if `verifyGoogle()` is invoked\n * without this endpoint configured. At least one of `verifyApple` or\n * `verifyGoogle` must be set.\n */\n verifyGoogle: z.string().min(1).optional(),\n entitlements: z.string().min(1),\n restore: z.string().min(1),\n /**\n * Optional. When set, the library fetches the SKU manifest from this\n * endpoint during `initialize()` if `products` is omitted from config.\n * See `docs/guide/backend-contract.md` for the response shape.\n */\n products: z.string().min(1).optional(),\n })\n .superRefine((data, ctx) => {\n if (!data.verifyApple && !data.verifyGoogle) {\n // Attach to the object root rather than one of the two fields — the\n // constraint is cross-field, so naming a single path is misleading\n // (a developer reading \"verifyApple: ...\" may add only that and miss\n // that verifyGoogle would also satisfy the constraint).\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n 'At least one of backend.endpoints.verifyApple or backend.endpoints.verifyGoogle must be set.',\n path: [],\n });\n }\n });\n\nconst backendConfigSchema = z\n .object({\n /**\n * Custom backend transport. If provided, all HTTP-specific fields below\n * are ignored and the library uses this object directly for backend\n * operations. Must implement `BackendAdapter`.\n */\n adapter: z.unknown().optional(),\n\n // ----- HTTP-specific fields (used when `adapter` is not provided) -----\n baseUrl: z.string().url().optional(),\n endpoints: backendEndpointsSchema.optional(),\n /**\n * Returns auth headers to merge into every backend request. Called fresh\n * per request so token refresh works automatically. Type is checked at\n * runtime via shape guard, not zod (zod can't validate function contracts).\n */\n getAuthHeaders: z.unknown().optional(),\n /** Pre-send request transform. See {@link BackendConfig} for the typed shape. */\n requestTransform: z.unknown().optional(),\n /** Post-receive response transform. See {@link BackendConfig} for the typed shape. */\n responseTransform: z.unknown().optional(),\n entitlementSchema: z.unknown().optional(),\n\n // ----- Common (apply to both HTTP and custom adapters where relevant) -----\n timeoutMs: z.number().int().positive().default(10_000),\n retries: z.number().int().min(0).max(5).default(2),\n })\n .superRefine((data, ctx) => {\n // When no custom adapter, HTTP fields are required.\n if (data.adapter !== undefined) return;\n if (!data.baseUrl) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'backend.baseUrl is required when no custom adapter is provided.',\n path: ['baseUrl'],\n });\n }\n if (!data.endpoints) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: 'backend.endpoints is required when no custom adapter is provided.',\n path: ['endpoints'],\n });\n }\n if (typeof data.getAuthHeaders !== 'function') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n 'backend.getAuthHeaders must be a function (() => Record<string, string> | Promise<Record<string, string>>) when no custom adapter is provided.',\n path: ['getAuthHeaders'],\n });\n }\n });\n\n/**\n * Verify purchases on the device instead of through a backend.\n *\n * For an app with no server at all. Every safety guarantee still applies —\n * the purchase flow, the acknowledge-after-verify ordering and the\n * unfinished-transaction recovery are all above the adapter boundary and do\n * not know which mode they are in. What changes is who answers \"is this\n * purchase real\", and how strong that answer is.\n *\n * Read `docs/guide/offline-and-no-backend.md` before choosing this: on\n * Android no cryptographic check is possible on the device, so a passing\n * verification there means \"Play told this device it owns this\".\n */\nconst verificationConfigSchema = z.object({\n mode: z.literal('local'),\n /**\n * Maps a verified purchase to the entitlements it grants. Required: iap\n * does not know what a product entitles anyone to, and in local mode\n * there is no backend to ask. Type is checked at runtime via a shape\n * guard, not zod — see {@link VerificationConfig}.\n */\n entitlements: z.unknown(),\n /**\n * The binding every purchase must carry, as passed to\n * `purchase({ appUserId })`. A purchase bound to something else is\n * refused. Omit it if the app does not bind purchases.\n *\n * Either the id itself, or a function returning it — in which case it is\n * read **at the time of each check**, so the binding follows the session.\n * A fixed string is captured at `createIAP()` time and cannot track a\n * login change, which in a multi-user app means every purchase after a\n * switch is refused as the previous user's.\n *\n * The function may return `null` for \"nobody is signed in right now\".\n * That is **not** the same as using no binding: iap refuses the purchase\n * rather than dropping the check. See `LocalVerificationAdapter`.\n *\n * Typed via the overlay on {@link VerificationConfig}; validated in the\n * schema's `superRefine`, the same way the backend's functions are.\n */\n appUserId: z.unknown().optional(),\n});\n\n/**\n * Android-specific settings.\n *\n * `packageName` exists because Google's verification APIs are keyed on it\n * and **the native layer does not report it**: capgo's `Transaction` shape\n * has no such field, so iap cannot derive it from a purchase. Without it,\n * every Google transaction fails to build a verify or restore request.\n *\n * Set it to your app's applicationId, exactly as Play Console has it. Only\n * required for an Android build that sells anything.\n */\nconst androidConfigSchema = z.object({\n packageName: z.string().min(1).optional(),\n});\n\nconst storageConfigSchema = z.object({\n type: z.enum(['preferences', 'memory', 'custom']).default('preferences'),\n namespace: z.string().min(1).default('nosslabs_iap'),\n adapter: z.unknown().optional(),\n});\n\nconst optionsConfigSchema = z.object({\n refreshOnResume: z.boolean().default(true),\n entitlementCacheTtlMs: z\n .number()\n .int()\n .positive()\n .default(60 * 60 * 1000),\n /**\n * Extra time past an entitlement's `expiresAt` during which it still\n * counts as active, by the **device** clock.\n *\n * Exists because a renewal is not instantaneous: a subscription that\n * renews at midnight may not have a fresh receipt on the device for\n * minutes or hours, and locking the user out in that window is a worse\n * error than letting a lapsed subscription run slightly long. Store\n * grace periods and billing retry can stretch much further — on Android\n * those are server-side only, so a backendless app cannot see them at all\n * and this window is the only cushion it has.\n *\n * Defaults to 0: no grace, which is the strict reading of `expiresAt`.\n */\n entitlementGraceMs: z.number().int().nonnegative().default(0),\n recoverUnfinishedTransactions: z.boolean().default(true),\n /**\n * Cap on how many unfinished transactions recovery inspects per launch.\n * Defends against pathological growth if the consumer's backend has been\n * down for an extended period and the unfinished list keeps growing.\n * Excess entries stay in storage and are processed on subsequent launches.\n */\n recoveryMaxBatch: z.number().int().positive().default(50),\n /**\n * List of backend `valid:false` error codes that recovery should treat as\n * permanent — entries with a matching error are removed from storage\n * instead of retried on every launch. When omitted (the default), iap\n * uses `DEFAULT_PERMANENT_ERROR_CODES` (`['TRANSACTION_NOT_FOUND',\n * 'PRODUCT_MISMATCH']`).\n *\n * REPLACES the default when provided — pass `[...DEFAULT_PERMANENT_ERROR_CODES,\n * 'YOUR_CODE']` to extend, or `[]` to disable the feature entirely\n * (revert to retry-forever behavior). Export the constant from\n * `@nosslabs/iap` for the spread form.\n */\n permanentErrorCodes: z.array(z.string()).optional(),\n productPriceCacheTtlMs: z\n .number()\n .int()\n .positive()\n .default(24 * 60 * 60 * 1000),\n logLevel: z.enum(['silent', 'error', 'warn', 'info', 'debug']).default('info'),\n logger: z.unknown().optional(),\n});\n\nexport const iapConfigSchema = z\n .object({\n /**\n * Static SKU manifest. Optional: when omitted, the library calls\n * `backend.adapter.listProducts()` (custom adapter) or GETs\n * `backend.endpoints.products` (HTTP) during `initialize()`. Configs\n * without either path throw `INVALID_CONFIG` at parse time.\n */\n products: z.array(configuredProductSchema).min(1).optional(),\n /**\n * The consumer's backend, which calls Attesto. Optional **only** when\n * `verification` is set instead — one of the two has to answer\n * whether a purchase is real.\n */\n backend: backendConfigSchema.optional(),\n /** On-device verification, for an app with no backend. */\n verification: verificationConfigSchema.optional(),\n /** Android-specific settings. See {@link androidConfigSchema}. */\n android: androidConfigSchema.default({}),\n storage: storageConfigSchema.default({ type: 'preferences', namespace: 'nosslabs_iap' }),\n options: optionsConfigSchema.default({\n refreshOnResume: true,\n entitlementCacheTtlMs: 60 * 60 * 1000,\n recoverUnfinishedTransactions: true,\n recoveryMaxBatch: 50,\n productPriceCacheTtlMs: 24 * 60 * 60 * 1000,\n logLevel: 'info',\n }),\n })\n .superRefine((data, ctx) => {\n // Exactly one verification source. Both would be ambiguous (which one\n // decides?) and neither leaves nothing to gate acknowledgement on.\n if (data.backend && data.verification) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n 'Set either backend or verification, not both — they are two answers to the same question.',\n path: [],\n });\n }\n if (!data.backend && !data.verification) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n 'One of backend or verification is required: something has to verify a purchase before an entitlement is granted. Use verification: { mode: \"local\", entitlements } for an app with no backend.',\n path: [],\n });\n }\n if (data.verification && typeof data.verification.entitlements !== 'function') {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n 'verification.entitlements must be a function ((purchase) => TEntitlement[]) — iap cannot know what a product entitles a user to.',\n path: ['verification', 'entitlements'],\n });\n }\n // Either the id or a function returning it. A non-UUID string could\n // never match a purchase — `purchase({ appUserId })` enforces the same\n // constraint — so it would silently refuse every one.\n const binding = data.verification?.appUserId;\n if (\n data.verification &&\n binding !== undefined &&\n typeof binding !== 'function' &&\n !(typeof binding === 'string' && isValidUuid(binding))\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n 'verification.appUserId must be an RFC 9562 UUID, or a function returning one (or null when nobody is signed in) — the same constraint purchase({ appUserId }) enforces.',\n path: ['verification', 'appUserId'],\n });\n }\n\n // Local mode has no backend to curate a manifest, so the catalog must\n // be static. Checked here because the products rule below only knows\n // about the backend paths.\n if (data.verification && data.products === undefined) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n 'products is required in local verification mode: there is no backend to supply the manifest.',\n path: ['products'],\n });\n }\n\n if (data.products !== undefined) return;\n if (data.verification) return;\n // No static products → the backend must be able to supply them.\n // Adapter takes precedence: if `adapter` is provided, the HTTP fields are\n // ignored everywhere else, so we ignore them here too. The HTTP path is\n // only consulted when no custom adapter is set.\n // `verification` returned above, so a backend is present here.\n const backend = data.backend;\n if (!backend) return;\n const adapter = backend.adapter as { listProducts?: unknown } | undefined;\n const adapterCanList = adapter && typeof adapter.listProducts === 'function';\n const httpCanList = !backend.adapter && backend.endpoints?.products;\n if (!adapterCanList && !httpCanList) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n 'products is required unless the backend can supply it: set backend.endpoints.products (HTTP) or implement listProducts() on a custom adapter.',\n path: ['products'],\n });\n }\n });\n\ntype RawBackendConfig = z.infer<typeof backendConfigSchema>;\ntype RawBackendConfigInput = z.input<typeof backendConfigSchema>;\n\n/**\n * Replace the schema's `unknown` typings for function-shaped fields with\n * their precise TS contracts. The schema captures the *structural* shape\n * and runtime validates \"is a function\" via `superRefine`; this overlay\n * gives consumers proper IDE autocomplete and removes the need for\n * `as never` casts inside the HTTP adapter.\n *\n * Zod's `z.function()` would type these as `(...args: unknown[]) => unknown`\n * which is too wide, and zod can't validate a function *contract* at runtime\n * anyway — only the existence of a function reference.\n */\ntype FunctionTypedBackendOverlay = {\n getAuthHeaders?: () => Record<string, string> | Promise<Record<string, string>>;\n requestTransform?: (req: HttpRequest) => HttpRequest | Promise<HttpRequest>;\n responseTransform?: (raw: unknown) => unknown | Promise<unknown>;\n};\n\nexport type BackendConfig = Omit<\n RawBackendConfig,\n 'getAuthHeaders' | 'requestTransform' | 'responseTransform'\n> &\n FunctionTypedBackendOverlay;\n\nexport type BackendConfigInput = Omit<\n RawBackendConfigInput,\n 'getAuthHeaders' | 'requestTransform' | 'responseTransform'\n> &\n FunctionTypedBackendOverlay;\n\ntype RawIAPConfig = z.infer<typeof iapConfigSchema>;\ntype RawIAPConfigInput = z.input<typeof iapConfigSchema>;\n\n/**\n * Replace the schema's `unknown` typing for the entitlement mapper with its\n * real contract, the same way {@link BackendConfig} does for its functions.\n *\n * Generic over the consumer's entitlement shape. `LocallyVerifiedPurchase`\n * carries what a mapper needs to decide: the product, the expiry, the\n * binding, and how strongly the purchase was checked.\n */\nexport type VerificationConfig<TEntitlement extends EntitlementBase = EntitlementBase> = Omit<\n z.infer<typeof verificationConfigSchema>,\n 'entitlements' | 'appUserId'\n> & {\n entitlements: (purchase: LocallyVerifiedPurchase) => TEntitlement[];\n /**\n * The id, or a getter so the binding can follow the session. A getter\n * returning `null` means \"nobody signed in\", and refuses rather than\n * skipping the check.\n */\n appUserId?: string | (() => string | null);\n};\n\nexport type IAPConfig<TEntitlement extends EntitlementBase = EntitlementBase> = Omit<\n RawIAPConfig,\n 'backend' | 'verification'\n> & {\n backend?: BackendConfig;\n verification?: VerificationConfig<TEntitlement>;\n};\n\nexport type IAPConfigInput<TEntitlement extends EntitlementBase = EntitlementBase> = Omit<\n RawIAPConfigInput,\n 'backend' | 'verification'\n> & {\n backend?: BackendConfigInput;\n verification?: VerificationConfig<TEntitlement>;\n};\nexport type StorageConfig = z.infer<typeof storageConfigSchema>;\nexport type OptionsConfig = z.infer<typeof optionsConfigSchema>;\n","import { z } from 'zod';\n\nexport const entitlementBaseSchema = z.object({\n key: z.string().min(1),\n productId: z.string().min(1),\n expiresAt: z.string().nullable(),\n});\n\n/**\n * Minimum shape every entitlement returned by the backend must satisfy.\n * Consumer-defined fields pass through unvalidated unless the consumer\n * supplies their own schema via `config.backend.entitlementSchema`.\n */\nexport type EntitlementBase = z.infer<typeof entitlementBaseSchema>;\n\n/** Default shape used when no `TEntitlement` type parameter is given. */\nexport type DefaultEntitlement = EntitlementBase;\n","import { z } from 'zod';\nimport { configuredProductsArraySchema } from '../../types/config.js';\nimport type { EntitlementBase } from '../../types/entitlement.js';\nimport { entitlementBaseSchema } from '../../types/entitlement.js';\nimport type { ConfiguredProduct, ProductType } from '../../types/product.js';\nimport type { NativeTransaction } from '../../types/transaction.js';\n\n// ----- Request types (constructed by the library; static TS types are sufficient) -----\n\nexport interface VerifyAppleRequest {\n productId: string;\n /** Apple StoreKit transaction id (numeric string). */\n transactionId: string;\n type: ProductType;\n}\n\nexport interface VerifyGoogleRequest {\n productId: string;\n /** Google Play `purchaseToken`. */\n purchaseToken: string;\n /** Application package name (e.g. `com.example.app`). */\n packageName: string;\n type: ProductType;\n}\n\n/** A single entry in a restore batch. Discriminated by `platform`. */\nexport type RestoreRequestTransaction =\n | {\n platform: 'apple';\n productId: string;\n transactionId: string;\n }\n | {\n platform: 'google';\n productId: string;\n purchaseToken: string;\n packageName: string;\n };\n\nexport interface RestoreRequest {\n transactions: RestoreRequestTransaction[];\n}\n\n// ----- Response schemas (validated; consumer fields ride along via .passthrough()) -----\n\n/**\n * Validates the EntitlementBase shape but lets consumer-defined fields pass\n * through unstripped. The HttpBackendAdapter casts results to TEntitlement\n * at the public boundary — same pattern as EntitlementCache.\n */\nconst passthroughEntitlementSchema = entitlementBaseSchema.passthrough();\n\nconst verifiedTransactionSchema = z\n .object({\n id: z.string(),\n productId: z.string(),\n /** ISO 8601 timestamp; null for non-expiring transactions. */\n expiresAt: z.string().nullable().optional(),\n })\n .passthrough();\n\nconst verifySuccessSchema = z\n .object({\n valid: z.literal(true),\n entitlements: z.array(passthroughEntitlementSchema),\n transaction: verifiedTransactionSchema,\n })\n .passthrough();\n\nconst verifyFailureSchema = z\n .object({\n valid: z.literal(false),\n /** Stable machine-readable code, e.g. \"TRANSACTION_NOT_FOUND\". */\n error: z.string(),\n /** Optional human-readable detail. */\n message: z.string().optional(),\n })\n .passthrough();\n\nexport const verifyResponseSchema = z.discriminatedUnion('valid', [\n verifySuccessSchema,\n verifyFailureSchema,\n]);\n\nconst restoreSuccessSchema = z\n .object({\n valid: z.literal(true),\n entitlements: z.array(passthroughEntitlementSchema),\n verifiedTokens: z.array(z.string()).optional(),\n })\n .passthrough();\n\nexport const restoreResponseSchema = z.discriminatedUnion('valid', [\n restoreSuccessSchema,\n verifyFailureSchema,\n]);\n\nexport const entitlementsResponseSchema = z\n .object({ entitlements: z.array(passthroughEntitlementSchema) })\n .passthrough();\n\n/**\n * Backend product-manifest response. Mirrors the entitlements envelope\n * shape (`{ entitlements: [...] }`) for API consistency. The inner array\n * is validated against the same `configuredProductSchema` used at config\n * parse time, so a backend that drifts from the schema fails loudly.\n */\nexport const productManifestResponseSchema = z\n .object({ products: configuredProductsArraySchema })\n .passthrough();\n\n// ----- Public response types (plain TS; runtime schemas above passthrough extras at parse time) -----\n//\n// Defined as plain TS interfaces rather than `z.infer<...>` because Zod's\n// `.passthrough()` adds `[k: string]: unknown` to the inferred type, which\n// TS treats as overriding named property types — so consumer code reading\n// `result.entitlements` would receive `unknown`. The runtime schemas above\n// still passthrough at parse time, so backend-defined extras ARE preserved\n// on the resolved object — consumers who want them just cast.\n//\n// The transaction echo's shape is inlined (rather than referencing the\n// separate `VerifiedTransaction` in `src/types/transaction.ts`) because the\n// purchase orchestrator does its own `as VerifiedTransaction` cast when\n// surfacing the value in `PurchaseResult` — the public type there is the\n// canonical one.\n\n/** Public response type for `verifyApple` / `verifyGoogle`, generic over the consumer's entitlement shape. */\nexport type VerifyResponse<TEntitlement extends EntitlementBase = EntitlementBase> =\n | {\n valid: true;\n entitlements: TEntitlement[];\n transaction: { id: string; productId: string; expiresAt?: string | null };\n }\n | { valid: false; error: string; message?: string };\n\n/**\n * Restore response. Distinct from {@link VerifyResponse} because the\n * orchestrator never reads `transaction` on the restore path — the schema\n * accordingly omits any required transaction echo. Backends that include\n * a `transaction` (or any other field) on the success branch ride through\n * unmodified via top-level passthrough; consumers cast to read them.\n */\nexport type RestoreResponse<TEntitlement extends EntitlementBase = EntitlementBase> =\n | {\n valid: true;\n entitlements: TEntitlement[];\n /**\n * Optional: the tokens that were actually verified, when the\n * adapter judged them individually.\n *\n * When present, only these are acknowledged. It exists because a\n * single consolidated `valid: true` cannot say *which* of the\n * submitted transactions passed — and acknowledging one that did\n * not finalises a purchase the adapter just refused, waiving\n * Play's refund window for it.\n *\n * A backend that validates the batch as a whole omits it, and\n * every submitted transaction is acknowledged as before.\n */\n verifiedTokens?: string[];\n }\n | { valid: false; error: string; message?: string };\n\n// ----- BackendAdapter interface (transport-agnostic) -----\n\n/**\n * Abstracts the consumer's backend so the orchestrator (Phase 4+) doesn't\n * depend on `fetch`. The default `HttpBackendAdapter` is HTTP/JSON via\n * `fetch`; consumers on GraphQL, gRPC-web, Supabase, Firebase, etc. supply\n * their own implementation via `config.backend.adapter`.\n *\n * All methods MUST validate response shape. Failures should throw IAPError\n * (HTTP impl uses BACKEND_UNAVAILABLE / BACKEND_TIMEOUT / BACKEND_AUTH_FAILED\n * / VERIFICATION_REJECTED depending on cause) — the orchestrator relies on\n * `IAPError.recoverable` to decide whether to surface a transient error or\n * abort the purchase flow.\n */\nexport interface BackendAdapter<TEntitlement extends EntitlementBase = EntitlementBase> {\n verifyApple(req: VerifyAppleRequest): Promise<VerifyResponse<TEntitlement>>;\n verifyGoogle(req: VerifyGoogleRequest): Promise<VerifyResponse<TEntitlement>>;\n /** GET current entitlements; library uses this for refresh + warm cache. */\n getEntitlements(): Promise<TEntitlement[]>;\n /**\n * Batch re-verify. Backend returns consolidated entitlements.\n *\n * Returns {@link RestoreResponse} (not {@link VerifyResponse}) — the orchestrator\n * does not consume any per-transaction echo on restore, so the response\n * shape intentionally omits the required `transaction` field that verify\n * has. Backends may still attach a `transaction` (or any other extras)\n * — they ride through via the schema's top-level passthrough.\n */\n restore(req: RestoreRequest): Promise<RestoreResponse<TEntitlement>>;\n /**\n * Optional: return the SKU manifest the app should register.\n *\n * When implemented, the library calls this during `initialize()` if the\n * consumer omitted `products` from `createIAP()` config — letting the\n * backend curate which SKUs are surfaced (feature flags, A/B mixes,\n * regional catalogs). Returned ids MUST still be pre-registered in App\n * Store Connect / Google Play Console; the manifest is a curated subset,\n * not a registration.\n */\n listProducts?(): Promise<ConfiguredProduct[]>;\n /**\n * Optional: verify a transaction **without** extracting it into the HTTP\n * request shapes.\n *\n * `VerifyAppleRequest` and `VerifyGoogleRequest` carry what a server needs\n * to look a receipt up — a product id and a token. An on-device check\n * needs more than that: the binding, the subscription state, the expiry.\n * Rather than widen the HTTP contract (and so change what gets sent over\n * the wire), an adapter that can answer from the transaction itself\n * implements this, and the router prefers it.\n *\n * Implemented by the built-in local-verification adapter. The HTTP path\n * does not implement it and is unaffected.\n */\n verifyNative?(transaction: NativeTransaction): Promise<VerifyResponse<TEntitlement>>;\n /**\n * Optional counterpart to {@link verifyNative} for restore: the owned\n * transactions, unextracted.\n *\n * Avoids two problems for an adapter that answers from the transaction.\n * It needs the fields `RestoreRequestTransaction` drops; and building\n * that request requires a `packageName` on every Google transaction,\n * which such an adapter never reads — so a request it would discard\n * could fail the restore outright.\n */\n restoreNative?(owned: NativeTransaction[]): Promise<RestoreResponse<TEntitlement>>;\n}\n\n/** Type guard; consumers passing a custom adapter via config get a runtime check. */\nexport function isBackendAdapter(value: unknown): value is BackendAdapter {\n if (!value || typeof value !== 'object') return false;\n const candidate = value as Partial<BackendAdapter>;\n if (typeof candidate.getEntitlements !== 'function') return false;\n\n // Either the extracted per-platform pair, or the whole-transaction form.\n // An adapter that verifies from the transaction has no use for the\n // extracted shapes, and requiring it to stub them out would be a tax on\n // the pattern the docs recommend for on-device verification.\n const hasExtracted =\n typeof candidate.verifyApple === 'function' &&\n typeof candidate.verifyGoogle === 'function' &&\n typeof candidate.restore === 'function';\n const hasNative =\n typeof candidate.verifyNative === 'function' &&\n (typeof candidate.restore === 'function' || typeof candidate.restoreNative === 'function');\n\n return hasExtracted || hasNative;\n}\n","import type { ProductType } from '../types/product.js';\nimport type { NativeTransaction, Platform, SubscriptionRenewal } from '../types/transaction.js';\n\n/**\n * How strongly a purchase was checked. Exposed rather than hidden, because\n * the two platforms genuinely differ and a consumer deciding what to unlock\n * offline deserves to know which one it got.\n *\n * - `store-signed` — iOS. StoreKit 2 verified Apple's signature over the\n * transaction in native code before it ever reached the WebView; the\n * native layer resolves a purchase only for a `VerificationResult.verified`\n * and rejects anything else. So this is a cryptographic guarantee, made by\n * the platform rather than by iap.\n * - `store-reported` — Android. The native layer exposes neither Play's\n * purchase signature nor the original JSON, so **no cryptographic check is\n * possible on the device**. This means \"Play told this device it owns\n * this\", which is a real answer and the one Play's own client APIs give —\n * but it is the store's say-so, not proof.\n *\n * Neither is a substitute for server-side validation against the store's\n * API. A rooted device can lie to the app about both.\n */\nexport type PurchaseAssurance = 'store-signed' | 'store-reported';\n\n/** Why a local check refused a purchase. Stable strings, safe to switch on. */\nexport type LocalVerificationError =\n | 'PRODUCT_NOT_CONFIGURED'\n | 'BINDING_MISMATCH'\n /**\n * The app binds purchases to an account, and there is no account to bind\n * to right now — a signed-out session, or a `verification.appUserId`\n * getter that threw. Raised by `LocalVerificationAdapter`, never by\n * {@link verifyPurchaseOnDevice}, which is told the binding rather than\n * resolving it.\n */\n | 'BINDING_UNAVAILABLE'\n | 'NOT_PURCHASED'\n | 'REVOKED'\n | 'SUBSCRIPTION_EXPIRED';\n\n/** A purchase that passed the on-device checks. */\nexport interface LocallyVerifiedPurchase {\n productId: string;\n platform: Platform;\n /**\n * What the purchase was bought as.\n *\n * Exposed because it changes what an entitlement *means*, and a mapper\n * needs to know. In particular iOS's owned set retains **finished\n * consumables**, so a mapper that grants on every verified purchase\n * re-grants a consumable on every refresh, forever. A consumable's effect\n * belongs in your own records, not in a standing entitlement.\n */\n productType: ProductType;\n /** Stable across renewals. See `NativeTransaction.purchaseReference`. */\n purchaseReference: string;\n /** The binding the purchase carried, or `null`. */\n appUserId: string | null;\n /** ISO 8601 for a subscription; `null` for a non-expiring purchase. */\n expiresAt: string | null;\n subscription: SubscriptionRenewal | null;\n /** How strongly this was checked. See {@link PurchaseAssurance}. */\n assurance: PurchaseAssurance;\n}\n\nexport type LocalVerification =\n | { valid: true; purchase: LocallyVerifiedPurchase }\n | { valid: false; error: LocalVerificationError; message: string };\n\nexport interface LocalVerificationOptions {\n /**\n * Product ids the app sells. A transaction for anything else is refused —\n * the store can report purchases from a previous version of the app, or\n * from a product that has since been retired.\n */\n productIds: readonly string[];\n /**\n * When set, the purchase must carry this binding. Compared\n * case-insensitively, because StoreKit returns an uppercase UUID string\n * while callers deal in lowercase.\n *\n * `null` or omitted skips the check: a purchase made before the app\n * started binding, or a flow with no user identity, carries none.\n */\n appUserId?: string | null;\n /** Extra time past `expiresAt` during which a subscription still counts. */\n graceMs?: number;\n /** Injectable clock. Defaults to `Date.now`. */\n now?: () => number;\n}\n\n/**\n * Whether an ISO 8601 expiry has passed, by the **device** clock.\n *\n * The device clock is the only clock available with no backend, and it can\n * be wrong — a user can set it back and extend a subscription. That is the\n * accepted cost of working offline, and the reason this is not a substitute\n * for server-side validation.\n *\n * An unparseable or absent expiry is treated as \"does not expire\" rather\n * than \"expired\": refusing a purchase because its expiry string was\n * malformed would revoke access over a formatting problem.\n *\n * `expiresAt` must be ISO 8601. `Date.parse` is lenient and\n * implementation-defined for anything else — `'10/26/2026'` parses as\n * *local* time in V8 — so a non-ISO string may compare against the wrong\n * instant. Everything iap produces is ISO 8601; this matters only for a\n * value you supply. An exact boundary (`now === expiry`) reads as active.\n */\nexport function isExpired(expiresAt: string | null | undefined, now: number, graceMs = 0): boolean {\n if (!expiresAt) return false;\n const expiry = Date.parse(expiresAt);\n if (Number.isNaN(expiry)) return false;\n // A non-finite grace would make `now > expiry + grace` false for every\n // date, so nothing would ever expire. This is a public export, so the\n // config schema's validation is not the only gate.\n const grace = Number.isFinite(graceMs) ? graceMs : 0;\n return now > expiry + grace;\n}\n\n/**\n * Check a purchase on the device, with no backend.\n *\n * This is the whole of what can be checked without a server, and it is\n * deliberately a short list:\n *\n * 1. The product is one the app actually sells.\n * 2. The binding matches, when one is expected.\n * 3. On Android, the store calls the purchase purchased rather than pending.\n * 4. The purchase has not been revoked or refunded, where the platform\n * says so locally (iOS does; Android does not).\n * 5. A subscription has not expired by the device clock.\n *\n * What it does **not** do is verify a signature. On iOS it does not need to —\n * the platform already did, natively, and {@link PurchaseAssurance}\n * records that. On Android it cannot: the native layer exposes neither\n * Play's purchase signature nor the original JSON it is computed over.\n *\n * So a passing result means \"this device's store says it owns this, and the\n * claim is internally consistent\" — strong on iOS, the store's word on\n * Android. For anything where being wrong is expensive, verify server-side.\n */\nexport function verifyPurchaseOnDevice(\n transaction: NativeTransaction,\n options: LocalVerificationOptions,\n): LocalVerification {\n const now = (options.now ?? Date.now)();\n\n if (!options.productIds.includes(transaction.productId)) {\n return {\n valid: false,\n error: 'PRODUCT_NOT_CONFIGURED',\n message: `The store reported a purchase of \"${transaction.productId}\", which is not in the configured product list.`,\n };\n }\n\n const expected = options.appUserId;\n if (expected) {\n const actual = transaction.appUserId ?? null;\n if (actual === null || actual.toLowerCase() !== expected.toLowerCase()) {\n return {\n valid: false,\n error: 'BINDING_MISMATCH',\n message: `The purchase of \"${transaction.productId}\" is not bound to the expected account.`,\n };\n }\n }\n\n // Android reports a purchase awaiting clearance as owned-but-not-purchased.\n // `getOwnedTransactions` already filters those out, so this is a second\n // line of defence for a transaction that reached here another way.\n if (transaction.platform === 'google') {\n const state = (transaction.raw as { purchaseState?: unknown } | undefined)?.purchaseState;\n // Coerced, not type-narrowed: the value crosses a native bridge, and a\n // `typeof === 'string'` gate would skip the check entirely if the plugin\n // ever sent a number. Play's own enum has PURCHASED = 1.\n if (state !== undefined && state !== null && String(state) !== '1') {\n return {\n valid: false,\n error: 'NOT_PURCHASED',\n message: `The purchase of \"${transaction.productId}\" is not in Play's purchased state.`,\n };\n }\n }\n\n // A refund or revocation, which iOS **does** report on the device — and\n // which the owned set still contains, because `Transaction.all` retains\n // revoked transactions. Missing this granted a refunded non-expiring\n // purchase forever, since it has no expiry to fall back on.\n //\n // Android reports none of this locally: a refunded Play purchase simply\n // disappears from the owned set, which is why refund detection there needs\n // the server API.\n const revocationDate = (transaction.raw as { revocationDate?: unknown } | undefined)\n ?.revocationDate;\n if (transaction.subscription?.state === 'revoked' || typeof revocationDate === 'string') {\n return {\n valid: false,\n error: 'REVOKED',\n message: `The purchase of \"${transaction.productId}\" has been revoked or refunded.`,\n };\n }\n\n const expiresAt = transaction.subscription?.expiresAt ?? null;\n if (isExpired(expiresAt, now, options.graceMs)) {\n return {\n valid: false,\n error: 'SUBSCRIPTION_EXPIRED',\n message: `The subscription \"${transaction.productId}\" expired at ${expiresAt}.`,\n };\n }\n\n return {\n valid: true,\n purchase: {\n productId: transaction.productId,\n platform: transaction.platform,\n productType: transaction.productType,\n purchaseReference: transaction.purchaseReference,\n appUserId: transaction.appUserId ?? null,\n expiresAt,\n subscription: transaction.subscription ?? null,\n // iOS transactions are signature-checked by StoreKit in native code\n // before they cross the bridge; Android has no equivalent available.\n assurance: transaction.platform === 'apple' ? 'store-signed' : 'store-reported',\n },\n };\n}\n","import { z } from 'zod';\nimport { verifyPurchaseOnDevice } from '../../core/local-verification.js';\nimport type {\n LocalVerificationError,\n LocalVerificationOptions,\n LocallyVerifiedPurchase,\n} from '../../core/local-verification.js';\nimport { IAPError, IAPErrorCode } from '../../lib/errors.js';\nimport type { Logger } from '../../lib/logger.js';\nimport { isValidUuid } from '../../lib/uuid.js';\nimport { entitlementBaseSchema } from '../../types/entitlement.js';\nimport type { EntitlementBase } from '../../types/entitlement.js';\nimport type { ConfiguredProduct } from '../../types/product.js';\nimport type { NativeTransaction } from '../../types/transaction.js';\nimport type { NativeAdapter } from '../native/types.js';\nimport type { BackendAdapter, RestoreRequest, RestoreResponse, VerifyResponse } from './types.js';\n\nexport interface LocalVerificationAdapterOptions<TEntitlement extends EntitlementBase> {\n /**\n * Resolved lazily: the native adapter is constructed in `initialize()`,\n * after this adapter, and is needed to read what the store owns.\n */\n getNativeAdapter: () => NativeAdapter | null;\n getProducts: () => readonly ConfiguredProduct[];\n /** Maps a verified purchase to the entitlements it grants. */\n entitlements: (purchase: LocallyVerifiedPurchase) => TEntitlement[];\n /**\n * The binding every purchase must carry, resolved **at the time of each\n * check** so it can follow the session.\n *\n * Present means the app binds purchases; omitted means it does not. A\n * present resolver returning `null` is therefore \"the app binds\n * purchases and nobody is signed in\", which refuses rather than\n * silently dropping the check — see {@link LocalVerificationAdapter}.\n */\n getAppUserId?: () => string | null;\n /**\n * The entitlements currently held, so an ambiguous answer from the store\n * can preserve them rather than wipe them. See {@link getEntitlements}.\n */\n getCurrentEntitlements: () => TEntitlement[];\n graceMs: number;\n logger: Logger;\n}\n\n/**\n * Verifies purchases on the device, with no backend.\n *\n * Implemented as a `BackendAdapter` on purpose. iap's safety guarantees —\n * persist before verifying, acknowledge only after verification succeeds,\n * retry anything unfinished on the next launch — all live in the purchase\n * and recovery flows, above this interface. Making local mode an adapter\n * means those flows are **untouched** by it: there is no second purchase\n * path to keep in step, and the no-backend case gets exactly the same\n * crash-safety as the backend case.\n *\n * It is not a stub or a bypass. Every verification still happens, still\n * gates acknowledgement, and can still fail — it is just answered on the\n * device instead of over the network.\n *\n * **What the device cannot do**, and what the docs say plainly: check Play's\n * purchase signature (the native layer does not expose it), detect a refund\n * Apple has not yet reflected in the local receipt, or resist a device whose\n * clock or store client is lying. A purchase's\n * {@link LocallyVerifiedPurchase.assurance} records which of the two\n * strengths it got. If being wrong is expensive, use a backend.\n */\nexport class LocalVerificationAdapter<TEntitlement extends EntitlementBase = EntitlementBase>\n implements BackendAdapter<TEntitlement>\n{\n constructor(private readonly opts: LocalVerificationAdapterOptions<TEntitlement>) {}\n\n /**\n * The whole transaction, not the extracted fields the HTTP contract sends.\n *\n * A local check needs the binding, the subscription state and the expiry,\n * and `VerifyAppleRequest` carries none of them — it is shaped for what a\n * server needs to look a receipt up. The router prefers this method when\n * an adapter has it, so the HTTP path is unaffected.\n */\n async verifyNative(transaction: NativeTransaction): Promise<VerifyResponse<TEntitlement>> {\n const checked = this.check(transaction);\n if (!checked.valid) return checked;\n\n // Return the **consolidated** set, not just this purchase's.\n //\n // The flows treat `VerifyResponse.entitlements` as the whole truth and\n // replace state with it, which is what a backend returns. Returning one\n // purchase's worth here silently revoked everything else: buying a\n // consumable wiped a subscription, in memory and on disk, until the next\n // refresh.\n //\n // The store may not report the just-bought purchase yet, so it is merged\n // in explicitly rather than relied upon.\n return {\n valid: true,\n entitlements: await this.consolidated(checked.purchase),\n transaction: checked.transaction,\n };\n }\n\n /**\n * Unreachable in practice: the router prefers {@link verifyNative}. Kept\n * because `BackendAdapter` requires them, and failing loudly is better\n * than silently granting if a future caller bypasses the router.\n */\n async verifyApple(): Promise<VerifyResponse<TEntitlement>> {\n throw this.unsupported('verifyApple');\n }\n\n async verifyGoogle(): Promise<VerifyResponse<TEntitlement>> {\n throw this.unsupported('verifyGoogle');\n }\n\n /**\n * In local mode the store **is** the source of truth, so a refresh asks\n * it what it owns and re-derives entitlements from that.\n *\n * This is why `refreshOnResume` keeps working with no network: there is\n * nothing to reach. A purchase that expired while the app was backgrounded\n * drops out here, which is the only downgrade local mode performs.\n */\n async getEntitlements(): Promise<TEntitlement[]> {\n // Same asymmetry as the empty-store answer below: \"I cannot tell you\"\n // must never read as \"you own nothing\". A multi-user app restores its\n // session asynchronously, so an initial refresh — or a `refreshOnResume`\n // during a sign-out — can land while the binding is unresolved, and\n // re-deriving from nothing would revoke a paying user's access.\n //\n // Purchases and restores still refuse while it is unavailable; those\n // are the paths where failing closed is the safe direction.\n const binding = this.binding();\n if (!binding.ok) {\n this.opts.logger.debug(\n `Keeping the current entitlements: ${binding.error}. ${binding.message}`,\n );\n return this.opts.getCurrentEntitlements();\n }\n\n const owned = await this.ownedTransactions();\n\n // An empty answer is ambiguous, and must not downgrade anyone.\n //\n // Play resolves `getPurchases()` with an empty array when the query\n // *fails* — a disconnected billing service, a signed-out account, a\n // non-OK response code — rather than rejecting. So \"owns nothing\" and\n // \"could not tell you\" look identical, and treating the first as\n // authoritative would wipe a paying user's entitlements on a transient\n // store error, which is exactly what the offline guarantee forbids.\n //\n // `restorePurchases()` has always guarded this; `refresh()` did not,\n // and `refreshOnResume` calls it on every foreground.\n if (owned.length === 0) {\n const current = this.opts.getCurrentEntitlements();\n if (current.length > 0) {\n this.opts.logger.debug(\n 'The store reported nothing owned. Keeping the current entitlements, since an empty answer is indistinguishable from a failed query.',\n );\n }\n return current;\n }\n\n return this.consolidated();\n }\n\n /**\n * Restore is the same question as a refresh here — \"what does this store\n * account own\" — answered from the transactions the orchestrator already\n * read, so the store is not asked twice.\n */\n async restoreNative(owned: NativeTransaction[]): Promise<RestoreResponse<TEntitlement>> {\n const binding = this.binding();\n if (!binding.ok) {\n return { valid: false, error: binding.error, message: binding.message };\n }\n\n const { entitlements, verifiedTokens } = this.evaluate(owned);\n\n // `verifiedTokens` is what keeps the acknowledge-after-verification\n // invariant true on this path. Without it the orchestrator reads only\n // the top-level `valid` and acknowledges **every** owned transaction —\n // including ones this check refused, which on Android finalises the\n // purchase and waives Play's refund window for something just declared\n // invalid.\n if (verifiedTokens.length === 0) {\n return {\n valid: false,\n error: 'NO_VERIFIED_PURCHASES',\n message: 'The store reported purchases, but none passed the on-device checks.',\n };\n }\n\n return { valid: true, entitlements, verifiedTokens };\n }\n\n /**\n * Unreachable via the orchestrator, which prefers {@link restoreNative}.\n * Kept so the adapter satisfies a consumer holding it as a plain\n * `BackendAdapter`; it re-reads the store rather than trusting an\n * extracted request a local check cannot verify from.\n */\n async restore(_req: RestoreRequest): Promise<RestoreResponse<TEntitlement>> {\n return this.restoreNative(await this.ownedTransactions());\n }\n\n /**\n * The binding to check against, or a refusal.\n *\n * Read per check rather than once at construction, because a\n * `verification.appUserId` getter exists precisely so the binding can\n * follow the session: in a multi-user app a value captured at\n * `createIAP()` time is the previous user's after a switch, and every\n * purchase is then refused as a mismatch.\n *\n * The thing it will not do is treat \"no account right now\" as \"this app\n * uses no binding\". That would turn a signed-out session into an\n * unguarded one, accepting a purchase bound to **someone else** — a\n * weaker check than the app asked for, silently. Refusing is the safe\n * direction: the purchase stays unacknowledged and the store retries it.\n */\n private binding():\n | { ok: true; appUserId: string | null }\n | { ok: false; error: LocalVerificationError; message: string } {\n const resolve = this.opts.getAppUserId;\n if (!resolve) return { ok: true, appUserId: null };\n\n let value: string | null;\n try {\n value = resolve();\n } catch (error) {\n // A throwing getter is the same situation as a null one, and must\n // not fail open either.\n this.opts.logger.warn(\n 'verification.appUserId threw. Refusing purchases rather than dropping the binding check.',\n error,\n );\n return {\n ok: false,\n error: 'BINDING_UNAVAILABLE',\n message: 'The expected account binding could not be read.',\n };\n }\n\n if (value === null || value === undefined || value === '') {\n return {\n ok: false,\n error: 'BINDING_UNAVAILABLE',\n message:\n 'This app binds purchases to an account, and verification.appUserId resolved to none. Nothing can be verified until someone is signed in.',\n };\n }\n\n // Only the getter form reaches here unvalidated — the schema checks a\n // literal string. A non-UUID could never match a purchase, since\n // `purchase({ appUserId })` enforces the same constraint, so every\n // purchase would be refused as a mismatch with no clue why.\n if (!isValidUuid(value) && !this.warnedAboutBinding) {\n this.warnedAboutBinding = true;\n this.opts.logger.warn(\n 'verification.appUserId returned a value that is not an RFC 9562 UUID. purchase({ appUserId }) only accepts UUIDs, so no purchase can ever match it.',\n );\n }\n\n return { ok: true, appUserId: value };\n }\n\n /** Warned once per instance, not once per check — a refresh runs this. */\n private warnedAboutBinding = false;\n\n private checkOptions(appUserId: string | null): LocalVerificationOptions {\n return {\n productIds: this.opts.getProducts().map((p) => p.id),\n appUserId,\n graceMs: this.opts.graceMs,\n };\n }\n\n private check(transaction: NativeTransaction):\n | { valid: false; error: string; message: string }\n | {\n valid: true;\n purchase: LocallyVerifiedPurchase;\n transaction: { id: string; productId: string; expiresAt: string | null };\n } {\n const binding = this.binding();\n if (!binding.ok) {\n this.opts.logger.debug(\n `Local verification refused \"${transaction.productId}\": ${binding.error}.`,\n );\n return { valid: false, error: binding.error, message: binding.message };\n }\n\n const result = verifyPurchaseOnDevice(transaction, this.checkOptions(binding.appUserId));\n\n if (!result.valid) {\n this.opts.logger.debug(\n `Local verification refused \"${transaction.productId}\": ${result.error}.`,\n );\n return { valid: false, error: result.error, message: result.message };\n }\n\n return {\n valid: true,\n purchase: result.purchase,\n transaction: {\n // The purchase's own identity, not a server-assigned id — there is\n // no server to assign one. Note it is stable across renewals, so it\n // is not a per-transaction key.\n id: result.purchase.purchaseReference,\n productId: result.purchase.productId,\n expiresAt: result.purchase.expiresAt,\n },\n };\n }\n\n /**\n * Run the consumer's mapper and validate what it returns.\n *\n * Unlike a backend response, this value never went through a schema — it\n * comes straight from consumer code into iap's state and cache. An\n * unvalidated mapper could cache an object with no `key` (so\n * `hasEntitlement` could never match it, and the next launch would drop it\n * from the cache, making entitlements differ between sessions), or return\n * a non-array and throw a raw `TypeError` out of `purchase()` *after* the\n * transaction was acknowledged.\n */\n private map(purchase: LocallyVerifiedPurchase): TEntitlement[] {\n let mapped: unknown;\n try {\n mapped = this.opts.entitlements(purchase);\n } catch (error) {\n this.opts.logger.warn(\n `verification.entitlements threw for \"${purchase.productId}\"; granting nothing for it.`,\n error,\n );\n return [];\n }\n\n const parsed = z.array(entitlementBaseSchema.passthrough()).safeParse(mapped);\n if (!parsed.success) {\n this.opts.logger.warn(\n `verification.entitlements returned something that is not a list of entitlements for \"${purchase.productId}\"; granting nothing for it. Each entry needs a key, a productId and an expiresAt (which may be null).`,\n );\n return [];\n }\n\n return parsed.data as TEntitlement[];\n }\n\n /** The consolidated entitlements, optionally merging a just-verified purchase. */\n private async consolidated(extra?: LocallyVerifiedPurchase): Promise<TEntitlement[]> {\n const owned = await this.ownedTransactions();\n const { entitlements } = this.evaluate(owned, extra);\n return entitlements;\n }\n\n /**\n * Evaluate an owned set: which transactions passed, and what they grant.\n *\n * Returns the tokens that passed as well as the entitlements, because the\n * caller needs to know *which* transactions may be acknowledged — a\n * single consolidated list cannot say.\n */\n private evaluate(\n owned: NativeTransaction[],\n extra?: LocallyVerifiedPurchase,\n ): { entitlements: TEntitlement[]; verifiedTokens: string[] } {\n const binding = this.binding();\n // Unreachable from the three callers, which all resolve it first; kept\n // so this cannot silently verify against no binding if one is added.\n if (!binding.ok) return { entitlements: [], verifiedTokens: [] };\n\n const options = this.checkOptions(binding.appUserId);\n const verifiedTokens: string[] = [];\n const byKey = new Map<string, TEntitlement>();\n\n const absorb = (purchase: LocallyVerifiedPurchase): void => {\n for (const entitlement of this.map(purchase)) {\n const existing = byKey.get(entitlement.key);\n // iOS reports historical transactions alongside current ones, so one\n // key is derived several times. Keep the one that lasts longest —\n // keeping the first would discard the live renewal's entitlement in\n // favour of an older one still inside the grace window, and the\n // user's access would then lapse while the subscription was valid.\n if (!existing || outlasts(entitlement.expiresAt, existing.expiresAt)) {\n byKey.set(entitlement.key, entitlement);\n }\n }\n };\n\n for (const transaction of owned) {\n const result = verifyPurchaseOnDevice(transaction, options);\n if (!result.valid) {\n this.opts.logger.debug(\n `Local verification refused \"${transaction.productId}\": ${result.error}.`,\n );\n continue;\n }\n verifiedTokens.push(transaction.token);\n absorb(result.purchase);\n }\n\n if (extra) absorb(extra);\n\n return { entitlements: [...byKey.values()], verifiedTokens };\n }\n\n private async ownedTransactions(): Promise<NativeTransaction[]> {\n const native = this.opts.getNativeAdapter();\n if (!native) {\n throw new IAPError({\n code: IAPErrorCode.NOT_INITIALIZED,\n message: 'Local verification needs the native adapter; call iap.initialize() first.',\n });\n }\n return native.getOwnedTransactions();\n }\n\n private unsupported(method: string): IAPError {\n return new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message: `${method}() cannot verify locally: it receives only the extracted request fields, and an on-device check needs the binding, the subscription state and the expiry. Call verifyNative(transaction) instead — which is what iap's own router does.`,\n });\n }\n}\n\n/** Whether `a` lasts longer than `b`; a null expiry outlasts any date. */\nfunction outlasts(a: string | null, b: string | null): boolean {\n if (a === null) return true;\n if (b === null) return false;\n return Date.parse(a) > Date.parse(b);\n}\n","import { IAPError, IAPErrorCode } from '../../lib/errors.js';\nimport type { StorageConfig } from '../../types/config.js';\nimport { MemoryAdapter } from './memory-adapter.js';\nimport { PreferencesAdapter } from './preferences-adapter.js';\nimport type { StorageAdapter } from './types.js';\n\n/**\n * Build the storage adapter for the configured `storage.type`.\n *\n * - `'preferences'` → Capacitor Preferences (native + localStorage on web)\n * - `'memory'` → in-memory map (tests, ephemeral environments)\n * - `'custom'` → user-supplied adapter via `storage.adapter`\n */\nexport function selectStorageAdapter(config: StorageConfig): StorageAdapter {\n if (config.type === 'memory') {\n return new MemoryAdapter(config.namespace);\n }\n if (config.type === 'custom') {\n if (!isStorageAdapter(config.adapter)) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'storage.type is \"custom\" but storage.adapter is missing or does not implement StorageAdapter.',\n });\n }\n return config.adapter;\n }\n return new PreferencesAdapter(config.namespace);\n}\n\nfunction isStorageAdapter(value: unknown): value is StorageAdapter {\n if (!value || typeof value !== 'object') return false;\n const candidate = value as Partial<StorageAdapter>;\n return (\n typeof candidate.get === 'function' &&\n typeof candidate.set === 'function' &&\n typeof candidate.remove === 'function' &&\n typeof candidate.clear === 'function'\n );\n}\n\nexport type { StorageAdapter } from './types.js';\n","import type { StorageAdapter } from './types.js';\n\n/**\n * In-memory storage adapter. Used as the default for tests and on web\n * dev environments where Capacitor Preferences is unnecessary.\n *\n * Each instance owns its own Map — no global state. Namespace prefix is\n * prepended to keys so multiple instances against shared backing storage\n * (e.g., on the same device when used as a fallback) don't collide.\n */\nexport class MemoryAdapter implements StorageAdapter {\n private readonly store = new Map<string, string>();\n private readonly prefix: string;\n\n constructor(namespace: string) {\n this.prefix = `${namespace}.`;\n }\n\n async get(key: string): Promise<string | null> {\n return this.store.get(this.prefix + key) ?? null;\n }\n\n async set(key: string, value: string): Promise<void> {\n this.store.set(this.prefix + key, value);\n }\n\n async remove(key: string): Promise<void> {\n this.store.delete(this.prefix + key);\n }\n\n async clear(): Promise<void> {\n for (const key of [...this.store.keys()]) {\n if (key.startsWith(this.prefix)) this.store.delete(key);\n }\n }\n}\n","import { IAPError, IAPErrorCode } from '../../lib/errors.js';\nimport type { StorageAdapter } from './types.js';\n\n/** The slice of the plugin this adapter uses. */\ntype PreferencesPlugin = Pick<\n typeof import('@capacitor/preferences').Preferences,\n 'get' | 'set' | 'remove'\n>;\n\n/**\n * Storage adapter backed by `@capacitor/preferences`.\n *\n * On iOS/Android, Preferences uses native key-value stores\n * (NSUserDefaults / SharedPreferences). On web it transparently falls\n * back to `localStorage`, which means cached entitlements and\n * unfinished transactions survive page reloads in browser dev too.\n *\n * Keys are prefixed with `${namespace}.` to avoid collisions with other\n * Preferences consumers in the same app.\n *\n * ## Why the plugin is loaded lazily\n *\n * `@capacitor/preferences` is an **optional** peer dependency, and it is\n * reached only through the `await import()` below. A static import would be\n * hoisted into the bundle's top-level imports, so every consumer would ship\n * the native plugin — including one that passes `storage.type: 'custom'` and\n * never touches Preferences at all.\n *\n * Note this is about *bundling*, not resolution. A bundler still resolves a\n * dynamic import at build time — Rollup fails with\n * `failed to resolve import \"@capacitor/preferences\"` — so an app that\n * actually uninstalls the package has to externalise it. The installation\n * guide carries the config. What the lazy import buys is that the plugin is\n * not pulled into the top-level graph of every consumer that keeps it\n * installed but never selects `storage.type: 'preferences'`.\n *\n * {@link PreferencesAdapter.ensureAvailable} exists so `initialize()` can\n * surface a missing plugin immediately rather than letting it appear as an\n * unreadable cache: the cache read is deliberately tolerant of failure, so\n * without the early check a missing plugin would look like an empty cache\n * and iap would silently persist nothing.\n */\nexport class PreferencesAdapter implements StorageAdapter {\n private readonly prefix: string;\n private readonly knownKeys = new Set<string>();\n /**\n * Boxed, and that is not incidental — see {@link PreferencesAdapter.preferences}.\n */\n private plugin: Promise<{ preferences: PreferencesPlugin }> | null = null;\n\n constructor(namespace: string) {\n this.prefix = `${namespace}.`;\n }\n\n /**\n * The plugin, inside a box.\n *\n * The box is load-bearing. `registerPlugin()` hands back a **Proxy** that\n * answers any property, `then` included — so resolving a promise *with*\n * the plugin makes it look like a thenable, and promise assimilation\n * calls `Preferences.then()`. On web that rejects with\n * `\"Preferences.then()\" is not implemented on web`, from inside\n * `await this.preferences()`, for every storage operation.\n *\n * Wrapping it in a plain object means the promise resolves with something\n * that has no `then`, so nothing is assimilated.\n */\n private preferences(): Promise<{ preferences: PreferencesPlugin }> {\n this.plugin ??= import('@capacitor/preferences')\n .then((mod) => ({ preferences: mod.Preferences }))\n .catch((cause) => {\n // Two different failures, and conflating them was wrong in both\n // directions: \"the package is not installed\" is a configuration\n // problem no retry can fix, while \"the chunk did not load\" is a\n // network problem a retry may well fix. Only the second clears the\n // memo — caching the rejection for the first is what stops every\n // later storage call re-requesting a module that is not there.\n if (isModuleNotFound(cause)) throw notInstalled(cause);\n this.plugin = null;\n throw new IAPError({\n code: IAPErrorCode.STORAGE_ERROR,\n message:\n 'Could not load @capacitor/preferences. The package is installed, so this is most likely a chunk that failed to load; it is worth retrying.',\n cause,\n recoverable: true,\n });\n });\n return this.plugin;\n }\n\n /**\n * Resolve the plugin now, so a missing one is reported at `initialize()`.\n *\n * See the note on lazy loading above for why this is not left to the first\n * `get()`.\n */\n async ensureAvailable(): Promise<void> {\n await this.preferences();\n }\n\n async get(key: string): Promise<string | null> {\n // Resolved outside the try so its own error survives: a missing plugin\n // is a configuration problem, and re-wrapping it as a transient\n // STORAGE_ERROR is what the recovery loop acts on — it would retry at\n // every launch forever for a cause no retry can fix.\n const { preferences } = await this.preferences();\n try {\n const result = await preferences.get({ key: this.prefix + key });\n return result.value;\n } catch (cause) {\n throw wrap(cause, `Preferences.get failed for \"${key}\".`);\n }\n }\n\n async set(key: string, value: string): Promise<void> {\n const { preferences } = await this.preferences();\n try {\n await preferences.set({ key: this.prefix + key, value });\n this.knownKeys.add(key);\n } catch (cause) {\n throw wrap(cause, `Preferences.set failed for \"${key}\".`);\n }\n }\n\n async remove(key: string): Promise<void> {\n const { preferences } = await this.preferences();\n try {\n await preferences.remove({ key: this.prefix + key });\n this.knownKeys.delete(key);\n } catch (cause) {\n throw wrap(cause, `Preferences.remove failed for \"${key}\".`);\n }\n }\n\n async clear(): Promise<void> {\n const { preferences } = await this.preferences();\n // We can't ask Preferences to clear-by-prefix, so we remove the keys\n // we know about. Phase 2/3/4/6 each only touch a small fixed set.\n const keys = [...this.knownKeys];\n\n // A key whose removal fails is **kept** in the known set, so a later\n // clear tries it again. `reset()` relies on exactly that: it removes\n // every registry key by name and then calls this, and its comment says\n // the trailing clear gives a failed key a second attempt. Dropping the\n // whole set up front — which this used to do — made that untrue, and\n // left a key on the device that nothing would ever try again.\n const failed: string[] = [];\n const errors: unknown[] = [];\n await Promise.all(\n keys.map(async (key) => {\n try {\n await preferences.remove({ key: this.prefix + key });\n this.knownKeys.delete(key);\n } catch (cause) {\n failed.push(key);\n errors.push(cause);\n }\n }),\n );\n\n if (failed.length > 0) {\n // Wrapped like every other method, rather than letting a raw plugin\n // rejection escape as something that is not an IAPError.\n throw wrap(errors[0], `Preferences.clear failed for ${failed.length} key(s).`);\n }\n }\n}\n\n/**\n * Whether a dynamic-import failure means \"not installed\" rather than\n * \"did not load this time\".\n *\n * Node sets a `code`; bundlers and browsers only give a message, and they\n * word it differently, so both are checked.\n *\n * The **`cause` chain** is walked because the error that reaches here is\n * often not the original: module loaders and dev servers wrap it, and the\n * reason only survives one level down. Depth-bounded rather than recursive\n * to the end, since a `cause` chain can be circular.\n */\nfunction isModuleNotFound(cause: unknown): boolean {\n let current: unknown = cause;\n for (let depth = 0; depth < 5 && current; depth += 1) {\n const code = (current as { code?: unknown }).code;\n if (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND') return true;\n\n const message = current instanceof Error ? current.message : String(current);\n if (/cannot find (module|package)|could not resolve|failed to resolve/i.test(message)) {\n return true;\n }\n\n const next = (current as { cause?: unknown }).cause;\n if (next === current) break;\n current = next;\n }\n return false;\n}\n\nfunction notInstalled(cause: unknown): IAPError {\n return new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'storage.type is \"preferences\" (the default) but @capacitor/preferences is not installed. Install it (npm i @capacitor/preferences && npx cap sync), or choose storage that needs no plugin: storage.type \"memory\", or \"custom\" with your own adapter.',\n // The per-code hint for INVALID_CONFIG sends the reader to check field\n // paths against the config schema. There are none to check, and no\n // config change fixes this — the message above already says what to do.\n includeHint: false,\n cause,\n });\n}\n\nfunction wrap(cause: unknown, message: string): IAPError {\n return new IAPError({\n code: IAPErrorCode.STORAGE_ERROR,\n message,\n cause,\n recoverable: true,\n });\n}\n","import type { StorageAdapter } from '../adapters/storage/types.js';\nimport { IAPError, IAPErrorCode, toIAPError } from '../lib/errors.js';\nimport type { Logger } from '../lib/logger.js';\nimport { entitlementBaseSchema } from '../types/entitlement.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport { isExpired } from './local-verification.js';\nimport { IAP_STORAGE_KEYS } from './storage-keys.js';\n\nconst ENTITLEMENTS_KEY = IAP_STORAGE_KEYS.entitlements;\n\ninterface CacheEnvelope<T> {\n entitlements: T[];\n cachedAt: number;\n}\n\nexport interface CacheLoadResult<T extends EntitlementBase> {\n entitlements: T[];\n cachedAt: number;\n}\n\n/**\n * Persists the consumer's entitlements list to a {@link StorageAdapter}\n * with a cachedAt timestamp so refresh logic (Phase 6) can reason\n * about staleness.\n *\n * Generic over `TEntitlement` so consumer-defined fields pass through.\n * Validates only the {@link EntitlementBase} subset on read; if the\n * stored payload is structurally wrong we drop the cache rather than\n * crash, since stale or corrupt cache should never block the app.\n */\nexport class EntitlementCache<TEntitlement extends EntitlementBase> {\n constructor(\n private readonly storage: StorageAdapter,\n private readonly logger: Logger,\n ) {}\n\n async load(): Promise<CacheLoadResult<TEntitlement> | null> {\n let raw: string | null;\n try {\n raw = await this.storage.get(ENTITLEMENTS_KEY);\n } catch (cause) {\n this.logger.warn('Storage read failed; treating cache as empty.', cause);\n return null;\n }\n if (!raw) return null;\n\n let parsed: CacheEnvelope<unknown>;\n try {\n parsed = JSON.parse(raw) as CacheEnvelope<unknown>;\n } catch (cause) {\n this.logger.warn('Cached entitlements payload is not valid JSON; clearing.', cause);\n await this.safeRemove();\n return null;\n }\n\n if (\n !parsed ||\n typeof parsed !== 'object' ||\n typeof parsed.cachedAt !== 'number' ||\n !Array.isArray(parsed.entitlements)\n ) {\n this.logger.warn('Cached entitlements envelope has unexpected shape; clearing.');\n await this.safeRemove();\n return null;\n }\n\n const validated: TEntitlement[] = [];\n for (const item of parsed.entitlements) {\n const result = entitlementBaseSchema.safeParse(item);\n if (!result.success) {\n this.logger.warn('Dropping cached entitlement that fails base validation.', result.error);\n continue;\n }\n validated.push(item as TEntitlement);\n }\n\n return { entitlements: validated, cachedAt: parsed.cachedAt };\n }\n\n /** Returns the `cachedAt` timestamp written so callers can keep their\n * in-memory copy of the timestamp in sync with disk. */\n async save(entitlements: TEntitlement[]): Promise<number> {\n const cachedAt = Date.now();\n const envelope: CacheEnvelope<TEntitlement> = {\n entitlements,\n cachedAt,\n };\n try {\n await this.storage.set(ENTITLEMENTS_KEY, JSON.stringify(envelope));\n } catch (cause) {\n // `toIAPError`, not a fresh IAPError: an error that already *is* an\n // IAPError keeps its own code. A storage adapter can fail for a\n // reason that is not transient — `PreferencesAdapter` raises\n // INVALID_CONFIG when its plugin is not installed — and flattening\n // that to a `recoverable: true` STORAGE_ERROR is what the recovery\n // loop acts on, so the entry would be retried at every launch\n // forever for a cause no retry can fix.\n throw toIAPError(cause, 'Failed to persist entitlement cache.', IAPErrorCode.STORAGE_ERROR);\n }\n return cachedAt;\n }\n\n async clear(): Promise<void> {\n await this.safeRemove();\n }\n\n private async safeRemove(): Promise<void> {\n try {\n await this.storage.remove(ENTITLEMENTS_KEY);\n } catch (cause) {\n this.logger.warn('Failed to remove corrupt entitlement cache.', cause);\n }\n }\n}\n\n/**\n * The entitlements that are still active, by the **device** clock.\n *\n * iap's offline rule, in one function: an entitlement is dropped only when\n * its `expiresAt` has passed (plus any configured grace), never because a\n * refresh failed or the cache is old. A network error must not downgrade\n * anyone — the cached answer stands until the store's own deadline says\n * otherwise, or until an authoritative negative replaces it.\n *\n * The device clock can be wrong, and a user who sets it back can extend a\n * subscription. That is the price of answering offline at all; a backend is\n * the fix if it matters.\n */\nexport function activeEntitlements<T extends EntitlementBase>(\n entitlements: readonly T[],\n now: number,\n graceMs = 0,\n): T[] {\n return entitlements.filter((entitlement) => !isExpired(entitlement.expiresAt, now, graceMs));\n}\n\n/**\n * Shallow-equal comparator on the {@link EntitlementBase} fields.\n * Used by the orchestrators to skip emitting `entitlements-changed` when\n * a refresh / recovery / restore returns content-identical lists — avoids\n * spurious re-renders in reactive consumer stores.\n *\n * \"Content-identical\" means: same length, same `(key, productId, expiresAt)`\n * triples in the same order. Consumer-defined fields are NOT compared\n * because the library doesn't know their shape — if you need finer-grained\n * change detection, subscribe and run your own equality check on payload.\n */\nexport function entitlementsEqual(a: EntitlementBase[], b: EntitlementBase[]): boolean {\n if (a === b) return true;\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n const x = a[i];\n const y = b[i];\n if (!x || !y) return false;\n if (x.key !== y.key || x.productId !== y.productId || x.expiresAt !== y.expiresAt) {\n return false;\n }\n }\n return true;\n}\n","/**\n * Every storage key iap owns, in one place.\n *\n * It exists for `reset()`. The keys used to be declared in three separate\n * store modules, so \"erase everything iap stored\" was a hand-maintained list\n * that happened to match — and a future store added without someone\n * remembering to touch `reset()` would have survived a delete-everything\n * silently, which is the kind of bug nobody finds until it matters.\n *\n * Adding a store means adding its key here, and the test over\n * {@link IAP_STORAGE_KEYS} is what makes forgetting fail loudly rather than\n * quietly.\n *\n * These are relative to the configured storage namespace (`nosslabs_iap` by\n * default), not absolute — the storage adapter prefixes them.\n */\nexport const IAP_STORAGE_KEYS = {\n /** The entitlement cache envelope. See `EntitlementCache`. */\n entitlements: 'entitlements',\n /** Purchases awaiting backend confirmation. See `UnfinishedTransactionsStore`. */\n unfinishedTransactions: 'unfinished_transactions',\n /** Products reported as awaiting clearance. See `PendingPurchasesStore`. */\n pendingPurchases: 'pending_purchases',\n} as const;\n\nexport type IapStorageKey = (typeof IAP_STORAGE_KEYS)[keyof typeof IAP_STORAGE_KEYS];\n\n/**\n * The keys as a list, for anything that clears or audits all of them.\n *\n * Frozen, not merely typed `readonly`: `Object.values()` hands back an\n * ordinary mutable array, and a caller that spliced it would quietly shrink\n * what `reset()` erases.\n */\nexport const ALL_IAP_STORAGE_KEYS: readonly IapStorageKey[] = Object.freeze(\n Object.values(IAP_STORAGE_KEYS),\n);\n","import type { BackendAdapter } from '../adapters/backend/types.js';\nimport type { NativeAdapter, TransactionWatchHandle } from '../adapters/native/types.js';\nimport type { StorageAdapter } from '../adapters/storage/types.js';\nimport type { TypedEventEmitter } from '../events/emitter.js';\nimport { IAPError, IAPErrorCode } from '../lib/errors.js';\nimport type { Logger } from '../lib/logger.js';\nimport type { IAPConfig } from '../types/config.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport type { ConfiguredProduct } from '../types/product.js';\nimport type { AppResumeListenerHandle } from './app-resume-listener.js';\nimport type { EntitlementCache } from './entitlement-cache.js';\nimport type { PendingPurchasesStore } from './pending-purchases.js';\nimport type { PurchaseOrchestrator } from './purchase-flow.js';\nimport type { RecoveryOrchestrator } from './recovery-flow.js';\nimport type { RestoreOrchestrator } from './restore-flow.js';\nimport type { TransactionUpdateOrchestrator } from './transaction-updates.js';\nimport type { UnfinishedTransactionsStore } from './unfinished-transactions.js';\n\n/**\n * The mutable state one `createIAP()` instance owns.\n *\n * Passed around as a bag rather than captured in the factory's closure, so\n * the lifecycle steps can live in their own modules instead of accumulating\n * inside one 200-line function. Every lifecycle feature so far landed in\n * `initialize()`; this is what stops the next one from doing the same.\n */\nexport interface IAPInternalState<TEntitlement extends EntitlementBase> {\n config: IAPConfig;\n /** Populated by initialize(); null beforehand. Lazy to avoid loading\n * `@capgo/native-purchases` on web platforms (PLAN.md §9 / review C4). */\n adapter: NativeAdapter | null;\n /** Backend transport. Constructed eagerly in the factory so config errors\n * surface immediately; methods are not invoked until refresh()/purchase(). */\n backend: BackendAdapter<TEntitlement>;\n storage: StorageAdapter;\n cache: EntitlementCache<TEntitlement>;\n unfinished: UnfinishedTransactionsStore;\n pending: PendingPurchasesStore;\n /** Constructed lazily in initialize() once the native adapter is resolved. */\n orchestrator: PurchaseOrchestrator<TEntitlement> | null;\n /** Constructed alongside the orchestrator in initialize(). */\n restorer: RestoreOrchestrator<TEntitlement> | null;\n /** Constructed alongside the orchestrator; recovery runs once at init. */\n recoverer: RecoveryOrchestrator<TEntitlement> | null;\n /** Handles transactions arriving outside a purchase, and pending resolution. */\n updates: TransactionUpdateOrchestrator<TEntitlement> | null;\n /** Native transaction-feed listener; null when the platform has none. */\n txWatch: TransactionWatchHandle | null;\n /** App resume listener handle; null when refreshOnResume is disabled, on\n * web, or when @capacitor/app isn't installed. */\n resumeListener: AppResumeListenerHandle | null;\n emitter: TypedEventEmitter<TEntitlement>;\n logger: Logger;\n initialized: boolean;\n destroyed: boolean;\n entitlements: TEntitlement[];\n /** Timestamp of the last cache write, used for TTL-based background refresh. */\n cachedAt: number | null;\n /**\n * Resolved SKU manifest. Populated in `initialize()` from either the\n * static `config.products` or `backend.listProducts()`. Read by\n * `getProducts()`, `purchase()`, and the orchestrators.\n */\n products: ConfiguredProduct[];\n}\n\nexport function freezeAll<T extends object>(items: T[]): T[] {\n return items.map((item) => Object.freeze({ ...item }));\n}\n\nexport function ensureUniqueProductIds(products: ConfiguredProduct[]): void {\n const seen = new Set<string>();\n for (const product of products) {\n if (seen.has(product.id)) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message: `Duplicate product id \"${product.id}\" in product manifest.`,\n });\n }\n seen.add(product.id);\n }\n}\n\nexport function requireInitialized<TEntitlement extends EntitlementBase>(\n state: IAPInternalState<TEntitlement>,\n): void {\n if (!state.initialized) {\n throw new IAPError({\n code: IAPErrorCode.NOT_INITIALIZED,\n message: 'Call iap.initialize() before this method.',\n });\n }\n}\n","import type { Logger } from '../../lib/logger.js';\nimport { getPlatform } from '../../lib/platform.js';\nimport type { ConfiguredProduct } from '../../types/product.js';\nimport type { NativeAdapter } from './types.js';\nimport { WebStubAdapter } from './web/web-stub.js';\n\n/**\n * Select the appropriate native adapter for the runtime platform.\n *\n * - iOS / Android → capgo adapter wrapping `@capgo/native-purchases` (^8.0.0,\n * the Capacitor 8 line), reached via dynamic import so the adapter's *code*\n * doesn't run on web.\n * - web → no-op stub (purchases reject with PLATFORM_NOT_SUPPORTED).\n *\n * The deferral is execution-only, not module-graph: `tsup` builds with\n * `splitting: false`, so esbuild inlines this dynamic import into the single\n * chunk and hoists `@capgo/native-purchases` to a static top-level import in\n * both `dist/index.js` and `dist/index.cjs`. The plugin's `registerPlugin`\n * side effect therefore still fires at import time, including on web. Enabling\n * `splitting` for the ESM build would emit a separate chunk and make the\n * deferral real; until then, don't rely on this to keep the plugin out of a web\n * bundle. (`@capacitor/app`, imported dynamically in `app-resume-listener.ts`,\n * *is* genuinely deferred — it isn't reachable from this static graph.)\n *\n * Async because the capgo module is loaded lazily; web returns synchronously\n * but is still wrapped in a Promise for a uniform call signature.\n */\nexport async function selectNativeAdapter(\n logger: Logger,\n packageName?: string,\n /**\n * The configured catalog, as a getter.\n *\n * The adapter needs it to type a transaction the *store* reported. The\n * plugin's payload carries Play's `'inapp' | 'subs'`, and `'inapp'`\n * covers consumables and one-time purchases alike — so the catalog is the\n * only thing that can tell them apart, and the difference decides whether\n * iap acknowledges the transaction or consumes it. Getting it wrong leaves\n * a consumable owned, and the user unable to buy it again.\n *\n * It refines the store's answer rather than replacing it: see\n * `inferProductType`.\n *\n * A getter rather than an array because a backend-supplied manifest is\n * resolved into `state.products` just before this call, and nothing\n * stops it being refreshed later.\n */\n getConfiguredProducts?: () => readonly ConfiguredProduct[],\n): Promise<NativeAdapter> {\n const platform = getPlatform();\n if (platform === 'ios' || platform === 'android') {\n const mod = await import('./capgo/native-adapter.js');\n return new mod.CapgoNativeAdapter(logger, packageName, getConfiguredProducts);\n }\n return new WebStubAdapter();\n}\n\nexport type { NativeAdapter, NativePurchaseOptions } from './types.js';\n","import { IAPError, IAPErrorCode } from '../../../lib/errors.js';\nimport type { ConfiguredProduct, Product } from '../../../types/product.js';\nimport type { Storefront } from '../../../types/storefront.js';\nimport type { NativeTransaction } from '../../../types/transaction.js';\nimport type { NativeAdapter, NativePurchaseOptions } from '../types.js';\n\nexport class WebStubAdapter implements NativeAdapter {\n async isAvailable(): Promise<boolean> {\n return false;\n }\n\n async getProducts(_requests: ConfiguredProduct[]): Promise<Product[]> {\n return [];\n }\n\n async purchaseProduct(_opts: NativePurchaseOptions): Promise<NativeTransaction> {\n throw new IAPError({\n code: IAPErrorCode.PLATFORM_NOT_SUPPORTED,\n message: 'In-app purchases are not supported on the web platform.',\n });\n }\n\n async getOwnedTransactions(): Promise<NativeTransaction[]> {\n return [];\n }\n\n async acknowledge(_transaction: NativeTransaction): Promise<void> {\n // No-op on web.\n }\n\n async manageSubscriptions(): Promise<void> {\n throw new IAPError({\n code: IAPErrorCode.PLATFORM_NOT_SUPPORTED,\n message: 'Subscription management is not supported on the web platform.',\n });\n }\n\n async getStorefront(): Promise<Storefront | null> {\n // No App Store / Play storefront on web — entitlement queries still work.\n return null;\n }\n}\n","import { selectNativeAdapter } from '../adapters/native/index.js';\nimport { IAPError, IAPErrorCode } from '../lib/errors.js';\nimport { getPlatform, isNative } from '../lib/platform.js';\nimport { configuredProductsArraySchema } from '../types/config.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport type { ConfiguredProduct } from '../types/product.js';\nimport { attachAppResumeListener } from './app-resume-listener.js';\nimport { attachTransactionWatch } from './attach-transaction-watch.js';\nimport { type IAPInternalState, ensureUniqueProductIds, freezeAll } from './iap-state.js';\nimport { PurchaseOrchestrator } from './purchase-flow.js';\nimport { DEFAULT_PERMANENT_ERROR_CODES, RecoveryOrchestrator } from './recovery-flow.js';\nimport { RestoreOrchestrator } from './restore-flow.js';\nimport { TransactionUpdateOrchestrator } from './transaction-updates.js';\n\n/**\n * Bring an instance up: resolve the manifest, construct the native adapter\n * and the orchestrators, load the cache, run recovery, subscribe to the\n * transaction feed, and fire `ready`.\n *\n * Extracted from the factory because every lifecycle feature added a step\n * here and the function had reached 220-odd lines — four times the\n * project's guideline, and the place where the subtlest ordering lives.\n *\n * @param refreshEntitlements the factory's own refresh, which the resume\n * listener and the TTL microtask call. Passed in rather than reached\n * through the state bag so it cannot be confused with the public method.\n */\nexport async function initializeIap<TEntitlement extends EntitlementBase>(\n state: IAPInternalState<TEntitlement>,\n refreshEntitlements: () => Promise<void>,\n): Promise<void> {\n if (state.destroyed) {\n throw new IAPError({\n code: IAPErrorCode.NOT_INITIALIZED,\n message: 'IAP instance has been destroyed; create a new one with createIAP().',\n });\n }\n if (state.initialized) {\n state.logger.debug('initialize() called more than once; ignoring.');\n return;\n }\n\n // Storage first, before anything reads or writes it.\n //\n // `PreferencesAdapter` reaches `@capacitor/preferences` through a lazy\n // `import()` — so the plugin stays out of a bundle that does not use it —\n // and this is where a missing one is reported. It has to be here rather\n // than left to the first cache read, because that read treats any failure\n // as \"nothing cached\": an uninstalled plugin would look like a cold start\n // and iap would go on silently persisting nothing.\n await state.storage.ensureAvailable?.();\n\n const platform = getPlatform();\n if (!isNative()) {\n state.logger.info('Native purchases unavailable on web; entitlement queries still functional.');\n } else {\n state.logger.debug(`Initializing on platform=${platform}`);\n }\n\n // Resolve the SKU manifest. If the consumer omitted `products` from\n // config, the schema's superRefine has already guaranteed that the\n // backend can supply one — call listProducts() and validate the\n // response against the same schema config-time `products` would have\n // gone through. Failures throw verbatim (the adapter is responsible\n // for mapping transport errors to IAPError).\n if (!state.config.products) {\n if (typeof state.backend.listProducts !== 'function') {\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message:\n 'config.products is omitted but backend adapter does not implement listProducts(). This is a library bug; the schema should have caught it.',\n });\n }\n const fetched = await state.backend.listProducts();\n // Redundant validation on the HTTP path (HttpBackendAdapter already\n // parses with productManifestResponseSchema), but the only validation\n // gate for custom adapters that don't go through HttpClient.\n const validated = configuredProductsArraySchema.safeParse(fetched);\n if (!validated.success) {\n throw new IAPError({\n code: IAPErrorCode.BACKEND_BAD_RESPONSE,\n message: `backend.listProducts() returned an invalid manifest: ${validated.error.issues\n .map((i) => `${i.path.join('.') || '<root>'}: ${i.message}`)\n .join('; ')}`,\n cause: validated.error,\n });\n }\n ensureUniqueProductIds(validated.data);\n state.products = Object.freeze([...validated.data]) as ConfiguredProduct[];\n state.logger.debug(`Resolved ${validated.data.length} product(s) from backend manifest.`);\n }\n\n // Lazy adapter construction — this is the dynamic-import boundary so\n // web builds don't pull in `@capgo/native-purchases`.\n // The catalog is passed as a getter so the adapter can type a transaction\n // the store reported: Play calls a consumable and a one-time purchase both\n // `'inapp'`, and the difference decides whether iap acknowledges it or\n // consumes it.\n state.adapter = await selectNativeAdapter(\n state.logger,\n state.config.android.packageName,\n () => state.products,\n );\n\n // Now that the native adapter is resolved, wire the orchestrators.\n // Both share the same getter/setter triplet into createIAP's state.\n // The HTTP-config `getAuthHeaders` is hoisted here so the purchase\n // orchestrator can forward it to function-form `appUserId` fetchers\n // as `ctx.authHeaders`. Custom-adapter consumers don't have one\n // configured at the IAP-config level, so we resolve to `{}` for\n // them (their fetcher closes over their own auth state).\n const configGetAuthHeaders = state.config.backend?.getAuthHeaders;\n const getAuthHeaders: () => Promise<Record<string, string>> = configGetAuthHeaders\n ? async () => configGetAuthHeaders()\n : async () => ({});\n const sharedDeps = {\n nativeAdapter: state.adapter,\n backend: state.backend,\n cache: state.cache,\n unfinished: state.unfinished,\n emitter: state.emitter,\n logger: state.logger,\n getCurrentEntitlements: () => state.entitlements,\n setEntitlements: (next: TEntitlement[]) => {\n state.entitlements = freezeAll(next);\n },\n setCachePersisted: (cachedAt: number) => {\n state.cachedAt = cachedAt;\n },\n getAuthHeaders,\n };\n\n state.orchestrator = new PurchaseOrchestrator<TEntitlement>({\n ...sharedDeps,\n products: state.products,\n pending: state.pending,\n });\n state.restorer = new RestoreOrchestrator<TEntitlement>({ ...sharedDeps, pending: state.pending });\n state.recoverer = new RecoveryOrchestrator<TEntitlement>({\n ...sharedDeps,\n pending: state.pending,\n maxBatch: state.config.options.recoveryMaxBatch,\n permanentErrorCodes: new Set(\n state.config.options.permanentErrorCodes ?? DEFAULT_PERMANENT_ERROR_CODES,\n ),\n });\n\n state.updates = new TransactionUpdateOrchestrator<TEntitlement>({\n nativeAdapter: state.adapter,\n recoverer: state.recoverer,\n pending: state.pending,\n emitter: state.emitter,\n logger: state.logger,\n isPurchaseInFlight: (productId) => state.orchestrator?.isInFlight(productId) ?? false,\n isActive: () => state.initialized && !state.destroyed,\n });\n\n // Android cannot build a verify or restore request without it, and\n // the failure would otherwise surface per-purchase as a STORE_ERROR\n // long after startup.\n if (platform === 'android' && !state.config.android.packageName) {\n state.logger.warn(\n \"config.android.packageName is not set. Google verification and restore requests cannot be built without it, so purchases will fail with STORE_ERROR. Set it to your app's applicationId.\",\n );\n }\n\n try {\n await state.adapter.isAvailable();\n } catch (error) {\n state.logger.warn('Native adapter availability check threw; continuing.', error);\n }\n\n const cached = await state.cache.load();\n if (cached) {\n state.entitlements = freezeAll(cached.entitlements);\n state.cachedAt = cached.cachedAt;\n state.logger.debug(\n `Loaded ${cached.entitlements.length} cached entitlement(s) from ${new Date(cached.cachedAt).toISOString()}.`,\n );\n }\n\n // Run recovery for unfinished transactions. Best-effort, never throws.\n // Successful recoveries update entitlements before `ready` fires so\n // the consumer's first read sees the latest state.\n if (state.config.options.recoverUnfinishedTransactions && isNative()) {\n try {\n const result = await state.recoverer.recoverUnfinishedTransactions();\n if (result.inspected > 0) {\n state.logger.info(\n `Recovery inspected ${result.inspected} unfinished transaction(s): ${result.recovered} recovered, ${result.failures} retained.`,\n );\n }\n } catch (error) {\n // Recovery should swallow internally; this catches the\n // unexpected case where it didn't.\n state.logger.warn('Recovery threw unexpectedly; continuing initialize.', error);\n }\n }\n\n // Subscribe to the native transaction feed, and close out any pending\n // purchase that resolved while the app was closed. Both are native-only\n // and best-effort: a failure here costs latency (the next resume picks\n // it up), never correctness.\n if (isNative()) {\n state.txWatch = await attachTransactionWatch({\n adapter: state.adapter,\n updates: state.updates,\n logger: state.logger,\n });\n }\n\n // Wire the app-resume listener. Lazy-imports @capacitor/app so consumers\n // who disable refreshOnResume aren't forced to install it.\n if (state.config.options.refreshOnResume && isNative()) {\n state.resumeListener = await attachAppResumeListener({\n logger: state.logger,\n onResume: async () => {\n // Best-effort: warn-and-swallow so a transient backend hiccup\n // doesn't poison subsequent foreground events.\n try {\n await refreshEntitlements();\n } catch (error) {\n state.logger.warn('refreshOnResume: refresh() failed.', error);\n }\n // Returning from the store's own payment UI is exactly when a\n // pending purchase has most likely resolved. `reconcilePending`\n // no-ops when nothing is pending, so this costs nothing in the\n // common case and never throws.\n await state.updates?.reconcilePending();\n },\n });\n }\n\n // TTL-based stale-cache check: if we loaded cached entitlements that\n // are older than the configured TTL, schedule a background refresh\n // to fire after `ready`. Reads still return the cached value\n // immediately — PLAN.md §7 \"still returns the cached value but the\n // library schedules a refresh\".\n if (\n state.cachedAt !== null &&\n Date.now() - state.cachedAt > state.config.options.entitlementCacheTtlMs\n ) {\n state.logger.debug('Cache exceeds TTL; scheduling background refresh.');\n queueMicrotask(() => {\n // Guard against destroy()-during-init: if the consumer tore down\n // before the microtask drained, refresh() would throw NOT_INITIALIZED\n // and emit a confusing warn. Quietly skip instead.\n if (!state.initialized || state.destroyed) return;\n refreshEntitlements().catch((error) => {\n state.logger.warn('TTL background refresh failed.', error);\n });\n });\n }\n\n state.initialized = true;\n state.emitter.emit('ready', undefined);\n\n // Close out pending purchases after `ready`, not before it.\n //\n // Reconciliation can mean a store round-trip plus a backend verify,\n // and unlike recovery above it has no batch cap — so awaiting it\n // inside initialize() would delay every consumer's first render by\n // however long that takes. It is safe to run late: the purchase\n // already resolved in the store, nothing is lost by learning a moment\n // later, and `reconcilePending` no-ops when nothing is marked.\n if (isNative()) {\n queueMicrotask(() => {\n if (!state.initialized || state.destroyed) return;\n void state.updates?.reconcilePending();\n });\n }\n}\n","import type { Logger } from '../lib/logger.js';\n\nexport interface AppResumeListenerOptions {\n logger: Logger;\n /** Called whenever the app becomes active. Return value is awaited but\n * never propagated — failures are logged via `logger.warn`. */\n onResume: () => void | Promise<void>;\n}\n\nexport interface AppResumeListenerHandle {\n remove(): Promise<void>;\n}\n\n/**\n * Attach an `App.addListener('appStateChange')` listener via `@capacitor/app`\n * so the library can refresh entitlements when the app returns from\n * background. `@capacitor/app` is an OPTIONAL peer dep — when consumers\n * disable `options.refreshOnResume`, they don't have to install it.\n *\n * Returns `null` when `@capacitor/app` is unavailable or the runtime\n * cannot register the listener (e.g. web). Call sites should treat null\n * as \"no listener attached\" and continue.\n */\nexport async function attachAppResumeListener(\n opts: AppResumeListenerOptions,\n): Promise<AppResumeListenerHandle | null> {\n let mod: typeof import('@capacitor/app');\n try {\n mod = await import('@capacitor/app');\n } catch (error) {\n opts.logger.warn(\n 'refreshOnResume requested but @capacitor/app is not installed; resume listener disabled.',\n error,\n );\n return null;\n }\n\n let handle: { remove(): Promise<void> };\n try {\n handle = await mod.App.addListener('appStateChange', ({ isActive }) => {\n if (!isActive) return;\n void Promise.resolve(opts.onResume()).catch((error) => {\n opts.logger.warn('refreshOnResume handler threw.', error);\n });\n });\n } catch (error) {\n opts.logger.warn(\n 'Failed to attach App appStateChange listener; resume refresh disabled.',\n error,\n );\n return null;\n }\n\n return {\n async remove() {\n try {\n await handle.remove();\n } catch (error) {\n opts.logger.warn('Failed to remove App appStateChange listener.', error);\n }\n },\n };\n}\n","import type { NativeAdapter, TransactionWatchHandle } from '../adapters/native/types.js';\nimport type { Logger } from '../lib/logger.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport type { TransactionUpdateOrchestrator } from './transaction-updates.js';\n\nexport interface AttachTransactionWatchOptions<TEntitlement extends EntitlementBase> {\n adapter: NativeAdapter;\n updates: TransactionUpdateOrchestrator<TEntitlement>;\n logger: Logger;\n}\n\n/**\n * Subscribe to the platform's transaction feed, if it has one.\n *\n * Lives outside `initialize()` because the two subtle lines in it deserve a\n * home where they can be explained, rather than being three of two hundred\n * in a lifecycle function:\n *\n * - **The handler is deliberately not awaited.** It runs from a native\n * callback, which has nobody to await it and nowhere to put a rejection.\n * `handle` is written never to reject, so `void` is the honest spelling\n * rather than a swallowed promise.\n * - **`null` is a real answer, not a failure.** An adapter may have no feed\n * to offer — Android does not, today — and that is not an error: launch\n * recovery and refresh-on-resume cover the same ground more slowly. The\n * same `null` also comes back when subscribing failed, which is why this\n * returns one value for both and logs the difference.\n *\n * Never throws. A missing listener costs latency, not correctness, so it\n * must not be able to fail `initialize()`.\n */\nexport async function attachTransactionWatch<TEntitlement extends EntitlementBase>(\n opts: AttachTransactionWatchOptions<TEntitlement>,\n): Promise<TransactionWatchHandle | null> {\n const { adapter, updates, logger } = opts;\n\n let handle: TransactionWatchHandle | null;\n try {\n handle =\n (await adapter.watchTransactions?.((transaction) => {\n void updates.handle(transaction);\n })) ?? null;\n } catch (error) {\n logger.warn(\n 'Failed to subscribe to native transaction updates; renewals and refunds will be picked up at the next launch or resume instead.',\n error,\n );\n return null;\n }\n\n if (handle === null) {\n logger.debug(\n 'No native transaction feed on this platform; relying on recovery at launch and refresh on resume.',\n );\n }\n return handle;\n}\n","import type { BackendAdapter, VerifyResponse } from '../adapters/backend/types.js';\nimport type { NativeAdapter } from '../adapters/native/types.js';\nimport type { TypedEventEmitter } from '../events/emitter.js';\nimport { IAPError, IAPErrorCode, toIAPError } from '../lib/errors.js';\nimport type { Logger } from '../lib/logger.js';\nimport { isValidUuid } from '../lib/uuid.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport type { ConfiguredProduct } from '../types/product.js';\nimport type {\n AppUserId,\n AppUserIdFetcherContext,\n PurchaseOptions,\n PurchaseResult,\n} from '../types/results.js';\nimport type { NativeTransaction, VerifiedTransaction } from '../types/transaction.js';\nimport type { EntitlementCache } from './entitlement-cache.js';\nimport { finalizeTransaction } from './finalize-transaction.js';\nimport type { PendingPurchasesStore } from './pending-purchases.js';\nimport { resolvePendingPurchase } from './resolve-pending.js';\nimport { toStorePurchase } from './store-purchase.js';\nimport type { UnfinishedTransactionsStore } from './unfinished-transactions.js';\nimport { verifyNativeTransaction } from './verify-helpers.js';\n\ninterface PurchaseOrchestratorDeps<TEntitlement extends EntitlementBase> {\n /** Native adapter (capgo on iOS/Android, web stub on web). Always non-null\n * by the time the orchestrator is invoked — initialize() ensures it. */\n nativeAdapter: NativeAdapter;\n backend: BackendAdapter<TEntitlement>;\n cache: EntitlementCache<TEntitlement>;\n unfinished: UnfinishedTransactionsStore;\n emitter: TypedEventEmitter<TEntitlement>;\n logger: Logger;\n /** Resolved product catalog from config. Used to look up productType. */\n products: ConfiguredProduct[];\n /**\n * Returns the current entitlements list. Read fresh from state each call so\n * concurrent refreshes are reflected in the `previous` payload of\n * entitlements-changed events.\n */\n getCurrentEntitlements: () => TEntitlement[];\n /**\n * Replace the current entitlements list. Implementation must freeze entries\n * (createIAP's `freezeAll`).\n */\n setEntitlements: (next: TEntitlement[]) => void;\n /**\n * Mark the persisted cache as written at the given timestamp. Keeps the\n * in-memory `cachedAt` in sync with disk so Phase 6 TTL evaluation doesn't\n * see a spurious \"stale\" reading after a purchase.\n */\n setCachePersisted: (cachedAt: number) => void;\n /**\n * Resolves the auth headers the library uses for backend requests.\n * Forwarded to function-form `appUserId` fetchers as `ctx.authHeaders`\n * so consumers whose UUID-minting endpoint shares auth with their IAP\n * backend can reuse it without redefining a helper. For consumers\n * using a custom `BackendAdapter` (no `getAuthHeaders` configured),\n * this returns `{}`. Awaited fresh per purchase so token refresh\n * keeps working.\n */\n getAuthHeaders: () => Promise<Record<string, string>>;\n /**\n * Records a product whose purchase is awaiting clearance, so the\n * pending state can be closed out in a later session — a Play\n * e-wallet purchase usually clears with the app closed.\n */\n pending: PendingPurchasesStore;\n}\n\n/**\n * Coordinates the purchase flow across the native, backend, storage, and\n * eventing layers. The implementation is the literal expression of\n * PLAN.md §5.4 — read that section alongside this code.\n *\n * Safety guarantees:\n * 1. **At-least-once delivery to backend** — write to `unfinished` BEFORE\n * calling `backend.verifyApple/Google()`. App death between these two\n * points is recovered on next launch via `unfinished.list()`.\n * 2. **Never `acknowledge()` before backend confirms** — `nativeAdapter.acknowledge()`\n * is only called after `backend.verifyApple/Google()` returns `valid: true`.\n * On any failure path the transaction is left in the `unfinished` store (or\n * still owned at the store level) so it's retried on the next launch via\n * the recovery flow.\n * 3. **Per-product lock** — concurrent `purchase('premium_monthly')` calls are\n * rejected: the `inFlight` set throws `ALREADY_IN_PROGRESS` on the second.\n *\n * The 5 result statuses (PLAN.md §5.4):\n * - `success` — backend returned `valid: true`; entitlements + cache updated.\n * - `cancelled` — user cancelled the native sheet (USER_CANCELLED).\n * - `pending` — Android-only; payment pending platform-side. Not yet acked.\n * - `verification_failed` — backend returned `valid: false`. Persisted to\n * `unfinished` for retry on next refresh.\n * - `failed` — native or transport error. May or may not be persisted depending\n * on whether a NativeTransaction was produced.\n */\nexport class PurchaseOrchestrator<TEntitlement extends EntitlementBase = EntitlementBase> {\n private readonly inFlight = new Set<string>();\n\n /**\n * Whether this orchestrator is currently handling `productId`.\n *\n * Read by the transaction-update orchestrator: StoreKit delivers the\n * transaction a purchase produced to `Transaction.updates` as well, and\n * whichever path started it owns settling it.\n */\n isInFlight(productId: string): boolean {\n return this.inFlight.has(productId);\n }\n\n /**\n * The products currently being purchased.\n *\n * Read by `reset()`, which refuses to run while one is in flight. The\n * reason is the unfinished-transaction entry, not the cache: that entry is\n * written *before* verification precisely so a purchase survives a crash,\n * and deleting it mid-flight leaves a purchase that is neither\n * acknowledged nor tracked — which Play auto-refunds in three days. The\n * cache coming back is harmless by comparison, since `reset()` is not a\n * revocation.\n *\n * Marked from the moment the purchase is committed to running, before any\n * consumer-supplied `appUserId` fetcher is awaited — that await is a\n * network round-trip, and a window in which this said \"nothing in flight\"\n * while a purchase was already under way.\n */\n inFlightProducts(): string[] {\n return [...this.inFlight];\n }\n\n constructor(private readonly deps: PurchaseOrchestratorDeps<TEntitlement>) {}\n\n async purchase(opts: PurchaseOptions): Promise<PurchaseResult<TEntitlement>> {\n const { productId, appUserId } = opts;\n if (this.inFlight.has(productId)) {\n throw new IAPError({\n code: IAPErrorCode.ALREADY_IN_PROGRESS,\n message: `A purchase of \"${productId}\" is already in progress.`,\n });\n }\n const product = this.deps.products.find((p) => p.id === productId);\n if (!product) {\n throw new IAPError({\n code: IAPErrorCode.PRODUCT_NOT_FOUND,\n message: `Product \"${productId}\" is not in the configured catalog.`,\n });\n }\n\n // In flight from here, before the appUserId resolution below. That\n // resolution awaits consumer code — typically an HTTP call — and\n // marking only after it left a window the length of a network\n // round-trip in which `isInFlight`/`inFlightProducts` reported nothing\n // while the purchase was already committed. `reset()` could wipe the\n // unfinished queue in that window, and a second tap could open a\n // second native sheet.\n this.inFlight.add(productId);\n\n try {\n // Resolve and validate appUserId BEFORE emitting purchase-started —\n // these throws are pre-flight (caller bug or backend-fetcher\n // failure), not purchase outcomes. They surface synchronously to the\n // awaiter without polluting the event stream.\n //\n // For function-form fetchers, eagerly resolve `getAuthHeaders()` so\n // we can pass it via ctx. String-form supplies skip the await. The\n // ctx is always populated (with `{}` when no headers are wired) so\n // fetchers that destructure `({ authHeaders })` never see undefined.\n let resolvedAppUserId: string | undefined;\n if (appUserId !== undefined) {\n const ctx: AppUserIdFetcherContext =\n typeof appUserId === 'function'\n ? { authHeaders: await this.deps.getAuthHeaders() }\n : { authHeaders: {} };\n resolvedAppUserId = await resolveAppUserId(appUserId, ctx);\n }\n\n this.deps.emitter.emit('purchase-started', { productId });\n\n return await this.runFlow(product, resolvedAppUserId);\n } finally {\n this.inFlight.delete(productId);\n }\n }\n\n private async runFlow(\n product: ConfiguredProduct,\n appUserId: string | undefined,\n ): Promise<PurchaseResult<TEntitlement>> {\n const { nativeAdapter, logger } = this.deps;\n let nativeTx: NativeTransaction;\n\n // ----- 1. Native purchase -----\n try {\n nativeTx = await nativeAdapter.purchaseProduct({\n productId: product.id,\n productType: product.type,\n ...(product.androidPlanId ? { androidPlanId: product.androidPlanId } : {}),\n ...(appUserId ? { appAccountToken: appUserId } : {}),\n });\n } catch (error) {\n return this.handleNativeError(product.id, error);\n }\n\n // ----- 2. Persist BEFORE verifying — at-least-once invariant -----\n try {\n await this.deps.unfinished.add(nativeTx);\n } catch (error) {\n logger.warn(\n `Failed to persist unfinished entry for \"${product.id}\"; verification will still proceed.`,\n error,\n );\n }\n\n // ----- 3. Backend verification -----\n let verifyResult: VerifyResponse<TEntitlement>;\n try {\n verifyResult = await verifyNativeTransaction(this.deps.backend, nativeTx);\n } catch (error) {\n return this.handleVerifyError(product.id, error);\n }\n\n // ----- 4. Branch on backend response -----\n if (!verifyResult.valid) {\n return this.handleVerificationRejected(product.id, verifyResult);\n }\n\n // ----- 5. Backend says valid: ack natively + update cache + emit -----\n return this.finalizeSuccess(product.id, nativeTx, verifyResult);\n }\n\n private async finalizeSuccess(\n productId: string,\n nativeTx: NativeTransaction,\n response: Extract<VerifyResponse<TEntitlement>, { valid: true }>,\n ): Promise<PurchaseResult<TEntitlement>> {\n const { nativeAdapter, cache, unfinished, emitter, logger } = this.deps;\n const transaction = response.transaction as VerifiedTransaction;\n const entitlements = response.entitlements;\n\n // Acknowledge the native transaction. Failure here is recoverable: the\n // entitlement is confirmed, so the user gets access — but the store\n // still considers the purchase unfinished, and on Android Google\n // auto-refunds an unacknowledged purchase after three days.\n //\n // So the unfinished entry is **kept** when this fails, for recovery to\n // retry the acknowledgement on the next launch. It used to be removed\n // regardless, on the reasoning that \"a later restore()/refresh() re-acks\n // it\" — but only `restore()` acknowledges, and nothing calls it\n // automatically. An ack failure therefore left a paid-for purchase\n // unacknowledged and untracked, granting access right up to the silent\n // refund.\n let acknowledged = true;\n try {\n // Acknowledge, or consume for an Android consumable — see\n // `finalizeTransaction`. Both are \"tell the store we are done with\n // it\", and only the second lets a consumable be bought again.\n await finalizeTransaction({ nativeAdapter, transaction: nativeTx, logger });\n } catch (error) {\n acknowledged = false;\n logger.warn(\n `Settling \"${nativeTx.productId}\" with the store failed; the entitlement is granted, and the transaction is retained for recovery to retry on the next launch.`,\n error,\n );\n }\n\n // Persist entitlements (best-effort) and clear the unfinished entry.\n const previous = this.deps.getCurrentEntitlements();\n try {\n const cachedAt = await cache.save(entitlements);\n this.deps.setCachePersisted(cachedAt);\n } catch (error) {\n logger.warn(\n `Failed to persist entitlements after purchase of \"${productId}\"; in-memory state still updated.`,\n error,\n );\n }\n this.deps.setEntitlements(entitlements);\n\n if (acknowledged) {\n try {\n await unfinished.remove(nativeTx.token);\n } catch (error) {\n logger.warn(\n `Failed to remove \"${productId}\" from unfinished list; will be skipped on next recovery.`,\n error,\n );\n }\n }\n\n // A pending purchase the user retried and completed directly: clear the\n // mark, or a later reconcile finds it unowned and reports `cancelled`.\n await resolvePendingPurchase(this.deps, productId, 'purchased');\n\n emitter.emit('purchase-success', { productId, transaction });\n emitter.emit('entitlements-changed', {\n entitlements: this.deps.getCurrentEntitlements(),\n previous,\n });\n\n return {\n status: 'success',\n productId,\n transaction,\n purchase: toStorePurchase(nativeTx),\n entitlements: this.deps.getCurrentEntitlements(),\n };\n }\n\n private handleVerificationRejected(\n productId: string,\n response: Extract<VerifyResponse<TEntitlement>, { valid: false }>,\n ): PurchaseResult<TEntitlement> {\n // Compose both the human-readable message and the stable machine code\n // so consumers can grep for either. PLAN.md §5.8 marks `error` as the\n // stable identifier — preserve it even when message is present.\n const detail = response.message\n ? `${response.message} [${response.error}]`\n : `Backend rejected the transaction (${response.error}).`;\n const error = new IAPError({\n code: IAPErrorCode.VERIFICATION_REJECTED,\n message: detail,\n });\n this.deps.emitter.emit('verification-failed', { productId, error });\n return { status: 'verification_failed', productId, error };\n }\n\n private async handleNativeError(\n productId: string,\n error: unknown,\n ): Promise<PurchaseResult<TEntitlement>> {\n const iapError = toIAPError(\n error,\n `Native purchase of \"${productId}\" failed.`,\n IAPErrorCode.STORE_ERROR,\n );\n\n if (iapError.code === IAPErrorCode.USER_CANCELLED) {\n this.deps.emitter.emit('purchase-cancelled', { productId });\n return { status: 'cancelled', productId };\n }\n\n if (iapError.code === IAPErrorCode.PURCHASE_PENDING) {\n // Remember it before announcing it. The purchase can clear hours\n // later in another session, and without a persisted mark nothing\n // would ever tell the consumer the pending state had ended.\n await this.deps.pending.add(productId);\n this.deps.emitter.emit('purchase-pending', { productId });\n return { status: 'pending', productId };\n }\n\n this.deps.emitter.emit('purchase-failed', { productId, error: iapError });\n return { status: 'failed', productId, error: iapError };\n }\n\n private handleVerifyError(productId: string, error: unknown): PurchaseResult<TEntitlement> {\n const iapError = toIAPError(\n error,\n `Backend verification of \"${productId}\" failed.`,\n IAPErrorCode.BACKEND_UNAVAILABLE,\n );\n // Transport / auth errors leave the unfinished entry in place for retry.\n // We surface verification_failed so the consumer UI shows a \"we'll retry\"\n // message; a hard `failed` would suggest the user should restart the flow.\n this.deps.emitter.emit('verification-failed', { productId, error: iapError });\n return { status: 'verification_failed', productId, error: iapError };\n }\n}\n\n/**\n * Resolve an `appUserId` supply to a validated UUID string (any RFC 9562\n * version — see {@link isValidUuid}).\n *\n * - String input: validate directly.\n * - Async fetcher: invoke once (fresh per purchase — iap caches nothing,\n * the backend owns mint-or-lookup idempotency), then validate the\n * resolved value. Wraps fetcher rejections in\n * `IAPError(APP_USER_ID_FETCH_FAILED, cause)` so callers can\n * distinguish \"fetcher exploded\" from \"fetcher returned junk\".\n *\n * Function-form fetchers always receive `ctx`. Zero-arg fetchers\n * (`async () => '...'`) ignore the extra argument at runtime — JS\n * standard behavior — so 0.2.x callers continue to work unchanged.\n *\n * Throws synchronously (or via Promise rejection) on invalid input;\n * never returns a non-UUID string.\n */\nasync function resolveAppUserId(supply: AppUserId, ctx: AppUserIdFetcherContext): Promise<string> {\n let resolved: string;\n if (typeof supply === 'function') {\n try {\n // Cast to the ctx-form signature so the call typechecks for both\n // shapes in the union; zero-arg fetchers ignore the extra arg.\n resolved = await (supply as (ctx: AppUserIdFetcherContext) => Promise<string>)(ctx);\n } catch (cause) {\n throw new IAPError({\n code: IAPErrorCode.APP_USER_ID_FETCH_FAILED,\n message: 'The async appUserId fetcher threw or rejected.',\n cause,\n });\n }\n } else {\n resolved = supply;\n }\n if (!isValidUuid(resolved)) {\n throw new IAPError({\n code: IAPErrorCode.INVALID_APP_USER_ID,\n message: `appUserId must be an RFC 9562 UUID (any version); received ${\n typeof resolved === 'string' ? `\"${resolved}\"` : typeof resolved\n }.`,\n });\n }\n return resolved;\n}\n","import type { NativeAdapter } from '../adapters/native/types.js';\nimport type { Logger } from '../lib/logger.js';\nimport type { NativeTransaction } from '../types/transaction.js';\n\n/**\n * Finish a verified transaction with the store: acknowledge it, or consume\n * it when that is what the product needs.\n *\n * One function rather than each caller deciding for itself, because getting\n * it wrong is silent in both directions and the paths that settle a\n * transaction are not obviously related: a purchase, a restore, launch\n * recovery, and a transaction arriving on its own. (Three call sites for\n * those four paths — recovery's `processTransaction` serves the last two.)\n *\n * ## Why consuming is a separate thing\n *\n * On Android, acknowledging a purchase tells Play \"I have granted this\", and\n * consuming additionally tells it \"ownership is released\". For a consumable\n * only the second allows the product to be bought again — acknowledging\n * alone leaves Play reporting it owned forever, and `purchase()` of it then\n * fails `ALREADY_PURCHASED`. The user has paid for a consumable they can\n * never buy a second time, and no amount of retrying fixes it.\n *\n * Consuming also acknowledges, so this is one call either way, never both.\n *\n * iOS has no equivalent: `Transaction.finish()` — which `acknowledge()`\n * calls — is the whole of finishing there, for every product type. So the\n * consume branch is Google-only, and an adapter that does not implement\n * `consume` falls back to acknowledging, which still protects the refund\n * window even though the product stays owned.\n *\n * ## Ordering\n *\n * Called only **after** verification succeeds, on every path. That is iap's\n * central invariant and it is stronger here than elsewhere: a consumed\n * purchase is gone from `getPurchases()` in Billing 8.x, so consuming\n * before verifying would make a failed verification unrecoverable rather\n * than merely retried.\n *\n * ## On failure\n *\n * Throws, so the caller keeps the transaction's unfinished entry and\n * recovery retries on the next launch. Before throwing, a failed *consume*\n * falls back to acknowledging — not as a substitute, but to stop Google's\n * three-day auto-refund clock while the retry is pending.\n */\nexport async function finalizeTransaction(opts: {\n nativeAdapter: NativeAdapter;\n transaction: NativeTransaction;\n logger: Logger;\n}): Promise<void> {\n const { nativeAdapter, transaction, logger } = opts;\n\n if (transaction.platform !== 'google' || transaction.productType !== 'consumable') {\n await nativeAdapter.acknowledge(transaction);\n return;\n }\n\n if (!nativeAdapter.consume) {\n // A custom adapter. (Not an old plugin: the peer range floor is the\n // version that added `consumePurchase()`, and the capgo adapter always\n // implements this.) Acknowledging is the safe fallback — the refund\n // window is what matters most — but say so, because the product will\n // stay owned and unbuyable.\n logger.warn(\n `The native adapter cannot consume, so \"${transaction.productId}\" was only acknowledged. Google will keep reporting it owned, and buying it again will fail with ALREADY_PURCHASED.`,\n );\n await nativeAdapter.acknowledge(transaction);\n return;\n }\n\n try {\n await nativeAdapter.consume(transaction);\n } catch (error) {\n // Acknowledge before giving up, for the refund window.\n //\n // A consume that fails leaves the purchase neither consumed nor\n // acknowledged, and Google auto-refunds an unacknowledged purchase\n // after three days — so a transient billing error would cost the user\n // a purchase iap had already granted them. Acknowledging stops that\n // clock without closing anything off: an acknowledged purchase can\n // still be consumed, so the retry below is still open.\n //\n // Best-effort, and usually futile — whatever broke the consume has\n // normally broken this too, and if the consume in fact *succeeded* and\n // only the bridge reply failed, there is no purchase left to\n // acknowledge. Either way the original error is what the caller needs.\n try {\n await nativeAdapter.acknowledge(transaction);\n logger.debug(\n `Consuming \"${transaction.productId}\" failed; acknowledged it instead so Google does not auto-refund, and the consume will be retried.`,\n );\n } catch {\n // Swallowed deliberately: it is a safety net, not the operation.\n }\n throw error;\n }\n}\n","import type { TypedEventEmitter } from '../events/emitter.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport type { PendingPurchasesStore } from './pending-purchases.js';\n\nexport interface ResolvePendingDeps<TEntitlement extends EntitlementBase> {\n pending: PendingPurchasesStore;\n emitter: TypedEventEmitter<TEntitlement>;\n}\n\n/**\n * Clear a product's pending mark and announce how it ended, if it was marked.\n *\n * Lives on its own because **every** path that settles a transaction has to\n * do this, not just the one that handles out-of-band updates. A pending\n * purchase can be finished by a later `purchase()` retry, by `restore()`, by\n * launch recovery, or by the update listener — and a path that settles the\n * purchase without clearing the mark leaves it behind to be reported\n * `cancelled` on a subsequent reconcile. Telling a consumer a purchase was\n * cancelled after it succeeded is the worst answer this feature can give.\n *\n * Atomic via {@link PendingPurchasesStore.takeIfPresent}: the callers can\n * overlap, and `purchase-pending-resolved` promises to fire at most once per\n * pending purchase.\n *\n * Emits nothing when the product was not marked pending, which is the common\n * case — an ordinary purchase or renewal was never announced as pending.\n */\nexport async function resolvePendingPurchase<TEntitlement extends EntitlementBase>(\n deps: ResolvePendingDeps<TEntitlement>,\n productId: string,\n status: 'purchased' | 'cancelled',\n): Promise<void> {\n if (!(await deps.pending.takeIfPresent(productId))) return;\n deps.emitter.emit('purchase-pending-resolved', { productId, status });\n}\n","import type { StorePurchase } from '../types/results.js';\nimport type { NativeTransaction } from '../types/transaction.js';\n\n/**\n * Project a normalized {@link NativeTransaction} down to the public\n * {@link StorePurchase} a consumer sees.\n *\n * Deliberately a narrowing rather than a pass-through: `token` is the\n * acknowledge handle and `raw` is the plugin's own shape, and neither is\n * part of iap's contract. Exposing the transaction wholesale would promise\n * both, and `raw` cannot be promised across plugin versions at all.\n */\nexport function toStorePurchase(tx: NativeTransaction): StorePurchase {\n return {\n platform: tx.platform,\n productId: tx.productId,\n purchaseReference: tx.purchaseReference,\n appUserId: tx.appUserId ?? null,\n subscription: tx.subscription ?? null,\n };\n}\n","import type { BackendAdapter, VerifyResponse } from '../adapters/backend/types.js';\nimport { IAPError, IAPErrorCode } from '../lib/errors.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport type { NativeTransaction } from '../types/transaction.js';\n\n/**\n * Route a native transaction to the right per-platform verify endpoint.\n *\n * - An adapter implementing `verifyNative` → the transaction, unextracted.\n * - Apple → `backend.verifyApple({ productId, transactionId, type })`\n * - Google → `backend.verifyGoogle({ productId, purchaseToken, packageName, type })`\n *\n * Throws `IAPError(STORE_ERROR)` if a Google transaction is missing a\n * `packageName` (the verify request body cannot be built without it).\n *\n * Used by the purchase orchestrator and the recovery orchestrator;\n * restore uses `backend.restore()` (batched, different shape).\n */\nexport async function verifyNativeTransaction<TEntitlement extends EntitlementBase>(\n backend: BackendAdapter<TEntitlement>,\n tx: NativeTransaction,\n): Promise<VerifyResponse<TEntitlement>> {\n // An adapter that can answer from the whole transaction gets it whole.\n // The extraction below exists for the HTTP contract's sake, and throws\n // away exactly the fields an on-device check needs.\n if (typeof backend.verifyNative === 'function') {\n return backend.verifyNative(tx);\n }\n\n if (tx.platform === 'apple') {\n return backend.verifyApple({\n productId: tx.productId,\n transactionId: tx.token,\n type: tx.productType,\n });\n }\n if (!tx.packageName) {\n throw new IAPError({\n code: IAPErrorCode.STORE_ERROR,\n message: `Google transaction for \"${tx.productId}\" has no packageName; cannot verify. Set config.android.packageName to your app's applicationId — the native plugin does not report it, so iap cannot derive it from the purchase.`,\n });\n }\n return backend.verifyGoogle({\n productId: tx.productId,\n purchaseToken: tx.token,\n packageName: tx.packageName,\n type: tx.productType,\n });\n}\n","import type { BackendAdapter } from '../adapters/backend/types.js';\nimport type { NativeAdapter } from '../adapters/native/types.js';\nimport type { TypedEventEmitter } from '../events/emitter.js';\nimport type { Logger } from '../lib/logger.js';\nimport { maskToken } from '../lib/redact.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport type { NativeTransaction } from '../types/transaction.js';\nimport { type EntitlementCache, entitlementsEqual } from './entitlement-cache.js';\nimport { finalizeTransaction } from './finalize-transaction.js';\nimport type { PendingPurchasesStore } from './pending-purchases.js';\nimport { resolvePendingPurchase } from './resolve-pending.js';\nimport type {\n UnfinishedTransaction,\n UnfinishedTransactionsStore,\n} from './unfinished-transactions.js';\nimport { verifyNativeTransaction } from './verify-helpers.js';\n\n/**\n * Backend `valid:false` error codes that are treated as permanent by default\n * (entry removed from `unfinished_transactions` instead of retried forever).\n *\n * Conservative on purpose: only the two codes the documented recipe\n * contract identifies as unambiguous \"domain-not-found\" answers. Consumers\n * with custom backend error vocabularies extend via\n * `options.permanentErrorCodes`.\n *\n * Distinct from the `RECOVERABLE_CODES` set in `lib/errors.ts`: that one\n * classifies iap-internal `IAPErrorCode`s for transport/storage retry\n * semantics; this one classifies opaque error strings the consumer's\n * backend returns in `valid:false` responses.\n */\nexport const DEFAULT_PERMANENT_ERROR_CODES: readonly string[] = [\n 'TRANSACTION_NOT_FOUND',\n 'PRODUCT_MISMATCH',\n] as const;\n\ninterface RecoveryOrchestratorDeps<TEntitlement extends EntitlementBase> {\n nativeAdapter: NativeAdapter;\n backend: BackendAdapter<TEntitlement>;\n cache: EntitlementCache<TEntitlement>;\n unfinished: UnfinishedTransactionsStore;\n /**\n * Pending marks, so a purchase settled here clears the one it was\n * announced under. Every settlement path has to, or a reconcile later\n * reports `cancelled` for a purchase that succeeded.\n */\n pending: PendingPurchasesStore;\n emitter: TypedEventEmitter<TEntitlement>;\n logger: Logger;\n getCurrentEntitlements: () => TEntitlement[];\n setEntitlements: (next: TEntitlement[]) => void;\n setCachePersisted: (cachedAt: number) => void;\n /** Cap on entries inspected per launch (config.options.recoveryMaxBatch). */\n maxBatch: number;\n /**\n * Backend `valid:false` error codes treated as permanent. Entries with a\n * matching error are removed from storage instead of retried next launch.\n * Resolved from `config.options.permanentErrorCodes` (or the default set\n * when omitted) at orchestrator construction in `createIAP`.\n */\n permanentErrorCodes: ReadonlySet<string>;\n}\n\ninterface RecoveryResult {\n /** Number of entries that were verified, acknowledged, and removed. */\n recovered: number;\n /** Number of entries left in the list (transient errors, valid:false, etc.). */\n failures: number;\n /**\n * Number of entries removed from the list because the backend's\n * `valid:false` response carried a permanent error code (per\n * `options.permanentErrorCodes`). These will NOT retry on next launch.\n */\n droppedPermanent: number;\n /** Total entries inspected. */\n inspected: number;\n}\n\n/**\n * Re-attempts verification and settlement for unfinished transactions\n * that survived from a prior session (app killed mid-purchase, network\n * outage during verify, etc.). Runs once per `initialize()` call before\n * `ready` fires.\n *\n * Best-effort by design — never throws. Each entry is processed\n * independently; one failure does not abort the rest. Entries that fail\n * stay in storage for the next launch's recovery.\n *\n * Per-entry sequence:\n * 1. `verifyNativeTransaction` — reuse the shared platform router.\n * 2. If `valid: false` → log debug, increment `failures`, leave in list.\n * 3. If `valid: true`:\n * a. `finalizeTransaction()` — acknowledge, or consume for an Android\n * consumable. A failure means we don't yet remove from the list\n * (next launch will retry).\n * b. `unfinished.remove(token)` — clear the entry.\n * c. Stash the response's `entitlements` as the latest seen.\n * 4. Transport / verify throw → log warn, increment `failures`, leave.\n *\n * After processing all entries, if at least one succeeded, the latest\n * verified `entitlements` array is applied as the new state (cache.save +\n * setEntitlements + emit `entitlements-changed`). Multiple verifies for\n * the same user normally return the same consolidated list — last-wins\n * is the simplest correct strategy.\n */\nexport class RecoveryOrchestrator<TEntitlement extends EntitlementBase = EntitlementBase> {\n constructor(private readonly deps: RecoveryOrchestratorDeps<TEntitlement>) {}\n\n async recoverUnfinishedTransactions(): Promise<RecoveryResult> {\n const { unfinished, logger, maxBatch } = this.deps;\n const allEntries = await unfinished.list();\n if (allEntries.length === 0) {\n return { recovered: 0, failures: 0, droppedPermanent: 0, inspected: 0 };\n }\n\n // L2: cap inspected entries per launch. Excess entries stay in storage\n // and are processed on subsequent launches.\n const entries = allEntries.slice(0, maxBatch);\n if (allEntries.length > maxBatch) {\n logger.info(\n `Recovery: inspecting ${entries.length}/${allEntries.length} entries; remaining ${allEntries.length - entries.length} will be processed on subsequent launches.`,\n );\n } else {\n logger.debug(`Recovery: inspecting ${entries.length} unfinished transaction(s).`);\n }\n\n // L1: parallelize per-entry verify→ack→remove via Promise.allSettled.\n // Within an entry the steps are sequential (the orchestrator's safety\n // invariants rely on it); across entries they're independent.\n const settled = await Promise.allSettled(entries.map((entry) => this.processEntry(entry)));\n\n let recovered = 0;\n let failures = 0;\n let droppedPermanent = 0;\n let latestEntitlements: TEntitlement[] | null = null;\n\n // Iterate in input order so latestEntitlements is the LAST successful\n // entry's response (deterministic last-write-wins). NOTE: parallel\n // verifies for the same user are expected to return the same consolidated\n // list — replicas that drift mid-rollout could yield different lists; in\n // that case the input-order tiebreak is arbitrary but stable. If your\n // backend cannot guarantee read-after-write across replicas, prefer a\n // single iap.refresh() over multi-entry recovery.\n for (const result of settled) {\n if (result.status === 'rejected') {\n // processEntry catches its own throws; this branch only fires on a\n // truly unexpected runtime error (e.g. logger threw). Count as failure.\n failures += 1;\n continue;\n }\n if (result.value.kind === 'recovered') {\n recovered += 1;\n latestEntitlements = result.value.entitlements;\n } else if (result.value.kind === 'dropped-permanent') {\n droppedPermanent += 1;\n } else {\n failures += 1;\n }\n }\n\n if (latestEntitlements !== null) {\n await this.applyEntitlements(latestEntitlements);\n }\n\n logger.debug(\n `Recovery: ${recovered} recovered, ${droppedPermanent} dropped (permanent), ${failures} left in list (will retry next launch).`,\n );\n\n return { recovered, failures, droppedPermanent, inspected: entries.length };\n }\n\n /**\n * Verify, acknowledge and settle one transaction that arrived outside a\n * `purchase()` call — a renewal, a refund, an Ask-to-Buy approval, a\n * pending Play purchase that cleared.\n *\n * Routed through the same path recovery uses, deliberately: persisted\n * before verification so app death cannot lose it, and left in the store\n * to retry if anything fails. A second settlement path would be a second\n * place for those to drift.\n *\n * **One invariant does not carry over, and it is worth being exact about.**\n * On the iOS update feed the native plugin calls `transaction.finish()`\n * *before* it notifies listeners, so by the time iap sees the transaction\n * the platform has already finished it. \"Acknowledged only after the\n * backend confirms\" therefore describes the purchase flow, not this path —\n * iap has no say in the ordering here. The consequence is that persisting\n * first matters *more*, not less: StoreKit will not redeliver a finished\n * transaction, so the `unfinished` entry is the only remaining handle on\n * it. Callers on that path pass `alreadyFinished`.\n */\n /**\n * Whether an Android consumable's purchase has left the store's owned set,\n * which makes a failed consume terminal rather than retryable.\n *\n * The sequence this exists for: the consume succeeds on Play, then the\n * bridge reply or the `unfinished.remove` that follows fails. Play has\n * already dropped the purchase — Billing 8.x stops returning consumed\n * purchases from `getPurchases()` — so every later consume of that token\n * rejects, the entry is retained, and recovery retries it at every launch\n * forever, burning a `recoveryMaxBatch` slot and a verify each time. The\n * unfinished store has no age-based eviction to catch that.\n *\n * Acknowledging had no such trap: the purchase stayed owned, so a retry\n * eventually worked. So this asks the store a positive question — is the\n * purchase still there — rather than trying to read a meaning out of the\n * error, which would mean matching on Play's message text.\n *\n * Only for Google consumables, only on the failure path, and `false` on\n * any doubt: a store that cannot answer must not be taken to have said\n * \"gone\", or a genuinely retryable failure would be dropped.\n */\n private async alreadyGone(tx: NativeTransaction): Promise<boolean> {\n if (tx.platform !== 'google' || tx.productType !== 'consumable') return false;\n\n try {\n const owned = await this.deps.nativeAdapter.getOwnedTransactions();\n return !owned.some((candidate) => candidate.token === tx.token);\n } catch (error) {\n this.deps.logger.debug(\n `Recovery: could not re-read the owned set for productId=${tx.productId}; treating the settle failure as retryable.`,\n error,\n );\n return false;\n }\n }\n\n async settleTransaction(\n tx: NativeTransaction,\n opts: { persist?: boolean; alreadyFinished?: boolean } = {},\n ): Promise<'settled' | 'failed' | 'dropped-permanent'> {\n // At-least-once: persist before verifying, as the purchase flow does.\n //\n // `persist: false` is for a transaction there is nothing to recover from\n // — a revocation, say. Those verify `valid:false` with a code no\n // permanent-error list knows, so they would be retained and re-verified\n // at every launch forever, eating the recovery batch that real entries\n // need. The store has no age-based eviction to catch that.\n if (opts.persist !== false) {\n try {\n await this.deps.unfinished.add(tx);\n } catch (error) {\n this.deps.logger.warn(\n `Transaction update: failed to persist unfinished entry for \"${tx.productId}\"; verifying anyway.`,\n error,\n );\n }\n }\n\n const result = await this.processTransaction(tx, opts);\n if (result.kind === 'recovered') {\n await this.applyEntitlements(result.entitlements);\n return 'settled';\n }\n return result.kind === 'dropped-permanent' ? 'dropped-permanent' : 'failed';\n }\n\n private async processEntry(\n entry: UnfinishedTransaction,\n ): Promise<\n | { kind: 'recovered'; entitlements: TEntitlement[] }\n | { kind: 'failed' }\n | { kind: 'dropped-permanent' }\n > {\n return this.processTransaction(entryToNativeTransaction(entry));\n }\n\n private async processTransaction(\n tx: NativeTransaction,\n opts: { alreadyFinished?: boolean } = {},\n ): Promise<\n | { kind: 'recovered'; entitlements: TEntitlement[] }\n | { kind: 'failed' }\n | { kind: 'dropped-permanent' }\n > {\n const { nativeAdapter, unfinished, logger, emitter, permanentErrorCodes } = this.deps;\n const tokenLabel = maskToken(tx.token);\n\n try {\n const response = await verifyNativeTransaction(this.deps.backend, tx);\n\n if (!response.valid) {\n if (permanentErrorCodes.has(response.error)) {\n logger.info(\n `Recovery: dropping permanently-invalid token=${tokenLabel} productId=${tx.productId} (${response.error}).`,\n );\n\n // Best-effort native ack — clears StoreKit's queue. Failure here\n // doesn't block removal: the entry is permanently invalid, native\n // ack failure is rare and transient, and even an orphaned native\n // tx won't re-enter unfinished storage (no init-time sync exists,\n // only `purchase-flow.ts` writes to this store).\n //\n // Deliberately an acknowledge and not `finalizeTransaction`:\n // consuming is for a purchase iap has granted, and verification\n // has just called this one permanently invalid. The cost is worth\n // naming — a permanently-rejected Android *consumable* stays\n // owned, so the user can never buy that product again. Releasing\n // ownership for something declared invalid is the worse trade, and\n // a purchase that fails verification permanently is a backend or\n // catalog problem to fix, not a state to launder.\n try {\n await nativeAdapter.acknowledge(tx);\n } catch (error) {\n logger.warn(\n `Recovery: best-effort acknowledge() failed for productId=${tx.productId}; proceeding with removal anyway.`,\n error,\n );\n }\n\n try {\n await unfinished.remove(tx.token);\n } catch (error) {\n logger.warn(\n `Recovery: unfinished.remove() failed for productId=${tx.productId} after permanent classification; will dedupe on next launch.`,\n error,\n );\n }\n\n emitter.emit('recovery-dropped-permanent', {\n productId: tx.productId,\n token: tx.token,\n error: response.error,\n ...(response.message !== undefined ? { message: response.message } : {}),\n });\n\n return { kind: 'dropped-permanent' };\n }\n\n logger.debug(\n `Recovery: backend rejected token=${tokenLabel} productId=${tx.productId} (${response.error}); leaving in list for retry.`,\n );\n return { kind: 'failed' };\n }\n\n // Settle with the store — acknowledge, or consume for an Android\n // consumable. Failure means we don't yet remove — next launch retries.\n //\n // The permanent-rejection path above deliberately still only\n // acknowledges: that transaction did *not* verify, and consuming is\n // for a purchase iap has granted.\n try {\n await finalizeTransaction({ nativeAdapter, transaction: tx, logger });\n } catch (error) {\n // …unless the platform already finished it, which is the case for a\n // transaction off the iOS update feed. There the plugin finishes\n // before notifying, and `acknowledgePurchase` then looks the\n // transaction up in `Transaction.all` and rejects with \"not found or\n // already finished\" — which `Transaction.all` guarantees for a\n // finished consumable. Treating that as a failure would retain the\n // entry forever and never resolve a pending purchase that in fact\n // completed.\n if (opts.alreadyFinished || (await this.alreadyGone(tx))) {\n logger.debug(\n `Recovery: settling productId=${tx.productId} failed, but the store no longer has the purchase; treating as settled.`,\n );\n } else {\n logger.warn(\n `Recovery: settling productId=${tx.productId} with the store failed; entry retained for next launch.`,\n error,\n );\n return { kind: 'failed' };\n }\n }\n\n // Remove from unfinished. A failure here is logged but treated as\n // success for entitlement purposes — the cache write below still\n // happens, and the next recovery's idempotent verify will be a\n // no-op (token already verified by backend).\n try {\n await unfinished.remove(tx.token);\n } catch (error) {\n logger.warn(\n `Recovery: unfinished.remove() failed for productId=${tx.productId}; will dedupe on next launch.`,\n error,\n );\n }\n\n // Settled, so a pending mark announced for this product is over.\n // Done here rather than in the caller so recovery at launch, the\n // update listener and reconciliation all get it.\n await resolvePendingPurchase(this.deps, tx.productId, 'purchased');\n\n return { kind: 'recovered', entitlements: response.entitlements };\n } catch (error) {\n logger.warn(\n `Recovery: verify failed for productId=${tx.productId}; will retry next launch.`,\n error,\n );\n return { kind: 'failed' };\n }\n }\n\n private async applyEntitlements(entitlements: TEntitlement[]): Promise<void> {\n const { cache, emitter, logger } = this.deps;\n const previous = this.deps.getCurrentEntitlements();\n\n // L3: structural-compare BEFORE write so a future setter that normalizes\n // the array (sort, dedupe, freeze) can't make the equality check lie.\n const unchanged = entitlementsEqual(previous, entitlements);\n\n try {\n const cachedAt = await cache.save(entitlements);\n this.deps.setCachePersisted(cachedAt);\n } catch (error) {\n logger.warn('Recovery: cache.save failed; in-memory state still updated.', error);\n }\n this.deps.setEntitlements(entitlements);\n\n if (unchanged) return;\n\n emitter.emit('entitlements-changed', {\n entitlements: this.deps.getCurrentEntitlements(),\n previous,\n });\n }\n}\n\nfunction entryToNativeTransaction(entry: UnfinishedTransaction): NativeTransaction {\n const tx: NativeTransaction = {\n platform: entry.platform,\n productId: entry.productId,\n token: entry.token,\n // Entries persisted before `purchaseReference` existed carry only the\n // token; on Android the two are the same value anyway, and on iOS the\n // token is the right fallback (see `NativeTransaction`).\n // `||`, not `??`: a stored empty string is as unusable as an absent one.\n purchaseReference: entry.purchaseReference || entry.token,\n productType: entry.productType,\n };\n // Restore what a verification needs. Without these a local check sees an\n // amputated transaction and answers differently than it did at purchase\n // time — see the fields' note in `unfinished-transactions.ts`.\n if (entry.appUserId) tx.appUserId = entry.appUserId;\n if (entry.expiresAt) {\n tx.subscription = {\n state: null,\n autoRenewing: null,\n renewsAt: null,\n renewalProductId: null,\n expiresAt: entry.expiresAt,\n };\n }\n if (entry.purchaseState) {\n tx.raw = { purchaseState: entry.purchaseState };\n }\n if (entry.packageName) tx.packageName = entry.packageName;\n return tx;\n}\n","import type {\n BackendAdapter,\n RestoreRequest,\n RestoreRequestTransaction,\n RestoreResponse,\n} from '../adapters/backend/types.js';\nimport type { NativeAdapter } from '../adapters/native/types.js';\nimport type { TypedEventEmitter } from '../events/emitter.js';\nimport { IAPError, IAPErrorCode, toIAPError } from '../lib/errors.js';\nimport type { Logger } from '../lib/logger.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport type { RestoreResult } from '../types/results.js';\nimport type { NativeTransaction } from '../types/transaction.js';\nimport { type EntitlementCache, entitlementsEqual } from './entitlement-cache.js';\nimport { finalizeTransaction } from './finalize-transaction.js';\nimport type { PendingPurchasesStore } from './pending-purchases.js';\nimport { resolvePendingPurchase } from './resolve-pending.js';\nimport { toStorePurchase } from './store-purchase.js';\nimport type { UnfinishedTransactionsStore } from './unfinished-transactions.js';\n\ninterface RestoreOrchestratorDeps<TEntitlement extends EntitlementBase> {\n nativeAdapter: NativeAdapter;\n backend: BackendAdapter<TEntitlement>;\n cache: EntitlementCache<TEntitlement>;\n unfinished: UnfinishedTransactionsStore;\n /**\n * So a pending mark this restore settles is cleared.\n *\n * Restore used to be the one settle path without this, and it was\n * survivable only by accident: an acknowledged purchase stays in the\n * store's owned set, so the next reconcile found it and cleared the mark\n * one pass late. A **consumed** purchase is gone from that set, so the\n * reconcile instead sees it neither owned nor pending and reports it\n * `cancelled` — for a purchase that succeeded.\n */\n pending: PendingPurchasesStore;\n emitter: TypedEventEmitter<TEntitlement>;\n logger: Logger;\n getCurrentEntitlements: () => TEntitlement[];\n setEntitlements: (next: TEntitlement[]) => void;\n setCachePersisted: (cachedAt: number) => void;\n}\n\n/**\n * Coordinates `iap.restorePurchases()` per PLAN.md §5.5.\n *\n * Sequence:\n * 1. Emit `restore-started`.\n * 2. `nativeAdapter.getOwnedTransactions()` (delegates to the capgo plugin's\n * `getPurchases()`).\n * 3. If empty → emit `restore-completed` with current entitlements,\n * return `{ restored: 0, entitlements: <current> }`. No backend call.\n * This covers fresh-install-no-purchases. The empty-array guard lives\n * here (orchestrator level) rather than in the HTTP adapter so all\n * transport implementations benefit automatically.\n * 4. POST batch to `backend.restore()`.\n * 5. On `valid: true`:\n * - Settle each verified transaction with the store — acknowledge, or\n * consume for an Android consumable (see `finalizeTransaction`).\n * Best-effort per transaction; one that fails keeps its unfinished\n * entry so recovery retries it on the next launch.\n * - Persist consolidated entitlements via `cache.save()`.\n * - Replace state.\n * - Remove from `unfinished_transactions` (defensive — purchase flow may\n * have left an entry there for one of these tokens after a crash).\n * - Emit `restore-completed` then `entitlements-changed`.\n * 6. On `valid: false` or backend throw: throw `IAPError` (orchestrator\n * surface is throw-on-fail, unlike `purchase()` which returns a\n * discriminated union; restore is consumer-initiated and a thrown\n * error is the right shape for \"Restore Purchases\" buttons).\n */\nexport class RestoreOrchestrator<TEntitlement extends EntitlementBase = EntitlementBase> {\n constructor(private readonly deps: RestoreOrchestratorDeps<TEntitlement>) {}\n\n async restorePurchases(): Promise<RestoreResult<TEntitlement>> {\n const { nativeAdapter, backend, cache, unfinished, emitter, logger } = this.deps;\n\n emitter.emit('restore-started', undefined);\n\n let owned: NativeTransaction[];\n try {\n owned = await nativeAdapter.getOwnedTransactions();\n } catch (cause) {\n throw toIAPError(cause, 'Failed to fetch owned transactions.', IAPErrorCode.STORE_ERROR);\n }\n\n if (owned.length === 0) {\n const entitlements = this.deps.getCurrentEntitlements();\n emitter.emit('restore-completed', { restored: 0, entitlements });\n // `purchases` is derived from the store's own answer, not the backend\n // response, so it is correct on this short-circuit path too.\n return { restored: 0, entitlements, purchases: [] };\n }\n\n let response: RestoreResponse<TEntitlement>;\n try {\n // An adapter that answers from the transaction gets them whole. The\n // extraction below drops the fields it needs, and building it requires\n // a packageName such an adapter never reads — so a request it would\n // discard could fail the restore outright.\n response = backend.restoreNative\n ? await backend.restoreNative(owned)\n : await backend.restore({ transactions: owned.map((tx) => this.toRestoreEntry(tx)) });\n } catch (cause) {\n throw toIAPError(cause, 'Backend restore call failed.', IAPErrorCode.BACKEND_UNAVAILABLE);\n }\n\n if (!response.valid) {\n // Compose both the human-readable message and the stable machine code\n // so consumers can grep for either. PLAN.md §5.8 marks `error` as the\n // stable identifier — preserve it even when message is present.\n const detail = response.message\n ? `${response.message} [${response.error}]`\n : `Backend rejected restore (${response.error}).`;\n throw new IAPError({\n code: IAPErrorCode.VERIFICATION_REJECTED,\n message: detail,\n });\n }\n\n // Settle each verified transaction with the store. Failures are\n // best-effort per transaction — verification says these are valid — and\n // the entry survives below so recovery retries it.\n //\n // `verifiedTokens`, when the adapter supplies it, is what keeps the\n // acknowledge-after-verification invariant true here. An adapter that\n // judges transactions individually (on-device verification does) can\n // pass some and refuse others, and a single consolidated `valid: true`\n // cannot say which — so acknowledging the whole owned set would\n // finalise purchases that were just refused.\n const ackable =\n response.verifiedTokens === undefined\n ? owned\n : owned.filter((tx) => response.verifiedTokens?.includes(tx.token));\n\n if (ackable.length !== owned.length) {\n logger.debug(\n `Restore: settling ${ackable.length} of ${owned.length} owned transaction(s); the rest were not verified.`,\n );\n }\n\n // Which transactions actually settled, so the drain below removes only\n // those. Draining the whole owned set used to be merely untidy, because\n // a failed acknowledge left the purchase owned and the next\n // restore()/refresh() re-acked it. A consumable that fails to consume\n // stays owned *and* unacknowledged, with Play's three-day refund clock\n // running — and dropping its unfinished entry removes the only record\n // that would have made recovery retry it.\n const settled: NativeTransaction[] = [];\n for (const tx of ackable) {\n try {\n await finalizeTransaction({ nativeAdapter, transaction: tx, logger });\n settled.push(tx);\n } catch (error) {\n logger.warn(`Settling \"${tx.productId}\" with the store failed during restore.`, error);\n }\n }\n\n const entitlements = response.entitlements;\n const previous = this.deps.getCurrentEntitlements();\n\n try {\n const cachedAt = await cache.save(entitlements);\n this.deps.setCachePersisted(cachedAt);\n } catch (error) {\n logger.warn(\n 'Failed to persist entitlements after restore; in-memory state still updated.',\n error,\n );\n }\n this.deps.setEntitlements(entitlements);\n\n // Drain the unfinished list of the tokens we actually settled — not the\n // whole owned set, which would also drop entries for transactions\n // `verifiedTokens` explicitly refused.\n for (const tx of settled) {\n try {\n await unfinished.remove(tx.token);\n } catch (error) {\n logger.warn(\n `Failed to remove \"${tx.productId}\" from unfinished list during restore.`,\n error,\n );\n }\n }\n\n // And clear any pending mark these settled, which is what stops a later\n // reconcile reporting a succeeded purchase as `cancelled`. Atomic via\n // `takeIfPresent`, so overlapping with recovery or the update listener\n // still fires `purchase-pending-resolved` at most once.\n for (const tx of settled) {\n try {\n await resolvePendingPurchase(this.deps, tx.productId, 'purchased');\n } catch (error) {\n logger.warn(\n `Failed to clear the pending mark for \"${tx.productId}\" during restore.`,\n error,\n );\n }\n }\n\n const next = this.deps.getCurrentEntitlements();\n emitter.emit('restore-completed', { restored: owned.length, entitlements: next });\n\n // L3: skip the emit when content is unchanged (avoids spurious re-renders\n // in reactive consumer stores that subscribe to entitlements-changed).\n if (!entitlementsEqual(previous, next)) {\n emitter.emit('entitlements-changed', { entitlements: next, previous });\n }\n\n return {\n restored: owned.length,\n entitlements: next,\n purchases: owned.map(toStorePurchase),\n };\n }\n\n private toRestoreEntry(tx: NativeTransaction): RestoreRequestTransaction {\n if (tx.platform === 'apple') {\n return {\n platform: 'apple',\n productId: tx.productId,\n transactionId: tx.token,\n };\n }\n if (!tx.packageName) {\n throw new IAPError({\n code: IAPErrorCode.STORE_ERROR,\n message: `Google owned transaction for \"${tx.productId}\" has no packageName; cannot restore. Set config.android.packageName to your app's applicationId — the native plugin does not report it, so iap cannot derive it from the purchase.`,\n });\n }\n return {\n platform: 'google',\n productId: tx.productId,\n purchaseToken: tx.token,\n packageName: tx.packageName,\n };\n }\n}\n","import type { NativeAdapter } from '../adapters/native/types.js';\nimport type { TypedEventEmitter } from '../events/emitter.js';\nimport type { Logger } from '../lib/logger.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport type { NativeTransaction } from '../types/transaction.js';\nimport type { PendingPurchasesStore } from './pending-purchases.js';\nimport type { RecoveryOrchestrator } from './recovery-flow.js';\nimport { resolvePendingPurchase } from './resolve-pending.js';\nimport { toStorePurchase } from './store-purchase.js';\n\ninterface TransactionUpdateDeps<TEntitlement extends EntitlementBase> {\n nativeAdapter: NativeAdapter;\n /** Reused for settlement so the safety invariants live in one place. */\n recoverer: RecoveryOrchestrator<TEntitlement>;\n pending: PendingPurchasesStore;\n emitter: TypedEventEmitter<TEntitlement>;\n logger: Logger;\n /**\n * Whether `purchase()` is currently handling this product. The platform\n * delivers the same transaction to both paths, and the purchase flow owns\n * the one it started.\n */\n isPurchaseInFlight: (productId: string) => boolean;\n /**\n * Whether the iap instance is still live. A native callback can fire\n * during or after `destroy()`, and settling then would write through the\n * shared state closures and repopulate a torn-down instance.\n */\n isActive: () => boolean;\n}\n\n/**\n * Handles transactions the store produces on its own, and closes out\n * pending purchases.\n *\n * Two entry points, because the platforms differ:\n *\n * - {@link handle} is driven by a native listener. Apple's\n * `Transaction.updates` pushes renewals, refunds, revocations and\n * Ask-to-Buy approvals as they happen.\n * - {@link reconcilePending} asks the store directly. It is the **only**\n * mechanism on Android, which has no equivalent feed — a Play purchase\n * that clears while the app is closed is discovered by looking, at the\n * next launch or resume.\n *\n * Nothing here throws. Both are called from a native callback or from\n * `initialize()`, where a rejection would either be swallowed somewhere\n * unhelpful or break startup.\n */\nexport class TransactionUpdateOrchestrator<TEntitlement extends EntitlementBase = EntitlementBase> {\n /**\n * Tokens currently being settled, so two paths cannot settle the same\n * transaction at once.\n *\n * The listener is fire-and-forget and reconciliation runs on resume, so\n * they genuinely overlap. Without this, both verify and both acknowledge —\n * and on Android a second `acknowledge` of an already-acked token errors,\n * which the settle path reads as a failure and retains the entry for.\n */\n private readonly settling = new Set<string>();\n\n /** The in-flight reconciliation pass, so concurrent callers join it. */\n private reconciling: Promise<void> | null = null;\n\n constructor(private readonly deps: TransactionUpdateDeps<TEntitlement>) {}\n\n /** Settle a transaction pushed by the platform. Never throws. */\n async handle(transaction: NativeTransaction): Promise<void> {\n const { logger, emitter, isPurchaseInFlight } = this.deps;\n\n try {\n // StoreKit delivers the transaction a purchase() produced to\n // Transaction.updates as well. Settling it here too would verify and\n // acknowledge twice and emit a spurious entitlements-changed, so the\n // flow that started it keeps it.\n if (!this.deps.isActive()) {\n logger.debug('Transaction update arrived after teardown; ignoring.');\n return;\n }\n\n if (isPurchaseInFlight(transaction.productId)) {\n logger.debug(\n `Transaction update for \"${transaction.productId}\" arrived while a purchase is in flight; leaving it to the purchase flow.`,\n );\n return;\n }\n\n emitter.emit('transaction-updated', {\n productId: transaction.productId,\n purchase: toStorePurchase(transaction),\n });\n\n // A revocation or a refund has nothing to recover: it verifies\n // `valid:false` with a code no permanent-error list knows, so\n // persisting it would retain it and re-verify at every launch forever,\n // crowding out entries that can still succeed.\n const isRevocation = transaction.subscription?.state === 'revoked';\n\n // On iOS the plugin finishes the transaction before notifying, so a\n // failing acknowledge here means \"already finished\", not \"could not\n // finish\". Android has no update feed, so this only ever applies to\n // Apple transactions.\n const outcome = await this.settleOnce(transaction, {\n persist: !isRevocation,\n alreadyFinished: transaction.platform === 'apple',\n });\n if (outcome !== 'settled') {\n logger.debug(\n `Transaction update for \"${transaction.productId}\" did not settle (${outcome}).`,\n );\n }\n // The 'purchased' resolution happens inside the settle path, so every\n // route to a settled transaction reports it — see `resolve-pending.ts`.\n } catch (error) {\n logger.warn(\n `Transaction update handling threw for \"${transaction.productId}\"; ignoring.`,\n error,\n );\n }\n }\n\n /**\n * Ask the store what became of the purchases iap reported as pending.\n *\n * Call at `initialize()` and on resume. Does nothing when nothing is\n * tracked, so the common case costs no native calls. Never throws.\n */\n async reconcilePending(): Promise<void> {\n // Single-flight. Two resume events in quick succession each schedule a\n // pass (the resume listener does not debounce), and two passes would\n // each settle the same transactions.\n if (this.reconciling) return this.reconciling;\n this.reconciling = this.runReconcile().finally(() => {\n this.reconciling = null;\n });\n return this.reconciling;\n }\n\n private async runReconcile(): Promise<void> {\n const { nativeAdapter, logger, pending } = this.deps;\n\n try {\n if (!this.deps.isActive()) return;\n const tracked = await pending.list();\n if (tracked.length === 0) return;\n\n // Read pending FIRST, then owned. These are two separate native\n // round-trips, so a purchase can clear in between — and the order\n // decides which way that window resolves. Pending-then-owned means a\n // purchase seen as pending and then as owned reads as owned (correct),\n // while owned-then-pending would show it in neither and report it\n // cancelled. Erring towards \"still pending\" self-corrects next pass;\n // erring towards \"cancelled\" is permanent.\n //\n // `null` means the platform cannot report pending state, which is a\n // different answer from \"nothing is pending\". iOS cannot: a deferred\n // purchase that is never approved produces no signal, so \"not owned\"\n // there is indistinguishable from \"still waiting\".\n const stillPending = (await nativeAdapter.getPendingProductIds?.()) ?? null;\n\n const owned = await nativeAdapter.getOwnedTransactions();\n const ownedByProduct = new Map(owned.map((tx) => [tx.productId, tx]));\n\n for (const productId of tracked) {\n // Same reasoning as `handle()`: whichever path started a purchase\n // owns settling it. Reconciliation can coincide with a retry of the\n // same product, and settling underneath it would verify and\n // acknowledge twice.\n if (this.deps.isPurchaseInFlight(productId)) {\n logger.debug(\n `Pending purchase \"${productId}\" is being purchased right now; leaving it to the purchase flow.`,\n );\n continue;\n }\n\n const ownedTx = ownedByProduct.get(productId);\n if (ownedTx) {\n // Announcing it is not enough: an unacknowledged Play purchase is\n // refunded after three days, and nothing else will settle this one\n // on Android, where no update event exists.\n const outcome = await this.settleOnce(ownedTx);\n if (outcome !== 'settled') {\n logger.debug(\n `Pending purchase \"${productId}\" is owned but did not settle (${outcome}); keeping it pending.`,\n );\n }\n continue;\n }\n\n if (stillPending === null) {\n logger.debug(\n `Pending purchase \"${productId}\" is not owned, but this platform cannot report pending state; keeping it pending.`,\n );\n continue;\n }\n\n if (stillPending.includes(productId)) continue;\n\n // The store has it neither owned nor waiting: the payment failed,\n // expired, or was abandoned.\n await this.resolvePending(productId, 'cancelled');\n }\n } catch (error) {\n // Keep every marker on failure. A pending purchase wrongly left\n // pending resolves on the next pass; one wrongly cancelled tells the\n // consumer something false and never corrects itself.\n logger.warn('Reconciling pending purchases failed; markers kept for the next pass.', error);\n }\n }\n\n /**\n * Settle a transaction, unless it is already being settled.\n *\n * Keyed on the token, not the product: two different transactions for one\n * product (an iOS subscription has a token per renewal) should both\n * settle, while the same transaction reaching both paths should not.\n */\n private async settleOnce(\n tx: NativeTransaction,\n opts: { persist?: boolean; alreadyFinished?: boolean } = {},\n ): Promise<'settled' | 'failed' | 'dropped-permanent' | 'already-settling'> {\n if (this.settling.has(tx.token)) return 'already-settling';\n this.settling.add(tx.token);\n try {\n return await this.deps.recoverer.settleTransaction(tx, opts);\n } finally {\n this.settling.delete(tx.token);\n }\n }\n\n /** Announce how a pending purchase ended. See `resolve-pending.ts`. */\n private async resolvePending(\n productId: string,\n status: 'purchased' | 'cancelled',\n ): Promise<void> {\n await resolvePendingPurchase(this.deps, productId, status);\n }\n}\n","/**\n * Serializes read-modify-write sequences against a single storage key.\n *\n * Every store here does the same thing — read the current value, change it,\n * write it back — and that is not atomic over an async storage adapter. Two\n * concurrent callers each read the same snapshot and the second write\n * silently discards the first. Recovery running several entries in parallel\n * is what first exposed it.\n *\n * A promise chain rather than a real lock: each call awaits the previous\n * one's completion, so sequences run in invocation order and a throw inside\n * one does not wedge the chain (the `finally` always releases).\n *\n * Reads are deliberately *not* serialized. They tolerate a stale snapshot,\n * and routing them through the chain would let a slow write block them.\n */\nexport type MutationLock = <T>(fn: () => Promise<T>) => Promise<T>;\n\nexport function createMutationLock(): MutationLock {\n let tail: Promise<void> = Promise.resolve();\n\n return async function runExclusive<T>(fn: () => Promise<T>): Promise<T> {\n const previous = tail;\n let release!: () => void;\n tail = new Promise((resolve) => {\n release = resolve;\n });\n try {\n await previous;\n return await fn();\n } finally {\n release();\n }\n };\n}\n","import { z } from 'zod';\nimport type { StorageAdapter } from '../adapters/storage/types.js';\nimport type { Logger } from '../lib/logger.js';\nimport { type MutationLock, createMutationLock } from './mutation-lock.js';\nimport { IAP_STORAGE_KEYS } from './storage-keys.js';\n\nconst STORE_KEY = IAP_STORAGE_KEYS.pendingPurchases;\n\n/**\n * An entry carries when it was marked, so a mark that can never resolve\n * does not live forever. See {@link MAX_PENDING_AGE_MS}.\n *\n * The bare-string form is what earlier versions wrote. Accepted on read so\n * an upgrade does not drop a live pending purchase; such an entry has no\n * recorded time, so it is treated as marked now and ages from this launch.\n */\nconst pendingEntrySchema = z.union([\n z.object({ productId: z.string().min(1), recordedAt: z.string().min(1) }),\n z\n .string()\n .min(1)\n .transform((productId) => ({ productId, recordedAt: '' })),\n]);\n\nconst pendingListSchema = z.array(pendingEntrySchema);\n\ninterface PendingEntry {\n productId: string;\n /** ISO 8601, or `''` for an entry written before this field existed. */\n recordedAt: string;\n}\n\n/**\n * How long a pending mark is kept.\n *\n * It exists for the iOS case that cannot otherwise end: a deferred\n * (Ask-to-Buy) purchase that is declined produces no signal at all, and\n * StoreKit offers no way to enumerate deferred purchases — so iap can never\n * learn that mark is dead. Left alone it would survive for the life of the\n * install and make every single foreground ask the store for its owned\n * transactions.\n *\n * 30 days is well past any real clearance window (Play's cash and e-wallet\n * flows are hours to days) while still bounding the cost. An expired mark is\n * dropped **silently** — no `cancelled` event — because expiry is iap giving\n * up on knowing, not the store saying the purchase failed.\n */\nconst MAX_PENDING_AGE_MS = 30 * 24 * 60 * 60 * 1000;\n\n/**\n * The product ids iap has told the consumer are awaiting clearance — the\n * ones it emitted `purchase-pending` for.\n *\n * It exists because a pending purchase resolves **out of band and possibly\n * in another session**. Play's e-wallet and cash flows can take hours; the\n * app is usually closed by the time the money arrives. Without a record\n * that survives a launch, iap could never tell the consumer the pending\n * state had ended, and a paywall would sit on \"waiting for payment\" until\n * the user reinstalled.\n *\n * Deliberately only product ids, not transactions: a pending Play purchase\n * has no token worth keeping (it is not owned yet), and the only question\n * being tracked is \"did the thing we announced ever resolve\".\n *\n * Tolerant like the other stores: a corrupt payload reads as empty rather\n * than throwing, because a lost pending marker costs a stale UI hint, while\n * a throw here would break `initialize()`.\n */\nexport class PendingPurchasesStore {\n private readonly runExclusive: MutationLock = createMutationLock();\n\n constructor(\n private readonly storage: StorageAdapter,\n private readonly logger: Logger,\n ) {}\n\n /** Product ids currently marked pending, or `[]` if empty / corrupt. */\n async list(): Promise<string[]> {\n return (await this.readLive()).map((entry) => entry.productId);\n }\n\n /** Live entries, with anything past {@link MAX_PENDING_AGE_MS} dropped. */\n private async readLive(): Promise<PendingEntry[]> {\n let raw: string | null;\n try {\n raw = await this.storage.get(STORE_KEY);\n } catch (cause) {\n this.logger.warn('Storage read failed; treating pending list as empty.', cause);\n return [];\n }\n if (!raw) return [];\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (cause) {\n this.logger.warn('pending_purchases payload is not valid JSON; clearing.', cause);\n await this.safeRemove();\n return [];\n }\n\n const result = pendingListSchema.safeParse(parsed);\n if (!result.success) {\n this.logger.warn('pending_purchases has unexpected shape; clearing.', result.error);\n await this.safeRemove();\n return [];\n }\n\n const now = Date.now();\n const live = result.data.filter((entry) => {\n // An entry with no recorded time came from a version before the field\n // existed. Keep it and let it age from now rather than guessing.\n if (entry.recordedAt === '') return true;\n const marked = Date.parse(entry.recordedAt);\n if (Number.isNaN(marked)) return false;\n return now - marked < MAX_PENDING_AGE_MS;\n });\n\n if (live.length !== result.data.length) {\n this.logger.debug(\n `Dropping ${result.data.length - live.length} pending mark(s) past the age limit.`,\n );\n // Best-effort: re-reading is cheap and a lost prune just re-prunes.\n await this.persist(live);\n }\n return live;\n }\n\n async has(productId: string): Promise<boolean> {\n return (await this.list()).includes(productId);\n }\n\n /**\n * Remove a product's pending mark and report whether it was there.\n *\n * The atomic form of `has()` then `remove()`, and the reason it exists:\n * `purchase-pending-resolved` promises to fire at most once per pending\n * purchase, and the two callers that resolve one can run concurrently —\n * the iOS transaction listener is fire-and-forget, so it can interleave\n * with the reconciliation that runs on resume. Checked and removed\n * separately, both would observe the mark and both would emit.\n */\n async takeIfPresent(productId: string): Promise<boolean> {\n return this.runExclusive(async () => {\n const current = await this.readLive();\n if (!current.some((entry) => entry.productId === productId)) return false;\n await this.persist(current.filter((entry) => entry.productId !== productId));\n return true;\n });\n }\n\n /** Mark a product pending. Idempotent — re-marking does not reset the age. */\n async add(productId: string): Promise<void> {\n return this.runExclusive(async () => {\n const current = await this.readLive();\n if (current.some((entry) => entry.productId === productId)) return;\n await this.persist([...current, { productId, recordedAt: new Date().toISOString() }]);\n });\n }\n\n /** Clear a product's pending mark. No-op if absent. */\n async remove(productId: string): Promise<void> {\n return this.runExclusive(async () => {\n const current = await this.readLive();\n const next = current.filter((entry) => entry.productId !== productId);\n if (next.length === current.length) return;\n await this.persist(next);\n });\n }\n\n /** Drop every pending mark. Used by `iap.reset()`. */\n async clear(): Promise<void> {\n return this.runExclusive(() => this.safeRemove());\n }\n\n private async persist(entries: PendingEntry[]): Promise<void> {\n try {\n await this.storage.set(STORE_KEY, JSON.stringify(entries));\n } catch (cause) {\n // Best-effort, unlike the unfinished store: losing a pending marker\n // costs a stale UI hint, not a purchase. Never throw into a caller\n // that is reporting a pending result to the consumer.\n this.logger.warn('Failed to persist pending_purchases; pending state may be lost.', cause);\n }\n }\n\n private async safeRemove(): Promise<void> {\n try {\n await this.storage.remove(STORE_KEY);\n } catch (cause) {\n this.logger.warn('Failed to clear pending_purchases key.', cause);\n }\n }\n}\n","import { IAPError, IAPErrorCode } from '../lib/errors.js';\nimport type { EntitlementBase } from '../types/entitlement.js';\nimport { activeEntitlements } from './entitlement-cache.js';\nimport type { IAPInternalState } from './iap-state.js';\nimport { ALL_IAP_STORAGE_KEYS } from './storage-keys.js';\n\n/**\n * Erase everything iap has stored on this device.\n *\n * See `IAP.reset()` for what this is and is not — in particular that it is\n * neither `destroy()` nor a revocation.\n */\nexport async function resetIap<TEntitlement extends EntitlementBase>(\n state: IAPInternalState<TEntitlement>,\n): Promise<void> {\n // A purchase mid-flight is the one thing worth refusing over, and it is\n // the *unfinished-transaction entry* that makes it so, not the cache.\n // That entry is written before verification precisely so a purchase\n // survives a crash; deleting it mid-flight leaves a purchase neither\n // acknowledged nor tracked, which Play auto-refunds in three days. The\n // cache coming straight back is harmless by comparison — `reset()` was\n // never a revocation, and a `refresh()` re-deriving from the store is\n // documented behaviour.\n //\n // Vacuously true after `destroy()`, which nulls the orchestrator. That\n // is the right answer there: a destroyed instance has nothing left that\n // could re-persist, so it is the *safest* moment to wipe, and a teardown\n // racing a \"delete my data\" tap is a real sequence. Returning early\n // would leave the cache, the queue and the pending marks on the device\n // while telling the caller their data was gone.\n const inFlight = state.orchestrator?.inFlightProducts() ?? [];\n if (inFlight.length > 0) {\n throw new IAPError({\n code: IAPErrorCode.ALREADY_IN_PROGRESS,\n message: `Cannot reset while a purchase of ${inFlight.map((id) => `\"${id}\"`).join(', ')} is in progress: its unfinished-transaction record is still needed. Await the purchase, then reset.`,\n // The per-code hint is written for the other caller of this code — a\n // double `purchase()` of one product — and would tell a consumer\n // debugging a failed reset that they double-called `purchase()`.\n includeHint: false,\n // It is recoverable, whatever the code's default says: await the\n // purchase and try again.\n recoverable: true,\n });\n }\n\n // Fail loudly if the storage backend cannot be reached at all.\n //\n // Every step below is swallow-and-warn, which is right for one key that\n // will not delete — but it also means an adapter that can reach *nothing*\n // resolves this promise normally after logging six warnings and deleting\n // nothing. For a \"delete everything\" control, telling the caller their\n // data is gone when it is still on the device is the one outcome worth\n // throwing over. `reset()` has no `requireInitialized`, so this is the\n // only place that check happens on this path.\n await state.storage.ensureAvailable?.();\n\n const previous = state.entitlements;\n state.entitlements = [];\n state.cachedAt = null;\n\n // Through the stores first, because two of the three serialise their\n // read-modify-write through a mutation lock (`runExclusive`) and this is\n // the only way to take it. A concurrent `pending.add()` that has read but\n // not yet written would otherwise re-persist the whole list after a bare\n // `storage.remove`. Each store swallows its own storage failures.\n await state.cache.clear();\n await state.unfinished.clear();\n await state.pending.clear();\n\n // Then every key in the registry, by name. This is the completeness\n // half: it catches a store added later whose `clear()` nobody remembered\n // to call above, and it is also the only step that works on the\n // Preferences adapter, which can only remove keys it has *seen* this\n // session — an empty set on a fresh launch — so clearing the namespace\n // alone would be a no-op there.\n for (const key of ALL_IAP_STORAGE_KEYS) {\n try {\n await state.storage.remove(key);\n } catch (error) {\n state.logger.warn(`reset(): failed to remove the \"${key}\" key.`, error);\n }\n }\n\n // Finally the namespace itself. Best-effort and adapter-dependent: an\n // adapter that can enumerate by prefix (memory, and most custom ones)\n // sweeps anything not in the registry, while the Preferences adapter is\n // again limited to this session's keys. Ordering matters — a per-key\n // removal that threw leaves the key in the Preferences adapter's known\n // set, so this gives it a second attempt.\n try {\n await state.storage.clear();\n } catch (error) {\n state.logger.warn('reset(): failed to clear the storage namespace.', error);\n }\n\n // The real previous list, not an empty one: a consumer diffing\n // `previous` against `entitlements` is the documented use, and on the\n // one event that removes everything an empty `previous` would read as\n // \"nothing changed\". Skipped entirely when there was nothing to\n // remove, which is the emitter's de-duplication rule elsewhere.\n //\n // `state.entitlements` rather than a literal `[]`, so the payload cannot\n // contradict the instance: a writer that repopulated during the awaits\n // above would otherwise have the event announce \"nothing\" while\n // `getEntitlements()` returned something.\n if (previous.length > 0) {\n state.emitter.emit('entitlements-changed', {\n entitlements: [...state.entitlements],\n previous,\n });\n }\n}\n\n/**\n * The entitlements that are still active right now.\n *\n * Applied at the read boundary rather than when the cache is written,\n * because expiry is a function of *when you ask*: an entitlement cached as\n * valid at 23:59 is not valid at 00:01, with no refresh in between and no\n * network to ask. Filtering on write would hand out a stale answer for the\n * rest of the session.\n */\nexport function activeNow<TEntitlement extends EntitlementBase>(\n state: IAPInternalState<TEntitlement>,\n): TEntitlement[] {\n // Local mode only, deliberately.\n //\n // With a backend, the backend is the authority on what is granted, and it\n // may return an entitlement whose `expiresAt` has passed on purpose —\n // that is exactly what a store-side grace period or billing retry looks\n // like. Second-guessing it against the device clock would have iap\n // perform the downgrade it promises never to, and a device with a fast\n // clock would lock out a paying user even with the backend reachable.\n //\n // With no backend there is no other authority, and the deadline is the\n // only thing that can revoke anything — so enforcing it locally is the\n // whole point. A consumer who wants this in backend mode can filter on\n // `expiresAt` themselves; `getEntitlementsVerifiedAt()` is there for it.\n if (!state.config.verification) return [...state.entitlements];\n\n return activeEntitlements(\n state.entitlements,\n Date.now(),\n state.config.options.entitlementGraceMs,\n );\n}\n","import { z } from 'zod';\nimport type { StorageAdapter } from '../adapters/storage/types.js';\nimport { IAPError, IAPErrorCode, toIAPError } from '../lib/errors.js';\nimport type { Logger } from '../lib/logger.js';\nimport { productTypeSchema } from '../types/config.js';\nimport type { NativeTransaction } from '../types/transaction.js';\nimport { type MutationLock, createMutationLock } from './mutation-lock.js';\nimport { IAP_STORAGE_KEYS } from './storage-keys.js';\n\nconst STORE_KEY = IAP_STORAGE_KEYS.unfinishedTransactions;\n\nconst unfinishedEntrySchema = z.object({\n platform: z.enum(['apple', 'google']),\n productId: z.string().min(1),\n token: z.string().min(1),\n productType: productTypeSchema,\n packageName: z.string().optional(),\n /**\n * The renewal-stable purchase reference. Optional, and deliberately\n * unconstrained beyond its type: entries written before it existed are\n * still valid, and readers fall back to `token`. A `min(1)` here would\n * make an empty string fail the whole entry's parse — rejecting a\n * recoverable purchase over a field recovery does not even read.\n */\n purchaseReference: z.string().optional(),\n /**\n * The fields a verification needs that the extracted request shapes do\n * not carry. All optional, so entries written before they existed still\n * parse.\n *\n * These exist because recovery re-verifies from the **stored entry**, not\n * from a live transaction. Without them a rebuilt transaction has no\n * binding, no expiry and no purchase state — so an on-device check sees\n * an amputated object and answers differently than it did at purchase\n * time: an expired subscription verifies as non-expiring and is granted,\n * and a purchase with a binding fails `BINDING_MISMATCH` forever and is\n * never acknowledged (which on Android means Google refunds it).\n */\n appUserId: z.string().optional(),\n expiresAt: z.string().optional(),\n purchaseState: z.string().optional(),\n /** ISO 8601 timestamp the entry was first persisted. */\n recordedAt: z.string(),\n});\n\n/**\n * Entries are validated one at a time rather than as an array, so one\n * unreadable entry cannot take its neighbours down with it. Parsing the\n * whole array meant a single malformed record failed the parse and cleared\n * every pending recovery — abandoning purchases that were paid for and\n * never acknowledged, which on Android Google refunds after three days.\n */\nconst entryListSchema = z.array(z.unknown());\n\nexport type UnfinishedTransaction = z.infer<typeof unfinishedEntrySchema>;\n\n/**\n * Persistent store for transactions that have completed natively (the user's\n * purchase succeeded with the platform store) but have NOT yet been verified\n * by the consumer backend.\n *\n * Lifecycle:\n * 1. Purchase orchestrator writes the entry BEFORE calling backend verify.\n * 2. On backend success, the orchestrator removes the entry and acks natively.\n * 3. If the app dies between (1) and acking, recovery on next `initialize()`\n * reads this list and re-attempts verification (Phase 6).\n *\n * Same tolerance pattern as {@link EntitlementCache}: malformed JSON is dropped\n * silently and reported as an empty list rather than crashing initialize.\n */\nexport class UnfinishedTransactionsStore {\n /**\n * Serializes mutating operations (`add` / `remove`) so concurrent callers\n * don't race the read-modify-write on the storage key. Phase 6's\n * parallel recovery exposed this — multiple `remove()` calls in flight\n * could each `list()` the same snapshot and overwrite each other's\n * `persist()`.\n */\n private readonly runExclusive: MutationLock = createMutationLock();\n\n constructor(\n private readonly storage: StorageAdapter,\n private readonly logger: Logger,\n ) {}\n\n /** Returns the current list, or `[]` if empty / corrupt. */\n async list(): Promise<UnfinishedTransaction[]> {\n let raw: string | null;\n try {\n raw = await this.storage.get(STORE_KEY);\n } catch (cause) {\n this.logger.warn('Storage read failed; treating unfinished list as empty.', cause);\n return [];\n }\n if (!raw) return [];\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch (cause) {\n this.logger.warn('unfinished_transactions payload is not valid JSON; clearing.', cause);\n await this.safeClear();\n return [];\n }\n\n const list = entryListSchema.safeParse(parsed);\n if (!list.success) {\n // Not a list at all — nothing here is salvageable.\n this.logger.warn('unfinished_transactions is not a list; clearing.', list.error);\n await this.safeClear();\n return [];\n }\n\n const entries: UnfinishedTransaction[] = [];\n let dropped = 0;\n for (const candidate of list.data) {\n const entry = unfinishedEntrySchema.safeParse(candidate);\n if (entry.success) {\n entries.push(entry.data);\n } else {\n dropped++;\n }\n }\n if (dropped > 0) {\n this.logger.warn(\n `Dropped ${dropped} unreadable unfinished-transaction entry/entries; kept ${entries.length}.`,\n );\n }\n return entries;\n }\n\n /**\n * Append a transaction to the list. Idempotent: if a same-token entry\n * already exists, this is a no-op (avoids dupes when restore + active\n * purchase race for the same StoreKit replay).\n *\n * **Keyed on `token`, deliberately — not on `purchaseReference`.** The\n * token is what acknowledges one transaction, and on iOS a subscription\n * has a separate token per renewal while sharing one reference. Keying\n * on the reference would collapse several unacknowledged renewals into\n * one entry and leave the rest unfinished.\n */\n async add(tx: NativeTransaction): Promise<void> {\n return this.runExclusive(async () => {\n const current = await this.list();\n if (current.some((e) => e.token === tx.token)) return;\n const entry: UnfinishedTransaction = {\n platform: tx.platform,\n productId: tx.productId,\n token: tx.token,\n productType: tx.productType,\n ...(tx.packageName ? { packageName: tx.packageName } : {}),\n ...(tx.purchaseReference ? { purchaseReference: tx.purchaseReference } : {}),\n ...(tx.appUserId ? { appUserId: tx.appUserId } : {}),\n ...(tx.subscription?.expiresAt ? { expiresAt: tx.subscription.expiresAt } : {}),\n ...(typeof (tx.raw as { purchaseState?: unknown } | undefined)?.purchaseState ===\n 'string' ||\n typeof (tx.raw as { purchaseState?: unknown } | undefined)?.purchaseState === 'number'\n ? {\n purchaseState: String((tx.raw as { purchaseState?: unknown }).purchaseState),\n }\n : {}),\n recordedAt: new Date().toISOString(),\n };\n await this.persist([...current, entry]);\n });\n }\n\n /** Remove the entry with the given token. No-op if not present. */\n async remove(token: string): Promise<void> {\n return this.runExclusive(async () => {\n const current = await this.list();\n const next = current.filter((e) => e.token !== token);\n if (next.length === current.length) return;\n await this.persist(next);\n });\n }\n\n /** Clear every unfinished entry. */\n async clear(): Promise<void> {\n return this.runExclusive(() => this.safeClear());\n }\n\n private async persist(entries: UnfinishedTransaction[]): Promise<void> {\n try {\n await this.storage.set(STORE_KEY, JSON.stringify(entries));\n } catch (cause) {\n // `toIAPError`, not a fresh IAPError: an error that already *is* an\n // IAPError keeps its own code. A storage adapter can fail for a\n // reason that is not transient — `PreferencesAdapter` raises\n // INVALID_CONFIG when its plugin is not installed — and flattening\n // that to a `recoverable: true` STORAGE_ERROR is what the recovery\n // loop acts on, so the entry would be retried at every launch\n // forever for a cause no retry can fix.\n throw toIAPError(\n cause,\n 'Failed to persist unfinished transactions list.',\n IAPErrorCode.STORAGE_ERROR,\n );\n }\n }\n\n private async safeClear(): Promise<void> {\n try {\n await this.storage.remove(STORE_KEY);\n } catch (cause) {\n this.logger.warn('Failed to clear unfinished_transactions key.', cause);\n }\n }\n}\n","import type { EntitlementBase } from '../types/entitlement.js';\nimport type { EventMap, EventName, EventPayload, Unsubscribe } from '../types/events.js';\n\ntype AnyHandler = (payload: unknown) => void;\n\n/**\n * Tiny typed event emitter. No external dep — just a Map of name → Set<handler>.\n * Generic over the consumer's entitlement type so payloads are statically checked.\n */\nexport class TypedEventEmitter<TEntitlement extends EntitlementBase = EntitlementBase> {\n private readonly handlers = new Map<string, Set<AnyHandler>>();\n\n on<K extends EventName<TEntitlement>>(\n event: K,\n handler: (payload: EventPayload<K, TEntitlement>) => void,\n ): Unsubscribe {\n const key = event as string;\n let set = this.handlers.get(key);\n if (!set) {\n set = new Set();\n this.handlers.set(key, set);\n }\n set.add(handler as AnyHandler);\n return () => {\n const current = this.handlers.get(key);\n if (current) current.delete(handler as AnyHandler);\n };\n }\n\n emit<K extends EventName<TEntitlement>>(event: K, payload: EventPayload<K, TEntitlement>): void {\n const set = this.handlers.get(event as string);\n if (!set) return;\n for (const handler of [...set]) {\n try {\n handler(payload);\n } catch {\n // Handlers must not break the emitter. Swallow to keep other listeners alive.\n }\n }\n }\n\n removeAll(): void {\n this.handlers.clear();\n }\n\n /** Number of listeners for a given event — used by tests. */\n listenerCount(event: keyof EventMap<TEntitlement>): number {\n return this.handlers.get(event as string)?.size ?? 0;\n }\n}\n","import { z } from 'zod';\nimport { selectBackendAdapter } from './adapters/backend/index.js';\nimport type { BackendAdapter } from './adapters/backend/types.js';\nimport { selectStorageAdapter } from './adapters/storage/index.js';\nimport { EntitlementCache, entitlementsEqual } from './core/entitlement-cache.js';\nimport { type IAPInternalState, freezeAll, requireInitialized } from './core/iap-state.js';\nimport { ensureUniqueProductIds } from './core/iap-state.js';\nimport { initializeIap } from './core/initialize.js';\nimport { PendingPurchasesStore } from './core/pending-purchases.js';\nimport { activeNow, resetIap } from './core/reset.js';\nimport { UnfinishedTransactionsStore } from './core/unfinished-transactions.js';\nimport { TypedEventEmitter } from './events/emitter.js';\nimport { IAPError, IAPErrorCode } from './lib/errors.js';\nimport { type LogLevel, type Logger, createDefaultLogger, isLogger } from './lib/logger.js';\nimport { type IAPConfig, type IAPConfigInput, iapConfigSchema } from './types/config.js';\nimport type { EntitlementBase } from './types/entitlement.js';\nimport type { IAP } from './types/iap.js';\nimport type { ConfiguredProduct } from './types/product.js';\n\nexport type { IAP } from './types/iap.js';\n\nexport function createIAP<TEntitlement extends EntitlementBase = EntitlementBase>(\n input: IAPConfigInput<TEntitlement>,\n): IAP<TEntitlement> {\n const config = parseConfig(input);\n const logger = resolveLogger(config.options.logLevel, config.options.logger);\n const storage = selectStorageAdapter(config.storage);\n const cache = new EntitlementCache<TEntitlement>(storage, logger);\n const unfinished = new UnfinishedTransactionsStore(storage, logger);\n const pending = new PendingPurchasesStore(storage, logger);\n const backend = selectBackendAdapter<TEntitlement>({\n config,\n logger,\n getNativeAdapter: () => state.adapter,\n getProducts: () => state.products,\n getCurrentEntitlements: () => state.entitlements,\n });\n const emitter = new TypedEventEmitter<TEntitlement>();\n\n // Validate the static manifest eagerly so config typos surface synchronously.\n // The dynamic-manifest path validates inside initialize() once the backend\n // returns the response.\n if (config.products) {\n ensureUniqueProductIds(config.products);\n }\n\n const state: IAPInternalState<TEntitlement> = {\n config,\n adapter: null,\n backend,\n storage,\n cache,\n unfinished,\n pending,\n orchestrator: null,\n restorer: null,\n recoverer: null,\n updates: null,\n txWatch: null,\n resumeListener: null,\n emitter,\n logger,\n initialized: false,\n destroyed: false,\n entitlements: [],\n cachedAt: null,\n products: Object.freeze([...(config.products ?? [])]) as ConfiguredProduct[],\n };\n\n // Refresh implementation lives outside the returned object literal so\n // internal callers (the app-resume listener, the TTL microtask) can invoke\n // it directly without going through `this.refresh()` — that pattern would\n // break if a consumer destructured `initialize` from the iap object. The\n // public `refresh` method below just delegates to this function.\n async function refreshEntitlements(): Promise<void> {\n requireInitialized(state);\n const previous = state.entitlements;\n const fetched = await state.backend.getEntitlements();\n const next = freezeAll(fetched);\n\n // Persist + replace state in a single transition. If save() fails the\n // in-memory state still reflects what the backend returned (best-effort\n // cache; the next session will re-fetch on its own refresh).\n try {\n state.cachedAt = await state.cache.save(next);\n } catch (error) {\n state.logger.warn(\n 'Failed to persist refreshed entitlements; in-memory state still updated.',\n error,\n );\n }\n\n state.entitlements = next;\n // L3: skip the emit when content is unchanged.\n if (!entitlementsEqual(previous, next)) {\n state.emitter.emit('entitlements-changed', { entitlements: next, previous });\n }\n }\n\n return {\n async initialize() {\n return initializeIap(state, refreshEntitlements);\n },\n\n refresh: refreshEntitlements,\n\n async destroy() {\n if (state.destroyed) return;\n state.destroyed = true;\n state.initialized = false;\n state.entitlements = [];\n state.cachedAt = null;\n state.emitter.removeAll();\n\n if (state.resumeListener) {\n try {\n await state.resumeListener.remove();\n } catch (error) {\n state.logger.warn('Resume listener remove threw; continuing teardown.', error);\n }\n state.resumeListener = null;\n }\n\n if (state.txWatch) {\n try {\n await state.txWatch.remove();\n } catch (error) {\n state.logger.warn('Transaction listener remove threw; continuing teardown.', error);\n }\n state.txWatch = null;\n }\n\n if (state.adapter?.dispose) {\n try {\n await state.adapter.dispose();\n } catch (error) {\n state.logger.warn('Adapter dispose threw; continuing teardown.', error);\n }\n }\n state.adapter = null;\n state.orchestrator = null;\n state.restorer = null;\n state.recoverer = null;\n state.updates = null;\n },\n\n async purchase(opts) {\n requireInitialized(state);\n // orchestrator is set in initialize() alongside the native adapter,\n // so it's always present once initialized=true.\n if (!state.orchestrator) {\n throw new IAPError({\n code: IAPErrorCode.NOT_INITIALIZED,\n message: 'Purchase orchestrator not constructed; this is a library bug.',\n });\n }\n return state.orchestrator.purchase(opts);\n },\n\n async restorePurchases() {\n requireInitialized(state);\n if (!state.restorer) {\n throw new IAPError({\n code: IAPErrorCode.NOT_INITIALIZED,\n message: 'Restore orchestrator not constructed; this is a library bug.',\n });\n }\n return state.restorer.restorePurchases();\n },\n\n async getProducts() {\n requireInitialized(state);\n // requireInitialized() guarantees state.adapter is set; the explicit\n // null-check below matches the same defensive pattern used by purchase().\n if (!state.adapter) {\n throw new IAPError({\n code: IAPErrorCode.NOT_INITIALIZED,\n message: 'Native adapter not constructed; this is a library bug.',\n });\n }\n // Pass the manifest entries whole: the adapter needs `androidPlanId`\n // to pick a base plan on Android.\n return state.adapter.getProducts([...state.products]);\n },\n\n async getStorefront() {\n requireInitialized(state);\n // Adapter is guaranteed set once initialized (see getProducts()); the\n // `?.` on getStorefront covers adapters that don't implement the\n // optional method, and `?? null` keeps the contract total.\n return state.adapter?.getStorefront?.() ?? null;\n },\n\n hasEntitlement(key) {\n return activeNow(state).some((e) => e.key === key);\n },\n\n getEntitlements() {\n return activeNow(state);\n },\n\n getEntitlement(key) {\n return activeNow(state).find((e) => e.key === key) ?? null;\n },\n\n getEntitlementsVerifiedAt() {\n return state.cachedAt === null ? null : new Date(state.cachedAt).toISOString();\n },\n\n async reset() {\n return resetIap(state);\n },\n\n on(event, handler) {\n return state.emitter.on(event, handler);\n },\n };\n}\n\nfunction parseConfig(input: IAPConfigInput): IAPConfig {\n try {\n // Schema's `superRefine` has runtime-validated that the function-typed\n // fields ARE functions (or that an adapter is provided instead). The\n // overlay type on IAPConfig narrows them from `unknown` to their proper\n // contracts. Cast at this boundary, not at every use site.\n const parsed = iapConfigSchema.parse(input);\n return parsed as unknown as IAPConfig;\n } catch (error) {\n if (error instanceof z.ZodError) {\n const issues = error.issues\n .map((i) => ` - ${i.path.join('.') || '<root>'}: ${i.message}`)\n .join('\\n');\n throw new IAPError({\n code: IAPErrorCode.INVALID_CONFIG,\n message: `Invalid IAP configuration:\\n${issues}`,\n cause: error,\n });\n }\n throw error;\n }\n}\n\nfunction resolveLogger(level: LogLevel, candidate: unknown): Logger {\n if (isLogger(candidate)) return candidate;\n return createDefaultLogger(level);\n}\n","export type LogLevel = 'silent' | 'error' | 'warn' | 'info' | 'debug';\n\nexport interface Logger {\n error(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n debug(message: string, ...args: unknown[]): void;\n}\n\nconst LEVEL_PRIORITY: Record<LogLevel, number> = {\n silent: 0,\n error: 1,\n warn: 2,\n info: 3,\n debug: 4,\n};\n\nconst PREFIX = '[@nosslabs/iap]';\n\n/**\n * Default logger that writes to console at or above the configured level.\n * Consumers can pass a custom logger (Sentry, Datadog, etc.) via config.\n */\nexport function createDefaultLogger(level: LogLevel): Logger {\n const minPriority = LEVEL_PRIORITY[level];\n const enabled = (l: LogLevel) => LEVEL_PRIORITY[l] <= minPriority;\n\n return {\n error(message, ...args) {\n if (enabled('error')) console.error(PREFIX, message, ...args);\n },\n warn(message, ...args) {\n if (enabled('warn')) console.warn(PREFIX, message, ...args);\n },\n info(message, ...args) {\n if (enabled('info')) console.info(PREFIX, message, ...args);\n },\n debug(message, ...args) {\n if (enabled('debug')) console.debug(PREFIX, message, ...args);\n },\n };\n}\n\nexport function isLogger(value: unknown): value is Logger {\n if (!value || typeof value !== 'object') return false;\n const candidate = value as Partial<Logger>;\n return (\n typeof candidate.error === 'function' &&\n typeof candidate.warn === 'function' &&\n typeof candidate.info === 'function' &&\n typeof candidate.debug === 'function'\n );\n}\n","export { createIAP, type IAP } from './createIAP.js';\nexport { DEFAULT_PERMANENT_ERROR_CODES } from './core/recovery-flow.js';\nexport { IAPError, IAPErrorCode, errorHint, isIAPError } from './lib/errors.js';\nexport { VERSION } from './version.js';\n\nexport type {\n IAPConfig,\n IAPConfigInput,\n VerificationConfig,\n BackendConfig,\n BackendConfigInput,\n StorageConfig,\n OptionsConfig,\n} from './types/config.js';\n\nexport type {\n ConfiguredProduct,\n Product,\n ProductType,\n SubscriptionOffer,\n SubscriptionOfferPayment,\n SubscriptionOfferType,\n} from './types/product.js';\n\nexport type { Storefront } from './types/storefront.js';\n\nexport type {\n EntitlementBase,\n DefaultEntitlement,\n} from './types/entitlement.js';\n\nexport type {\n NativeTransaction,\n SubscriptionRenewal,\n SubscriptionState,\n VerifiedTransaction,\n Platform,\n} from './types/transaction.js';\n\nexport type {\n AppUserId,\n AppUserIdFetcherContext,\n PurchaseOptions,\n PurchaseResult,\n RestoreResult,\n StorePurchase,\n} from './types/results.js';\n\nexport type {\n EventMap,\n EventName,\n EventPayload,\n Unsubscribe,\n} from './types/events.js';\n\nexport type { Logger, LogLevel } from './lib/logger.js';\n\n// Backend layer (Phase 3) — consumers building a custom transport implement\n// BackendAdapter and pass it via config.backend.adapter. The default HTTP\n// implementation is also exported for advanced use (e.g. custom test setups).\nexport type {\n BackendAdapter,\n RestoreRequest,\n RestoreRequestTransaction,\n RestoreResponse,\n VerifyAppleRequest,\n VerifyGoogleRequest,\n VerifyResponse,\n} from './adapters/backend/types.js';\nexport { HttpBackendAdapter, HttpClient } from './adapters/backend/index.js';\n\n// On-device verification (local mode).\n//\n// `LocalVerificationAdapter` itself is deliberately NOT exported: its\n// options require a `NativeAdapter`, which is internal and which a consumer\n// has no way to obtain, so the export would be unusable. `verification:\n// { mode: 'local' }` is how you get one. These two are for a consumer who\n// would rather write their own `BackendAdapter` around the same checks.\nexport { isExpired, verifyPurchaseOnDevice } from './core/local-verification.js';\nexport type {\n LocalVerification,\n LocalVerificationError,\n LocalVerificationOptions,\n LocallyVerifiedPurchase,\n PurchaseAssurance,\n} from './core/local-verification.js';\nexport type { HttpRequest } from './adapters/backend/http-client.js';\n","/**\n * Library version, injected at build time from `package.json` (see the\n * `define` in tsup.config.ts, mirrored in vitest.config.ts).\n *\n * Exported for consumers to read — nothing inside the library consumes it. (An\n * earlier comment claimed the logger stamped it onto error reports; it never\n * did. `src/lib/logger.ts` uses a fixed `[@nosslabs/iap]` prefix.)\n */\nexport const VERSION: string = __PKG_VERSION__;\n"]}