Browse documentation

Configure once at module scope

// src/subkit.ts
import { configureSubKit } from '@piparotech/subkit-expo'

configureSubKit({
  sdkKey: 'sk_sdk_replace_me',
  installationId: 'install_abc',
  appUserId: 'user_123', // optional until login
})

Call configureSubKit(...) at module level — not inside useEffect or a component. The SDK starts automatically (autoStart defaults to true) and begins syncing purchases, so the shared client is ready before paywalls, hooks, or entitlement checks use it. This also avoids reconfiguration on re-renders. Calling configureSubKit again stops the previous client and replaces it.

If client is used before configuration, it throws.

Required fields

  • sdkKey — a public, app-bound SDK key (sk_sdk_…). The same key is used on iOS and Android. It resolves only the app; verified Apple or Google evidence determines the store environment of each purchase. Never use a server key here.

  • installationId — a stable ID for this app install on this device. Generate once, persist locally, and reuse on every launch:

    import AsyncStorage from '@react-native-async-storage/async-storage'
    import * as Crypto from 'expo-crypto'
    
    async function getInstallationId(): Promise<string> {
      const existing = await AsyncStorage.getItem('subkit.installationId')
      if (existing != null) return existing
      const id = `install_${Crypto.randomUUID()}`
      await AsyncStorage.setItem('subkit.installationId', id)
      return id
    }

    The SDK scopes its local queue and customer-info cache to sdkKey + installationId, so a changing installation ID would orphan queued purchases and cached access state.

apiBaseUrl and the HTTPS rule

apiBaseUrl defaults to https://subkit.piparo.tech. Pass it explicitly for local development or self-hosted deployments. Validation enforces HTTPS everywhere except localhost and 127.0.0.1:

configureSubKit({
  sdkKey: 'sk_sdk_replace_me',
  installationId,
  apiBaseUrl: __DEV__ ? 'http://127.0.0.1:3010' : undefined,
})

An invalid URL or plain HTTP against a non-local host throws at configure time.

iap options

All sync and offline-cache behavior, with defaults:

Option Default Effect
autoSync true Master switch for automatic purchase sync
syncOnAppStart true Sync once when the SDK starts
syncOnForeground true Sync when the app returns to foreground
syncOnPurchaseEvent true Sync when a purchase listener event arrives
foregroundMinIntervalMs 15 min Minimum gap between foreground syncs
sessionResumeThresholdMs 15 min Background time before foreground counts as a resume
customerInfoStaleAfterMs 24 h Cache age after which freshness becomes stale
nonExpiringEntitlementMaxOfflineAgeMs 30 d Offline validity window for non-expiring entitlements

See Offline access for how the last two interact with cached entitlements.

Lifecycle: autoStart, start(), stop()

By default the client starts when configured. Override autoStart: false only for custom startup control or tests, then call client.start() yourself. start() is idempotent — concurrent calls await the same startup. stop() tears down listeners and app-state subscriptions.

Advanced injection points

configureSubKit also accepts adapterBundle, appStateSource, queue, customerInfoCache, logger, platform, and sessionId. These override defaults for tests or custom infrastructure — covered in Advanced configuration.

Next

Type to search…

↑↓ navigate↵ selectEsc close