Skip to content

Commit e695999

Browse files
committed
feat: Android VAL2
1 parent dcad508 commit e695999

3 files changed

Lines changed: 60 additions & 29 deletions

File tree

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class RNAppsFlyerConstants {
3030
final static String afOnInstallConversionFailure = "onInstallConversionFailure";
3131
final static String afOnInstallConversionDataLoaded = "onInstallConversionDataLoaded";
3232
final static String afOnDeepLinking = "onDeepLinking";
33+
final static String afOnValidationResult = "onValidationResult";
3334

3435
final static String INVITE_FAIL = "Could not create invite link";
3536
final static String INVITE_CHANNEL = "channel";

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

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -782,48 +782,78 @@ public void onValidateInAppFailure(String error) {
782782
@ReactMethod
783783
public void validateAndLogInAppPurchaseV2(ReadableMap purchaseDetails, ReadableMap additionalParameters) {
784784
try {
785+
// Extract and validate required fields
785786
String purchaseType = purchaseDetails.getString("purchaseType");
786787
String purchaseToken = purchaseDetails.getString("transactionId");
787788
String productId = purchaseDetails.getString("productId");
788789

789-
// Convert purchaseType string to AFPurchaseType enum
790-
AFPurchaseType afPurchaseType;
791-
if ("subscription".equals(purchaseType)) {
792-
afPurchaseType = AFPurchaseType.SUBSCRIPTION;
793-
} else {
794-
afPurchaseType = AFPurchaseType.ONE_TIME_PURCHASE;
790+
if (purchaseType == null || purchaseToken == null || productId == null) {
791+
sendValidationError("Missing required fields: purchaseType, transactionId, or productId");
792+
return;
795793
}
796794

797-
// Create AFPurchaseDetails object
795+
// Convert purchase type
796+
AFPurchaseType afPurchaseType = "subscription".equals(purchaseType)
797+
? AFPurchaseType.SUBSCRIPTION
798+
: AFPurchaseType.ONE_TIME_PURCHASE;
799+
800+
// Create purchase details
798801
AFPurchaseDetails afPurchaseDetails = new AFPurchaseDetails(afPurchaseType, purchaseToken, productId);
799802

800-
// Convert additionalParameters to Map
801-
Map<String, String> additionalParamsMap = null;
802-
if (additionalParameters != null) {
803-
additionalParamsMap = RNUtil.toMap(additionalParameters);
804-
}
803+
// Convert additional parameters to string map
804+
Map<String, String> additionalParams = convertReadableMapToStringMap(additionalParameters);
805805

806+
// Validate purchase
806807
AppsFlyerLib.getInstance().validateAndLogInAppPurchase(
807-
afPurchaseDetails,
808-
additionalParamsMap,
809-
new AppsFlyerInAppPurchaseValidationCallback() {
810-
@Override
811-
public void onInAppPurchaseValidationFinished(Map<String, Object> validationResult) {
812-
sendEvent(reactContext, "onValidationResult", validationResult.toString());
813-
}
814-
815-
@Override
816-
public void onInAppPurchaseValidationError(Map<String, Object> validationError) {
817-
sendEvent(reactContext, "onValidationResult", validationError.toString());
818-
}
819-
});
808+
afPurchaseDetails,
809+
additionalParams,
810+
new AppsFlyerInAppPurchaseValidationCallback() {
811+
@Override
812+
public void onInAppPurchaseValidationFinished(@NonNull Map<String, ?> result) {
813+
sendValidationResult(result);
814+
}
815+
816+
@Override
817+
public void onInAppPurchaseValidationError(@NonNull Map<String, ?> error) {
818+
sendValidationResult(error);
819+
}
820+
}
821+
);
822+
} catch (Exception e) {
823+
sendValidationError("Validation failed: " + e.getMessage());
824+
}
825+
}
826+
827+
private Map<String, String> convertReadableMapToStringMap(ReadableMap readableMap) {
828+
Map<String, String> result = new HashMap<>();
829+
if (readableMap == null) {
830+
return result;
831+
}
832+
833+
ReadableMapKeySetIterator iterator = readableMap.keySetIterator();
834+
while (iterator.hasNextKey()) {
835+
String key = iterator.nextKey();
836+
Object value = readableMap.getDynamic(key);
837+
result.put(key, value != null ? value.toString() : null);
838+
}
839+
return result;
840+
}
841+
842+
private void sendValidationResult(Map<String, ?> data) {
843+
try {
844+
JSONObject json = new JSONObject(data);
845+
sendEvent(reactContext, afOnValidationResult, json.toString());
820846
} catch (Exception e) {
821-
Map<String, Object> error = new HashMap<>();
822-
error.put("error", e.getMessage());
823-
sendEvent(reactContext, "onValidationResult", error.toString());
847+
sendEvent(reactContext, afOnValidationResult, data.toString());
824848
}
825849
}
826850

851+
private void sendValidationError(String errorMessage) {
852+
Map<String, Object> error = new HashMap<>();
853+
error.put("error", errorMessage);
854+
sendValidationResult(error);
855+
}
856+
827857
@ReactMethod
828858
public void sendPushNotificationData(ReadableMap pushPayload, Callback errorCallback) {
829859
JSONObject payload = RNUtil.readableMapToJson(pushPayload);

ios/RNAppsFlyer.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,7 @@ - (BOOL)isExpoApp {
631631

632632
AFSDKPurchaseDetails* details = [[AFSDKPurchaseDetails alloc] initWithProductId:productId transactionId:transactionId purchaseType:afPurchaseType];
633633

634-
[[AppsFlyerLib shared] validateAndLogInAppPurchase:details purchaseAdditionalDetails:additionalParameters completion:^(NSDictionary * _Nullable response, NSError * _Nullable error) {
634+
[[AppsFlyerLib shared] validateAndLogInAppPurchaseWithPurchaseDetails:details purchaseAdditionalDetails:additionalParameters completion:^(NSDictionary * _Nullable response, NSError * _Nullable error) {
635635
if (error == nil) {
636636
BOOL valid = [response[@"result"] boolValue];
637637
if (valid) {

0 commit comments

Comments
 (0)