npm package: @omendilly/react-native-nitro-iap
Description: apple StoreKit sdk for react native made with nitro modules
Author: Dmitry Yatsenko
Latest version: 0.0.1

## @omendilly/react-native-nitro-iap (StoreKit 2)

React Native in‑app purchases for iOS built with Nitro Modules and StoreKit 2.

- **Native**: Uses StoreKit 2 under the hood
- **Typed**: End‑to‑end TypeScript types generated by Nitro
- **Simple**: Minimal API surface for common flows (fetch, buy, restore)

### Requirements

- **iOS 15.0+** (StoreKit 2) [[enforced by the podspec]]
- Xcode 15+
- React Native with `react-native-nitro-modules`

### Installation

```bash
# npm
npm install @omendilly/react-native-nitro-iap react-native-nitro-modules

# or yarn
yarn add @omendilly/react-native-nitro-iap react-native-nitro-modules

# or pnpm
pnpm add @omendilly/react-native-nitro-iap react-native-nitro-modules
```

iOS CocoaPods install:

```bash
cd ios && pod install && cd -
```

### iOS Setup

- Enable the `In‑App Purchase` capability in your iOS target.
- Create products in App Store Connect and use their product identifiers.
- Optional: Use StoreKit configuration files for local testing in Xcode.

### API

Import the module and types:

```ts
import { StoreKitModule, type SKProduct, type PurchaseResult } from '@omendilly/react-native-nitro-iap'
```

#### getProducts(ids)

Fetch product metadata. Note: `getProducts` expects an array of `{ value: string }` due to a Nitro/Swift interop workaround.

```ts
const ids = ['coins_100', 'premium_yearly']
const products: SKProduct[] = await StoreKitModule.getProducts(ids.map((id) => ({ value: id })))
```

Returns items of shape:

```ts
type SKProduct = {
  id: string
  type: 'consumable' | 'nonConsumable' | 'autoRenewable' | 'nonRenewing'
  title: string
  description: string
  price: string // localized price string
  currencyCode: string
}
```

#### purchase(id)

Initiates a purchase flow for the given product identifier.

```ts
const result: PurchaseResult = await StoreKitModule.purchase('premium_yearly')

// result.state: 'purchased' | 'pending' | 'failed' | 'deferred' | 'cancelled'
```

```ts
type PurchaseResult = {
  id: string
  productId: string
  state: 'purchased' | 'pending' | 'failed' | 'deferred' | 'cancelled'
  transactionDate: number // ms since epoch
  transactionId?: string
  errorCode?: string
  errorMessage?: string
}
```

Notes:
- On success, the transaction is automatically finished.
- If the user cancels, `state` is `cancelled`.

#### restore()

Returns the current entitlements (non‑consumable, subscriptions) for the signed‑in App Store user.

```ts
const purchases: PurchaseResult[] = await StoreKitModule.restore()
```

#### observeTransactions()

Starts a background listener to automatically finish new verified transactions (StoreKit 2 `Transaction.updates`). Call this once on app launch.

```ts
useEffect(() => {
  StoreKitModule.observeTransactions()
}, [])
```

#### finishTransaction(id)

Manually finish an unfinished transaction by its `transactionId` (rarely needed if `observeTransactions()` is active).

```ts
await StoreKitModule.finishTransaction('1000001234567890')
```

### End‑to‑end example

```ts
import { useEffect, useState } from 'react'
import { StoreKitModule, type SKProduct, type PurchaseResult } from '@omendilly/react-native-nitro-iap'

export function useIAP() {
  const [products, setProducts] = useState<SKProduct[]>([])

  useEffect(() => {
    StoreKitModule.observeTransactions()
    ;(async () => {
      const ids = ['coins_100', 'premium_yearly']
      const list = await StoreKitModule.getProducts(ids.map((id) => ({ value: id })))
      setProducts(list)
    })()
  }, [])

  const buy = async (id: string): Promise<PurchaseResult> => {
    return await StoreKitModule.purchase(id)
  }

  const restore = async (): Promise<PurchaseResult[]> => {
    return await StoreKitModule.restore()
  }

  return { products, buy, restore }
}
```

### Notes and best practices

- Validate receipts or transactions on your backend for subscriptions/entitlements.
- Keep product identifiers in a single source of truth.
- For UI determinism, returned products are stably sorted by title (and then id).

### Development

This package is built with Nitro Modules. If you modify the Nitro specs, regenerate code:

npm:
```bash
npm run specs
```

yarn:
```bash
yarn specs
```

bun:
```bash
bunx specs
```
### License

MIT