Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
0a4ff94
Merge pull request #255 from adaptyteam/master
StanislavMayorov Dec 24, 2025
50fad77
refactor: move onboarding events tests
StanislavMayorov Dec 26, 2025
19da172
test: add paywall events integration tests, for android/ios platform …
StanislavMayorov Dec 26, 2025
1d47055
feat: rewrite paywall events parser
StanislavMayorov Dec 29, 2025
db9aad2
chore: apply prettier
StanislavMayorov Dec 30, 2025
5da3d4a
feat: upgrade SDK to 3.15.1 (3.15.2 ios/android). add param clearData…
StanislavMayorov Dec 30, 2025
975c660
feat: add default onRenderingFailed handler
StanislavMayorov Dec 30, 2025
5a65ebb
feat: move field clearDataOnBackup to ios
StanislavMayorov Dec 30, 2025
45feacb
Merge pull request #258 from adaptyteam/feat/upgrade-3.15.1
StanislavMayorov Jan 7, 2026
022e527
fix: remove unused onAndroidSystemBack props from AdaptyPaywallViewCo…
StanislavMayorov Jan 9, 2026
9edf038
chore: upgrade ios SDK to 3.15.3
StanislavMayorov Jan 9, 2026
7302f27
Merge pull request #260 from adaptyteam/chore/upgrade-ios-3.15.3
StanislavMayorov Jan 9, 2026
445f6b2
fix: remove unused onPaywallClosed props from AdaptyPaywallViewComponent
StanislavMayorov Jan 9, 2026
8a3cbf7
refactor: improve types for AdaptyUICreateOnboardingViewParamsCoder
StanislavMayorov Jan 8, 2026
3031d91
test: add integration test for paywall event listeners unsubscription
StanislavMayorov Jan 8, 2026
1af378b
fix: add missing onPaywallClosed event. add internalHandlers for payw…
StanislavMayorov Jan 11, 2026
90f4d8c
refactor: resolves native event to handler name based on event data w…
StanislavMayorov Jan 12, 2026
d1bf255
docs: add ExpoGo example to README.md
StanislavMayorov Jan 12, 2026
f298688
docs: add Table of Contents
StanislavMayorov Jan 12, 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
62 changes: 38 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,21 @@

![Adapty: CRM for mobile apps with subscriptions](https://adapty-portal-media-production.s3.amazonaws.com/github/adapty-schema.png)

Adapty SDK is an open-source framework that makes implementing in-app subscriptions for React Native fast and easy. It’s 100% open-source and lightweight.
Adapty SDK is an open-source framework that makes implementing in-app subscriptions for React Native fast and easy. It's 100% open-source and lightweight.

## Table of Contents

- [Why Adapty?](#why-adapty)
- [Getting Started](#getting-started)
- [Integrate IAPs within a few hours without server coding](#integrate-iaps-within-a-few-hours-without-server-coding)
- [Design paywalls in the no-code builder](#design-paywalls-in-the-no-code-builder)
- [Test paywalls & prices on React Native without app releases](#test-paywalls--prices-on-react-native-without-app-releases)
- [Real-time analytics for your React Native app](#real-time-analytics-for-your-react-native-app)
- [Mobile app monetization's largest community](#mobile-app-monetizations-largest-community)
- [React Native Architecture Compatibility](#react-native-architecture-compatibility)
- [Examples](#examples)
- [Contributing](#contributing)
- [License](#license)

## Why Adapty?

Expand All @@ -39,6 +53,27 @@ Adapty SDK is an open-source framework that makes implementing in-app subscripti
<a href="https://adapty.io/schedule-demo?utm_source=github&utm_medium=referral&utm_campaign=AdaptySDK-React-Native_schedule-demo">Talk to Us to Learn More</a>
</h3>

## Getting Started

### For React Native projects:

```sh
# using npm
npm install react-native-adapty

# or using yarn
yarn add react-native-adapty
```

### For Expo projects:

```sh
npx expo install react-native-adapty
npx expo prebuild
```

Read the [documentation](https://adapty.io/docs/sdk-installation-reactnative?utm_source=github&utm_medium=referral&utm_campaign=AdaptySDK-React-Native) to install and configure Adapty SDK. Set up purchases in hours instead of weeks :rocket:

## Integrate IAPs within a few hours without server coding

**Adapty handles everything, from free trials to refunds, in a simple, developer-friendly SDK.**
Expand Down Expand Up @@ -78,28 +113,6 @@ Ask questions, participate in discussions about Adapty-related topics, become a

<a href="https://discord.gg/subscriptions-hub"><img src="https://adapty-portal-media-production.s3.amazonaws.com/github/join-discord.svg" /></a>


## Getting Started

### For React Native projects:

```sh
# using npm
npm install react-native-adapty

# or using yarn
yarn add react-native-adapty
```

### For Expo projects:

```sh
npx expo install react-native-adapty
npx expo prebuild
```

Read the [documentation](https://adapty.io/docs/sdk-installation-reactnative?utm_source=github&utm_medium=referral&utm_campaign=AdaptySDK-React-Native) to install and configure Adapty SDK. Set up purchases in hours instead of weeks :rocket:

## React Native Architecture Compatibility

Adapty SDK is compatible with both **React Native's New Architecture** (including Turbo Modules) and the legacy architecture.
Expand All @@ -110,7 +123,8 @@ Adapty SDK is compatible with both **React Native's New Architecture** (includin
We provide several example applications with increasing complexity:

- **[BasicExample](./examples/BasicExample/)** (React Native) – Minimal setup example showing core SDK features.
- **[FocusJournalExpo](./examples/FocusJournalExpo/)** (Expo) – Full-featured app with navigation and premium features.
- **[ExpoGoWebMock](./examples/ExpoGoWebMock/)** (Expo Go / Expo Web) – Easiest to run (works in browser with mock mode, no Adapty key required). Demonstrates mock data usage for Expo Go/Web. Includes both custom paywall and Adapty Paywall Builder.
- **[FocusJournalExpo](./examples/FocusJournalExpo/)** (Expo) – Simple app with premium features using Adapty Paywall Builder. Includes video guide.
- **[AdaptyDevtools](./examples/AdaptyDevtools/)** (React Native) – DevTools and bug reporting tool.

📹 **Watch our video guide** for step-by-step integration with the Focus Journal Expo example:
Expand Down
4 changes: 2 additions & 2 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -110,10 +110,10 @@ def getExtOrDefault(name) {
def kotlin_version = getExtOrDefault('kotlinVersion')

dependencies {
implementation platform('io.adapty:adapty-bom:3.15.1')
implementation platform('io.adapty:adapty-bom:3.15.2')
implementation 'io.adapty:android-sdk'
implementation 'io.adapty:android-ui'
implementation 'io.adapty.internal:crossplatform:3.15.2'
implementation 'io.adapty.internal:crossplatform:3.15.3'

// Compatible with older and newer RN
//noinspection GradleDynamicVersion
Expand Down
4 changes: 3 additions & 1 deletion cross_platform.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
$schema: "https://json-schema.org/draft/2020-12/schema"
$id: "https://adapty.io/crossPlatform/3.15.1/schema"
$id: "https://adapty.io/crossPlatform/3.15.2/schema"
title: "Cross Platform Format"

$requests:
Expand Down Expand Up @@ -412,6 +412,7 @@ $requests:
properties:
paywall: { $ref: "#/$defs/AdaptyPaywall" }


OpenWebPaywall.Response: #response
type: object
oneOf:
Expand Down Expand Up @@ -931,6 +932,7 @@ $defs:
google_enable_pending_prepaid_plans: { type: boolean, default: false }
google_local_access_level_allowed: { type: boolean, default: false }
ip_address_collection_disabled: { type: boolean, default: false }
clear_data_on_backup: { type: boolean, default: false }
server_cluster: { type: string, enum: ["default", "eu", "cn"] }
backend_proxy_host: { type: string }
backend_proxy_port: { type: integer }
Expand Down
50 changes: 25 additions & 25 deletions examples/AdaptyDevtools/ios/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
PODS:
- Adapty (3.15.1):
- AdaptyLogger (= 3.15.1)
- AdaptyUIBuilder (= 3.15.1)
- AdaptyLogger (3.15.1)
- AdaptyPlugin (3.15.1):
- Adapty (= 3.15.1)
- AdaptyLogger (= 3.15.1)
- AdaptyUI (= 3.15.1)
- AdaptyUIBuilder (= 3.15.1)
- AdaptyUI (3.15.1):
- Adapty (= 3.15.1)
- AdaptyLogger (= 3.15.1)
- AdaptyUIBuilder (= 3.15.1)
- AdaptyUIBuilder (3.15.1):
- AdaptyLogger (= 3.15.1)
- Adapty (3.15.3):
- AdaptyLogger (= 3.15.3)
- AdaptyUIBuilder (= 3.15.3)
- AdaptyLogger (3.15.3)
- AdaptyPlugin (3.15.3):
- Adapty (= 3.15.3)
- AdaptyLogger (= 3.15.3)
- AdaptyUI (= 3.15.3)
- AdaptyUIBuilder (= 3.15.3)
- AdaptyUI (3.15.3):
- Adapty (= 3.15.3)
- AdaptyLogger (= 3.15.3)
- AdaptyUIBuilder (= 3.15.3)
- AdaptyUIBuilder (3.15.3):
- AdaptyLogger (= 3.15.3)
- boost (1.84.0)
- DoubleConversion (1.1.6)
- fast_float (8.0.0)
Expand Down Expand Up @@ -1663,10 +1663,10 @@ PODS:
- React-RCTFBReactNativeSpec
- ReactCommon/turbomodule/core
- SocketRocket
- react-native-adapty-sdk (3.15.0):
- Adapty (= 3.15.1)
- AdaptyPlugin (= 3.15.1)
- AdaptyUI (= 3.15.1)
- react-native-adapty-sdk (3.15.1):
- Adapty (= 3.15.3)
- AdaptyPlugin (= 3.15.3)
- AdaptyUI (= 3.15.3)
- React
- react-native-safe-area-context (5.4.1):
- boost
Expand Down Expand Up @@ -2538,11 +2538,11 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"

SPEC CHECKSUMS:
Adapty: bb2cc10a238b5d53025a0a969bc2a7ad6e9a48f5
AdaptyLogger: 2d1a3cc8b8dee29dc171df753d6b6d45332bd399
AdaptyPlugin: 79f4d39bcaa84ad3755fe0f0a07148abca2af4ed
AdaptyUI: 56ff8ed7be49cbff9cdc29ddde230de60e115d4f
AdaptyUIBuilder: 3204524ee377de2eddec478d51c3cf1f1e83ef1c
Adapty: 9d5c8378ddf71747e5182ae9dd3426b2a4dc274a
AdaptyLogger: 8a58745fe27ac991d2b2f05de57bfa9d932383ca
AdaptyPlugin: d832e606563b2cc3e77dbc4ca23e64725a3b21c5
AdaptyUI: 7b8515dade06d8a046826f024940c009bedb5f00
AdaptyUIBuilder: e94ea218d936f58f13123fda19f3c13fba5cdb7d
boost: 7e761d76ca2ce687f7cc98e698152abd03a18f90
DoubleConversion: cb417026b2400c8f53ae97020b2be961b59470cb
fast_float: b32c788ed9c6a8c584d114d0047beda9664e7cc6
Expand Down Expand Up @@ -2583,7 +2583,7 @@ SPEC CHECKSUMS:
React-logger: b69e65dc60f768e5509ac0cc27a360124bf70478
React-Mapbuffer: b48f9f3311fd0ec0f7a5dc39d707eff521fb5f38
React-microtasksnativemodule: d8568d0485a350c720c061ae835e09fc88c28715
react-native-adapty-sdk: 39e2fb1607910e7d719e291281516864846792f1
react-native-adapty-sdk: 765bc4b65a425b4f77e370d9b8e33ddcd046c578
react-native-safe-area-context: 6775aa9089fa84b77abd7ebdcf45e224a2a2ad3e
React-NativeModulesApple: f10596688a03af66804cfbe61792be24a7888da8
React-oscompat: 7c0a341cc31e350da71ddf2e46de0a845d1d1626
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package",
"name": "react-native-adapty",
"version": "3.15.0",
"version": "3.15.1",
"description": "Adapty React Native SDK",
"license": "MIT",
"author": "Adapty team <support@adapty.io>",
Expand Down
6 changes: 3 additions & 3 deletions react-native-adapty-sdk.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ Pod::Spec.new do |s|
s.resources = "ios/**/*.{plist}"
s.requires_arc = true

s.dependency "Adapty", "3.15.1"
s.dependency "AdaptyUI", "3.15.1"
s.dependency "AdaptyPlugin", "3.15.1"
s.dependency "Adapty", "3.15.3"
s.dependency "AdaptyUI", "3.15.3"
s.dependency "AdaptyPlugin", "3.15.3"
s.dependency "React"
end

Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* Bridge event samples for general Adapty handler events
*
* Real event data extracted from native logs for accurate testing.
*
* Use these samples for integration tests to verify event handling.
*/

/**
* Sample for Event.DidLoadLatestProfile with active premium subscription
* @see cross_platform.yaml#/$events/Event.DidLoadLatestProfile
*/
export const PROFILE_DID_LOAD_LATEST_WITH_PREMIUM = {
id: 'did_load_latest_profile',
profile: {
paid_access_levels: {
premium: {
activated_at: '2025-12-26T13:36:09.931000+0000',
expires_at: '2025-12-26T13:41:09.549000+0000',
id: 'premium',
is_active: true,
is_in_grace_period: false,
is_lifetime: false,
is_refund: false,
renewed_at: '2025-12-26T13:36:09.931000+0000',
store: 'play_store',
vendor_product_id: 'weekly.premium.599',
will_renew: true,
},
},
custom_attributes: {},
is_test_user: false,
non_subscriptions: {},
profile_id: 'cbdabead-697c-4804-9ea5-7ccaa83411c7',
subscriptions: {
'weekly.premium.599': {
activated_at: '2025-12-26T13:36:09.931000+0000',
expires_at: '2025-12-26T13:41:09.549000+0000',
is_active: true,
is_in_grace_period: false,
is_lifetime: false,
is_refund: false,
is_sandbox: true,
renewed_at: '2025-12-26T13:36:09.931000+0000',
store: 'play_store',
vendor_original_transaction_id: 'GPA.3338-3241-1006-23335',
vendor_product_id: 'weekly.premium.599',
vendor_transaction_id: 'GPA.3338-3241-1006-23335',
will_renew: true,
},
},
segment_hash: 'not implemented',
timestamp: -1,
},
} as const;

/**
* Sample for Event.DidLoadLatestProfile with empty profile (no subscriptions)
* @see cross_platform.yaml#/$events/Event.DidLoadLatestProfile
*/
export const PROFILE_DID_LOAD_LATEST_EMPTY = {
id: 'did_load_latest_profile',
profile: {
profile_id: '8b79ec26-3f3d-482c-99e8-ec745710ef59',
customer_user_id: null,
segment_hash:
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
paid_access_levels: {},
subscriptions: {},
non_subscriptions: {},
},
} as const;

/**
* Sample for Event.OnInstallationDetailsSuccess
* @see cross_platform.yaml#/$events/Event.OnInstallationDetailsSuccess
*/
export const INSTALLATION_DETAILS_SUCCESS = {
id: 'on_installation_details_success',
details: {
app_launch_count: 8,
payload: '{}',
install_time: '2025-12-16T12:08:41.041Z',
install_id: 'some-install-id',
},
} as const;
Loading