https://github.com/appsflyersdk/appsflyer-android-purchase-connector
https://github.com/appsflyersdk/appsflyer-android-purchase-connector
Last synced: about 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/appsflyersdk/appsflyer-android-purchase-connector
- Owner: AppsFlyerSDK
- License: mit
- Created: 2022-05-12T09:35:08.000Z (about 3 years ago)
- Default Branch: main
- Last Pushed: 2025-02-23T11:27:34.000Z (3 months ago)
- Last Synced: 2025-02-23T12:23:18.144Z (3 months ago)
- Size: 59.6 KB
- Stars: 0
- Watchers: 5
- Forks: 0
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
![]()
# Android Purchase Connector
[](https://github.com/AppsFlyerSDK/android-purchase-connector/blob/main/LICENSE)
[](https://repo1.maven.org/maven2/com/appsflyer/purchase-connector/)🛠 In order for us to provide optimal support, we would kindly ask you to submit any issues to
[email protected]> *When submitting an issue please specify your AppsFlyer sign-up (account) email , your app ID , production steps, logs, code snippets and any additional relevant information.*
## Table Of Content
* [This Module is Built for](#plugin-build-for)
* [Important Note](#important-note)
* [Adding The Connector To Your Project](#install-connector)
* [Basic Integration Of The Connector](#basic-integration)
+ [Create PurchaseClient Instance ](#create-instance)
+ [Start Observing Transactions](#start)
+ [Stop Observing Transactions](#stop)
+ [Log Subscriptions](#log-subscriptions)
+ [Log In App](#log-inapps)
* [Register Purchase Event Data Source](#data-source)
+ [Subscription Purchase Event Data Source](#ars-data-source)
+ [In Apps Purchase Event Data Source](#inapps-data-source)
* [Register Validation Results Listeners](#validation-callbacks)
+ [Subscription Validation Result Listener](#ars-validation-callbacks)
+ [In Apps Validation Result Listener](#inapps-validation-callbacks)
* [ Testing The Integration](#testing)
* [Full Code Example](#example)- Android AppsFlyer SDK **6.15.0** and above
Some Purchase Connector versions require a specific version of the AppsFlyer SDK to operate properly.
The following table details the compatibility between the Purchase Connector versions and the SDK versions.| Purchase Connector Version | Supported AppsFlyer SDK Versions | Supported Billing Library Versions
|----------------------------|------------------------------------|----------------------------------|
| v2.0.0 | v6.12.2 - v6.14.3 | v5.x.x |
| v2.0.1 | v6.12.2 - v6.14.3 | v5.x.x - v6.x.x |
| v2.1.0 | v6.15.0 (and above) |v5.x.x - v6.x.x |## Adding The Connector To Your Project
1. Add to your build.gradle file:
```
implementation 'com.appsflyer:purchase-connector:2.1.1'
implementation 'com.android.billingclient:billing:$play_billing_version'
```where `play_billing_version` is 5.x.x or 6.x.x.
2. If you are using ProGuard, add following keep rules to your `proguard-rules.pro` file:
```grooby
-keep class com.appsflyer.** { *; }
-keep class kotlin.jvm.internal.Intrinsics{ *; }
-keep class kotlin.collections.**{ *; }
```## Basic Integration Of The Connector
### Create PurchaseClient Instance
Create an instance of this Connector to configure (in the following steps) for observing and validating transactions in your app.
**Make sure to save a reference to the built object. If the object is not saved, it could lead to unexpected behavior and memory leaks.*** Kotlin
```kotlin
// init
val builder = PurchaseClient.Builder(this, Store.GOOGLE)
// Make sure to keep this instance
val afPurchaseClient = builder.build()
```* Java
```java
// init
PurchaseClient.Builder builder = new PurchaseClient.Builder(context, Store.GOOGLE);
// Make sure to keep this instance
PurchaseClient purchaseClient = builder.build();
```### Start Observing Transactions
Start the SDK instance to observe transactions.**⚠️ Please Note**
> This should be called right after calling the Android SDK's [`start`](https://dev.appsflyer.com/hc/docs/integrate-android-sdk#starting-the-android-sdk) method.
> Calling `startObservingTransactions` activates a listener that automatically observes new billing transactions. This includes new and existing subscriptions and new in app purchases.
> The best practice is to activate the listener as early as possible, preferably in the `Application` class.
* Kotlin
```kotlin
// start
afPurchaseClient.startObservingTransactions()
```* Java
```java
// start
afPurchaseClient.startObservingTransactions();
```* Kotlin
```kotlin
// start
afPurchaseClient.stopObservingTransactions()
```* Java
```java
// start
afPurchaseClient.stopObservingTransactions();
```* Java
```java
builder.logSubscriptions(true);
```* Java
```java
builder.autoLogInApps(true);
```### Subscription Purchase Event Data Source
* Kotlin
```kotlin
builder.setSubscriptionPurchaseEventDataSource(object : PurchaseClient.SubscriptionPurchaseEventDataSource{
override fun onNewPurchases(purchaseEvents: List): Map {
return mapOf("some key" to "some value")
}
})// or use lambda
builder.setSubscriptionPurchaseEventDataSource {
mapOf(
"some key" to "some value",
"another key" to it.size
)
}
```
* Java
```java
builder.setSubscriptionPurchaseEventDataSource(new PurchaseClient.SubscriptionPurchaseEventDataSource() {
@NonNull
@Override
public Map onNewPurchases(@NonNull List extends SubscriptionPurchaseEvent> purchaseEvents) {
Map map = new HashMap();
map.put("some key", "value");
return map;
}
});// or use lambda
builder.setSubscriptionPurchaseEventDataSource(purchaseEvents -> {
Map map = new HashMap();
map.put("some key", "value");
return map;
});
```### In Apps Purchase Event Data Source
* Kotlin
```kotlin
builder.setInAppPurchaseEventDataSource(object :
PurchaseClient.InAppPurchaseEventDataSource {
override fun onNewPurchases(purchaseEvents: List): Map {
return mapOf(
"some key" to "some value",
"another key" to purchaseEvents.size
)
}
})// or use lambda
builder.setInAppPurchaseEventDataSource {
mapOf(
"some key" to "some value",
"another key" to it.size
)
}
```
* Java
```java
builder.setInAppPurchaseEventDataSource(new PurchaseClient.InAppPurchaseEventDataSource() {
@NonNull
@Override
public Map onNewPurchases(@NonNull List extends InAppPurchaseEvent> purchaseEvents) {
Map map = new HashMap();
map.put("some key", "value");
return map;
}
});// or use lambda
builder.setInAppPurchaseEventDataSource(purchaseEvents -> {
Map map = new HashMap();
map.put("some key", "value");
return map;
});
```| Listener Method | Description |
|-------------------------------|--------------|
| `onResponse(result: Result?)` | Invoked when we got 200 OK response from the server (INVALID purchase is considered to be successful response and will be returned to this callback) |
|`onFailure(result: String, error: Throwable?)`|Invoked when we got some network exception or non 200/OK response from the server.|### Subscription Validation Result Listener
* Kotlin
```kotlin
builder.setSubscriptionValidationResultListener(object :
PurchaseClient.SubscriptionPurchaseValidationResultListener {
override fun onResponse(result: Map?) {
result?.forEach { (k: String, v: SubscriptionValidationResult?) ->
if (v.success) {
Log.d(TAG, "[PurchaseConnector]: Subscription with ID $k was validated successfully")
val subscriptionPurchase = v.subscriptionPurchase
Log.d(TAG, subscriptionPurchase.toString())
} else {
Log.d(TAG, "[PurchaseConnector]: Subscription with ID $k wasn't validated successfully")
val failureData = v.failureData
Log.d(TAG, failureData.toString())
}
}
}override fun onFailure(result: String, error: Throwable?) {
Log.d(TAG, "[PurchaseConnector]: Validation fail: $result")
error?.printStackTrace()
}
})
```* Java
```java
builder.setSubscriptionValidationResultListener(new PurchaseClient.SubscriptionPurchaseValidationResultListener() {
@Override
public void onResponse(@Nullable Map result) {
if (result == null) {
return;
}
result.forEach((k, v) -> {
if (v.getSuccess()) {
Log.d(TAG, "[PurchaseConnector]: Subscription with ID " + k + " was validated successfully");
SubscriptionPurchase subscriptionPurchase = v.getSubscriptionPurchase();
Log.d(TAG, subscriptionPurchase.toString());
} else {
Log.d(TAG, "[PurchaseConnector]: Subscription with ID " + k + " wasn't validated successfully");
ValidationFailureData failureData = v.getFailureData();
Log.d(TAG, failureData.toString());
}
});
}@Override
public void onFailure(@NonNull String result, @Nullable Throwable error) {
Log.d(TAG, "[PurchaseConnector]: Validation fail: " + result);
if (error != null) {
error.printStackTrace();
}
}
});
```### In Apps Validation Result Listener
* Kotlin
```kotlin
builder.setInAppValidationResultListener(object :
PurchaseClient.InAppPurchaseValidationResultListener {
override fun onResponse(result: Map?) {
result?.forEach { (k: String, v: InAppPurchaseValidationResult?) ->
if (v.success) {
Log.d(TAG, "[PurchaseConnector]: Product with Purchase Token$k was validated successfully")
val productPurchase = v.productPurchase
Log.d(TAG, productPurchase.toString())
} else {
Log.d(TAG, "[PurchaseConnector]: Product with Purchase Token $k wasn't validated successfully")
val failureData = v.failureData
Log.d(TAG, failureData.toString())
}
}
}override fun onFailure(result: String, error: Throwable?) {
Log.d(TAG, "[PurchaseConnector]: Validation fail: $result")
error?.printStackTrace()
}
})
```* Java
```java
builder.setInAppValidationResultListener(new PurchaseClient.InAppPurchaseValidationResultListener() {
@Override
public void onResponse(@Nullable Map result) {
if (result == null) {
return;
}
result.forEach((k, v) -> {
if (v.getSuccess()) {
Log.d(TAG, "[PurchaseConnector]: Product with Purchase Token " + k + " was validated successfully");
ProductPurchase productPurchase = v.getProductPurchase();
Log.d(TAG, productPurchase.toString());
} else {
Log.d(TAG, "[PurchaseConnector]: Subscription with Purchase Token " + k + " wasn't validated successfully");
ValidationFailureData failureData = v.getFailureData();
Log.d(TAG, failureData.toString());
}
});
}@Override
public void onFailure(@NonNull String result, @Nullable Throwable error) {
Log.d(TAG, "[PurchaseConnector]: Validation fail: " + result);
if (error != null) {
error.printStackTrace();
}
}
});
``````
* Java
```java
// sandbox environment
builder.setSandbox(true);
// production environment
builder.setSandbox(false);```
override fun onFailure(result: String, error: Throwable?) {
Log.d(TAG, "[PurchaseConnector]: Validation fail: $result")
error?.printStackTrace()
}
})
// In Apps Purchase Validation listener. Invoked after getting response from AppsFlyer servers
// to let customer know if purchase was validated successfully
.setInAppValidationResultListener(object :
PurchaseClient.InAppPurchaseValidationResultListener {
override fun onResponse(result: Map?) {
result?.forEach { (k: String, v: InAppPurchaseValidationResult?) ->
if (v.success) {
Log.d(
TAG,
"[PurchaseConnector]: Product with Purchase Token$k was validated successfully"
)
val productPurchase = v.productPurchase
Log.d(TAG, productPurchase.toString())
} else {
Log.d(
TAG,
"[PurchaseConnector]: Product with Purchase Token $k wasn't validated successfully"
)
val failureData = v.failureData
Log.d(TAG, failureData.toString())
}
}
}override fun onFailure(result: String, error: Throwable?) {
Log.d(TAG, "[PurchaseConnector]: Validation fail: $result")
error?.printStackTrace()
}
})
// Build the client
.build()// Start the SDK instance to observe transactions.
afPurchaseClient.startObservingTransactions()
}
```* Java
```java
@Override
public void onCreate() {
super.onCreate();
AppsFlyerLib.getInstance().init("YOUR_DEV_KEY", listener, getApplicationContext());
AppsFlyerLib.getInstance().start(getApplicationContext());
// init - Make sure to save a reference to the built object. If the object is not saved,
// it could lead to unexpected behavior and memory leaks.
PurchaseClient afPurchaseClient = new PurchaseClient.Builder(getApplicationContext(), Store.GOOGLE)
// Enable Subscriptions auto logging
.logSubscriptions(true)
// Enable In Apps auto logging
.autoLogInApps(true)
// set production environment
.setSandbox(false)
// Subscription Purchase Event Data source listener. Invoked before sending data to AppsFlyer servers
// to let customer add extra parameters to the payload
.setSubscriptionPurchaseEventDataSource(purchaseEvents -> {
Map map = new HashMap();
map.put("somekey", "value");
map.put("type", "Subscription");
return map;
})
// In Apps Purchase Event Data source listener. Invoked before sending data to AppsFlyer servers
// to let customer add extra parameters to the payload
.setInAppPurchaseEventDataSource(purchaseEvents -> {
Map map = new HashMap();
map.put("somekey", "value");
map.put("type", "InApps");
return map;
})
// Subscriptions Purchase Validation listener. Invoked after getting response from AppsFlyer servers
// to let customer know if purchase was validated successfully
.setSubscriptionValidationResultListener(new PurchaseClient.SubscriptionPurchaseValidationResultListener() {
@Override
public void onResponse(@Nullable Map result) {
if (result == null) {
return;
}
result.forEach((k, v) -> {
if (v.getSuccess()) {
Log.d(TAG, "[PurchaseConnector]: Subscription with ID " + k + " was validated successfully");
SubscriptionPurchase subscriptionPurchase = v.getSubscriptionPurchase();
Log.d(TAG, subscriptionPurchase.toString());
} else {
Log.d(TAG, "[PurchaseConnector]: Subscription with ID " + k + " wasn't validated successfully");
ValidationFailureData failureData = v.getFailureData();
Log.d(TAG, failureData.toString());
}
});
}@Override
public void onFailure(@NonNull String result, @Nullable Throwable error) {
Log.d(TAG, "[PurchaseConnector]: Validation fail: " + result);
if (error != null) {
error.printStackTrace();
}
}
})
// In Apps Purchase Validation listener. Invoked after getting response from AppsFlyer servers
// to let customer know if purchase was validated successfully
.setInAppValidationResultListener(new PurchaseClient.InAppPurchaseValidationResultListener() {
@Override
public void onResponse(@Nullable Map result) {
if (result == null) {
return;
}
result.forEach((k, v) -> {
if (v.getSuccess()) {
Log.d(TAG, "[PurchaseConnector]: Product with Purchase Token " + k + " was validated successfully");
ProductPurchase productPurchase = v.getProductPurchase();
Log.d(TAG, productPurchase.toString());
} else {
Log.d(TAG, "[PurchaseConnector]: Subscription with Purchase Token " + k + " wasn't validated successfully");
ValidationFailureData failureData = v.getFailureData();
Log.d(TAG, failureData.toString());
}
});
}@Override
public void onFailure(@NonNull String result, @Nullable Throwable error) {
Log.d(TAG, "[PurchaseConnector]: Validation fail: " + result);
if (error != null) {
error.printStackTrace();
}
}
})
// Build the client
.build();// Start the SDK instance to observe transactions.
afPurchaseClient.startObservingTransactions();
}
```