Validate and log purchase
Learn how to validate and log purchases.
The validateAndLogInAppPurchase
method is part of the receipt validation flow, which enables your app to validate in-app purchase events generated by Google Play.
📘Note
The function
validateAndLogInAppPurchase
can be replaced by the fully automatic purchase SDK connector (a premium service). To learn how to integrate the connector, see in Github Android purchase SDK connector.
The method is currently implemented in two versions.
- validateAndLogInAppPurchase (BETA) supported from SDK v.6.14.0
- validateAndLogInAppPurchase (LEGACY)
Implement validateAndLogInAppPurchase (BETA)
The validateAndLogInAppPurchase (currently in BETA) sends the purchase details to AppsFlyer for validation. After AppsFlyer validates the purchase with Google Play the method returns the response to a callback function.
📘Note
Contact your CSM to join the beta.
To implement the method perform the following steps:
- Query the Play Store for the Purchase object of the in-app purchase event.
- Initialize an AFPurchaseDetails instance and set it with the purchase type, token, product ID, price, and currency details retrieved from the Purchase object.
- If you want to add additional details to the purchase in-app event, populate a hash map with key-value pairs.
- Invoke
validateAndLogInAppPurchase
with the following:- The
AFPurchaseDetails
object you created in step 2. - The hash map with the additional details you created in step 3.
- An instance of the AppsFlyerInAppPurchaseValidationCallback to handle validation success and failure.
- The
- Add your logic for handling the failure, success, or error responses returned to the callback function. See here a few response examples.
If the validation is successful, an af_purchase
event is logged with the values provided to validateAndLogInAppPurchase
.
📘Note
validateAndLogInAppPurchase
generates anaf_purchase
in-app event upon successful validation. Sending this event yourself will cause duplicate event reporting.
代码示例
AFPurchaseDetails purchaseDetails = new AFPurchaseDetails(
AFPurchaseType.SUBSCRIPTION, //Purchase type
"PurchaseToken", // Purchase token
"myProductId", // Product ID
"202.34", // Price
"USD"); // Currency
Map<String, String> purchaseAdditionalDetails = new HashMap<>();
// Adding some key-value pairs to the map
purchaseAdditionalDetails.put("firstDetail", "something");
purchaseAdditionalDetails.put("secondDetail", "nice");
AppsFlyerLib.getInstance().validateAndLogInAppPurchase(
purchaseDetails,
purchaseAdditionalDetails, //optional
new AppsFlyerInAppPurchaseValidationCallback() {
@Override
public void onInAppPurchaseValidationFinished(@NonNull Map<String, ?> validationFinishedResult) {
Log.d(LOG_TAG, "Purchase validation response arrived");
Boolean validationResult = (Boolean) validationFinishedResult.get("result");
if (validationResult == true) {
Log.d(LOG_TAG, "Purchase validated successfully");
// Add here code following successful purchase validation
} else {
@NonNull Map<String, ?> error_data = (Map<String, ?>) validationFinishedResult.get("error_data");
Log.d(LOG_TAG, "Purchase was not validated due to " + error_data.get("message"));
// Add here code when validation was not successful
}
}
@Override
public void onInAppPurchaseValidationError(@NonNull Map<String, ?> validationErrorResult) {
Log.d(LOG_TAG, "Purchase validation returned error: " + validationErrorResult.get("error_message"));
}
}
);
Response Examples
The callback function AppsFlyerInAppPurchaseValidationCallback receives validation responses from AppsFlyer in JSON format. Here are two examples:
One time purchase validated successfully
{
"result": true,
"purchase_type": "one_time_purchase",
"product_purchase": {
"purchasetimemillis": "1699667717458",
"purchasestate": "0",
"consumptionstate": "1",
"quantity": "0",
"regioncode": "US",
"acknowledgementstate": "1",
"productid": "",
"orderid": "GPA.3345-6347-1243-65405",
"purchasetoken": "",
"kind": "androidpublisher#productPurchase",
"developerpayload": "",
"obfuscatedexternalprofileid": "",
"purchasetype": "null",
"obfuscatedexternalaccountid": ""
}
}
Subscription validated successfully
{
"result": true,
"purchase_type": "subscription",
"subscription_purchase": {
"externalaccountidentifiers": {
"obfuscatedexternalaccountid": "LD32LMR23K4E2"
},
"lineitems": [
{
"offerdetails": {
"baseplanid": "p1w",
"offerid": "freetrial"
},
"autorenewingplan": {
"autorenewenabled": true
},
"productid": "s2_sub_00_00_00",
"expirytime": "2023-10-21T09:15:16.427Z"
}
],
"regioncode": "AU",
"acknowledgementstate": "ACKNOWLEDGEMENT_STATE_PENDING",
"subscriptionstate": "SUBSCRIPTION_STATE_ACTIVE",
"kind": "androidpublisher#subscriptionPurchaseV2",
"latestorderid": "GPA.3335-6293-5584-30859",
"starttime": "2023-10-18T09:15:45.814Z"
}
}
validateAndLogInAppPurchase (Legacy)
validateAndLogInAppPurchase
is exposed via AppsFlyerLib
.
validateAndLognInAppPurchase
需要这些参数:
validateAndLogInAppPurchase(Context context,
java.lang.String publicKey,
java.lang.String signature,
java.lang.String purchaseData,
java.lang.String price, java.lang.String currency,
java.util.Map<java.lang.String,java.lang.String> additionalParameters)
context
:应用程序/行为方面publicKey
:从Google Play控制台获得的许可证密钥signature
:data.INAPP_DATA_SIGNATURE
fromonActivityResult
purchaseData
:data.INAPP_PURCHASE_DATA
fromonActivityResult
price
:购买价格,应来自于skuDetails.getStringArrayList("DETAILS_LIST")
currency
:购买货币,应来自于skuDetails.getStringArrayList("DETAILS_LIST")
additionalParameters
- Additional event parameters to log
If the validation is successful, an af_purchase
event is logged with the values provided to validateAndLogInAppPurchase
.
注意
validateAndLogInAppPurchase
generates anaf_purchase
in-app event upon successful validation. Sending this event yourself will cause duplicate event reporting.
Example: Validate an in-app purchase
// Purchase object is returned by Google API in onPurchasesUpdated() callback
private void handlePurchase(Purchase purchase) {
Log.d(LOG_TAG, "Purchase successful!");
Map<String, String> eventValues = new HashMap<>();
eventValues.put("some_parameter", "some_value");
AppsFlyerLib.getInstance().validateAndLogInAppPurchase(getApplicationContext(),
PUBLIC_KEY,
purchase.getSignature(),
purchase.getOriginalJson(),
"10",
"USD",
eventValues);
}
// Purchase object is returned by Google API in onPurchasesUpdated() callback
private fun handlePurchase(Purchase purchase) {
Log.d(LOG_TAG, "Purchase successful!")
val eventValues = HashMap<String, String>()
eventValues.put("some_parameter", "some_value")
AppsFlyerLib.getInstance().validateAndLogInAppPurchase(this,
PUBLIC_KEY,
purchase.getSignature(),
purchase.getOriginalJson(),
"10",
"USD",
eventValues)
}
Handling purchase validation success/failure
Use AppsFlyerInAppPurchaseValidatorListener
to subscribe to purchase validation successes/failures and registerValidatorListener
to register it in your Application class.
registerValidatorListener
is exposed via AppsFlyerLib
. To use AppsFlyerInAppPurchaseValidatorListener
, import it:
import com.appsflyer.AppsFlyerInAppPurchaseValidatorListener;
import com.appsflyer.AppsFlyerInAppPurchaseValidatorListener
AppsFlyerInAppPurchaseValidatorListener
有两个回调:
onValidateInApp
:购买验证成功时触发onValidateInAppFailure
:购买验证失败时触发
registerValidatorListener
需要2个参数:
context
:应用程序情景validationListener
: TheAppsFlyerInAppPurchaseValidatorListener
object you wish to register
AppsFlyerLib.getInstance().registerValidatorListener(this,new
AppsFlyerInAppPurchaseValidatorListener() {
public void onValidateInApp() {
Log.d(TAG, "Purchase validated successfully");
}
public void onValidateInAppFailure(String error) {
Log.d(TAG, "onValidateInAppFailure called: " + error);
}
});
AppsFlyerLib.getInstance().registerValidatorListener(this, object : AppsFlyerInAppPurchaseValidatorListener {
override fun onValidateInApp() {
Log.d(LOG_TAG, "Purchase validated successfully")
}
override fun onValidateInAppFailure(error: String) {
Log.d(LOG_TAG, "onValidateInAppFailure called: $error")
}
})
验证应用内购会自动将应用内购买事件上报到AppsFlyer。参见下面event_value参数中传递的示例数据:
{
"some_parameter": "some_value", // from additional_event_values
"af_currency": "USD", // from currency
"af_content_id" :"test_id", // from purchase
"af_revenue": "10", // from revenue
"af_quantity": "1", // from purchase
"af_validated": true // flag that AF verified the purchase
}
已更新 about 2 months ago