### Quickstart Commands Source: https://github.com/iaphub/react-native-iaphub/blob/master/examples/example-expo/README.md Commands to install dependencies and launch the application on various platforms. ```bash # Install dependencies npm install # Start the Metro bundler npm run start # Or launch directly to a platform npm run ios npm run android npm run web ``` -------------------------------- ### start() Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/iaphub.md Initializes IAPHUB with credentials and configuration options. This method must be called before any other IAPHUB methods. ```APIDOC ## start() ### Description Initializes IAPHUB with credentials and configuration options. This method must be called before any other IAPHUB methods. ### Method `public async start(opts: StartOptions): Promise` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body - **opts** (object) - Required - Configuration options for initialization. - **opts.appId** (string) - Required - IAPHUB app ID from the IAPHUB dashboard. - **opts.apiKey** (string) - Required - IAPHUB Client API key from the IAPHUB dashboard. - **opts.userId** (string) - Optional - User ID associated with the authenticated account. - **opts.allowAnonymousPurchase** (boolean) - Optional - Whether anonymous purchases are permitted. Defaults to `false`. - **opts.enableDeferredPurchaseListener** (boolean) - Optional - Toggles the deferred purchase listener. Defaults to `true`. - **opts.enableStorekitV2** (boolean) - Optional - Enables StoreKit V2 when available (iOS 15+). Enabling is recommended. Defaults to `false`. - **opts.lang** (string) - Optional - Locale code to localize product titles and descriptions (e.g., `en`, `fr`). Defaults to `"en"`. - **opts.environment** (string) - Optional - Target IAPHUB environment. Defaults to `"production"`. ### Request Example ```typescript try { await Iaphub.start({ appId: 'your-app-id', apiKey: 'your-api-key', userId: 'user@example.com', allowAnonymousPurchase: false, enableStorekitV2: true, lang: 'en' }); } catch (err) { console.error('Failed to start:', err.code, err.message); } ``` ### Response #### Success Response Resolves when initialization is complete. #### Response Example None (void return type) ``` -------------------------------- ### Setup Listeners on App Start Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/event-emitter.md Initializes the IAPHub SDK and sets up event listeners for user updates, errors, and deferred purchases when the app starts. Includes cleanup logic to remove listeners and stop the SDK on component unmount. ```typescript useEffect(() => { const setupListeners = async () => { try { // Initialize SDK await Iaphub.start({ appId: 'your-app-id', apiKey: 'your-api-key' }); // Add listeners Iaphub.addEventListener('onUserUpdate', handleUserUpdate); Iaphub.addEventListener('onError', handleError); Iaphub.addEventListener('onDeferredPurchase', handleDeferredPurchase); } catch (err) { console.error('Setup failed:', err); } }; setupListeners(); // Cleanup on unmount return () => { Iaphub.removeAllListeners(); Iaphub.stop(); }; }, []); ``` -------------------------------- ### Install IAPHUB SDK Source: https://github.com/iaphub/react-native-iaphub/blob/master/examples/example-expo/README.md Command to add the IAPHUB SDK dependency to the project. ```bash npm install react-native-iaphub ``` -------------------------------- ### Initialize IAPHUB SDK Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/quick-reference.md Start the IAPHUB SDK with your application credentials and configuration. Ensure you replace placeholders with your actual `appId`, `apiKey`, and `userId`. ```typescript await Iaphub.start({ appId: 'your-app-id', apiKey: 'your-api-key', userId: 'user@example.com', allowAnonymousPurchase: false, enableStorekitV2: true, lang: 'en' }); ``` -------------------------------- ### Start IAPHub in Sandbox Environment Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/integration-guide.md Configure IAPHub to use the sandbox environment for testing purchases. Ensure you replace 'YOUR_APP_ID' and 'YOUR_API_KEY' with your actual credentials. ```typescript await Iaphub.start({ appId: 'YOUR_APP_ID', apiKey: 'YOUR_API_KEY', environment: 'sandbox' // Test purchases }); ``` -------------------------------- ### Initialize IAPHUB with Start Options Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/iaphub.md Initializes IAPHUB with your application ID, API key, and optional user ID and configuration settings. Ensure to handle potential initialization errors. ```typescript import Iaphub from 'react-native-iaphub'; try { await Iaphub.start({ appId: 'your-app-id', apiKey: 'your-api-key', userId: 'user@example.com', allowAnonymousPurchase: false, enableStorekitV2: true, lang: 'en' }); } catch (err) { console.error('Failed to start:', err.code, err.message); } ``` -------------------------------- ### Subscription Intro Phases Structure Source: https://github.com/iaphub/react-native-iaphub/blob/master/guides/migrate-v7-to-v8.md The `subscriptionIntroPhases` property is an ordered list representing intro phases. This example shows a free trial followed by a discounted introductory price. ```javascript [ { type: "trial", price: 0, currency: "USD", localizedPrice: "FREE", cycleDuration: "P1M", cycleCount: 1, payment: "upfront" }, { type: "intro", price: 4.99, currency: "USD", localizedPrice: "$4.99", cycleDuration: "P1M", cycleCount: 3, payment: "as_you_go" } ] ``` -------------------------------- ### Get Products for Sale Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/quick-reference.md Retrieve a list of products that are currently available for purchase. ```typescript // Get products for sale const products = await Iaphub.getProductsForSale(); ``` -------------------------------- ### Initialization Error Handling Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/errors.md Catch errors that occur during IAPHUB initialization. This example logs the error message and suggests retrying or informing the user. ```typescript try { await Iaphub.start({ appId: 'your-app-id', apiKey: 'your-api-key' }); } catch (err) { console.error('IAPHUB initialization failed:', err.message); // Retry after delay or show user message } ``` -------------------------------- ### Get All Products Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/quick-reference.md Fetch both products available for sale and products the user actively owns in a single call. ```typescript // Get both const { productsForSale, activeProducts } = await Iaphub.getProducts(); ``` -------------------------------- ### Install react-native-iaphub v7 Source: https://github.com/iaphub/react-native-iaphub/blob/master/guides/migrate-v6-to-v7.md Use npm to install the latest version of react-native-iaphub. After installation, update your Xcode dependencies by running `pod install` in the `ios` directory. ```bash npm install react-native-iaphub@latest --save pod install ``` -------------------------------- ### Initialize IAPHub in App Root Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/integration-guide.md Initialize the IAPHub SDK when your application starts. Ensure you replace 'YOUR_APP_ID' and 'YOUR_API_KEY' with your actual credentials. This snippet demonstrates basic initialization with anonymous purchase enabled and StoreKit v2 enabled. ```typescript import React, { useEffect } from 'react'; import Iaphub from 'react-native-iaphub'; const App = () => { useEffect(() => { initializeIAP(); }, []); const initializeIAP = async () => { try { await Iaphub.start({ appId: 'YOUR_APP_ID', apiKey: 'YOUR_API_KEY', allowAnonymousPurchase: true, enableStorekitV2: true }); } catch (err) { console.error('IAP initialization failed:', err); } }; return ( {/* App content */} ); }; export default App; ``` -------------------------------- ### Get Products Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/product.md Retrieves products, which are then available via the `Products.productsForSale` property. This method is an alternative way to access product data. ```APIDOC ## getProducts() ### Description Retrieves products, making them available through the `Products.productsForSale` property. ### Method `Iaphub.getProducts()` ### Returns This method does not directly return products but populates `Products.productsForSale`. ### Related Types - `Products` — Container with both `productsForSale` and `activeProducts` ``` -------------------------------- ### Handle Purchase Result Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/transaction.md This example demonstrates how to handle the result of a purchase, checking the webhook status to confirm server validation and grant access accordingly. ```APIDOC ## Handle Purchase Result ### Description Handles the result of a purchase, checking the `webhookStatus` to determine if the purchase has been successfully validated by the server. It outlines actions for 'success', 'failed', and 'pending' statuses. ### Method `Iaphub.buy(sku: string)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```typescript try { const transaction = await Iaphub.buy('premium_monthly_sku'); if (transaction.webhookStatus === 'success') { // Purchase confirmed on server console.log('Purchase successful and validated'); grantPremiumAccess(); } else if (transaction.webhookStatus === 'failed') { // Server validation failed console.warn( 'Purchase completed but server validation failed. ' + 'Access will be granted once validation succeeds.' ); showAlert( 'Purchase delayed', 'Your purchase was successful but we need more time to validate it. ' + 'Access will be restored shortly.' ); } else if (transaction.webhookStatus === 'pending') { // Still waiting for server response console.log('Waiting for server validation...'); } } catch (err) { console.error('Purchase failed:', err.message); } ``` ### Response #### Success Response (Transaction Object) - `webhookStatus` (string) - The status of the server-side validation ('success', 'failed', 'pending'). #### Response Example ```json { "purchase": "...', "sku": "premium_monthly_sku", "platform": "ios", "webhookStatus": "success", "purchaseDate": "...", "expirationDate": "..." } ``` ``` -------------------------------- ### Get All Products (For Sale and Active) Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/iaphub.md Retrieves both products available for sale and the user's currently owned active products. Use this to display both purchase options and owned content. ```typescript const products = await Iaphub.getProducts(); console.log('Available:', products.productsForSale.length); console.log('Owned:', products.activeProducts.length); ``` -------------------------------- ### Get and Log Active Products Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/active-product.md Retrieves all active products and logs their details. Useful for displaying a user's current subscriptions. ```typescript const activeProducts = await Iaphub.getActiveProducts(); activeProducts.forEach(product => { console.log(`Product: ${product.localizedTitle}`); console.log(`Purchased: ${product.purchaseDate}`); console.log(`Expires: ${product.expirationDate}`); console.log(`State: ${product.subscriptionState}`); console.log(`Platform: ${product.platform}`); }); ``` -------------------------------- ### Get Products for Sale Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/product.md Retrieves a list of all products that are currently available for purchase. This is a primary method for displaying available items to the user. ```APIDOC ## getProductsForSale() ### Description Retrieves a list of products available for sale. ### Method `Iaphub.getProductsForSale()` ### Returns `Product[]` - An array of product objects. ### Usage Example ```typescript const products = await Iaphub.getProductsForSale(); products.forEach(product => { console.log(`Product: ${product.localizedTitle}`); console.log(`Price: ${product.localizedPrice} (${product.currency})`); console.log(`Type: ${product.type}`); console.log(`Description: ${product.localizedDescription}`); }); ``` ``` -------------------------------- ### Get Trial Badge Information Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/integration-guide.md A utility function to determine and format trial or intro offer information for a product. Returns a string representing the offer or null if no offer is available. ```typescript const getTrialBadge = (product) => { if (!product.subscriptionIntroPhases?.length) return null; const phase = product.subscriptionIntroPhases[0]; if (phase.type === 'trial' && phase.price === 0) { return `${phase.cycleDuration} free`; } if (phase.type === 'intro') { return `Intro: ${phase.localizedPrice}`; } return null; }; ``` -------------------------------- ### Get Active Products with IAPHUB Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/iaphub.md Retrieves products a user currently owns or has an active subscription to. You can filter by subscription states to include specific statuses like 'paused' or 'retry_period'. ```typescript // Get only active and grace period subscriptions const active = await Iaphub.getActiveProducts(); // Include paused and retry period subscriptions const allStates = await Iaphub.getActiveProducts({ includeSubscriptionStates: ['paused', 'retry_period'] }); ``` -------------------------------- ### StartOptions Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/types.md Configuration options for initializing IAPHUB. These options are used when calling the `Iaphub.start()` method. ```APIDOC ## StartOptions ### Description Configuration options for initializing IAPHUB. ### Fields #### appId (string) - Yes - IAPHUB app ID from the dashboard. #### apiKey (string) - Yes - IAPHUB Client API key from the dashboard. #### userId (string) - No - User ID for authentication. #### allowAnonymousPurchase (boolean) - No - Allow purchases without user login. #### enableDeferredPurchaseListener (boolean) - No - Enable deferred purchase event listener. #### enableStorekitV2 (boolean) - No - Use StoreKit V2 on iOS 15+. #### lang (string) - No - Locale code (e.g., `en`, `fr`). #### environment (string) - No - Target environment. ``` -------------------------------- ### Initialize IAPHub and Fetch Products Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/quick-reference.md Initialize the SDK with your app ID and API key, set up an event listener for user updates, and fetch available products. This is typically done once when the component mounts. ```typescript useEffect(() => { (async () => { await Iaphub.start({ appId: 'id', apiKey: 'key' }); Iaphub.addEventListener('onUserUpdate', refreshProducts); await refreshProducts(); })(); }, []); const refreshProducts = async () => { const products = await Iaphub.getProducts(); setActiveProducts(products.activeProducts); setForSale(products.productsForSale); }; ``` -------------------------------- ### StartOptions Interface Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/types.md Configuration options for initializing IAPHUB. Use these options when calling the Iaphub.start() method. ```typescript interface StartOptions { appId: string; apiKey: string; userId?: string; allowAnonymousPurchase?: boolean; enableDeferredPurchaseListener?: boolean; enableStorekitV2?: boolean; lang?: string; environment?: string; } ``` -------------------------------- ### Get Active Products Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/quick-reference.md Retrieve a list of products that the user currently owns or has active subscriptions for. ```typescript // Get active products (owned) const active = await Iaphub.getActiveProducts(); ``` -------------------------------- ### Initialize SDK with Full Configuration Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/configuration.md Use this snippet to initialize the IAPHUB SDK with all available configuration options. This provides granular control over SDK behavior, including user identification, anonymous purchases, deferred purchase listening, StoreKit V2 usage, language localization, and environment targeting. ```typescript await Iaphub.start({ appId: 'your-app-id-from-dashboard', apiKey: 'your-client-api-key', userId: 'user@example.com', allowAnonymousPurchase: false, enableDeferredPurchaseListener: true, enableStorekitV2: true, lang: 'en', environment: 'production' }); ``` -------------------------------- ### Initialize SDK with Minimal Configuration Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/configuration.md This snippet shows the minimum required configuration to initialize the IAPHUB SDK. Only the `appId` and `apiKey` are mandatory for basic SDK functionality. ```typescript await Iaphub.start({ appId: 'your-app-id', apiKey: 'your-api-key' }); ``` -------------------------------- ### Creating an IaphubError Instance Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/iaphub-error.md Example of creating a new IaphubError instance with a specific error code, message, and associated parameters. ```typescript const err = new IaphubError({ code: 'product_already_owned', message: 'You already own this product', params: { productId: '123' } }); ``` -------------------------------- ### Display Multi-Phase Intro Pricing Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/subscription-intro-phase.md Iterate through and display details for all introductory pricing phases of a product. Assumes the product has subscription intro phases. ```typescript const product = products.find(p => p.sku === 'premium_annual_sku'); if (product?.subscriptionIntroPhases) { console.log('Introductory pricing:'); product.subscriptionIntroPhases.forEach((phase, index) => { const totalPrice = phase.price * phase.cycleCount; console.log( `Phase ${index + 1}: ${phase.localizedPrice}/${phase.cycleDuration} ` + `for ${phase.cycleCount} cycles ` + `(${phase.payment})` ); }); } ``` -------------------------------- ### IAPHUB Initialization Data Flow Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/modules-overview.md Illustrates the sequence of calls from the App to the native layer during IAPHub initialization. ```text App ↓ Iaphub.start(opts) ↓ NativeIaphub.start(opts) [native layer] ↓ IaphubError.parse() [error handling] ↓ Event listeners registered ``` -------------------------------- ### Change Product Localization Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/configuration.md Changes the language for product localization. After changing the language, you may need to fetch products again to get the updated localization. ```typescript const success = await Iaphub.setLang('fr'); if (success) { // Fetch products again to get French localization const products = await Iaphub.getProducts(); } ``` -------------------------------- ### Initialize Singleton Instance Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/README.md The SDK utilizes a singleton pattern, ensuring a single instance is shared across the application. Import the Iaphub module to access this instance. ```typescript import Iaphub from 'react-native-iaphub'; // Iaphub is a single instance shared across the app ``` -------------------------------- ### Initialize IAPHUB SDK Source: https://github.com/iaphub/react-native-iaphub/blob/master/examples/example-expo/README.md Initialization code to be placed in App.js using your specific IAPHUB credentials. ```js import Iaphub from 'react-native-iaphub'; Iaphub.start({ appId: 'YOUR_IAPHUB_APP_ID', apiKey: 'YOUR_IAPHUB_API_KEY', enableStorekitV2: true, lang: 'en', }); ``` -------------------------------- ### Build Pricing Summary String Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/subscription-intro-phase.md Generate a human-readable pricing summary string for a product, detailing introductory offers and the final price. Handles products with and without intro phases. ```typescript const buildPricingSummary = (product: Product): string => { if (!product.subscriptionIntroPhases?.length) { return `${product.localizedPrice}/${product.subscriptionDuration}`; } const phases = product.subscriptionIntroPhases; const intro = phases.map(p => `${p.localizedPrice}/${p.cycleDuration} for ${p.cycleCount} cycles` ).join(', then '); return `Try now: ${intro}, then ${product.localizedPrice}`; }; // Example output: // "Try now: $0.00/P7D for 1 cycles, then $9.99/P1M" ``` -------------------------------- ### Display Product Information Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/product.md Iterates through a list of products obtained from `Iaphub.getProductsForSale()` and logs their localized title, price, currency, type, and description. ```typescript const products = await Iaphub.getProductsForSale(); products.forEach(product => { console.log(`Product: ${product.localizedTitle}`); console.log(`Price: ${product.localizedPrice} (${product.currency})`); console.log(`Type: ${product.type}`); console.log(`Description: ${product.localizedDescription}`); }); ``` -------------------------------- ### buy() Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/iaphub.md Initiates a purchase for a product. This method handles the process of buying a specific SKU, with options for cross-platform conflict resolution and proration modes. ```APIDOC ## buy() ### Description Initiates a purchase for a product. ### Method `public async buy(sku: string, opts?: BuyOptions): Promise` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body * **sku** (string) - Required - Store identifier to purchase (SKU). * **opts.crossPlatformConflict** (boolean) - Optional - Whether to throw an error if the user already has a subscription on a different platform. Defaults to `true`. * **opts.prorationMode** (string) - Optional - Optional Google Play proration mode for upgrades/downgrades (Android only). Defaults to `undefined`. ### Request Example ```typescript try { const transaction = await Iaphub.buy('premium_monthly_sku'); console.log('Purchase successful:', transaction.purchase); if (transaction.webhookStatus === 'failed') { // Webhook delivery failed; transaction needs server validation } } catch (err) { if (err.code === 'user_cancelled') { // User cancelled the purchase } else if (err.code === 'product_already_owned') { // Product already owned; user should restore } else { console.error('Purchase failed:', err.message); } } ``` ### Response #### Success Response (200) * **Transaction** - Object containing purchase details. #### Response Example ```json { "purchase": "..." } ``` ERROR HANDLING: * **Throws:** `IaphubError` — With codes: `product_already_owned`, `deferred_payment`, `billing_unavailable`, `network_error`, `receipt_failed`, `cross_platform_conflict`, `user_conflict`, `user_cancelled`, `product_already_purchased`, `unexpected`. ``` -------------------------------- ### Compare Intro Phases Length Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/subscription-intro-phase.md Compare the introductory phase durations of two products to determine which has a longer trial. Assumes products have at least one intro phase. ```typescript const compareProducts = (productA: Product, productB: Product) => { const getIntroLength = (p: Product): number => { if (!p.subscriptionIntroPhases?.length) return 0; const phase = p.subscriptionIntroPhases[0]; const duration = parseInt(phase.cycleDuration.match(/\d+/)[0]); return duration * phase.cycleCount; }; const aLength = getIntroLength(productA); const bLength = getIntroLength(productB); if (aLength > bLength) { console.log(`${productA.localizedTitle} has longer trial`); } else if (bLength > aLength) { console.log(`${productB.localizedTitle} has longer trial`); } else { console.log('Trials are equal length'); } }; ``` -------------------------------- ### Get Billing Status Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/iaphub.md Retrieves the current billing status, including any errors encountered or product IDs that have been filtered from the store. Check this to diagnose billing issues or understand store filtering. ```typescript const status = await Iaphub.getBillingStatus(); if (status.error) { console.error('Billing error:', status.error.message); } if (status.filteredProductIds.length > 0) { console.log('Filtered products:', status.filteredProductIds); } ``` -------------------------------- ### Import SDK and Types Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/quick-reference.md Import the Iaphub SDK and necessary types for working with products, active products, transactions, and errors. ```typescript import Iaphub from 'react-native-iaphub'; import type { Product, ActiveProduct, Transaction, IaphubError } from 'react-native-iaphub'; ``` -------------------------------- ### IAPHUB Product Fetch Data Flow Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/modules-overview.md Outlines the process for fetching products, including the structure of the returned products object. ```text App ↓ Iaphub.getProducts(opts) ↓ NativeIaphub.getProducts(opts) [native layer] ↓ Products object with: - productsForSale: Product[] - activeProducts: ActiveProduct[] ``` -------------------------------- ### Get Current User ID Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/iaphub.md Retrieves the unique identifier for the currently authenticated user. This method is asynchronous and returns a promise that resolves with the user ID string. Errors during retrieval are logged to the console. ```typescript const userId = await Iaphub.getUserId(); console.log('Current user:', userId); ``` -------------------------------- ### Purchase Flow Error Handling Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/errors.md Handle specific error codes during the purchase flow to provide user-friendly messages or take appropriate actions. This example maps common error codes to user-facing messages. ```typescript try { const transaction = await Iaphub.buy('premium_monthly_sku'); console.log('Purchase successful'); } catch (err) { const errorMap = { 'product_already_owned': 'Product owned; please restore purchases', 'deferred_payment': 'Purchase awaiting approval', 'billing_unavailable': 'In-app purchases not available', 'network_error': 'Network error; please retry', 'receipt_failed': 'Receipt validation failed; retrying', 'cross_platform_conflict': 'Subscription exists on different platform', 'user_cancelled': null, // Silent; user cancelled 'user_conflict': 'Product owned by different user', 'unexpected': 'Purchase failed; contact support' }; const message = errorMap[err.code]; if (message) { Alert.alert('Error', message); } } ``` -------------------------------- ### Initiate Product Purchase Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/product.md Attempts to initiate a purchase for a given product SKU using `Iaphub.buy()`. Logs success or failure messages based on the outcome of the purchase attempt. ```typescript const product = products.find(p => p.sku === 'premium_monthly_sku'); if (product) { try { const transaction = await Iaphub.buy(product.sku); console.log('Purchase successful'); } catch (err) { console.error('Purchase failed:', err.message); } } ``` -------------------------------- ### Calculate Total Trial Cost Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/subscription-intro-phase.md Calculate the total cost of all introductory phases for a product, excluding free trial phases. Requires a product with subscription intro phases. ```typescript const product = products.find(p => p.sku === 'premium_sku'); const calculateTrialCost = (phase: SubscriptionIntroPhase) => { if (phase.type === 'trial') { return 0; } return phase.price * phase.cycleCount; }; if (product?.subscriptionIntroPhases) { const totalIntro = product.subscriptionIntroPhases .reduce((sum, phase) => sum + calculateTrialCost(phase), 0); console.log(`Total intro cost: ${totalIntro} ${product.currency}`); } ``` -------------------------------- ### Listen for Errors Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/event-emitter.md Fires when an error occurs. Errors are automatically converted to `IaphubError` instances by the SDK. Triggers include billing unavailability, network errors, and other SDK errors. Product missing from the store is logged as a warning during `start()`. ```typescript Iaphub.addEventListener('onError', (err: IaphubError) => { console.error(`Error [${err.code}]: ${err.message}`); if (err.code === 'billing_unavailable') { disablePurchaseUI(); } }); ``` -------------------------------- ### Display Subscription Trial Information Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/quick-reference.md Check if a product has an introductory phase (trial) and log its details, such as localized price, cycle duration, and number of cycles. This helps in informing users about trial terms. ```typescript const trial = product.subscriptionIntroPhases?.[0]; if (trial) { console.log(`${trial.localizedPrice}/${trial.cycleDuration} for ${trial.cycleCount} cycles`); } ``` -------------------------------- ### Check Payment Timing for Intro Phase Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/subscription-intro-phase.md Determine if the first introductory phase requires an upfront payment or per-cycle charges. Assumes the product has at least one intro phase. ```typescript const product = products.find(p => p.sku === 'premium_sku'); if (product?.subscriptionIntroPhases?.length) { const introPhase = product.subscriptionIntroPhases[0]; if (introPhase.payment === 'upfront') { // User charged once for all cycles const totalCost = introPhase.price * introPhase.cycleCount; console.log(`Charge ${totalCost} ${introPhase.currency} upfront`); } else { // User charged per cycle console.log(`Charge ${introPhase.localizedPrice} per ${introPhase.cycleDuration}`); } } ``` -------------------------------- ### Display Introductory Pricing Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/product.md Finds a specific product by SKU and displays details about its introductory pricing phases, including localized price, cycle duration, and cycle count. ```typescript const product = products.find(p => p.sku === 'premium_monthly_sku'); if (product?.subscriptionIntroPhases?.length) { const intro = product.subscriptionIntroPhases[0]; console.log( `Trial: ${intro.localizedPrice}/${intro.cycleDuration} for ${intro.cycleCount} cycles` ); } ``` -------------------------------- ### Purchase a Product Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/quick-reference.md Initiate the purchase of a product using its SKU. Check the `webhookStatus` on the returned transaction to confirm purchase. ```typescript // Buy a product const transaction = await Iaphub.buy('premium_monthly_sku'); // Check webhook status if (transaction.webhookStatus === 'success') { // Purchase confirmed } ``` -------------------------------- ### Iaphub Class Methods Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/README.md The Iaphub class provides the main interface for interacting with the SDK. It includes methods for initialization, authentication, managing purchases and subscriptions, handling events, setting device parameters, and diagnostics. ```APIDOC ## Iaphub Class ### Description The main SDK class with all public methods for managing in-app purchases and subscriptions. ### Methods - **Initialization**: `start()`, `stop()` - **Authentication**: `login()`, `logout()`, `getUserId()` - **Purchases**: `buy()`, `restore()` - **Products**: `getProducts()`, `getActiveProducts()`, `getProductsForSale()` - **Subscriptions**: `showManageSubscriptions()`, `presentCodeRedemptionSheet()` - **Events**: `addEventListener()`, `removeEventListener()`, `removeAllListeners()` - **Metadata**: `setDeviceParams()`, `setUserTags()`, `setLang()` - **Diagnostics**: `getBillingStatus()` ``` -------------------------------- ### Initialization Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/MANIFEST.md Functions for initializing and shutting down the SDK. ```APIDOC ## start() ### Description Initializes the IAPHUB SDK. ### Method start() ### Parameters None explicitly documented. ### Request Example ```javascript await iaphub.start(); ``` ### Response None explicitly documented. ``` ```APIDOC ## stop() ### Description Shuts down the IAPHUB SDK. ### Method stop() ### Parameters None explicitly documented. ### Request Example ```javascript await iaphub.stop(); ``` ### Response None explicitly documented. ``` -------------------------------- ### Display Trial Information Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/subscription-intro-phase.md Find and display details about a free trial phase for a product. Requires the product and its subscription intro phases to be available. ```typescript const product = products.find(p => p.sku === 'premium_monthly_sku'); if (product?.subscriptionIntroPhases?.length) { const trialPhase = product.subscriptionIntroPhases.find(p => p.type === 'trial'); if (trialPhase) { console.log(`Free trial for ${trialPhase.cycleDuration}`); console.log(`Then ${product.localizedPrice}/${product.subscriptionDuration}`); } } ``` -------------------------------- ### Initialize IAPHUB SDK in React Native App Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/configuration.md This snippet demonstrates the complete integration of the IAPHUB SDK within a React Native application. It initializes the SDK, sets device parameters, and adds event listeners for user updates and errors. Ensure environment variables for APP_ID and API_KEY are set. ```typescript import React, { useEffect } from 'react'; import Iaphub from 'react-native-iaphub'; export const IAPProvider = ({ children }) => { useEffect(() => { initializeIAP(); return () => { Iaphub.stop(); }; }, []); const initializeIAP = async () => { try { // Initialize SDK await Iaphub.start({ appId: process.env.IAPHUB_APP_ID, apiKey: process.env.IAPHUB_API_KEY, allowAnonymousPurchase: true, enableStorekitV2: true, lang: 'en' }); // Set device metadata await Iaphub.setDeviceParams({ appVersion: '1.0.0' }); // Add event listeners Iaphub.addEventListener('onUserUpdate', async () => { console.log('Products updated'); }); Iaphub.addEventListener('onError', (err) => { console.error('IAP Error:', err.code, err.message); }); } catch (err) { console.error('IAP initialization failed:', err); } }; return <>{children}; }; ``` -------------------------------- ### Import Default Iaphub Instance Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/modules-overview.md Import the default singleton instance of the Iaphub class. This is the primary way to interact with the SDK. ```typescript import Iaphub from 'react-native-iaphub'; ``` -------------------------------- ### Initiate Purchase Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/product.md Initiates the purchase process for a given product SKU. This method handles the transaction flow and returns a transaction object upon success. ```APIDOC ## buy(sku: string) ### Description Initiates a purchase for the product associated with the provided SKU. ### Method `Iaphub.buy(sku)` ### Parameters #### Path Parameters - **sku** (string) - Required - The SKU of the product to purchase. ### Request Example ```typescript const transaction = await Iaphub.buy('premium_monthly_sku'); ``` ### Response #### Success Response - `transaction` (object) - Details of the completed transaction. #### Error Handling - Throws an error if the purchase fails. ``` -------------------------------- ### Configure Android Subscription Upgrade with Immediate Proration Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/configuration.md For Android purchases, use `prorationMode: 'upgrade_immediate'` to ensure the new subscription price is applied instantly when a user upgrades. This requires `crossPlatformConflict` to be set. ```typescript const transaction = await Iaphub.buy('premium_monthly_sku', { crossPlatformConflict: true, prorationMode: 'upgrade_immediate' }); ``` -------------------------------- ### Configuration and Metadata Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/MANIFEST.md Functions for setting localization, device parameters, and user tags. ```APIDOC ## setLang() ### Description Sets the language for the SDK. ### Method setLang(lang: string) ### Parameters - **lang** (string) - The language code (e.g., 'en', 'fr'). ### Request Example ```javascript await iaphub.setLang('en'); ``` ### Response None explicitly documented. ``` ```APIDOC ## setDeviceParams() ### Description Sets device-specific parameters for the SDK. ### Method setDeviceParams(params: DeviceParams) ### Parameters - **params** (DeviceParams) - An object containing device parameters. ### Request Example ```javascript await iaphub.setDeviceParams({ device_id: '123', platform: 'android' }); ``` ### Response None explicitly documented. ``` ```APIDOC ## setUserTags() ### Description Sets custom tags for user analytics. ### Method setUserTags(tags: UserTags) ### Parameters - **tags** (UserTags) - An object containing user tags. ### Request Example ```javascript await iaphub.setUserTags({ plan: 'premium' }); ``` ### Response None explicitly documented. ``` -------------------------------- ### Product Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/types.md Represents a product available for purchase through the IAPHub SDK. It includes details such as pricing, localization, subscription information, and custom metadata. ```APIDOC ## Product Product available for purchase. ### Interface Definition ```typescript interface Product { readonly id: string; readonly type: string; readonly sku: string; readonly price: number; readonly currency: string | null; readonly localizedPrice: string | null; readonly localizedTitle: string | null; readonly localizedDescription: string | null; readonly alias: string | null; readonly group: string | null; readonly groupName: string | null; readonly subscriptionDuration: string | null; readonly subscriptionIntroPhases: SubscriptionIntroPhase[] | null; readonly metadata: { [key: string]: string }; } ``` ### Fields | Field | Type | Description | |---|---|---| | id | string | Product identifier. | | type | string | Product type (e.g., `subscription`, `consumable`, `non_consumable`). | | sku | string | Store-specific SKU for purchase. | | price | number | Price in currency units. | | currency | string \| null | ISO 4217 currency code (e.g., `USD`). | | localizedPrice | string \| null | Formatted price string (e.g., `$9.99`). | | localizedTitle | string \| null | Localized product name. | | localizedDescription | string \| null | Localized product description. | | alias | string \| null | Custom product alias. | | group | string \| null | Product group identifier. | | groupName | string \| null | Product group name. | | subscriptionDuration | string \| null | ISO 8601 subscription cycle duration (e.g., `P1M` for 1 month). | | subscriptionIntroPhases | SubscriptionIntroPhase[] \| null | Introductory pricing phases (trials, discounts). | | metadata | { [key: string]: string } | Custom key/value product metadata. | **Returned by:** `Iaphub.getProductsForSale()`, `Iaphub.getProducts()` ``` -------------------------------- ### Create an IAP Provider with Context Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/integration-guide.md Set up a React Context Provider to manage IAP state, including initialization, product fetching, and error handling. This provider listens for user and error updates and cleans up listeners on unmount. ```typescript import React, { createContext, useContext, useCallback, useState, useEffect } from 'react'; import Iaphub from 'react-native-iaphub'; const IAPContext = createContext(); export const IAPProvider = ({ children }) => { const [isInitialized, setIsInitialized] = useState(false); const [activeProducts, setActiveProducts] = useState([]); const [productsForSale, setProductsForSale] = useState([]); const [error, setError] = useState(null); useEffect(() => { const initIAP = async () => { try { await Iaphub.start({ appId: 'YOUR_APP_ID', apiKey: 'YOUR_API_KEY' }); // Listen for product changes Iaphub.addEventListener('onUserUpdate', refreshProducts); Iaphub.addEventListener('onError', handleError); // Initial product fetch await refreshProducts(); setIsInitialized(true); } catch (err) { console.error('IAP init failed:', err); setError(err); } }; initIAP(); return () => { Iaphub.removeAllListeners(); Iaphub.stop(); }; }, []); const refreshProducts = useCallback(async () => { try { const { activeProducts, productsForSale } = await Iaphub.getProducts(); setActiveProducts(activeProducts); setProductsForSale(productsForSale); } catch (err) { console.error('Failed to fetch products:', err); setError(err); } }, []); const handleError = useCallback((err) => { console.error('IAP Error:', err); setError(err); }, []); return ( {children} ); }; export const useIAP = () => { const context = useContext(IAPContext); if (!context) { throw new Error('useIAP must be used within IAPProvider'); } return context; }; ``` -------------------------------- ### Show Subscription Management Screen Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/integration-guide.md Call this function to open the native subscription management screen. Requires the product SKU. ```typescript const handleManageSubscriptions = async (sku) => { try { await Iaphub.showManageSubscriptions({ sku }); } catch (err) { console.error('Failed to show subscriptions:', err); } }; ``` -------------------------------- ### Handle Simple Purchase Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/integration-guide.md Initiates a purchase for a given product SKU and handles success or failure based on webhook status. Includes a helper function for purchase error messages. ```typescript import { Alert } from 'react-native'; const handlePurchase = async (productSku) => { try { const transaction = await Iaphub.buy(productSku); if (transaction.webhookStatus === 'success') { Alert.alert('Success', 'Purchase completed!'); grantAccess(); } else if (transaction.webhookStatus === 'failed') { Alert.alert( 'Processing', 'Your purchase is being validated. Access will be granted shortly.' ); } } catch (err) { const errorMessage = getPurchaseErrorMessage(err.code); Alert.alert('Purchase Failed', errorMessage); } }; const getPurchaseErrorMessage = (code) => { const messages = { 'product_already_owned': 'Product already owned. Please restore purchases.', 'user_cancelled': 'Purchase cancelled.', 'billing_unavailable': 'In-app purchases not available.', 'network_error': 'Network error. Please try again.', 'unexpected': 'Purchase failed. Please try again later.' }; return messages[code] || messages['unexpected']; }; ``` -------------------------------- ### Public API Methods Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/modules-overview.md This section lists all the public methods available on the default Iaphub instance, detailing their purpose, parameters, and return types. ```APIDOC ## Public API Surface All public APIs are exported from the default `Iaphub` instance: ### Methods - **`start(opts)`** - Returns: `Promise` - Purpose: Initialize SDK - **`stop()`** - Returns: `Promise` - Purpose: Shut down SDK - **`login(userId)`** - Returns: `Promise` - Purpose: Authenticate user - **`logout()`** - Returns: `Promise` - Purpose: Deauthenticate user - **`getUserId()`** - Returns: `Promise` - Purpose: Get current user ID - **`setLang(lang)`** - Returns: `Promise` - Purpose: Change localization - **`setDeviceParams(params)`** - Returns: `Promise` - Purpose: Set device metadata - **`setUserTags(tags)`** - Returns: `Promise` - Purpose: Set user analytics tags - **`buy(sku, opts)`** - Returns: `Promise` - Purpose: Purchase product - **`restore()`** - Returns: `Promise` - Purpose: Restore previous purchases - **`getActiveProducts(opts)`** - Returns: `Promise` - Purpose: Get owned products - **`getProductsForSale()`** - Returns: `Promise` - Purpose: Get products to sell - **`getProducts(opts)`** - Returns: `Promise` - Purpose: Get all products - **`getBillingStatus()`** - Returns: `Promise` - Purpose: Check billing health - **`presentCodeRedemptionSheet()`** - Returns: `Promise` - Purpose: Show iOS code redemption - **`showManageSubscriptions(opts)`** - Returns: `Promise` - Purpose: Show subscription manager - **`addEventListener(name, callback)`** - Returns: `EmitterSubscription` - Purpose: Register event listener - **`removeEventListener(listener)`** - Returns: `boolean` - Purpose: Unregister listener - **`removeAllListeners()`** - Returns: `void` - Purpose: Clear all listeners ``` -------------------------------- ### getProducts() Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/iaphub.md Retrieves both products for sale and the user's active products. ```APIDOC ## getProducts(opts?: GetProductsOptions) ### Description Retrieves both products for sale and the user's active products. ### Method GET (assumed, as it's a retrieval operation) ### Endpoint /products ### Parameters #### Query Parameters - **includeSubscriptionStates** (string[]) - Optional - List of subscription states to include. ### Response #### Success Response (200) - **productsForSale** (Product[]) - Array of Product objects available for sale. - **activeProducts** (ActiveProduct[]) - Array of ActiveProduct objects owned by the user. ### Response Example { "productsForSale": [ { "productId": "com.example.product1", "localizedTitle": "Product 1", "localizedPrice": "$1.99" } ], "activeProducts": [ { "productId": "com.example.subscription1", "state": "active" } ] } ``` -------------------------------- ### Initiate Purchase Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/iaphub.md Initiates a purchase for a product using its SKU. Handles various purchase outcomes and errors, including user cancellation and existing ownership. ```typescript try { const transaction = await Iaphub.buy('premium_monthly_sku'); console.log('Purchase successful:', transaction.purchase); if (transaction.webhookStatus === 'failed') { // Webhook delivery failed; transaction needs server validation } } catch (err) { if (err.code === 'user_cancelled') { // User cancelled the purchase } else if (err.code === 'product_already_owned') { // Product already owned; user should restore } else { console.error('Purchase failed:', err.message); } } ``` -------------------------------- ### getProductsForSale() Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/iaphub.md Retrieves all products available for purchase from the store. ```APIDOC ## getProductsForSale() ### Description Retrieves all products available for purchase. ### Method GET (assumed, as it's a retrieval operation) ### Endpoint /products ### Parameters None ### Response #### Success Response (200) - **products** (Product[]) - An array of Product objects available for sale. ### Response Example { "products": [ { "productId": "com.example.product1", "localizedTitle": "Product 1", "localizedPrice": "$1.99" } ] } ``` -------------------------------- ### Group Products by Category Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/api-reference/product.md Organizes products fetched from `Iaphub.getProductsForSale()` into groups based on their `groupName` property and logs the products within each group. ```typescript const products = await Iaphub.getProductsForSale(); const grouped = {}; products.forEach(product => { if (!grouped[product.groupName]) { grouped[product.groupName] = []; } grouped[product.groupName].push(product); }); Object.entries(grouped).forEach(([groupName, items]) => { console.log(`${groupName}:`); items.forEach(item => console.log(` - ${item.localizedTitle}`)); }); ``` -------------------------------- ### ShowManageSubscriptionsOptions Source: https://github.com/iaphub/react-native-iaphub/blob/master/_autodocs/types.md Options for configuring the subscription management page. This allows highlighting a specific SKU. ```APIDOC ## ShowManageSubscriptionsOptions Options for the subscription management page. ### Description This interface specifies options for the subscription management page, with the ability to highlight a particular SKU. ### Fields #### sku - **Type**: string - **Required**: No - **Description**: SKU to highlight on the management page. **Used by:** `Iaphub.showManageSubscriptions()` ```