expo-iap 6.2.0 → 6.3.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/.prettierignore +3 -1
- package/build/index.d.ts +12 -9
- package/build/index.d.ts.map +1 -1
- package/build/index.js +3 -2
- package/build/index.js.map +1 -1
- package/build/index.kepler.d.ts +6 -6
- package/build/index.kepler.d.ts.map +1 -1
- package/build/index.kepler.js +3 -2
- package/build/index.kepler.js.map +1 -1
- package/build/purchase-flow-confirmers.d.ts +99 -0
- package/build/purchase-flow-confirmers.d.ts.map +1 -0
- package/build/purchase-flow-confirmers.js +201 -0
- package/build/purchase-flow-confirmers.js.map +1 -0
- package/build/purchase-flow-core.d.ts +206 -0
- package/build/purchase-flow-core.d.ts.map +1 -0
- package/build/purchase-flow-core.js +343 -0
- package/build/purchase-flow-core.js.map +1 -0
- package/build/purchase-flow.d.ts +20 -297
- package/build/purchase-flow.d.ts.map +1 -1
- package/build/purchase-flow.js +13 -531
- package/build/purchase-flow.js.map +1 -1
- package/build/useIAP.d.ts +1 -1
- package/build/useIAP.d.ts.map +1 -1
- package/build/useIAP.js.map +1 -1
- package/build/utils/purchaseFlowBinding.d.ts +1 -1
- package/build/utils/purchaseFlowBinding.d.ts.map +1 -1
- package/build/utils/purchaseFlowBinding.js +1 -1
- package/build/utils/purchaseFlowBinding.js.map +1 -1
- package/build/vega-adapter.d.ts.map +1 -1
- package/build/vega-adapter.js +6 -5
- package/build/vega-adapter.js.map +1 -1
- package/openiap-versions.json +3 -3
- package/package.json +1 -1
- package/src/index.kepler.ts +9 -11
- package/src/index.ts +20 -19
- package/src/purchase-flow-confirmers.ts +346 -0
- package/src/purchase-flow-core.ts +604 -0
- package/src/purchase-flow.ts +43 -923
- package/src/useIAP.ts +1 -1
- package/src/utils/purchaseFlowBinding.ts +1 -1
- package/src/vega-adapter.ts +9 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.kepler.js","sourceRoot":"","sources":["../src/index.kepler.ts"],"names":[],"mappings":"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","sourcesContent":["import {getVegaIapModule} from './vega';\nimport {ErrorCode} from './types';\nimport {\n createIapkitConfirmation,\n type IapkitConfirmationOptions,\n type PurchaseConfirmation,\n type PurchaseFlow,\n type PurchaseFlowOptions,\n type PurchaseFlowPurchase,\n} from './purchase-flow';\nimport {\n clearRequested,\n createSdkPurchaseFlow,\n markRequested,\n type PurchaseFlowSdk,\n type SdkPurchaseFlowOptions,\n} from './utils/purchaseFlowBinding';\nimport type {\n MutationField,\n ProductQueryType,\n ProductRequest,\n Purchase,\n PurchaseError,\n PurchaseOptions,\n PurchaseUpdatedListenerOptions,\n QueryField,\n RequestPurchasePropsByPlatforms,\n RequestSubscriptionPropsByPlatforms,\n} from './types';\nimport {decodeAndroidPurchases} from './utils/availablePurchases';\nimport {createPurchaseError} from './utils/errorMapping';\n\nexport * from './types';\nexport * from './vega';\nexport * from './useIAP';\nexport {kitApi, KitApiError, resolveLocalizedPayload} from './kit-api';\nexport type {\n EntitlementsResponse,\n KitApiOptions,\n KitClientPayloadCache,\n KitClientPayloadOptions,\n KitClientPayloadResponse,\n KitLocalizedClientPayload,\n KitLocalizedClientPayloadOptions,\n KitLocalizedPayloadOptions,\n KitProduct,\n KitProductClientPayload,\n KitProductOffer,\n KitProductPlatform,\n KitProductsOptions,\n KitProductsResponse,\n KitSubscription,\n StatusResponse,\n} from './kit-api';\nexport {\n describePurchaseFlowStatus,\n toPurchaseConfirmationRequest,\n} from './purchase-flow';\nexport type {\n IapkitConfirmationOptions,\n PurchaseConfirmation,\n PurchaseConfirmationRequest,\n PurchaseFlow,\n PurchaseFlowGuidance,\n PurchaseFlowGuidanceKey,\n PurchaseFlowOptions,\n PurchaseFlowOutcome,\n PurchaseFlowPurchase,\n PurchaseFlowStatus,\n RecoverPurchasesOptions,\n} from './purchase-flow';\nexport type {SdkPurchaseFlowOptions} from './utils/purchaseFlowBinding';\n\nexport enum OpenIapEvent {\n PurchaseUpdated = 'purchase-updated',\n PurchaseError = 'purchase-error',\n PromotedProductIOS = 'promoted-product-ios',\n UserChoiceBillingAndroid = 'user-choice-billing-android',\n DeveloperProvidedBillingAndroid = 'developer-provided-billing-android',\n SubscriptionBillingIssue = 'subscription-billing-issue',\n}\n\nexport type ProductTypeInput = ProductQueryType;\n\nexport interface EventSubscription {\n remove(): void;\n}\n\nconst getModule = () => {\n const module = getVegaIapModule();\n if (!module) {\n throw new Error(\n 'Amazon Vega IAP module is unavailable. Install @amazon-devices/keplerscript-appstore-iap-lib in the Vega app target and build with the React Native for Vega kepler platform.',\n );\n }\n return module;\n};\n\nconst unsupported = (feature: string): never => {\n throw new Error(`${feature} is not supported on Amazon Vega.`);\n};\n\nconst normalizeProductType = (\n type?: ProductTypeInput | null,\n): ProductQueryType => {\n if (type == null || type === 'in-app') return 'in-app';\n if (type === 'subs' || type === 'all') return type;\n throw new Error(\n `Unsupported product type: ${String(type)}. Use in-app, subs, or all.`,\n );\n};\n\nconst normalizePurchaseArray = (purchases: Purchase[]): Purchase[] =>\n decodeAndroidPurchases(purchases);\n\nconst getAndroidRequest = (\n request?:\n | RequestPurchasePropsByPlatforms\n | RequestSubscriptionPropsByPlatforms\n | null,\n) => {\n return request?.google;\n};\n\nconst createPurchaseTokenError = (purchase: Purchase): Error => {\n const error = new Error(\n 'Purchase token is required to finish Amazon Vega transaction',\n ) as Error & PurchaseError;\n error.code = ErrorCode.DeveloperError;\n error.productId = purchase.productId;\n return error;\n};\n\nexport const emitter = {\n addListener(\n eventName: OpenIapEvent,\n listener: (payload: Purchase | PurchaseError) => void,\n ): EventSubscription {\n return getModule().addListener(eventName, listener);\n },\n removeListener(\n eventName: OpenIapEvent,\n listener: (payload: Purchase | PurchaseError) => void,\n ): void {\n return getModule().removeListener(eventName, listener);\n },\n};\n\nexport const purchaseUpdatedListener = (\n listener: (event: Purchase) => void,\n options?: PurchaseUpdatedListenerOptions | null,\n): EventSubscription => {\n return getModule().addListener(OpenIapEvent.PurchaseUpdated, (purchase) => {\n listener(purchase as Purchase);\n });\n};\n\nexport const purchaseErrorListener = (\n listener: (error: PurchaseError) => void,\n): EventSubscription => {\n return getModule().addListener(OpenIapEvent.PurchaseError, (error) => {\n listener(error as PurchaseError);\n });\n};\n\nexport const initConnection: MutationField<'initConnection'> = async (\n config,\n) => {\n return getModule().initConnection(config ?? null);\n};\n\nexport const endConnection: MutationField<'endConnection'> = async () => {\n return getModule().endConnection();\n};\n\nexport const fetchProducts = async (\n request: Omit<ProductRequest, 'type'> & {\n type?: ProductTypeInput | null;\n },\n): ReturnType<QueryField<'fetchProducts'>> => {\n const {skus, type} = request;\n return getModule().fetchProducts(normalizeProductType(type), skus);\n};\n\nexport const requestPurchase: MutationField<'requestPurchase'> = async (\n args,\n) => {\n markRequested(args.request.google?.skus ?? []);\n try {\n return await requestPurchaseFromStore(args);\n } catch (error) {\n clearRequested();\n throw error;\n }\n};\n\nconst requestPurchaseFromStore: MutationField<'requestPurchase'> = async (\n args,\n) => {\n const type = normalizeProductType(args.type);\n if (type === 'all') {\n throw createPurchaseError({\n code: ErrorCode.DeveloperError,\n message: 'Product type all is only supported for product queries.',\n });\n }\n const androidRequest = getAndroidRequest(args.request);\n if (!androidRequest?.skus?.length) {\n throw new Error(\n 'Invalid request for Amazon Vega. The `request.google.skus` property is required and must be a non-empty array.',\n );\n }\n\n return normalizePurchaseArray(\n await getModule().requestPurchase({\n skus: androidRequest.skus,\n type,\n }),\n );\n};\n\nexport const getAvailablePurchases: QueryField<\n 'getAvailablePurchases'\n> = async (options) => {\n return normalizePurchaseArray(\n await getModule().getAvailableItems((options ?? {}) as PurchaseOptions),\n );\n};\n\nexport const finishTransaction: MutationField<'finishTransaction'> = async ({\n purchase,\n isConsumable = false,\n}) => {\n const token = purchase.purchaseToken ?? undefined;\n if (!token) {\n throw createPurchaseTokenError(purchase);\n }\n\n if (isConsumable) {\n await getModule().consumePurchaseAndroid(token);\n return;\n }\n\n await getModule().acknowledgePurchaseAndroid(token);\n};\n\nexport const restorePurchases: MutationField<'restorePurchases'> = async () => {\n await getAvailablePurchases({\n includeSuspendedAndroid: false,\n });\n};\n\nexport const getActiveSubscriptions: QueryField<\n 'getActiveSubscriptions'\n> = async (subscriptionIds) => {\n return getModule().getActiveSubscriptions(subscriptionIds ?? null);\n};\n\nexport const hasActiveSubscriptions: QueryField<\n 'hasActiveSubscriptions'\n> = async (subscriptionIds) => {\n return getModule().hasActiveSubscriptions(subscriptionIds ?? null);\n};\n\nexport const getStorefront: QueryField<'getStorefront'> = async () => {\n return getModule().getStorefront();\n};\n\nexport const verifyPurchaseWithProvider: MutationField<\n 'verifyPurchaseWithProvider'\n> = async (options) => {\n return getModule().verifyPurchaseWithProvider(options);\n};\n\nexport const verifyPurchase: MutationField<'verifyPurchase'> = async () =>\n unsupported('verifyPurchase');\n\nexport const acknowledgePurchaseAndroid: MutationField<\n 'acknowledgePurchaseAndroid'\n> = async (purchaseToken) => {\n await getModule().acknowledgePurchaseAndroid(purchaseToken);\n return true;\n};\n\nexport const consumePurchaseAndroid: MutationField<\n 'consumePurchaseAndroid'\n> = async (purchaseToken) => {\n await getModule().consumePurchaseAndroid(purchaseToken);\n return true;\n};\n\nexport const syncIOS: MutationField<'syncIOS'> = async () =>\n unsupported('syncIOS');\nexport const verifyAppOwnership: QueryField<\n 'verifyAppOwnership'\n> = async () => ({status: 'unknown', reason: 'unsupported', storeId: 'amazon'});\n\nexport const getAppTransactionIOS: QueryField<\n 'getAppTransactionIOS'\n> = async () => null;\nexport const getPromotedProductIOS: QueryField<\n 'getPromotedProductIOS'\n> = async () => null;\n\nexport const showManageSubscriptionsIOS: MutationField<\n 'showManageSubscriptionsIOS'\n> = async () => [];\nexport const presentExternalPurchaseLinkIOS: MutationField<\n 'presentExternalPurchaseLinkIOS'\n> = async () => unsupported('presentExternalPurchaseLinkIOS');\n\nexport const deepLinkToSubscriptions: MutationField<\n 'deepLinkToSubscriptions'\n> = async () => unsupported('deepLinkToSubscriptions');\n// Vega has no offer-code redemption surface; resolve null without launching.\nexport const openRedeemOfferCode: MutationField<\n 'openRedeemOfferCode'\n> = async () => null;\n\nexport const promotedProductListenerIOS = (): EventSubscription => ({\n remove: () => {},\n});\nexport const userChoiceBillingListenerAndroid = (): EventSubscription => ({\n remove: () => {},\n});\nexport const developerProvidedBillingListenerAndroid =\n (): EventSubscription => ({\n remove: () => {},\n });\nexport const subscriptionBillingIssueListener = (): EventSubscription => ({\n remove: () => {},\n});\n\nexport const isBillingProgramAvailableAndroid: MutationField<\n 'isBillingProgramAvailableAndroid'\n> = async () => unsupported('isBillingProgramAvailableAndroid');\nexport const getBillingChoiceInfoAndroid: QueryField<\n 'getBillingChoiceInfoAndroid'\n> = async () => unsupported('getBillingChoiceInfoAndroid');\nexport const launchExternalLinkAndroid: MutationField<\n 'launchExternalLinkAndroid'\n> = async () => unsupported('launchExternalLinkAndroid');\nexport const createBillingProgramReportingDetailsAndroid: MutationField<\n 'createBillingProgramReportingDetailsAndroid'\n> = async () => unsupported('createBillingProgramReportingDetailsAndroid');\nexport const showBillingProgramInformationDialogAndroid: MutationField<\n 'showBillingProgramInformationDialogAndroid'\n> = async () => unsupported('showBillingProgramInformationDialogAndroid');\nexport const showInAppMessagesAndroid: MutationField<\n 'showInAppMessagesAndroid'\n> = async () => unsupported('showInAppMessagesAndroid');\n\nconst purchaseFlowSdk: PurchaseFlowSdk = {\n finishTransaction: (args) => finishTransaction(args),\n getAvailablePurchases: () => getAvailablePurchases(),\n getPendingTransactionsIOS: undefined,\n purchaseUpdatedListener: (listener) => purchaseUpdatedListener(listener),\n purchaseErrorListener: (listener) => purchaseErrorListener(listener),\n};\n\n/**\n * Creates the app's purchase flow on Amazon Vega. Create one per signed-in\n * account, dispose it when the account changes, and pass it to\n * `useIAP({purchaseFlow})`.\n * @see {@link https://kit.openiap.dev/docs/purchase-flow}\n */\nexport function createPurchaseFlow(\n options: SdkPurchaseFlowOptions,\n): PurchaseFlow<Purchase>;\nexport function createPurchaseFlow<P extends PurchaseFlowPurchase>(\n options: PurchaseFlowOptions<P>,\n): PurchaseFlow<P>;\nexport function createPurchaseFlow(\n options: SdkPurchaseFlowOptions,\n): PurchaseFlow<Purchase> {\n return createSdkPurchaseFlow(purchaseFlowSdk, options);\n}\n\n/**\n * Confirms purchases with IAPKit from the app, for apps without a backend:\n * pass it as `confirmWithBackend` with a publishable key. Credit consumables\n * in `grant`, which runs before the purchase is consumed.\n */\nexport function confirmWithIapkit(\n options: IapkitConfirmationOptions<Purchase>,\n): (\n purchase: Purchase,\n context: {isConsumable: boolean},\n) => Promise<PurchaseConfirmation> {\n return createIapkitConfirmation(verifyPurchaseWithProvider, options);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.kepler.js","sourceRoot":"","sources":["../src/index.kepler.ts"],"names":[],"mappings":"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","sourcesContent":["import {getVegaIapModule} from './vega';\nimport {ErrorCode} from './types';\nimport {\n type PurchaseFlow,\n type PurchaseFlowOptions,\n type PurchaseFlowPurchase,\n} from './purchase-flow-core';\nimport {\n createIapkitConfirmation,\n type IapkitConfirmationOptions,\n} from './purchase-flow-confirmers';\nimport {\n clearRequested,\n createSdkPurchaseFlow,\n markRequested,\n type PurchaseFlowSdk,\n type SdkPurchaseFlowOptions,\n} from './utils/purchaseFlowBinding';\nimport type {\n MutationField,\n ProductQueryType,\n ProductRequest,\n Purchase,\n PurchaseError,\n PurchaseOptions,\n PurchaseUpdatedListenerOptions,\n QueryField,\n RequestPurchasePropsByPlatforms,\n RequestSubscriptionPropsByPlatforms,\n} from './types';\nimport {decodeAndroidPurchases} from './utils/availablePurchases';\nimport {createPurchaseError} from './utils/errorMapping';\n\nexport * from './types';\nexport * from './vega';\nexport * from './useIAP';\nexport {kitApi, KitApiError, resolveLocalizedPayload} from './kit-api';\nexport type {\n EntitlementsResponse,\n KitApiOptions,\n KitClientPayloadCache,\n KitClientPayloadOptions,\n KitClientPayloadResponse,\n KitLocalizedClientPayload,\n KitLocalizedClientPayloadOptions,\n KitLocalizedPayloadOptions,\n KitProduct,\n KitProductClientPayload,\n KitProductOffer,\n KitProductPlatform,\n KitProductsOptions,\n KitProductsResponse,\n KitSubscription,\n StatusResponse,\n} from './kit-api';\nexport {\n describePurchaseFlowStatus,\n toPurchaseConfirmationRequest,\n} from './purchase-flow-core';\nexport type {\n PurchaseConfirmation,\n PurchaseConfirmationRequest,\n PurchaseFlow,\n PurchaseFlowGuidance,\n PurchaseFlowGuidanceKey,\n PurchaseFlowOptions,\n PurchaseFlowOutcome,\n PurchaseFlowPurchase,\n PurchaseFlowStatus,\n RecoverPurchasesOptions,\n} from './purchase-flow-core';\nexport type {IapkitConfirmationOptions} from './purchase-flow-confirmers';\nexport type {SdkPurchaseFlowOptions} from './utils/purchaseFlowBinding';\n\nexport enum OpenIapEvent {\n PurchaseUpdated = 'purchase-updated',\n PurchaseError = 'purchase-error',\n PromotedProductIOS = 'promoted-product-ios',\n UserChoiceBillingAndroid = 'user-choice-billing-android',\n DeveloperProvidedBillingAndroid = 'developer-provided-billing-android',\n SubscriptionBillingIssue = 'subscription-billing-issue',\n}\n\nexport type ProductTypeInput = ProductQueryType;\n\nexport interface EventSubscription {\n remove(): void;\n}\n\nconst getModule = () => {\n const module = getVegaIapModule();\n if (!module) {\n throw new Error(\n 'Amazon Vega IAP module is unavailable. Install @amazon-devices/keplerscript-appstore-iap-lib in the Vega app target and build with the React Native for Vega kepler platform.',\n );\n }\n return module;\n};\n\nconst unsupported = (feature: string): never => {\n throw new Error(`${feature} is not supported on Amazon Vega.`);\n};\n\nconst normalizeProductType = (\n type?: ProductTypeInput | null,\n): ProductQueryType => {\n if (type == null || type === 'in-app') return 'in-app';\n if (type === 'subs' || type === 'all') return type;\n throw new Error(\n `Unsupported product type: ${String(type)}. Use in-app, subs, or all.`,\n );\n};\n\nconst normalizePurchaseArray = (purchases: Purchase[]): Purchase[] =>\n decodeAndroidPurchases(purchases);\n\nconst getAndroidRequest = (\n request?:\n | RequestPurchasePropsByPlatforms\n | RequestSubscriptionPropsByPlatforms\n | null,\n) => {\n return request?.google;\n};\n\nconst createPurchaseTokenError = (purchase: Purchase): Error => {\n const error = new Error(\n 'Purchase token is required to finish Amazon Vega transaction',\n ) as Error & PurchaseError;\n error.code = ErrorCode.DeveloperError;\n error.productId = purchase.productId;\n return error;\n};\n\nexport const emitter = {\n addListener(\n eventName: OpenIapEvent,\n listener: (payload: Purchase | PurchaseError) => void,\n ): EventSubscription {\n return getModule().addListener(eventName, listener);\n },\n removeListener(\n eventName: OpenIapEvent,\n listener: (payload: Purchase | PurchaseError) => void,\n ): void {\n return getModule().removeListener(eventName, listener);\n },\n};\n\nexport const purchaseUpdatedListener = (\n listener: (event: Purchase) => void,\n options?: PurchaseUpdatedListenerOptions | null,\n): EventSubscription => {\n return getModule().addListener(OpenIapEvent.PurchaseUpdated, (purchase) => {\n listener(purchase as Purchase);\n });\n};\n\nexport const purchaseErrorListener = (\n listener: (error: PurchaseError) => void,\n): EventSubscription => {\n return getModule().addListener(OpenIapEvent.PurchaseError, (error) => {\n listener(error as PurchaseError);\n });\n};\n\nexport const initConnection: MutationField<'initConnection'> = async (\n config,\n) => {\n return getModule().initConnection(config ?? null);\n};\n\nexport const endConnection: MutationField<'endConnection'> = async () => {\n return getModule().endConnection();\n};\n\nexport const fetchProducts = async (\n request: Omit<ProductRequest, 'type'> & {\n type?: ProductTypeInput | null;\n },\n): ReturnType<QueryField<'fetchProducts'>> => {\n const {skus, type} = request;\n return getModule().fetchProducts(normalizeProductType(type), skus);\n};\n\nexport const requestPurchase: MutationField<'requestPurchase'> = async (\n args,\n) => {\n markRequested(args.request.google?.skus ?? []);\n try {\n return await requestPurchaseFromStore(args);\n } catch (error) {\n clearRequested();\n throw error;\n }\n};\n\nconst requestPurchaseFromStore: MutationField<'requestPurchase'> = async (\n args,\n) => {\n const type = normalizeProductType(args.type);\n if (type === 'all') {\n throw createPurchaseError({\n code: ErrorCode.DeveloperError,\n message: 'Product type all is only supported for product queries.',\n });\n }\n const androidRequest = getAndroidRequest(args.request);\n if (!androidRequest?.skus?.length) {\n throw new Error(\n 'Invalid request for Amazon Vega. The `request.google.skus` property is required and must be a non-empty array.',\n );\n }\n\n return normalizePurchaseArray(\n await getModule().requestPurchase({\n skus: androidRequest.skus,\n type,\n }),\n );\n};\n\nexport const getAvailablePurchases: QueryField<\n 'getAvailablePurchases'\n> = async (options) => {\n return normalizePurchaseArray(\n await getModule().getAvailableItems((options ?? {}) as PurchaseOptions),\n );\n};\n\nexport const finishTransaction: MutationField<'finishTransaction'> = async ({\n purchase,\n isConsumable = false,\n}) => {\n const token = purchase.purchaseToken ?? undefined;\n if (!token) {\n throw createPurchaseTokenError(purchase);\n }\n\n if (isConsumable) {\n await getModule().consumePurchaseAndroid(token);\n return;\n }\n\n await getModule().acknowledgePurchaseAndroid(token);\n};\n\nexport const restorePurchases: MutationField<'restorePurchases'> = async () => {\n await getAvailablePurchases({\n includeSuspendedAndroid: false,\n });\n};\n\nexport const getActiveSubscriptions: QueryField<\n 'getActiveSubscriptions'\n> = async (subscriptionIds) => {\n return getModule().getActiveSubscriptions(subscriptionIds ?? null);\n};\n\nexport const hasActiveSubscriptions: QueryField<\n 'hasActiveSubscriptions'\n> = async (subscriptionIds) => {\n return getModule().hasActiveSubscriptions(subscriptionIds ?? null);\n};\n\nexport const getStorefront: QueryField<'getStorefront'> = async () => {\n return getModule().getStorefront();\n};\n\nexport const verifyPurchaseWithProvider: MutationField<\n 'verifyPurchaseWithProvider'\n> = async (options) => {\n return getModule().verifyPurchaseWithProvider(options);\n};\n\nexport const verifyPurchase: MutationField<'verifyPurchase'> = async () =>\n unsupported('verifyPurchase');\n\nexport const acknowledgePurchaseAndroid: MutationField<\n 'acknowledgePurchaseAndroid'\n> = async (purchaseToken) => {\n await getModule().acknowledgePurchaseAndroid(purchaseToken);\n return true;\n};\n\nexport const consumePurchaseAndroid: MutationField<\n 'consumePurchaseAndroid'\n> = async (purchaseToken) => {\n await getModule().consumePurchaseAndroid(purchaseToken);\n return true;\n};\n\nexport const syncIOS: MutationField<'syncIOS'> = async () =>\n unsupported('syncIOS');\nexport const verifyAppOwnership: QueryField<\n 'verifyAppOwnership'\n> = async () => ({status: 'unknown', reason: 'unsupported', storeId: 'amazon'});\n\nexport const getAppTransactionIOS: QueryField<\n 'getAppTransactionIOS'\n> = async () => null;\nexport const getPromotedProductIOS: QueryField<\n 'getPromotedProductIOS'\n> = async () => null;\n\nexport const showManageSubscriptionsIOS: MutationField<\n 'showManageSubscriptionsIOS'\n> = async () => [];\nexport const presentExternalPurchaseLinkIOS: MutationField<\n 'presentExternalPurchaseLinkIOS'\n> = async () => unsupported('presentExternalPurchaseLinkIOS');\n\nexport const deepLinkToSubscriptions: MutationField<\n 'deepLinkToSubscriptions'\n> = async () => unsupported('deepLinkToSubscriptions');\n// Vega has no offer-code redemption surface; resolve null without launching.\nexport const openRedeemOfferCode: MutationField<\n 'openRedeemOfferCode'\n> = async () => null;\n\nexport const promotedProductListenerIOS = (): EventSubscription => ({\n remove: () => {},\n});\nexport const userChoiceBillingListenerAndroid = (): EventSubscription => ({\n remove: () => {},\n});\nexport const developerProvidedBillingListenerAndroid =\n (): EventSubscription => ({\n remove: () => {},\n });\nexport const subscriptionBillingIssueListener = (): EventSubscription => ({\n remove: () => {},\n});\n\nexport const isBillingProgramAvailableAndroid: MutationField<\n 'isBillingProgramAvailableAndroid'\n> = async () => unsupported('isBillingProgramAvailableAndroid');\nexport const getBillingChoiceInfoAndroid: QueryField<\n 'getBillingChoiceInfoAndroid'\n> = async () => unsupported('getBillingChoiceInfoAndroid');\nexport const launchExternalLinkAndroid: MutationField<\n 'launchExternalLinkAndroid'\n> = async () => unsupported('launchExternalLinkAndroid');\nexport const createBillingProgramReportingDetailsAndroid: MutationField<\n 'createBillingProgramReportingDetailsAndroid'\n> = async () => unsupported('createBillingProgramReportingDetailsAndroid');\nexport const showBillingProgramInformationDialogAndroid: MutationField<\n 'showBillingProgramInformationDialogAndroid'\n> = async () => unsupported('showBillingProgramInformationDialogAndroid');\nexport const showInAppMessagesAndroid: MutationField<\n 'showInAppMessagesAndroid'\n> = async () => unsupported('showInAppMessagesAndroid');\n\nconst purchaseFlowSdk: PurchaseFlowSdk = {\n finishTransaction: (args) => finishTransaction(args),\n getAvailablePurchases: () => getAvailablePurchases(),\n getPendingTransactionsIOS: undefined,\n purchaseUpdatedListener: (listener) => purchaseUpdatedListener(listener),\n purchaseErrorListener: (listener) => purchaseErrorListener(listener),\n};\n\n/**\n * Creates the app's purchase flow on Amazon Vega. Create one per signed-in\n * account, dispose it when the account changes, and pass it to\n * `useIAP({purchaseFlow})`.\n * @see {@link https://kit.openiap.dev/docs/purchase-flow}\n */\nexport function createPurchaseFlow(\n options: SdkPurchaseFlowOptions,\n): PurchaseFlow<Purchase>;\nexport function createPurchaseFlow<P extends PurchaseFlowPurchase>(\n options: PurchaseFlowOptions<P>,\n): PurchaseFlow<P>;\nexport function createPurchaseFlow(\n options: SdkPurchaseFlowOptions,\n): PurchaseFlow<Purchase> {\n return createSdkPurchaseFlow(purchaseFlowSdk, options);\n}\n\n/**\n * Confirms purchases with IAPKit from the app, for apps without a backend:\n * pass it as `confirmWithBackend` with a publishable key. Credit consumables\n * in `grant`, which runs before the purchase is consumed.\n */\nexport function confirmWithIapkit(\n options: IapkitConfirmationOptions<Purchase>,\n): PurchaseFlowOptions<Purchase>['confirmWithBackend'] {\n return createIapkitConfirmation(verifyPurchaseWithProvider, options);\n}\n"]}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import type { PurchaseConfirmation, PurchaseFlowOptions, PurchaseFlowPurchase } from "./purchase-flow-core";
|
|
2
|
+
type IapkitStore = "apple" | "google" | "amazon" | "horizon";
|
|
3
|
+
/** How an app without its own backend confirms purchases with IAPKit. */
|
|
4
|
+
export interface IapkitConfirmationOptions<P extends PurchaseFlowPurchase = PurchaseFlowPurchase> {
|
|
5
|
+
/**
|
|
6
|
+
* A publishable key (`openiap-kit_pk_...`), which is safe to ship in an
|
|
7
|
+
* app. Leave it out where the SDK has one configured, such as Expo's
|
|
8
|
+
* `iapkitApiKey`.
|
|
9
|
+
*/
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
/** A self-hosted or local IAPKit origin. Defaults to https://kit.openiap.dev. */
|
|
12
|
+
baseUrl?: string;
|
|
13
|
+
amazon?: {
|
|
14
|
+
/** Verify App Tester receipts with the Amazon RVS Cloud Sandbox. */
|
|
15
|
+
sandbox?: boolean;
|
|
16
|
+
/** RVS reports a subscription term under its parent SKU; maps one to the other. */
|
|
17
|
+
verifiedProductId?: (productId: string) => string;
|
|
18
|
+
};
|
|
19
|
+
/** The IAPKit store that verifies a community store's evidence, such as an Amazon RVS adapter. */
|
|
20
|
+
verifyAs?: (purchase: P) => IapkitStore | undefined;
|
|
21
|
+
/** Credits consumables before finishing; must be idempotent per purchase.id. */
|
|
22
|
+
grant?: (purchase: P, context: {
|
|
23
|
+
isConsumable: boolean;
|
|
24
|
+
}) => Promise<void>;
|
|
25
|
+
}
|
|
26
|
+
/** @internal Use the SDK's VerifyPurchaseWithProviderProps. */
|
|
27
|
+
export interface IapkitVerificationProps {
|
|
28
|
+
provider: "iapkit";
|
|
29
|
+
iapkit: {
|
|
30
|
+
apiKey?: string;
|
|
31
|
+
baseUrl?: string;
|
|
32
|
+
apple?: {
|
|
33
|
+
jws: string;
|
|
34
|
+
};
|
|
35
|
+
google?: {
|
|
36
|
+
purchaseToken: string;
|
|
37
|
+
};
|
|
38
|
+
amazon?: {
|
|
39
|
+
receiptId: string;
|
|
40
|
+
expectedProductId: string;
|
|
41
|
+
sandbox: boolean;
|
|
42
|
+
userId?: string;
|
|
43
|
+
};
|
|
44
|
+
horizon?: {
|
|
45
|
+
sku: string;
|
|
46
|
+
};
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/** @internal Use the SDK's VerifyPurchaseWithProviderResult. */
|
|
50
|
+
export interface IapkitVerificationResult {
|
|
51
|
+
iapkit?: {
|
|
52
|
+
store: string;
|
|
53
|
+
storeId: string;
|
|
54
|
+
environment?: string | null;
|
|
55
|
+
isValid: boolean;
|
|
56
|
+
state: string;
|
|
57
|
+
productId?: string | null;
|
|
58
|
+
} | null;
|
|
59
|
+
errors?: {
|
|
60
|
+
code?: string | null;
|
|
61
|
+
message: string;
|
|
62
|
+
}[] | null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* @internal Use the SDK's confirmWithIapkit.
|
|
66
|
+
* The SDK's `confirmWithIapkit`, given its `verifyPurchaseWithProvider`:
|
|
67
|
+
* verifies the purchase with IAPKit, then runs `grant` before the flow
|
|
68
|
+
* finishes it.
|
|
69
|
+
*/
|
|
70
|
+
export declare function createIapkitConfirmation<P extends PurchaseFlowPurchase>(verifyPurchaseWithProvider: (props: IapkitVerificationProps) => Promise<IapkitVerificationResult>, options: IapkitConfirmationOptions<P>): PurchaseFlowOptions<P>["confirmWithBackend"];
|
|
71
|
+
/**
|
|
72
|
+
* @internal Use the SDK's confirmOnDeviceIOS.
|
|
73
|
+
* The SDK's `confirmOnDeviceIOS`, given its `getPendingTransactionsIOS`, for an
|
|
74
|
+
* app with neither a backend nor IAPKit. StoreKit verified the transaction if
|
|
75
|
+
* it is still unfinished, unrevoked, not upgraded, unexpired, and from the
|
|
76
|
+
* purchase's environment; `grant` then runs before the flow finishes it.
|
|
77
|
+
*/
|
|
78
|
+
export declare function createDeviceConfirmationIOS<P extends PurchaseFlowPurchase>(getPendingTransactionsIOS: () => Promise<P[]>, options?: {
|
|
79
|
+
/** Required for consumables; credit each purchase.id only once. */
|
|
80
|
+
grant?: (purchase: P, context: {
|
|
81
|
+
isConsumable: boolean;
|
|
82
|
+
}) => Promise<void>;
|
|
83
|
+
}): PurchaseFlowOptions<P>["confirmWithBackend"];
|
|
84
|
+
/** @internal Builds the IAPKit request; throws for a store IAPKit cannot verify. */
|
|
85
|
+
export declare function toIapkitVerificationProps<P extends PurchaseFlowPurchase>(purchase: P, options: IapkitConfirmationOptions<P>): IapkitVerificationProps;
|
|
86
|
+
/**
|
|
87
|
+
* @internal Use the SDK's confirmWithIapkit.
|
|
88
|
+
* Turns IAPKit's answer into the flow's confirmation. Anything that may be a
|
|
89
|
+
* configuration error rather than a rejected payment throws, so the flow
|
|
90
|
+
* reports `failed` and leaves the purchase unfinished: evidence for another
|
|
91
|
+
* store, product, or environment, `inauthentic` (IAPKit's answer to a product
|
|
92
|
+
* or package mismatch, and to every Horizon rejection), and a valid state this
|
|
93
|
+
* product type cannot be granted from.
|
|
94
|
+
*/
|
|
95
|
+
export declare function readIapkitVerification<P extends PurchaseFlowPurchase>(result: IapkitVerificationResult, purchase: P, context: {
|
|
96
|
+
isConsumable: boolean;
|
|
97
|
+
}, options?: Omit<IapkitConfirmationOptions<P>, "apiKey">): PurchaseConfirmation;
|
|
98
|
+
export {};
|
|
99
|
+
//# sourceMappingURL=purchase-flow-confirmers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purchase-flow-confirmers.d.ts","sourceRoot":"","sources":["../src/purchase-flow-confirmers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
const IAPKIT_UNKNOWN_RETRY_MS = 30_000;
|
|
2
|
+
/**
|
|
3
|
+
* @internal Use the SDK's confirmWithIapkit.
|
|
4
|
+
* The SDK's `confirmWithIapkit`, given its `verifyPurchaseWithProvider`:
|
|
5
|
+
* verifies the purchase with IAPKit, then runs `grant` before the flow
|
|
6
|
+
* finishes it.
|
|
7
|
+
*/
|
|
8
|
+
export function createIapkitConfirmation(verifyPurchaseWithProvider, options) {
|
|
9
|
+
return async (purchase, context) => {
|
|
10
|
+
requireGrant("confirmWithIapkit", purchase, context, options);
|
|
11
|
+
const confirmation = readIapkitVerification(await verifyPurchaseWithProvider(toIapkitVerificationProps(purchase, options)), purchase, context, options);
|
|
12
|
+
if (confirmation.status === "entitled" && !confirmation.alreadyGranted) {
|
|
13
|
+
await options.grant?.(purchase, context);
|
|
14
|
+
}
|
|
15
|
+
return confirmation;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* @internal Use the SDK's confirmOnDeviceIOS.
|
|
20
|
+
* The SDK's `confirmOnDeviceIOS`, given its `getPendingTransactionsIOS`, for an
|
|
21
|
+
* app with neither a backend nor IAPKit. StoreKit verified the transaction if
|
|
22
|
+
* it is still unfinished, unrevoked, not upgraded, unexpired, and from the
|
|
23
|
+
* purchase's environment; `grant` then runs before the flow finishes it.
|
|
24
|
+
*/
|
|
25
|
+
export function createDeviceConfirmationIOS(getPendingTransactionsIOS, options = {}) {
|
|
26
|
+
return async (purchase, context) => {
|
|
27
|
+
requireGrant("confirmOnDeviceIOS", purchase, context, options);
|
|
28
|
+
// A community provider may report store "apple" under its own storeId.
|
|
29
|
+
if (purchase.store !== "apple" ||
|
|
30
|
+
(purchase.storeId ?? "apple") !== "apple") {
|
|
31
|
+
throw new Error(`Device confirmation covers App Store purchases, not ${purchase.storeId ?? purchase.store}`);
|
|
32
|
+
}
|
|
33
|
+
const pending = await getPendingTransactionsIOS();
|
|
34
|
+
// After the query: a transaction can expire while StoreKit answers.
|
|
35
|
+
const now = Date.now();
|
|
36
|
+
const verified = pending.some((candidate) => candidate.store === "apple" &&
|
|
37
|
+
purchase.id !== "" &&
|
|
38
|
+
candidate.id === purchase.id &&
|
|
39
|
+
candidate.productId === purchase.productId &&
|
|
40
|
+
candidate.revocationDateIOS == null &&
|
|
41
|
+
candidate.isUpgradedIOS !== true &&
|
|
42
|
+
(candidate.expirationDateIOS == null ||
|
|
43
|
+
candidate.expirationDateIOS > now) &&
|
|
44
|
+
(purchase.environmentIOS == null ||
|
|
45
|
+
candidate.environmentIOS === purchase.environmentIOS));
|
|
46
|
+
if (!verified) {
|
|
47
|
+
throw new Error(`StoreKit lists no valid unfinished transaction for ${purchase.productId}`);
|
|
48
|
+
}
|
|
49
|
+
await options.grant?.(purchase, context);
|
|
50
|
+
return { status: "entitled", alreadyGranted: false };
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// Checked before verifying: a consumable must never pass without a way to credit it.
|
|
54
|
+
function requireGrant(name, purchase, context, options) {
|
|
55
|
+
if (context.isConsumable && !options.grant) {
|
|
56
|
+
throw new Error(`${name} needs grant to credit consumable ${purchase.productId} before it is consumed`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/** @internal Builds the IAPKit request; throws for a store IAPKit cannot verify. */
|
|
60
|
+
export function toIapkitVerificationProps(purchase, options) {
|
|
61
|
+
const apiKey = options.apiKey?.trim();
|
|
62
|
+
// An unset environment variable, not a deliberate fallback to the SDK's key.
|
|
63
|
+
if (apiKey === "")
|
|
64
|
+
throw new Error("IAPKit apiKey is empty");
|
|
65
|
+
const baseUrl = options.baseUrl?.trim();
|
|
66
|
+
const base = {
|
|
67
|
+
...(apiKey ? { apiKey } : {}),
|
|
68
|
+
...(baseUrl ? { baseUrl } : {}),
|
|
69
|
+
};
|
|
70
|
+
const token = () => {
|
|
71
|
+
if (!purchase.purchaseToken) {
|
|
72
|
+
throw new Error(`Purchase ${purchase.productId} has no purchase token to verify`);
|
|
73
|
+
}
|
|
74
|
+
return purchase.purchaseToken;
|
|
75
|
+
};
|
|
76
|
+
const store = verifyingStore(purchase, options);
|
|
77
|
+
switch (store) {
|
|
78
|
+
case "apple":
|
|
79
|
+
return {
|
|
80
|
+
provider: "iapkit",
|
|
81
|
+
iapkit: { ...base, apple: { jws: token() } },
|
|
82
|
+
};
|
|
83
|
+
case "google":
|
|
84
|
+
return {
|
|
85
|
+
provider: "iapkit",
|
|
86
|
+
iapkit: { ...base, google: { purchaseToken: token() } },
|
|
87
|
+
};
|
|
88
|
+
case "amazon":
|
|
89
|
+
return {
|
|
90
|
+
provider: "iapkit",
|
|
91
|
+
iapkit: {
|
|
92
|
+
...base,
|
|
93
|
+
amazon: {
|
|
94
|
+
receiptId: token(),
|
|
95
|
+
expectedProductId: amazonProductId(purchase, options),
|
|
96
|
+
sandbox: options.amazon?.sandbox ?? false,
|
|
97
|
+
...(purchase.userIdAmazon ? { userId: purchase.userIdAmazon } : {}),
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
case "horizon":
|
|
102
|
+
return {
|
|
103
|
+
provider: "iapkit",
|
|
104
|
+
iapkit: { ...base, horizon: { sku: purchase.productId } },
|
|
105
|
+
};
|
|
106
|
+
default:
|
|
107
|
+
throw new Error(`IAPKit cannot verify store ${purchase.store}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* @internal Use the SDK's confirmWithIapkit.
|
|
112
|
+
* Turns IAPKit's answer into the flow's confirmation. Anything that may be a
|
|
113
|
+
* configuration error rather than a rejected payment throws, so the flow
|
|
114
|
+
* reports `failed` and leaves the purchase unfinished: evidence for another
|
|
115
|
+
* store, product, or environment, `inauthentic` (IAPKit's answer to a product
|
|
116
|
+
* or package mismatch, and to every Horizon rejection), and a valid state this
|
|
117
|
+
* product type cannot be granted from.
|
|
118
|
+
*/
|
|
119
|
+
export function readIapkitVerification(result, purchase, context, options = {}) {
|
|
120
|
+
const verified = result.iapkit;
|
|
121
|
+
if (!verified) {
|
|
122
|
+
const errors = (result.errors ?? []).map((error) => error.code ? `[${error.code}] ${error.message}` : error.message);
|
|
123
|
+
throw new Error(errors.join("\n") || "IAPKit returned no verification result");
|
|
124
|
+
}
|
|
125
|
+
switch (verified.state) {
|
|
126
|
+
case "pending":
|
|
127
|
+
return { status: "store_pending" };
|
|
128
|
+
// The store gave no usable answer: retry instead of rejecting a payment.
|
|
129
|
+
case "unknown":
|
|
130
|
+
return {
|
|
131
|
+
status: "verification_delayed",
|
|
132
|
+
retryAfterMs: IAPKIT_UNKNOWN_RETRY_MS,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const store = verifyingStore(purchase, options);
|
|
136
|
+
const expectedProductId = store === "amazon"
|
|
137
|
+
? amazonProductId(purchase, options)
|
|
138
|
+
: purchase.productId;
|
|
139
|
+
const mismatch = verified.store !== purchase.store
|
|
140
|
+
? `store ${verified.store}, expected ${purchase.store}`
|
|
141
|
+
: purchase.storeId && verified.storeId !== purchase.storeId
|
|
142
|
+
? `store id ${verified.storeId}, expected ${purchase.storeId}`
|
|
143
|
+
: verified.productId !== expectedProductId
|
|
144
|
+
? `product ${verified.productId ?? "(none)"}, expected ${expectedProductId}`
|
|
145
|
+
: environmentMismatch(verified.environment, store, purchase, options);
|
|
146
|
+
if (mismatch)
|
|
147
|
+
throw new Error(`IAPKit verified ${mismatch}`);
|
|
148
|
+
if (!verified.isValid) {
|
|
149
|
+
switch (verified.state) {
|
|
150
|
+
case "canceled":
|
|
151
|
+
case "expired":
|
|
152
|
+
return { status: "invalid", reason: verified.state };
|
|
153
|
+
// Only a granted purchase is consumed; the flow grants before finishing.
|
|
154
|
+
case "consumed":
|
|
155
|
+
return { status: "entitled", alreadyGranted: true };
|
|
156
|
+
default:
|
|
157
|
+
throw new Error(`IAPKit rejected the purchase: ${verified.state}`);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
if (!grantsAccess(store, verified.state, context.isConsumable)) {
|
|
161
|
+
throw new Error(`IAPKit state ${verified.state} cannot grant this ${context.isConsumable ? "consumable" : "non-consumable"} ${purchase.store} purchase`);
|
|
162
|
+
}
|
|
163
|
+
return { status: "entitled", alreadyGranted: false };
|
|
164
|
+
}
|
|
165
|
+
function verifyingStore(purchase, options) {
|
|
166
|
+
return options.verifyAs?.(purchase) ?? purchase.store;
|
|
167
|
+
}
|
|
168
|
+
function amazonProductId(purchase, options) {
|
|
169
|
+
return (options.amazon?.verifiedProductId?.(purchase.productId) ??
|
|
170
|
+
purchase.productId);
|
|
171
|
+
}
|
|
172
|
+
function environmentMismatch(environment, store, purchase, options) {
|
|
173
|
+
const expected = store === "amazon"
|
|
174
|
+
? options.amazon?.sandbox
|
|
175
|
+
? "Sandbox"
|
|
176
|
+
: "Production"
|
|
177
|
+
: store === "apple"
|
|
178
|
+
? purchase.environmentIOS
|
|
179
|
+
: null;
|
|
180
|
+
return expected && environment !== expected
|
|
181
|
+
? `environment ${environment ?? "(none)"}, expected ${expected}`
|
|
182
|
+
: null;
|
|
183
|
+
}
|
|
184
|
+
// Apple and Amazon keep a consumable at ready-to-consume until it is finished;
|
|
185
|
+
// Google reports a granted purchase as pending-acknowledgment until then.
|
|
186
|
+
function grantsAccess(store, state, isConsumable) {
|
|
187
|
+
switch (store) {
|
|
188
|
+
case "apple":
|
|
189
|
+
case "amazon":
|
|
190
|
+
return state === (isConsumable ? "ready-to-consume" : "entitled");
|
|
191
|
+
case "google":
|
|
192
|
+
return (state === "entitled" ||
|
|
193
|
+
state === "pending-acknowledgment" ||
|
|
194
|
+
(isConsumable && state === "ready-to-consume"));
|
|
195
|
+
case "horizon":
|
|
196
|
+
return state === "entitled";
|
|
197
|
+
default:
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=purchase-flow-confirmers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"purchase-flow-confirmers.js","sourceRoot":"","sources":["../src/purchase-flow-confirmers.ts"],"names":[],"mappings":"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","sourcesContent":["// Internal adapters for SDK confirmation helpers; apps use SDK root imports.\n// Each adapter uses the same lifecycle contract as other verification services.\nimport type {\n PurchaseConfirmation,\n PurchaseFlowOptions,\n PurchaseFlowPurchase,\n} from \"./purchase-flow-core\";\n\ntype IapkitStore = \"apple\" | \"google\" | \"amazon\" | \"horizon\";\n\n/** How an app without its own backend confirms purchases with IAPKit. */\nexport interface IapkitConfirmationOptions<\n P extends PurchaseFlowPurchase = PurchaseFlowPurchase,\n> {\n /**\n * A publishable key (`openiap-kit_pk_...`), which is safe to ship in an\n * app. Leave it out where the SDK has one configured, such as Expo's\n * `iapkitApiKey`.\n */\n apiKey?: string;\n /** A self-hosted or local IAPKit origin. Defaults to https://kit.openiap.dev. */\n baseUrl?: string;\n amazon?: {\n /** Verify App Tester receipts with the Amazon RVS Cloud Sandbox. */\n sandbox?: boolean;\n /** RVS reports a subscription term under its parent SKU; maps one to the other. */\n verifiedProductId?: (productId: string) => string;\n };\n /** The IAPKit store that verifies a community store's evidence, such as an Amazon RVS adapter. */\n verifyAs?: (purchase: P) => IapkitStore | undefined;\n /** Credits consumables before finishing; must be idempotent per purchase.id. */\n grant?: (purchase: P, context: { isConsumable: boolean }) => Promise<void>;\n}\n\n/** @internal Use the SDK's VerifyPurchaseWithProviderProps. */\nexport interface IapkitVerificationProps {\n provider: \"iapkit\";\n iapkit: {\n apiKey?: string;\n baseUrl?: string;\n apple?: { jws: string };\n google?: { purchaseToken: string };\n amazon?: {\n receiptId: string;\n expectedProductId: string;\n sandbox: boolean;\n userId?: string;\n };\n horizon?: { sku: string };\n };\n}\n\n/** @internal Use the SDK's VerifyPurchaseWithProviderResult. */\nexport interface IapkitVerificationResult {\n iapkit?: {\n store: string;\n storeId: string;\n environment?: string | null;\n isValid: boolean;\n state: string;\n productId?: string | null;\n } | null;\n errors?: { code?: string | null; message: string }[] | null;\n}\n\nconst IAPKIT_UNKNOWN_RETRY_MS = 30_000;\n\n/**\n * @internal Use the SDK's confirmWithIapkit.\n * The SDK's `confirmWithIapkit`, given its `verifyPurchaseWithProvider`:\n * verifies the purchase with IAPKit, then runs `grant` before the flow\n * finishes it.\n */\nexport function createIapkitConfirmation<P extends PurchaseFlowPurchase>(\n verifyPurchaseWithProvider: (\n props: IapkitVerificationProps,\n ) => Promise<IapkitVerificationResult>,\n options: IapkitConfirmationOptions<P>,\n): PurchaseFlowOptions<P>[\"confirmWithBackend\"] {\n return async (purchase, context) => {\n requireGrant(\"confirmWithIapkit\", purchase, context, options);\n const confirmation = readIapkitVerification(\n await verifyPurchaseWithProvider(\n toIapkitVerificationProps(purchase, options),\n ),\n purchase,\n context,\n options,\n );\n if (confirmation.status === \"entitled\" && !confirmation.alreadyGranted) {\n await options.grant?.(purchase, context);\n }\n return confirmation;\n };\n}\n\n/**\n * @internal Use the SDK's confirmOnDeviceIOS.\n * The SDK's `confirmOnDeviceIOS`, given its `getPendingTransactionsIOS`, for an\n * app with neither a backend nor IAPKit. StoreKit verified the transaction if\n * it is still unfinished, unrevoked, not upgraded, unexpired, and from the\n * purchase's environment; `grant` then runs before the flow finishes it.\n */\nexport function createDeviceConfirmationIOS<P extends PurchaseFlowPurchase>(\n getPendingTransactionsIOS: () => Promise<P[]>,\n options: {\n /** Required for consumables; credit each purchase.id only once. */\n grant?: (purchase: P, context: { isConsumable: boolean }) => Promise<void>;\n } = {},\n): PurchaseFlowOptions<P>[\"confirmWithBackend\"] {\n return async (purchase, context) => {\n requireGrant(\"confirmOnDeviceIOS\", purchase, context, options);\n // A community provider may report store \"apple\" under its own storeId.\n if (\n purchase.store !== \"apple\" ||\n (purchase.storeId ?? \"apple\") !== \"apple\"\n ) {\n throw new Error(\n `Device confirmation covers App Store purchases, not ${purchase.storeId ?? purchase.store}`,\n );\n }\n const pending = await getPendingTransactionsIOS();\n // After the query: a transaction can expire while StoreKit answers.\n const now = Date.now();\n const verified = pending.some(\n (candidate) =>\n candidate.store === \"apple\" &&\n purchase.id !== \"\" &&\n candidate.id === purchase.id &&\n candidate.productId === purchase.productId &&\n candidate.revocationDateIOS == null &&\n candidate.isUpgradedIOS !== true &&\n (candidate.expirationDateIOS == null ||\n candidate.expirationDateIOS > now) &&\n (purchase.environmentIOS == null ||\n candidate.environmentIOS === purchase.environmentIOS),\n );\n if (!verified) {\n throw new Error(\n `StoreKit lists no valid unfinished transaction for ${purchase.productId}`,\n );\n }\n await options.grant?.(purchase, context);\n return { status: \"entitled\", alreadyGranted: false };\n };\n}\n\n// Checked before verifying: a consumable must never pass without a way to credit it.\nfunction requireGrant<P extends PurchaseFlowPurchase>(\n name: string,\n purchase: P,\n context: { isConsumable: boolean },\n options: Pick<IapkitConfirmationOptions<P>, \"grant\">,\n): void {\n if (context.isConsumable && !options.grant) {\n throw new Error(\n `${name} needs grant to credit consumable ${purchase.productId} before it is consumed`,\n );\n }\n}\n\n/** @internal Builds the IAPKit request; throws for a store IAPKit cannot verify. */\nexport function toIapkitVerificationProps<P extends PurchaseFlowPurchase>(\n purchase: P,\n options: IapkitConfirmationOptions<P>,\n): IapkitVerificationProps {\n const apiKey = options.apiKey?.trim();\n // An unset environment variable, not a deliberate fallback to the SDK's key.\n if (apiKey === \"\") throw new Error(\"IAPKit apiKey is empty\");\n const baseUrl = options.baseUrl?.trim();\n const base = {\n ...(apiKey ? { apiKey } : {}),\n ...(baseUrl ? { baseUrl } : {}),\n };\n const token = (): string => {\n if (!purchase.purchaseToken) {\n throw new Error(\n `Purchase ${purchase.productId} has no purchase token to verify`,\n );\n }\n return purchase.purchaseToken;\n };\n const store = verifyingStore(purchase, options);\n switch (store) {\n case \"apple\":\n return {\n provider: \"iapkit\",\n iapkit: { ...base, apple: { jws: token() } },\n };\n case \"google\":\n return {\n provider: \"iapkit\",\n iapkit: { ...base, google: { purchaseToken: token() } },\n };\n case \"amazon\":\n return {\n provider: \"iapkit\",\n iapkit: {\n ...base,\n amazon: {\n receiptId: token(),\n expectedProductId: amazonProductId(purchase, options),\n sandbox: options.amazon?.sandbox ?? false,\n ...(purchase.userIdAmazon ? { userId: purchase.userIdAmazon } : {}),\n },\n },\n };\n case \"horizon\":\n return {\n provider: \"iapkit\",\n iapkit: { ...base, horizon: { sku: purchase.productId } },\n };\n default:\n throw new Error(`IAPKit cannot verify store ${purchase.store}`);\n }\n}\n\n/**\n * @internal Use the SDK's confirmWithIapkit.\n * Turns IAPKit's answer into the flow's confirmation. Anything that may be a\n * configuration error rather than a rejected payment throws, so the flow\n * reports `failed` and leaves the purchase unfinished: evidence for another\n * store, product, or environment, `inauthentic` (IAPKit's answer to a product\n * or package mismatch, and to every Horizon rejection), and a valid state this\n * product type cannot be granted from.\n */\nexport function readIapkitVerification<P extends PurchaseFlowPurchase>(\n result: IapkitVerificationResult,\n purchase: P,\n context: { isConsumable: boolean },\n options: Omit<IapkitConfirmationOptions<P>, \"apiKey\"> = {},\n): PurchaseConfirmation {\n const verified = result.iapkit;\n if (!verified) {\n const errors = (result.errors ?? []).map((error) =>\n error.code ? `[${error.code}] ${error.message}` : error.message,\n );\n throw new Error(\n errors.join(\"\\n\") || \"IAPKit returned no verification result\",\n );\n }\n switch (verified.state) {\n case \"pending\":\n return { status: \"store_pending\" };\n // The store gave no usable answer: retry instead of rejecting a payment.\n case \"unknown\":\n return {\n status: \"verification_delayed\",\n retryAfterMs: IAPKIT_UNKNOWN_RETRY_MS,\n };\n }\n const store = verifyingStore(purchase, options);\n const expectedProductId =\n store === \"amazon\"\n ? amazonProductId(purchase, options)\n : purchase.productId;\n const mismatch =\n verified.store !== purchase.store\n ? `store ${verified.store}, expected ${purchase.store}`\n : purchase.storeId && verified.storeId !== purchase.storeId\n ? `store id ${verified.storeId}, expected ${purchase.storeId}`\n : verified.productId !== expectedProductId\n ? `product ${verified.productId ?? \"(none)\"}, expected ${expectedProductId}`\n : environmentMismatch(verified.environment, store, purchase, options);\n if (mismatch) throw new Error(`IAPKit verified ${mismatch}`);\n if (!verified.isValid) {\n switch (verified.state) {\n case \"canceled\":\n case \"expired\":\n return { status: \"invalid\", reason: verified.state };\n // Only a granted purchase is consumed; the flow grants before finishing.\n case \"consumed\":\n return { status: \"entitled\", alreadyGranted: true };\n default:\n throw new Error(`IAPKit rejected the purchase: ${verified.state}`);\n }\n }\n if (!grantsAccess(store, verified.state, context.isConsumable)) {\n throw new Error(\n `IAPKit state ${verified.state} cannot grant this ${\n context.isConsumable ? \"consumable\" : \"non-consumable\"\n } ${purchase.store} purchase`,\n );\n }\n return { status: \"entitled\", alreadyGranted: false };\n}\n\nfunction verifyingStore<P extends PurchaseFlowPurchase>(\n purchase: P,\n options: Pick<IapkitConfirmationOptions<P>, \"verifyAs\">,\n): string {\n return options.verifyAs?.(purchase) ?? purchase.store;\n}\n\nfunction amazonProductId(\n purchase: PurchaseFlowPurchase,\n options: Pick<IapkitConfirmationOptions, \"amazon\">,\n): string {\n return (\n options.amazon?.verifiedProductId?.(purchase.productId) ??\n purchase.productId\n );\n}\n\nfunction environmentMismatch(\n environment: string | null | undefined,\n store: string,\n purchase: PurchaseFlowPurchase,\n options: Pick<IapkitConfirmationOptions, \"amazon\">,\n): string | null {\n const expected =\n store === \"amazon\"\n ? options.amazon?.sandbox\n ? \"Sandbox\"\n : \"Production\"\n : store === \"apple\"\n ? purchase.environmentIOS\n : null;\n return expected && environment !== expected\n ? `environment ${environment ?? \"(none)\"}, expected ${expected}`\n : null;\n}\n\n// Apple and Amazon keep a consumable at ready-to-consume until it is finished;\n// Google reports a granted purchase as pending-acknowledgment until then.\nfunction grantsAccess(\n store: string,\n state: string,\n isConsumable: boolean,\n): boolean {\n switch (store) {\n case \"apple\":\n case \"amazon\":\n return state === (isConsumable ? \"ready-to-consume\" : \"entitled\");\n case \"google\":\n return (\n state === \"entitled\" ||\n state === \"pending-acknowledgment\" ||\n (isConsumable && state === \"ready-to-consume\")\n );\n case \"horizon\":\n return state === \"entitled\";\n default:\n return false;\n }\n}\n"]}
|