Skip to content

Commit

Permalink
Handling opting in/out the PC module, Reverting demo app to default s…
Browse files Browse the repository at this point in the history
…ettings and adding documentation
  • Loading branch information
al-af committed Oct 20, 2024
1 parent e611717 commit e9976b3
Show file tree
Hide file tree
Showing 30 changed files with 150,737 additions and 149 deletions.
373 changes: 373 additions & 0 deletions Docs/RN_PurchaseConnector.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ If you have used 1 of the removed APIs, please check the integration guide for t
- [In-app events](/Docs/RN_InAppEvents.md)
- [Uninstall measurement](/Docs/RN_UninstallMeasurement.md)
- [Send consent for DMA compliance](/Docs/RN_CMP.md)
- [Purchase Connector](/Docs/RN_PurchaseConnector.md)
## 🔗 Deep Linking
- [Integration](/Docs/RN_DeepLinkIntegrate.md)
- [***Expo*** Integration](/Docs/RN_ExpoDeepLinkIntegration.md)
Expand Down
9 changes: 9 additions & 0 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,15 @@ android {

buildConfigField 'boolean', 'INCLUDE_CONNECTOR', includeConnector.toString()
}

sourceSets {
main {
java.srcDirs = ['src/main/java']
java.srcDirs += includeConnector ? ['src/main/includeConnector'] : ['src/main/excludeConnector']
}
includeConnector ? ['src/main/includeConnector'] : ['src/main/excludeConnector']
}

lintOptions {
warning 'InvalidPackage'
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.appsflyer.reactnative;

import android.app.Application;
import android.content.Context;
import android.util.Log;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class PCAppsFlyerModule extends ReactContextBaseJavaModule {

private ReactApplicationContext reactContext;
private Application application;

public PCAppsFlyerModule(ReactApplicationContext reactContext) {
super(reactContext);
this.reactContext = reactContext;
this.application = (Application) reactContext.getApplicationContext();
Log.d("AppsFlyer", "PurchaseConnector inclusion status: " + BuildConfig.INCLUDE_CONNECTOR);
}

@Override
public String getName() {
return "PCAppsFlyer";
}

@ReactMethod
public void addListener(String eventName) {
// Keep: Required for RN built in Event Emitter Calls.
}

@ReactMethod
public void removeListeners(Integer count) {
// Keep: Required for RN built in Event Emitter Calls.
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,9 @@
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.Arrays;
Expand Down Expand Up @@ -51,6 +49,7 @@ public PCAppsFlyerModule(ReactApplicationContext reactContext) {
this.reactContext = reactContext;
this.application = (Application) reactContext.getApplicationContext();
this.isModuleEnabled = BuildConfig.INCLUDE_CONNECTOR;
Log.d("AppsFlyer_", "PurchaseConnector inclusion status: " + this.isModuleEnabled);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.appsflyer.reactnative;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class PCAppsFlyerPackage implements ReactPackage {

public PCAppsFlyerPackage() {
}


public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}

@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Arrays.<NativeModule>asList(new PCAppsFlyerModule(reactContext));
}

@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
103 changes: 51 additions & 52 deletions demos/appsflyer-react-native-app/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import {
} from 'react-native-iap';
import {AppsFlyerPurchaseConnector} from 'react-native-appsflyer';


const Stack = createStackNavigator();

try {
Expand All @@ -44,40 +43,38 @@ LogBox.ignoreLogs([
]);

// Test items (hardcoded)
/*
const items = Platform.select({
ios: [
'one1',
'non.cons2',
'auto.renew',
'non.renew',
'cons.test',
'nonconsumable.purchase1',
'autorenewable.purchase1',
'nonrenewing.purchase1',
],
ios: ['com.appsflyer.inapppurchase.non.cons', 'com.appsflyer.inapppurchase.cons', 'com.appsflyer.inapppurchase.two'],
android: ['noa_coin1', 'paz_test', 'btc'],
});
const subscriptions = ['cheap', 'intro'];

const subscriptions = Platform.select({
ios: ['com.appsflyer.inapppurchase.non.renew', 'com.appsflyer.inapppurchase.auto.renew'],
android: ['cheap', 'intro'],
});
*/
class App extends Component {
/*
purchaseUpdateSubscription = null;
purchaseErrorSubscription = null;
componentDidMount() {
this.setupIAP();
}

setupIAP = async () => {
try {
await initConnection();
await initConnection().then(() => {});
if (Platform.OS == 'android') {
await flushFailedPurchasesCachedAsPendingAndroid().catch(() => {
console.warn(
"there are pending purchases that are still pending (we can't consume a pending purchase)",
);
});
}
console.log('[RNPurchaseConnector] Items: >>', items);
console.log('[RNPurchaseConnector] Subscriptions: >>', subscriptions);
await getProducts({skus: items})
.then(res => {
Expand All @@ -90,42 +87,42 @@ class App extends Component {
.then(res => {
console.log('[Subscriptions] >> ', res);
})
.catch((err) => {
console.log('[Error finding Subscriptions] >> ', err);
});
this.purchaseUpdateSubscription = purchaseUpdatedListener(
async purchase => {
try {
console.log('purchaseUpdatedListener', purchase);
const receipt = purchase.transactionReceipt;
if (receipt) {
// Check if the purchased product is a subscription or a consumable item
const isSubscription = subscriptions.includes(purchase.productId);
const isConsumable = items.includes(purchase.productId);
console.log('[Receipt] >> ', receipt);
if (isSubscription || isConsumable) {
await finishTransaction({
purchase: purchase,
isConsumable: isConsumable, // true for consumables, false for subscriptions
}).catch(error => {
console.warn('Error finishing transaction:', error);
});
} else {
// Handle the case where the purchase is non-consumable and not a subscription.
await finishTransaction({
purchase: purchase,
isConsumable: false,
}).catch(error => {
console.warn('Error finishing transaction:', error);
});
}
}
} catch (error) {
console.warn('Error in purchaseUpdatedListener', error);
}
},
);
.catch(err => {
console.log('[Error finding Subscriptions] >> ', err);
});
this.purchaseUpdateSubscription = purchaseUpdatedListener(
async purchase => {
try {
console.log('purchaseUpdatedListener', purchase);
const receipt = purchase.transactionReceipt;
if (receipt) {
// Check if the purchased product is a subscription or a consumable item
const isSubscription = subscriptions.includes(purchase.productId);
const isConsumable = items.includes(purchase.productId);
console.log('[Receipt] >> ', receipt);
if (isSubscription || isConsumable) {
await finishTransaction({
purchase: purchase,
isConsumable: isConsumable, // true for consumables, false for subscriptions
}).catch(error => {
console.warn('Error finishing transaction:', error);
});
} else {
// Handle the case where the purchase is non-consumable and not a subscription.
await finishTransaction({
purchase: purchase,
isConsumable: false,
}).catch(error => {
console.warn('Error finishing transaction:', error);
});
}
}
} catch (error) {
console.warn('Error in purchaseUpdatedListener', error);
}
},
);
this.purchaseErrorSubscription = purchaseErrorListener(error => {
console.warn('purchaseErrorListener', error);
Expand All @@ -148,6 +145,7 @@ class App extends Component {
endConnection();
}
*/

render() {
return (
Expand All @@ -170,7 +168,8 @@ class App extends Component {
title: 'The AppsFlyer Shop!',
}}
/>
<Stack.Screen name="Cart" component={withIAPContext(Cart)} />
{/* <Stack.Screen name="Cart" component={withIAPContext(Cart)} /> */}
<Stack.Screen name="Cart" component={Cart} />
<Stack.Screen
name="Item"
component={Item}
Expand Down
4 changes: 2 additions & 2 deletions demos/appsflyer-react-native-app/android/app/_BUCK
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ android_library(

android_build_config(
name = "build_config",
package = "com.appsflyer.billing2",
package = "com.appsflyerexample",
)

android_resource(
name = "res",
package = "com.appsflyer.billing2",
package = "com.appsflyerexample",
res = "src/main/res",
)

Expand Down
3 changes: 1 addition & 2 deletions demos/appsflyer-react-native-app/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@ android {
compileSdkVersion rootProject.ext.compileSdkVersion

defaultConfig {
applicationId "com.appsflyer.billing2"
//applicationId "com.appsflyerexample"
applicationId "com.appsflyerexample"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* <p>This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
*/
package com.appsflyer.billing2;
package com.appsflyerexample;

import android.content.Context;
import com.facebook.flipper.android.AndroidFlipperClient;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.appsflyer.billing2">
package="com.appsflyerexample">

<uses-permission android:name="android.permission.INTERNET" />

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.appsflyer.billing2;
package com.appsflyerexample;

import com.facebook.react.ReactActivity;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.appsflyer.billing2;
package com.appsflyerexample;

import android.app.Application;
import android.content.Context;

import com.appsflyer.reactnative.PCAppsFlyerPackage;
import com.appsflyer.reactnative.RNAppsFlyerPackage;
import com.appsflyer.reactnative.PCAppsFlyerPackage;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
Expand Down Expand Up @@ -80,7 +80,7 @@ private static void initializeFlipper(
We use reflection here to pick up the class that initializes Flipper,
since Flipper library is not available in release mode
*/
Class<?> aClass = Class.forName("com.appsflyer.billing2.ReactNativeFlipper");
Class<?> aClass = Class.forName("com.appsflyerexample.ReactNativeFlipper");
aClass
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
.invoke(null, context, reactInstanceManager);
Expand Down
2 changes: 1 addition & 1 deletion demos/appsflyer-react-native-app/android/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ android.enableJetifier=true
# Version of flipper SDK to use with React Native
FLIPPER_VERSION=0.93.0
# Uncomment to enable purchase connector
appsflyer.enable_purchase_connector=true
# appsflyer.enable_purchase_connector=true
5 changes: 3 additions & 2 deletions demos/appsflyer-react-native-app/components/AppsFlyer.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ export const AF_clickOnItem = 'af_click_on_item';

const initOptions = {
isDebug: true,
devKey: '6jJTVBNyc832U5D57Jvzmg',
devKey: 'Us4GmXxXx46Qed',
onInstallConversionDataListener: true,
timeToWaitForATTUserAuthorization: 10,
onDeepLinkListener: true,
appId: '1201211633',
appId: '741993747',
};

// AppsFlyer initialization flow. ends with initSdk.
Expand All @@ -36,6 +36,7 @@ export function AFInit() {
});
}

// AppsFlyer Purchase Connector initialization flow
export function PCInit() {
const purchaseConnectorConfig: PurchaseConnectorConfig = AppsFlyerPurchaseConnectorConfig.setConfig({
logSubscriptions: true,
Expand Down
Loading

0 comments on commit e9976b3

Please sign in to comment.