From 8c3cfc45f7452dec512d43dbd5d687c38747cf96 Mon Sep 17 00:00:00 2001 From: Amit Date: Tue, 29 Sep 2020 11:12:53 +0300 Subject: [PATCH 1/9] added In-app Purchase validation --- .gitignore | 3 + Docs/API.md | 29 +- SampleApp/App.js | 524 +++++++++--------- SampleApp/android/build.gradle | 1 + android/build.gradle | 18 +- .../reactnative/RNAppsFlyerConstants.java | 15 +- .../reactnative/RNAppsFlyerModule.java | 122 ++-- .../com/appsflyer/reactnative/RNUtil.java | 12 + index.d.ts | 48 +- index.js | 227 ++++---- ios/RNAppsFlyer.h | 14 +- ios/RNAppsFlyer.m | 192 ++++--- 12 files changed, 709 insertions(+), 496 deletions(-) diff --git a/.gitignore b/.gitignore index dbb0f6e0..fb6f0995 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,9 @@ ios/Podfile.lock .idea .gradle local.properties +android/gradlew +android/gradlew.bat +android/gradle # node.js # diff --git a/Docs/API.md b/Docs/API.md index 3ea3b7ef..12f5f093 100755 --- a/Docs/API.md +++ b/Docs/API.md @@ -27,6 +27,7 @@ - [setSharingFilter](#setSharingFilter) - [disableCollectASA](#disableCollectASA) - [disableAdvertisingIdentifier](#disableAdvertisingIdentifier) +- [validateAndLogInAppPurchase](#validateAndLogInAppPurchase) --- @@ -737,4 +738,30 @@ Disables IDFA collecting appsFlyer.disableAdvertisingIdentifier(true); ``` ---- \ No newline at end of file +--- + +##### **`validateAndLogInAppPurchase(purchaseInfo: InAppPurchase, successC, errorC): Response`** +Receipt validation is a secure mechanism whereby the payment platform (e.g. Apple or Google) validates that an in-app purchase indeed occurred as reported.
+Learn more - https://support.appsflyer.com/hc/en-us/articles/207032106-Receipt-validation-for-in-app-purchases + +| parameter | type | description | +| ---------- |----------|------------------ | +| purchaseInfo | json | In-App Purchase parameters | +| successC | function | success callback (generated link)| +| errorC | function | error callback | + + +*Example:* + +```javascript + const info = { + publicKey: 'biz', + currency: 'buz', + signature: 'sasa', + purchaseData: 'ffff', + price: '123', + additionalParameters: {'foo': 'bar'}, + }; + + appsFlyer.validateAndLogInAppPurchase(info, res => console.log(res), err => console.log(err.message)); +``` diff --git a/SampleApp/App.js b/SampleApp/App.js index 7aa7f3fd..ca5d5dca 100644 --- a/SampleApp/App.js +++ b/SampleApp/App.js @@ -10,289 +10,317 @@ import React, {Node} from 'react'; import appsFlyer from 'react-native-appsflyer'; import { - Button, - ImageBackground, - SafeAreaView, - ScrollView, - StatusBar, - StyleSheet, - Text, - View, + Button, + ImageBackground, + SafeAreaView, + ScrollView, + StatusBar, + StyleSheet, + Text, + View, } from 'react-native'; import { - Colors, - DebugInstructions, - LearnMoreLinks, - ReloadInstructions, + Colors, + DebugInstructions, + LearnMoreLinks, + ReloadInstructions, } from 'react-native/Libraries/NewAppScreen'; // eslint-disable-next-line no-unused-vars var onInstallConversionDataCanceller = appsFlyer.onInstallConversionData( - (res) => { - console.log('onInstallConversionData: ' + JSON.stringify(res)); - if (res.type === 'onInstallConversionSuccess') { - if (JSON.parse(res.data.is_first_launch) === true) { - if (res.data.af_status === 'Non-organic') { - var media_source = res.data.media_source; - var campaign = res.data.campaign; - console.log( - 'This is first launch and a Non-Organic install. Media source: ' + - media_source + - ' Campaign: ' + - campaign, - ); - } else if (res.data.af_status === 'Organic') { - console.log('This is first launch and a Organic Install'); + (res) => { + console.log('onInstallConversionData: ' + JSON.stringify(res)); + if (res.type === 'onInstallConversionSuccess') { + if (JSON.parse(res.data.is_first_launch) === true) { + if (res.data.af_status === 'Non-organic') { + var media_source = res.data.media_source; + var campaign = res.data.campaign; + console.log( + 'This is first launch and a Non-Organic install. Media source: ' + + media_source + + ' Campaign: ' + + campaign, + ); + } else if (res.data.af_status === 'Organic') { + console.log('This is first launch and a Organic Install'); + } + } else { + console.log('This is not first launch'); + } } - } else { - console.log('This is not first launch'); - } - } - }, + }, ); // eslint-disable-next-line no-unused-vars var onAppOpenAttributionCanceller = appsFlyer.onAppOpenAttribution((res) => { - console.log(res); + console.log(res); }); + appsFlyer.setCustomerUserId("testID"); appsFlyer.initSdk( - { - isDebug: true, - devKey: '4UGrDF4vFvPLbHq5bXtCza', - appId: '753258300', - timeToWaitForATTUserAuthorization: 60, - }, - (result) => { - console.log('initSdk: ' + result); - if (Platform.OS === 'android') { - appsFlyer.setCollectAndroidID(true) - } - }, - (error) => { - console.error('initSdk: ' + error); - }, + { + isDebug: true, + devKey: 'Us4Gm2SnJghcuoev846Qed', + appId: '789456231', + onInstallConversionDataListener: true, + timeToWaitForATTUserAuthorization: 60, + }, + (result) => { + console.log('initSdk: ' + result); + if (Platform.OS === 'android') { + appsFlyer.setCollectAndroidID(true) + } + }, + (error) => { + console.error('initSdk: ' + error); + }, ); const App: () => React$Node = () => { - const LogEventPressed = () => { - const eventName = 'af_test_event'; - const eventValues = { - af_event_param0: 'biz', - af_event_param1: 'buz', - af_event_param2: 'bizbuz', + const logEvent = () => { + const eventName = 'af_test_event'; + const eventValues = {'price': '123', 'amount': '5'}; + appsFlyer.logEvent( + eventName, + eventValues, + (result) => { + console.log('logEvent: ' + result); + }, + (error) => { + console.error('logEvent: ' + error); + }, + ); + }; + + + const logInAppPurchase = () => { + const info = { + publicKey: 'biz', + currency: 'buz', + signature: 'sasa', + purchaseData: 'ffff', + price: '123', + additionalParameters: {'foo': 'bar'}, + }; + + appsFlyer.validateAndLogInAppPurchase(info, res => console.log(res), err => console.log(err.message)); + }; + + const init = () => { + appsFlyer.initSdk(option, result => console.log(result), error => console.log(error)); }; - appsFlyer.logEvent( - eventName, - eventValues, - (result) => { - console.log('logEvent: ' + result); - }, - (error) => { - console.error('logEvent: ' + error); - }, - ); - }; - const LogLocationPressed = () => { - appsFlyer.logLocation(32.0853, 34.781769, (result) => { - console.log('logLocation: ' + result); - }); - }; + const LogLocationPressed = () => { + appsFlyer.logLocation(32.0853, 34.781769, (result) => { + console.log('logLocation: ' + result); + }); + }; - const StopPressed = () => { - appsFlyer.stop(true, (res) => { - console.log('stop: ' + res); - }), - (err) => { - console.log('stop: ' + err); - }; - }; + const StopPressed = () => { + appsFlyer.stop(true, (res) => { + console.log('stop: ' + res); + }), + (err) => { + console.log('stop: ' + err); + }; + }; - const LogCrossPromotion = () => { - appsFlyer.logCrossPromotionImpression('1192323960', 'test', { - custom_param: 'custom_value', - }); - }; + const LogCrossPromotion = () => { + appsFlyer.logCrossPromotionImpression('1192323960', 'test', { + custom_param: 'custom_value', + }); + }; - const logCrossPromotionAndOpenStore = () => { - appsFlyer.logCrossPromotionAndOpenStore('1192323960', 'test', { - custom_param: 'custom_value', - }); - }; + const logCrossPromotionAndOpenStore = () => { + appsFlyer.logCrossPromotionAndOpenStore('1192323960', 'test', { + custom_param: 'custom_value', + }); + }; - const anonymizeUser = () => { - appsFlyer.anonymizeUser(true, (res) => { - console.log('anonymizeUser: ' + res); - }); - }; + const anonymizeUser = () => { + appsFlyer.anonymizeUser(true, (res) => { + console.log('anonymizeUser: ' + res); + }); + }; - const Header = (): Node => ( - - - Welcome to the React Native AppsFlyer Test App! - - - ); + const Header = (): Node => ( + + + Welcome to the React Native AppsFlyer Test App! + + + ); - return ( - <> - - - -
- - Press to log event! -