@subx-dev/react-native
v0.2.1
Published
SubX React Native SDK for in-app subscriptions
Maintainers
Readme
English | 한국어
@subx-dev/react-native
React Native SDK for SubX — in-app subscription management.
Prerequisites
Before integrating the SDK, you need a SubX account and project:
- Sign up at subx.dev and create a new project
- Create an app — register your iOS (App Store) or Android (Play Store) app within the project
- Set up products — define your subscription products, entitlements, and offerings in the SubX dashboard
- Get your API key — go to Project Settings → API Keys and copy your Public API Key (starts with a long hex string). This is the key you'll pass to
SubXProvider - Configure store credentials — upload your Apple App Store p8 key or Google Play service account JSON for server-side receipt validation
- Set up webhooks — in your backend, create a
POST /webhooks/subxendpoint and register the URL in Project Settings → Webhooks. SubX will send subscription lifecycle events (purchases, renewals, cancellations) with HMAC-SHA256 signatures
Tip: The Public API Key is safe to include in client-side code. It can only read offerings and submit receipts — it cannot modify your project settings.
Installation
npm install @subx-dev/react-native react-native-iapiOS Setup
cd ios && pod installAndroid Setup
No additional setup required.
Expo
Add react-native-iap to your app.json plugins:
{
"plugins": ["react-native-iap"]
}Quick Start
1. Wrap your app with SubXProvider
import { SubXProvider } from '@subx-dev/react-native';
export default function App() {
return (
<SubXProvider
apiKey="your_subx_api_key"
baseUrl="https://api.subx.dev"
entitlementIds={['pro']}
>
<YourApp />
</SubXProvider>
);
}2. Identify user after login
import { useSubX } from '@subx-dev/react-native';
function LoginScreen() {
const { identify } = useSubX();
const handleLogin = async (userId: string) => {
await identify(userId);
};
}3. Check subscription status
import { useSubX } from '@subx-dev/react-native';
function SettingsScreen() {
const { isPro, isEntitled, customerInfo } = useSubX();
return (
<View>
<Text>{isPro ? 'Pro Plan' : 'Free Plan'}</Text>
<Text>{isEntitled('premium_feature') ? 'Unlocked' : 'Locked'}</Text>
</View>
);
}4. Display offerings and make purchases
import { useOfferings, usePurchase } from '@subx-dev/react-native';
function PaywallScreen() {
const { currentOffering, isLoading } = useOfferings();
const { purchase, isPurchasing } = usePurchase();
if (isLoading) return <ActivityIndicator />;
return (
<View>
{currentOffering?.packagesWithProducts.map((pkg) => {
const product = pkg.storeProducts[0];
if (!product) return null;
return (
<TouchableOpacity
key={pkg.id}
onPress={() => purchase(product.productId)}
disabled={isPurchasing}
>
<Text>{pkg.displayName}</Text>
<Text>{product.localizedPrice}</Text>
</TouchableOpacity>
);
})}
</View>
);
}5. Restore purchases
const { restore } = useSubX();
await restore();API Reference
SubXProvider
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| apiKey | string | Yes | SubX public API key |
| baseUrl | string | No | SubX API base URL (default: https://api.subx.dev) |
| entitlementIds | string[] | No | Entitlement IDs to check for isPro |
useSubX()
Returns:
| Property | Type | Description |
|----------|------|-------------|
| isReady | boolean | Whether SDK is initialized |
| isPro | boolean | Whether user has any of the specified entitlements |
| appUserId | string \| null | Current user ID |
| customerInfo | CustomerInfo \| null | Full customer info |
| isEntitled(id) | (id: string) => boolean | Check specific entitlement |
| identify(userId) | (userId: string) => Promise<CustomerInfo> | Identify user |
| purchase(productId) | (productId: string) => Promise<{ success, customerInfo }> | Make purchase |
| restore() | () => Promise<CustomerInfo \| null> | Restore purchases |
| logout() | () => Promise<void> | Clear user session |
useOfferings()
Returns:
| Property | Type | Description |
|----------|------|-------------|
| offerings | OfferingWithStoreProducts[] | All offerings with store prices |
| currentOffering | OfferingWithStoreProducts \| null | Current/default offering |
| isLoading | boolean | Loading state |
| error | Error \| null | Error state |
usePurchase()
Returns:
| Property | Type | Description |
|----------|------|-------------|
| purchase(productId) | (productId: string) => Promise<{ success, customerInfo }> | Execute purchase |
| isPurchasing | boolean | Purchase in progress |
| error | Error \| null | Error state |
SubXReactNative (Advanced)
Singleton class for direct access:
import { SubXReactNative } from '@subx-dev/react-native';
const subx = SubXReactNative.shared;
await subx.configure({ apiKey: '...', entitlementIds: ['pro'] });
await subx.identify('user-123');
const info = await subx.getCustomerInfo();How It Works
- Purchase Flow:
requestPurchase→ store purchase →purchaseUpdatedListener→submitReceiptto SubX →finishTransaction→ refresh customer info - Restore Flow:
getAvailablePurchases→ submit each receipt → refresh customer info - Auto-sync: Customer info refreshes when app returns to foreground
License
MIT
