### Start Development Server Source: https://github.com/revenuecat/purchases-js/blob/main/examples/webbilling-demo/README.md Run this command to start the local development server for the web billing demo. ```bash npm run dev ``` -------------------------------- ### Install local development dependencies Source: https://github.com/revenuecat/purchases-js/blob/main/README.md Install project dependencies and build the library for local development using pnpm. ```bash pnpm install pnpm run build:dev ``` -------------------------------- ### Run Storybook Source: https://github.com/revenuecat/purchases-js/blob/main/README.md Start the Storybook development server to view and test UI components. ```bash pnpm run storybook ``` -------------------------------- ### Install Purchases.js SDK Source: https://context7.com/revenuecat/purchases-js/llms.txt Install the Purchases.js SDK using npm, yarn, or pnpm. This snippet also shows how to import the SDK and its required styles for ES modules. ```bash # npm npm install --save @revenuecat/purchases-js # yarn yarn add @revenuecat/purchases-js # pnpm pnpm add @revenuecat/purchases-js ``` ```typescript // ES module import (recommended) import { Purchases } from "@revenuecat/purchases-js"; // Import required styles (purchase UI components) import "@revenuecat/purchases-js/styles"; ``` -------------------------------- ### Install Purchases.js with yarn Source: https://github.com/revenuecat/purchases-js/blob/main/README.md Add the RevenueCat Purchases.js library to your project's dependencies using yarn. ```bash yarn add --save @revenuecat/purchases-js ``` -------------------------------- ### Install Purchases.js with npm Source: https://github.com/revenuecat/purchases-js/blob/main/README.md Add the RevenueCat Purchases.js library to your project's dependencies using npm. ```bash npm install --save @revenuecat/purchases-js ``` -------------------------------- ### Install Xcode Command Line Tools Source: https://github.com/revenuecat/purchases-js/blob/main/fastlane/README.md Ensure you have the latest version of the Xcode command line tools installed before proceeding with Fastlane installation. ```shell xcode-select --install ``` -------------------------------- ### Run Development Server with Fake HTTPS Source: https://github.com/revenuecat/purchases-js/blob/main/examples/webbilling-demo/README.md Start the development server, forcing the use of a specific domain and port for HTTPS support, necessary for testing Apple Pay and Google Pay locally. ```bash sudo npm run dev-fake-https -- --host somedomain.com --port 443 ``` -------------------------------- ### Install Playwright Dependencies Source: https://github.com/revenuecat/purchases-js/blob/main/examples/webbilling-demo/README.md Install Playwright with its dependencies, which is required for running end-to-end tests. ```bash npx playwright install --with-deps ``` -------------------------------- ### Add Localhost to Hosts File Source: https://github.com/revenuecat/purchases-js/blob/main/examples/webbilling-demo/README.md Modify your system's hosts file to resolve a specific domain to localhost. This is part of the setup for testing Apple Pay and Google Pay with local HTTPS. ```bash 127.0.0.1 somedomain.com ``` -------------------------------- ### Configure Production Backend URLs Source: https://github.com/revenuecat/purchases-js/blob/main/examples/webbilling-demo/README.md Set these environment variables in your `.env` file to point the demo to a production or custom backend instead of the default localhost. ```bash VITE_RC_PROXY_URL=https://api.revenuecat.com VITE_RC_EVENTS_URL=https://e.revenue.cat ``` -------------------------------- ### Set up local environment variables for Storybook Source: https://github.com/revenuecat/purchases-js/blob/main/README.md Configure necessary Stripe API keys and account IDs in a `.env.development.local` file for running purchase-related Storybook stories. ```bash VITE_STORYBOOK_PUBLISHABLE_API_KEY="pk_test_1234567890" VITE_STORYBOOK_ACCOUNT_ID="acct_1234567890" ``` -------------------------------- ### purchases.getOfferings Source: https://context7.com/revenuecat/purchases-js/llms.txt Fetches the configured offerings from RevenueCat, including all packages, products, pricing phases, and trial/intro offer details. Optionally filter by currency, offering identifier, or discount code. ```APIDOC ## purchases.getOfferings(params?) ### Description Fetches the configured offerings from RevenueCat, including all packages, products, pricing phases, and trial/intro offer details. Optionally filter by currency, offering identifier, or discount code. ### Method `getOfferings` ### Parameters #### Query Parameters - **offeringIdentifier** (string) - Optional - The identifier of the offering to fetch. Can be `OfferingKeyword.Current`. - **currency** (string) - Optional - Filters offerings by the specified currency (e.g., "EUR"). - **discountCode** (string) - Optional - Applies a discount code to the fetched offerings. ### Request Example ```typescript import { Purchases, OfferingKeyword } from "@revenuecat/purchases-js"; const purchases = Purchases.configure({ apiKey: "rcb_sb_key", appUserId: "user_123" }); // Fetch all offerings const offerings = await purchases.getOfferings(); // Fetch only the current offering, in EUR const { current } = await purchases.getOfferings({ offeringIdentifier: OfferingKeyword.Current, currency: "EUR", }); // Fetch a specific named offering with a discount code applied const discounted = await purchases.getOfferings({ offeringIdentifier: "summer_sale", discountCode: "SUMMER2024", }); ``` ### Response #### Success Response Returns an object containing `current` and `all` offerings. `current` is the current offering, and `all` is a dictionary of all available offerings by their identifier. - **current** (Offering) - The current offering. - **all** ({ [offeringId]: Offering }) - A dictionary of all available offerings. #### Response Example ```json { "current": { "identifier": "default", "serverDescription": "My main offering", "availablePackages": [ { "packageType": "PackageType.Monthly", "webBillingProduct": { "title": "Pro Monthly", "price": { "formattedPrice": "$5.00", "amountMicros": 5000000, "currency": "USD" }, "defaultSubscriptionOption": { "base": { "periodDuration": "P1M" }, "trial": { "periodDuration": "P7D" }, "introPrice": { "price": { "formattedPrice": "$1.99" }, "cycleCount": 3 } } } } ], "monthly": { ... }, // Package object for monthly "annual": { ... } // Package object for annual }, "all": { ... } // Dictionary of all offerings } ``` ``` -------------------------------- ### Link local purchases-js package Source: https://github.com/revenuecat/purchases-js/blob/main/README.md Register the local purchases-js package using `pnpm link` and then link it in a testing project. ```bash pnpm link ``` ```bash pnpm link "@revenuecat/purchases-js" ``` -------------------------------- ### Fetch Product Offerings with RevenueCat JS SDK Source: https://context7.com/revenuecat/purchases-js/llms.txt Fetches configured offerings from RevenueCat. Optionally filter by currency, offering identifier, or discount code. Requires `Purchases.configure` to be called first. ```typescript import { Purchases, OfferingKeyword, PackageType, ProductType, } from "@revenuecat/purchases-js"; const purchases = Purchases.configure({ apiKey: "rcb_sb_key", appUserId: "user_123" }); // Fetch all offerings const offerings = await purchases.getOfferings(); // offerings.current — the current offering // offerings.all — { [offeringId]: Offering } // Fetch only the current offering, in EUR const { current } = await purchases.getOfferings({ offeringIdentifier: OfferingKeyword.Current, currency: "EUR", }); if (current) { console.log(current.identifier); // "default" console.log(current.serverDescription); // "My main offering" for (const pkg of current.availablePackages) { const product = pkg.webBillingProduct; console.log(pkg.packageType); // PackageType.Monthly, etc. console.log(product.title); // "Pro Monthly" console.log(product.price.formattedPrice); // "$5.00" console.log(product.price.amountMicros); // 5000000 console.log(product.price.currency); // "USD" // Subscription phases const subOption = product.defaultSubscriptionOption; if (subOption) { console.log(subOption.base.periodDuration); // "P1M" if (subOption.trial) { console.log(subOption.trial.periodDuration); // "P7D" (free trial) } if (subOption.introPrice) { console.log(subOption.introPrice.price?.formattedPrice); // "$1.99" intro console.log(subOption.introPrice.cycleCount); // 3 } } } // Shortcut accessors const monthly = current.monthly; // Package | null const annual = current.annual; // Package | null } // Fetch a specific named offering with a discount code applied const discounted = await purchases.getOfferings({ offeringIdentifier: "summer_sale", discountCode: "SUMMER2024", }); ``` -------------------------------- ### Run Fastlane Generate Docs Action Source: https://github.com/revenuecat/purchases-js/blob/main/fastlane/README.md Execute the 'generate_docs' action to automatically generate documentation for your project. ```shell [bundle exec] fastlane generate_docs ``` -------------------------------- ### Run tests Source: https://github.com/revenuecat/purchases-js/blob/main/README.md Execute the project's test suite using the pnpm command. ```bash pnpm run test ``` -------------------------------- ### Purchases.configure(config) Source: https://context7.com/revenuecat/purchases-js/llms.txt Initializes the singleton Purchases instance with the provided configuration. This method must be called once before any other SDK method. It accepts a configuration object including your API key, app user ID, and optional HTTP configurations or flags. ```APIDOC ## Purchases.configure(config) — Initialize the SDK Configures the singleton `Purchases` instance. Must be called once before any other SDK method. Accepts a `PurchasesConfig` object with `apiKey`, `appUserId`, and optional `httpConfig` and `flags`. Throws `PurchasesError` for invalid API keys or user IDs. ```typescript import { Purchases, LogLevel, ErrorCode, PurchasesError } from "@revenuecat/purchases-js"; // Recommended object-based configuration const purchases = Purchases.configure({ apiKey: "rcb_sb_your_sandbox_api_key", // rcb_, rcb_sb_, strp_, strp_sb_, pdl_, test_ appUserId: "user_123", httpConfig: { proxyURL: "https://your-proxy.example.com", // optional: proxy for all API requests additionalHeaders: { "X-My-App-Header": "v2" }, // optional: custom headers (non-reserved) }, flags: { autoCollectUTMAsMetadata: true, // auto-attach UTM params as purchase metadata collectAnalyticsEvents: true, // enable behavioural event tracking storeLoadTime: "configuration", // or "purchase_start" — when to preload Stripe }, }); // Anonymous user flow const anonId = Purchases.generateRevenueCatAnonymousAppUserId(); // => "$RCAnonymousID:123e4567e89b12d3a456426614174000" const anonPurchases = Purchases.configure({ apiKey: "rcb_sb_your_sandbox_api_key", appUserId: anonId, }); // Retrieve the shared instance from anywhere else in the app const shared = Purchases.getSharedInstance(); // throws UninitializedPurchasesError if not configured console.log(Purchases.isConfigured()); // true // Error handling for invalid configuration try { Purchases.configure({ apiKey: "bad_key", appUserId: "user_123" }); } catch (e) { if (e instanceof PurchasesError && e.errorCode === ErrorCode.ConfigurationError) { console.error("Bad config:", e.message); } } ``` ``` -------------------------------- ### Initialize Purchases SDK Source: https://context7.com/revenuecat/purchases-js/llms.txt Configure the singleton Purchases instance with your API key and user ID. Supports various configuration options including proxy URLs, custom headers, and analytics flags. Handles anonymous user flows and provides error handling for invalid configurations. ```typescript import { Purchases, LogLevel, ErrorCode, PurchasesError } from "@revenuecat/purchases-js"; // Recommended object-based configuration const purchases = Purchases.configure({ apiKey: "rcb_sb_your_sandbox_api_key", // rcb_, rcb_sb_, strp_, strp_sb_, pdl_, test_ appUserId: "user_123", httpConfig: { proxyURL: "https://your-proxy.example.com", // optional: proxy for all API requests additionalHeaders: { "X-My-App-Header": "v2" }, // optional: custom headers (non-reserved) }, flags: { autoCollectUTMAsMetadata: true, // auto-attach UTM params as purchase metadata collectAnalyticsEvents: true, // enable behavioural event tracking storeLoadTime: "configuration", // or "purchase_start" — when to preload Stripe }, }); // Anonymous user flow const anonId = Purchases.generateRevenueCatAnonymousAppUserId(); // => "$RCAnonymousID:123e4567e89b12d3a456426614174000" const anonPurchases = Purchases.configure({ apiKey: "rcb_sb_your_sandbox_api_key", appUserId: anonId, }); // Retrieve the shared instance from anywhere else in the app const shared = Purchases.getSharedInstance(); // throws UninitializedPurchasesError if not configured console.log(Purchases.isConfigured()); // true // Error handling for invalid configuration try { Purchases.configure({ apiKey: "bad_key", appUserId: "user_123" }); } catch (e) { if (e instanceof PurchasesError && e.errorCode === ErrorCode.ConfigurationError) { console.error("Bad config:", e.message); } } ``` -------------------------------- ### Run E2E Tests (With UI) Source: https://github.com/revenuecat/purchases-js/blob/main/examples/webbilling-demo/README.md Execute the end-to-end tests with a user interface for easier debugging. ```bash npm run test:e2e-ui ``` -------------------------------- ### Run linters and formatters Source: https://github.com/revenuecat/purchases-js/blob/main/README.md Execute Prettier for code formatting and ESLint for linting. ```bash pnpm run prettier pnpm run lint ``` -------------------------------- ### Run E2E Tests (Headless) Source: https://github.com/revenuecat/purchases-js/blob/main/examples/webbilling-demo/README.md Execute the end-to-end tests in headless mode. ```bash npm run test:e2e ``` -------------------------------- ### Configure Purchases.js with UMD Source: https://context7.com/revenuecat/purchases-js/llms.txt Configure the Purchases.js SDK using a UMD bundle in a browser environment. This includes linking the CSS and JavaScript files and initializing the SDK. ```html ``` -------------------------------- ### Offerings and Products Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Fetch available offerings, products, and present paywalls to users. ```APIDOC ## Purchases.getOfferings ### Description Fetches all available offerings for the current user. ### Method `getOfferings(params?: GetOfferingsParams): Promise` ### Parameters #### Request Body - **params** (GetOfferingsParams) - Optional - Parameters for fetching offerings. ``` ```APIDOC ## Purchases.getCurrentOfferingForPlacement ### Description Fetches the current offering for a specific placement. ### Method `getCurrentOfferingForPlacement(placementIdentifier: string, params?: GetOfferingsParams): Promise` ### Parameters #### Request Body - **placementIdentifier** (string) - Required - The identifier of the placement. - **params** (GetOfferingsParams) - Optional - Parameters for fetching offerings. ``` ```APIDOC ## Purchases.presentPaywall ### Description Presents a paywall to the user. ### Method `presentPaywall(paywallParams: PresentPaywallParams): Promise` ### Parameters #### Request Body - **paywallParams** (PresentPaywallParams) - Required - Parameters for presenting the paywall. ``` -------------------------------- ### PresentedOfferingContext Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Context for a presented offering. ```APIDOC export interface PresentedOfferingContext { readonly offeringIdentifier: string; readonly placementIdentifier: string | null; readonly targetingContext: TargetingContext | null; } ``` -------------------------------- ### Set Public API Key for Development Source: https://github.com/revenuecat/purchases-js/blob/main/examples/webbilling-demo/README.md Set your public API key as an environment variable for development. This is required to initialize the SDK. ```bash export VITE_RC_API_KEY = 'your public api key' ``` -------------------------------- ### Fetch Placement-Targeted Offering with RevenueCat JS SDK Source: https://context7.com/revenuecat/purchases-js/llms.txt Returns the offering assigned to a specific placement identifier, respecting RevenueCat's targeting rules. Falls back to the default offering if no placement-specific offering is configured. Requires `Purchases.configure` to be called first. ```typescript import { Purchases } from "@revenuecat/purchases-js"; const purchases = Purchases.configure({ apiKey: "rcb_sb_key", appUserId: "user_123" }); const offering = await purchases.getCurrentOfferingForPlacement("onboarding_paywall"); if (offering) { console.log(offering.identifier); // e.g. "offering_2" const product = offering.availablePackages[0].webBillingProduct; console.log(product.presentedOfferingContext.placementIdentifier); // "onboarding_paywall" console.log(product.presentedOfferingContext.targetingContext?.ruleId); // targeting rule id } else { console.log("No offering for this placement"); } ``` -------------------------------- ### Product Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Represents a product in the store. ```APIDOC export interface Product { // @deprecated readonly currentPrice: Price; readonly defaultNonSubscriptionOption: NonSubscriptionOption | null; readonly defaultPurchaseOption: PurchaseOption; readonly defaultSubscriptionOption: SubscriptionOption | null; readonly description: string | null; // @deprecated } ``` -------------------------------- ### SDK Lifecycle and Utility Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Methods for managing the SDK's lifecycle and utility functions. ```APIDOC ## Purchases.close ### Description Closes the Purchases SDK. This should be called when the application is shutting down. ### Method `close(): void` ``` ```APIDOC ## Purchases.preload ### Description Preloads offerings and products for a faster user experience. ### Method `preload(): Promise` ``` ```APIDOC ## Purchases.isSandbox ### Description Checks if the SDK is running in a sandbox environment. ### Method `isSandbox(): boolean` ``` -------------------------------- ### Run Fastlane GitHub Release Action Source: https://github.com/revenuecat/purchases-js/blob/main/fastlane/README.md Use the 'github_release' action to create a GitHub release for your project. ```shell [bundle exec] fastlane github_release ``` -------------------------------- ### Trigger Purchase Flow with `purchases.purchase()` Source: https://context7.com/revenuecat/purchases-js/llms.txt Use this to present the payment UI for a specific package. It handles routing to the correct payment processor. Configure options like customer email, locale, discount codes, and metadata. Handles success and failure outcomes, including user cancellation. ```typescript import { Purchases, ErrorCode, PurchasesError, } from "@revenuecat/purchases-js"; const purchases = Purchases.configure({ apiKey: "rcb_sb_key", appUserId: "user_123" }); const { current } = await purchases.getOfferings(); const pkg = current!.monthly!; // Modal mode (no htmlTarget — appended to body automatically) try { const result = await purchases.purchase({ rcPackage: pkg, customerEmail: "jane@example.com", // optional — skip the email step selectedLocale: "en-US", // optional — locale for checkout UI skipSuccessPage: false, // optional — skip built-in success screen showDiscountCodeField: true, // optional — show a discount code input discountCode: "PROMO10", // optional — pre-fill discount code metadata: { campaign: "spring_2025" }, // optional — arbitrary purchase metadata onDiscountCodeChanged: (code) => { console.log("Discount code applied:", code); }, }); console.log(result.customerInfo.originalAppUserId); console.log(result.storeTransaction.storeTransactionId); console.log(result.operationSessionId); if (result.redemptionInfo?.redeemUrl) { console.log("Redeem at:", result.redemptionInfo.redeemUrl); } } catch (e) { if (e instanceof PurchasesError) { if (e.errorCode === ErrorCode.UserCancelledError) { console.log("User cancelled"); } else if (e.errorCode === ErrorCode.ProductAlreadyPurchasedError) { console.warn("Already subscribed"); } else { console.error(`Purchase failed [${e.errorCode}]: ${e.message}`); if (e.underlyingErrorMessage) console.error(e.underlyingErrorMessage); if (e.extra?.statusCode) console.error("HTTP status:", e.extra.statusCode); } } } ``` ```typescript // Embedded mode — render checkout into a specific DOM element const container = document.getElementById("checkout-container")!; const embeddedResult = await purchases.purchase({ rcPackage: pkg, htmlTarget: container, }); ``` -------------------------------- ### Verify workspace override resolution Source: https://github.com/revenuecat/purchases-js/blob/main/README.md Check if the `@revenuecat/purchases-ui-js` package has been correctly linked using the local path. ```bash pnpm why @revenuecat/purchases-ui-js ``` -------------------------------- ### Fetch Customer Info & Entitlements with purchases.getCustomerInfo() Source: https://context7.com/revenuecat/purchases-js/llms.txt Retrieves the current user's complete subscription and entitlement status. Use this to display active entitlements, subscription details, and transaction history. ```typescript import { Purchases } from "@revenuecat/purchases-js"; const purchases = Purchases.configure({ apiKey: "rcb_sb_key", appUserId: "user_123" }); const info = await purchases.getCustomerInfo(); // Entitlements const active = info.entitlements.active; if ("pro_access" in active) { const ent = active["pro_access"]; console.log(ent.isActive); // true console.log(ent.expirationDate); // Date | null console.log(ent.periodType); // "normal" | "trial" | "intro" | "prepaid" console.log(ent.store); // "rc_billing" | "stripe" | "paddle" | ... console.log(ent.willRenew); // true console.log(ent.isSandbox); // true in sandbox } // Active subscriptions console.log([...info.activeSubscriptions]); // ["monthly_pro"] // Subscription details const sub = info.subscriptionsByProductIdentifier["monthly_pro"]; if (sub) { console.log(sub.expiresDate); // Date | null console.log(sub.isActive); // boolean console.log(sub.managementURL); // URL to manage subscription console.log(sub.ownershipType); // "PURCHASED" | "FAMILY_SHARED" | "UNKNOWN" console.log(sub.billingIssuesDetectedAt); // Date | null } // Non-subscription (consumable) transactions for (const tx of info.nonSubscriptionTransactions) { console.log(tx.productIdentifier, tx.purchaseDate); } console.log(info.managementURL); // general management URL console.log(info.originalAppUserId); // original user id console.log(info.firstSeenDate); // Date of first seen ``` -------------------------------- ### Configure pnpm workspace override for local UI development Source: https://github.com/revenuecat/purchases-js/blob/main/README.md Use a `pnpm-workspace.yaml` override to point the `purchases-js` project to a local `purchases-ui-js` sibling directory for integrated development. ```yaml overrides: "@revenuecat/purchases-ui-js": "link:../purchases-ui-js" ``` -------------------------------- ### purchases.getCustomerInfo() Source: https://context7.com/revenuecat/purchases-js/llms.txt Fetches the current user's complete subscription and entitlement status from RevenueCat. This method provides detailed information about active subscriptions, entitlements, and past transactions. ```APIDOC ## purchases.getCustomerInfo() ### Description Returns the current user's full subscription and entitlement state from RevenueCat. ### Method `await purchases.getCustomerInfo()` ### Parameters None ### Response - **entitlements**: Object containing active entitlements. - **activeSubscriptions**: Array of active subscription product identifiers. - **subscriptionsByProductIdentifier**: Object mapping product identifiers to subscription details. - **nonSubscriptionTransactions**: Array of non-subscription transaction details. - **managementURL**: URL to manage the user's subscriptions. - **originalAppUserId**: The original user ID associated with the account. - **firstSeenDate**: The date the user was first seen. ### Request Example ```typescript const info = await purchases.getCustomerInfo(); ``` ### Response Example ```json { "entitlements": { "active": { "pro_access": { "isActive": true, "expirationDate": "2024-12-31T23:59:59Z", "periodType": "normal", "store": "app_store", "willRenew": true, "isSandbox": false } } }, "activeSubscriptions": ["monthly_pro"], "subscriptionsByProductIdentifier": { "monthly_pro": { "expiresDate": "2024-12-31T23:59:59Z", "isActive": true, "managementURL": "https://buy.itunes.apple.com/...".", "ownershipType": "PURCHASED", "billingIssuesDetectedAt": null } }, "nonSubscriptionTransactions": [], "managementURL": "https://app.revenuecat.com/...".", "originalAppUserId": "user_123", "firstSeenDate": "2023-01-01T00:00:00Z" } ``` ``` -------------------------------- ### Run Fastlane Bump Locally Source: https://github.com/revenuecat/purchases-js/blob/main/RELEASING.md Execute the Fastlane bump command locally to initiate the release process. This requires a `fastlane/.env` file with your GitHub API token and may prompt for version input and changelog updates. ```bash bundle exec fastlane bump github_rate_limit:10 ``` -------------------------------- ### Run type checking Source: https://github.com/revenuecat/purchases-js/blob/main/README.md Perform static type checking on the project using the `svelte-check` command. ```bash pnpm run test:typecheck pnpm run svelte-check ``` -------------------------------- ### GetOfferingsParams Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Parameters for fetching offerings. ```APIDOC ## Interface: GetOfferingsParams ### Description Parameters for fetching offerings. ### Properties - **currency** (string) - The currency to filter offerings by. - **offeringIdentifier** (string | OfferingKeyword) - The identifier of the offering to fetch. ``` -------------------------------- ### purchases.preload() Source: https://context7.com/revenuecat/purchases-js/llms.txt Fetches and caches branding information in advance to minimize latency on the initial `purchase()` call. This method is safe to call multiple times, and concurrent calls are automatically deduplicated. ```APIDOC ## purchases.preload() — Preload Branding Resources Fetches and caches branding information early to reduce latency on the first `purchase()` call. Safe to call multiple times; concurrent calls are deduplicated. ```typescript import { Purchases } from "@revenuecat/purchases-js"; const purchases = Purchases.configure({ apiKey: "rcb_sb_key", appUserId: "user_123" }); // Call during app startup, before the user clicks "Buy" await purchases.preload(); // Later — purchase UI renders immediately with cached branding const result = await purchases.purchase({ rcPackage: somePackage }); ``` ``` -------------------------------- ### PlatformInfo Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Information about the platform the SDK is running on. ```APIDOC export interface PlatformInfo { readonly flavor: string; readonly version: string; } ``` -------------------------------- ### Offerings Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Represents all available offerings. ```APIDOC export interface Offerings { readonly all: { [offeringId: string]: Offering; }; readonly current: Offering | null; } ``` -------------------------------- ### PresentPaywallParams Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Parameters for presenting a paywall. ```APIDOC export interface PresentPaywallParams { readonly customerEmail?: string; readonly customVariables?: CustomVariables; readonly discountCode?: string; readonly hideBackButtons?: boolean; readonly htmlTarget?: HTMLElement; readonly listener?: PaywallListener; readonly offering?: Offering; readonly onBack?: (closePaywall: () => void) => void; readonly onDiscountCodeChanged?: (discountCode: string | null) => void; readonly onNavigateToUrl?: (url: string) => void; // @deprecated readonly onPurchaseError?: (error: Error) => void; readonly onVisitCustomerCenter?: () => void; readonly purchaseHtmlTarget?: HTMLElement; readonly selectedLocale?: string; readonly showDiscountCodeField?: boolean; } ``` -------------------------------- ### Offering Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Represents an offering of products available for purchase. ```APIDOC export interface Offering { readonly annual: Package | null; readonly availablePackages: Package[]; readonly hasPaywall: boolean; readonly identifier: string; readonly lifetime: Package | null; readonly metadata: { [key: string]: unknown; } | null; readonly monthly: Package | null; readonly packagesById: { [key: string]: Package; }; readonly serverDescription: string; readonly sixMonth: Package | null; readonly threeMonth: Package | null; readonly twoMonth: Package | null; readonly webCheckoutURL?: string | null; readonly weekly: Package | null; /* Excluded from this release type: paywallComponents */ /* Excluded from this release type: uiConfig */ } ``` -------------------------------- ### Reinstall dependencies after workspace override Source: https://github.com/revenuecat/purchases-js/blob/main/README.md After modifying `pnpm-workspace.yaml`, reinstall dependencies from the `purchases-js` root to apply the changes. ```bash pnpm install ``` -------------------------------- ### Run Fastlane Release Action Source: https://github.com/revenuecat/purchases-js/blob/main/fastlane/README.md The 'release' action creates a GitHub release and publishes both react-native-purchases and react-native-purchases-ui. ```shell [bundle exec] fastlane release ``` -------------------------------- ### purchases.getVirtualCurrencies() Source: https://context7.com/revenuecat/purchases-js/llms.txt Retrieves the current subscriber's virtual currency balances. Results are cached for 5 minutes. You can also read from the in-memory cache synchronously or invalidate the cache. ```APIDOC ## purchases.getVirtualCurrencies() ### Description Retrieves the current subscriber's virtual currency balances. Results are cached for 5 minutes. ### Method `getVirtualCurrencies()` ### Parameters None ### Request Example ```typescript import { Purchases } from "@revenuecat/purchases-js"; const purchases = Purchases.configure({ apiKey: "rcb_sb_key", appUserId: "user_123" }); // Fetch from network (or cache) const currencies = await purchases.getVirtualCurrencies(); for (const [code, vc] of Object.entries(currencies.all)) { console.log(`${vc.name} (${code}): ${vc.balance}`); console.log(vc.serverDescription); // "It's gold" | null } // Read from in-memory cache synchronously (returns null if not yet fetched) const cached = purchases.getCachedVirtualCurrencies(); if (cached) { console.log(cached.all["GLD"].balance); } // Invalidate cache (e.g. after spending currency via your backend) purchases.invalidateVirtualCurrenciesCache(); // Next call will fetch fresh data const fresh = await purchases.getVirtualCurrencies(); ``` ### Response #### Success Response Returns an object containing virtual currency balances. The structure includes `all`, an object where keys are currency codes and values are currency details (name, balance, serverDescription). #### Response Example ```json { "all": { "GLD": { "name": "Gold", "balance": 100, "serverDescription": "It's gold" } } } ``` ``` -------------------------------- ### Run Fastlane Bump Action Source: https://github.com/revenuecat/purchases-js/blob/main/fastlane/README.md Use the 'bump' action to replace version numbers, update the changelog, and create a pull request. ```shell [bundle exec] fastlane bump ``` -------------------------------- ### Purchases Configuration Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Configure the Purchases SDK with your API key and optionally set an app user ID, HTTP configuration, and feature flags. ```APIDOC ## Purchases.configure ### Description Configures the RevenueCat SDK. This method must be called before any other. ### Method `static configure(config: PurchasesConfig): Purchases` ### Parameters #### Request Body - **config** (PurchasesConfig) - Required - Configuration object for the SDK. - **apiKey** (string) - Required - Your RevenueCat API key. - **appUserId** (string) - Optional - The unique identifier for the current user. - **httpConfig** (HttpConfig) - Optional - Configuration for HTTP requests. - **flags** (FlagsConfig) - Optional - Configuration for feature flags. ### Method `static configure(apiKey: string, appUserId: string, httpConfig?: HttpConfig, flags?: FlagsConfig): Purchases` ### Parameters #### Path Parameters - **apiKey** (string) - Required - Your RevenueCat API key. - **appUserId** (string) - Optional - The unique identifier for the current user. - **httpConfig** (HttpConfig) - Optional - Configuration for HTTP requests. - **flags** (FlagsConfig) - Optional - Configuration for feature flags. ``` -------------------------------- ### Present Paywall with `purchases.presentPaywall()` Source: https://context7.com/revenuecat/purchases-js/llms.txt Renders a dashboard-configured paywall into a DOM element or as a full-screen overlay. Requires the offering to have a paywall attached. Supports custom listeners for purchase events, back buttons, URL navigation, and customer center links. ```typescript import { Purchases, ErrorCode, PurchasesError, type PaywallListener, } from "@revenuecat/purchases-js"; const purchases = Purchases.configure({ apiKey: "rcb_sb_key", appUserId: "user_123" }); const { current } = await purchases.getOfferings(); const listener: PaywallListener = { onPurchaseStarted: (pkg) => console.log("Purchase started for:", pkg.identifier), onPurchaseCancelled: () => console.log("User cancelled from paywall"), onPurchaseError: (error) => console.error("Paywall purchase error:", error), }; try { const result = await purchases.presentPaywall({ offering: current ?? undefined, // omit to use current offering automatically htmlTarget: document.getElementById("paywall-root") ?? undefined, customerEmail: "jane@example.com", selectedLocale: "fr", // locale override for paywall copy hideBackButtons: false, showDiscountCodeField: true, customVariables: { plan_name: "Pro" }, // inject into paywall template variables listener, onBack: (closePaywall) => { // Custom back-button behaviour; call closePaywall() to dismiss if (confirm("Leave paywall?")) closePaywall(); }, onNavigateToUrl: (url) => { // Override URL navigation (terms, privacy links) window.open(url, "_blank"); }, onVisitCustomerCenter: () => { // Handle "manage subscription" tap window.location.href = "/account"; }, }); console.log("Purchased package:", result.selectedPackage.identifier); console.log("Customer info:", result.customerInfo); } catch (e) { if (e instanceof PurchasesError && e.errorCode === ErrorCode.UserCancelledError) { console.log("Paywall dismissed without purchase"); } } ``` -------------------------------- ### PricingPhase Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Represents a pricing phase for a subscription. ```APIDOC export interface PricingPhase { readonly cycleCount: number; readonly period: Period | null; readonly periodDuration: string | null; readonly price: Price | null; readonly pricePerMonth: Price | null; readonly pricePerWeek: Price | null; readonly pricePerYear: Price | null; } ``` -------------------------------- ### Render Stripe Form with RCBilling Source: https://github.com/revenuecat/purchases-js/blob/main/test.html Use this snippet to initialize RCBilling and render a payment form for a specific product. Ensure the DOM is fully loaded before attempting to render the form. The form rendering is delayed by 3 seconds. ```javascript document.addEventListener("DOMContentLoaded", function () { var billing = new RCBilling( "web\_tFpmIVwEGKNprbMOyiRRzZAbzIHX", "test\_rcbilling", ); setTimeout(() => { billing.renderForm( document.getElementById("payment-form"), "monthly.product\_1234", ); }, 3000); }); ``` -------------------------------- ### Fetch Virtual Currencies with Purchases.js Source: https://context7.com/revenuecat/purchases-js/llms.txt Retrieves virtual currency balances for the current subscriber. Results are cached for 5 minutes. Use `getCachedVirtualCurrencies()` for synchronous access to the cache and `invalidateVirtualCurrenciesCache()` to force a fresh fetch. ```typescript import { Purchases } from "@revenuecat/purchases-js"; const purchases = Purchases.configure({ apiKey: "rcb_sb_key", appUserId: "user_123" }); // Fetch from network (or cache) const currencies = await purchases.getVirtualCurrencies(); for (const [code, vc] of Object.entries(currencies.all)) { console.log(`${vc.name} (${code}): ${vc.balance}`); // e.g. "Gold (GLD): 100" console.log(vc.serverDescription); // "It's gold" | null } // Read from in-memory cache synchronously (returns null if not yet fetched) const cached = purchases.getCachedVirtualCurrencies(); if (cached) { console.log(cached.all["GLD"].balance); } // Invalidate cache (e.g. after spending currency via your backend) purchases.invalidateVirtualCurrenciesCache(); // Next call will fetch fresh data const fresh = await purchases.getVirtualCurrencies(); ``` -------------------------------- ### Preload Branding Resources Source: https://context7.com/revenuecat/purchases-js/llms.txt Fetch and cache branding information early to improve the performance of the first `purchase()` call. This function is safe to call multiple times and handles concurrent calls efficiently. ```typescript import { Purchases } from "@revenuecat/purchases-js"; const purchases = Purchases.configure({ apiKey: "rcb_sb_key", appUserId: "user_123" }); // Call during app startup, before the user clicks "Buy" await purchases.preload(); // Later — purchase UI renders immediately with cached branding const result = await purchases.purchase({ rcPackage: somePackage }); ``` -------------------------------- ### Customer Information and Entitlements Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Retrieve customer information, check entitlements, and manage virtual currency. ```APIDOC ## Purchases.getCustomerInfo ### Description Fetches the latest customer information. ### Method `getCustomerInfo(): Promise` ``` ```APIDOC ## Purchases.isEntitledTo ### Description Checks if the user is entitled to a specific entitlement. ### Method `isEntitledTo(entitlementIdentifier: string): Promise` ### Parameters #### Request Body - **entitlementIdentifier** (string) - Required - The identifier of the entitlement to check. ``` ```APIDOC ## Purchases.getVirtualCurrencies ### Description Fetches the user's virtual currency balance. ### Method `getVirtualCurrencies(): Promise` ``` ```APIDOC ## Purchases.getCachedVirtualCurrencies ### Description Returns the cached virtual currency balance. ### Method `getCachedVirtualCurrencies(): VirtualCurrencies | null` ``` ```APIDOC ## Purchases.invalidateVirtualCurrenciesCache ### Description Invalidates the cache for virtual currency balances. ### Method `invalidateVirtualCurrenciesCache(): void` ``` -------------------------------- ### FlagsConfig Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Configuration options for SDK flags. ```APIDOC ## Interface: FlagsConfig ### Description Configuration options for SDK flags. ### Properties - **autoCollectUTMAsMetadata** (boolean) - Whether to automatically collect UTM parameters as metadata. - **collectAnalyticsEvents** (boolean) - Whether to collect analytics events. - **storeLoadTime** (StoreLoadTime) - Configuration for store load time. ``` -------------------------------- ### Set E2E Test API Keys Source: https://github.com/revenuecat/purchases-js/blob/main/examples/webbilling-demo/README.md Configure the necessary environment variables with your e2e test public API keys before running end-to-end tests. ```bash export VITE_RC_NON_TAX_E2E_API_KEY = 'your e2e tests public api key' export VITE_RC_TAX_E2E_API_KEY = 'your e2e tests public api key' export VITE_RC_STRIPE_CHECKOUT_E2E_API_KEY = 'your stripe checkout e2e tests public api key' ``` -------------------------------- ### purchases.close() Source: https://context7.com/revenuecat/purchases-js/llms.txt Disposes the current `Purchases` singleton, flushes the events tracker, and allows `configure()` to be called again. This is useful for scenarios like user logout. ```APIDOC ## purchases.close() ### Description Disposes the current `Purchases` singleton, flushes the events tracker, and allows `configure()` to be called again. ### Method `close()` ### Parameters None ### Request Example ```typescript import { Purchases } from "@revenuecat/purchases-js"; const purchases = Purchases.configure({ apiKey: "rcb_sb_key", appUserId: "user_123" }); console.log(Purchases.isConfigured()); // true purchases.close(); console.log(Purchases.isConfigured()); // false // Can now reconfigure, e.g. after logout ``` ### Response This method does not return a value. ``` -------------------------------- ### Package Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Represents a package within an offering. ```APIDOC export interface Package { readonly identifier: string; readonly packageType: PackageType; // @deprecated readonly rcBillingProduct: Product; readonly webBillingProduct: Product; readonly webCheckoutURL?: string | null; } ``` -------------------------------- ### Run Fastlane Tag Current Branch Action Source: https://github.com/revenuecat/purchases-js/blob/main/fastlane/README.md Tag the current branch with the current version number using the 'tag_current_branch' action. ```shell [bundle exec] fastlane tag_current_branch ``` -------------------------------- ### SubscriptionOption Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Represents a subscription option available for purchase, including base pricing, introductory offers, and trials. ```APIDOC export interface SubscriptionOption extends PurchaseOption { readonly base: PricingPhase; readonly introPrice: PricingPhase | null; readonly trial: PricingPhase | null; } ``` -------------------------------- ### Price Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Represents a price. ```APIDOC export interface Price { // @deprecated readonly amount: number; readonly amountMicros: number; readonly currency: string; readonly formattedPrice: string; } ``` -------------------------------- ### Run Fastlane Automatic Bump Action Source: https://github.com/revenuecat/purchases-js/blob/main/fastlane/README.md The 'automatic_bump' action automates version bumping, version number replacement, changelog updates, and pull request creation. ```shell [bundle exec] fastlane automatic_bump ``` -------------------------------- ### PaywallListener Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Listener for paywall events. ```APIDOC export interface PaywallListener { onPurchaseCancelled?: () => void; onPurchaseError?: (error: Error) => void; onPurchaseStarted?: (rcPackage: Package) => void; } ``` -------------------------------- ### Trigger a new release Source: https://github.com/revenuecat/purchases-js/blob/main/README.md Manually trigger a new version release using the `fastlane` tool, which will create a PR and hold a job in CircleCI for approval. ```bash bundle exec fastlane bump ``` -------------------------------- ### CustomerInfo Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Contains information about the customer's purchases and subscriptions. ```APIDOC ## Interface: CustomerInfo ### Description Contains information about the customer's purchases and subscriptions. ### Properties - **activeSubscriptions** (Set) - A set of active subscription identifiers. - **allExpirationDatesByProduct** ({ [productIdentifier: string]: Date | null }) - A map of product identifiers to their expiration dates. - **allPurchaseDatesByProduct** ({ [productIdentifier: string]: Date | null }) - A map of product identifiers to their purchase dates. - **entitlements** (EntitlementInfos) - Information about the customer's entitlements. - **firstSeenDate** (Date) - The date the customer was first seen. - **managementURL** (string | null) - The URL for managing the customer's subscriptions. - **nonSubscriptionTransactions** (NonSubscriptionTransaction[]) - An array of non-subscription transactions. - **originalAppUserId** (string) - The original app user ID. - **originalPurchaseDate** (Date | null) - The original purchase date. - **requestDate** (Date) - The date the request was made. - **subscriptionsByProductIdentifier** ({ [productId: string]: SubscriptionInfo }) - A map of product identifiers to their subscription information. ``` -------------------------------- ### HttpConfig Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Configuration for HTTP requests. ```APIDOC ## Interface: HttpConfig ### Description Configuration for HTTP requests. ### Properties - **additionalHeaders** (Record) - Additional headers to include in requests. - **proxyURL** (string) - The URL for a proxy server. ``` -------------------------------- ### UninitializedPurchasesError Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md An error class indicating that the Purchases SDK has not been initialized. ```APIDOC export class UninitializedPurchasesError extends Error { constructor(); } ``` -------------------------------- ### Set Paddle API Key for Paddle Flow Source: https://github.com/revenuecat/purchases-js/blob/main/examples/webbilling-demo/README.md When using Paddle, set your Paddle API key as the environment variable. The SDK automatically detects this and routes to the Paddle flow. ```bash export VITE_RC_API_KEY = 'your paddle api key' ``` -------------------------------- ### OfferingKeyword Enum Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Keywords for referencing offerings. ```APIDOC export enum OfferingKeyword { Current = "current" } ``` -------------------------------- ### Tear Down Purchases.js SDK Instance Source: https://context7.com/revenuecat/purchases-js/llms.txt Disposes the current `Purchases` singleton, flushes the events tracker, and allows `configure()` to be called again. This is useful for scenarios like user logout. ```typescript import { Purchases } from "@revenuecat/purchases-js"; const purchases = Purchases.configure({ apiKey: "rcb_sb_key", appUserId: "user_123" }); console.log(Purchases.isConfigured()); // true purchases.close(); console.log(Purchases.isConfigured()); // false // Can now reconfigure, e.g. after logout ``` -------------------------------- ### BrandingAppearance Interface Source: https://github.com/revenuecat/purchases-js/blob/main/api-report/purchases-js.api.md Defines the appearance properties for branding elements within the SDK. ```APIDOC ## Interface: BrandingAppearance ### Description Defines the appearance properties for branding elements within the SDK. ### Properties - **color_accent** (string) - The accent color. - **color_buttons_primary** (string) - The primary button color. - **color_error** (string) - The error color. - **color_form_bg** (string) - The background color for forms. - **color_page_bg** (string) - The page background color. - **color_product_info_bg** (string) - The background color for product information. - **font** (string) - The font family to use. - **shapes** ("default" | "rectangle" | "rounded" | "pill") - The shape style for UI elements. - **show_product_description** (boolean) - Whether to display the product description. ```