@nosslabs/iap 7.0.0-next.0 → 7.1.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.
- package/CHANGELOG.md +89 -0
- package/README.md +4 -4
- package/dist/index.cjs +330 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -8
- package/dist/index.d.ts +53 -8
- package/dist/index.js +330 -21
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/errors.ts","../src/lib/platform.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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","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\nexport interface 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 {\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 { getPlatform } from '../../../lib/platform.js';\nimport type { Product, ProductType } from '../../../types/product.js';\nimport type { NativeTransaction, Platform } from '../../../types/transaction.js';\nimport type { NativeAdapter, NativePurchaseOptions } from '../types.js';\n\n/**\n * Capacitor 7+ adapter built against `@capgo/native-purchases@7.16.2`\n * (also runs on Capacitor 8). Captured plugin surface:\n * `docs/internal/plugin-v7-api.md`.\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 on both platforms.\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 it to\n // the backend's /restore would only get rejected. Mirrors the cdv\n // adapter's `state === 'approved'` filter.\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 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 async dispose(): Promise<void> {\n // No-op: this adapter owns no long-lived listeners or timers.\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 only\n * signals available:\n * - iOS: `\"User cancelled\"`, `\"Transaction pending\"`, `\"Product not found\"`.\n * - Android: `\"Purchase is pending\"`, `\"Product not found\"`. Note Android does\n * NOT distinguish user-cancel from other billing errors — both surface as\n * `\"Purchase is not purchased\"`, which falls through to `STORE_ERROR`.\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 if (lower.includes('product not found')) {\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@^7.16`\n * (also runs on Capacitor 8), loaded via dynamic import so web builds\n * don't pull the plugin's ESM in (and don't pay its native-registration\n * side effects on page load).\n * - web → no-op stub (purchases reject with PLATFORM_NOT_SUPPORTED).\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 { 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","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';\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 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 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 this.refresh();\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 this.refresh().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 async refresh() {\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 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 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 {\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 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. Updated by the publish workflow to match `package.json`.\n * Read at runtime by the logger so error reports include the version.\n */\nexport const VERSION = '0.1.0';\n"]}
|
|
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 7 adapter for the `@capgo/native-purchases` 7.16.x line (this is\n * the `7.x` line of `@nosslabs/iap`; Capacitor 8 support lands in v8). Captured\n * plugin surface: `docs/internal/plugin-v7-api.md`.\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` (^7.16.2,\n * the Capacitor 7 line), loaded via dynamic import so web builds don't pull\n * the plugin's ESM in (and don't pay its native-registration side effects on\n * page load).\n * - web → no-op stub (purchases reject with PLATFORM_NOT_SUPPORTED).\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. Updated by the publish workflow to match `package.json`.\n * Read at runtime by the logger so error reports include the version.\n */\nexport const VERSION = '0.1.0';\n"]}
|