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 the App Store.


The function validateAndLogInAppPurchase can be replaced by the fully automatic purchase SDK connector (a premium service). To learn how to integrate the connector, see on Github iOS purchase SDK connector.

The method is currently implemented in two versions.

Implement validateAndLogInAppPurchase (BETA)

The validateAndLogInAppPurchase method (currently in BETA) sends the purchase details to AppsFlyer for validation. After AppsFlyer validates the purchase with the App Store, the method returns the response to a completion handler block.

To implement the method, perform the following steps:

  1. Query the App Store for the object of the in-app purchase event.
  2. Initialize an AFSDKPurchaseDetails instance and set it with the purchase type, token, product ID, price, and currency details retrieved from the Purchase object.
  3. If you want to add additional details to the purchase in-app event, populate a dictionary with key-value pairs.
  4. Invoke validateAndLogInAppPurchase 다음 인수 사용:
    • The AFSDKPurchaseDetails object you created in step 2.
    • The dictionary with the additional details you created in step 3.
  5. Add your logic for handling the failure, success, or error responses to a completion handler block in the function body.

If the validation is successful, an af_purchase event is logged with the values provided to validateAndLogInAppPurchase.


validateAndLogInAppPurchase generates an af_purchase in-app event upon successful validation. Sending this event yourself will cause duplicate event reporting.

Code example

func sampleCodeValidateAndLog(){
    let productId = "my-product-id"
    let price = "1.99"
    let currency = "USD"
    let transactionId = "12345-transaction-id"

    // Create a new instance of AFSDKPurchaseDetails with the required information
    let purchaseDetails = AFSDKPurchaseDetails(productId: productId, price: price, currency: currency, transactionId: transactionId)
    let extraEventValues: [String: Any]? = [
        "firstExtraEventValue": "something",
        "secondExtraEventValue": "nice",
    AppsFlyerLib.shared().validateAndLog(inAppPurchase: purchaseDetails, extraEventValues: extraEventValues) { result in
        // This block is executed when the logging and validation operation is complete.
        // Process the 'result' as needed
        switch result!.status {
        case .success:
            print("Purchase validation and logging succeeded.")
            if let resultData = result?.result {
                // Process successful result data
                print("Validation successful data: \(resultData)")
        case .failure:
            print("Purchase was not validated.")
            if let errorData = result?.errorData {
                // Process failure error data
                print("Validation failed data: \(errorData)")
        case .error:
            print("An error occurred during the validation and logging operation.")
            if let error = result?.error {
                // Process NSError
                print("Error: \(error)")

Subscription purchase that failed validation

  "result": false,
  "status": "failure",
  "product_id": "my-product-id",
  "price": "1.99",
  "currency": "USD",
  "transaction_id": "12345-transaction-id",
  "error": {
    "code": 100,
    "message": "Invalid purchase token or product id."
  "additional_parameters": {
    "firstExtraEventValue": "something",
    "secondExtraEventValue": "nice"

validateAndLogInAppPurchase (LEGACY)

Purchase validation using validateAndLogInAppPurchase

validateAndLoginInAppPurchase 인수 4개를 갖습니다.

- (void) validateAndLogInAppPurchase:(NSString *) productIdentifier,
                  price:(NSString *) price
                  currency:(NSString *) currency
                  transactionId:(NSString *) tranactionId
                  additionalParameters:(NSDictionary *) params
                  success:(void (^)(NSDictionary *response)) successBlock
                  failure:(void (^)(NSError *error, id reponse)) failedBlock;
validateAndLog(inAppPurchase: String?,
               price: String?,
               currency: String?,
               transactionId: String?,
               additionalParameters: [AnyHashable : Any]?,
               success: ([AnyHashable : Any]) -> Void)?,
               failure: ((Error?, Any?) -> Void)?)

Upon successful validation, a NSDictionary is returned with the receipt validation data (provided by Apple servers).



Calling validateAndLogInAppPurchase generates an af_purchase in-app event upon successful validation. Sending this event yourself creates duplicate event reporting.

Example: Validate in-app purchase

[[AppsFlyerLib shared] validateAndLogInAppPurchase:@"ProductIdentifier" price:@"price"
    additionalParameters:@{@"test": @"val" , @"test1" : @"val 1"}
    success:^(NSDictionary *result){
      NSLog(@"Purchase succeeded And verified! response: %@", result[@"receipt"]);
    } failure:^(NSError *error, id response) {
      NSLog(@"response = %@", response);
      if([response isKindOfClass:[NSDictionary class]]) {
        if([response[@"status"] isEqualToString:@"in_app_arr_empty"]){
          // retry with 'SKReceiptRefreshRequest' because
          // Apple has returned an empty response
          // <YOUR CODE HERE>

      } else {
        //handle other errors
AppsFlyerLib.shared().validateAndLogInAppPurchase (
  inAppPurchase: "productIdentifier",
  price: "price",
  currency: "currency",
  transactionId: "transactionId",
  additionalParameters: [:],
  success: {
      guard let dictionary = $0 as? [String:Any] else { return }
  failure: { error, result in
      guard let emptyInApp = result as? [String:Any],
      let status = emptyInApp["status"] as? String,
      status == "in_app_arr_empty" else {
      // Try to handle other errors

샌드박스 모드에서 구매 검증 테스트하기

샌드박스 환경에서 구매 검증을 테스트할 때, 다음 코드를 추가합니다:

[AppsFlyerLib shared].useReceiptValidationSandbox = YES;
AppsFlyerLib.shared().useReceiptValidationSandbox = true



이 코드는 프로덕션 빌드에서 제거해야 합니다.

Validating an in-app purchase automatically generates and sends an in-app purchase event to AppsFlyer. Its eventValues will look something like this:

   "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