diff --git a/project.hxp b/project.hxp index 0b434b3a6..e138b2a52 100644 --- a/project.hxp +++ b/project.hxp @@ -313,10 +313,16 @@ class Project extends HXProject { /** * `-DFEATURE_ADMOB_ADS` - * If this flag is enabled, ADs from AdMob will be disabled. + * If this flag is disabled, ADs from AdMob will be disabled. */ static final FEATURE_ADMOB_ADS:FeatureFlag = "FEATURE_ADMOB_ADS"; + /** + * `-DFEATURE_IAP` + * If this flag is enabled, ADs from AdMob will be disabled. + */ + static final FEATURE_IAP:FeatureFlag = "FEATURE_IAP"; + /** * `-DTESTING_ADS` * If this flag is enabled, ADs will use testing mode. @@ -660,6 +666,9 @@ class Project extends HXProject { // Should be true only on mobile builds. FEATURE_ADMOB_ADS.apply(this, isMobile()); + // Should be true only on android builds for now. + FEATURE_IAP.apply(this, isAndroid()); + // Should be true only on debug mobile builds. TESTING_ADS.apply(this, (isTest() || isDebug()) && FEATURE_ADMOB_ADS.isEnabled(this)); @@ -828,8 +837,9 @@ class Project extends HXProject { addHaxelib('hxvlc'); // Video playback } - if (isAndroid()) - addHaxelib('extension-androidtools'); // Android Functions + if (isAndroid()) { + addHaxelib('extension-androidtools'); // Android Functions + } if (FEATURE_DISCORD_RPC.isEnabled(this)) { addHaxelib('hxdiscord_rpc'); // Discord API @@ -856,8 +866,8 @@ class Project extends HXProject { addHaxelib('extension-haptics'); // Haptic feedback } - if (isMobile()) { - addHaxelib('extension-iap'); // In-app purchases Extension + if (FEATURE_IAP.isEnabled(this)) { + addHaxelib('extension-iapcore'); // In-app purchases Extension } } diff --git a/source/funkin/InitState.hx b/source/funkin/InitState.hx index a69f1908f..637a58468 100644 --- a/source/funkin/InitState.hx +++ b/source/funkin/InitState.hx @@ -101,7 +101,7 @@ class InitState extends FlxState funkin.mobile.util.AdMobUtil.init(); #end - #if android + #if FEATURE_IAP // Setup In-App purchases funkin.mobile.util.InAppPurchasesUtil.init(); #end diff --git a/source/funkin/mobile/util/InAppPurchasesUtil.hx b/source/funkin/mobile/util/InAppPurchasesUtil.hx index 7cf472d1e..d4f8cab26 100644 --- a/source/funkin/mobile/util/InAppPurchasesUtil.hx +++ b/source/funkin/mobile/util/InAppPurchasesUtil.hx @@ -1,7 +1,10 @@ package funkin.mobile.util; -#if android -import iap.IAP; +#if FEATURE_IAP +import extension.iapcore.android.IAPAndroid; +import extension.iapcore.android.IAPProductDetails; +import extension.iapcore.android.IAPPurchase; +import extension.iapcore.android.IAPResponseCode; /** * Utility class for managing in-app purchases in a mobile application. @@ -11,11 +14,6 @@ import iap.IAP; */ class InAppPurchasesUtil { - /** - * The public key used for verifying in-app purchases, this key is used to ensure the integrity and authenticity of the purchase data. - */ - static final PUBLIC_KEY:String = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvkjukXVNVifxcwvCdntLoVPlMo4H0y232w+7FJCyDLIE39Sif6peAZzRJx5qppCwKhEy0BPp8DNcPCo+KeuYjOroXgPGdwZ6Zr8Cwlrs+xKba2Yt0qr98VhF4PjjJMaDbrLCxtsXEtcpKfItu+Z7m6+4+R5HLP3lvUvK5JynvQ79mct0amKM5WLtnGGDF/cUHaj3prw745SmOpXawTjb43AAIvwWTvEPnFYsoIXodU+4KAm5QIS4FM55HpwXPs8McJFQouo8LaSzYu8SYwRsHBOZpAGgszDIK40gIUmKTe3Ca2Vd77Ib+YP1+EgHJywfuYfC5NAzQRatEX0uDLZ8fwIDAQAB"; - /** * A static final array containing the product IDs for fetching product details. */ @@ -24,42 +22,58 @@ class InAppPurchasesUtil /** * A static variable that holds an array of currently loaded product details for in-app purchases. */ - public static var currentLoadedProductDetails:Array = []; + public static var currentLoadedProductDetails:Array = []; /** * Initializes the in-app purchases utility. */ public static function init():Void { - IAP.onSetup.add(function(success:Bool):Void { - if (success) IAP.queryProductDetails(FETCH_PRODUCT_DETAILS_IDS); - - trace(success ? 'IAP Successfully initialized!' : 'IAP Initialization Failure!'); + IAPAndroid.onLog.add(function(message:String):Void { + logMessage(message); }); - IAP.onDebugLog.add(function(message:String):Void { - trace(message); - }); - - #if android - IAP.onQueryProductDetails.add(function(products:Array):Void { - if (products != null && products.length > 0) - { - currentLoadedProductDetails = products; - - for (product in currentLoadedProductDetails) - { - trace("Product Details found: " + product.title); - } - } + IAPAndroid.onBillingSetupFinished.add(function(code:IAPResponseCode, message:String):Void { + if (message != null && message.length > 0) logMessage('IAP Setup finished with code "$code" "$message"!'); else { - trace("No products found."); + logMessage('IAP Setup finished with code "$code"!'); + } + + if (code == IAPResponseCode.OK) + { + IAPAndroid.queryPurchases(); + + IAPAndroid.queryProductDetails(FETCH_PRODUCT_DETAILS_IDS); } }); - #end - IAP.init(PUBLIC_KEY); + IAPAndroid.onBillingServiceDisconnected.add(function():Void { + logMessage("IAP Billing service disconnected!"); + }); + + IAPAndroid.onProductDetailsResponse.add(function(code:IAPResponseCode, productDetails:Array):Void { + logMessage('IAP Product details responded with code "$code", $productDetails'); + + currentLoadedProductDetails = productDetails; + + for (productDetails in currentLoadedProductDetails) + { + logMessage('IAP Product details with title: ${productDetails.getTitle()}'); + } + }); + + IAPAndroid.onQueryPurchasesResponse.add(function(code:IAPResponseCode, purchases:Array):Void { + logMessage('IAP Query purchases responded with code "$code", $purchases'); + }); + + IAPAndroid.onPurchasesUpdated.add(function(code:IAPResponseCode, purchases:Array):Void { + logMessage('IAP Purchases updated response with code "$code", $purchases'); + }); + + IAPAndroid.init(); + + IAPAndroid.startConnection(); } /** @@ -71,15 +85,31 @@ class InAppPurchasesUtil { for (product in currentLoadedProductDetails) { - if (product.productId == id) + if (product.getProductId() == id) { - IAP.purchase(product); + logMessage('Lunching purchase flow for ${product.getTitle()}'); + + IAPAndroid.launchPurchaseFlow(product); return; } + else + { + logMessage('Current ${product.getProductId()} doesnt match ${id}'); + } } - trace("Didn\'t Found Product Details for ID: " + id); + logMessage("Didn\'t Found Product Details for ID: " + id); + } + + @:noCompletion + private static function logMessage(message:String):Void + { + #if android + android.widget.Toast.makeText(message, android.widget.Toast.LENGTH_SHORT); + #end + + trace(message); } } #end diff --git a/source/funkin/ui/options/OptionsState.hx b/source/funkin/ui/options/OptionsState.hx index f69465462..c15868562 100644 --- a/source/funkin/ui/options/OptionsState.hx +++ b/source/funkin/ui/options/OptionsState.hx @@ -150,6 +150,9 @@ class OptionsMenu extends Page createItem("CLEAR SAVE DATA", function() { promptClearSaveData(); }); + createItem("Launch purchase flow", function() { + funkin.mobile.util.InAppPurchasesUtil.purchase('test_product_0'); + }); createItem("EXIT", exit); }