Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
0f13f92
security: pin GitHub Actions to SHA hashes (#1691)
alfondotnet Mar 25, 2026
6ad68c9
Bump fast-xml-parser from 4.5.4 to 4.5.5 in /examples/MagicWeather (#…
dependabot[bot] Mar 25, 2026
ae0d039
Bump activesupport from 7.2.2.1 to 7.2.3.1 in /examples/purchaseTeste…
dependabot[bot] Mar 25, 2026
4ad8bf2
Bump picomatch from 2.3.1 to 2.3.2 in /examples/MagicWeather (#1696)
dependabot[bot] Mar 26, 2026
4401dfc
Bump picomatch from 2.3.1 to 2.3.2 (#1697)
dependabot[bot] Mar 26, 2026
5975d4a
Bump yaml from 2.8.2 to 2.8.3 in /examples/MagicWeather (#1698)
dependabot[bot] Mar 26, 2026
00344b9
Bump yaml from 1.10.2 to 1.10.3 (#1695)
dependabot[bot] Mar 26, 2026
2807b02
Bump fastlane-plugin-revenuecat_internal from `9a6911b` to `f11fe40` …
dependabot[bot] Mar 27, 2026
48a1171
Bump node-forge from 1.3.3 to 1.4.0 (#1700)
dependabot[bot] Mar 27, 2026
f88f32a
CustomerCenter: Adds onPromotionalOfferSucceeded callback, bump purch…
RCGitBot Mar 27, 2026
0a7c6d0
[AUTOMATIC] Release/9.15.0 (#1701)
RCGitBot Mar 27, 2026
6d1b6b2
Bump brace-expansion from 1.1.12 to 1.1.13 in /examples/MagicWeather …
dependabot[bot] Mar 27, 2026
c4ab76d
feat: add maestro E2E test for purchase through paywall
ajpallares Feb 27, 2026
c5a2a5f
feat: update maestro tests to match iOS V2 paywall flow and add confi…
ajpallares Mar 25, 2026
ad51429
refactor: simplify maestro tests to always use test store
ajpallares Mar 30, 2026
d01345c
refactor: remove takeScreenshot steps from maestro tests
ajpallares Mar 30, 2026
fa2f0e8
fix: use regex in confirm_purchase.yaml to match both iOS and Android…
ajpallares Mar 30, 2026
ac5abc5
fix: tighten confirm_purchase regex to match Test.*Purchase
ajpallares Mar 30, 2026
35608f1
Fix known security vulnerabilities in dependencies (#1703)
vegaro Mar 31, 2026
49feb06
chore: bump react-native devDependency from 0.73.5 to 0.78.0 (#1704)
vegaro Mar 31, 2026
061fe7a
Add AGENTS.md for AI coding assistants (#1616)
facumenzella Apr 1, 2026
156d0ba
[AUTOMATIC BUMP] Updates purchases-hybrid-common to 17.54.0 (#1706)
RCGitBot Apr 1, 2026
0175ca8
Bump fastlane-plugin-revenuecat_internal from `f11fe40` to `b5a7159` …
dependabot[bot] Apr 1, 2026
d35a34f
[AUTOMATIC] Release/9.15.1 (#1711)
RCGitBot Apr 1, 2026
ad82515
Bump fastlane-plugin-revenuecat_internal from `b5a7159` to `5d6e93f` …
dependabot[bot] Apr 2, 2026
93e8e50
Bump lodash from 4.17.23 to 4.18.1 in /examples/MagicWeather (#1714)
dependabot[bot] Apr 2, 2026
5a6e18d
Bump fastlane-plugin-revenuecat_internal from `5d6e93f` to `6289be1` …
dependabot[bot] Apr 3, 2026
3832688
Merge remote-tracking branch 'origin/main' into e2e-tests-app
ajpallares Apr 3, 2026
451856f
Merge e2e-tests-app into add-maestro-e2e-test
ajpallares Apr 3, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/issue-notifications.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ on:

jobs:
notify:
uses: revenuecat/sdk-github-workflows/.github/workflows/issue-notifications.yml@v2
uses: revenuecat/sdk-github-workflows/.github/workflows/issue-notifications.yml@acb41efc0045b05dd0517dc08200dd4112ea9bae # v2
secrets:
ACK_SLACK_WEBHOOK_URL: ${{ secrets.ACK_SLACK_WEBHOOK_URL }}
ACK_ALERT_KEYWORDS: ${{ secrets.ACK_ALERT_KEYWORDS }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/lock.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
lock:
runs-on: ubuntu-latest
steps:
- uses: dessant/[email protected]
- uses: dessant/lock-threads@63786a6c74ee3cfc4584f36de4360305c55e5126 # v2.0.1
with:
github-token: ${{ github.token }}
issue-lock-inactive-days: "7"
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,6 @@ vendor/
!.yarn/versions

package.tgz

# Claude Code
.claude/
2 changes: 1 addition & 1 deletion .version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
9.14.0
9.15.1
188 changes: 188 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
# react-native-purchases — Development Guidelines

This file provides guidance to AI coding agents when working with code in this repository.

## Project Overview

RevenueCat's official React Native SDK for in-app purchases and subscriptions. Provides a TypeScript API that wraps native iOS and Android SDKs, with web support and browser fallback for web, Expo Go, and Rork Sandbox environments.

**Related repositories:**
- **iOS SDK**: https://github.com/RevenueCat/purchases-ios
- **Android SDK**: https://github.com/RevenueCat/purchases-android
- **Web SDK**: https://github.com/RevenueCat/purchases-js — Web/JS SDK
- **Hybrid Common**: https://github.com/RevenueCat/purchases-hybrid-common — Native bridge layer
- **UI Package**: Located in `react-native-purchases-ui/` workspace

When implementing features or debugging, check these repos for reference and patterns.

## Important: Public API Stability

**Do NOT introduce breaking changes to the public API.** The SDK is used by many production apps.

**Safe changes:**
- Adding new optional parameters to existing methods
- Adding new classes, methods, or properties
- Bug fixes that don't change method signatures
- Internal implementation changes

**Requires explicit approval:**
- Removing or renaming public classes/methods/properties
- Changing method signatures (parameter types, required params)
- Changing return types
- Modifying behavior in ways that break existing integrations

## Code Structure

```
react-native-purchases/
├── src/
│ ├── index.ts # Main entry point
│ ├── purchases.ts # Core Purchases class
│ ├── customerInfo.ts # Re-exports from typescript-internal
│ ├── offerings.ts # Re-exports from typescript-internal
│ ├── errors.ts # Re-exports from typescript-internal
│ ├── browser/ # Browser/web/Expo Go/Rork Sandbox fallback implementation
│ │ ├── nativeModule.ts # Browser implementation of native module
│ │ ├── typeGuards.ts # Runtime type validation for browser responses
│ │ ├── utils.ts # Browser helpers (e.g. methodNotSupportedOnWeb)
│ │ └── simulatedstore/ # Simulated purchase helpers
│ └── utils/
│ └── environment.ts # Environment detection
├── android/ # Android native module (Java/Kotlin)
│ └── src/main/java/com/revenuecat/purchases/react/
│ ├── RNPurchasesModule.java
│ ├── RNPurchasesConverters.kt
│ ├── RNPurchasesPackage.java
│ └── GoogleUpgradeInfo.java
├── ios/ # iOS native module (Obj-C/Swift)
│ ├── RNPurchases.m
│ └── PurchasesPlugin.swift
├── __tests__/ # Jest test suites
├── examples/
│ ├── MagicWeather/ # Complete example app
│ ├── purchaseTesterTypescript/ # Main test app (workspace)
│ └── purchaseTesterExpo/ # Expo test app
├── react-native-purchases-ui/ # UI components workspace
├── dist/ # Compiled output (generated by `yarn build`, not in repo)
└── fastlane/ # Release automation
```

## Common Development Commands

```bash
# Install dependencies and bootstrap
yarn bootstrap

# Build TypeScript
yarn build
yarn build-watch

# Run tests
yarn test

# Type checking
yarn typecheck

# Lint (runs the project's configured linter despite the name)
yarn tslint

# Run example app (workspace)
yarn example ios
yarn example android

# Prepare for Expo testing
yarn prepare-expo
```

## Project Architecture

### Main Entry Point: `src/purchases.ts`
- **Core Class**: `Purchases` with static methods
- **Dual Mode**: Native module OR browser mode (web, Expo Go, Rork Sandbox)
- **Environment Detection**: `shouldUseBrowserMode()` utility

### Architecture Layers
1. **TypeScript Wrapper** (`src/purchases.ts`) — Type-safe public API
2. **Native Bridge** (`PurchasesHybridCommon`) — iOS/Android hybrid mappings come from the corresponding PHC libraries
3. **Native Modules**:
- iOS: `ios/RNPurchases.m`, `ios/PurchasesPlugin.swift`
- Android: `android/.../RNPurchasesModule.java`
4. **Browser Fallback** (`src/browser/`) — For web/Expo Go/Rork Sandbox environments

### Key Dependencies
- `@revenuecat/purchases-js-hybrid-mappings` — Mappings for the purchases-js (web) library only; not used for iOS/Android
- `@revenuecat/purchases-typescript-internal` — Shared types (also shared with purchases-capacitor)
- `PurchasesHybridCommon` (iOS/Android) — Native bridge and hybrid mappings for iOS/Android

### Re-export Pattern
Files like `customerInfo.ts`, `errors.ts`, `offerings.ts` re-export from `@revenuecat/purchases-typescript-internal` for backwards compatibility.

## Constraints / Support Policy

| Platform | Minimum Version |
|----------|-----------------|
| React | >= 16.6.3 |
| React Native | >= 0.73.0 |
| iOS | 13.0+ |
| Android | API 21+ |
| TypeScript | 5.2.2 |
| Web | Supported (via browser mode) |

Don't raise minimum versions unless explicitly required and justified.

## Testing

Test files are in `__tests__/`. Coverage includes native module integration, browser/web mode fallback, environment detection, and API key validation for Expo Go and Rork Sandbox.

## Development Workflow

1. Bootstrap: `yarn bootstrap`
2. Build: `yarn build`
3. Make changes in `src/` (TypeScript) or native code (`ios/`, `android/`)
4. Run tests: `yarn test`
5. Type check: `yarn typecheck`
6. Test in example app: `yarn example ios` or `yarn example android`
7. Test browser/web mode: `yarn prepare-expo`, then run the Expo test app in web mode

### Local Native SDK Development
For testing with local purchases-hybrid-common:
```bash
cd android && ./gradlew enableLocalBuild -PpurchasesPath="path/to/purchases-hybrid-common"
```

## Yarn Workspaces

```
workspaces:
- examples/purchaseTesterTypescript
- react-native-purchases-ui
```

## Pull Request Labels

When creating a pull request, **always add one of these labels** to categorize the change:

| Label | When to Use |
|-------|-------------|
| `pr:feat` | New user-facing features or enhancements |
| `pr:fix` | Bug fixes |
| `pr:other` | Internal changes, refactors, CI, docs, or anything that shouldn't trigger a release |

## When the Task is Ambiguous

1. Search for similar existing implementation in this repo first
2. Check purchases-ios, purchases-android, and purchases-hybrid-common for patterns
3. If there's a pattern, follow it exactly
4. If not, propose options with tradeoffs and pick the safest default

## Guardrails

- **Don't invent APIs or file paths** — verify they exist before referencing them
- **Don't remove code you don't understand** — ask for context first
- **Don't make large refactors** unless explicitly requested
- **Keep diffs minimal** — only touch what's necessary, preserve existing formatting
- **Don't break the public API** — maintain backwards compatibility
- **Check native SDKs** when unsure about platform implementation details
- **Test both native and browser modes** — ensure web/Expo Go/Rork Sandbox fallback works
- **Run build before testing** — always `yarn build` first
- **Never commit API keys or secrets** — do not stage or commit credentials or sensitive data
16 changes: 10 additions & 6 deletions CHANGELOG.latest.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
## RevenueCat SDK
### ✨ New Features
* Add offeringId override to trackCustomPaywallImpression (#1679) via Rick (@rickvdl)
### 📦 Dependency Updates
* [AUTOMATIC BUMP] Updates purchases-hybrid-common to 17.52.0 (#1680) via RevenueCat Git Bot (@RCGitBot)
* [AUTOMATIC BUMP] Updates purchases-hybrid-common to 17.54.0 (#1706) via RevenueCat Git Bot (@RCGitBot)
* [Android 9.28.1](https://github.com/RevenueCat/purchases-android/releases/tag/9.28.1)
* [Android 9.28.0](https://github.com/RevenueCat/purchases-android/releases/tag/9.28.0)
* [iOS 5.67.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.67.0)

## RevenueCatUI SDK
### ✨ New Features
* Add number and boolean support for CustomVariable (#1675) via Facundo Menzella (@facumenzella)
### 🔄 Other Changes
* Bump fastlane-plugin-revenuecat_internal from `f11fe40` to `b5a7159` (#1707) via dependabot[bot] (@dependabot[bot])
* Add AGENTS.md for AI coding assistants (#1616) via Facundo Menzella (@facumenzella)
* chore: bump react-native devDependency from 0.73.5 to 0.78.0 (#1704) via Cesar de la Vega (@vegaro)
* Fix known security vulnerabilities in dependencies (#1703) via Cesar de la Vega (@vegaro)
* Bump brace-expansion from 1.1.12 to 1.1.13 in /examples/MagicWeather (#1702) via dependabot[bot] (@dependabot[bot])
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,44 @@
## 9.15.1
## RevenueCat SDK
### 📦 Dependency Updates
* [AUTOMATIC BUMP] Updates purchases-hybrid-common to 17.54.0 (#1706) via RevenueCat Git Bot (@RCGitBot)
* [Android 9.28.1](https://github.com/RevenueCat/purchases-android/releases/tag/9.28.1)
* [Android 9.28.0](https://github.com/RevenueCat/purchases-android/releases/tag/9.28.0)
* [iOS 5.67.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.67.0)

### 🔄 Other Changes
* Bump fastlane-plugin-revenuecat_internal from `f11fe40` to `b5a7159` (#1707) via dependabot[bot] (@dependabot[bot])
* Add AGENTS.md for AI coding assistants (#1616) via Facundo Menzella (@facumenzella)
* chore: bump react-native devDependency from 0.73.5 to 0.78.0 (#1704) via Cesar de la Vega (@vegaro)
* Fix known security vulnerabilities in dependencies (#1703) via Cesar de la Vega (@vegaro)
* Bump brace-expansion from 1.1.12 to 1.1.13 in /examples/MagicWeather (#1702) via dependabot[bot] (@dependabot[bot])

## 9.15.0
## RevenueCat SDK
### ✨ New Features
* CustomerCenter: Adds onPromotionalOfferSucceeded callback, bump purchases-hybrid-common to 17.53.0 (#1684) via RevenueCat Git Bot (@RCGitBot)
* [Android 9.27.0](https://github.com/RevenueCat/purchases-android/releases/tag/9.27.0)
* [iOS 5.66.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.66.0)
### 📦 Dependency Updates
* [RENOVATE] Update dependency gradle to v9.4.1 (#1688) via RevenueCat Git Bot (@RCGitBot)

### 🔄 Other Changes
* Bump node-forge from 1.3.3 to 1.4.0 (#1700) via dependabot[bot] (@dependabot[bot])
* Bump fastlane-plugin-revenuecat_internal from `9a6911b` to `f11fe40` (#1699) via dependabot[bot] (@dependabot[bot])
* Bump yaml from 1.10.2 to 1.10.3 (#1695) via dependabot[bot] (@dependabot[bot])
* Bump yaml from 2.8.2 to 2.8.3 in /examples/MagicWeather (#1698) via dependabot[bot] (@dependabot[bot])
* Bump picomatch from 2.3.1 to 2.3.2 (#1697) via dependabot[bot] (@dependabot[bot])
* Bump picomatch from 2.3.1 to 2.3.2 in /examples/MagicWeather (#1696) via dependabot[bot] (@dependabot[bot])
* Bump activesupport from 7.2.2.1 to 7.2.3.1 in /examples/purchaseTesterTypescript (#1693) via dependabot[bot] (@dependabot[bot])
* Bump fast-xml-parser from 4.5.4 to 4.5.5 in /examples/MagicWeather (#1692) via dependabot[bot] (@dependabot[bot])
* security: pin GitHub Actions to SHA hashes (#1691) via Alfonso Embid-Desmet (@alfondotnet)
* Bump activesupport from 7.2.2.2 to 7.2.3.1 (#1690) via dependabot[bot] (@dependabot[bot])
* Bump activesupport from 7.2.2.1 to 7.2.3.1 in /examples/MagicWeather (#1689) via dependabot[bot] (@dependabot[bot])
* Merge release PR after deploy (#1686) via Antonio Pallares (@ajpallares)
* Require PR approval before release tagging (#1685) via Antonio Pallares (@ajpallares)
* Bump flatted from 3.3.3 to 3.4.2 in /examples/MagicWeather (#1687) via dependabot[bot] (@dependabot[bot])
* Bump json from 2.18.1 to 2.19.2 (#1683) via dependabot[bot] (@dependabot[bot])

## 9.14.0
## RevenueCat SDK
### ✨ New Features
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
8 changes: 4 additions & 4 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
GIT
remote: https://github.com/RevenueCat/fastlane-plugin-revenuecat_internal
revision: 9a6911be3659cd14fe62ada4cbae3a2f8792691c
revision: 6289be1dcdf7efc57682b284be9bdb1db3efbe69
specs:
fastlane-plugin-revenuecat_internal (0.1.0)
nokogiri
Expand Down Expand Up @@ -280,7 +280,7 @@ GEM
mime-types (3.7.0)
logger
mime-types-data (~> 3.2025, >= 3.2025.0507)
mime-types-data (3.2026.0303)
mime-types-data (3.2026.0331)
mini_magick (4.13.2)
mini_mime (1.1.5)
mini_portile2 (2.8.9)
Expand All @@ -294,10 +294,10 @@ GEM
naturally (2.3.0)
netrc (0.11.0)
nkf (0.2.0)
nokogiri (1.19.1)
nokogiri (1.19.2)
mini_portile2 (~> 2.8.2)
racc (~> 1.4)
nokogiri (1.19.1-arm64-darwin)
nokogiri (1.19.2-arm64-darwin)
racc (~> 1.4)
octokit (10.0.0)
faraday (>= 1, < 3)
Expand Down
2 changes: 1 addition & 1 deletion RNPurchases.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,6 @@ Pod::Spec.new do |spec|
]

spec.dependency "React-Core"
spec.dependency "PurchasesHybridCommon", '17.52.0'
spec.dependency "PurchasesHybridCommon", '17.54.0'
spec.swift_version = '5.7'
end
2 changes: 2 additions & 0 deletions VERSIONS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
| Version | iOS version | Android version | Common files version | Play Billing Library version |
|---------------|-------------|-----------------|-----------------------|------------------------------|
| 9.15.1 | [5.67.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.67.0) | [9.28.1](https://github.com/RevenueCat/purchases-android/releases/tag/9.28.1) | [17.54.0](https://github.com/RevenueCat/purchases-hybrid-common/releases/tag/17.54.0) | [8.0.0](https://developer.android.com/google/play/billing/release-notes) |
| 9.15.0 | [5.66.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.66.0) | [9.27.0](https://github.com/RevenueCat/purchases-android/releases/tag/9.27.0) | [17.53.0](https://github.com/RevenueCat/purchases-hybrid-common/releases/tag/17.53.0) | [8.0.0](https://developer.android.com/google/play/billing/release-notes) |
| 9.14.0 | [5.65.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.65.0) | [9.26.1](https://github.com/RevenueCat/purchases-android/releases/tag/9.26.1) | [17.52.0](https://github.com/RevenueCat/purchases-hybrid-common/releases/tag/17.52.0) | [8.0.0](https://developer.android.com/google/play/billing/release-notes) |
| 9.13.0 | [5.65.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.65.0) | [9.26.1](https://github.com/RevenueCat/purchases-android/releases/tag/9.26.1) | [17.51.1](https://github.com/RevenueCat/purchases-hybrid-common/releases/tag/17.51.1) | [8.0.0](https://developer.android.com/google/play/billing/release-notes) |
| 9.12.0 | [5.61.0](https://github.com/RevenueCat/purchases-ios/releases/tag/5.61.0) | [9.23.1](https://github.com/RevenueCat/purchases-android/releases/tag/9.23.1) | [17.46.1](https://github.com/RevenueCat/purchases-hybrid-common/releases/tag/17.46.1) | [8.0.0](https://developer.android.com/google/play/billing/release-notes) |
Expand Down
4 changes: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ android {
minSdkVersion getExtOrIntegerDefault('minSdkVersion')
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
versionCode 1
versionName '9.14.0'
versionName '9.15.1'
}

buildTypes {
Expand Down Expand Up @@ -121,6 +121,6 @@ def kotlin_version = getExtOrDefault('kotlinVersion')
dependencies {
//noinspection GradleDynamicVersion
api 'com.facebook.react:react-native:+'
implementation 'com.revenuecat.purchases:purchases-hybrid-common:17.52.0'
implementation 'com.revenuecat.purchases:purchases-hybrid-common:17.54.0'
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class RNPurchasesModule extends ReactContextBaseJavaModule implements Upd
private static final String TRACKED_EVENT = "Purchases-TrackedEvent";
private static final String DEBUG_EVENT = "Purchases-DebugEvent";
public static final String PLATFORM_NAME = "react-native";
public static final String PLUGIN_VERSION = "9.14.0";
public static final String PLUGIN_VERSION = "9.15.1";

private final ReactApplicationContext reactContext;

Expand Down
7 changes: 7 additions & 0 deletions e2e-tests/maestro/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# config.yaml

executionOrder:
continueOnFailure: false

flows:
- e2e_tests/*
Loading