Back to resources
Expansion Roadmap Google Play ECLP EU DMA Fee Math

Expanding from US iOS to Google Play and EU

You shipped web checkout on US iOS. The regulatory trend is global. Here's the phase-by-phase rollout - Google ECLP, EU DMA, Japan - with fee math, enrollment deadlines, and a per-region kill switch you can build once and expand incrementally.

~10 min read · Updated March 2026
Phase 1
Google Play US (ECLP)
Enrollment required · 0% fee now
Phase 2
EU - Apple & Google
DMA compliance · tiered fees
Phase 3
Japan + Rest of World
Build now, expand when ready

What you'll walk away with: Phase-by-phase rollout plan for Google ECLP, EU Apple DMA, EU Google, and Japan. Enrollment checklists. Fee comparison table across every region. A per-region remote config structure that lets you build the architecture once and expand by flipping flags.

Phase 1: Google Play US - External Content Links Program

Enrollment Deadline: January 28, 2026

All US developers using external content links must enroll via Play Console before this date. Failure to enroll blocks external link functionality - your existing links will stop working, not just new ones.

Google's External Content Links Program (ECLP) is the Android equivalent of Apple's US storefront ruling. It allows US Google Play developers to link to external payment pages. The fee model is different from Apple: Google charges 10% on auto-renewing subscriptions and 20% on one-time purchases for transactions completed within 24 hours of a link click. At current Google Small Business rates (15%), ECLP saves you 5% on subscriptions.

ECLP Enrollment Checklist

Open Play Console → Settings → External content links
Complete enrollment before January 28, 2026
Add Android storefront detection via BillingClient country code or device locale as fallback
Add platform === 'android' && isUS && eclpEnabled branch to your PaywallGate component
Add enable_web_checkout_android_us remote config flag (separate kill switch from iOS)
Configure Android App Links (assetlinks.json) for RevenueCat redemption links on Android
Test full web → redemption flow on a physical Android device (not emulator)

Android Storefront Detection

Android doesn't have a direct equivalent of StoreKit 2's Storefront.current. The most reliable approach is BillingClient - it returns the user's Play Store country. Use Google Play Billing Library 6+ for this.

Kotlin StorefrontDetection.kt
// Google Play Billing Library 6+
val billingClient = BillingClient.newBuilder(context)
    .setListener(purchasesUpdatedListener)
    .enablePendingPurchases()
    .build()

billingClient.startConnection(object : BillingClientStateListener {
    override fun onBillingSetupFinished(result: BillingResult) {
        if (result.responseCode == BillingClient.BillingResponseCode.OK) {
            // countryCode is the user's Play Store country
            val countryCode = billingClient.productDetails
                .firstOrNull()?.subscriptionOfferDetails
                ?.firstOrNull()?.pricingPhases
                ?.pricingPhaseList?.firstOrNull()?.priceAmountMicros

            // Simpler: use BillingClient.isFeatureSupported or locale
            val isUS = Locale.getDefault().country == "US"
        }
    }
    override fun onBillingServiceDisconnected() { /* retry */ }
})

Phase 2: EU - DMA Compliance

EU Apple (Jan 2026)
Basic services tier 5%
Full App Store services 13%
Initial acquisition fee 2% (waived <$1M)
Effective rate (+ Stripe) ~8–16%
EU Google (June 2026)
Standard commission 20%
Recurring subscriptions 10%
Alternative billing Reduced
Effective rate (+ Stripe) ~13%

For EU users, your storefront detection needs to identify the EU App Store region - not just "non-US." The EU fee tiers are meaningfully better than standard IAP (30%) but not as good as US web (3% Stripe only). Still worth enabling, especially at volume.

Small Business Program note: If your app revenue is under $1M annually, Apple waives the 2% initial acquisition fee in the EU. You're paying 5–13% rather than 7–15%. Apply for the EU Small Business Program separately - it's not automatic if you're in the US SBP.

EU detection: use store country code, not device locale

A German user with a UK App Store account is in the UK fee tier, not the EU tier. A UK user since Brexit is not subject to DMA. Always use the store's country code - Storefront.current.countryCode on iOS - and maintain an explicit list of EU country codes to check against.

Phase 3: Japan and Rest of World

Japan has been regulating alternative billing since 2021. South Korea has had mandatory alternative billing since 2022. The trend is clear and one-directional. Build your architecture for per-region billing from the start - don't hardcode "US only" in a way that forces a refactor later.

The right architecture is a remote config structure that maps country codes to billing modes. You ship the logic once. Each new region goes live by updating the config, not the app.

Per-Region Remote Config Structure

JSON remote_config_billing.json
{
  "web_checkout": {
    "enabled_regions": {
      "USA": { "ios": true,  "android": true  },
      "DEU": { "ios": true,  "android": false },
      "FRA": { "ios": true,  "android": false },
      "JPN": { "ios": false, "android": false },
      "default": { "ios": false, "android": false }
    },
    "checkout_urls": {
      "ios_default":     "https://checkout.yourapp.com/ios",
      "android_default": "https://checkout.yourapp.com/android"
    }
  }
}

Gate Logic with Per-Region Config

TypeScript billingGate.ts
type BillingMode = 'web' | 'iap';

function getBillingMode(
  countryCode: string,
  platform: 'ios' | 'android',
  config: WebCheckoutConfig
): BillingMode {
  const regionConfig =
    config.enabled_regions[countryCode] ??
    config.enabled_regions['default'];

  return regionConfig[platform] ? 'web' : 'iap';
}

// Usage in PaywallGate
const mode = getBillingMode(storefront.countryCode, platform, config);

if (mode === 'web') {
  return <WebCheckoutButton url={config.checkout_urls[`${platform}_default`]} />;
}
return <IAPPaywall />;

Fee Comparison Across All Regions

At 10,000 subscribers paying $9.99/month, the difference between IAP and web is $324K annually. Every percentage point of effective rate matters. This table shows the real cost of each path - platform fee plus payment processor.

Region + Platform Method Platform Fee Effective Rate
US iOS (web) Stripe checkout 0% Apple ~3%
US iOS (IAP) Apple IAP 15–30% Apple 15–30%
US Android (ECLP) Stripe + ECLP 10% Google (future) ~13%
US Android (IAP) Google Play Billing 15–30% Google 15–30%
EU Apple (DMA) Stripe + DMA 5–13% Apple ~8–16%
EU Google (DMA) Stripe + DMA 10% Google (subs) ~13%
Rest of World IAP only 15–30% 15–30%

Multi-Region Kill Switch Strategy

Each region and platform has independent policy risk. EU Apple introduced an unexpected fee change. Google ECLP deadlines shifted. Japan's timeline is still unclear. Your kill switch architecture needs to be per-region, per-platform - not a single global flag.

When EU introduces a new fee you didn't plan for, you disable web for EU Apple, keep it for US iOS and EU Google. No app update. No emergency release. The config structure above handles this - each key in enabled_regions is an independent switch.

1 hr
Recommended TTL for remote config cache
0
App Store releases needed to disable a region
~5 min
Time from flag change to propagation (Firebase)

Log which region and billing mode each user sees

Tag every paywall impression event with storefront_country, billing_mode, and platform. When a policy changes, you need to know exactly how many users are affected before you flip the flag. You'll also need this data for compliance audits in the EU.

Official Documentation

Want a custom expansion roadmap for your app?

Let's talk through your stack, current regions, and the fastest path to each new platform.

Book a 15-min Call →