expo-iap 3.1.38 → 3.3.0-rc.1
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 +1 -0
- package/android/src/main/java/expo/modules/iap/ExpoIapModule.kt +124 -0
- package/build/index.d.ts +15 -6
- package/build/index.d.ts.map +1 -1
- package/build/index.js +30 -17
- package/build/index.js.map +1 -1
- package/build/modules/android.d.ts +53 -1
- package/build/modules/android.d.ts.map +1 -1
- package/build/modules/android.js +61 -0
- package/build/modules/android.js.map +1 -1
- package/build/types.d.ts +255 -11
- package/build/types.d.ts.map +1 -1
- package/build/types.js.map +1 -1
- package/build/useIAP.d.ts.map +1 -1
- package/build/useIAP.js +2 -0
- package/build/useIAP.js.map +1 -1
- package/coverage/clover.xml +147 -139
- package/coverage/coverage-final.json +5 -5
- package/coverage/lcov-report/block-navigation.js +1 -1
- package/coverage/lcov-report/index.html +23 -23
- package/coverage/lcov-report/sorter.js +7 -21
- package/coverage/lcov-report/src/ExpoIap.types.ts.html +1396 -0
- package/coverage/lcov-report/src/helpers/index.html +116 -0
- package/coverage/lcov-report/src/helpers/subscription.ts.html +499 -0
- package/coverage/lcov-report/src/index.html +14 -14
- package/coverage/lcov-report/src/index.ts.html +64 -25
- package/coverage/lcov-report/src/modules/android.ts.html +233 -8
- package/coverage/lcov-report/src/modules/index.html +15 -15
- package/coverage/lcov-report/src/modules/ios.ts.html +1 -1
- package/coverage/lcov-report/src/onside/ExpoOnsideMarketplaceAvailabilityModule.ts.html +145 -0
- package/coverage/lcov-report/src/onside/index.html +131 -0
- package/coverage/lcov-report/src/onside/index.ts.html +253 -0
- package/coverage/lcov-report/src/types/ExpoIapAndroid.types.ts.html +502 -0
- package/coverage/lcov-report/src/types/index.html +116 -0
- package/coverage/lcov-report/src/useIAP.ts.html +1654 -0
- package/coverage/lcov-report/src/utils/constants.ts.html +127 -0
- package/coverage/lcov-report/src/utils/debug.ts.html +1 -1
- package/coverage/lcov-report/src/utils/errorMapping.ts.html +1 -1
- package/coverage/lcov-report/src/utils/index.html +1 -1
- package/coverage/lcov.info +249 -232
- package/ios/expoiap.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
- package/ios/expoiap.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- package/openiap-versions.json +3 -3
- package/package.json +1 -1
- package/plugin/tsconfig.tsbuildinfo +1 -1
- package/src/index.ts +30 -17
- package/src/modules/android.ts +75 -0
- package/src/types.ts +273 -12
- package/src/useIAP.ts +2 -0
package/build/modules/android.js
CHANGED
|
@@ -183,4 +183,65 @@ export const showAlternativeBillingDialogAndroid = async () => {
|
|
|
183
183
|
export const createAlternativeBillingTokenAndroid = async (sku) => {
|
|
184
184
|
return ExpoIapModule.createAlternativeBillingTokenAndroid(sku);
|
|
185
185
|
};
|
|
186
|
+
// ============================================================================
|
|
187
|
+
// Billing Programs API (Google Play Billing Library 8.2.0+)
|
|
188
|
+
// ============================================================================
|
|
189
|
+
/**
|
|
190
|
+
* Check if a specific billing program is available for this user/device (Android only).
|
|
191
|
+
* Available in Google Play Billing Library 8.2.0+.
|
|
192
|
+
*
|
|
193
|
+
* @param program - The billing program to check ('external-offer' or 'external-content-link')
|
|
194
|
+
* @returns Promise resolving to availability result
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```typescript
|
|
198
|
+
* const result = await isBillingProgramAvailableAndroid('external-offer');
|
|
199
|
+
* if (result.isAvailable) {
|
|
200
|
+
* // Proceed with billing program flow
|
|
201
|
+
* }
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
export const isBillingProgramAvailableAndroid = async (program) => {
|
|
205
|
+
return ExpoIapModule.isBillingProgramAvailableAndroid(program);
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* Launch an external link for the specified billing program (Android only).
|
|
209
|
+
* Available in Google Play Billing Library 8.2.0+.
|
|
210
|
+
*
|
|
211
|
+
* @param params - The external link parameters
|
|
212
|
+
* @returns Promise resolving when the link is launched
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* ```typescript
|
|
216
|
+
* await launchExternalLinkAndroid({
|
|
217
|
+
* billingProgram: 'external-offer',
|
|
218
|
+
* launchMode: 'launch-in-external-browser-or-app',
|
|
219
|
+
* linkType: 'link-to-digital-content-offer',
|
|
220
|
+
* linkUri: 'https://your-payment-site.com',
|
|
221
|
+
* });
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
export const launchExternalLinkAndroid = async (params) => {
|
|
225
|
+
return ExpoIapModule.launchExternalLinkAndroid(params);
|
|
226
|
+
};
|
|
227
|
+
/**
|
|
228
|
+
* Create billing program reporting details for Google Play reporting (Android only).
|
|
229
|
+
* Available in Google Play Billing Library 8.2.0+.
|
|
230
|
+
*
|
|
231
|
+
* Must be called AFTER successful payment in your payment system.
|
|
232
|
+
* Token must be reported to Google Play backend within 24 hours.
|
|
233
|
+
*
|
|
234
|
+
* @param program - The billing program type
|
|
235
|
+
* @returns Promise resolving to reporting details including the external transaction token
|
|
236
|
+
*
|
|
237
|
+
* @example
|
|
238
|
+
* ```typescript
|
|
239
|
+
* const details = await createBillingProgramReportingDetailsAndroid('external-offer');
|
|
240
|
+
* // Report details.externalTransactionToken to Google Play within 24 hours
|
|
241
|
+
* await reportToGooglePlay(details.externalTransactionToken);
|
|
242
|
+
* ```
|
|
243
|
+
*/
|
|
244
|
+
export const createBillingProgramReportingDetailsAndroid = async (program) => {
|
|
245
|
+
return ExpoIapModule.createBillingProgramReportingDetailsAndroid(program);
|
|
246
|
+
};
|
|
186
247
|
//# sourceMappingURL=android.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"android.js","sourceRoot":"","sources":["../../src/modules/android.ts"],"names":[],"mappings":"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","sourcesContent":["// External dependencies\nimport {Linking} from 'react-native';\n\n// Internal modules\nimport ExpoIapModule from '../ExpoIapModule';\n\n// Types\nimport type {\n DeepLinkOptions,\n MutationField,\n VerifyPurchaseResultAndroid,\n} from '../types';\n\ntype NativeAndroidModule = {\n deepLinkToSubscriptionsAndroid?: (params: {\n skuAndroid?: string;\n packageNameAndroid?: string;\n }) => Promise<void> | void;\n getStorefront?: () => Promise<string> | string;\n};\n\nconst nativeAndroidModule = ExpoIapModule as NativeAndroidModule;\n\n// Type guards\nexport function isProductAndroid<T extends {platform?: string}>(\n item: unknown,\n): item is T & {platform: 'android'} {\n return (\n item != null &&\n typeof item === 'object' &&\n 'platform' in item &&\n typeof (item as any).platform === 'string' &&\n (item as any).platform.toLowerCase() === 'android'\n );\n}\n\n/**\n * Deep link to subscriptions screen on Android.\n * @param {Object} params - The parameters object\n * @param {string} params.skuAndroid - The product's SKU (on Android)\n * @param {string} params.packageNameAndroid - The package name of your Android app (e.g., 'com.example.app')\n * @returns {Promise<void>}\n *\n * @example\n * ```typescript\n * await deepLinkToSubscriptionsAndroid({\n * skuAndroid: 'subscription_id',\n * packageNameAndroid: 'com.example.app'\n * });\n * ```\n */\nexport const deepLinkToSubscriptionsAndroid = async (\n options?: DeepLinkOptions | null,\n): Promise<void> => {\n const sku = options?.skuAndroid ?? undefined;\n const packageName = options?.packageNameAndroid ?? undefined;\n\n // Prefer native deep link implementation via OpenIAP module\n if (nativeAndroidModule?.deepLinkToSubscriptionsAndroid) {\n return nativeAndroidModule.deepLinkToSubscriptionsAndroid({\n skuAndroid: sku,\n packageNameAndroid: packageName,\n });\n }\n\n // Fallback to Linking if native method unavailable\n if (!packageName) {\n throw new Error(\n 'packageName is required for deepLinkToSubscriptionsAndroid',\n );\n }\n const base = `https://play.google.com/store/account/subscriptions?package=${encodeURIComponent(\n packageName,\n )}`;\n const url = sku ? `${base}&sku=${encodeURIComponent(sku)}` : base;\n return Linking.openURL(url);\n};\n\n/**\n * Validate receipt for Android. NOTE: This method is here for debugging purposes only. Including\n * your access token in the binary you ship to users is potentially dangerous.\n * Use server side validation instead for your production builds\n *\n * @deprecated Use verifyPurchase instead\n * @param {Object} params - The parameters object\n * @param {string} params.packageName - package name of your app.\n * @param {string} params.productId - product id for your in app product.\n * @param {string} params.productToken - token for your purchase (called 'token' in the API documentation).\n * @param {string} params.accessToken - OAuth access token with androidpublisher scope. Required for authentication.\n * @param {boolean} params.isSub - whether this is subscription or in-app. `true` for subscription.\n * @returns {Promise<ReceiptAndroid>}\n */\nexport const validateReceiptAndroid = async ({\n packageName,\n productId,\n productToken,\n accessToken,\n isSub,\n}: {\n packageName: string;\n productId: string;\n productToken: string;\n accessToken: string;\n isSub?: boolean;\n}): Promise<VerifyPurchaseResultAndroid> => {\n const type = isSub ? 'subscriptions' : 'products';\n\n const url =\n 'https://androidpublisher.googleapis.com/androidpublisher/v3/applications' +\n `/${packageName}/purchases/${type}/${productId}` +\n `/tokens/${productToken}`;\n\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!response.ok) {\n throw Object.assign(new Error(response.statusText), {\n statusCode: response.status,\n });\n }\n\n return response.json();\n};\n\n/**\n * Acknowledge a product (on Android.) No-op on iOS.\n * @param {Object} params - The parameters object\n * @param {string} params.token - The product's token (on Android)\n * @returns {Promise<VoidResult | void>}\n */\nexport const acknowledgePurchaseAndroid: MutationField<\n 'acknowledgePurchaseAndroid'\n> = async (purchaseToken) => {\n const result = await ExpoIapModule.acknowledgePurchaseAndroid(purchaseToken);\n\n if (typeof result === 'boolean') {\n return result;\n }\n\n if (result && typeof result === 'object') {\n const record = result as Record<string, unknown>;\n if (typeof record.success === 'boolean') {\n return record.success;\n }\n if (typeof record.responseCode === 'number') {\n return record.responseCode === 0;\n }\n }\n\n return true;\n};\n\n/**\n * Open the Google Play Store to redeem offer codes (Android only).\n * Note: Google Play does not provide a direct API to redeem codes within the app.\n * This function opens the Play Store where users can manually enter their codes.\n *\n * @returns {Promise<void>}\n */\nexport const openRedeemOfferCodeAndroid = async (): Promise<void> => {\n return Linking.openURL(`https://play.google.com/redeem?code=`);\n};\n\n/**\n * Check if alternative billing is available for this user/device (Android only).\n * Step 1 of alternative billing flow.\n *\n * Returns true if available, false otherwise.\n * Throws OpenIapError.NotPrepared if billing client not ready.\n *\n * @returns {Promise<boolean>}\n *\n * @example\n * ```typescript\n * const isAvailable = await checkAlternativeBillingAvailabilityAndroid();\n * if (isAvailable) {\n * // Proceed with alternative billing flow\n * }\n * ```\n */\nexport const checkAlternativeBillingAvailabilityAndroid: MutationField<\n 'checkAlternativeBillingAvailabilityAndroid'\n> = async () => {\n return ExpoIapModule.checkAlternativeBillingAvailabilityAndroid();\n};\n\n/**\n * Show alternative billing information dialog to user (Android only).\n * Step 2 of alternative billing flow.\n * Must be called BEFORE processing payment in your payment system.\n *\n * Returns true if user accepted, false if user canceled.\n * Throws OpenIapError.NotPrepared if billing client not ready.\n *\n * @returns {Promise<boolean>}\n *\n * @example\n * ```typescript\n * const userAccepted = await showAlternativeBillingDialogAndroid();\n * if (userAccepted) {\n * // Process payment in your payment system\n * const success = await processCustomPayment();\n * if (success) {\n * // Create reporting token\n * const token = await createAlternativeBillingTokenAndroid();\n * // Send token to your backend for Google Play reporting\n * }\n * }\n * ```\n */\nexport const showAlternativeBillingDialogAndroid: MutationField<\n 'showAlternativeBillingDialogAndroid'\n> = async () => {\n return ExpoIapModule.showAlternativeBillingDialogAndroid();\n};\n\n/**\n * Create external transaction token for Google Play reporting (Android only).\n * Step 3 of alternative billing flow.\n * Must be called AFTER successful payment in your payment system.\n * Token must be reported to Google Play backend within 24 hours.\n *\n * Returns token string, or null if creation failed.\n * Throws OpenIapError.NotPrepared if billing client not ready.\n *\n * @param {string} sku - The product SKU that was purchased\n * @returns {Promise<string | null>}\n *\n * @example\n * ```typescript\n * const token = await createAlternativeBillingTokenAndroid('premium_subscription');\n * if (token) {\n * // Send token to your backend\n * await fetch('/api/report-transaction', {\n * method: 'POST',\n * body: JSON.stringify({ token, sku: 'premium_subscription' })\n * });\n * }\n * ```\n */\nexport const createAlternativeBillingTokenAndroid: MutationField<\n 'createAlternativeBillingTokenAndroid'\n> = async (sku?: string) => {\n return ExpoIapModule.createAlternativeBillingTokenAndroid(sku);\n};\n"]}
|
|
1
|
+
{"version":3,"file":"android.js","sourceRoot":"","sources":["../../src/modules/android.ts"],"names":[],"mappings":"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","sourcesContent":["// External dependencies\nimport {Linking} from 'react-native';\n\n// Internal modules\nimport ExpoIapModule from '../ExpoIapModule';\n\n// Types\nimport type {\n BillingProgramAndroid,\n BillingProgramAvailabilityResultAndroid,\n BillingProgramReportingDetailsAndroid,\n DeepLinkOptions,\n LaunchExternalLinkParamsAndroid,\n MutationField,\n VerifyPurchaseResultAndroid,\n} from '../types';\n\ntype NativeAndroidModule = {\n deepLinkToSubscriptionsAndroid?: (params: {\n skuAndroid?: string;\n packageNameAndroid?: string;\n }) => Promise<void> | void;\n getStorefront?: () => Promise<string> | string;\n};\n\nconst nativeAndroidModule = ExpoIapModule as NativeAndroidModule;\n\n// Type guards\nexport function isProductAndroid<T extends {platform?: string}>(\n item: unknown,\n): item is T & {platform: 'android'} {\n return (\n item != null &&\n typeof item === 'object' &&\n 'platform' in item &&\n typeof (item as any).platform === 'string' &&\n (item as any).platform.toLowerCase() === 'android'\n );\n}\n\n/**\n * Deep link to subscriptions screen on Android.\n * @param {Object} params - The parameters object\n * @param {string} params.skuAndroid - The product's SKU (on Android)\n * @param {string} params.packageNameAndroid - The package name of your Android app (e.g., 'com.example.app')\n * @returns {Promise<void>}\n *\n * @example\n * ```typescript\n * await deepLinkToSubscriptionsAndroid({\n * skuAndroid: 'subscription_id',\n * packageNameAndroid: 'com.example.app'\n * });\n * ```\n */\nexport const deepLinkToSubscriptionsAndroid = async (\n options?: DeepLinkOptions | null,\n): Promise<void> => {\n const sku = options?.skuAndroid ?? undefined;\n const packageName = options?.packageNameAndroid ?? undefined;\n\n // Prefer native deep link implementation via OpenIAP module\n if (nativeAndroidModule?.deepLinkToSubscriptionsAndroid) {\n return nativeAndroidModule.deepLinkToSubscriptionsAndroid({\n skuAndroid: sku,\n packageNameAndroid: packageName,\n });\n }\n\n // Fallback to Linking if native method unavailable\n if (!packageName) {\n throw new Error(\n 'packageName is required for deepLinkToSubscriptionsAndroid',\n );\n }\n const base = `https://play.google.com/store/account/subscriptions?package=${encodeURIComponent(\n packageName,\n )}`;\n const url = sku ? `${base}&sku=${encodeURIComponent(sku)}` : base;\n return Linking.openURL(url);\n};\n\n/**\n * Validate receipt for Android. NOTE: This method is here for debugging purposes only. Including\n * your access token in the binary you ship to users is potentially dangerous.\n * Use server side validation instead for your production builds\n *\n * @deprecated Use verifyPurchase instead\n * @param {Object} params - The parameters object\n * @param {string} params.packageName - package name of your app.\n * @param {string} params.productId - product id for your in app product.\n * @param {string} params.productToken - token for your purchase (called 'token' in the API documentation).\n * @param {string} params.accessToken - OAuth access token with androidpublisher scope. Required for authentication.\n * @param {boolean} params.isSub - whether this is subscription or in-app. `true` for subscription.\n * @returns {Promise<ReceiptAndroid>}\n */\nexport const validateReceiptAndroid = async ({\n packageName,\n productId,\n productToken,\n accessToken,\n isSub,\n}: {\n packageName: string;\n productId: string;\n productToken: string;\n accessToken: string;\n isSub?: boolean;\n}): Promise<VerifyPurchaseResultAndroid> => {\n const type = isSub ? 'subscriptions' : 'products';\n\n const url =\n 'https://androidpublisher.googleapis.com/androidpublisher/v3/applications' +\n `/${packageName}/purchases/${type}/${productId}` +\n `/tokens/${productToken}`;\n\n const response = await fetch(url, {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n },\n });\n\n if (!response.ok) {\n throw Object.assign(new Error(response.statusText), {\n statusCode: response.status,\n });\n }\n\n return response.json();\n};\n\n/**\n * Acknowledge a product (on Android.) No-op on iOS.\n * @param {Object} params - The parameters object\n * @param {string} params.token - The product's token (on Android)\n * @returns {Promise<VoidResult | void>}\n */\nexport const acknowledgePurchaseAndroid: MutationField<\n 'acknowledgePurchaseAndroid'\n> = async (purchaseToken) => {\n const result = await ExpoIapModule.acknowledgePurchaseAndroid(purchaseToken);\n\n if (typeof result === 'boolean') {\n return result;\n }\n\n if (result && typeof result === 'object') {\n const record = result as Record<string, unknown>;\n if (typeof record.success === 'boolean') {\n return record.success;\n }\n if (typeof record.responseCode === 'number') {\n return record.responseCode === 0;\n }\n }\n\n return true;\n};\n\n/**\n * Open the Google Play Store to redeem offer codes (Android only).\n * Note: Google Play does not provide a direct API to redeem codes within the app.\n * This function opens the Play Store where users can manually enter their codes.\n *\n * @returns {Promise<void>}\n */\nexport const openRedeemOfferCodeAndroid = async (): Promise<void> => {\n return Linking.openURL(`https://play.google.com/redeem?code=`);\n};\n\n/**\n * Check if alternative billing is available for this user/device (Android only).\n * Step 1 of alternative billing flow.\n *\n * Returns true if available, false otherwise.\n * Throws OpenIapError.NotPrepared if billing client not ready.\n *\n * @returns {Promise<boolean>}\n *\n * @example\n * ```typescript\n * const isAvailable = await checkAlternativeBillingAvailabilityAndroid();\n * if (isAvailable) {\n * // Proceed with alternative billing flow\n * }\n * ```\n */\nexport const checkAlternativeBillingAvailabilityAndroid: MutationField<\n 'checkAlternativeBillingAvailabilityAndroid'\n> = async () => {\n return ExpoIapModule.checkAlternativeBillingAvailabilityAndroid();\n};\n\n/**\n * Show alternative billing information dialog to user (Android only).\n * Step 2 of alternative billing flow.\n * Must be called BEFORE processing payment in your payment system.\n *\n * Returns true if user accepted, false if user canceled.\n * Throws OpenIapError.NotPrepared if billing client not ready.\n *\n * @returns {Promise<boolean>}\n *\n * @example\n * ```typescript\n * const userAccepted = await showAlternativeBillingDialogAndroid();\n * if (userAccepted) {\n * // Process payment in your payment system\n * const success = await processCustomPayment();\n * if (success) {\n * // Create reporting token\n * const token = await createAlternativeBillingTokenAndroid();\n * // Send token to your backend for Google Play reporting\n * }\n * }\n * ```\n */\nexport const showAlternativeBillingDialogAndroid: MutationField<\n 'showAlternativeBillingDialogAndroid'\n> = async () => {\n return ExpoIapModule.showAlternativeBillingDialogAndroid();\n};\n\n/**\n * Create external transaction token for Google Play reporting (Android only).\n * Step 3 of alternative billing flow.\n * Must be called AFTER successful payment in your payment system.\n * Token must be reported to Google Play backend within 24 hours.\n *\n * Returns token string, or null if creation failed.\n * Throws OpenIapError.NotPrepared if billing client not ready.\n *\n * @param {string} sku - The product SKU that was purchased\n * @returns {Promise<string | null>}\n *\n * @example\n * ```typescript\n * const token = await createAlternativeBillingTokenAndroid('premium_subscription');\n * if (token) {\n * // Send token to your backend\n * await fetch('/api/report-transaction', {\n * method: 'POST',\n * body: JSON.stringify({ token, sku: 'premium_subscription' })\n * });\n * }\n * ```\n */\nexport const createAlternativeBillingTokenAndroid: MutationField<\n 'createAlternativeBillingTokenAndroid'\n> = async (sku?: string) => {\n return ExpoIapModule.createAlternativeBillingTokenAndroid(sku);\n};\n\n// ============================================================================\n// Billing Programs API (Google Play Billing Library 8.2.0+)\n// ============================================================================\n\n/**\n * Check if a specific billing program is available for this user/device (Android only).\n * Available in Google Play Billing Library 8.2.0+.\n *\n * @param program - The billing program to check ('external-offer' or 'external-content-link')\n * @returns Promise resolving to availability result\n *\n * @example\n * ```typescript\n * const result = await isBillingProgramAvailableAndroid('external-offer');\n * if (result.isAvailable) {\n * // Proceed with billing program flow\n * }\n * ```\n */\nexport const isBillingProgramAvailableAndroid = async (\n program: BillingProgramAndroid,\n): Promise<BillingProgramAvailabilityResultAndroid> => {\n return ExpoIapModule.isBillingProgramAvailableAndroid(program);\n};\n\n/**\n * Launch an external link for the specified billing program (Android only).\n * Available in Google Play Billing Library 8.2.0+.\n *\n * @param params - The external link parameters\n * @returns Promise resolving when the link is launched\n *\n * @example\n * ```typescript\n * await launchExternalLinkAndroid({\n * billingProgram: 'external-offer',\n * launchMode: 'launch-in-external-browser-or-app',\n * linkType: 'link-to-digital-content-offer',\n * linkUri: 'https://your-payment-site.com',\n * });\n * ```\n */\nexport const launchExternalLinkAndroid = async (\n params: LaunchExternalLinkParamsAndroid,\n): Promise<void> => {\n return ExpoIapModule.launchExternalLinkAndroid(params);\n};\n\n/**\n * Create billing program reporting details for Google Play reporting (Android only).\n * Available in Google Play Billing Library 8.2.0+.\n *\n * Must be called AFTER successful payment in your payment system.\n * Token must be reported to Google Play backend within 24 hours.\n *\n * @param program - The billing program type\n * @returns Promise resolving to reporting details including the external transaction token\n *\n * @example\n * ```typescript\n * const details = await createBillingProgramReportingDetailsAndroid('external-offer');\n * // Report details.externalTransactionToken to Google Play within 24 hours\n * await reportToGooglePlay(details.externalTransactionToken);\n * ```\n */\nexport const createBillingProgramReportingDetailsAndroid = async (\n program: BillingProgramAndroid,\n): Promise<BillingProgramReportingDetailsAndroid> => {\n return ExpoIapModule.createBillingProgramReportingDetailsAndroid(program);\n};\n"]}
|
package/build/types.d.ts
CHANGED
|
@@ -56,12 +56,67 @@ export interface AppTransaction {
|
|
|
56
56
|
preorderDate?: (number | null);
|
|
57
57
|
signedDate: number;
|
|
58
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Billing program types for external content links and external offers (Android)
|
|
61
|
+
* Available in Google Play Billing Library 8.2.0+
|
|
62
|
+
*/
|
|
63
|
+
export type BillingProgramAndroid = 'unspecified' | 'external-content-link' | 'external-offer';
|
|
64
|
+
/**
|
|
65
|
+
* Result of checking billing program availability (Android)
|
|
66
|
+
* Available in Google Play Billing Library 8.2.0+
|
|
67
|
+
*/
|
|
68
|
+
export interface BillingProgramAvailabilityResultAndroid {
|
|
69
|
+
/** The billing program that was checked */
|
|
70
|
+
billingProgram: BillingProgramAndroid;
|
|
71
|
+
/** Whether the billing program is available for the user */
|
|
72
|
+
isAvailable: boolean;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Reporting details for transactions made outside of Google Play Billing (Android)
|
|
76
|
+
* Contains the external transaction token needed for reporting
|
|
77
|
+
* Available in Google Play Billing Library 8.2.0+
|
|
78
|
+
*/
|
|
79
|
+
export interface BillingProgramReportingDetailsAndroid {
|
|
80
|
+
/** The billing program that the reporting details are associated with */
|
|
81
|
+
billingProgram: BillingProgramAndroid;
|
|
82
|
+
/**
|
|
83
|
+
* External transaction token used to report transactions made outside of Google Play Billing.
|
|
84
|
+
* This token must be used when reporting the external transaction to Google.
|
|
85
|
+
*/
|
|
86
|
+
externalTransactionToken: string;
|
|
87
|
+
}
|
|
59
88
|
export interface DeepLinkOptions {
|
|
60
89
|
/** Android package name to target (required on Android) */
|
|
61
90
|
packageNameAndroid?: (string | null);
|
|
62
91
|
/** Android SKU to open (required on Android) */
|
|
63
92
|
skuAndroid?: (string | null);
|
|
64
93
|
}
|
|
94
|
+
/**
|
|
95
|
+
* Discount amount details for one-time purchase offers (Android)
|
|
96
|
+
* Available in Google Play Billing Library 7.0+
|
|
97
|
+
*/
|
|
98
|
+
export interface DiscountAmountAndroid {
|
|
99
|
+
/** Discount amount in micro-units (1,000,000 = 1 unit of currency) */
|
|
100
|
+
discountAmountMicros: string;
|
|
101
|
+
/** Formatted discount amount with currency sign (e.g., "$4.99") */
|
|
102
|
+
formattedDiscountAmount: string;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Discount display information for one-time purchase offers (Android)
|
|
106
|
+
* Available in Google Play Billing Library 7.0+
|
|
107
|
+
*/
|
|
108
|
+
export interface DiscountDisplayInfoAndroid {
|
|
109
|
+
/**
|
|
110
|
+
* Absolute discount amount details
|
|
111
|
+
* Only returned for fixed amount discounts
|
|
112
|
+
*/
|
|
113
|
+
discountAmount?: (DiscountAmountAndroid | null);
|
|
114
|
+
/**
|
|
115
|
+
* Percentage discount (e.g., 33 for 33% off)
|
|
116
|
+
* Only returned for percentage-based discounts
|
|
117
|
+
*/
|
|
118
|
+
percentageDiscount?: (number | null);
|
|
119
|
+
}
|
|
65
120
|
export interface DiscountIOS {
|
|
66
121
|
identifier: string;
|
|
67
122
|
localizedPrice?: (string | null);
|
|
@@ -140,6 +195,36 @@ export declare enum ErrorCode {
|
|
|
140
195
|
UserCancelled = "user-cancelled",
|
|
141
196
|
UserError = "user-error"
|
|
142
197
|
}
|
|
198
|
+
/**
|
|
199
|
+
* Launch mode for external link flow (Android)
|
|
200
|
+
* Determines how the external URL is launched
|
|
201
|
+
* Available in Google Play Billing Library 8.2.0+
|
|
202
|
+
*/
|
|
203
|
+
export type ExternalLinkLaunchModeAndroid = 'unspecified' | 'launch-in-external-browser-or-app' | 'caller-will-launch-link';
|
|
204
|
+
/**
|
|
205
|
+
* Link type for external link flow (Android)
|
|
206
|
+
* Specifies the type of external link destination
|
|
207
|
+
* Available in Google Play Billing Library 8.2.0+
|
|
208
|
+
*/
|
|
209
|
+
export type ExternalLinkTypeAndroid = 'unspecified' | 'link-to-digital-content-offer' | 'link-to-app-download';
|
|
210
|
+
/**
|
|
211
|
+
* External offer availability result (Android)
|
|
212
|
+
* @deprecated Use BillingProgramAvailabilityResultAndroid with isBillingProgramAvailableAsync instead
|
|
213
|
+
* Available in Google Play Billing Library 6.2.0+, deprecated in 8.2.0
|
|
214
|
+
*/
|
|
215
|
+
export interface ExternalOfferAvailabilityResultAndroid {
|
|
216
|
+
/** Whether external offers are available for the user */
|
|
217
|
+
isAvailable: boolean;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* External offer reporting details (Android)
|
|
221
|
+
* @deprecated Use BillingProgramReportingDetailsAndroid with createBillingProgramReportingDetailsAsync instead
|
|
222
|
+
* Available in Google Play Billing Library 6.2.0+, deprecated in 8.2.0
|
|
223
|
+
*/
|
|
224
|
+
export interface ExternalOfferReportingDetailsAndroid {
|
|
225
|
+
/** External transaction token for reporting external offer transactions */
|
|
226
|
+
externalTransactionToken: string;
|
|
227
|
+
}
|
|
143
228
|
/** Result of presenting an external purchase link (iOS 18.2+) */
|
|
144
229
|
export interface ExternalPurchaseLinkResultIOS {
|
|
145
230
|
/** Optional error message if the presentation failed */
|
|
@@ -159,9 +244,9 @@ export interface ExternalPurchaseNoticeResultIOS {
|
|
|
159
244
|
export type FetchProductsResult = ProductOrSubscription[] | Product[] | ProductSubscription[] | null;
|
|
160
245
|
export type IapEvent = 'purchase-updated' | 'purchase-error' | 'promoted-product-ios' | 'user-choice-billing-android';
|
|
161
246
|
export type IapPlatform = 'ios' | 'android';
|
|
247
|
+
export type IapStore = 'unknown' | 'apple' | 'google' | 'horizon';
|
|
162
248
|
/** Unified purchase states from IAPKit verification response. */
|
|
163
249
|
export type IapkitPurchaseState = 'entitled' | 'pending-acknowledgment' | 'pending' | 'canceled' | 'expired' | 'ready-to-consume' | 'consumed' | 'unknown' | 'inauthentic';
|
|
164
|
-
export type IapkitStore = 'apple' | 'google';
|
|
165
250
|
/** Connection initialization configuration */
|
|
166
251
|
export interface InitConnectionConfig {
|
|
167
252
|
/**
|
|
@@ -170,6 +255,31 @@ export interface InitConnectionConfig {
|
|
|
170
255
|
*/
|
|
171
256
|
alternativeBillingModeAndroid?: (AlternativeBillingModeAndroid | null);
|
|
172
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* Parameters for launching an external link (Android)
|
|
260
|
+
* Used with launchExternalLink to initiate external offer or app install flows
|
|
261
|
+
* Available in Google Play Billing Library 8.2.0+
|
|
262
|
+
*/
|
|
263
|
+
export interface LaunchExternalLinkParamsAndroid {
|
|
264
|
+
/** The billing program (EXTERNAL_CONTENT_LINK or EXTERNAL_OFFER) */
|
|
265
|
+
billingProgram: BillingProgramAndroid;
|
|
266
|
+
/** The external link launch mode */
|
|
267
|
+
launchMode: ExternalLinkLaunchModeAndroid;
|
|
268
|
+
/** The type of the external link */
|
|
269
|
+
linkType: ExternalLinkTypeAndroid;
|
|
270
|
+
/** The URI where the content will be accessed from */
|
|
271
|
+
linkUri: string;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Limited quantity information for one-time purchase offers (Android)
|
|
275
|
+
* Available in Google Play Billing Library 7.0+
|
|
276
|
+
*/
|
|
277
|
+
export interface LimitedQuantityInfoAndroid {
|
|
278
|
+
/** Maximum quantity a user can purchase */
|
|
279
|
+
maximumQuantity: number;
|
|
280
|
+
/** Remaining quantity the user can still purchase */
|
|
281
|
+
remainingQuantity: number;
|
|
282
|
+
}
|
|
173
283
|
export interface Mutation {
|
|
174
284
|
/** Acknowledge a non-consumable purchase or subscription */
|
|
175
285
|
acknowledgePurchaseAndroid: Promise<boolean>;
|
|
@@ -267,6 +377,22 @@ export type MutationValidateReceiptArgs = VerifyPurchaseProps;
|
|
|
267
377
|
export type MutationVerifyPurchaseArgs = VerifyPurchaseProps;
|
|
268
378
|
export type MutationVerifyPurchaseWithProviderArgs = VerifyPurchaseWithProviderProps;
|
|
269
379
|
export type PaymentModeIOS = 'empty' | 'free-trial' | 'pay-as-you-go' | 'pay-up-front';
|
|
380
|
+
/**
|
|
381
|
+
* Pre-order details for one-time purchase products (Android)
|
|
382
|
+
* Available in Google Play Billing Library 8.1.0+
|
|
383
|
+
*/
|
|
384
|
+
export interface PreorderDetailsAndroid {
|
|
385
|
+
/**
|
|
386
|
+
* Pre-order presale end time in milliseconds since epoch.
|
|
387
|
+
* This is when the presale period ends and the product will be released.
|
|
388
|
+
*/
|
|
389
|
+
preorderPresaleEndTimeMillis: string;
|
|
390
|
+
/**
|
|
391
|
+
* Pre-order release time in milliseconds since epoch.
|
|
392
|
+
* This is when the product will be available to users who pre-ordered.
|
|
393
|
+
*/
|
|
394
|
+
preorderReleaseTimeMillis: string;
|
|
395
|
+
}
|
|
270
396
|
export interface PricingPhaseAndroid {
|
|
271
397
|
billingCycleCount: number;
|
|
272
398
|
billingPeriod: string;
|
|
@@ -287,17 +413,52 @@ export interface ProductAndroid extends ProductCommon {
|
|
|
287
413
|
displayPrice: string;
|
|
288
414
|
id: string;
|
|
289
415
|
nameAndroid: string;
|
|
290
|
-
|
|
416
|
+
/**
|
|
417
|
+
* One-time purchase offer details including discounts (Android)
|
|
418
|
+
* Returns all eligible offers. Available in Google Play Billing Library 7.0+
|
|
419
|
+
*/
|
|
420
|
+
oneTimePurchaseOfferDetailsAndroid?: (ProductAndroidOneTimePurchaseOfferDetail[] | null);
|
|
291
421
|
platform: 'android';
|
|
292
422
|
price?: (number | null);
|
|
293
423
|
subscriptionOfferDetailsAndroid?: (ProductSubscriptionAndroidOfferDetails[] | null);
|
|
294
424
|
title: string;
|
|
295
425
|
type: 'in-app';
|
|
296
426
|
}
|
|
427
|
+
/**
|
|
428
|
+
* One-time purchase offer details (Android)
|
|
429
|
+
* Available in Google Play Billing Library 7.0+
|
|
430
|
+
*/
|
|
297
431
|
export interface ProductAndroidOneTimePurchaseOfferDetail {
|
|
432
|
+
/**
|
|
433
|
+
* Discount display information
|
|
434
|
+
* Only available for discounted offers
|
|
435
|
+
*/
|
|
436
|
+
discountDisplayInfo?: (DiscountDisplayInfoAndroid | null);
|
|
298
437
|
formattedPrice: string;
|
|
438
|
+
/**
|
|
439
|
+
* Full (non-discounted) price in micro-units
|
|
440
|
+
* Only available for discounted offers
|
|
441
|
+
*/
|
|
442
|
+
fullPriceMicros?: (string | null);
|
|
443
|
+
/** Limited quantity information */
|
|
444
|
+
limitedQuantityInfo?: (LimitedQuantityInfoAndroid | null);
|
|
445
|
+
/** Offer ID */
|
|
446
|
+
offerId?: (string | null);
|
|
447
|
+
/** List of offer tags */
|
|
448
|
+
offerTags: string[];
|
|
449
|
+
/** Offer token for use in BillingFlowParams when purchasing */
|
|
450
|
+
offerToken: string;
|
|
451
|
+
/**
|
|
452
|
+
* Pre-order details for products available for pre-order
|
|
453
|
+
* Available in Google Play Billing Library 8.1.0+
|
|
454
|
+
*/
|
|
455
|
+
preorderDetailsAndroid?: (PreorderDetailsAndroid | null);
|
|
299
456
|
priceAmountMicros: string;
|
|
300
457
|
priceCurrencyCode: string;
|
|
458
|
+
/** Rental details for rental offers */
|
|
459
|
+
rentalDetailsAndroid?: (RentalDetailsAndroid | null);
|
|
460
|
+
/** Valid time window for the offer */
|
|
461
|
+
validTimeWindow?: (ValidTimeWindowAndroid | null);
|
|
301
462
|
}
|
|
302
463
|
export interface ProductCommon {
|
|
303
464
|
currency: string;
|
|
@@ -343,7 +504,11 @@ export interface ProductSubscriptionAndroid extends ProductCommon {
|
|
|
343
504
|
displayPrice: string;
|
|
344
505
|
id: string;
|
|
345
506
|
nameAndroid: string;
|
|
346
|
-
|
|
507
|
+
/**
|
|
508
|
+
* One-time purchase offer details including discounts (Android)
|
|
509
|
+
* Returns all eligible offers. Available in Google Play Billing Library 7.0+
|
|
510
|
+
*/
|
|
511
|
+
oneTimePurchaseOfferDetailsAndroid?: (ProductAndroidOneTimePurchaseOfferDetail[] | null);
|
|
347
512
|
platform: 'android';
|
|
348
513
|
price?: (number | null);
|
|
349
514
|
subscriptionOfferDetailsAndroid: ProductSubscriptionAndroidOfferDetails[];
|
|
@@ -394,15 +559,26 @@ export interface PurchaseAndroid extends PurchaseCommon {
|
|
|
394
559
|
ids?: (string[] | null);
|
|
395
560
|
isAcknowledgedAndroid?: (boolean | null);
|
|
396
561
|
isAutoRenewing: boolean;
|
|
562
|
+
/**
|
|
563
|
+
* Whether the subscription is suspended (Android)
|
|
564
|
+
* A suspended subscription means the user's payment method failed and they need to fix it.
|
|
565
|
+
* Users should be directed to the subscription center to resolve the issue.
|
|
566
|
+
* Do NOT grant entitlements for suspended subscriptions.
|
|
567
|
+
* Available in Google Play Billing Library 8.1.0+
|
|
568
|
+
*/
|
|
569
|
+
isSuspendedAndroid?: (boolean | null);
|
|
397
570
|
obfuscatedAccountIdAndroid?: (string | null);
|
|
398
571
|
obfuscatedProfileIdAndroid?: (string | null);
|
|
399
572
|
packageNameAndroid?: (string | null);
|
|
573
|
+
/** @deprecated Use store instead */
|
|
400
574
|
platform: IapPlatform;
|
|
401
575
|
productId: string;
|
|
402
576
|
purchaseState: PurchaseState;
|
|
403
577
|
purchaseToken?: (string | null);
|
|
404
578
|
quantity: number;
|
|
405
579
|
signatureAndroid?: (string | null);
|
|
580
|
+
/** Store where purchase was made */
|
|
581
|
+
store: IapStore;
|
|
406
582
|
transactionDate: number;
|
|
407
583
|
transactionId?: (string | null);
|
|
408
584
|
}
|
|
@@ -417,12 +593,15 @@ export interface PurchaseCommon {
|
|
|
417
593
|
id: string;
|
|
418
594
|
ids?: (string[] | null);
|
|
419
595
|
isAutoRenewing: boolean;
|
|
596
|
+
/** @deprecated Use store instead */
|
|
420
597
|
platform: IapPlatform;
|
|
421
598
|
productId: string;
|
|
422
599
|
purchaseState: PurchaseState;
|
|
423
600
|
/** Unified purchase token (iOS JWS, Android purchaseToken) */
|
|
424
601
|
purchaseToken?: (string | null);
|
|
425
602
|
quantity: number;
|
|
603
|
+
/** Store where purchase was made */
|
|
604
|
+
store: IapStore;
|
|
426
605
|
transactionDate: number;
|
|
427
606
|
}
|
|
428
607
|
export interface PurchaseError {
|
|
@@ -447,6 +626,7 @@ export interface PurchaseIOS extends PurchaseCommon {
|
|
|
447
626
|
originalTransactionDateIOS?: (number | null);
|
|
448
627
|
originalTransactionIdentifierIOS?: (string | null);
|
|
449
628
|
ownershipTypeIOS?: (string | null);
|
|
629
|
+
/** @deprecated Use store instead */
|
|
450
630
|
platform: IapPlatform;
|
|
451
631
|
productId: string;
|
|
452
632
|
purchaseState: PurchaseState;
|
|
@@ -458,6 +638,8 @@ export interface PurchaseIOS extends PurchaseCommon {
|
|
|
458
638
|
renewalInfoIOS?: (RenewalInfoIOS | null);
|
|
459
639
|
revocationDateIOS?: (number | null);
|
|
460
640
|
revocationReasonIOS?: (string | null);
|
|
641
|
+
/** Store where purchase was made */
|
|
642
|
+
store: IapStore;
|
|
461
643
|
storefrontCountryCodeIOS?: (string | null);
|
|
462
644
|
subscriptionGroupIdIOS?: (string | null);
|
|
463
645
|
transactionDate: number;
|
|
@@ -584,6 +766,19 @@ export interface RenewalInfoIOS {
|
|
|
584
766
|
renewalOfferType?: (string | null);
|
|
585
767
|
willAutoRenew: boolean;
|
|
586
768
|
}
|
|
769
|
+
/**
|
|
770
|
+
* Rental details for one-time purchase products that can be rented (Android)
|
|
771
|
+
* Available in Google Play Billing Library 7.0+
|
|
772
|
+
*/
|
|
773
|
+
export interface RentalDetailsAndroid {
|
|
774
|
+
/**
|
|
775
|
+
* Rental expiration period in ISO 8601 format
|
|
776
|
+
* Time after rental period ends when user can still extend
|
|
777
|
+
*/
|
|
778
|
+
rentalExpirationPeriod?: (string | null);
|
|
779
|
+
/** Rental period in ISO 8601 format (e.g., P7D for 7 days) */
|
|
780
|
+
rentalPeriod: string;
|
|
781
|
+
}
|
|
587
782
|
export interface RequestPurchaseAndroidProps {
|
|
588
783
|
/** Personalized offer flag */
|
|
589
784
|
isOfferPersonalized?: (boolean | null);
|
|
@@ -620,9 +815,13 @@ export type RequestPurchaseProps = {
|
|
|
620
815
|
useAlternativeBilling?: boolean | null;
|
|
621
816
|
};
|
|
622
817
|
export interface RequestPurchasePropsByPlatforms {
|
|
623
|
-
/**
|
|
818
|
+
/** @deprecated Use google instead */
|
|
624
819
|
android?: (RequestPurchaseAndroidProps | null);
|
|
625
|
-
/**
|
|
820
|
+
/** Apple-specific purchase parameters */
|
|
821
|
+
apple?: (RequestPurchaseIosProps | null);
|
|
822
|
+
/** Google-specific purchase parameters */
|
|
823
|
+
google?: (RequestPurchaseAndroidProps | null);
|
|
824
|
+
/** @deprecated Use apple instead */
|
|
626
825
|
ios?: (RequestPurchaseIosProps | null);
|
|
627
826
|
}
|
|
628
827
|
export type RequestPurchaseResult = Purchase | Purchase[] | null;
|
|
@@ -635,12 +834,20 @@ export interface RequestSubscriptionAndroidProps {
|
|
|
635
834
|
obfuscatedProfileIdAndroid?: (string | null);
|
|
636
835
|
/** Purchase token for upgrades/downgrades */
|
|
637
836
|
purchaseTokenAndroid?: (string | null);
|
|
638
|
-
/**
|
|
837
|
+
/**
|
|
838
|
+
* Replacement mode for subscription changes
|
|
839
|
+
* @deprecated Use subscriptionProductReplacementParams instead for item-level replacement (8.1.0+)
|
|
840
|
+
*/
|
|
639
841
|
replacementModeAndroid?: (number | null);
|
|
640
842
|
/** List of subscription SKUs */
|
|
641
843
|
skus: string[];
|
|
642
844
|
/** Subscription offers */
|
|
643
845
|
subscriptionOffers?: (AndroidSubscriptionOfferInput[] | null);
|
|
846
|
+
/**
|
|
847
|
+
* Product-level replacement parameters (8.1.0+)
|
|
848
|
+
* Use this instead of replacementModeAndroid for item-level replacement
|
|
849
|
+
*/
|
|
850
|
+
subscriptionProductReplacementParams?: (SubscriptionProductReplacementParamsAndroid | null);
|
|
644
851
|
}
|
|
645
852
|
export interface RequestSubscriptionIosProps {
|
|
646
853
|
andDangerouslyFinishTransactionAutomatically?: (boolean | null);
|
|
@@ -650,9 +857,13 @@ export interface RequestSubscriptionIosProps {
|
|
|
650
857
|
withOffer?: (DiscountOfferInputIOS | null);
|
|
651
858
|
}
|
|
652
859
|
export interface RequestSubscriptionPropsByPlatforms {
|
|
653
|
-
/**
|
|
860
|
+
/** @deprecated Use google instead */
|
|
654
861
|
android?: (RequestSubscriptionAndroidProps | null);
|
|
655
|
-
/**
|
|
862
|
+
/** Apple-specific subscription parameters */
|
|
863
|
+
apple?: (RequestSubscriptionIosProps | null);
|
|
864
|
+
/** Google-specific subscription parameters */
|
|
865
|
+
google?: (RequestSubscriptionAndroidProps | null);
|
|
866
|
+
/** @deprecated Use apple instead */
|
|
656
867
|
ios?: (RequestSubscriptionIosProps | null);
|
|
657
868
|
}
|
|
658
869
|
export interface RequestVerifyPurchaseWithIapkitAppleProps {
|
|
@@ -676,7 +887,7 @@ export interface RequestVerifyPurchaseWithIapkitResult {
|
|
|
676
887
|
isValid: boolean;
|
|
677
888
|
/** The current state of the purchase. */
|
|
678
889
|
state: IapkitPurchaseState;
|
|
679
|
-
store:
|
|
890
|
+
store: IapStore;
|
|
680
891
|
}
|
|
681
892
|
export interface Subscription {
|
|
682
893
|
/** Fires when the App Store surfaces a promoted product (iOS only) */
|
|
@@ -712,6 +923,23 @@ export interface SubscriptionPeriodValueIOS {
|
|
|
712
923
|
unit: SubscriptionPeriodIOS;
|
|
713
924
|
value: number;
|
|
714
925
|
}
|
|
926
|
+
/**
|
|
927
|
+
* Product-level subscription replacement parameters (Android)
|
|
928
|
+
* Used with setSubscriptionProductReplacementParams in BillingFlowParams.ProductDetailsParams
|
|
929
|
+
* Available in Google Play Billing Library 8.1.0+
|
|
930
|
+
*/
|
|
931
|
+
export interface SubscriptionProductReplacementParamsAndroid {
|
|
932
|
+
/** The old product ID that needs to be replaced */
|
|
933
|
+
oldProductId: string;
|
|
934
|
+
/** The replacement mode for this product change */
|
|
935
|
+
replacementMode: SubscriptionReplacementModeAndroid;
|
|
936
|
+
}
|
|
937
|
+
/**
|
|
938
|
+
* Replacement mode for subscription changes (Android)
|
|
939
|
+
* These modes determine how the subscription replacement affects billing.
|
|
940
|
+
* Available in Google Play Billing Library 8.1.0+
|
|
941
|
+
*/
|
|
942
|
+
export type SubscriptionReplacementModeAndroid = 'unknown-replacement-mode' | 'with-time-proration' | 'charge-prorated-price' | 'charge-full-price' | 'without-proration' | 'deferred' | 'keep-existing';
|
|
715
943
|
export interface SubscriptionStatusIOS {
|
|
716
944
|
renewalInfo?: (RenewalInfoIOS | null);
|
|
717
945
|
state: string;
|
|
@@ -726,6 +954,16 @@ export interface UserChoiceBillingDetails {
|
|
|
726
954
|
/** List of product IDs selected by the user */
|
|
727
955
|
products: string[];
|
|
728
956
|
}
|
|
957
|
+
/**
|
|
958
|
+
* Valid time window for when an offer is available (Android)
|
|
959
|
+
* Available in Google Play Billing Library 7.0+
|
|
960
|
+
*/
|
|
961
|
+
export interface ValidTimeWindowAndroid {
|
|
962
|
+
/** End time in milliseconds since epoch */
|
|
963
|
+
endTimeMillis: string;
|
|
964
|
+
/** Start time in milliseconds since epoch */
|
|
965
|
+
startTimeMillis: string;
|
|
966
|
+
}
|
|
729
967
|
export interface VerifyPurchaseAndroidOptions {
|
|
730
968
|
accessToken: string;
|
|
731
969
|
isSub?: (boolean | null);
|
|
@@ -769,13 +1007,19 @@ export interface VerifyPurchaseResultIOS {
|
|
|
769
1007
|
/** Receipt data string */
|
|
770
1008
|
receiptData: string;
|
|
771
1009
|
}
|
|
1010
|
+
export interface VerifyPurchaseWithProviderError {
|
|
1011
|
+
code?: (string | null);
|
|
1012
|
+
message: string;
|
|
1013
|
+
}
|
|
772
1014
|
export interface VerifyPurchaseWithProviderProps {
|
|
773
1015
|
iapkit?: (RequestVerifyPurchaseWithIapkitProps | null);
|
|
774
1016
|
provider: PurchaseVerificationProvider;
|
|
775
1017
|
}
|
|
776
1018
|
export interface VerifyPurchaseWithProviderResult {
|
|
777
|
-
/**
|
|
778
|
-
|
|
1019
|
+
/** Error details if verification failed */
|
|
1020
|
+
errors?: (VerifyPurchaseWithProviderError[] | null);
|
|
1021
|
+
/** IAPKit verification result */
|
|
1022
|
+
iapkit?: (RequestVerifyPurchaseWithIapkitResult | null);
|
|
779
1023
|
provider: PurchaseVerificationProvider;
|
|
780
1024
|
}
|
|
781
1025
|
export type VoidResult = void;
|