├── .gitattributes ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── RNInAppPurchase.podspec ├── android ├── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── net │ └── class101 │ └── iap │ ├── NativeInAppPurchaseModule.java │ ├── RNInAppPurchasePackage.java │ └── internal │ └── utils │ └── ReadableMapUtils.java ├── docs ├── android_1.png ├── ios_1.png └── ios_2.png ├── ios ├── RNInAppPurchase.h ├── RNInAppPurchase.mm └── RNInAppPurchase.xcodeproj │ └── project.pbxproj ├── package.json ├── sample ├── .eslintrc.js ├── .gitignore ├── .prettierrc.js ├── .vscode │ └── settings.json ├── .watchmanconfig ├── App.tsx ├── Gemfile ├── __tests__ │ └── App.test.tsx ├── android │ ├── app │ │ ├── build.gradle │ │ ├── debug.keystore │ │ ├── proguard-rules.pro │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── rninapppurchasesample │ │ │ │ ├── MainActivity.kt │ │ │ │ └── MainApplication.kt │ │ │ └── res │ │ │ ├── drawable │ │ │ └── rn_edit_text_material.xml │ │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ └── settings.gradle ├── app.json ├── babel.config.js ├── index.js ├── ios │ ├── .xcode.env │ ├── Podfile │ ├── Podfile.lock │ ├── RNInAppPurchaseSample.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── RNInAppPurchaseSample.xcscheme │ ├── RNInAppPurchaseSample.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── IDEWorkspaceChecks.plist │ ├── RNInAppPurchaseSample │ │ ├── AppDelegate.h │ │ ├── AppDelegate.mm │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ └── Contents.json │ │ ├── Info.plist │ │ ├── LaunchScreen.storyboard │ │ ├── PrivacyInfo.xcprivacy │ │ └── main.m │ └── RNInAppPurchaseSampleTests │ │ ├── Info.plist │ │ └── RNInAppPurchaseSampleTests.m ├── jest.config.js ├── metro.config.js ├── package.json ├── tsconfig.json └── yarn.lock └── src ├── NativeInAppPurchaseModule.ts └── index.ts /.gitattributes: -------------------------------------------------------------------------------- 1 | *.pbxproj -text -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # OSX 3 | # 4 | .DS_Store 5 | 6 | # node.js 7 | # 8 | node_modules/ 9 | npm-debug.log 10 | yarn-error.log 11 | 12 | 13 | # Xcode 14 | # 15 | build/ 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | xcuserdata 25 | *.xccheckout 26 | *.moved-aside 27 | DerivedData 28 | *.hmap 29 | *.ipa 30 | *.xcuserstate 31 | project.xcworkspace 32 | 33 | 34 | # Android/IntelliJ 35 | # 36 | build/ 37 | .idea 38 | .gradle 39 | local.properties 40 | *.iml 41 | 42 | # BUCK 43 | buck-out/ 44 | \.buckd/ 45 | *.keystore 46 | 47 | .yarn 48 | .bundle -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | sample 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2019 Injung Chung 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-native-in-app-purchase 2 | 3 | [![Version](https://img.shields.io/npm/v/@class101/react-native-in-app-purchase.svg?style=flat-square)](https://www.npmjs.com/package/@class101/react-native-in-app-purchase) 4 | [![NPM](https://img.shields.io/npm/dm/@class101/react-native-in-app-purchase.svg?style=flat-square)](https://www.npmjs.com/package/@class101/react-native-in-app-purchase) 5 | [![LICENSE](https://img.shields.io/github/license/pedaling/react-native-in-app-purchase.svg?style=flat-square)](https://www.npmjs.com/package/@class101/react-native-in-app-purchase) 6 | 7 | 👻 A dead simple In-App Purchase library for React Native 8 | 9 | ## Getting started 10 | 11 | ```bash 12 | $ yarn add @class101/react-native-in-app-purchase 13 | 14 | # RN >= 0.60 15 | cd ios && pod install 16 | 17 | # RN < 0.60 18 | react-native link @class101/react-native-in-app-purchase 19 | ``` 20 | 21 | ### Android 22 | 23 | Add `BILLING` permission to the `AndroidManifest.xml`. 24 | 25 | ```xml 26 | 29 | 30 | 31 | 32 | 33 | ... 34 | 35 | ``` 36 | 37 | Create your app on the Google Play Console, and add product in the In-App Products section. Make sure set the product status to **active** so that you can view or purchase it. 38 | 39 | [![link config](docs/android_1.png)](docs/android_1.png?raw=true) 40 | 41 | Note that testing Android In-App Billing is only possible after uploading your APK to Alpha release or above. 42 | 43 | ### iOS 44 | 45 | Add In-App Purchase capability on the Signing & Capabilities section of the project. 46 | 47 | [![link config](docs/ios_1.png)](docs/ios_1.png?raw=true) 48 | 49 | Create your app on the App Store Connect, and add product in the In-App Purchases section. You may need to fill the audit information field. 50 | 51 | [![link config](docs/ios_2.png)](docs/ios_2.png?raw=true) 52 | 53 | Testing iOS In-App Purchase is possible on TestFlight. 54 | 55 | ## Usage 56 | 57 | See full example [here](sample/App.js). This sample can also be downloaded from the [Play Store](https://play.google.com/store/apps/details?id=com.rninapppurchasesample). 58 | 59 | #### 1. Prepare product ids 60 | 61 | Choose the product id that you want to sell. It would be nice to have the same product id for Android and iOS. 62 | 63 | ```javascript 64 | import InAppPurchase from "@class101/react-native-in-app-purchase"; 65 | 66 | const PRODUCT_IDS = [ 67 | "rniap.sample.normal", 68 | "rniap.sample.consumable", 69 | "rniap.sample.subscribe", 70 | ]; 71 | ``` 72 | 73 | #### 2. Add Listeners 74 | 75 | For some reasons, the `purchase` and `fetchProducts` functions are not `Promise`. So you need to register `onPurchase` and `onFetchProducts` listeners. 76 | 77 | ```javascript 78 | const onFetchProducts = (products) => { 79 | this.setState({ products }); 80 | }; 81 | 82 | const onPurchase = (purchase) => { 83 | // Validate payment on your backend server with purchase object. 84 | setTimeout(() => { 85 | // Complete the purchase flow by calling finalize function. 86 | InAppPurchase.finalize( 87 | purchase, 88 | purchase.productId === "rniap.sample.consumable" 89 | ).then(() => { 90 | Alert.alert("In App Purchase", "Purchase Succeed!"); 91 | }); 92 | }); 93 | }; 94 | 95 | const onError = (e) => { 96 | console.log(e); 97 | }; 98 | 99 | InAppPurchase.onFetchProducts(onFetchProducts); 100 | InAppPurchase.onPurchase(onPurchase); 101 | InAppPurchase.onError(onError); 102 | ``` 103 | 104 | After each purchase, you need to verify receipt on your server. If purchase is valid, call `finalize` function in the app. Set whether it is consumable or not as the second argument to the `finalize` function. 105 | 106 | #### 3. Configure and Fetch Products 107 | 108 | Once you have registered your listeners, call `configure` and `fetchProducts`. Since the library will initialize billingClient only once, you can call `configure`, `fetchProducts` multiple times. 109 | 110 | ```javascript 111 | InAppPurchase.configure().then(() => { 112 | InAppPurchase.fetchProducts(PRODUCT_IDS); 113 | }); 114 | ``` 115 | 116 | #### 4. Purchase Product 117 | 118 | Call `InAppPurchase.purchase` with product id. 119 | 120 | ```javascript 121 | InAppPurchase.purchase(item.productId); // 'rniap.sample.consumable' 122 | ``` 123 | 124 | #### 5. Retry 125 | 126 | In some cases, your app may not be able to call the `finalize` function even the purchase was successful. (such as poor internet connection) Purchases that are not finalized can be retrieved with the `flush` function. Send these purchases to the server to verify, and then call the `finalize` function. 127 | 128 | ```javascript 129 | InAppPurchase.flush().then((purchases) => { 130 | purchases.forEach(onPurchase); 131 | }); 132 | ``` 133 | 134 | ## Type Definitions 135 | 136 | Type definitions of Product, Purchase and InAppPurchaseError. 137 | 138 | #### Product 139 | 140 | | Property | Type | Comment | 141 | | ----------- | ------ | --------------------------- | 142 | | productId | string | - | 143 | | price | string | - | 144 | | currency | string | Currency code (USD, KRW...) | 145 | | title | string | - | 146 | | description | string | - | 147 | 148 | #### Purchase 149 | 150 | | Property | Type | Comment | 151 | | --------------- | -------- | ---------------------------------------------- | 152 | | productIds | string[] | - | 153 | | transactionId | string | - | 154 | | transactionDate | string | - | 155 | | receipt | string | Use this property to validate iOS purchase | 156 | | purchaseToken | string | Use this property to validate Android purchase | 157 | 158 | #### InAppPurchaseError 159 | 160 | | Property | Type | Comment | 161 | | -------- | ------------------------------------ | --------------------------------------------- | 162 | | type | FETCH_PRODUCTS, PURCHASE, CONNECTION | `CONNECTION` error is only occurs on Android. | 163 | | code | number | - | 164 | | message | string | - | 165 | 166 | ## Receipt Verification 167 | 168 | Actually this isn't something that should be mentioned in this document. However, since it's critical part of implementing In-App Purchase flow, I'll show you how I implemented it. 169 | 170 | #### Client Side 171 | 172 | ```typescript 173 | const onPurchase = useCallback( 174 | (result: Purchase) => { 175 | return verifyReceipt({ 176 | variables: { 177 | input: { 178 | platform: Platform.select({ 179 | ios: "apple", 180 | android: "google", 181 | }), 182 | productId: result.productIds[0], 183 | receipt: Platform.select({ 184 | ios: result.receipt, 185 | android: result.purchaseToken, 186 | }), 187 | }, 188 | }, 189 | }) 190 | .then(() => InAppPurchase.finalize(result, true)) 191 | .then(() => 192 | Alert.alert( 193 | LocalizedStrings.COIN_PURCHASE_SUCCESS_TITLE, 194 | LocalizedStrings.COIN_PURCHASE_SUCCESS_MESSAGE 195 | ) 196 | ) 197 | .catch((e) => Alert.alert(LocalizedStrings.COMMON_ERROR, e.message)) 198 | .finally(() => setIsLoading(false)); 199 | }, 200 | [setIsLoading, verifyReceipt] 201 | ); 202 | ``` 203 | 204 | #### Server Side 205 | 206 | Here I used [node-iap](https://github.com/Wizcorp/node-iap) library. 207 | 208 | ```typescript 209 | class VerifyReceipt extends Interactor { 210 | public async perform() { 211 | const { user, platform, productId, receipt, language } = this.context; 212 | 213 | if (!["apple", "google"].includes(platform)) { 214 | throw new functions.https.HttpsError( 215 | "invalid-argument", 216 | LocalizedStrings(language).ERROR_RECEIPT_VALIDATE_FAILURE 217 | ); 218 | } 219 | 220 | return new Promise((resolve, reject) => { 221 | iap.verifyPayment( 222 | platform, 223 | { 224 | receipt, 225 | productId, 226 | packageName: PACKAGE_NAME, 227 | keyObject: require("../../../iapServiceAccountKey.json"), 228 | }, 229 | async (error, response) => { 230 | if (error) { 231 | return reject( 232 | new functions.https.HttpsError("aborted", error.message) 233 | ); 234 | } 235 | 236 | // If it's already consumed 237 | if (platform === "google" && response.receipt.purchase_state === 1) { 238 | return reject( 239 | new functions.https.HttpsError( 240 | "unavailable", 241 | LocalizedStrings(language).ERROR_RECEIPT_NOT_FOUND 242 | ) 243 | ); 244 | } 245 | 246 | const coin = COIN_LIST[language].find((c) => c.id === productId); 247 | 248 | // Unavailable product 249 | if (!coin) { 250 | return reject( 251 | new functions.https.HttpsError( 252 | "unavailable", 253 | LocalizedStrings(language).ERROR_RECEIPT_VALIDATE_FAILURE 254 | ) 255 | ); 256 | } 257 | 258 | const orderId = response.transactionId; 259 | 260 | // If it's already verified 261 | const userRef = firestore().collection("users").doc(user.id); 262 | const transactionSnapshot = await userRef 263 | .collection("transactions") 264 | .where("orderId", "==", orderId) 265 | .get(); 266 | if (transactionSnapshot.docs.length > 0) { 267 | return resolve({ 268 | transaction: transactionSnapshot.docs[0].data() as Transaction, 269 | profile: user, 270 | }); 271 | } 272 | 273 | const now = Date.now(); 274 | const batch = firestore().batch(); 275 | const receiptRef = userRef.collection("receipts").doc(); 276 | const transactionRef = userRef.collection("transactions").doc(); 277 | 278 | const transaction = { 279 | id: transactionRef.id, 280 | description: LocalizedStrings(language).DESCRIPTION_PURCHASE_COIN, 281 | orderId, 282 | amount: coin.amount, 283 | createdAt: now, 284 | }; 285 | 286 | batch.set(receiptRef, { 287 | id: receiptRef.id, 288 | productId, 289 | orderId, 290 | createdAt: now, 291 | }); 292 | 293 | batch.set( 294 | userRef, 295 | { 296 | coin: firestore.FieldValue.increment(coin.amount), 297 | }, 298 | { 299 | merge: true, 300 | } 301 | ); 302 | 303 | batch.set(transactionRef, transaction); 304 | 305 | await batch.commit(); 306 | 307 | resolve({ 308 | transaction, 309 | profile: { 310 | ...user, 311 | coin: user.coin + coin.amount, 312 | }, 313 | }); 314 | } 315 | ); 316 | }); 317 | } 318 | } 319 | ``` 320 | 321 | Note the part _If it's already verified_. Purchases that have already been verified should also return **success**. Otherwise, the item will be provided multiple times when flushing. 322 | 323 | ## Contributing 324 | 325 | Bug reports and pull requests are welcome on [GitHub](https://github.com/pedaling/react-native-in-app-purchase/issues). 326 | 327 | ## License 328 | 329 | The package is available as open source under the terms of the [MIT License](LICENSE). 330 | -------------------------------------------------------------------------------- /RNInAppPurchase.podspec: -------------------------------------------------------------------------------- 1 | require 'json' 2 | 3 | package = JSON.parse(File.read(File.join(__dir__, 'package.json'))) 4 | 5 | Pod::Spec.new do |s| 6 | s.name = "RNInAppPurchase" 7 | s.version = package['version'] 8 | s.summary = package['description'] 9 | s.license = package['license'] 10 | 11 | s.authors = package['author'] 12 | s.homepage = 'https://github.com/pedaling/react-native-in-app-purchase' 13 | s.platform = :ios, "9.0" 14 | s.ios.deployment_target = '9.0' 15 | s.tvos.deployment_target = '10.0' 16 | 17 | s.source = { :git => "https://github.com/pedaling/react-native-in-app-purchase.git", :tag => "v#{s.version}" } 18 | s.source_files = "ios/**/*.{h,m,mm,swift}" 19 | 20 | s.dependency 'React' 21 | 22 | install_modules_dependencies(s) 23 | end 24 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.safeExtGet = { prop -> 3 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : project.properties['ReactNativeIAP_' + prop] 4 | } 5 | repositories { 6 | google() 7 | gradlePluginPortal() 8 | } 9 | dependencies { 10 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet('kotlinVersion')}") 11 | classpath("com.android.tools.build:gradle:7.0.4") 12 | } 13 | } 14 | 15 | def safeExtGet(prop, fallback) { 16 | rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback 17 | } 18 | 19 | def isNewArchitectureEnabled() { 20 | return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true" 21 | } 22 | 23 | apply plugin: 'com.android.library' 24 | apply plugin: 'com.facebook.react' 25 | 26 | android { 27 | compileSdkVersion safeExtGet('compileSdkVersion', 34) 28 | buildToolsVersion safeExtGet('buildToolsVersion', '34.0.0') 29 | 30 | defaultConfig { 31 | minSdkVersion safeExtGet('minSdkVersion', 28) 32 | targetSdkVersion safeExtGet('targetSdkVersion', 34) 33 | buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() 34 | ndk { 35 | abiFilters "armeabi-v7a", "x86" 36 | } 37 | } 38 | buildFeatures { 39 | buildConfig true 40 | } 41 | sourceSets { 42 | main { 43 | if (isNewArchitectureEnabled()) { 44 | java.srcDirs += [ 45 | "generated/java", 46 | "generated/jni" 47 | ] 48 | } 49 | } 50 | } 51 | } 52 | 53 | repositories { 54 | mavenCentral() 55 | google() 56 | } 57 | 58 | dependencies { 59 | implementation 'com.facebook.react:react-native:+' 60 | implementation "com.android.billingclient:billing:${safeExtGet('googleBillingVersion', '7.0.0')}" 61 | } 62 | 63 | if (isNewArchitectureEnabled()) { 64 | react { 65 | jsRootDir = file("../src") 66 | libraryName = "InAppPurchase" 67 | codegenJavaPackageName = "net.class101.iap" 68 | } 69 | } -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | # This is normally unused 84 | # shellcheck disable=SC2034 85 | APP_BASE_NAME=${0##*/} 86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit 88 | 89 | # Use the maximum available, or set MAX_FD != -1 to use that value. 90 | MAX_FD=maximum 91 | 92 | warn () { 93 | echo "$*" 94 | } >&2 95 | 96 | die () { 97 | echo 98 | echo "$*" 99 | echo 100 | exit 1 101 | } >&2 102 | 103 | # OS specific support (must be 'true' or 'false'). 104 | cygwin=false 105 | msys=false 106 | darwin=false 107 | nonstop=false 108 | case "$( uname )" in #( 109 | CYGWIN* ) cygwin=true ;; #( 110 | Darwin* ) darwin=true ;; #( 111 | MSYS* | MINGW* ) msys=true ;; #( 112 | NONSTOP* ) nonstop=true ;; 113 | esac 114 | 115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 116 | 117 | 118 | # Determine the Java command to use to start the JVM. 119 | if [ -n "$JAVA_HOME" ] ; then 120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 121 | # IBM's JDK on AIX uses strange locations for the executables 122 | JAVACMD=$JAVA_HOME/jre/sh/java 123 | else 124 | JAVACMD=$JAVA_HOME/bin/java 125 | fi 126 | if [ ! -x "$JAVACMD" ] ; then 127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 128 | 129 | Please set the JAVA_HOME variable in your environment to match the 130 | location of your Java installation." 131 | fi 132 | else 133 | JAVACMD=java 134 | if ! command -v java >/dev/null 2>&1 135 | then 136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | fi 142 | 143 | # Increase the maximum file descriptors if we can. 144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 145 | case $MAX_FD in #( 146 | max*) 147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 148 | # shellcheck disable=SC2039,SC3045 149 | MAX_FD=$( ulimit -H -n ) || 150 | warn "Could not query maximum file descriptor limit" 151 | esac 152 | case $MAX_FD in #( 153 | '' | soft) :;; #( 154 | *) 155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 156 | # shellcheck disable=SC2039,SC3045 157 | ulimit -n "$MAX_FD" || 158 | warn "Could not set maximum file descriptor limit to $MAX_FD" 159 | esac 160 | fi 161 | 162 | # Collect all arguments for the java command, stacking in reverse order: 163 | # * args from the command line 164 | # * the main class name 165 | # * -classpath 166 | # * -D...appname settings 167 | # * --module-path (only if needed) 168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 169 | 170 | # For Cygwin or MSYS, switch paths to Windows format before running java 171 | if "$cygwin" || "$msys" ; then 172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 174 | 175 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 176 | 177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 178 | for arg do 179 | if 180 | case $arg in #( 181 | -*) false ;; # don't mess with options #( 182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 183 | [ -e "$t" ] ;; #( 184 | *) false ;; 185 | esac 186 | then 187 | arg=$( cygpath --path --ignore --mixed "$arg" ) 188 | fi 189 | # Roll the args list around exactly as many times as the number of 190 | # args, so each arg winds up back in the position where it started, but 191 | # possibly modified. 192 | # 193 | # NB: a `for` loop captures its iteration list before it begins, so 194 | # changing the positional parameters here affects neither the number of 195 | # iterations, nor the values presented in `arg`. 196 | shift # remove old arg 197 | set -- "$@" "$arg" # push replacement arg 198 | done 199 | fi 200 | 201 | 202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 204 | 205 | # Collect all arguments for the java command: 206 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, 207 | # and any embedded shellness will be escaped. 208 | # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be 209 | # treated as '${Hostname}' itself on the command line. 210 | 211 | set -- \ 212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 213 | -classpath "$CLASSPATH" \ 214 | org.gradle.wrapper.GradleWrapperMain \ 215 | "$@" 216 | 217 | # Stop when "xargs" is not available. 218 | if ! command -v xargs >/dev/null 2>&1 219 | then 220 | die "xargs is not available" 221 | fi 222 | 223 | # Use "xargs" to parse quoted args. 224 | # 225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 226 | # 227 | # In Bash we could simply go: 228 | # 229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 230 | # set -- "${ARGS[@]}" "$@" 231 | # 232 | # but POSIX shell has neither arrays nor command substitution, so instead we 233 | # post-process each arg (as a line of input to sed) to backslash-escape any 234 | # character that might be a shell metacharacter, then use eval to reverse 235 | # that process (while maintaining the separation between arguments), and wrap 236 | # the whole thing up as a single "set" statement. 237 | # 238 | # This will of course break if any of these variables contains a newline or 239 | # an unmatched quote. 240 | # 241 | 242 | eval "set -- $( 243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 244 | xargs -n1 | 245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 246 | tr '\n' ' ' 247 | )" '"$@"' 248 | 249 | exec "$JAVACMD" "$@" 250 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /android/src/main/java/net/class101/iap/NativeInAppPurchaseModule.java: -------------------------------------------------------------------------------- 1 | package net.class101.iap; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.annotation.Nullable; 5 | 6 | import com.android.billingclient.api.AcknowledgePurchaseParams; 7 | import com.android.billingclient.api.BillingClient; 8 | import com.android.billingclient.api.BillingClientStateListener; 9 | import com.android.billingclient.api.BillingFlowParams; 10 | import com.android.billingclient.api.BillingResult; 11 | import com.android.billingclient.api.ConsumeParams; 12 | import com.android.billingclient.api.PendingPurchasesParams; 13 | import com.android.billingclient.api.ProductDetails; 14 | import com.android.billingclient.api.Purchase; 15 | import com.android.billingclient.api.PurchasesUpdatedListener; 16 | import com.android.billingclient.api.QueryProductDetailsParams; 17 | import com.android.billingclient.api.QueryPurchasesParams; 18 | import com.android.billingclient.api.UserChoiceBillingListener; 19 | import com.android.billingclient.api.UserChoiceDetails; 20 | import com.facebook.common.internal.ImmutableList; 21 | import com.facebook.react.bridge.Arguments; 22 | import com.facebook.react.bridge.Callback; 23 | import com.facebook.react.bridge.Promise; 24 | import com.facebook.react.bridge.ReactApplicationContext; 25 | import com.facebook.react.bridge.ReadableArray; 26 | import com.facebook.react.bridge.ReadableMap; 27 | import com.facebook.react.bridge.WritableArray; 28 | import com.facebook.react.bridge.WritableMap; 29 | import com.facebook.react.bridge.WritableNativeArray; 30 | 31 | import net.class101.iap.internal.utils.ReadableMapUtils; 32 | 33 | import java.util.ArrayList; 34 | import java.util.HashMap; 35 | import java.util.List; 36 | import java.util.Map; 37 | import java.util.Optional; 38 | 39 | public class NativeInAppPurchaseModule extends NativeInAppPurchaseModuleSpec implements PurchasesUpdatedListener, UserChoiceBillingListener { 40 | private final ReactApplicationContext reactContext; 41 | 42 | private final Map productDetailsMap; 43 | 44 | private BillingClient client; 45 | private ReadableMap appliedConfig; 46 | 47 | private Callback fetchProductsListener; 48 | private Callback purchaseListener; 49 | private Callback errorListener; 50 | private Callback alternativeBillingFlowListener; 51 | 52 | public NativeInAppPurchaseModule(ReactApplicationContext reactContext) { 53 | super(reactContext); 54 | this.reactContext = reactContext; 55 | this.productDetailsMap = new HashMap<>(); 56 | } 57 | 58 | @Override 59 | public void configure(@Nullable ReadableMap config, Promise promise) { 60 | if (client != null) { 61 | if (client.isReady() && !hasChangedOptions(appliedConfig, config)) { 62 | promise.resolve(true); 63 | return; 64 | } 65 | 66 | client.endConnection(); 67 | client = null; 68 | } 69 | this.appliedConfig = config; 70 | 71 | BillingClient.Builder builder = BillingClient.newBuilder(reactContext) 72 | .setListener(this) 73 | .enablePendingPurchases(PendingPurchasesParams.newBuilder().enableOneTimeProducts().build()); 74 | 75 | var isAlternativeBillingEnable = Optional.ofNullable(config).map(it -> it.getBoolean("isAlternativeBillingEnable")).orElse(false); 76 | 77 | if (isAlternativeBillingEnable) { 78 | builder.enableUserChoiceBilling(this); 79 | } 80 | 81 | client = builder.build(); 82 | 83 | client.startConnection(new BillingClientStateListener() { 84 | @Override 85 | public void onBillingSetupFinished(@NonNull BillingResult result) { 86 | int code = result.getResponseCode(); 87 | 88 | if (code == BillingClient.BillingResponseCode.OK) { 89 | promise.resolve(true); 90 | } else { 91 | promise.reject("configure", "Billing service setup failed with code " + code); 92 | } 93 | } 94 | 95 | @Override 96 | public void onBillingServiceDisconnected() { 97 | promise.reject("configure", "Billing service disconnected"); 98 | } 99 | }); 100 | } 101 | 102 | @Override 103 | public void fetchProducts(ReadableArray products) { 104 | tryConnect(() -> { 105 | ImmutableList productList = ImmutableList.of(); 106 | 107 | 108 | for (int i = 0; i < products.size(); i++) { 109 | ReadableMap product = products.getMap(i); 110 | 111 | String productId = product.getString("id"); 112 | String productType = product.getString("type"); 113 | 114 | if (productId == null || productType == null) { 115 | continue; 116 | } 117 | 118 | if (!productType.equals(BillingClient.ProductType.SUBS) && !productType.equals(BillingClient.ProductType.INAPP)) { 119 | continue; 120 | } 121 | 122 | productList.add( 123 | QueryProductDetailsParams.Product.newBuilder() 124 | .setProductId(productId) 125 | .setProductType(productType) 126 | .build() 127 | ); 128 | } 129 | 130 | QueryProductDetailsParams params = QueryProductDetailsParams.newBuilder() 131 | .setProductList(productList) 132 | .build(); 133 | 134 | final WritableArray items = new WritableNativeArray(); 135 | 136 | // Query in-app items 137 | client.queryProductDetailsAsync(params, (billingResult, productDetailsList) -> { 138 | if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) { 139 | sendBillingError("FETCH_PRODUCTS", billingResult); 140 | return; 141 | } 142 | 143 | for (int i = 0; i < products.size(); i++) { 144 | ReadableMap product = products.getMap(i); 145 | 146 | String productId = product.getString("id"); 147 | String productType = product.getString("type"); 148 | String planId = product.getString("planId"); 149 | String offerId = product.getString("offerId"); 150 | 151 | if (productId == null || productType == null) { 152 | continue; 153 | } 154 | 155 | if (!productType.equals(BillingClient.ProductType.SUBS) && !productType.equals(BillingClient.ProductType.INAPP)) { 156 | continue; 157 | } 158 | 159 | Optional productDetails = productDetailsList.stream().filter(details -> details.getProductId().equals(productId)).findFirst(); 160 | if (!productDetails.isPresent()) { 161 | continue; 162 | } 163 | 164 | if (productType.equals(BillingClient.ProductType.INAPP)) { 165 | WritableMap item = Arguments.createMap(); 166 | item.putString("productId", productDetails.get().getProductId()); 167 | item.putString("offerId", offerId); 168 | item.putString("title", productDetails.get().getTitle()); 169 | item.putString("description", productDetails.get().getDescription()); 170 | 171 | ProductDetails.OneTimePurchaseOfferDetails offerDetails = productDetails.get().getOneTimePurchaseOfferDetails(); 172 | if (offerDetails != null) { 173 | item.putString("price", offerDetails.getFormattedPrice()); 174 | item.putString("currency", offerDetails.getPriceCurrencyCode()); 175 | } 176 | 177 | items.pushMap(item); 178 | continue; 179 | } 180 | 181 | List offerDetailsList = productDetails.get().getSubscriptionOfferDetails(); 182 | 183 | if (offerDetailsList == null || offerDetailsList.isEmpty()) { 184 | continue; 185 | } 186 | 187 | Optional offerDetails = offerDetailsList.stream() 188 | .filter(details -> planId == null || details.getBasePlanId().equals(planId)) 189 | .filter(details -> offerId == null || (details.getOfferId() != null && details.getOfferId().equals(offerId))) 190 | .findFirst(); 191 | 192 | if (offerDetails.isPresent()) { 193 | WritableMap item = Arguments.createMap(); 194 | item.putString("productId", productDetails.get().getProductId()); 195 | item.putString("planId", planId); 196 | item.putString("offerId", offerId); 197 | item.putString("title", productDetails.get().getTitle()); 198 | item.putString("description", productDetails.get().getDescription()); 199 | item.putString("price", offerDetails.get().getPricingPhases().getPricingPhaseList().get(0).getFormattedPrice()); 200 | item.putString("currency", offerDetails.get().getPricingPhases().getPricingPhaseList().get(0).getPriceCurrencyCode()); 201 | 202 | items.pushMap(item); 203 | } 204 | } 205 | 206 | for (ProductDetails productDetails : productDetailsList) { 207 | productDetailsMap.put(productDetails.getProductId(), productDetails); 208 | } 209 | 210 | if (fetchProductsListener != null) { 211 | fetchProductsListener.invoke(items); 212 | } 213 | }); 214 | }); 215 | } 216 | 217 | @Override 218 | public void flush(Promise promise) { 219 | tryConnect(() -> client.queryPurchasesAsync( 220 | QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.INAPP).build(), 221 | (inAppResult, inAppPurchases) -> { 222 | if (inAppResult.getResponseCode() != BillingClient.BillingResponseCode.OK) { 223 | promise.reject("flush", inAppResult.getDebugMessage()); 224 | return; 225 | } 226 | List purchaseList = new ArrayList<>(inAppPurchases); 227 | 228 | client.queryPurchasesAsync( 229 | QueryPurchasesParams.newBuilder().setProductType(BillingClient.ProductType.SUBS).build(), 230 | (subscriptionResult, subscriptionPurchases) -> { 231 | if (subscriptionResult.getResponseCode() != BillingClient.BillingResponseCode.OK) { 232 | promise.reject("flush", subscriptionResult.getDebugMessage()); 233 | return; 234 | } 235 | 236 | purchaseList.addAll(subscriptionPurchases); 237 | WritableArray items = new WritableNativeArray(); 238 | 239 | for (Purchase purchase : purchaseList) { 240 | if (purchase.isAcknowledged()) { 241 | continue; 242 | } 243 | 244 | ReadableMap item = this.buildPurchaseJSON(purchase); 245 | items.pushMap(item); 246 | } 247 | 248 | promise.resolve(items); 249 | } 250 | ); 251 | } 252 | )); 253 | } 254 | 255 | @Override 256 | public void purchase(String productId, @Nullable ReadableMap args) { 257 | tryConnect(() -> { 258 | if (getCurrentActivity() == null) { 259 | return; 260 | } 261 | 262 | ProductDetails productDetails = productDetailsMap.get(productId); 263 | String obfuscatedAccountId = args != null ? args.getString("obfuscatedAccountId") : null; 264 | String obfuscatedProfileId = args != null ? args.getString("obfuscatedProfileId") : null; 265 | String originalPurchaseToken = args != null ? args.getString("originalPurchaseToken") : null; 266 | 267 | String planId = args != null ? args.getString("planId") : null; 268 | String offerId = args != null ? args.getString("offerId") : null; 269 | 270 | if (productDetails == null) { 271 | return; 272 | } 273 | 274 | BillingFlowParams.Builder builder = BillingFlowParams.newBuilder(); 275 | 276 | if (obfuscatedAccountId != null) { 277 | builder.setObfuscatedAccountId(obfuscatedAccountId); 278 | } 279 | 280 | if (obfuscatedProfileId != null) { 281 | builder.setObfuscatedProfileId(obfuscatedProfileId); 282 | } 283 | 284 | if (originalPurchaseToken != null) { 285 | builder.setSubscriptionUpdateParams( 286 | BillingFlowParams.SubscriptionUpdateParams.newBuilder() 287 | .setOldPurchaseToken(originalPurchaseToken) 288 | .build() 289 | ); 290 | } 291 | 292 | BillingFlowParams.ProductDetailsParams.Builder productDetailsParamsBuilder = BillingFlowParams.ProductDetailsParams.newBuilder(); 293 | List offerDetailsList = productDetails.getSubscriptionOfferDetails(); 294 | 295 | productDetailsParamsBuilder.setProductDetails(productDetails); 296 | 297 | if (offerDetailsList != null) { 298 | offerDetailsList.stream() 299 | .filter(details -> planId == null || details.getBasePlanId().equals(planId)) 300 | .filter(details -> offerId == null || (details.getOfferId() != null && details.getOfferId().equals(offerId))) 301 | .findFirst() 302 | .ifPresent(details -> productDetailsParamsBuilder.setOfferToken(details.getOfferToken())); 303 | } 304 | 305 | ImmutableList productDetailsParamsList = ImmutableList.of(productDetailsParamsBuilder.build()); 306 | BillingFlowParams params = builder.setProductDetailsParamsList(productDetailsParamsList).build(); 307 | 308 | client.launchBillingFlow(getCurrentActivity(), params); 309 | }); 310 | } 311 | 312 | @Override 313 | public void finalize(ReadableMap purchase, boolean isConsumable, final Promise promise) { 314 | tryConnect(() -> { 315 | String token = purchase.getString("purchaseToken"); 316 | 317 | if (token == null) { 318 | return; 319 | } 320 | 321 | if (isConsumable) { 322 | ConsumeParams params = ConsumeParams.newBuilder() 323 | .setPurchaseToken(token) 324 | .build(); 325 | 326 | client.consumeAsync(params, (result, purchaseToken) -> { 327 | if (result.getResponseCode() != BillingClient.BillingResponseCode.OK) { 328 | promise.reject("finalize", result.getDebugMessage()); 329 | return; 330 | } 331 | 332 | WritableMap event = Arguments.createMap(); 333 | event.putString("message", result.getDebugMessage()); 334 | 335 | promise.resolve(event); 336 | }); 337 | return; 338 | } 339 | 340 | AcknowledgePurchaseParams acknowledgePurchaseParams = AcknowledgePurchaseParams.newBuilder() 341 | .setPurchaseToken(token) 342 | .build(); 343 | 344 | client.acknowledgePurchase(acknowledgePurchaseParams, (result) -> { 345 | if (result.getResponseCode() != BillingClient.BillingResponseCode.OK) { 346 | promise.reject("finalize", result.getDebugMessage()); 347 | return; 348 | } 349 | 350 | WritableMap event = Arguments.createMap(); 351 | event.putString("message", result.getDebugMessage()); 352 | 353 | promise.resolve(event); 354 | }); 355 | }); 356 | } 357 | 358 | @Override 359 | public void fetchReceipt(Promise promise) { 360 | promise.reject("fetchReceipt", "Not implemented"); 361 | } 362 | 363 | @Override 364 | public void onFetchProducts(Callback listener) { 365 | this.fetchProductsListener = listener; 366 | } 367 | 368 | @Override 369 | public void onPurchase(Callback listener) { 370 | this.purchaseListener = listener; 371 | } 372 | 373 | @Override 374 | public void onAlternativeBillingFlow(Callback listener) { 375 | this.alternativeBillingFlowListener = listener; 376 | } 377 | 378 | @Override 379 | public void onError(Callback listener) { 380 | this.errorListener = listener; 381 | } 382 | 383 | @Override 384 | public void clear() { 385 | this.fetchProductsListener = null; 386 | this.purchaseListener = null; 387 | this.errorListener = null; 388 | this.alternativeBillingFlowListener = null; 389 | } 390 | 391 | @Override 392 | public void onPurchasesUpdated(@NonNull BillingResult billingResult, @Nullable List purchases) { 393 | if (billingResult.getResponseCode() != BillingClient.BillingResponseCode.OK) { 394 | sendBillingError("PURCHASE", billingResult); 395 | return; 396 | } 397 | 398 | if (purchases != null) { 399 | for (Purchase purchase : purchases) { 400 | ReadableMap item = this.buildPurchaseJSON(purchase); 401 | this.purchaseListener.invoke(item); 402 | } 403 | } 404 | } 405 | 406 | @Override 407 | public void userSelectedAlternativeBilling(@NonNull UserChoiceDetails userChoiceDetails) { 408 | if (this.alternativeBillingFlowListener == null) { 409 | return; 410 | } 411 | 412 | this.alternativeBillingFlowListener.invoke(userChoiceDetails.getExternalTransactionToken()); 413 | } 414 | 415 | private boolean hasChangedOptions(ReadableMap appliedConfig, ReadableMap newConfig) { 416 | return !ReadableMapUtils.deepEquals(appliedConfig, newConfig); 417 | } 418 | 419 | 420 | private void tryConnect(final Runnable runnable) { 421 | if (client.isReady()) { 422 | runnable.run(); 423 | return; 424 | } 425 | 426 | client.startConnection(new BillingClientStateListener() { 427 | @Override 428 | public void onBillingSetupFinished(@NonNull BillingResult result) { 429 | if (result.getResponseCode() == BillingClient.BillingResponseCode.OK) { 430 | runnable.run(); 431 | } else { 432 | sendBillingError("CONNECTION", result); 433 | } 434 | } 435 | 436 | @Override 437 | public void onBillingServiceDisconnected() { 438 | } 439 | }); 440 | } 441 | 442 | private void sendBillingError(String type, BillingResult result) { 443 | WritableMap exception = Arguments.createMap(); 444 | exception.putString("type", type); 445 | exception.putInt("code", result.getResponseCode()); 446 | exception.putString("message", result.getDebugMessage()); 447 | 448 | if (errorListener != null) { 449 | errorListener.invoke(exception); 450 | } 451 | } 452 | 453 | private ReadableMap buildPurchaseJSON(Purchase purchase) { 454 | WritableMap item = Arguments.createMap(); 455 | WritableArray productIds = Arguments.createArray(); 456 | for (String sku : purchase.getProducts()) { 457 | productIds.pushString(sku); 458 | } 459 | item.putArray("productIds", productIds); 460 | item.putString("transactionId", purchase.getOrderId()); 461 | item.putString("transactionDate", String.valueOf(purchase.getPurchaseTime())); 462 | item.putString("receipt", purchase.getOriginalJson()); 463 | item.putString("purchaseToken", purchase.getPurchaseToken()); 464 | 465 | return item; 466 | } 467 | } 468 | 469 | -------------------------------------------------------------------------------- /android/src/main/java/net/class101/iap/RNInAppPurchasePackage.java: -------------------------------------------------------------------------------- 1 | package net.class101.iap; 2 | 3 | import androidx.annotation.NonNull; 4 | import androidx.annotation.Nullable; 5 | 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | 9 | import com.facebook.react.TurboReactPackage; 10 | import com.facebook.react.bridge.NativeModule; 11 | import com.facebook.react.bridge.ReactApplicationContext; 12 | import com.facebook.react.module.model.ReactModuleInfo; 13 | import com.facebook.react.module.model.ReactModuleInfoProvider; 14 | 15 | public class RNInAppPurchasePackage extends TurboReactPackage { 16 | 17 | @Nullable 18 | @Override 19 | public NativeModule getModule(@NonNull String name, @NonNull ReactApplicationContext reactApplicationContext) { 20 | if (name.equals(NativeInAppPurchaseModule.NAME)) { 21 | return new NativeInAppPurchaseModule(reactApplicationContext); 22 | } else { 23 | return null; 24 | } 25 | } 26 | 27 | @Override 28 | public ReactModuleInfoProvider getReactModuleInfoProvider() { 29 | return () -> { 30 | final Map moduleInfos = new HashMap<>(); 31 | boolean isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; 32 | 33 | moduleInfos.put( 34 | NativeInAppPurchaseModule.NAME, 35 | new ReactModuleInfo( 36 | NativeInAppPurchaseModule.NAME, 37 | NativeInAppPurchaseModule.NAME, 38 | false, // canOverrideExistingModule 39 | false, // needsEagerInit 40 | false, // isCxxModule 41 | isTurboModule 42 | )); 43 | return moduleInfos; 44 | }; 45 | } 46 | } -------------------------------------------------------------------------------- /android/src/main/java/net/class101/iap/internal/utils/ReadableMapUtils.java: -------------------------------------------------------------------------------- 1 | package net.class101.iap.internal.utils; 2 | 3 | import com.facebook.react.bridge.Dynamic; 4 | import com.facebook.react.bridge.ReadableArray; 5 | import com.facebook.react.bridge.ReadableMap; 6 | import com.facebook.react.bridge.ReadableMapKeySetIterator; 7 | 8 | public class ReadableMapUtils { 9 | public static boolean deepEquals(ReadableMap map1, ReadableMap map2) { 10 | if (map1 == null && map2 == null) { 11 | return true; 12 | } 13 | if (map1 == null || map2 == null) { 14 | return false; 15 | } 16 | 17 | ReadableMapKeySetIterator iterator = map1.keySetIterator(); 18 | while (iterator.hasNextKey()) { 19 | String key = iterator.nextKey(); 20 | if (!map2.hasKey(key) || !deepEquals(map1.getDynamic(key), map2.getDynamic(key))) { 21 | return false; 22 | } 23 | } 24 | 25 | iterator = map2.keySetIterator(); 26 | while (iterator.hasNextKey()) { 27 | String key = iterator.nextKey(); 28 | if (!map1.hasKey(key)) { 29 | return false; 30 | } 31 | } 32 | 33 | return true; 34 | } 35 | 36 | private static boolean deepEquals(Dynamic value1, Dynamic value2) { 37 | if (value1.getType() != value2.getType()) return false; 38 | switch (value1.getType()) { 39 | case Null: 40 | return true; 41 | case Boolean: 42 | return value1.asBoolean() == value2.asBoolean(); 43 | case Number: 44 | return value1.asDouble() == value2.asDouble(); 45 | case String: 46 | return value1.asString().equals(value2.asString()); 47 | case Map: 48 | return deepEquals(value1.asMap(), value2.asMap()); 49 | case Array: 50 | return deepEquals(value1.asArray(), value2.asArray()); 51 | default: 52 | return false; 53 | } 54 | } 55 | 56 | private static boolean deepEquals(ReadableArray array1, ReadableArray array2) { 57 | if (array1.size() != array2.size()) return false; 58 | for (int i = 0; i < array1.size(); i++) { 59 | if (!deepEquals(array1.getDynamic(i), array2.getDynamic(i))) return false; 60 | } 61 | return true; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /docs/android_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/docs/android_1.png -------------------------------------------------------------------------------- /docs/ios_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/docs/ios_1.png -------------------------------------------------------------------------------- /docs/ios_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/docs/ios_2.png -------------------------------------------------------------------------------- /ios/RNInAppPurchase.h: -------------------------------------------------------------------------------- 1 | #ifndef RNInAppPurchase_h 2 | #define RNInAppPurchase_h 3 | 4 | #import 5 | #import 6 | #import 7 | 8 | #ifdef RCT_NEW_ARCH_ENABLED 9 | #import 10 | #endif /* RCT_NEW_ARCH_ENABLED */ 11 | 12 | @interface RNInAppPurchase : 13 | #ifdef RCT_NEW_ARCH_ENABLED 14 | NSObject 15 | #else 16 | RCTEventEmitter 17 | #endif /* RCT_NEW_ARCH_ENABLED */ 18 | { 19 | NSMutableDictionary* productsMap; 20 | NSMutableDictionary* transactionsMap; 21 | 22 | RCTResponseSenderBlock fetchProductsListener; 23 | RCTResponseSenderBlock purchaseListener; 24 | RCTResponseSenderBlock errorListener; 25 | RCTResponseSenderBlock alternativeBillingFlowListener; 26 | } 27 | @end 28 | 29 | #endif /* RNInAppPurchase_h */ 30 | 31 | -------------------------------------------------------------------------------- /ios/RNInAppPurchase.mm: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import 5 | #import "RNInAppPurchase.h" 6 | 7 | #import 8 | 9 | @implementation RNInAppPurchase 10 | 11 | - (instancetype) init { 12 | if (self = [super init]) { 13 | [[SKPaymentQueue defaultQueue] addTransactionObserver: self]; 14 | } 15 | productsMap = [[NSMutableDictionary alloc] init]; 16 | transactionsMap = [[NSMutableDictionary alloc] init]; 17 | 18 | return self; 19 | } 20 | 21 | - (void) dealloc { 22 | [[SKPaymentQueue defaultQueue] removeTransactionObserver: self]; 23 | } 24 | 25 | + (BOOL) requiresMainQueueSetup { 26 | return YES; 27 | } 28 | 29 | RCT_EXPORT_MODULE(); 30 | 31 | RCT_EXPORT_METHOD(fetchProducts: (NSArray*) products) { 32 | NSSet* identifiers = [NSSet setWithArray: [products valueForKey: @"id"]]; 33 | SKProductsRequest* productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers: identifiers]; 34 | productsRequest.delegate = self; 35 | [productsRequest start]; 36 | } 37 | 38 | RCT_EXPORT_METHOD(onFetchProducts:(RCTResponseSenderBlock)listener) { 39 | fetchProductsListener = listener; 40 | } 41 | 42 | RCT_EXPORT_METHOD(onPurchase:(RCTResponseSenderBlock)listener) { 43 | purchaseListener = listener; 44 | } 45 | 46 | RCT_EXPORT_METHOD(onAlternativeBillingFlow:(RCTResponseSenderBlock)listener) { 47 | alternativeBillingFlowListener = listener; 48 | } 49 | 50 | RCT_EXPORT_METHOD(onError:(RCTResponseSenderBlock)listener) { 51 | errorListener = listener; 52 | } 53 | 54 | RCT_EXPORT_METHOD(flush: (RCTPromiseResolveBlock) resolve 55 | rejector: (RCTPromiseRejectBlock) reject) { 56 | NSArray* transactions = [[SKPaymentQueue defaultQueue] transactions]; 57 | NSMutableArray* items = [NSMutableArray array]; 58 | 59 | for (SKPaymentTransaction* transaction in transactions) { 60 | NSURL* receiptURL = [[NSBundle mainBundle] appStoreReceiptURL]; 61 | NSData* receipt = [[NSData alloc] initWithContentsOfURL: receiptURL]; 62 | 63 | if (!receipt) { 64 | [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; 65 | continue; 66 | } 67 | 68 | if (!transaction.transactionIdentifier) { 69 | continue; 70 | } 71 | 72 | NSArray* productIds = @[transaction.payment.productIdentifier]; 73 | NSDictionary* item = @{ 74 | @"productIds": productIds, 75 | @"transactionId": transaction.transactionIdentifier, 76 | @"transactionDate": @(transaction.transactionDate.timeIntervalSince1970 * 1000), 77 | @"receipt": [receipt base64EncodedStringWithOptions: 0] 78 | }; 79 | 80 | [transactionsMap setObject: transaction forKey: transaction.transactionIdentifier]; 81 | [items addObject: item]; 82 | } 83 | 84 | resolve(items); 85 | } 86 | 87 | 88 | - (void) paymentQueue: (SKPaymentQueue*) queue updatedTransactions: (NSArray*) transactions { 89 | for (SKPaymentTransaction* transaction in transactions) { 90 | switch (transaction.transactionState) { 91 | case SKPaymentTransactionStatePurchased: { 92 | NSURL* receiptURL = [[NSBundle mainBundle] appStoreReceiptURL]; 93 | NSData* receipt = [[NSData alloc] initWithContentsOfURL: receiptURL]; 94 | 95 | if (!receipt) { 96 | [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; 97 | return; 98 | } 99 | 100 | NSArray* productIds = @[transaction.payment.productIdentifier]; 101 | NSDictionary* item = @{ 102 | @"productIds": productIds, 103 | @"transactionId": transaction.transactionIdentifier, 104 | @"transactionDate": @(transaction.transactionDate.timeIntervalSince1970 * 1000), 105 | @"receipt": [receipt base64EncodedStringWithOptions: 0] 106 | }; 107 | 108 | [transactionsMap setObject: transaction forKey: transaction.transactionIdentifier]; 109 | purchaseListener(@[item]); 110 | break; 111 | } 112 | case SKPaymentTransactionStateFailed: { 113 | [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; 114 | NSDictionary* error = @{ 115 | @"code": [@(transaction.error.code) stringValue], 116 | @"message": transaction.error.localizedDescription 117 | }; 118 | [self sendError: @"PURCHASE" body: error]; 119 | break; 120 | } 121 | case SKPaymentTransactionStateRestored: 122 | [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; 123 | break; 124 | case SKPaymentTransactionStateDeferred: 125 | break; 126 | case SKPaymentTransactionStatePurchasing: 127 | break; 128 | } 129 | } 130 | } 131 | 132 | - (void) productsRequest: (SKProductsRequest*) request didReceiveResponse: (SKProductsResponse*) response { 133 | NSMutableArray* items = [NSMutableArray array]; 134 | 135 | for (SKProduct* product in response.products) { 136 | NSString* title = product.localizedTitle ? product.localizedTitle : @""; 137 | NSString* description = product.localizedDescription ? product.localizedDescription : @""; 138 | NSString* currency = @""; 139 | 140 | if (@available(iOS 10.0, *)) { 141 | currency = product.priceLocale.currencyCode; 142 | } 143 | 144 | NSDictionary* item = @{ 145 | @"productId": product.productIdentifier, 146 | @"price": [product.price stringValue], 147 | @"currency": currency, 148 | @"title": title, 149 | @"description": description 150 | }; 151 | [items addObject: item]; 152 | [productsMap setObject: product forKey: product.productIdentifier]; 153 | } 154 | 155 | fetchProductsListener(@[items]); // or iap:onFetchProductsFailure 156 | } 157 | 158 | - (void) sendError: (NSString*) errorType body: (NSDictionary*) body { 159 | NSMutableDictionary *mutableDict = [body mutableCopy]; 160 | [mutableDict setObject:errorType forKey:@"type"]; 161 | errorListener(@[mutableDict]); 162 | } 163 | 164 | 165 | RCT_EXPORT_METHOD(clear) { 166 | 167 | } 168 | 169 | 170 | RCT_EXPORT_METHOD(fetchReceipt: (RCTPromiseResolveBlock) resolve 171 | rejector: (RCTPromiseRejectBlock) reject) { 172 | NSURL* receiptURL = [[NSBundle mainBundle] appStoreReceiptURL]; 173 | NSData* receipt = [[NSData alloc] initWithContentsOfURL: receiptURL]; 174 | 175 | if (receipt == nil) { 176 | resolve(nil); 177 | return; 178 | } 179 | 180 | NSString* encodedReceipt = [receipt base64EncodedStringWithOptions: 0]; 181 | resolve(encodedReceipt); 182 | } 183 | 184 | #if RCT_NEW_ARCH_ENABLED 185 | RCT_EXPORT_METHOD(configure:(JS::NativeInAppPurchaseModule::SpecConfigureConfig &)config 186 | resolve:(RCTPromiseResolveBlock)resolve 187 | reject:(RCTPromiseRejectBlock)reject) { 188 | resolve(@([SKPaymentQueue canMakePayments])); 189 | } 190 | 191 | RCT_EXPORT_METHOD(purchase:(NSString *)productId 192 | args:(JS::NativeInAppPurchaseModule::PurchaseArgs &)args) { 193 | SKProduct* product = productsMap[productId]; 194 | 195 | if (!product) { 196 | [self sendError:@"PURCHASE" body: @{ @"message": @"Invalid product id" }]; 197 | return; 198 | } 199 | 200 | SKMutablePayment* payment = [SKMutablePayment paymentWithProduct: product]; 201 | payment.applicationUsername = args.userId(); 202 | 203 | if (@available(iOS 12.2, *)) { 204 | NSUUID* nonce = nil; 205 | if (args.nonce() != nil) { 206 | nonce = [[NSUUID new] initWithUUIDString:args.nonce()]; 207 | } 208 | 209 | if (args.offerId() != nil && args.keyIdentifier() != nil && nonce != nil && args.signature() != nil && args.timestamp() != std::nullopt) { 210 | SKPaymentDiscount* paymentDiscount = [[SKPaymentDiscount new] initWithIdentifier:args.offerId() keyIdentifier:args.keyIdentifier() nonce:nonce signature:args.signature() timestamp:[NSNumber numberWithDouble: args.timestamp().value()]]; 211 | payment.paymentDiscount = paymentDiscount; 212 | } 213 | } 214 | 215 | [[SKPaymentQueue defaultQueue] addPayment: payment]; 216 | } 217 | 218 | RCT_EXPORT_METHOD(finalize:(JS::NativeInAppPurchaseModule::Purchase &)purchase 219 | isConsumable:(BOOL)isConsumable 220 | resolve:(RCTPromiseResolveBlock)resolve 221 | reject:(RCTPromiseRejectBlock)reject) { 222 | NSString* transactionId = purchase.transactionId(); 223 | SKPaymentTransaction* transaction = transactionsMap[transactionId]; 224 | [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; 225 | resolve(@{ @"message": @"Finalize success" }); 226 | } 227 | 228 | - (std::shared_ptr)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params { 229 | return std::make_shared(params); 230 | } 231 | 232 | #else 233 | RCT_EXPORT_METHOD(configure: (NSDictionary*) config 234 | resolver: (RCTPromiseResolveBlock) resolve 235 | rejector: (RCTPromiseRejectBlock) reject) { 236 | resolve(@([SKPaymentQueue canMakePayments])); 237 | } 238 | 239 | RCT_EXPORT_METHOD(purchase: (NSString*) productId 240 | extras: (NSDictionary*) extras) { 241 | SKProduct* product = productsMap[productId]; 242 | 243 | if (!product) { 244 | [self sendError:@"PURCHASE" body: @{ @"message": @"Invalid product id" }]; 245 | return; 246 | } 247 | 248 | NSString* offerId = extras[@"offerId"]; 249 | NSString* userId = extras[@"userId"]; 250 | NSString* keyIdentifier = extras[@"keyIdentifier"]; 251 | NSString* nonceString = extras[@"nonce"]; 252 | NSString* signature = extras[@"signature"]; 253 | NSNumber* timestamp = extras[@"timestamp"]; 254 | 255 | SKMutablePayment* payment = [SKMutablePayment paymentWithProduct: product]; 256 | payment.applicationUsername = userId; 257 | 258 | if (@available(iOS 12.2, *)) { 259 | NSUUID* nonce = nil; 260 | if (nonceString != nil) { 261 | nonce = [[NSUUID new] initWithUUIDString:nonceString]; 262 | } 263 | 264 | if (offerId != nil && keyIdentifier != nil && nonce != nil && signature != nil && timestamp != nil) { 265 | SKPaymentDiscount* paymentDiscount = [[SKPaymentDiscount new] initWithIdentifier:offerId keyIdentifier:keyIdentifier nonce:nonce signature:signature timestamp:timestamp]; 266 | payment.paymentDiscount = paymentDiscount; 267 | } 268 | } 269 | 270 | [[SKPaymentQueue defaultQueue] addPayment: payment]; 271 | } 272 | 273 | RCT_EXPORT_METHOD(finalize: (NSDictionary*) purchase 274 | resolver: (RCTPromiseResolveBlock) resolve 275 | rejector: (RCTPromiseRejectBlock) reject) { 276 | NSString* transactionId = purchase[@"transactionId"]; 277 | SKPaymentTransaction* transaction = transactionsMap[transactionId]; 278 | [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; 279 | resolve(@{ @"message": @"Finalize success" }); 280 | } 281 | 282 | #endif /* RCT_NEW_ARCH_ENABLED */ 283 | 284 | @end 285 | -------------------------------------------------------------------------------- /ios/RNInAppPurchase.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | B3E7B58A1CC2AC0600A0062D /* RNInAppPurchase.m in Sources */ = {isa = PBXBuildFile; fileRef = B3E7B5891CC2AC0600A0062D /* RNInAppPurchase.m */; }; 11 | /* End PBXBuildFile section */ 12 | 13 | /* Begin PBXCopyFilesBuildPhase section */ 14 | 58B511D91A9E6C8500147676 /* CopyFiles */ = { 15 | isa = PBXCopyFilesBuildPhase; 16 | buildActionMask = 2147483647; 17 | dstPath = "include/$(PRODUCT_NAME)"; 18 | dstSubfolderSpec = 16; 19 | files = ( 20 | ); 21 | runOnlyForDeploymentPostprocessing = 0; 22 | }; 23 | /* End PBXCopyFilesBuildPhase section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 134814201AA4EA6300B7C361 /* libRNInAppPurchase.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNInAppPurchase.a; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | B3E7B5881CC2AC0600A0062D /* RNInAppPurchase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNInAppPurchase.h; sourceTree = ""; }; 28 | B3E7B5891CC2AC0600A0062D /* RNInAppPurchase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNInAppPurchase.m; sourceTree = ""; }; 29 | /* End PBXFileReference section */ 30 | 31 | /* Begin PBXFrameworksBuildPhase section */ 32 | 58B511D81A9E6C8500147676 /* Frameworks */ = { 33 | isa = PBXFrameworksBuildPhase; 34 | buildActionMask = 2147483647; 35 | files = ( 36 | ); 37 | runOnlyForDeploymentPostprocessing = 0; 38 | }; 39 | /* End PBXFrameworksBuildPhase section */ 40 | 41 | /* Begin PBXGroup section */ 42 | 134814211AA4EA7D00B7C361 /* Products */ = { 43 | isa = PBXGroup; 44 | children = ( 45 | 134814201AA4EA6300B7C361 /* libRNInAppPurchase.a */, 46 | ); 47 | name = Products; 48 | sourceTree = ""; 49 | }; 50 | 58B511D21A9E6C8500147676 = { 51 | isa = PBXGroup; 52 | children = ( 53 | B3E7B5881CC2AC0600A0062D /* RNInAppPurchase.h */, 54 | B3E7B5891CC2AC0600A0062D /* RNInAppPurchase.m */, 55 | 134814211AA4EA7D00B7C361 /* Products */, 56 | ); 57 | sourceTree = ""; 58 | }; 59 | /* End PBXGroup section */ 60 | 61 | /* Begin PBXNativeTarget section */ 62 | 58B511DA1A9E6C8500147676 /* RNInAppPurchase */ = { 63 | isa = PBXNativeTarget; 64 | buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNInAppPurchase" */; 65 | buildPhases = ( 66 | 58B511D71A9E6C8500147676 /* Sources */, 67 | 58B511D81A9E6C8500147676 /* Frameworks */, 68 | 58B511D91A9E6C8500147676 /* CopyFiles */, 69 | ); 70 | buildRules = ( 71 | ); 72 | dependencies = ( 73 | ); 74 | name = RNInAppPurchase; 75 | productName = RCTDataManager; 76 | productReference = 134814201AA4EA6300B7C361 /* libRNInAppPurchase.a */; 77 | productType = "com.apple.product-type.library.static"; 78 | }; 79 | /* End PBXNativeTarget section */ 80 | 81 | /* Begin PBXProject section */ 82 | 58B511D31A9E6C8500147676 /* Project object */ = { 83 | isa = PBXProject; 84 | attributes = { 85 | LastUpgradeCheck = 0830; 86 | ORGANIZATIONNAME = Facebook; 87 | TargetAttributes = { 88 | 58B511DA1A9E6C8500147676 = { 89 | CreatedOnToolsVersion = 6.1.1; 90 | }; 91 | }; 92 | }; 93 | buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNInAppPurchase" */; 94 | compatibilityVersion = "Xcode 3.2"; 95 | developmentRegion = English; 96 | hasScannedForEncodings = 0; 97 | knownRegions = ( 98 | en, 99 | ); 100 | mainGroup = 58B511D21A9E6C8500147676; 101 | productRefGroup = 58B511D21A9E6C8500147676; 102 | projectDirPath = ""; 103 | projectRoot = ""; 104 | targets = ( 105 | 58B511DA1A9E6C8500147676 /* RNInAppPurchase */, 106 | ); 107 | }; 108 | /* End PBXProject section */ 109 | 110 | /* Begin PBXSourcesBuildPhase section */ 111 | 58B511D71A9E6C8500147676 /* Sources */ = { 112 | isa = PBXSourcesBuildPhase; 113 | buildActionMask = 2147483647; 114 | files = ( 115 | B3E7B58A1CC2AC0600A0062D /* RNInAppPurchase.m in Sources */, 116 | ); 117 | runOnlyForDeploymentPostprocessing = 0; 118 | }; 119 | /* End PBXSourcesBuildPhase section */ 120 | 121 | /* Begin XCBuildConfiguration section */ 122 | 58B511ED1A9E6C8500147676 /* Debug */ = { 123 | isa = XCBuildConfiguration; 124 | buildSettings = { 125 | ALWAYS_SEARCH_USER_PATHS = NO; 126 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 127 | CLANG_CXX_LIBRARY = "libc++"; 128 | CLANG_ENABLE_MODULES = YES; 129 | CLANG_ENABLE_OBJC_ARC = YES; 130 | CLANG_WARN_BOOL_CONVERSION = YES; 131 | CLANG_WARN_CONSTANT_CONVERSION = YES; 132 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 133 | CLANG_WARN_EMPTY_BODY = YES; 134 | CLANG_WARN_ENUM_CONVERSION = YES; 135 | CLANG_WARN_INFINITE_RECURSION = YES; 136 | CLANG_WARN_INT_CONVERSION = YES; 137 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 138 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 139 | CLANG_WARN_UNREACHABLE_CODE = YES; 140 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 141 | COPY_PHASE_STRIP = NO; 142 | ENABLE_STRICT_OBJC_MSGSEND = YES; 143 | ENABLE_TESTABILITY = YES; 144 | GCC_C_LANGUAGE_STANDARD = gnu99; 145 | GCC_DYNAMIC_NO_PIC = NO; 146 | GCC_NO_COMMON_BLOCKS = YES; 147 | GCC_OPTIMIZATION_LEVEL = 0; 148 | GCC_PREPROCESSOR_DEFINITIONS = ( 149 | "DEBUG=1", 150 | "$(inherited)", 151 | ); 152 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 153 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 154 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 155 | GCC_WARN_UNDECLARED_SELECTOR = YES; 156 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 157 | GCC_WARN_UNUSED_FUNCTION = YES; 158 | GCC_WARN_UNUSED_VARIABLE = YES; 159 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 160 | MTL_ENABLE_DEBUG_INFO = YES; 161 | ONLY_ACTIVE_ARCH = YES; 162 | SDKROOT = iphoneos; 163 | }; 164 | name = Debug; 165 | }; 166 | 58B511EE1A9E6C8500147676 /* Release */ = { 167 | isa = XCBuildConfiguration; 168 | buildSettings = { 169 | ALWAYS_SEARCH_USER_PATHS = NO; 170 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 171 | CLANG_CXX_LIBRARY = "libc++"; 172 | CLANG_ENABLE_MODULES = YES; 173 | CLANG_ENABLE_OBJC_ARC = YES; 174 | CLANG_WARN_BOOL_CONVERSION = YES; 175 | CLANG_WARN_CONSTANT_CONVERSION = YES; 176 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 177 | CLANG_WARN_EMPTY_BODY = YES; 178 | CLANG_WARN_ENUM_CONVERSION = YES; 179 | CLANG_WARN_INFINITE_RECURSION = YES; 180 | CLANG_WARN_INT_CONVERSION = YES; 181 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 182 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 183 | CLANG_WARN_UNREACHABLE_CODE = YES; 184 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 185 | COPY_PHASE_STRIP = YES; 186 | ENABLE_NS_ASSERTIONS = NO; 187 | ENABLE_STRICT_OBJC_MSGSEND = YES; 188 | GCC_C_LANGUAGE_STANDARD = gnu99; 189 | GCC_NO_COMMON_BLOCKS = YES; 190 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 191 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 192 | GCC_WARN_UNDECLARED_SELECTOR = YES; 193 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 194 | GCC_WARN_UNUSED_FUNCTION = YES; 195 | GCC_WARN_UNUSED_VARIABLE = YES; 196 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 197 | MTL_ENABLE_DEBUG_INFO = NO; 198 | SDKROOT = iphoneos; 199 | VALIDATE_PRODUCT = YES; 200 | }; 201 | name = Release; 202 | }; 203 | 58B511F01A9E6C8500147676 /* Debug */ = { 204 | isa = XCBuildConfiguration; 205 | buildSettings = { 206 | HEADER_SEARCH_PATHS = ( 207 | "$(inherited)", 208 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 209 | "$(SRCROOT)/../../../React/**", 210 | "$(SRCROOT)/../../react-native/React/**", 211 | ); 212 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 213 | OTHER_LDFLAGS = "-ObjC"; 214 | PRODUCT_NAME = RNInAppPurchase; 215 | SKIP_INSTALL = YES; 216 | }; 217 | name = Debug; 218 | }; 219 | 58B511F11A9E6C8500147676 /* Release */ = { 220 | isa = XCBuildConfiguration; 221 | buildSettings = { 222 | HEADER_SEARCH_PATHS = ( 223 | "$(inherited)", 224 | /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, 225 | "$(SRCROOT)/../../../React/**", 226 | "$(SRCROOT)/../../react-native/React/**", 227 | ); 228 | LIBRARY_SEARCH_PATHS = "$(inherited)"; 229 | OTHER_LDFLAGS = "-ObjC"; 230 | PRODUCT_NAME = RNInAppPurchase; 231 | SKIP_INSTALL = YES; 232 | }; 233 | name = Release; 234 | }; 235 | /* End XCBuildConfiguration section */ 236 | 237 | /* Begin XCConfigurationList section */ 238 | 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RNInAppPurchase" */ = { 239 | isa = XCConfigurationList; 240 | buildConfigurations = ( 241 | 58B511ED1A9E6C8500147676 /* Debug */, 242 | 58B511EE1A9E6C8500147676 /* Release */, 243 | ); 244 | defaultConfigurationIsVisible = 0; 245 | defaultConfigurationName = Release; 246 | }; 247 | 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RNInAppPurchase" */ = { 248 | isa = XCConfigurationList; 249 | buildConfigurations = ( 250 | 58B511F01A9E6C8500147676 /* Debug */, 251 | 58B511F11A9E6C8500147676 /* Release */, 252 | ); 253 | defaultConfigurationIsVisible = 0; 254 | defaultConfigurationName = Release; 255 | }; 256 | /* End XCConfigurationList section */ 257 | }; 258 | rootObject = 58B511D31A9E6C8500147676 /* Project object */; 259 | } 260 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@class101/react-native-in-app-purchase", 3 | "version": "3.0.0-rc1", 4 | "description": "👻 A dead simple in app purchase library for React Native", 5 | "main": "src/index.ts", 6 | "repository": "https://github.com/pedaling/react-native-in-app-purchase", 7 | "keywords": [ 8 | "react-native", 9 | "in-app-purchase", 10 | "purchase", 11 | "billing" 12 | ], 13 | "author": "Injung Chung ", 14 | "license": "MIT", 15 | "peerDependencies": { 16 | "react-native": "*" 17 | }, 18 | "codegenConfig": { 19 | "name": "InAppPurchase", 20 | "type": "all", 21 | "jsSrcsDir": "src", 22 | "outputDir": { 23 | "ios": "ios/generated", 24 | "android": "android/generated" 25 | }, 26 | "includesGeneratedCode": true, 27 | "android": { 28 | "javaPackageName": "net.class101.iap" 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /sample/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: '@react-native', 4 | }; 5 | -------------------------------------------------------------------------------- /sample/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | ios/.xcode.env.local 24 | 25 | # Android/IntelliJ 26 | # 27 | build/ 28 | .idea 29 | .gradle 30 | local.properties 31 | *.iml 32 | *.hprof 33 | .cxx/ 34 | *.keystore 35 | !debug.keystore 36 | 37 | # node.js 38 | # 39 | node_modules/ 40 | npm-debug.log 41 | yarn-error.log 42 | 43 | # fastlane 44 | # 45 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 46 | # screenshots whenever they are needed. 47 | # For more information about the recommended setup visit: 48 | # https://docs.fastlane.tools/best-practices/source-control/ 49 | 50 | **/fastlane/report.xml 51 | **/fastlane/Preview.html 52 | **/fastlane/screenshots 53 | **/fastlane/test_output 54 | 55 | # Bundle artifact 56 | *.jsbundle 57 | 58 | # Ruby / CocoaPods 59 | /ios/Pods/ 60 | /vendor/bundle/ 61 | 62 | # Temporary files created by Metro to check the health of the file watcher 63 | .metro-health-check* 64 | 65 | # testing 66 | /coverage 67 | -------------------------------------------------------------------------------- /sample/.prettierrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | arrowParens: 'avoid', 3 | bracketSameLine: true, 4 | bracketSpacing: false, 5 | singleQuote: true, 6 | trailingComma: 'all', 7 | }; 8 | -------------------------------------------------------------------------------- /sample/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.formatOnSave": true 3 | } -------------------------------------------------------------------------------- /sample/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /sample/App.tsx: -------------------------------------------------------------------------------- 1 | import React, { useEffect, useState, useCallback } from 'react'; 2 | import { 3 | Alert, 4 | View, 5 | Text, 6 | TouchableOpacity, 7 | StyleSheet, 8 | } from 'react-native'; 9 | import InAppPurchase from '@class101/react-native-in-app-purchase'; 10 | 11 | const PRODUCT_IDS = [ 12 | {id: 'rniap.sample.normal',}, 13 | { 14 | id: 'rniap.sample.consumable'}, 15 | { id: 'rniap.sample.subscribe'}, 16 | ]; 17 | 18 | const App = () => { 19 | const [products, setProducts] = useState([]); 20 | 21 | const handleFetchProducts = (fetchedProducts) => { 22 | console.log(fetchedProducts); 23 | setProducts(fetchedProducts); 24 | }; 25 | 26 | const handlePurchase = (purchase) => { 27 | setTimeout(() => { 28 | InAppPurchase.finalize(purchase, purchase.productId === 'rniap.sample.consumable').then(() => { 29 | Alert.alert('In App Purchase', 'Purchase Succeed!'); 30 | }); 31 | }); 32 | }; 33 | 34 | 35 | useEffect(() => { 36 | const handleError = (error) => { 37 | console.log(error); 38 | }; 39 | 40 | InAppPurchase.onFetchProducts(handleFetchProducts); 41 | InAppPurchase.onPurchase(handlePurchase); 42 | InAppPurchase.onError(handleError); 43 | 44 | InAppPurchase.configure().then(() => { 45 | InAppPurchase.fetchProducts(PRODUCT_IDS); 46 | }); 47 | 48 | return () => { 49 | InAppPurchase.clear(); 50 | }; 51 | }, []); 52 | 53 | const flush = useCallback(() => { 54 | InAppPurchase.flush().then((purchases) => { 55 | console.log(purchases); 56 | purchases.forEach((purchase) => { 57 | handlePurchase(purchase); 58 | }); 59 | }); 60 | }, []); 61 | 62 | const renderItem = useCallback((item) => ( 63 | InAppPurchase.purchase(item.productId)} 67 | style={styles.item} 68 | > 69 | 70 | {item.title} 71 | 72 | 73 | 74 | {item.currency} {item.price} 75 | 76 | 77 | 78 | ), []); 79 | 80 | return ( 81 | 82 | {products.map(renderItem)} 83 | 88 | 89 | Flush uncompleted purchases 90 | 91 | 92 | 93 | ); 94 | }; 95 | 96 | const styles = StyleSheet.create({ 97 | container: { 98 | flex: 1, 99 | justifyContent: 'center', 100 | backgroundColor: '#FFF', 101 | }, 102 | item: { 103 | flexDirection: 'row', 104 | justifyContent: 'space-between', 105 | alignItems: 'center', 106 | marginBottom: 24, 107 | marginHorizontal: 24, 108 | paddingVertical: 20, 109 | paddingHorizontal: 16, 110 | backgroundColor: '#F2F4F9', 111 | }, 112 | title: { 113 | fontSize: 16, 114 | color: '#191919', 115 | }, 116 | priceTag: { 117 | paddingHorizontal: 8, 118 | paddingVertical: 4, 119 | borderRadius: 2, 120 | backgroundColor: '#2D2D2D' 121 | }, 122 | priceText: { 123 | fontSize: 12, 124 | color: '#FAFAFA', 125 | }, 126 | button: { 127 | marginTop: 16, 128 | marginBottom: 0, 129 | justifyContent: 'center', 130 | backgroundColor: '#2D2D2D', 131 | borderRadius: 32, 132 | }, 133 | text: { 134 | fontSize: 16, 135 | color: '#FAFAFA', 136 | }, 137 | }); 138 | 139 | export default App; -------------------------------------------------------------------------------- /sample/Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # You may use http://rbenv.org/ or https://rvm.io/ to install and use this version 4 | ruby ">= 2.6.10" 5 | 6 | # Cocoapods 1.15 introduced a bug which break the build. We will remove the upper 7 | # bound in the template on Cocoapods with next React Native release. 8 | gem 'cocoapods', '>= 1.13', '< 1.15' 9 | gem 'activesupport', '>= 6.1.7.5', '< 7.1.0' 10 | -------------------------------------------------------------------------------- /sample/__tests__/App.test.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import 'react-native'; 6 | import React from 'react'; 7 | import App from '../App'; 8 | 9 | // Note: import explicitly to use the types shipped with jest. 10 | import {it} from '@jest/globals'; 11 | 12 | // Note: test renderer must be required after react-native. 13 | import renderer from 'react-test-renderer'; 14 | 15 | it('renders correctly', () => { 16 | renderer.create(); 17 | }); 18 | -------------------------------------------------------------------------------- /sample/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | apply plugin: "org.jetbrains.kotlin.android" 3 | apply plugin: "com.facebook.react" 4 | 5 | /** 6 | * This is the configuration block to customize your React Native Android app. 7 | * By default you don't need to apply any configuration, just uncomment the lines you need. 8 | */ 9 | react { 10 | /* Folders */ 11 | // The root of your project, i.e. where "package.json" lives. Default is '..' 12 | // root = file("../") 13 | // The folder where the react-native NPM package is. Default is ../node_modules/react-native 14 | // reactNativeDir = file("../node_modules/react-native") 15 | // The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen 16 | // codegenDir = file("../node_modules/@react-native/codegen") 17 | // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js 18 | // cliFile = file("../node_modules/react-native/cli.js") 19 | 20 | /* Variants */ 21 | // The list of variants to that are debuggable. For those we're going to 22 | // skip the bundling of the JS bundle and the assets. By default is just 'debug'. 23 | // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants. 24 | // debuggableVariants = ["liteDebug", "prodDebug"] 25 | 26 | /* Bundling */ 27 | // A list containing the node command and its flags. Default is just 'node'. 28 | // nodeExecutableAndArgs = ["node"] 29 | // 30 | // The command to run when bundling. By default is 'bundle' 31 | // bundleCommand = "ram-bundle" 32 | // 33 | // The path to the CLI configuration file. Default is empty. 34 | // bundleConfig = file(../rn-cli.config.js) 35 | // 36 | // The name of the generated asset file containing your JS bundle 37 | // bundleAssetName = "MyApplication.android.bundle" 38 | // 39 | // The entry file for bundle generation. Default is 'index.android.js' or 'index.js' 40 | // entryFile = file("../js/MyApplication.android.js") 41 | // 42 | // A list of extra flags to pass to the 'bundle' commands. 43 | // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle 44 | // extraPackagerArgs = [] 45 | 46 | /* Hermes Commands */ 47 | // The hermes compiler command to run. By default it is 'hermesc' 48 | // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc" 49 | // 50 | // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map" 51 | // hermesFlags = ["-O", "-output-source-map"] 52 | } 53 | 54 | /** 55 | * Set this to true to Run Proguard on Release builds to minify the Java bytecode. 56 | */ 57 | def enableProguardInReleaseBuilds = false 58 | 59 | /** 60 | * The preferred build flavor of JavaScriptCore (JSC) 61 | * 62 | * For example, to use the international variant, you can use: 63 | * `def jscFlavor = 'org.webkit:android-jsc-intl:+'` 64 | * 65 | * The international variant includes ICU i18n library and necessary data 66 | * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that 67 | * give correct results when using with locales other than en-US. Note that 68 | * this variant is about 6MiB larger per architecture than default. 69 | */ 70 | def jscFlavor = 'org.webkit:android-jsc:+' 71 | 72 | android { 73 | ndkVersion rootProject.ext.ndkVersion 74 | buildToolsVersion rootProject.ext.buildToolsVersion 75 | compileSdk rootProject.ext.compileSdkVersion 76 | 77 | namespace "com.rninapppurchasesample" 78 | defaultConfig { 79 | applicationId "com.rninapppurchasesample" 80 | minSdkVersion rootProject.ext.minSdkVersion 81 | targetSdkVersion rootProject.ext.targetSdkVersion 82 | versionCode 1 83 | versionName "1.0" 84 | } 85 | signingConfigs { 86 | debug { 87 | storeFile file('debug.keystore') 88 | storePassword 'android' 89 | keyAlias 'androiddebugkey' 90 | keyPassword 'android' 91 | } 92 | } 93 | buildTypes { 94 | debug { 95 | signingConfig signingConfigs.debug 96 | } 97 | release { 98 | // Caution! In production, you need to generate your own keystore file. 99 | // see https://reactnative.dev/docs/signed-apk-android. 100 | signingConfig signingConfigs.debug 101 | minifyEnabled enableProguardInReleaseBuilds 102 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 103 | } 104 | } 105 | } 106 | 107 | dependencies { 108 | // The version of react-native is set by the React Native Gradle Plugin 109 | implementation("com.facebook.react:react-android") 110 | implementation("com.facebook.react:flipper-integration") 111 | 112 | if (hermesEnabled.toBoolean()) { 113 | implementation("com.facebook.react:hermes-android") 114 | } else { 115 | implementation jscFlavor 116 | } 117 | } 118 | 119 | apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project) 120 | -------------------------------------------------------------------------------- /sample/android/app/debug.keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/debug.keystore -------------------------------------------------------------------------------- /sample/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | -------------------------------------------------------------------------------- /sample/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | -------------------------------------------------------------------------------- /sample/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /sample/android/app/src/main/java/com/rninapppurchasesample/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.rninapppurchasesample 2 | 3 | import com.facebook.react.ReactActivity 4 | import com.facebook.react.ReactActivityDelegate 5 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled 6 | import com.facebook.react.defaults.DefaultReactActivityDelegate 7 | 8 | class MainActivity : ReactActivity() { 9 | 10 | /** 11 | * Returns the name of the main component registered from JavaScript. This is used to schedule 12 | * rendering of the component. 13 | */ 14 | override fun getMainComponentName(): String = "RNInAppPurchaseSample" 15 | 16 | /** 17 | * Returns the instance of the [ReactActivityDelegate]. We use [DefaultReactActivityDelegate] 18 | * which allows you to enable New Architecture with a single boolean flags [fabricEnabled] 19 | */ 20 | override fun createReactActivityDelegate(): ReactActivityDelegate = 21 | DefaultReactActivityDelegate(this, mainComponentName, fabricEnabled) 22 | } 23 | -------------------------------------------------------------------------------- /sample/android/app/src/main/java/com/rninapppurchasesample/MainApplication.kt: -------------------------------------------------------------------------------- 1 | package com.rninapppurchasesample 2 | 3 | import android.app.Application 4 | import com.facebook.react.PackageList 5 | import com.facebook.react.ReactApplication 6 | import com.facebook.react.ReactHost 7 | import com.facebook.react.ReactNativeHost 8 | import com.facebook.react.ReactPackage 9 | import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load 10 | import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost 11 | import com.facebook.react.defaults.DefaultReactNativeHost 12 | import com.facebook.react.flipper.ReactNativeFlipper 13 | import com.facebook.soloader.SoLoader 14 | 15 | class MainApplication : Application(), ReactApplication { 16 | 17 | override val reactNativeHost: ReactNativeHost = 18 | object : DefaultReactNativeHost(this) { 19 | override fun getPackages(): List = 20 | PackageList(this).packages.apply { 21 | // Packages that cannot be autolinked yet can be added manually here, for example: 22 | // add(MyReactNativePackage()) 23 | } 24 | 25 | override fun getJSMainModuleName(): String = "index" 26 | 27 | override fun getUseDeveloperSupport(): Boolean = BuildConfig.DEBUG 28 | 29 | override val isNewArchEnabled: Boolean = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED 30 | override val isHermesEnabled: Boolean = BuildConfig.IS_HERMES_ENABLED 31 | } 32 | 33 | override val reactHost: ReactHost 34 | get() = getDefaultReactHost(this.applicationContext, reactNativeHost) 35 | 36 | override fun onCreate() { 37 | super.onCreate() 38 | SoLoader.init(this, false) 39 | if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { 40 | // If you opted-in for the New Architecture, we load the native entry point for this app. 41 | load() 42 | } 43 | ReactNativeFlipper.initializeFlipper(this, reactNativeHost.reactInstanceManager) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /sample/android/app/src/main/res/drawable/rn_edit_text_material.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | 22 | 23 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /sample/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /sample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /sample/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | RNInAppPurchaseSample 3 | 4 | -------------------------------------------------------------------------------- /sample/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /sample/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext { 3 | buildToolsVersion = "34.0.0" 4 | minSdkVersion = 24 5 | compileSdkVersion = 34 6 | targetSdkVersion = 34 7 | ndkVersion = "25.1.8937393" 8 | kotlinVersion = "1.8.0" 9 | } 10 | repositories { 11 | google() 12 | mavenCentral() 13 | } 14 | dependencies { 15 | classpath("com.android.tools.build:gradle") 16 | classpath("com.facebook.react:react-native-gradle-plugin") 17 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin") 18 | } 19 | } 20 | 21 | apply plugin: "com.facebook.react.rootproject" 22 | -------------------------------------------------------------------------------- /sample/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx512m -XX:MaxMetaspaceSize=256m 13 | org.gradle.jvmargs=-Xmx2048m -XX:MaxMetaspaceSize=512m 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | # AndroidX package structure to make it clearer which packages are bundled with the 21 | # Android operating system, and which are packaged with your app's APK 22 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 23 | android.useAndroidX=true 24 | # Automatically convert third-party libraries to use AndroidX 25 | android.enableJetifier=true 26 | 27 | # Use this property to specify which architecture you want to build. 28 | # You can also override it from the CLI using 29 | # ./gradlew -PreactNativeArchitectures=x86_64 30 | reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64 31 | 32 | # Use this property to enable support to the new architecture. 33 | # This will allow you to use TurboModules and the Fabric render in 34 | # your application. You should enable this flag either if you want 35 | # to write custom TurboModules/Fabric components OR use libraries that 36 | # are providing them. 37 | newArchEnabled=false 38 | 39 | # Use this property to enable or disable the Hermes JS engine. 40 | # If set to false, you will be using JSC instead. 41 | hermesEnabled=true 42 | -------------------------------------------------------------------------------- /sample/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pedaling/react-native-in-app-purchase/0df6ff308d75bed5d654ad3ec586ec20cf065105/sample/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /sample/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /sample/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # 4 | # Copyright © 2015-2021 the original authors. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # https://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | ############################################################################## 20 | # 21 | # Gradle start up script for POSIX generated by Gradle. 22 | # 23 | # Important for running: 24 | # 25 | # (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is 26 | # noncompliant, but you have some other compliant shell such as ksh or 27 | # bash, then to run this script, type that shell name before the whole 28 | # command line, like: 29 | # 30 | # ksh Gradle 31 | # 32 | # Busybox and similar reduced shells will NOT work, because this script 33 | # requires all of these POSIX shell features: 34 | # * functions; 35 | # * expansions «$var», «${var}», «${var:-default}», «${var+SET}», 36 | # «${var#prefix}», «${var%suffix}», and «$( cmd )»; 37 | # * compound commands having a testable exit status, especially «case»; 38 | # * various built-in commands including «command», «set», and «ulimit». 39 | # 40 | # Important for patching: 41 | # 42 | # (2) This script targets any POSIX shell, so it avoids extensions provided 43 | # by Bash, Ksh, etc; in particular arrays are avoided. 44 | # 45 | # The "traditional" practice of packing multiple parameters into a 46 | # space-separated string is a well documented source of bugs and security 47 | # problems, so this is (mostly) avoided, by progressively accumulating 48 | # options in "$@", and eventually passing that to Java. 49 | # 50 | # Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, 51 | # and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; 52 | # see the in-line comments for details. 53 | # 54 | # There are tweaks for specific operating systems such as AIX, CygWin, 55 | # Darwin, MinGW, and NonStop. 56 | # 57 | # (3) This script is generated from the Groovy template 58 | # https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt 59 | # within the Gradle project. 60 | # 61 | # You can find Gradle at https://github.com/gradle/gradle/. 62 | # 63 | ############################################################################## 64 | 65 | # Attempt to set APP_HOME 66 | 67 | # Resolve links: $0 may be a link 68 | app_path=$0 69 | 70 | # Need this for daisy-chained symlinks. 71 | while 72 | APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path 73 | [ -h "$app_path" ] 74 | do 75 | ls=$( ls -ld "$app_path" ) 76 | link=${ls#*' -> '} 77 | case $link in #( 78 | /*) app_path=$link ;; #( 79 | *) app_path=$APP_HOME$link ;; 80 | esac 81 | done 82 | 83 | # This is normally unused 84 | # shellcheck disable=SC2034 85 | APP_BASE_NAME=${0##*/} 86 | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) 87 | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit 88 | 89 | # Use the maximum available, or set MAX_FD != -1 to use that value. 90 | MAX_FD=maximum 91 | 92 | warn () { 93 | echo "$*" 94 | } >&2 95 | 96 | die () { 97 | echo 98 | echo "$*" 99 | echo 100 | exit 1 101 | } >&2 102 | 103 | # OS specific support (must be 'true' or 'false'). 104 | cygwin=false 105 | msys=false 106 | darwin=false 107 | nonstop=false 108 | case "$( uname )" in #( 109 | CYGWIN* ) cygwin=true ;; #( 110 | Darwin* ) darwin=true ;; #( 111 | MSYS* | MINGW* ) msys=true ;; #( 112 | NONSTOP* ) nonstop=true ;; 113 | esac 114 | 115 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 116 | 117 | 118 | # Determine the Java command to use to start the JVM. 119 | if [ -n "$JAVA_HOME" ] ; then 120 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 121 | # IBM's JDK on AIX uses strange locations for the executables 122 | JAVACMD=$JAVA_HOME/jre/sh/java 123 | else 124 | JAVACMD=$JAVA_HOME/bin/java 125 | fi 126 | if [ ! -x "$JAVACMD" ] ; then 127 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 128 | 129 | Please set the JAVA_HOME variable in your environment to match the 130 | location of your Java installation." 131 | fi 132 | else 133 | JAVACMD=java 134 | if ! command -v java >/dev/null 2>&1 135 | then 136 | die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 137 | 138 | Please set the JAVA_HOME variable in your environment to match the 139 | location of your Java installation." 140 | fi 141 | fi 142 | 143 | # Increase the maximum file descriptors if we can. 144 | if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then 145 | case $MAX_FD in #( 146 | max*) 147 | # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. 148 | # shellcheck disable=SC3045 149 | MAX_FD=$( ulimit -H -n ) || 150 | warn "Could not query maximum file descriptor limit" 151 | esac 152 | case $MAX_FD in #( 153 | '' | soft) :;; #( 154 | *) 155 | # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. 156 | # shellcheck disable=SC3045 157 | ulimit -n "$MAX_FD" || 158 | warn "Could not set maximum file descriptor limit to $MAX_FD" 159 | esac 160 | fi 161 | 162 | # Collect all arguments for the java command, stacking in reverse order: 163 | # * args from the command line 164 | # * the main class name 165 | # * -classpath 166 | # * -D...appname settings 167 | # * --module-path (only if needed) 168 | # * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. 169 | 170 | # For Cygwin or MSYS, switch paths to Windows format before running java 171 | if "$cygwin" || "$msys" ; then 172 | APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) 173 | CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) 174 | 175 | JAVACMD=$( cygpath --unix "$JAVACMD" ) 176 | 177 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 178 | for arg do 179 | if 180 | case $arg in #( 181 | -*) false ;; # don't mess with options #( 182 | /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath 183 | [ -e "$t" ] ;; #( 184 | *) false ;; 185 | esac 186 | then 187 | arg=$( cygpath --path --ignore --mixed "$arg" ) 188 | fi 189 | # Roll the args list around exactly as many times as the number of 190 | # args, so each arg winds up back in the position where it started, but 191 | # possibly modified. 192 | # 193 | # NB: a `for` loop captures its iteration list before it begins, so 194 | # changing the positional parameters here affects neither the number of 195 | # iterations, nor the values presented in `arg`. 196 | shift # remove old arg 197 | set -- "$@" "$arg" # push replacement arg 198 | done 199 | fi 200 | 201 | 202 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 203 | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' 204 | 205 | # Collect all arguments for the java command; 206 | # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of 207 | # shell script including quotes and variable substitutions, so put them in 208 | # double quotes to make sure that they get re-expanded; and 209 | # * put everything else in single quotes, so that it's not re-expanded. 210 | 211 | set -- \ 212 | "-Dorg.gradle.appname=$APP_BASE_NAME" \ 213 | -classpath "$CLASSPATH" \ 214 | org.gradle.wrapper.GradleWrapperMain \ 215 | "$@" 216 | 217 | # Stop when "xargs" is not available. 218 | if ! command -v xargs >/dev/null 2>&1 219 | then 220 | die "xargs is not available" 221 | fi 222 | 223 | # Use "xargs" to parse quoted args. 224 | # 225 | # With -n1 it outputs one arg per line, with the quotes and backslashes removed. 226 | # 227 | # In Bash we could simply go: 228 | # 229 | # readarray ARGS < <( xargs -n1 <<<"$var" ) && 230 | # set -- "${ARGS[@]}" "$@" 231 | # 232 | # but POSIX shell has neither arrays nor command substitution, so instead we 233 | # post-process each arg (as a line of input to sed) to backslash-escape any 234 | # character that might be a shell metacharacter, then use eval to reverse 235 | # that process (while maintaining the separation between arguments), and wrap 236 | # the whole thing up as a single "set" statement. 237 | # 238 | # This will of course break if any of these variables contains a newline or 239 | # an unmatched quote. 240 | # 241 | 242 | eval "set -- $( 243 | printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | 244 | xargs -n1 | 245 | sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | 246 | tr '\n' ' ' 247 | )" '"$@"' 248 | 249 | exec "$JAVACMD" "$@" 250 | -------------------------------------------------------------------------------- /sample/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%"=="" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%"=="" set DIRNAME=. 29 | @rem This is normally unused 30 | set APP_BASE_NAME=%~n0 31 | set APP_HOME=%DIRNAME% 32 | 33 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 34 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 35 | 36 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 37 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 38 | 39 | @rem Find java.exe 40 | if defined JAVA_HOME goto findJavaFromJavaHome 41 | 42 | set JAVA_EXE=java.exe 43 | %JAVA_EXE% -version >NUL 2>&1 44 | if %ERRORLEVEL% equ 0 goto execute 45 | 46 | echo. 47 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 48 | echo. 49 | echo Please set the JAVA_HOME variable in your environment to match the 50 | echo location of your Java installation. 51 | 52 | goto fail 53 | 54 | :findJavaFromJavaHome 55 | set JAVA_HOME=%JAVA_HOME:"=% 56 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 57 | 58 | if exist "%JAVA_EXE%" goto execute 59 | 60 | echo. 61 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 62 | echo. 63 | echo Please set the JAVA_HOME variable in your environment to match the 64 | echo location of your Java installation. 65 | 66 | goto fail 67 | 68 | :execute 69 | @rem Setup the command line 70 | 71 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 72 | 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if %ERRORLEVEL% equ 0 goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | set EXIT_CODE=%ERRORLEVEL% 85 | if %EXIT_CODE% equ 0 set EXIT_CODE=1 86 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% 87 | exit /b %EXIT_CODE% 88 | 89 | :mainEnd 90 | if "%OS%"=="Windows_NT" endlocal 91 | 92 | :omega 93 | -------------------------------------------------------------------------------- /sample/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'RNInAppPurchaseSample' 2 | apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); 3 | applyNativeModulesSettingsGradle(settings) 4 | 5 | include ':app' 6 | includeBuild('../node_modules/@react-native/gradle-plugin') 7 | -------------------------------------------------------------------------------- /sample/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RNInAppPurchaseSample", 3 | "displayName": "RNInAppPurchaseSample" 4 | } 5 | -------------------------------------------------------------------------------- /sample/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: ['module:@react-native/babel-preset'], 3 | }; 4 | -------------------------------------------------------------------------------- /sample/index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @format 3 | */ 4 | 5 | import {AppRegistry} from 'react-native'; 6 | import App from './App'; 7 | import {name as appName} from './app.json'; 8 | 9 | AppRegistry.registerComponent(appName, () => App); 10 | -------------------------------------------------------------------------------- /sample/ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /sample/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Resolve react_native_pods.rb with node to allow for hoisting 2 | require Pod::Executable.execute_command('node', ['-p', 3 | 'require.resolve( 4 | "react-native/scripts/react_native_pods.rb", 5 | {paths: [process.argv[1]]}, 6 | )', __dir__]).strip 7 | 8 | platform :ios, min_ios_version_supported 9 | prepare_react_native_project! 10 | 11 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. 12 | # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded 13 | # 14 | # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js` 15 | # ```js 16 | # module.exports = { 17 | # dependencies: { 18 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), 19 | # ``` 20 | flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled 21 | 22 | linkage = ENV['USE_FRAMEWORKS'] 23 | if linkage != nil 24 | Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green 25 | use_frameworks! :linkage => linkage.to_sym 26 | end 27 | 28 | target 'RNInAppPurchaseSample' do 29 | config = use_native_modules! 30 | 31 | use_react_native!( 32 | :path => config[:reactNativePath], 33 | # Enables Flipper. 34 | # 35 | # Note that if you have use_frameworks! enabled, Flipper will not work and 36 | # you should disable the next line. 37 | :flipper_configuration => flipper_config, 38 | # An absolute path to your application root. 39 | :app_path => "#{Pod::Config.instance.installation_root}/.." 40 | ) 41 | 42 | target 'RNInAppPurchaseSampleTests' do 43 | inherit! :complete 44 | # Pods for testing 45 | end 46 | 47 | post_install do |installer| 48 | # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 49 | react_native_post_install( 50 | installer, 51 | config[:reactNativePath], 52 | :mac_catalyst_enabled => false 53 | ) 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /sample/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - boost (1.83.0) 3 | - CocoaAsyncSocket (7.6.5) 4 | - DoubleConversion (1.1.6) 5 | - FBLazyVector (0.73.9) 6 | - FBReactNativeSpec (0.73.9): 7 | - RCT-Folly (= 2022.05.16.00) 8 | - RCTRequired (= 0.73.9) 9 | - RCTTypeSafety (= 0.73.9) 10 | - React-Core (= 0.73.9) 11 | - React-jsi (= 0.73.9) 12 | - ReactCommon/turbomodule/core (= 0.73.9) 13 | - Flipper (0.201.0): 14 | - Flipper-Folly (~> 2.6) 15 | - Flipper-Boost-iOSX (1.76.0.1.11) 16 | - Flipper-DoubleConversion (3.2.0.1) 17 | - Flipper-Fmt (7.1.7) 18 | - Flipper-Folly (2.6.10): 19 | - Flipper-Boost-iOSX 20 | - Flipper-DoubleConversion 21 | - Flipper-Fmt (= 7.1.7) 22 | - Flipper-Glog 23 | - libevent (~> 2.1.12) 24 | - OpenSSL-Universal (= 1.1.1100) 25 | - Flipper-Glog (0.5.0.5) 26 | - Flipper-PeerTalk (0.0.4) 27 | - FlipperKit (0.201.0): 28 | - FlipperKit/Core (= 0.201.0) 29 | - FlipperKit/Core (0.201.0): 30 | - Flipper (~> 0.201.0) 31 | - FlipperKit/CppBridge 32 | - FlipperKit/FBCxxFollyDynamicConvert 33 | - FlipperKit/FBDefines 34 | - FlipperKit/FKPortForwarding 35 | - SocketRocket (~> 0.6.0) 36 | - FlipperKit/CppBridge (0.201.0): 37 | - Flipper (~> 0.201.0) 38 | - FlipperKit/FBCxxFollyDynamicConvert (0.201.0): 39 | - Flipper-Folly (~> 2.6) 40 | - FlipperKit/FBDefines (0.201.0) 41 | - FlipperKit/FKPortForwarding (0.201.0): 42 | - CocoaAsyncSocket (~> 7.6) 43 | - Flipper-PeerTalk (~> 0.0.4) 44 | - FlipperKit/FlipperKitHighlightOverlay (0.201.0) 45 | - FlipperKit/FlipperKitLayoutHelpers (0.201.0): 46 | - FlipperKit/Core 47 | - FlipperKit/FlipperKitHighlightOverlay 48 | - FlipperKit/FlipperKitLayoutTextSearchable 49 | - FlipperKit/FlipperKitLayoutIOSDescriptors (0.201.0): 50 | - FlipperKit/Core 51 | - FlipperKit/FlipperKitHighlightOverlay 52 | - FlipperKit/FlipperKitLayoutHelpers 53 | - FlipperKit/FlipperKitLayoutPlugin (0.201.0): 54 | - FlipperKit/Core 55 | - FlipperKit/FlipperKitHighlightOverlay 56 | - FlipperKit/FlipperKitLayoutHelpers 57 | - FlipperKit/FlipperKitLayoutIOSDescriptors 58 | - FlipperKit/FlipperKitLayoutTextSearchable 59 | - FlipperKit/FlipperKitLayoutTextSearchable (0.201.0) 60 | - FlipperKit/FlipperKitNetworkPlugin (0.201.0): 61 | - FlipperKit/Core 62 | - FlipperKit/FlipperKitReactPlugin (0.201.0): 63 | - FlipperKit/Core 64 | - FlipperKit/FlipperKitUserDefaultsPlugin (0.201.0): 65 | - FlipperKit/Core 66 | - FlipperKit/SKIOSNetworkPlugin (0.201.0): 67 | - FlipperKit/Core 68 | - FlipperKit/FlipperKitNetworkPlugin 69 | - fmt (6.2.1) 70 | - glog (0.3.5) 71 | - hermes-engine (0.73.9): 72 | - hermes-engine/Pre-built (= 0.73.9) 73 | - hermes-engine/Pre-built (0.73.9) 74 | - libevent (2.1.12) 75 | - OpenSSL-Universal (1.1.1100) 76 | - RCT-Folly (2022.05.16.00): 77 | - boost 78 | - DoubleConversion 79 | - fmt (~> 6.2.1) 80 | - glog 81 | - RCT-Folly/Default (= 2022.05.16.00) 82 | - RCT-Folly/Default (2022.05.16.00): 83 | - boost 84 | - DoubleConversion 85 | - fmt (~> 6.2.1) 86 | - glog 87 | - RCT-Folly/Fabric (2022.05.16.00): 88 | - boost 89 | - DoubleConversion 90 | - fmt (~> 6.2.1) 91 | - glog 92 | - RCT-Folly/Futures (2022.05.16.00): 93 | - boost 94 | - DoubleConversion 95 | - fmt (~> 6.2.1) 96 | - glog 97 | - libevent 98 | - RCTRequired (0.73.9) 99 | - RCTTypeSafety (0.73.9): 100 | - FBLazyVector (= 0.73.9) 101 | - RCTRequired (= 0.73.9) 102 | - React-Core (= 0.73.9) 103 | - React (0.73.9): 104 | - React-Core (= 0.73.9) 105 | - React-Core/DevSupport (= 0.73.9) 106 | - React-Core/RCTWebSocket (= 0.73.9) 107 | - React-RCTActionSheet (= 0.73.9) 108 | - React-RCTAnimation (= 0.73.9) 109 | - React-RCTBlob (= 0.73.9) 110 | - React-RCTImage (= 0.73.9) 111 | - React-RCTLinking (= 0.73.9) 112 | - React-RCTNetwork (= 0.73.9) 113 | - React-RCTSettings (= 0.73.9) 114 | - React-RCTText (= 0.73.9) 115 | - React-RCTVibration (= 0.73.9) 116 | - React-callinvoker (0.73.9) 117 | - React-Codegen (0.73.9): 118 | - DoubleConversion 119 | - FBReactNativeSpec 120 | - glog 121 | - hermes-engine 122 | - RCT-Folly 123 | - RCTRequired 124 | - RCTTypeSafety 125 | - React-Core 126 | - React-jsi 127 | - React-jsiexecutor 128 | - React-NativeModulesApple 129 | - React-rncore 130 | - ReactCommon/turbomodule/bridging 131 | - ReactCommon/turbomodule/core 132 | - React-Core (0.73.9): 133 | - glog 134 | - hermes-engine 135 | - RCT-Folly (= 2022.05.16.00) 136 | - React-Core/Default (= 0.73.9) 137 | - React-cxxreact 138 | - React-hermes 139 | - React-jsi 140 | - React-jsiexecutor 141 | - React-perflogger 142 | - React-runtimescheduler 143 | - React-utils 144 | - SocketRocket (= 0.6.1) 145 | - Yoga 146 | - React-Core/CoreModulesHeaders (0.73.9): 147 | - glog 148 | - hermes-engine 149 | - RCT-Folly (= 2022.05.16.00) 150 | - React-Core/Default 151 | - React-cxxreact 152 | - React-hermes 153 | - React-jsi 154 | - React-jsiexecutor 155 | - React-perflogger 156 | - React-runtimescheduler 157 | - React-utils 158 | - SocketRocket (= 0.6.1) 159 | - Yoga 160 | - React-Core/Default (0.73.9): 161 | - glog 162 | - hermes-engine 163 | - RCT-Folly (= 2022.05.16.00) 164 | - React-cxxreact 165 | - React-hermes 166 | - React-jsi 167 | - React-jsiexecutor 168 | - React-perflogger 169 | - React-runtimescheduler 170 | - React-utils 171 | - SocketRocket (= 0.6.1) 172 | - Yoga 173 | - React-Core/DevSupport (0.73.9): 174 | - glog 175 | - hermes-engine 176 | - RCT-Folly (= 2022.05.16.00) 177 | - React-Core/Default (= 0.73.9) 178 | - React-Core/RCTWebSocket (= 0.73.9) 179 | - React-cxxreact 180 | - React-hermes 181 | - React-jsi 182 | - React-jsiexecutor 183 | - React-jsinspector (= 0.73.9) 184 | - React-perflogger 185 | - React-runtimescheduler 186 | - React-utils 187 | - SocketRocket (= 0.6.1) 188 | - Yoga 189 | - React-Core/RCTActionSheetHeaders (0.73.9): 190 | - glog 191 | - hermes-engine 192 | - RCT-Folly (= 2022.05.16.00) 193 | - React-Core/Default 194 | - React-cxxreact 195 | - React-hermes 196 | - React-jsi 197 | - React-jsiexecutor 198 | - React-perflogger 199 | - React-runtimescheduler 200 | - React-utils 201 | - SocketRocket (= 0.6.1) 202 | - Yoga 203 | - React-Core/RCTAnimationHeaders (0.73.9): 204 | - glog 205 | - hermes-engine 206 | - RCT-Folly (= 2022.05.16.00) 207 | - React-Core/Default 208 | - React-cxxreact 209 | - React-hermes 210 | - React-jsi 211 | - React-jsiexecutor 212 | - React-perflogger 213 | - React-runtimescheduler 214 | - React-utils 215 | - SocketRocket (= 0.6.1) 216 | - Yoga 217 | - React-Core/RCTBlobHeaders (0.73.9): 218 | - glog 219 | - hermes-engine 220 | - RCT-Folly (= 2022.05.16.00) 221 | - React-Core/Default 222 | - React-cxxreact 223 | - React-hermes 224 | - React-jsi 225 | - React-jsiexecutor 226 | - React-perflogger 227 | - React-runtimescheduler 228 | - React-utils 229 | - SocketRocket (= 0.6.1) 230 | - Yoga 231 | - React-Core/RCTImageHeaders (0.73.9): 232 | - glog 233 | - hermes-engine 234 | - RCT-Folly (= 2022.05.16.00) 235 | - React-Core/Default 236 | - React-cxxreact 237 | - React-hermes 238 | - React-jsi 239 | - React-jsiexecutor 240 | - React-perflogger 241 | - React-runtimescheduler 242 | - React-utils 243 | - SocketRocket (= 0.6.1) 244 | - Yoga 245 | - React-Core/RCTLinkingHeaders (0.73.9): 246 | - glog 247 | - hermes-engine 248 | - RCT-Folly (= 2022.05.16.00) 249 | - React-Core/Default 250 | - React-cxxreact 251 | - React-hermes 252 | - React-jsi 253 | - React-jsiexecutor 254 | - React-perflogger 255 | - React-runtimescheduler 256 | - React-utils 257 | - SocketRocket (= 0.6.1) 258 | - Yoga 259 | - React-Core/RCTNetworkHeaders (0.73.9): 260 | - glog 261 | - hermes-engine 262 | - RCT-Folly (= 2022.05.16.00) 263 | - React-Core/Default 264 | - React-cxxreact 265 | - React-hermes 266 | - React-jsi 267 | - React-jsiexecutor 268 | - React-perflogger 269 | - React-runtimescheduler 270 | - React-utils 271 | - SocketRocket (= 0.6.1) 272 | - Yoga 273 | - React-Core/RCTSettingsHeaders (0.73.9): 274 | - glog 275 | - hermes-engine 276 | - RCT-Folly (= 2022.05.16.00) 277 | - React-Core/Default 278 | - React-cxxreact 279 | - React-hermes 280 | - React-jsi 281 | - React-jsiexecutor 282 | - React-perflogger 283 | - React-runtimescheduler 284 | - React-utils 285 | - SocketRocket (= 0.6.1) 286 | - Yoga 287 | - React-Core/RCTTextHeaders (0.73.9): 288 | - glog 289 | - hermes-engine 290 | - RCT-Folly (= 2022.05.16.00) 291 | - React-Core/Default 292 | - React-cxxreact 293 | - React-hermes 294 | - React-jsi 295 | - React-jsiexecutor 296 | - React-perflogger 297 | - React-runtimescheduler 298 | - React-utils 299 | - SocketRocket (= 0.6.1) 300 | - Yoga 301 | - React-Core/RCTVibrationHeaders (0.73.9): 302 | - glog 303 | - hermes-engine 304 | - RCT-Folly (= 2022.05.16.00) 305 | - React-Core/Default 306 | - React-cxxreact 307 | - React-hermes 308 | - React-jsi 309 | - React-jsiexecutor 310 | - React-perflogger 311 | - React-runtimescheduler 312 | - React-utils 313 | - SocketRocket (= 0.6.1) 314 | - Yoga 315 | - React-Core/RCTWebSocket (0.73.9): 316 | - glog 317 | - hermes-engine 318 | - RCT-Folly (= 2022.05.16.00) 319 | - React-Core/Default (= 0.73.9) 320 | - React-cxxreact 321 | - React-hermes 322 | - React-jsi 323 | - React-jsiexecutor 324 | - React-perflogger 325 | - React-runtimescheduler 326 | - React-utils 327 | - SocketRocket (= 0.6.1) 328 | - Yoga 329 | - React-CoreModules (0.73.9): 330 | - RCT-Folly (= 2022.05.16.00) 331 | - RCTTypeSafety (= 0.73.9) 332 | - React-Codegen 333 | - React-Core/CoreModulesHeaders (= 0.73.9) 334 | - React-jsi (= 0.73.9) 335 | - React-NativeModulesApple 336 | - React-RCTBlob 337 | - React-RCTImage (= 0.73.9) 338 | - ReactCommon 339 | - SocketRocket (= 0.6.1) 340 | - React-cxxreact (0.73.9): 341 | - boost (= 1.83.0) 342 | - DoubleConversion 343 | - fmt (~> 6.2.1) 344 | - glog 345 | - hermes-engine 346 | - RCT-Folly (= 2022.05.16.00) 347 | - React-callinvoker (= 0.73.9) 348 | - React-debug (= 0.73.9) 349 | - React-jsi (= 0.73.9) 350 | - React-jsinspector (= 0.73.9) 351 | - React-logger (= 0.73.9) 352 | - React-perflogger (= 0.73.9) 353 | - React-runtimeexecutor (= 0.73.9) 354 | - React-debug (0.73.9) 355 | - React-Fabric (0.73.9): 356 | - DoubleConversion 357 | - fmt (~> 6.2.1) 358 | - glog 359 | - hermes-engine 360 | - RCT-Folly/Fabric (= 2022.05.16.00) 361 | - RCTRequired 362 | - RCTTypeSafety 363 | - React-Core 364 | - React-cxxreact 365 | - React-debug 366 | - React-Fabric/animations (= 0.73.9) 367 | - React-Fabric/attributedstring (= 0.73.9) 368 | - React-Fabric/componentregistry (= 0.73.9) 369 | - React-Fabric/componentregistrynative (= 0.73.9) 370 | - React-Fabric/components (= 0.73.9) 371 | - React-Fabric/core (= 0.73.9) 372 | - React-Fabric/imagemanager (= 0.73.9) 373 | - React-Fabric/leakchecker (= 0.73.9) 374 | - React-Fabric/mounting (= 0.73.9) 375 | - React-Fabric/scheduler (= 0.73.9) 376 | - React-Fabric/telemetry (= 0.73.9) 377 | - React-Fabric/templateprocessor (= 0.73.9) 378 | - React-Fabric/textlayoutmanager (= 0.73.9) 379 | - React-Fabric/uimanager (= 0.73.9) 380 | - React-graphics 381 | - React-jsi 382 | - React-jsiexecutor 383 | - React-logger 384 | - React-rendererdebug 385 | - React-runtimescheduler 386 | - React-utils 387 | - ReactCommon/turbomodule/core 388 | - React-Fabric/animations (0.73.9): 389 | - DoubleConversion 390 | - fmt (~> 6.2.1) 391 | - glog 392 | - hermes-engine 393 | - RCT-Folly/Fabric (= 2022.05.16.00) 394 | - RCTRequired 395 | - RCTTypeSafety 396 | - React-Core 397 | - React-cxxreact 398 | - React-debug 399 | - React-graphics 400 | - React-jsi 401 | - React-jsiexecutor 402 | - React-logger 403 | - React-rendererdebug 404 | - React-runtimescheduler 405 | - React-utils 406 | - ReactCommon/turbomodule/core 407 | - React-Fabric/attributedstring (0.73.9): 408 | - DoubleConversion 409 | - fmt (~> 6.2.1) 410 | - glog 411 | - hermes-engine 412 | - RCT-Folly/Fabric (= 2022.05.16.00) 413 | - RCTRequired 414 | - RCTTypeSafety 415 | - React-Core 416 | - React-cxxreact 417 | - React-debug 418 | - React-graphics 419 | - React-jsi 420 | - React-jsiexecutor 421 | - React-logger 422 | - React-rendererdebug 423 | - React-runtimescheduler 424 | - React-utils 425 | - ReactCommon/turbomodule/core 426 | - React-Fabric/componentregistry (0.73.9): 427 | - DoubleConversion 428 | - fmt (~> 6.2.1) 429 | - glog 430 | - hermes-engine 431 | - RCT-Folly/Fabric (= 2022.05.16.00) 432 | - RCTRequired 433 | - RCTTypeSafety 434 | - React-Core 435 | - React-cxxreact 436 | - React-debug 437 | - React-graphics 438 | - React-jsi 439 | - React-jsiexecutor 440 | - React-logger 441 | - React-rendererdebug 442 | - React-runtimescheduler 443 | - React-utils 444 | - ReactCommon/turbomodule/core 445 | - React-Fabric/componentregistrynative (0.73.9): 446 | - DoubleConversion 447 | - fmt (~> 6.2.1) 448 | - glog 449 | - hermes-engine 450 | - RCT-Folly/Fabric (= 2022.05.16.00) 451 | - RCTRequired 452 | - RCTTypeSafety 453 | - React-Core 454 | - React-cxxreact 455 | - React-debug 456 | - React-graphics 457 | - React-jsi 458 | - React-jsiexecutor 459 | - React-logger 460 | - React-rendererdebug 461 | - React-runtimescheduler 462 | - React-utils 463 | - ReactCommon/turbomodule/core 464 | - React-Fabric/components (0.73.9): 465 | - DoubleConversion 466 | - fmt (~> 6.2.1) 467 | - glog 468 | - hermes-engine 469 | - RCT-Folly/Fabric (= 2022.05.16.00) 470 | - RCTRequired 471 | - RCTTypeSafety 472 | - React-Core 473 | - React-cxxreact 474 | - React-debug 475 | - React-Fabric/components/inputaccessory (= 0.73.9) 476 | - React-Fabric/components/legacyviewmanagerinterop (= 0.73.9) 477 | - React-Fabric/components/modal (= 0.73.9) 478 | - React-Fabric/components/rncore (= 0.73.9) 479 | - React-Fabric/components/root (= 0.73.9) 480 | - React-Fabric/components/safeareaview (= 0.73.9) 481 | - React-Fabric/components/scrollview (= 0.73.9) 482 | - React-Fabric/components/text (= 0.73.9) 483 | - React-Fabric/components/textinput (= 0.73.9) 484 | - React-Fabric/components/unimplementedview (= 0.73.9) 485 | - React-Fabric/components/view (= 0.73.9) 486 | - React-graphics 487 | - React-jsi 488 | - React-jsiexecutor 489 | - React-logger 490 | - React-rendererdebug 491 | - React-runtimescheduler 492 | - React-utils 493 | - ReactCommon/turbomodule/core 494 | - React-Fabric/components/inputaccessory (0.73.9): 495 | - DoubleConversion 496 | - fmt (~> 6.2.1) 497 | - glog 498 | - hermes-engine 499 | - RCT-Folly/Fabric (= 2022.05.16.00) 500 | - RCTRequired 501 | - RCTTypeSafety 502 | - React-Core 503 | - React-cxxreact 504 | - React-debug 505 | - React-graphics 506 | - React-jsi 507 | - React-jsiexecutor 508 | - React-logger 509 | - React-rendererdebug 510 | - React-runtimescheduler 511 | - React-utils 512 | - ReactCommon/turbomodule/core 513 | - React-Fabric/components/legacyviewmanagerinterop (0.73.9): 514 | - DoubleConversion 515 | - fmt (~> 6.2.1) 516 | - glog 517 | - hermes-engine 518 | - RCT-Folly/Fabric (= 2022.05.16.00) 519 | - RCTRequired 520 | - RCTTypeSafety 521 | - React-Core 522 | - React-cxxreact 523 | - React-debug 524 | - React-graphics 525 | - React-jsi 526 | - React-jsiexecutor 527 | - React-logger 528 | - React-rendererdebug 529 | - React-runtimescheduler 530 | - React-utils 531 | - ReactCommon/turbomodule/core 532 | - React-Fabric/components/modal (0.73.9): 533 | - DoubleConversion 534 | - fmt (~> 6.2.1) 535 | - glog 536 | - hermes-engine 537 | - RCT-Folly/Fabric (= 2022.05.16.00) 538 | - RCTRequired 539 | - RCTTypeSafety 540 | - React-Core 541 | - React-cxxreact 542 | - React-debug 543 | - React-graphics 544 | - React-jsi 545 | - React-jsiexecutor 546 | - React-logger 547 | - React-rendererdebug 548 | - React-runtimescheduler 549 | - React-utils 550 | - ReactCommon/turbomodule/core 551 | - React-Fabric/components/rncore (0.73.9): 552 | - DoubleConversion 553 | - fmt (~> 6.2.1) 554 | - glog 555 | - hermes-engine 556 | - RCT-Folly/Fabric (= 2022.05.16.00) 557 | - RCTRequired 558 | - RCTTypeSafety 559 | - React-Core 560 | - React-cxxreact 561 | - React-debug 562 | - React-graphics 563 | - React-jsi 564 | - React-jsiexecutor 565 | - React-logger 566 | - React-rendererdebug 567 | - React-runtimescheduler 568 | - React-utils 569 | - ReactCommon/turbomodule/core 570 | - React-Fabric/components/root (0.73.9): 571 | - DoubleConversion 572 | - fmt (~> 6.2.1) 573 | - glog 574 | - hermes-engine 575 | - RCT-Folly/Fabric (= 2022.05.16.00) 576 | - RCTRequired 577 | - RCTTypeSafety 578 | - React-Core 579 | - React-cxxreact 580 | - React-debug 581 | - React-graphics 582 | - React-jsi 583 | - React-jsiexecutor 584 | - React-logger 585 | - React-rendererdebug 586 | - React-runtimescheduler 587 | - React-utils 588 | - ReactCommon/turbomodule/core 589 | - React-Fabric/components/safeareaview (0.73.9): 590 | - DoubleConversion 591 | - fmt (~> 6.2.1) 592 | - glog 593 | - hermes-engine 594 | - RCT-Folly/Fabric (= 2022.05.16.00) 595 | - RCTRequired 596 | - RCTTypeSafety 597 | - React-Core 598 | - React-cxxreact 599 | - React-debug 600 | - React-graphics 601 | - React-jsi 602 | - React-jsiexecutor 603 | - React-logger 604 | - React-rendererdebug 605 | - React-runtimescheduler 606 | - React-utils 607 | - ReactCommon/turbomodule/core 608 | - React-Fabric/components/scrollview (0.73.9): 609 | - DoubleConversion 610 | - fmt (~> 6.2.1) 611 | - glog 612 | - hermes-engine 613 | - RCT-Folly/Fabric (= 2022.05.16.00) 614 | - RCTRequired 615 | - RCTTypeSafety 616 | - React-Core 617 | - React-cxxreact 618 | - React-debug 619 | - React-graphics 620 | - React-jsi 621 | - React-jsiexecutor 622 | - React-logger 623 | - React-rendererdebug 624 | - React-runtimescheduler 625 | - React-utils 626 | - ReactCommon/turbomodule/core 627 | - React-Fabric/components/text (0.73.9): 628 | - DoubleConversion 629 | - fmt (~> 6.2.1) 630 | - glog 631 | - hermes-engine 632 | - RCT-Folly/Fabric (= 2022.05.16.00) 633 | - RCTRequired 634 | - RCTTypeSafety 635 | - React-Core 636 | - React-cxxreact 637 | - React-debug 638 | - React-graphics 639 | - React-jsi 640 | - React-jsiexecutor 641 | - React-logger 642 | - React-rendererdebug 643 | - React-runtimescheduler 644 | - React-utils 645 | - ReactCommon/turbomodule/core 646 | - React-Fabric/components/textinput (0.73.9): 647 | - DoubleConversion 648 | - fmt (~> 6.2.1) 649 | - glog 650 | - hermes-engine 651 | - RCT-Folly/Fabric (= 2022.05.16.00) 652 | - RCTRequired 653 | - RCTTypeSafety 654 | - React-Core 655 | - React-cxxreact 656 | - React-debug 657 | - React-graphics 658 | - React-jsi 659 | - React-jsiexecutor 660 | - React-logger 661 | - React-rendererdebug 662 | - React-runtimescheduler 663 | - React-utils 664 | - ReactCommon/turbomodule/core 665 | - React-Fabric/components/unimplementedview (0.73.9): 666 | - DoubleConversion 667 | - fmt (~> 6.2.1) 668 | - glog 669 | - hermes-engine 670 | - RCT-Folly/Fabric (= 2022.05.16.00) 671 | - RCTRequired 672 | - RCTTypeSafety 673 | - React-Core 674 | - React-cxxreact 675 | - React-debug 676 | - React-graphics 677 | - React-jsi 678 | - React-jsiexecutor 679 | - React-logger 680 | - React-rendererdebug 681 | - React-runtimescheduler 682 | - React-utils 683 | - ReactCommon/turbomodule/core 684 | - React-Fabric/components/view (0.73.9): 685 | - DoubleConversion 686 | - fmt (~> 6.2.1) 687 | - glog 688 | - hermes-engine 689 | - RCT-Folly/Fabric (= 2022.05.16.00) 690 | - RCTRequired 691 | - RCTTypeSafety 692 | - React-Core 693 | - React-cxxreact 694 | - React-debug 695 | - React-graphics 696 | - React-jsi 697 | - React-jsiexecutor 698 | - React-logger 699 | - React-rendererdebug 700 | - React-runtimescheduler 701 | - React-utils 702 | - ReactCommon/turbomodule/core 703 | - Yoga 704 | - React-Fabric/core (0.73.9): 705 | - DoubleConversion 706 | - fmt (~> 6.2.1) 707 | - glog 708 | - hermes-engine 709 | - RCT-Folly/Fabric (= 2022.05.16.00) 710 | - RCTRequired 711 | - RCTTypeSafety 712 | - React-Core 713 | - React-cxxreact 714 | - React-debug 715 | - React-graphics 716 | - React-jsi 717 | - React-jsiexecutor 718 | - React-logger 719 | - React-rendererdebug 720 | - React-runtimescheduler 721 | - React-utils 722 | - ReactCommon/turbomodule/core 723 | - React-Fabric/imagemanager (0.73.9): 724 | - DoubleConversion 725 | - fmt (~> 6.2.1) 726 | - glog 727 | - hermes-engine 728 | - RCT-Folly/Fabric (= 2022.05.16.00) 729 | - RCTRequired 730 | - RCTTypeSafety 731 | - React-Core 732 | - React-cxxreact 733 | - React-debug 734 | - React-graphics 735 | - React-jsi 736 | - React-jsiexecutor 737 | - React-logger 738 | - React-rendererdebug 739 | - React-runtimescheduler 740 | - React-utils 741 | - ReactCommon/turbomodule/core 742 | - React-Fabric/leakchecker (0.73.9): 743 | - DoubleConversion 744 | - fmt (~> 6.2.1) 745 | - glog 746 | - hermes-engine 747 | - RCT-Folly/Fabric (= 2022.05.16.00) 748 | - RCTRequired 749 | - RCTTypeSafety 750 | - React-Core 751 | - React-cxxreact 752 | - React-debug 753 | - React-graphics 754 | - React-jsi 755 | - React-jsiexecutor 756 | - React-logger 757 | - React-rendererdebug 758 | - React-runtimescheduler 759 | - React-utils 760 | - ReactCommon/turbomodule/core 761 | - React-Fabric/mounting (0.73.9): 762 | - DoubleConversion 763 | - fmt (~> 6.2.1) 764 | - glog 765 | - hermes-engine 766 | - RCT-Folly/Fabric (= 2022.05.16.00) 767 | - RCTRequired 768 | - RCTTypeSafety 769 | - React-Core 770 | - React-cxxreact 771 | - React-debug 772 | - React-graphics 773 | - React-jsi 774 | - React-jsiexecutor 775 | - React-logger 776 | - React-rendererdebug 777 | - React-runtimescheduler 778 | - React-utils 779 | - ReactCommon/turbomodule/core 780 | - React-Fabric/scheduler (0.73.9): 781 | - DoubleConversion 782 | - fmt (~> 6.2.1) 783 | - glog 784 | - hermes-engine 785 | - RCT-Folly/Fabric (= 2022.05.16.00) 786 | - RCTRequired 787 | - RCTTypeSafety 788 | - React-Core 789 | - React-cxxreact 790 | - React-debug 791 | - React-graphics 792 | - React-jsi 793 | - React-jsiexecutor 794 | - React-logger 795 | - React-rendererdebug 796 | - React-runtimescheduler 797 | - React-utils 798 | - ReactCommon/turbomodule/core 799 | - React-Fabric/telemetry (0.73.9): 800 | - DoubleConversion 801 | - fmt (~> 6.2.1) 802 | - glog 803 | - hermes-engine 804 | - RCT-Folly/Fabric (= 2022.05.16.00) 805 | - RCTRequired 806 | - RCTTypeSafety 807 | - React-Core 808 | - React-cxxreact 809 | - React-debug 810 | - React-graphics 811 | - React-jsi 812 | - React-jsiexecutor 813 | - React-logger 814 | - React-rendererdebug 815 | - React-runtimescheduler 816 | - React-utils 817 | - ReactCommon/turbomodule/core 818 | - React-Fabric/templateprocessor (0.73.9): 819 | - DoubleConversion 820 | - fmt (~> 6.2.1) 821 | - glog 822 | - hermes-engine 823 | - RCT-Folly/Fabric (= 2022.05.16.00) 824 | - RCTRequired 825 | - RCTTypeSafety 826 | - React-Core 827 | - React-cxxreact 828 | - React-debug 829 | - React-graphics 830 | - React-jsi 831 | - React-jsiexecutor 832 | - React-logger 833 | - React-rendererdebug 834 | - React-runtimescheduler 835 | - React-utils 836 | - ReactCommon/turbomodule/core 837 | - React-Fabric/textlayoutmanager (0.73.9): 838 | - DoubleConversion 839 | - fmt (~> 6.2.1) 840 | - glog 841 | - hermes-engine 842 | - RCT-Folly/Fabric (= 2022.05.16.00) 843 | - RCTRequired 844 | - RCTTypeSafety 845 | - React-Core 846 | - React-cxxreact 847 | - React-debug 848 | - React-Fabric/uimanager 849 | - React-graphics 850 | - React-jsi 851 | - React-jsiexecutor 852 | - React-logger 853 | - React-rendererdebug 854 | - React-runtimescheduler 855 | - React-utils 856 | - ReactCommon/turbomodule/core 857 | - React-Fabric/uimanager (0.73.9): 858 | - DoubleConversion 859 | - fmt (~> 6.2.1) 860 | - glog 861 | - hermes-engine 862 | - RCT-Folly/Fabric (= 2022.05.16.00) 863 | - RCTRequired 864 | - RCTTypeSafety 865 | - React-Core 866 | - React-cxxreact 867 | - React-debug 868 | - React-graphics 869 | - React-jsi 870 | - React-jsiexecutor 871 | - React-logger 872 | - React-rendererdebug 873 | - React-runtimescheduler 874 | - React-utils 875 | - ReactCommon/turbomodule/core 876 | - React-FabricImage (0.73.9): 877 | - DoubleConversion 878 | - fmt (~> 6.2.1) 879 | - glog 880 | - hermes-engine 881 | - RCT-Folly/Fabric (= 2022.05.16.00) 882 | - RCTRequired (= 0.73.9) 883 | - RCTTypeSafety (= 0.73.9) 884 | - React-Fabric 885 | - React-graphics 886 | - React-ImageManager 887 | - React-jsi 888 | - React-jsiexecutor (= 0.73.9) 889 | - React-logger 890 | - React-rendererdebug 891 | - React-utils 892 | - ReactCommon 893 | - Yoga 894 | - React-graphics (0.73.9): 895 | - glog 896 | - RCT-Folly/Fabric (= 2022.05.16.00) 897 | - React-Core/Default (= 0.73.9) 898 | - React-utils 899 | - React-hermes (0.73.9): 900 | - DoubleConversion 901 | - fmt (~> 6.2.1) 902 | - glog 903 | - hermes-engine 904 | - RCT-Folly (= 2022.05.16.00) 905 | - RCT-Folly/Futures (= 2022.05.16.00) 906 | - React-cxxreact (= 0.73.9) 907 | - React-jsi 908 | - React-jsiexecutor (= 0.73.9) 909 | - React-jsinspector (= 0.73.9) 910 | - React-perflogger (= 0.73.9) 911 | - React-ImageManager (0.73.9): 912 | - glog 913 | - RCT-Folly/Fabric 914 | - React-Core/Default 915 | - React-debug 916 | - React-Fabric 917 | - React-graphics 918 | - React-rendererdebug 919 | - React-utils 920 | - React-jserrorhandler (0.73.9): 921 | - RCT-Folly/Fabric (= 2022.05.16.00) 922 | - React-debug 923 | - React-jsi 924 | - React-Mapbuffer 925 | - React-jsi (0.73.9): 926 | - boost (= 1.83.0) 927 | - DoubleConversion 928 | - fmt (~> 6.2.1) 929 | - glog 930 | - hermes-engine 931 | - RCT-Folly (= 2022.05.16.00) 932 | - React-jsiexecutor (0.73.9): 933 | - DoubleConversion 934 | - fmt (~> 6.2.1) 935 | - glog 936 | - hermes-engine 937 | - RCT-Folly (= 2022.05.16.00) 938 | - React-cxxreact (= 0.73.9) 939 | - React-jsi (= 0.73.9) 940 | - React-perflogger (= 0.73.9) 941 | - React-jsinspector (0.73.9) 942 | - React-logger (0.73.9): 943 | - glog 944 | - React-Mapbuffer (0.73.9): 945 | - glog 946 | - React-debug 947 | - React-nativeconfig (0.73.9) 948 | - React-NativeModulesApple (0.73.9): 949 | - glog 950 | - hermes-engine 951 | - React-callinvoker 952 | - React-Core 953 | - React-cxxreact 954 | - React-jsi 955 | - React-runtimeexecutor 956 | - ReactCommon/turbomodule/bridging 957 | - ReactCommon/turbomodule/core 958 | - React-perflogger (0.73.9) 959 | - React-RCTActionSheet (0.73.9): 960 | - React-Core/RCTActionSheetHeaders (= 0.73.9) 961 | - React-RCTAnimation (0.73.9): 962 | - RCT-Folly (= 2022.05.16.00) 963 | - RCTTypeSafety 964 | - React-Codegen 965 | - React-Core/RCTAnimationHeaders 966 | - React-jsi 967 | - React-NativeModulesApple 968 | - ReactCommon 969 | - React-RCTAppDelegate (0.73.9): 970 | - RCT-Folly 971 | - RCTRequired 972 | - RCTTypeSafety 973 | - React-Core 974 | - React-CoreModules 975 | - React-hermes 976 | - React-nativeconfig 977 | - React-NativeModulesApple 978 | - React-RCTFabric 979 | - React-RCTImage 980 | - React-RCTNetwork 981 | - React-runtimescheduler 982 | - ReactCommon 983 | - React-RCTBlob (0.73.9): 984 | - hermes-engine 985 | - RCT-Folly (= 2022.05.16.00) 986 | - React-Codegen 987 | - React-Core/RCTBlobHeaders 988 | - React-Core/RCTWebSocket 989 | - React-jsi 990 | - React-NativeModulesApple 991 | - React-RCTNetwork 992 | - ReactCommon 993 | - React-RCTFabric (0.73.9): 994 | - glog 995 | - hermes-engine 996 | - RCT-Folly/Fabric (= 2022.05.16.00) 997 | - React-Core 998 | - React-debug 999 | - React-Fabric 1000 | - React-FabricImage 1001 | - React-graphics 1002 | - React-ImageManager 1003 | - React-jsi 1004 | - React-nativeconfig 1005 | - React-RCTImage 1006 | - React-RCTText 1007 | - React-rendererdebug 1008 | - React-runtimescheduler 1009 | - React-utils 1010 | - Yoga 1011 | - React-RCTImage (0.73.9): 1012 | - RCT-Folly (= 2022.05.16.00) 1013 | - RCTTypeSafety 1014 | - React-Codegen 1015 | - React-Core/RCTImageHeaders 1016 | - React-jsi 1017 | - React-NativeModulesApple 1018 | - React-RCTNetwork 1019 | - ReactCommon 1020 | - React-RCTLinking (0.73.9): 1021 | - React-Codegen 1022 | - React-Core/RCTLinkingHeaders (= 0.73.9) 1023 | - React-jsi (= 0.73.9) 1024 | - React-NativeModulesApple 1025 | - ReactCommon 1026 | - ReactCommon/turbomodule/core (= 0.73.9) 1027 | - React-RCTNetwork (0.73.9): 1028 | - RCT-Folly (= 2022.05.16.00) 1029 | - RCTTypeSafety 1030 | - React-Codegen 1031 | - React-Core/RCTNetworkHeaders 1032 | - React-jsi 1033 | - React-NativeModulesApple 1034 | - ReactCommon 1035 | - React-RCTSettings (0.73.9): 1036 | - RCT-Folly (= 2022.05.16.00) 1037 | - RCTTypeSafety 1038 | - React-Codegen 1039 | - React-Core/RCTSettingsHeaders 1040 | - React-jsi 1041 | - React-NativeModulesApple 1042 | - ReactCommon 1043 | - React-RCTText (0.73.9): 1044 | - React-Core/RCTTextHeaders (= 0.73.9) 1045 | - Yoga 1046 | - React-RCTVibration (0.73.9): 1047 | - RCT-Folly (= 2022.05.16.00) 1048 | - React-Codegen 1049 | - React-Core/RCTVibrationHeaders 1050 | - React-jsi 1051 | - React-NativeModulesApple 1052 | - ReactCommon 1053 | - React-rendererdebug (0.73.9): 1054 | - DoubleConversion 1055 | - fmt (~> 6.2.1) 1056 | - RCT-Folly (= 2022.05.16.00) 1057 | - React-debug 1058 | - React-rncore (0.73.9) 1059 | - React-runtimeexecutor (0.73.9): 1060 | - React-jsi (= 0.73.9) 1061 | - React-runtimescheduler (0.73.9): 1062 | - glog 1063 | - hermes-engine 1064 | - RCT-Folly (= 2022.05.16.00) 1065 | - React-callinvoker 1066 | - React-cxxreact 1067 | - React-debug 1068 | - React-jsi 1069 | - React-rendererdebug 1070 | - React-runtimeexecutor 1071 | - React-utils 1072 | - React-utils (0.73.9): 1073 | - glog 1074 | - RCT-Folly (= 2022.05.16.00) 1075 | - React-debug 1076 | - ReactCommon (0.73.9): 1077 | - React-logger (= 0.73.9) 1078 | - ReactCommon/turbomodule (= 0.73.9) 1079 | - ReactCommon/turbomodule (0.73.9): 1080 | - DoubleConversion 1081 | - fmt (~> 6.2.1) 1082 | - glog 1083 | - hermes-engine 1084 | - RCT-Folly (= 2022.05.16.00) 1085 | - React-callinvoker (= 0.73.9) 1086 | - React-cxxreact (= 0.73.9) 1087 | - React-jsi (= 0.73.9) 1088 | - React-logger (= 0.73.9) 1089 | - React-perflogger (= 0.73.9) 1090 | - ReactCommon/turbomodule/bridging (= 0.73.9) 1091 | - ReactCommon/turbomodule/core (= 0.73.9) 1092 | - ReactCommon/turbomodule/bridging (0.73.9): 1093 | - DoubleConversion 1094 | - fmt (~> 6.2.1) 1095 | - glog 1096 | - hermes-engine 1097 | - RCT-Folly (= 2022.05.16.00) 1098 | - React-callinvoker (= 0.73.9) 1099 | - React-cxxreact (= 0.73.9) 1100 | - React-jsi (= 0.73.9) 1101 | - React-logger (= 0.73.9) 1102 | - React-perflogger (= 0.73.9) 1103 | - ReactCommon/turbomodule/core (0.73.9): 1104 | - DoubleConversion 1105 | - fmt (~> 6.2.1) 1106 | - glog 1107 | - hermes-engine 1108 | - RCT-Folly (= 2022.05.16.00) 1109 | - React-callinvoker (= 0.73.9) 1110 | - React-cxxreact (= 0.73.9) 1111 | - React-jsi (= 0.73.9) 1112 | - React-logger (= 0.73.9) 1113 | - React-perflogger (= 0.73.9) 1114 | - RNInAppPurchase (2.0.10): 1115 | - glog 1116 | - RCT-Folly (= 2022.05.16.00) 1117 | - React 1118 | - React-Core 1119 | - SocketRocket (0.6.1) 1120 | - Yoga (1.14.0) 1121 | 1122 | DEPENDENCIES: 1123 | - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) 1124 | - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) 1125 | - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) 1126 | - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) 1127 | - Flipper (= 0.201.0) 1128 | - Flipper-Boost-iOSX (= 1.76.0.1.11) 1129 | - Flipper-DoubleConversion (= 3.2.0.1) 1130 | - Flipper-Fmt (= 7.1.7) 1131 | - Flipper-Folly (= 2.6.10) 1132 | - Flipper-Glog (= 0.5.0.5) 1133 | - Flipper-PeerTalk (= 0.0.4) 1134 | - FlipperKit (= 0.201.0) 1135 | - FlipperKit/Core (= 0.201.0) 1136 | - FlipperKit/CppBridge (= 0.201.0) 1137 | - FlipperKit/FBCxxFollyDynamicConvert (= 0.201.0) 1138 | - FlipperKit/FBDefines (= 0.201.0) 1139 | - FlipperKit/FKPortForwarding (= 0.201.0) 1140 | - FlipperKit/FlipperKitHighlightOverlay (= 0.201.0) 1141 | - FlipperKit/FlipperKitLayoutPlugin (= 0.201.0) 1142 | - FlipperKit/FlipperKitLayoutTextSearchable (= 0.201.0) 1143 | - FlipperKit/FlipperKitNetworkPlugin (= 0.201.0) 1144 | - FlipperKit/FlipperKitReactPlugin (= 0.201.0) 1145 | - FlipperKit/FlipperKitUserDefaultsPlugin (= 0.201.0) 1146 | - FlipperKit/SKIOSNetworkPlugin (= 0.201.0) 1147 | - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) 1148 | - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) 1149 | - libevent (~> 2.1.12) 1150 | - OpenSSL-Universal (= 1.1.1100) 1151 | - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) 1152 | - RCT-Folly/Fabric (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) 1153 | - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) 1154 | - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) 1155 | - React (from `../node_modules/react-native/`) 1156 | - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`) 1157 | - React-Codegen (from `build/generated/ios`) 1158 | - React-Core (from `../node_modules/react-native/`) 1159 | - React-Core/DevSupport (from `../node_modules/react-native/`) 1160 | - React-Core/RCTWebSocket (from `../node_modules/react-native/`) 1161 | - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) 1162 | - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) 1163 | - React-debug (from `../node_modules/react-native/ReactCommon/react/debug`) 1164 | - React-Fabric (from `../node_modules/react-native/ReactCommon`) 1165 | - React-FabricImage (from `../node_modules/react-native/ReactCommon`) 1166 | - React-graphics (from `../node_modules/react-native/ReactCommon/react/renderer/graphics`) 1167 | - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`) 1168 | - React-ImageManager (from `../node_modules/react-native/ReactCommon/react/renderer/imagemanager/platform/ios`) 1169 | - React-jserrorhandler (from `../node_modules/react-native/ReactCommon/jserrorhandler`) 1170 | - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) 1171 | - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) 1172 | - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector-modern`) 1173 | - React-logger (from `../node_modules/react-native/ReactCommon/logger`) 1174 | - React-Mapbuffer (from `../node_modules/react-native/ReactCommon`) 1175 | - React-nativeconfig (from `../node_modules/react-native/ReactCommon`) 1176 | - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) 1177 | - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) 1178 | - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) 1179 | - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) 1180 | - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`) 1181 | - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) 1182 | - React-RCTFabric (from `../node_modules/react-native/React`) 1183 | - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) 1184 | - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) 1185 | - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) 1186 | - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) 1187 | - React-RCTText (from `../node_modules/react-native/Libraries/Text`) 1188 | - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) 1189 | - React-rendererdebug (from `../node_modules/react-native/ReactCommon/react/renderer/debug`) 1190 | - React-rncore (from `../node_modules/react-native/ReactCommon`) 1191 | - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) 1192 | - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`) 1193 | - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) 1194 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) 1195 | - "RNInAppPurchase (from `../node_modules/@class101/react-native-in-app-purchase`)" 1196 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) 1197 | 1198 | SPEC REPOS: 1199 | trunk: 1200 | - CocoaAsyncSocket 1201 | - Flipper 1202 | - Flipper-Boost-iOSX 1203 | - Flipper-DoubleConversion 1204 | - Flipper-Fmt 1205 | - Flipper-Folly 1206 | - Flipper-Glog 1207 | - Flipper-PeerTalk 1208 | - FlipperKit 1209 | - fmt 1210 | - libevent 1211 | - OpenSSL-Universal 1212 | - SocketRocket 1213 | 1214 | EXTERNAL SOURCES: 1215 | boost: 1216 | :podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec" 1217 | DoubleConversion: 1218 | :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" 1219 | FBLazyVector: 1220 | :path: "../node_modules/react-native/Libraries/FBLazyVector" 1221 | FBReactNativeSpec: 1222 | :path: "../node_modules/react-native/React/FBReactNativeSpec" 1223 | glog: 1224 | :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" 1225 | hermes-engine: 1226 | :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" 1227 | :tag: hermes-2024-04-29-RNv0.73.8-644c8be78af1eae7c138fa4093fb87f0f4f8db85 1228 | RCT-Folly: 1229 | :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" 1230 | RCTRequired: 1231 | :path: "../node_modules/react-native/Libraries/RCTRequired" 1232 | RCTTypeSafety: 1233 | :path: "../node_modules/react-native/Libraries/TypeSafety" 1234 | React: 1235 | :path: "../node_modules/react-native/" 1236 | React-callinvoker: 1237 | :path: "../node_modules/react-native/ReactCommon/callinvoker" 1238 | React-Codegen: 1239 | :path: build/generated/ios 1240 | React-Core: 1241 | :path: "../node_modules/react-native/" 1242 | React-CoreModules: 1243 | :path: "../node_modules/react-native/React/CoreModules" 1244 | React-cxxreact: 1245 | :path: "../node_modules/react-native/ReactCommon/cxxreact" 1246 | React-debug: 1247 | :path: "../node_modules/react-native/ReactCommon/react/debug" 1248 | React-Fabric: 1249 | :path: "../node_modules/react-native/ReactCommon" 1250 | React-FabricImage: 1251 | :path: "../node_modules/react-native/ReactCommon" 1252 | React-graphics: 1253 | :path: "../node_modules/react-native/ReactCommon/react/renderer/graphics" 1254 | React-hermes: 1255 | :path: "../node_modules/react-native/ReactCommon/hermes" 1256 | React-ImageManager: 1257 | :path: "../node_modules/react-native/ReactCommon/react/renderer/imagemanager/platform/ios" 1258 | React-jserrorhandler: 1259 | :path: "../node_modules/react-native/ReactCommon/jserrorhandler" 1260 | React-jsi: 1261 | :path: "../node_modules/react-native/ReactCommon/jsi" 1262 | React-jsiexecutor: 1263 | :path: "../node_modules/react-native/ReactCommon/jsiexecutor" 1264 | React-jsinspector: 1265 | :path: "../node_modules/react-native/ReactCommon/jsinspector-modern" 1266 | React-logger: 1267 | :path: "../node_modules/react-native/ReactCommon/logger" 1268 | React-Mapbuffer: 1269 | :path: "../node_modules/react-native/ReactCommon" 1270 | React-nativeconfig: 1271 | :path: "../node_modules/react-native/ReactCommon" 1272 | React-NativeModulesApple: 1273 | :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios" 1274 | React-perflogger: 1275 | :path: "../node_modules/react-native/ReactCommon/reactperflogger" 1276 | React-RCTActionSheet: 1277 | :path: "../node_modules/react-native/Libraries/ActionSheetIOS" 1278 | React-RCTAnimation: 1279 | :path: "../node_modules/react-native/Libraries/NativeAnimation" 1280 | React-RCTAppDelegate: 1281 | :path: "../node_modules/react-native/Libraries/AppDelegate" 1282 | React-RCTBlob: 1283 | :path: "../node_modules/react-native/Libraries/Blob" 1284 | React-RCTFabric: 1285 | :path: "../node_modules/react-native/React" 1286 | React-RCTImage: 1287 | :path: "../node_modules/react-native/Libraries/Image" 1288 | React-RCTLinking: 1289 | :path: "../node_modules/react-native/Libraries/LinkingIOS" 1290 | React-RCTNetwork: 1291 | :path: "../node_modules/react-native/Libraries/Network" 1292 | React-RCTSettings: 1293 | :path: "../node_modules/react-native/Libraries/Settings" 1294 | React-RCTText: 1295 | :path: "../node_modules/react-native/Libraries/Text" 1296 | React-RCTVibration: 1297 | :path: "../node_modules/react-native/Libraries/Vibration" 1298 | React-rendererdebug: 1299 | :path: "../node_modules/react-native/ReactCommon/react/renderer/debug" 1300 | React-rncore: 1301 | :path: "../node_modules/react-native/ReactCommon" 1302 | React-runtimeexecutor: 1303 | :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" 1304 | React-runtimescheduler: 1305 | :path: "../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler" 1306 | React-utils: 1307 | :path: "../node_modules/react-native/ReactCommon/react/utils" 1308 | ReactCommon: 1309 | :path: "../node_modules/react-native/ReactCommon" 1310 | RNInAppPurchase: 1311 | :path: "../node_modules/@class101/react-native-in-app-purchase" 1312 | Yoga: 1313 | :path: "../node_modules/react-native/ReactCommon/yoga" 1314 | 1315 | SPEC CHECKSUMS: 1316 | boost: d3f49c53809116a5d38da093a8aa78bf551aed09 1317 | CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 1318 | DoubleConversion: fea03f2699887d960129cc54bba7e52542b6f953 1319 | FBLazyVector: 98c189b92292d4bfeac13ffa8df3ce3d84e2fc5b 1320 | FBReactNativeSpec: 4fe1d8c2fadc7949344b197d933f76b40401aac5 1321 | Flipper: c7a0093234c4bdd456e363f2f19b2e4b27652d44 1322 | Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c 1323 | Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30 1324 | Flipper-Fmt: 60cbdd92fc254826e61d669a5d87ef7015396a9b 1325 | Flipper-Folly: 584845625005ff068a6ebf41f857f468decd26b3 1326 | Flipper-Glog: 70c50ce58ddaf67dc35180db05f191692570f446 1327 | Flipper-PeerTalk: 116d8f857dc6ef55c7a5a75ea3ceaafe878aadc9 1328 | FlipperKit: 37525a5d056ef9b93d1578e04bc3ea1de940094f 1329 | fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 1330 | glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2 1331 | hermes-engine: ed62e0dcd013bf4a3b487f164feec1c4e705b5b5 1332 | libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 1333 | OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c 1334 | RCT-Folly: 7169b2b1c44399c76a47b5deaaba715eeeb476c0 1335 | RCTRequired: d362a61864a64315aee00faea8dee6cf5b3f4aad 1336 | RCTTypeSafety: 09baf60faeab02492dc8bf04ce5af1dda645b86d 1337 | React: b87c7c7c12f8232bd7cfdc4a00bf687144c17e30 1338 | React-callinvoker: 67de0bc05ecb7e690345a53a1661cea9b24670b0 1339 | React-Codegen: d4acea6cf2a7889c042653eaff9233b1d6c4d3c3 1340 | React-Core: 4c87a1873c6d11c6d3843582fbc266ba9ea304ce 1341 | React-CoreModules: 29ad1cbe757a70575913457bb7c646b7f4d4edf0 1342 | React-cxxreact: 08ffaf2def6fe1ec8ef7f16e208587c96a87978e 1343 | React-debug: 937e24adc0479b9bbed3f1b7e0db68688d93c31c 1344 | React-Fabric: 1e2eb26de25f2629350beaab7abc3623becce2b7 1345 | React-FabricImage: 5791bf14ff0550f26b81be575e9a10f1f3c69688 1346 | React-graphics: 3ba4dba54c4d1426118089f1943708ef0bba8a84 1347 | React-hermes: fdaab14cc289d8d9cd45ffd9a3f8aa11157d4c7e 1348 | React-ImageManager: 13b4aebbffd9addbcd79d1687355db2f6d8a37e2 1349 | React-jserrorhandler: f30af3ec30fdc04a4b080c5b1f3defb801c0c861 1350 | React-jsi: 2253621cb2fb5d43a78fec4db8989cf9711039df 1351 | React-jsiexecutor: 5e4620a87fbc4ab174d75220f06ba8b53ae8317b 1352 | React-jsinspector: aee04d04ef553d5e30e52a4de2af958cb060069f 1353 | React-logger: 87a4232dd55485435edfa6803ff0de0b5c9eea1a 1354 | React-Mapbuffer: 6c229dc8f1640457d1f665f0b7d79ab8f604dc8b 1355 | React-nativeconfig: c1729ab95240ec80d47a2bb8354d8f31138e35a7 1356 | React-NativeModulesApple: 115c934a87f3b45fecb0fada08fa70bab3dff65c 1357 | React-perflogger: c93b6a895eca3f9196656bb20ce0e15ad597a4e9 1358 | React-RCTActionSheet: 258842f426709dccbc2af31ca42b0a1807d76ad7 1359 | React-RCTAnimation: 78c40269e35864f541b7486d17bd82a353c99fbc 1360 | React-RCTAppDelegate: d98ec2cdfb161d7a8496990e9649f94018025922 1361 | React-RCTBlob: 593a5dbc58c45e3cccc37ad4498b10766ace26e6 1362 | React-RCTFabric: e6060e78040264f8a542bb8631ae1bbfd5a882ed 1363 | React-RCTImage: a0cdbb81db012ebc42c7dbaabdcb15f488c7c391 1364 | React-RCTLinking: 82b6b0a5b2d5c8d3a28997e70bda46bac4be4c6e 1365 | React-RCTNetwork: 45e30079bcb987724028c9a93c0110b6d82e4a1f 1366 | React-RCTSettings: e67cbe694fe45b080b96b1394d4e45dff1b3ae04 1367 | React-RCTText: 14a54686a1fa0b51b76660c7700980fdec6c3093 1368 | React-RCTVibration: 00561f3d12dca44ed55af9060752bf8cf3fb0bfc 1369 | React-rendererdebug: 975f3e6e430ba1a9b92dc44bc99757cb1c6cae60 1370 | React-rncore: e7dc772ade687746b8a8a38985b4512b8d232637 1371 | React-runtimeexecutor: bf98e8973ed4c45139fbbaf2c34af44053acc9a9 1372 | React-runtimescheduler: efb26ad81d94a9b047504bd716b48869bd311649 1373 | React-utils: dab84549e65d6d711937b9c34d9f6d8fb8bd711c 1374 | ReactCommon: 3dc453f427d2f3d7f2c71499d191b456f83c59bd 1375 | RNInAppPurchase: 4388b2b30b6dae90d63592c079ff98998e849293 1376 | SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 1377 | Yoga: 6aaa3c45f0fda0c6929f855121622669dabe1aaf 1378 | 1379 | PODFILE CHECKSUM: 633ce1a49803ed7ea8d9eae24b715dcf52a433d3 1380 | 1381 | COCOAPODS: 1.15.2 1382 | -------------------------------------------------------------------------------- /sample/ios/RNInAppPurchaseSample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 00E356F31AD99517003FC87E /* RNInAppPurchaseSampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* RNInAppPurchaseSampleTests.m */; }; 11 | 0C80B921A6F3F58F76C31292 /* libPods-RNInAppPurchaseSample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5DCACB8F33CDC322A6C60F78 /* libPods-RNInAppPurchaseSample.a */; }; 12 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 13 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 14 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 15 | 6132EF182BDFF13200BBE14D /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = 6132EF172BDFF13200BBE14D /* PrivacyInfo.xcprivacy */; }; 16 | 7699B88040F8A987B510C191 /* libPods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19F6CBCC0A4E27FBF8BF4A61 /* libPods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.a */; }; 17 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXContainerItemProxy section */ 21 | 00E356F41AD99517003FC87E /* PBXContainerItemProxy */ = { 22 | isa = PBXContainerItemProxy; 23 | containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; 24 | proxyType = 1; 25 | remoteGlobalIDString = 13B07F861A680F5B00A75B9A; 26 | remoteInfo = RNInAppPurchaseSample; 27 | }; 28 | /* End PBXContainerItemProxy section */ 29 | 30 | /* Begin PBXFileReference section */ 31 | 00E356EE1AD99517003FC87E /* RNInAppPurchaseSampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RNInAppPurchaseSampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | 00E356F21AD99517003FC87E /* RNInAppPurchaseSampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNInAppPurchaseSampleTests.m; sourceTree = ""; }; 34 | 13B07F961A680F5B00A75B9A /* RNInAppPurchaseSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RNInAppPurchaseSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 35 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = RNInAppPurchaseSample/AppDelegate.h; sourceTree = ""; }; 36 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = RNInAppPurchaseSample/AppDelegate.mm; sourceTree = ""; }; 37 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = RNInAppPurchaseSample/Images.xcassets; sourceTree = ""; }; 38 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = RNInAppPurchaseSample/Info.plist; sourceTree = ""; }; 39 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = RNInAppPurchaseSample/main.m; sourceTree = ""; }; 40 | 19F6CBCC0A4E27FBF8BF4A61 /* libPods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 41 | 3B4392A12AC88292D35C810B /* Pods-RNInAppPurchaseSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNInAppPurchaseSample.debug.xcconfig"; path = "Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample.debug.xcconfig"; sourceTree = ""; }; 42 | 5709B34CF0A7D63546082F79 /* Pods-RNInAppPurchaseSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNInAppPurchaseSample.release.xcconfig"; path = "Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample.release.xcconfig"; sourceTree = ""; }; 43 | 5B7EB9410499542E8C5724F5 /* Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.debug.xcconfig"; path = "Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.debug.xcconfig"; sourceTree = ""; }; 44 | 5DCACB8F33CDC322A6C60F78 /* libPods-RNInAppPurchaseSample.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RNInAppPurchaseSample.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 6132EF172BDFF13200BBE14D /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; name = PrivacyInfo.xcprivacy; path = RNInAppPurchaseSample/PrivacyInfo.xcprivacy; sourceTree = ""; }; 46 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = LaunchScreen.storyboard; path = RNInAppPurchaseSample/LaunchScreen.storyboard; sourceTree = ""; }; 47 | 89C6BE57DB24E9ADA2F236DE /* Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.release.xcconfig"; path = "Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.release.xcconfig"; sourceTree = ""; }; 48 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; 49 | /* End PBXFileReference section */ 50 | 51 | /* Begin PBXFrameworksBuildPhase section */ 52 | 00E356EB1AD99517003FC87E /* Frameworks */ = { 53 | isa = PBXFrameworksBuildPhase; 54 | buildActionMask = 2147483647; 55 | files = ( 56 | 7699B88040F8A987B510C191 /* libPods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.a in Frameworks */, 57 | ); 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { 61 | isa = PBXFrameworksBuildPhase; 62 | buildActionMask = 2147483647; 63 | files = ( 64 | 0C80B921A6F3F58F76C31292 /* libPods-RNInAppPurchaseSample.a in Frameworks */, 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | /* End PBXFrameworksBuildPhase section */ 69 | 70 | /* Begin PBXGroup section */ 71 | 00E356EF1AD99517003FC87E /* RNInAppPurchaseSampleTests */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | 00E356F21AD99517003FC87E /* RNInAppPurchaseSampleTests.m */, 75 | 00E356F01AD99517003FC87E /* Supporting Files */, 76 | ); 77 | path = RNInAppPurchaseSampleTests; 78 | sourceTree = ""; 79 | }; 80 | 00E356F01AD99517003FC87E /* Supporting Files */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | 00E356F11AD99517003FC87E /* Info.plist */, 84 | ); 85 | name = "Supporting Files"; 86 | sourceTree = ""; 87 | }; 88 | 13B07FAE1A68108700A75B9A /* RNInAppPurchaseSample */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 92 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */, 93 | 13B07FB51A68108700A75B9A /* Images.xcassets */, 94 | 13B07FB61A68108700A75B9A /* Info.plist */, 95 | 81AB9BB72411601600AC10FF /* LaunchScreen.storyboard */, 96 | 13B07FB71A68108700A75B9A /* main.m */, 97 | ); 98 | name = RNInAppPurchaseSample; 99 | sourceTree = ""; 100 | }; 101 | 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { 102 | isa = PBXGroup; 103 | children = ( 104 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */, 105 | 5DCACB8F33CDC322A6C60F78 /* libPods-RNInAppPurchaseSample.a */, 106 | 19F6CBCC0A4E27FBF8BF4A61 /* libPods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.a */, 107 | ); 108 | name = Frameworks; 109 | sourceTree = ""; 110 | }; 111 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = { 112 | isa = PBXGroup; 113 | children = ( 114 | ); 115 | name = Libraries; 116 | sourceTree = ""; 117 | }; 118 | 83CBB9F61A601CBA00E9B192 = { 119 | isa = PBXGroup; 120 | children = ( 121 | 6132EF172BDFF13200BBE14D /* PrivacyInfo.xcprivacy */, 122 | 13B07FAE1A68108700A75B9A /* RNInAppPurchaseSample */, 123 | 832341AE1AAA6A7D00B99B32 /* Libraries */, 124 | 00E356EF1AD99517003FC87E /* RNInAppPurchaseSampleTests */, 125 | 83CBBA001A601CBA00E9B192 /* Products */, 126 | 2D16E6871FA4F8E400B85C8A /* Frameworks */, 127 | BBD78D7AC51CEA395F1C20DB /* Pods */, 128 | ); 129 | indentWidth = 2; 130 | sourceTree = ""; 131 | tabWidth = 2; 132 | usesTabs = 0; 133 | }; 134 | 83CBBA001A601CBA00E9B192 /* Products */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 13B07F961A680F5B00A75B9A /* RNInAppPurchaseSample.app */, 138 | 00E356EE1AD99517003FC87E /* RNInAppPurchaseSampleTests.xctest */, 139 | ); 140 | name = Products; 141 | sourceTree = ""; 142 | }; 143 | BBD78D7AC51CEA395F1C20DB /* Pods */ = { 144 | isa = PBXGroup; 145 | children = ( 146 | 3B4392A12AC88292D35C810B /* Pods-RNInAppPurchaseSample.debug.xcconfig */, 147 | 5709B34CF0A7D63546082F79 /* Pods-RNInAppPurchaseSample.release.xcconfig */, 148 | 5B7EB9410499542E8C5724F5 /* Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.debug.xcconfig */, 149 | 89C6BE57DB24E9ADA2F236DE /* Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.release.xcconfig */, 150 | ); 151 | path = Pods; 152 | sourceTree = ""; 153 | }; 154 | /* End PBXGroup section */ 155 | 156 | /* Begin PBXNativeTarget section */ 157 | 00E356ED1AD99517003FC87E /* RNInAppPurchaseSampleTests */ = { 158 | isa = PBXNativeTarget; 159 | buildConfigurationList = 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "RNInAppPurchaseSampleTests" */; 160 | buildPhases = ( 161 | A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */, 162 | 00E356EA1AD99517003FC87E /* Sources */, 163 | 00E356EB1AD99517003FC87E /* Frameworks */, 164 | 00E356EC1AD99517003FC87E /* Resources */, 165 | C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */, 166 | F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */, 167 | ); 168 | buildRules = ( 169 | ); 170 | dependencies = ( 171 | 00E356F51AD99517003FC87E /* PBXTargetDependency */, 172 | ); 173 | name = RNInAppPurchaseSampleTests; 174 | productName = RNInAppPurchaseSampleTests; 175 | productReference = 00E356EE1AD99517003FC87E /* RNInAppPurchaseSampleTests.xctest */; 176 | productType = "com.apple.product-type.bundle.unit-test"; 177 | }; 178 | 13B07F861A680F5B00A75B9A /* RNInAppPurchaseSample */ = { 179 | isa = PBXNativeTarget; 180 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "RNInAppPurchaseSample" */; 181 | buildPhases = ( 182 | C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */, 183 | 13B07F871A680F5B00A75B9A /* Sources */, 184 | 13B07F8C1A680F5B00A75B9A /* Frameworks */, 185 | 13B07F8E1A680F5B00A75B9A /* Resources */, 186 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 187 | 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */, 188 | E235C05ADACE081382539298 /* [CP] Copy Pods Resources */, 189 | ); 190 | buildRules = ( 191 | ); 192 | dependencies = ( 193 | ); 194 | name = RNInAppPurchaseSample; 195 | productName = RNInAppPurchaseSample; 196 | productReference = 13B07F961A680F5B00A75B9A /* RNInAppPurchaseSample.app */; 197 | productType = "com.apple.product-type.application"; 198 | }; 199 | /* End PBXNativeTarget section */ 200 | 201 | /* Begin PBXProject section */ 202 | 83CBB9F71A601CBA00E9B192 /* Project object */ = { 203 | isa = PBXProject; 204 | attributes = { 205 | LastUpgradeCheck = 1210; 206 | TargetAttributes = { 207 | 00E356ED1AD99517003FC87E = { 208 | CreatedOnToolsVersion = 6.2; 209 | TestTargetID = 13B07F861A680F5B00A75B9A; 210 | }; 211 | 13B07F861A680F5B00A75B9A = { 212 | LastSwiftMigration = 1120; 213 | }; 214 | }; 215 | }; 216 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "RNInAppPurchaseSample" */; 217 | compatibilityVersion = "Xcode 12.0"; 218 | developmentRegion = en; 219 | hasScannedForEncodings = 0; 220 | knownRegions = ( 221 | en, 222 | Base, 223 | ); 224 | mainGroup = 83CBB9F61A601CBA00E9B192; 225 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; 226 | projectDirPath = ""; 227 | projectRoot = ""; 228 | targets = ( 229 | 13B07F861A680F5B00A75B9A /* RNInAppPurchaseSample */, 230 | 00E356ED1AD99517003FC87E /* RNInAppPurchaseSampleTests */, 231 | ); 232 | }; 233 | /* End PBXProject section */ 234 | 235 | /* Begin PBXResourcesBuildPhase section */ 236 | 00E356EC1AD99517003FC87E /* Resources */ = { 237 | isa = PBXResourcesBuildPhase; 238 | buildActionMask = 2147483647; 239 | files = ( 240 | ); 241 | runOnlyForDeploymentPostprocessing = 0; 242 | }; 243 | 13B07F8E1A680F5B00A75B9A /* Resources */ = { 244 | isa = PBXResourcesBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | 6132EF182BDFF13200BBE14D /* PrivacyInfo.xcprivacy in Resources */, 248 | 81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */, 249 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 250 | ); 251 | runOnlyForDeploymentPostprocessing = 0; 252 | }; 253 | /* End PBXResourcesBuildPhase section */ 254 | 255 | /* Begin PBXShellScriptBuildPhase section */ 256 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { 257 | isa = PBXShellScriptBuildPhase; 258 | buildActionMask = 2147483647; 259 | files = ( 260 | ); 261 | inputPaths = ( 262 | "$(SRCROOT)/.xcode.env.local", 263 | "$(SRCROOT)/.xcode.env", 264 | ); 265 | name = "Bundle React Native code and images"; 266 | outputPaths = ( 267 | ); 268 | runOnlyForDeploymentPostprocessing = 0; 269 | shellPath = /bin/sh; 270 | shellScript = "set -e\n\nWITH_ENVIRONMENT=\"../node_modules/react-native/scripts/xcode/with-environment.sh\"\nREACT_NATIVE_XCODE=\"../node_modules/react-native/scripts/react-native-xcode.sh\"\n\n/bin/sh -c \"$WITH_ENVIRONMENT $REACT_NATIVE_XCODE\"\n"; 271 | }; 272 | 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */ = { 273 | isa = PBXShellScriptBuildPhase; 274 | buildActionMask = 2147483647; 275 | files = ( 276 | ); 277 | inputFileListPaths = ( 278 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample-frameworks-${CONFIGURATION}-input-files.xcfilelist", 279 | ); 280 | name = "[CP] Embed Pods Frameworks"; 281 | outputFileListPaths = ( 282 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample-frameworks-${CONFIGURATION}-output-files.xcfilelist", 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | shellPath = /bin/sh; 286 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample-frameworks.sh\"\n"; 287 | showEnvVarsInLog = 0; 288 | }; 289 | A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */ = { 290 | isa = PBXShellScriptBuildPhase; 291 | buildActionMask = 2147483647; 292 | files = ( 293 | ); 294 | inputFileListPaths = ( 295 | ); 296 | inputPaths = ( 297 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 298 | "${PODS_ROOT}/Manifest.lock", 299 | ); 300 | name = "[CP] Check Pods Manifest.lock"; 301 | outputFileListPaths = ( 302 | ); 303 | outputPaths = ( 304 | "$(DERIVED_FILE_DIR)/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests-checkManifestLockResult.txt", 305 | ); 306 | runOnlyForDeploymentPostprocessing = 0; 307 | shellPath = /bin/sh; 308 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 309 | showEnvVarsInLog = 0; 310 | }; 311 | C38B50BA6285516D6DCD4F65 /* [CP] Check Pods Manifest.lock */ = { 312 | isa = PBXShellScriptBuildPhase; 313 | buildActionMask = 2147483647; 314 | files = ( 315 | ); 316 | inputFileListPaths = ( 317 | ); 318 | inputPaths = ( 319 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 320 | "${PODS_ROOT}/Manifest.lock", 321 | ); 322 | name = "[CP] Check Pods Manifest.lock"; 323 | outputFileListPaths = ( 324 | ); 325 | outputPaths = ( 326 | "$(DERIVED_FILE_DIR)/Pods-RNInAppPurchaseSample-checkManifestLockResult.txt", 327 | ); 328 | runOnlyForDeploymentPostprocessing = 0; 329 | shellPath = /bin/sh; 330 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 331 | showEnvVarsInLog = 0; 332 | }; 333 | C59DA0FBD6956966B86A3779 /* [CP] Embed Pods Frameworks */ = { 334 | isa = PBXShellScriptBuildPhase; 335 | buildActionMask = 2147483647; 336 | files = ( 337 | ); 338 | inputFileListPaths = ( 339 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests-frameworks-${CONFIGURATION}-input-files.xcfilelist", 340 | ); 341 | name = "[CP] Embed Pods Frameworks"; 342 | outputFileListPaths = ( 343 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests-frameworks-${CONFIGURATION}-output-files.xcfilelist", 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | shellPath = /bin/sh; 347 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests-frameworks.sh\"\n"; 348 | showEnvVarsInLog = 0; 349 | }; 350 | E235C05ADACE081382539298 /* [CP] Copy Pods Resources */ = { 351 | isa = PBXShellScriptBuildPhase; 352 | buildActionMask = 2147483647; 353 | files = ( 354 | ); 355 | inputFileListPaths = ( 356 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample-resources-${CONFIGURATION}-input-files.xcfilelist", 357 | ); 358 | name = "[CP] Copy Pods Resources"; 359 | outputFileListPaths = ( 360 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample-resources-${CONFIGURATION}-output-files.xcfilelist", 361 | ); 362 | runOnlyForDeploymentPostprocessing = 0; 363 | shellPath = /bin/sh; 364 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample/Pods-RNInAppPurchaseSample-resources.sh\"\n"; 365 | showEnvVarsInLog = 0; 366 | }; 367 | F6A41C54EA430FDDC6A6ED99 /* [CP] Copy Pods Resources */ = { 368 | isa = PBXShellScriptBuildPhase; 369 | buildActionMask = 2147483647; 370 | files = ( 371 | ); 372 | inputFileListPaths = ( 373 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests-resources-${CONFIGURATION}-input-files.xcfilelist", 374 | ); 375 | name = "[CP] Copy Pods Resources"; 376 | outputFileListPaths = ( 377 | "${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests-resources-${CONFIGURATION}-output-files.xcfilelist", 378 | ); 379 | runOnlyForDeploymentPostprocessing = 0; 380 | shellPath = /bin/sh; 381 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests/Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests-resources.sh\"\n"; 382 | showEnvVarsInLog = 0; 383 | }; 384 | /* End PBXShellScriptBuildPhase section */ 385 | 386 | /* Begin PBXSourcesBuildPhase section */ 387 | 00E356EA1AD99517003FC87E /* Sources */ = { 388 | isa = PBXSourcesBuildPhase; 389 | buildActionMask = 2147483647; 390 | files = ( 391 | 00E356F31AD99517003FC87E /* RNInAppPurchaseSampleTests.m in Sources */, 392 | ); 393 | runOnlyForDeploymentPostprocessing = 0; 394 | }; 395 | 13B07F871A680F5B00A75B9A /* Sources */ = { 396 | isa = PBXSourcesBuildPhase; 397 | buildActionMask = 2147483647; 398 | files = ( 399 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */, 400 | 13B07FC11A68108700A75B9A /* main.m in Sources */, 401 | ); 402 | runOnlyForDeploymentPostprocessing = 0; 403 | }; 404 | /* End PBXSourcesBuildPhase section */ 405 | 406 | /* Begin PBXTargetDependency section */ 407 | 00E356F51AD99517003FC87E /* PBXTargetDependency */ = { 408 | isa = PBXTargetDependency; 409 | target = 13B07F861A680F5B00A75B9A /* RNInAppPurchaseSample */; 410 | targetProxy = 00E356F41AD99517003FC87E /* PBXContainerItemProxy */; 411 | }; 412 | /* End PBXTargetDependency section */ 413 | 414 | /* Begin XCBuildConfiguration section */ 415 | 00E356F61AD99517003FC87E /* Debug */ = { 416 | isa = XCBuildConfiguration; 417 | baseConfigurationReference = 5B7EB9410499542E8C5724F5 /* Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.debug.xcconfig */; 418 | buildSettings = { 419 | BUNDLE_LOADER = "$(TEST_HOST)"; 420 | GCC_PREPROCESSOR_DEFINITIONS = ( 421 | "DEBUG=1", 422 | "$(inherited)", 423 | ); 424 | INFOPLIST_FILE = RNInAppPurchaseSampleTests/Info.plist; 425 | IPHONEOS_DEPLOYMENT_TARGET = 13.4; 426 | LD_RUNPATH_SEARCH_PATHS = ( 427 | "$(inherited)", 428 | "@executable_path/Frameworks", 429 | "@loader_path/Frameworks", 430 | ); 431 | OTHER_LDFLAGS = ( 432 | "-ObjC", 433 | "-lc++", 434 | "$(inherited)", 435 | ); 436 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 437 | PRODUCT_NAME = "$(TARGET_NAME)"; 438 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RNInAppPurchaseSample.app/RNInAppPurchaseSample"; 439 | }; 440 | name = Debug; 441 | }; 442 | 00E356F71AD99517003FC87E /* Release */ = { 443 | isa = XCBuildConfiguration; 444 | baseConfigurationReference = 89C6BE57DB24E9ADA2F236DE /* Pods-RNInAppPurchaseSample-RNInAppPurchaseSampleTests.release.xcconfig */; 445 | buildSettings = { 446 | BUNDLE_LOADER = "$(TEST_HOST)"; 447 | COPY_PHASE_STRIP = NO; 448 | INFOPLIST_FILE = RNInAppPurchaseSampleTests/Info.plist; 449 | IPHONEOS_DEPLOYMENT_TARGET = 13.4; 450 | LD_RUNPATH_SEARCH_PATHS = ( 451 | "$(inherited)", 452 | "@executable_path/Frameworks", 453 | "@loader_path/Frameworks", 454 | ); 455 | OTHER_LDFLAGS = ( 456 | "-ObjC", 457 | "-lc++", 458 | "$(inherited)", 459 | ); 460 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 461 | PRODUCT_NAME = "$(TARGET_NAME)"; 462 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/RNInAppPurchaseSample.app/RNInAppPurchaseSample"; 463 | }; 464 | name = Release; 465 | }; 466 | 13B07F941A680F5B00A75B9A /* Debug */ = { 467 | isa = XCBuildConfiguration; 468 | baseConfigurationReference = 3B4392A12AC88292D35C810B /* Pods-RNInAppPurchaseSample.debug.xcconfig */; 469 | buildSettings = { 470 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 471 | CLANG_ENABLE_MODULES = YES; 472 | CURRENT_PROJECT_VERSION = 1; 473 | ENABLE_BITCODE = NO; 474 | INFOPLIST_FILE = RNInAppPurchaseSample/Info.plist; 475 | LD_RUNPATH_SEARCH_PATHS = ( 476 | "$(inherited)", 477 | "@executable_path/Frameworks", 478 | ); 479 | MARKETING_VERSION = 1.0; 480 | OTHER_LDFLAGS = ( 481 | "$(inherited)", 482 | "-ObjC", 483 | "-lc++", 484 | ); 485 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 486 | PRODUCT_NAME = RNInAppPurchaseSample; 487 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 488 | SWIFT_VERSION = 5.0; 489 | VERSIONING_SYSTEM = "apple-generic"; 490 | }; 491 | name = Debug; 492 | }; 493 | 13B07F951A680F5B00A75B9A /* Release */ = { 494 | isa = XCBuildConfiguration; 495 | baseConfigurationReference = 5709B34CF0A7D63546082F79 /* Pods-RNInAppPurchaseSample.release.xcconfig */; 496 | buildSettings = { 497 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 498 | CLANG_ENABLE_MODULES = YES; 499 | CURRENT_PROJECT_VERSION = 1; 500 | INFOPLIST_FILE = RNInAppPurchaseSample/Info.plist; 501 | LD_RUNPATH_SEARCH_PATHS = ( 502 | "$(inherited)", 503 | "@executable_path/Frameworks", 504 | ); 505 | MARKETING_VERSION = 1.0; 506 | OTHER_LDFLAGS = ( 507 | "$(inherited)", 508 | "-ObjC", 509 | "-lc++", 510 | ); 511 | PRODUCT_BUNDLE_IDENTIFIER = "org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier)"; 512 | PRODUCT_NAME = RNInAppPurchaseSample; 513 | SWIFT_VERSION = 5.0; 514 | VERSIONING_SYSTEM = "apple-generic"; 515 | }; 516 | name = Release; 517 | }; 518 | 83CBBA201A601CBA00E9B192 /* Debug */ = { 519 | isa = XCBuildConfiguration; 520 | buildSettings = { 521 | ALWAYS_SEARCH_USER_PATHS = NO; 522 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 523 | CLANG_CXX_LANGUAGE_STANDARD = "c++20"; 524 | CLANG_CXX_LIBRARY = "libc++"; 525 | CLANG_ENABLE_MODULES = YES; 526 | CLANG_ENABLE_OBJC_ARC = YES; 527 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 528 | CLANG_WARN_BOOL_CONVERSION = YES; 529 | CLANG_WARN_COMMA = YES; 530 | CLANG_WARN_CONSTANT_CONVERSION = YES; 531 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 532 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 533 | CLANG_WARN_EMPTY_BODY = YES; 534 | CLANG_WARN_ENUM_CONVERSION = YES; 535 | CLANG_WARN_INFINITE_RECURSION = YES; 536 | CLANG_WARN_INT_CONVERSION = YES; 537 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 538 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 539 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 540 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 541 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 542 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 543 | CLANG_WARN_STRICT_PROTOTYPES = YES; 544 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 545 | CLANG_WARN_UNREACHABLE_CODE = YES; 546 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 547 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 548 | COPY_PHASE_STRIP = NO; 549 | ENABLE_STRICT_OBJC_MSGSEND = YES; 550 | ENABLE_TESTABILITY = YES; 551 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; 552 | GCC_C_LANGUAGE_STANDARD = gnu99; 553 | GCC_DYNAMIC_NO_PIC = NO; 554 | GCC_NO_COMMON_BLOCKS = YES; 555 | GCC_OPTIMIZATION_LEVEL = 0; 556 | GCC_PREPROCESSOR_DEFINITIONS = ( 557 | "DEBUG=1", 558 | "$(inherited)", 559 | ); 560 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 561 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 562 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 563 | GCC_WARN_UNDECLARED_SELECTOR = YES; 564 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 565 | GCC_WARN_UNUSED_FUNCTION = YES; 566 | GCC_WARN_UNUSED_VARIABLE = YES; 567 | IPHONEOS_DEPLOYMENT_TARGET = 13.4; 568 | LD_RUNPATH_SEARCH_PATHS = ( 569 | /usr/lib/swift, 570 | "$(inherited)", 571 | ); 572 | LIBRARY_SEARCH_PATHS = ( 573 | "\"$(SDKROOT)/usr/lib/swift\"", 574 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", 575 | "\"$(inherited)\"", 576 | ); 577 | MTL_ENABLE_DEBUG_INFO = YES; 578 | ONLY_ACTIVE_ARCH = YES; 579 | OTHER_CFLAGS = ( 580 | "$(inherited)", 581 | " ", 582 | ); 583 | OTHER_CPLUSPLUSFLAGS = ( 584 | "$(OTHER_CFLAGS)", 585 | "-DFOLLY_NO_CONFIG", 586 | "-DFOLLY_MOBILE=1", 587 | "-DFOLLY_USE_LIBCPP=1", 588 | "-DFOLLY_CFG_NO_COROUTINES=1", 589 | " ", 590 | ); 591 | OTHER_LDFLAGS = ( 592 | "$(inherited)", 593 | " ", 594 | ); 595 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; 596 | SDKROOT = iphoneos; 597 | USE_HERMES = true; 598 | }; 599 | name = Debug; 600 | }; 601 | 83CBBA211A601CBA00E9B192 /* Release */ = { 602 | isa = XCBuildConfiguration; 603 | buildSettings = { 604 | ALWAYS_SEARCH_USER_PATHS = NO; 605 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 606 | CLANG_CXX_LANGUAGE_STANDARD = "c++20"; 607 | CLANG_CXX_LIBRARY = "libc++"; 608 | CLANG_ENABLE_MODULES = YES; 609 | CLANG_ENABLE_OBJC_ARC = YES; 610 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 611 | CLANG_WARN_BOOL_CONVERSION = YES; 612 | CLANG_WARN_COMMA = YES; 613 | CLANG_WARN_CONSTANT_CONVERSION = YES; 614 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 615 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 616 | CLANG_WARN_EMPTY_BODY = YES; 617 | CLANG_WARN_ENUM_CONVERSION = YES; 618 | CLANG_WARN_INFINITE_RECURSION = YES; 619 | CLANG_WARN_INT_CONVERSION = YES; 620 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 621 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 622 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 623 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 624 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 625 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 626 | CLANG_WARN_STRICT_PROTOTYPES = YES; 627 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 628 | CLANG_WARN_UNREACHABLE_CODE = YES; 629 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 630 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 631 | COPY_PHASE_STRIP = YES; 632 | ENABLE_NS_ASSERTIONS = NO; 633 | ENABLE_STRICT_OBJC_MSGSEND = YES; 634 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; 635 | GCC_C_LANGUAGE_STANDARD = gnu99; 636 | GCC_NO_COMMON_BLOCKS = YES; 637 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 638 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 639 | GCC_WARN_UNDECLARED_SELECTOR = YES; 640 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 641 | GCC_WARN_UNUSED_FUNCTION = YES; 642 | GCC_WARN_UNUSED_VARIABLE = YES; 643 | IPHONEOS_DEPLOYMENT_TARGET = 13.4; 644 | LD_RUNPATH_SEARCH_PATHS = ( 645 | /usr/lib/swift, 646 | "$(inherited)", 647 | ); 648 | LIBRARY_SEARCH_PATHS = ( 649 | "\"$(SDKROOT)/usr/lib/swift\"", 650 | "\"$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)\"", 651 | "\"$(inherited)\"", 652 | ); 653 | MTL_ENABLE_DEBUG_INFO = NO; 654 | OTHER_CFLAGS = ( 655 | "$(inherited)", 656 | " ", 657 | ); 658 | OTHER_CPLUSPLUSFLAGS = ( 659 | "$(OTHER_CFLAGS)", 660 | "-DFOLLY_NO_CONFIG", 661 | "-DFOLLY_MOBILE=1", 662 | "-DFOLLY_USE_LIBCPP=1", 663 | "-DFOLLY_CFG_NO_COROUTINES=1", 664 | " ", 665 | ); 666 | OTHER_LDFLAGS = ( 667 | "$(inherited)", 668 | " ", 669 | ); 670 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; 671 | SDKROOT = iphoneos; 672 | USE_HERMES = true; 673 | VALIDATE_PRODUCT = YES; 674 | }; 675 | name = Release; 676 | }; 677 | /* End XCBuildConfiguration section */ 678 | 679 | /* Begin XCConfigurationList section */ 680 | 00E357021AD99517003FC87E /* Build configuration list for PBXNativeTarget "RNInAppPurchaseSampleTests" */ = { 681 | isa = XCConfigurationList; 682 | buildConfigurations = ( 683 | 00E356F61AD99517003FC87E /* Debug */, 684 | 00E356F71AD99517003FC87E /* Release */, 685 | ); 686 | defaultConfigurationIsVisible = 0; 687 | defaultConfigurationName = Release; 688 | }; 689 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "RNInAppPurchaseSample" */ = { 690 | isa = XCConfigurationList; 691 | buildConfigurations = ( 692 | 13B07F941A680F5B00A75B9A /* Debug */, 693 | 13B07F951A680F5B00A75B9A /* Release */, 694 | ); 695 | defaultConfigurationIsVisible = 0; 696 | defaultConfigurationName = Release; 697 | }; 698 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "RNInAppPurchaseSample" */ = { 699 | isa = XCConfigurationList; 700 | buildConfigurations = ( 701 | 83CBBA201A601CBA00E9B192 /* Debug */, 702 | 83CBBA211A601CBA00E9B192 /* Release */, 703 | ); 704 | defaultConfigurationIsVisible = 0; 705 | defaultConfigurationName = Release; 706 | }; 707 | /* End XCConfigurationList section */ 708 | }; 709 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; 710 | } 711 | -------------------------------------------------------------------------------- /sample/ios/RNInAppPurchaseSample.xcodeproj/xcshareddata/xcschemes/RNInAppPurchaseSample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /sample/ios/RNInAppPurchaseSample.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /sample/ios/RNInAppPurchaseSample.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /sample/ios/RNInAppPurchaseSample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : RCTAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /sample/ios/RNInAppPurchaseSample/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | 5 | @implementation AppDelegate 6 | 7 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 8 | { 9 | self.moduleName = @"RNInAppPurchaseSample"; 10 | // You can add your custom initial props in the dictionary below. 11 | // They will be passed down to the ViewController used by React Native. 12 | self.initialProps = @{}; 13 | 14 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 15 | } 16 | 17 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 18 | { 19 | return [self getBundleURL]; 20 | } 21 | 22 | - (NSURL *)getBundleURL 23 | { 24 | #if DEBUG 25 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index"]; 26 | #else 27 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 28 | #endif 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /sample/ios/RNInAppPurchaseSample/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "scale" : "1x", 46 | "size" : "1024x1024" 47 | } 48 | ], 49 | "info" : { 50 | "author" : "xcode", 51 | "version" : 1 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /sample/ios/RNInAppPurchaseSample/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /sample/ios/RNInAppPurchaseSample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | RNInAppPurchaseSample 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(MARKETING_VERSION) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(CURRENT_PROJECT_VERSION) 25 | LSRequiresIPhoneOS 26 | 27 | NSAppTransportSecurity 28 | 29 | 30 | NSAllowsArbitraryLoads 31 | 32 | NSAllowsLocalNetworking 33 | 34 | 35 | NSLocationWhenInUseUsageDescription 36 | 37 | UILaunchStoryboardName 38 | LaunchScreen 39 | UIRequiredDeviceCapabilities 40 | 41 | armv7 42 | 43 | UISupportedInterfaceOrientations 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationLandscapeLeft 47 | UIInterfaceOrientationLandscapeRight 48 | 49 | UIViewControllerBasedStatusBarAppearance 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /sample/ios/RNInAppPurchaseSample/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 24 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /sample/ios/RNInAppPurchaseSample/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyAccessedAPITypes 6 | 7 | 8 | NSPrivacyAccessedAPIType 9 | NSPrivacyAccessedAPICategoryFileTimestamp 10 | NSPrivacyAccessedAPITypeReasons 11 | 12 | C617.1 13 | 14 | 15 | 16 | NSPrivacyAccessedAPIType 17 | NSPrivacyAccessedAPICategoryUserDefaults 18 | NSPrivacyAccessedAPITypeReasons 19 | 20 | CA92.1 21 | 22 | 23 | 24 | NSPrivacyAccessedAPIType 25 | NSPrivacyAccessedAPICategorySystemBootTime 26 | NSPrivacyAccessedAPITypeReasons 27 | 28 | 35F9.1 29 | 30 | 31 | 32 | NSPrivacyCollectedDataTypes 33 | 34 | NSPrivacyTracking 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /sample/ios/RNInAppPurchaseSample/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | @autoreleasepool { 8 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /sample/ios/RNInAppPurchaseSampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /sample/ios/RNInAppPurchaseSampleTests/RNInAppPurchaseSampleTests.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | #import 5 | #import 6 | 7 | #define TIMEOUT_SECONDS 600 8 | #define TEXT_TO_LOOK_FOR @"Welcome to React" 9 | 10 | @interface RNInAppPurchaseSampleTests : XCTestCase 11 | 12 | @end 13 | 14 | @implementation RNInAppPurchaseSampleTests 15 | 16 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL (^)(UIView *view))test 17 | { 18 | if (test(view)) { 19 | return YES; 20 | } 21 | for (UIView *subview in [view subviews]) { 22 | if ([self findSubviewInView:subview matching:test]) { 23 | return YES; 24 | } 25 | } 26 | return NO; 27 | } 28 | 29 | - (void)testRendersWelcomeScreen 30 | { 31 | UIViewController *vc = [[[RCTSharedApplication() delegate] window] rootViewController]; 32 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 33 | BOOL foundElement = NO; 34 | 35 | __block NSString *redboxError = nil; 36 | #ifdef DEBUG 37 | RCTSetLogFunction( 38 | ^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 39 | if (level >= RCTLogLevelError) { 40 | redboxError = message; 41 | } 42 | }); 43 | #endif 44 | 45 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 46 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 47 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 48 | 49 | foundElement = [self findSubviewInView:vc.view 50 | matching:^BOOL(UIView *view) { 51 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 52 | return YES; 53 | } 54 | return NO; 55 | }]; 56 | } 57 | 58 | #ifdef DEBUG 59 | RCTSetLogFunction(RCTDefaultLogFunction); 60 | #endif 61 | 62 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 63 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 64 | } 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /sample/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | preset: 'react-native', 3 | }; 4 | -------------------------------------------------------------------------------- /sample/metro.config.js: -------------------------------------------------------------------------------- 1 | const {getDefaultConfig, mergeConfig} = require('@react-native/metro-config'); 2 | 3 | /** 4 | * Metro configuration 5 | * https://facebook.github.io/metro/docs/configuration 6 | * 7 | * @type {import('metro-config').MetroConfig} 8 | */ 9 | const config = {}; 10 | 11 | module.exports = mergeConfig(getDefaultConfig(__dirname), config); 12 | -------------------------------------------------------------------------------- /sample/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "RNInAppPurchaseSample", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "android": "react-native run-android", 7 | "ios": "react-native run-ios", 8 | "lint": "eslint .", 9 | "start": "react-native start", 10 | "test": "jest" 11 | }, 12 | "dependencies": { 13 | "@class101/react-native-in-app-purchase": "link:../", 14 | "react": "18.2.0", 15 | "react-native": "0.73.9" 16 | }, 17 | "devDependencies": { 18 | "@babel/core": "^7.20.0", 19 | "@babel/preset-env": "^7.20.0", 20 | "@babel/runtime": "^7.20.0", 21 | "@react-native/babel-preset": "0.73.21", 22 | "@react-native/eslint-config": "0.73.2", 23 | "@react-native/metro-config": "0.73.5", 24 | "@react-native/typescript-config": "0.73.1", 25 | "@types/react": "^18.2.6", 26 | "@types/react-test-renderer": "^18.0.0", 27 | "babel-jest": "^29.6.3", 28 | "eslint": "^8.19.0", 29 | "jest": "^29.6.3", 30 | "prettier": "2.8.8", 31 | "react-test-renderer": "18.2.0", 32 | "typescript": "5.0.4" 33 | }, 34 | "engines": { 35 | "node": ">=18" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /sample/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@react-native/typescript-config/tsconfig.json" 3 | } 4 | -------------------------------------------------------------------------------- /src/NativeInAppPurchaseModule.ts: -------------------------------------------------------------------------------- 1 | import { TurboModule, TurboModuleRegistry } from "react-native"; 2 | import type { 3 | Int32, 4 | } from 'react-native/Libraries/Types/CodegenTypes'; 5 | 6 | type FetchProductInput = { 7 | id: string; 8 | 9 | // Android only 10 | type?: 'inapp' | 'subs'; 11 | planId?: string; 12 | offerId?: string; 13 | } 14 | 15 | type Product = { 16 | productId: string; 17 | type: string; 18 | planId?: string; 19 | offerId?: string; 20 | title: string; 21 | description: string; 22 | price: string; 23 | currency: string; 24 | } 25 | 26 | type Purchase = { 27 | productIds: string[]; 28 | transactionId: string; 29 | transactionDate: string; 30 | receipt: string; 31 | purchaseToken: string; 32 | } 33 | 34 | type PurchaseArgs = { 35 | // Android 36 | planId?: string, 37 | offerId?: string, 38 | originalPurchaseToken?: string, 39 | obfuscatedAccountId?: string, 40 | obfuscatedProfileId?: string, 41 | 42 | // iOS 43 | userId?: string, 44 | keyIdentifier?: string, 45 | nonce?: string, 46 | signature?: string, 47 | timestamp?: Int32, 48 | } 49 | 50 | export interface Spec extends TurboModule { 51 | readonly getConstants: () => {}; 52 | configure:(config?: { 53 | isAlternativeBillingEnable?: boolean, 54 | }) => Promise; 55 | fetchProducts: (products: FetchProductInput[]) => void; 56 | flush: () => Promise; 57 | purchase: (productId: string, extras?: PurchaseArgs) => void; 58 | finalize: (purchase: Purchase, isConsumable: boolean) => Promise; 59 | fetchReceipt: () => Promise; 60 | onFetchProducts: (listener: (products: Product[]) => void) => void; 61 | onPurchase: (listener: (purchase: { 62 | productIds: string[], 63 | transactionId: string, 64 | transactionDate: string, 65 | receipt: string, 66 | purchaseToken: string, 67 | }) => void) => void, 68 | onAlternativeBillingFlow: (listener: (token: string) => void) => void; 69 | onError: (listener: (exception: { 70 | type: string, 71 | // Android only 72 | code?: Int32, 73 | message: string }) => void) => void; 74 | clear: () => void; 75 | } 76 | 77 | export default TurboModuleRegistry.get("NativeInAppPurchase") as Spec; 78 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | export { default } from './NativeInAppPurchaseModule'; --------------------------------------------------------------------------------