npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-iaptic

v2.0.0

Published

React Native In-App Purchase library with Iaptic receipt validation

Readme

Iaptic React Native SDK

npm version npm downloads types included License: MIT Made by Iaptic

Drop-in subscription paywall and server-validated in-app purchases for React Native, backed by the Iaptic service. Works on iOS (StoreKit) and Android (Google Play Billing), with first-class TypeScript support.

What is Iaptic? Iaptic is a hosted receipt-validation and subscription-management service. The SDK never trusts a local receipt — every purchase is verified server-side. Learn more →

Table of Contents

✨ Features

  • 🛒 Unified iOS + Android purchasing API
  • 🔄 Subscription tracking with renewal events
  • 🔒 Server-side receipt validation via Iaptic
  • 🎨 Themable drop-in paywall (IapticSubscriptionView)
  • 📦 Product catalog with entitlements model
  • 🛡 Typed errors with localized messages
  • 🪙 Optional token/credit tracking (IapticTokensManager)
  • ⚛️ First-class TypeScript types

Requirements

| Requirement | Version | |---|---| | React Native | ≥ 0.71 (tested through 0.85) | | Expo SDK | ≥ 49 (new architecture supported on SDK 55+) | | iOS deployment target | 13.0 | | Android minSdkVersion | 24 | | Node | ≥ 18 | | TypeScript | ≥ 4.7 (types ship with the package) | | @iaptic/react-native-iap | ^13.0.0 (peer) | | react | ≥ 17 (peer) | | @react-native-async-storage/async-storage | optional — ^3.1.0 or ~2.1.0 (only if using IapticTokensManager) |

Installation

react-native-iaptic requires @iaptic/react-native-iap, an Iaptic-maintained fork of [email protected] with GPBL V9 support, the iOS new-architecture pod fix, and the Kotlin currentActivity fix baked in. See Why the fork? below.

npm install @iaptic/react-native-iap react-native-iaptic
# iOS only
cd ios && pod install && cd ..

# Only if using IapticTokensManager (consumable token tracking):
npm install @react-native-async-storage/async-storage@^3.1.0

Expo

Add the config plugin to your app.json / app.config.js so the Android missingDimensionStrategy (Play Store flavor) is wired up at prebuild time:

// app.config.js
export default {
  expo: {
    plugins: [
      ['@iaptic/react-native-iap', { paymentProvider: 'Play Store' }]
    ],
    // ...
  },
};

Quick Start

import { IapticRN } from 'react-native-iaptic';

IapticRN.initialize({
  appName: 'app.example.com',
  publicKey: 'YOUR_PUBLIC_KEY',
  iosBundleId: 'com.yourcompany.app',
  products: [
    { id: 'premium_monthly', type: 'paid subscription', entitlements: ['premium'] },
    { id: 'coins_100',       type: 'consumable',        tokenType: 'coins', tokenValue: 100 },
  ],
});

That's the minimum needed to load products. From here you can either drop in the prebuilt subscription UI, or wire up the manual purchase flow yourself.

Drop-in Subscription UI

IapticSubscriptionView is a full-screen subscription picker with built-in purchase, restore, and active-subscription management. Render it once near your app root and open it on demand.

<IapticSubscriptionView
  entitlementLabels={{
    premium: {
      label: 'Premium Features',
      detail: 'Exclusive content and advanced tools',
    },
  }}
  onPurchaseComplete={() => {
    setEntitlements(IapticRN.listEntitlements());
  }}
  termsUrl="https://yourdomain.com/terms"
/>

The component automatically handles landscape/portrait layouts, localization, purchase states, active-subscription management, and receipt validation.

Props reference

| Prop | Type | Description | |------|------|-------------| | entitlementLabels | Record<string, { label: string, detail?: string }> | Labels and descriptions for each entitlement | | onPurchaseComplete | () => void | Callback after successful purchase | | termsUrl | string | URL for terms & conditions | | theme | IapticTheme | Customize colors — see IapticTheme | | styles | Partial<IapticSubscriptionViewStyles> | Per-element style overrides — see IapticSubscriptionViewStyles |

Customization

<IapticSubscriptionView
  styles={{
    productCard: { backgroundColor: '#FFFFFF', borderRadius: 12 },
    ctaButton:   { backgroundColor: '#4CAF50' },
  }}
/>

For the full list of overridable style slots, see IapticSubscriptionViewStyles.

Core Concepts

Product definitions

Products can be subscriptions, consumables, or non-consumables. Each can grant one or more entitlements:

IapticRN.setProductDefinitions([
  // Subscription that unlocks premium features
  { id: 'premium_monthly', type: 'paid subscription', entitlements: ['premium'] },

  // Non-consumable that unlocks a specific feature
  { id: 'dark_theme', type: 'non consumable', entitlements: ['cool_feature'] },

  // Consumable tokens / currency
  { id: 'coins_100', type: 'consumable', tokenType: 'coins', tokenValue: 100 },
]);

Purchase flow

try {
  await IapticRN.order(productOffer);
} catch (error) {
  showError(error);
}

Restore purchases

try {
  await IapticRN.restorePurchases((processed, total) => {
    console.log(`Processed ${processed} of ${total} purchases`);
  });
} catch (error) {
  showError(error);
}

Event handling

IapticRN.addEventListener('subscription.updated', (reason, purchase) => {
  console.log(`Subscription ${purchase.id} ${reason}`);
});

IapticRN.addEventListener('pendingPurchase.updated', (pendingPurchase) => {
  console.log(`Purchase ${pendingPurchase.productId} is now ${pendingPurchase.status}`);
});

IapticRN.addEventListener('purchase.updated', (purchase) => {
  console.log(`Purchase ${purchase.id} ${purchase.status}`);
});

Feature access control

if (IapticRN.checkEntitlement('premium')) {
  showPremiumContent();
} else {
  showUpgradePrompt();
}

// All currently active entitlements
const unlocked = IapticRN.listEntitlements(); // ['basic', 'premium', 'cool_feature']

Manual Purchase Flow

If you don't want the drop-in UI, drive purchases yourself:

const offer = IapticRN.getProduct('premium_monthly')?.offers[0];
if (offer) {
  await IapticRN.order(offer);
}

if (IapticRN.checkEntitlement('premium')) {
  // Unlock premium features
}

Error Handling

function showError(error: Error | IapticError) {
  if (error instanceof IapticError) {
    trackAnalyticsEvent(error.code);
    if (error.severity === IapticSeverity.INFO) {
      console.log('Info:', error.localizedMessage);
      return;
    }
    Alert.alert(error.localizedTitle, error.localizedMessage);
  } else {
    Alert.alert('Unknown error', error.message);
  }
}

Troubleshooting

  • Products won't load on iOS — verify your Xcode project has the In-App Purchase capability enabled (Xcode → Project → Targets → your app → Signing & Capabilities → + Capability → In-App Purchase).

  • iOS build fails on React Native ≥ 0.83 / Expo SDK ≥ 55 with Unable to find a specification for RCT-Folly depended upon by RNIap — you're depending on upstream react-native-iap instead of @iaptic/react-native-iap. Switch to the fork (see Installation) and the error goes away. Background: Why the fork?.

  • Android build fails with Unresolved reference 'currentActivity' — bump @iaptic/react-native-iap to ^13.0.0, which contains GPBL V9 support and the Kotlin fix for RN 0.83+ / new architecture.

  • Android Gradle resolution fails inside @react-native-async-storage/async-storage — versions 2.2.03.0.2 are broken on Android due to an unpublished Maven artifact. Use ^3.1.0 or stay on ~2.1.0. See release notes for details.

For more, see INTEGRATION_GUIDE.md → Troubleshooting.

Upgrading

From 1.3.x → 2.0.0

  • Bump @iaptic/react-native-iap to ^13.0.0 for Google Play Billing Library V9 support. This is a breaking change — the fork now requires GPBL 9.0.0 and drops the getPurchaseHistory API (removed in GPBL V9). Consumers pinning to @iaptic/[email protected] can stay on [email protected].
  • Install @react-native-async-storage/async-storage explicitly if (and only if) you use IapticTokensManager. It is now an optional peer dependency.

From 1.2.x → 1.3.0

  • Install @react-native-async-storage/async-storage explicitly if (and only if) you use IapticTokensManager. It is now an optional peer dependency.
  • Bump @iaptic/react-native-iap to ^12.16.6 to pick up the Kotlin currentActivity fix on RN 0.83+.

From 1.0.x → 1.1+

  • Install @iaptic/react-native-iap explicitly — it moved from a regular dependency to a peer dependency.
  • The JavaScript API surface and Expo withIAP plugin behaviour are identical to upstream [email protected].

See RELEASE_NOTES.md for the full changelog.

Why the fork?

Upstream hyochan/react-native-iap was archived on 2026-04-26; development moved to the OpenIAP monorepo, where it shipped as a Nitro Modules rewrite (v15+, different API). The 12.x line therefore won't receive any further patches upstream — including the iOS pod fix needed for React Native ≥ 0.83 / Expo SDK ≥ 55 / new architecture (Unable to find a specification for RCT-Folly depended upon by RNIap), and the Kotlin currentActivity fix for the same RN versions.

@iaptic/[email protected] upgrades Google Play Billing Library to V9, drops the getPurchaseHistory API (removed in GPBL V9), and includes the iOS new-architecture pod fix and the Kotlin currentActivity fix. Consumers who need GPBL V7 can stay on 12.16.6.

Documentation

  • Integration guide — step-by-step setup for subscriptions (single reference combining install, dashboard, example app, and API)
  • API reference — generated TypeDoc for all public types
  • Release notes — changelog and upgrade notes
  • Demo app — a runnable example app

Support & Community

Contributing

This repository is maintained by Iaptic. PRs and issue reports are welcome — please file an issue first for non-trivial changes so we can align on direction before you invest the work.

Security

Receipts are validated server-side by Iaptic; no validation logic runs in the app bundle, and your validation secret never ships to clients. To report a security issue, email [email protected] rather than opening a public GitHub issue.

License

MIT © Iaptic