Skip to content

Commit d0bfca4

Browse files
committed
Adding onValidationResult Callbacks
1 parent 1fb5969 commit d0bfca4

4 files changed

Lines changed: 53 additions & 52 deletions

File tree

android/src/main/java/com/appsflyer/reactnative/RNAppsFlyerModule.java

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525
import com.appsflyer.share.CrossPromotionHelper;
2626
import com.appsflyer.share.LinkGenerator;
2727
import com.appsflyer.share.ShareInviteHelper;
28-
import com.appsflyer.AFPurchaseDetails;
2928
import com.appsflyer.AFPurchaseType;
29+
import com.appsflyer.AFPurchaseDetails;
3030
import com.appsflyer.AppsFlyerInAppPurchaseValidationCallback;
3131
import com.facebook.react.bridge.Callback;
3232
import com.facebook.react.bridge.Promise;
@@ -780,15 +780,15 @@ public void onValidateInAppFailure(String error) {
780780
}
781781

782782
@ReactMethod
783-
public void validateAndLogInAppPurchaseV2(ReadableMap purchaseDetails, ReadableMap additionalParameters, Callback callback) {
783+
public void validateAndLogInAppPurchaseV2(ReadableMap purchaseDetails, ReadableMap additionalParameters) {
784784
try {
785785
String purchaseType = purchaseDetails.getString("purchaseType");
786786
String purchaseToken = purchaseDetails.getString("transactionId");
787787
String productId = purchaseDetails.getString("productId");
788788

789789
// Convert purchaseType string to AFPurchaseType enum
790790
AFPurchaseType afPurchaseType;
791-
if ("subscription".equals(purchaseType.rawValue())) {
791+
if ("subscription".equals(purchaseType)) {
792792
afPurchaseType = AFPurchaseType.SUBSCRIPTION;
793793
} else {
794794
afPurchaseType = AFPurchaseType.ONE_TIME_PURCHASE;
@@ -808,23 +808,19 @@ public void validateAndLogInAppPurchaseV2(ReadableMap purchaseDetails, ReadableM
808808
additionalParamsMap,
809809
new AppsFlyerInAppPurchaseValidationCallback() {
810810
@Override
811-
public void onSuccess() {
812-
if (callback != null) {
813-
callback.invoke("In App Purchase Validation completed successfully!");
814-
}
811+
public void onInAppPurchaseValidationFinished(Map<String, Object> validationResult) {
812+
sendEvent(reactContext, "onValidationResult", validationResult.toString());
815813
}
816814

817815
@Override
818-
public void onError(int errorCode, String errorMessage) {
819-
if (callback != null) {
820-
callback.invoke("Error: " + errorMessage);
821-
}
816+
public void onInAppPurchaseValidationError(Map<String, Object> validationError) {
817+
sendEvent(reactContext, "onValidationResult", validationError.toString());
822818
}
823819
});
824820
} catch (Exception e) {
825-
if (callback != null) {
826-
callback.invoke("Error: " + e.getMessage());
827-
}
821+
Map<String, Object> error = new HashMap<>();
822+
error.put("error", e.getMessage());
823+
sendEvent(reactContext, "onValidationResult", error.toString());
828824
}
829825
}
830826

index.d.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -376,12 +376,13 @@ declare module "react-native-appsflyer" {
376376
): Response<string>;
377377
/**
378378
* [NEW API] This is the new validateAndLogInAppPurchase API with AFPurchaseDetails.
379+
* Uses event emitter pattern for callback handling.
379380
*/
380-
validateAndLogInAppPurchase(
381+
validateAndLogInAppPurchaseV2(
381382
purchaseDetails: AFPurchaseDetails,
382383
additionalParameters?: object,
383384
callback?: AppsFlyerInAppPurchaseValidationCallback
384-
): void;
385+
): (() => void) | void;
385386

386387
updateServerUninstallToken(token: string, successC?: SuccessCB): void;
387388
sendPushNotificationData(pushPayload: object, errorC?: ErrorCB): void;

index.js

Lines changed: 32 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -852,30 +852,41 @@ export const AFPurchaseType = {
852852
};
853853

854854
/**
855-
* Validate and log in-app purchase with support for both legacy and new APIs.
856-
*
857-
* - **Legacy API**: validateAndLogInAppPurchase(purchaseInfo, successC, errorC)
858-
* - **New API**: validateAndLogInAppPurchase(purchaseDetails, additionalParameters, callback)
859-
*
860-
* The method automatically detects which API to use based on the parameters:
861-
* - If first parameter has 'purchaseType' property, uses new API
862-
* - Otherwise, uses legacy API
855+
* [LEGACY WARNING] This is the legacy validateAndLogInAppPurchase API.
863856
*/
864-
appsFlyer.validateAndLogInAppPurchase = (param1, param2, param3) => {
865-
// Debug: Check if native methods exist
866-
console.log('[AppsFlyer] RNAppsFlyer methods:', Object.keys(RNAppsFlyer));
867-
console.log('[AppsFlyer] validateAndLogInAppPurchaseV2 exists:', typeof RNAppsFlyer.validateAndLogInAppPurchaseV2);
857+
appsFlyer.validateAndLogInAppPurchase = (purchaseInfo, successCallback, errorCallback) => {
858+
console.log('[AppsFlyer] Using legacy validateAndLogInAppPurchase API');
859+
return RNAppsFlyer.validateAndLogInAppPurchase(purchaseInfo, successCallback, errorCallback);
860+
};
861+
862+
/**
863+
* New validateAndLogInAppPurchase API with AFPurchaseDetails support.
864+
*/
865+
appsFlyer.validateAndLogInAppPurchaseV2 = (purchaseDetails, additionalParameters, callback) => {
866+
console.log('[AppsFlyer] Using new validateAndLogInAppPurchaseV2 API with AFPurchaseDetails');
868867

869-
// Detect which API to use based on the first parameter
870-
if (param1 && typeof param1 === 'object' && param1.purchaseType) {
871-
// New API: (purchaseDetails, additionalParameters, callback)
872-
console.log('[AppsFlyer] Using new validateAndLogInAppPurchase API with AFPurchaseDetails');
873-
return RNAppsFlyer.validateAndLogInAppPurchaseV2(param1, param2, param3);
874-
} else {
875-
// Legacy API: (purchaseInfo, successC, errorC)
876-
console.log('[AppsFlyer] Using legacy validateAndLogInAppPurchase API');
877-
return RNAppsFlyer.validateAndLogInAppPurchase(param1, param2, param3);
868+
if (callback && typeof callback === typeof Function) {
869+
const listener = appsFlyerEventEmitter.addListener(
870+
"onValidationResult",
871+
(_data) => {
872+
try {
873+
let data = JSON.parse(_data);
874+
callback(data);
875+
} catch (_error) {
876+
callback(new AFParseJSONException("Invalid data structure", _data));
877+
}
878+
}
879+
);
880+
881+
eventsMap["onValidationResult"] = listener;
882+
883+
// unregister listener (suppose should be called from componentWillUnmount() )
884+
return function remove() {
885+
listener.remove();
886+
};
878887
}
888+
889+
return RNAppsFlyer.validateAndLogInAppPurchaseV2(purchaseDetails, additionalParameters);
879890
};
880891

881892
appsFlyer.setUseReceiptValidationSandbox = (isSandbox) => {

ios/RNAppsFlyer.m

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -604,14 +604,11 @@ - (BOOL)isExpoApp {
604604

605605
}
606606

607-
RCT_EXPORT_METHOD(validateAndLogInAppPurchaseV2:(NSDictionary*)purchaseDetails
608-
additionalParameters:(NSDictionary*)additionalParameters
609-
callback:(RCTResponseSenderBlock)callback) {
607+
RCT_EXPORT_METHOD(validateAndLogInAppPurchaseV2: (NSDictionary*)purchaseDetails
608+
additionalParameters:(NSDictionary*)additionalParameters) {
610609

611610
if (!purchaseDetails || [purchaseDetails isKindOfClass:[NSNull class]]) {
612-
if (callback) {
613-
callback(@[@"Error: Purchase details are required"]);
614-
}
611+
[self sendEventWithName:@"onValidationResult" body:@"{\"error\": \"Purchase details are required\"}"];
615612
return;
616613
}
617614

@@ -620,9 +617,7 @@ - (BOOL)isExpoApp {
620617
NSString* transactionId = [purchaseDetails objectForKey:@"transactionId"];
621618

622619
if (!purchaseType || !productId || !transactionId) {
623-
if (callback) {
624-
callback(@[@"Error: purchaseType, productId, and transactionId are required"]);
625-
}
620+
[self sendEventWithName:@"onValidationResult" body:@"{\"error\": \"purchaseType, productId, and transactionId are required\"}"];
626621
return;
627622
}
628623

@@ -642,12 +637,10 @@ - (BOOL)isExpoApp {
642637
[[AppsFlyerLib shared] validateAndLogInAppPurchase:details
643638
extraEventValues:additionalParameters
644639
completionHandler:^(AFSDKValidateAndLogResult * _Nullable result) {
645-
if (callback) {
646-
if (result && result.isValid) {
647-
callback(@[@"In App Purchase Validation completed successfully!"]);
648-
} else {
649-
callback(@[@"Error: Purchase validation failed"]);
650-
}
640+
if (result && result.isValid) {
641+
[self sendEventWithName:@"onValidationResult" body:@"{\"result\": true, \"message\": \"In App Purchase Validation completed successfully!\"}"];
642+
} else {
643+
[self sendEventWithName:@"onValidationResult" body:@"{\"error\": \"Purchase validation failed\"}"];
651644
}
652645
}];
653646
}

0 commit comments

Comments
 (0)