Salta al contenuto principale
Tutorial

Stripe Payments in Capacitor: nuove linee guida Apple

Scopri come implementare gli Stripe Payment Links nella tua app Capacitor per gestire i pagamenti di beni digitali in conformità con le nuove linee guida Apple dal 1° maggio 2025.

Stripe Payments in Capacitor: nuove linee guida Apple

Implementare Stripe Payment Links in app Capacitor seguendo le nuove linee guida Apple

A partire dal 1° maggio 2025, Apple ha introdotto cambiamenti significativi alle App Store Review Guidelines a seguito della sentenza nel caso Epic v. Apple. Queste modifiche consentono specificamente agli sviluppatori negli Stati Uniti di collegare metodi di pagamento esterni per beni e servizi digitali, offrendo alternative al sistema di acquisto in-app di Apple.

La battaglia epica che ha cambiato per sempre i pagamenti mobile

Il percorso verso questo momento è stato lungo e travagliato. Tutto è iniziato nell'agosto 2020, quando Epic Games, la casa produttrice del popolarissimo Fortnite, ha violato deliberatamente le linee guida dell'App Store di Apple implementando un'opzione di pagamento diretto per aggirare la commissione del 30% di Apple. Apple ha rimosso immediatamente Fortnite dall'App Store, e Epic ha risposto avviando una causa legale per contestare il controllo di Apple sulla distribuzione delle app iOS e sui pagamenti in-app.

Dopo anni di battaglie legali, appelli e contro-appelli, i tribunali hanno finalmente stabilito che Apple deve consentire agli sviluppatori di indirizzare gli utenti verso metodi di pagamento alternativi al di fuori delle loro app. Questa decisione cambia radicalmente l'economia dell'ecosistema App Store, che opera con lo stesso modello finanziario sin dalla sua nascita nel 2008.

La sentenza definitiva: niente più appelli

Ciò che rende questa sentenza particolarmente significativa è che è definitiva e non può essere ulteriormente impugnata. La Corte Suprema ha rifiutato di esaminare l'appello di Apple all'inizio del 2025, confermando la decisione del tribunale inferiore come legge vigente. Ciò significa che gli sviluppatori possono implementare metodi di pagamento esterni con la certezza che Apple non potrà ribaltare questa decisione con ulteriori azioni legali.

Trattamento paritario garantito dalla legge

La cosa più importante è che la sentenza stabilisce esplicitamente che Apple non può discriminare le app che utilizzano metodi di pagamento esterni. La corte ha specificamente vietato ad Apple di:

  1. Applicare commissioni aggiuntive o imporre requisiti extra alle app che usano metodi di pagamento esterni
  2. Favorire nei risultati di ricerca o in evidenza le app che usano esclusivamente il sistema IAP di Apple
  3. Usare misure tecniche per rendere l'esperienza di pagamento esterna inferiore rispetto al sistema di Apple
  4. Imporre requisiti di trasparenza eccessivi oltre le informazioni di base sul consumatore

Queste protezioni esplicite permettono agli sviluppatori di implementare Stripe o altri provider esterni senza temere ritorsioni o discriminazioni da parte di Apple. Il campo di gioco è stato livellato legalmente: Apple deve trattare tutte le app allo stesso modo, indipendentemente dal metodo di pagamento scelto.

La sentenza rappresenta una delle sfide più significative all'approccio 'walled garden' di Apple e segna un cambiamento cruciale nella monetizzazione delle app mobile. Per gli sviluppatori che da tempo lamentano la commissione del 30% di Apple (ridotta al 15% per le piccole imprese), questa decisione offre una via verso margini di profitto più alti e un maggiore controllo sulla customer experience.

Vantaggi finanziari nell'usare Stripe rispetto agli acquisti in-app di Apple

Le implicazioni finanziarie di questo cambiamento sono sostanziali per gli sviluppatori:

  • Commissioni di pagamento ridotte: Apple solitamente trattiene una commissione del 30% sugli acquisti in-app (15% per le piccole imprese), mentre la fee di Stripe è di circa il 2,9% + $0,30 per transazione. Questa differenza può aumentare significativamente i tuoi margini di revenue.

  • Payout più rapidi: Con Apple, solitamente si attendono dai 45 ai 90 giorni per ricevere i fondi. Stripe, invece, accredita i pagamenti sul conto bancario entro 2-3 giorni lavorativi.

  • Processo di rimborso semplificato: Gestisci i rimborsi direttamente dalla dashboard di Stripe, evitando il sistema di rimborso più complesso di Apple.

Questi risparmi e il miglioramento del cash flow possono fare la differenza, specialmente per i piccoli sviluppatori e le aziende.

In questo articolo vedremo come implementare gli Stripe Payment Links nella tua app Capacitor per sfruttare queste nuove regole, garantendo al contempo la conformità con le linee guida aggiornate.

Questa implementazione si basa sulla documentazione ufficiale di Stripe per i Payment Links, adattata appositamente per le app Capacitor.

Capire le nuove linee guida

Le App Store Review Guidelines aggiornate ora permettono agli sviluppatori di indirizzare gli utenti verso siti web esterni per il pagamento, in particolare per beni digitali e abbonamenti. Al momento questa modifica vale solo per le app distribuite nell'App Store degli Stati Uniti.

Punti chiave da capire:

  1. Ora puoi collegare opzioni di pagamento esterne per i beni digitali all'interno della tua app
  2. Si applica solo alle app nell'App Store degli Stati Uniti
  3. Devi comunque rispettare i requisiti di trasparenza di Apple
  4. Rimani responsabile di tutto il supporto clienti e della gestione dei rimborsi

Vediamo subito l'implementazione tecnica:

Per prima cosa, crea un link di pagamento nella tua dashboard di Stripe:

  1. Vai alla sezione Payment Links nella tua dashboard di Stripe
  2. Clicca su “+ New” per creare un nuovo link di pagamento
  3. Definisci i dettagli del prodotto o dell'abbonamento
  4. Nelle impostazioni “After payment”, seleziona “Don’t show confirmation page”
  5. Imposta un universal link come URL di successo (lo configureremo più tardi)
  6. Clicca su “Create Link” per generare il tuo link di pagamento

Per reindirizzare gli utenti alla tua app dopo il pagamento, configura gli universal links:

  1. Crea un file apple-app-site-association sul tuo dominio:
{
  "applinks": {
    "apps": [],
    "details": [
      {
        "appIDs": ["YOURTEAMID.com.yourdomain.yourapp"],
        "components": [
          {
            "/": "/checkout_redirect*",
            "comment": "Matches any URL whose path starts with /checkout_redirect"
          }
        ]
      }
    ]
  }
}
  1. Carica questo file su https://yourdomain.com/.well-known/apple-app-site-association

  2. Assicurati che venga servito con il MIME type corretto application/json

  3. Configura la tua app Capacitor per gestire gli universal links aggiungendo l'entitlement corretto. Per prima cosa, nel tuo capacitor.config.ts:

import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  // Your existing app configuration (appId, appName, etc.)
  plugins: {
    Geolocation: {
      // Request precise location access on iOS
      iosLocationAccuracy: 'reduced'
    }
  }
};

export default config;
  1. Aggiungi l'entitlement Associated Domains al tuo progetto Xcode:
    • Apri il tuo progetto Xcode
    • Seleziona il target della tua app
    • Vai su “Signing & Capabilities”
    • Clicca su “+ Capability” e seleziona “Associated Domains”
    • Aggiungi applinks:yourdomain.com

Passaggio 3: Crea una pagina di fallback

Crea una pagina di fallback all'URL di redirect per gestire i casi in cui l'app non è installata:

<!DOCTYPE html>
<html>
<head>
  <title>Redirecting...</title>
  <meta http-equiv="refresh" content="0;url=https://yourdomain.com/app-download">
</head>
<body>
  <p>Redirecting to download page...</p>
</body>
</html>

Passaggio 4: Implementa il tasto di pagamento nella tua app Capacitor

Ora, aggiungi il tasto di pagamento alla tua app:

import { Capacitor } from '@capacitor/core';

export async function openPaymentLink(userEmail, userId) {
  // Use your actual Stripe payment link
  const baseUrl = 'https://buy.stripe.com/your_payment_link';
  
  // Add URL parameters to customize the experience
  const params = new URLSearchParams({
    prefilled_email: encodeURIComponent(userEmail),
    client_reference_id: userId
  });

  const fullUrl = `${baseUrl}?${params.toString()}`;
  
  // Simple window.open works in both web and Capacitor
  // Using _blank opens in Safari on iOS which is important for users with saved Stripe Link credentials
  window.open(fullUrl, '_blank');
}

Perché Safari è importante: Aprire il link di pagamento in Safari (tramite window.open) invece di un browser in-app è vantaggioso perché gli utenti che hanno già salvato i dati di pagamento con Stripe Link avranno le credenziali disponibili automaticamente. Questo garantisce un checkout più fluido, senza dover reinserire i dati della carta, riducendo drasticamente attrito e abbandoni.

Configura la tua app per gestire i universal links quando gli utenti vengono reindirizzati:

  1. Per prima cosa, installa il plugin App:
npm install @capacitor/app
  1. Registra il plugin App nella tua app:
import { App } from '@capacitor/app';

// In your initialization code
App.addListener('appUrlOpen', (event) => {
  // Example URL: https://yourdomain.com/checkout_redirect?session_id=cs_test_...
  const url = new URL(event.url);
  
  if (url.pathname.startsWith('/checkout_redirect')) {
    // Extract any parameters you need
    const params = new URLSearchParams(url.search);
    const sessionId = params.get('session_id');
    
    // Handle successful payment
    if (sessionId) {
      // Verify the payment on your server if needed
      verifyPayment(sessionId);
      
      // Update UI to reflect successful purchase
      updatePurchaseStatus(true);
    }
  }
});

async function verifyPayment(sessionId) {
  // Call your backend to verify the payment
  // This is optional if you're relying on webhooks
}

function updatePurchaseStatus(success) {
  // Update your app UI to reflect purchase status
}

Passaggio 6: Configura il webhook per l'ordine

Infine, configura un webhook sul tuo server per gestire i pagamenti riusciti:

// Using Express.js as an example
const express = require('express');
const stripe = require('stripe')('sk_test_your_stripe_secret_key');
const app = express();

// Use raw body parser for webhook signature verification
app.post('/webhook', express.raw({type: 'application/json'}), async (req, res) => {
  const sig = req.headers['stripe-signature'];
  const webhookSecret = 'whsec_your_webhook_secret';
  
  let event;
  
  try {
    event = stripe.webhooks.constructEvent(req.body, sig, webhookSecret);
  } catch (err) {
    console.log(`Webhook Error: ${err.message}`);
    return res.status(400).send(`Webhook Error: ${err.message}`);
  }
  
  // Handle the checkout.session.completed event
  if (event.type === 'checkout.session.completed') {
    const session = event.data.object;
    
    // Retrieve client_reference_id (your user ID)
    const userId = session.client_reference_id;
    
    // Grant access to the purchased content
    await grantAccess(userId, session.id);
  }
  
  res.status(200).send();
});

async function grantAccess(userId, sessionId) {
  // Your logic to grant access to the purchased content
  // This could be updating a database, sending a notification, etc.
}

app.listen(3000, () => console.log('Webhook server running on port 3000'));

Compatibilità Android

Sia chiaro: la sentenza Epic v. Apple ha cambiato radicalmente il panorama dei pagamenti mobile. Non solo impatta direttamente le app iOS, ma rafforza anche la posizione degli sviluppatori Android che utilizzano metodi di pagamento esterni.

Gli sviluppatori Android possono ora implementare soluzioni di pagamento esterne con totale fiducia. Il precedente stabilito dalla sentenza Apple protegge efficacemente gli sviluppatori su tutte le piattaforme da potenziali restrizioni future. Questa decisione giudiziaria ha convalidato ciò che molti sviluppatori Android fanno da anni: offrire opzioni di pagamento alternative con commissioni inferiori.

Il Play Store di Google è sempre stato meno restrittivo sui metodi di pagamento esterni rispetto ad Apple e ora, con il precedente legale stabilito, non c'è praticamente alcun rischio nell'implementare Stripe o altri provider esterni nelle tue app Android. Puoi procedere con queste implementazioni sapendo di avere basi legali solide.

L'implementazione che abbiamo visto per iOS funziona in modo quasi identico sui dispositivi Android. Poiché il Google Play Store non ha le stesse restrizioni sui metodi di pagamento esterni, puoi usare lo stesso approccio con gli Stripe Payment Links senza dover gestire dialoghi di informativa specifici.

Per gestire il deep linking (equivalente agli universal links su iOS), dovrai:

  1. Configura gli App Links nel tuo AndroidManifest.xml per gestire l'URL di redirect
  2. Crea un .well-known/assetlinks.json file sul tuo dominio con i dettagli dell'app
  3. Usa la stessa appUrlOpen logica del listener per gestire i pagamenti riusciti

Il vantaggio di Capacitor è che, una volta implementate le configurazioni specifiche per piattaforma, il flusso di pagamento code rimane identico su entrambe le piattaforme.

Creare una UI di pagamento

Ecco un esempio di un componente per il pulsante di pagamento in Vue da aggiungere alla tua app Capacitor:

<template>
  <div class="payment-container">
    <div class="pricing-card">
      <h2 class="mb-4 text-xl font-bold">{{ product.name }}</h2>
      <p class="mb-6 text-gray-600">{{ product.description }}</p>
      <div class="mb-6 price-tag">
        <span class="text-2xl font-bold">${{ product.price }}</span>
        <span v-if="product.isSubscription" class="text-sm text-gray-500">/month</span>
      </div>
      <button 
        @click="handlePayment" 
        class="py-3 w-full font-medium text-white bg-indigo-600 rounded-lg transition-colors hover:bg-indigo-700"
      >
        Purchase Now
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue';
import { Dialog } from '@capacitor/dialog';

const props = defineProps({
  product: {
    type: Object,
    required: true
  },
  userEmail: {
    type: String,
    default: ''
  },
  userId: {
    type: String,
    required: true
  }
});

const isLoading = ref(false);

async function showExternalPaymentDisclosure() {
  const { value } = await Dialog.confirm({
    title: 'Leaving App for Payment',
    message: 'You are about to leave this app to make a payment. Apple is not responsible for the privacy or security of payments that are not made through the App Store. All payment-related issues, including refunds, must be handled by our support team.',
    okButtonTitle: 'Continue',
    cancelButtonTitle: 'Cancel'
  });
  
  return value;
}

async function openPaymentLink() {
  // Use your actual Stripe payment link
  const baseUrl = 'https://buy.stripe.com/your_payment_link';
  
  // Add URL parameters to customize the experience
  const params = new URLSearchParams({
    prefilled_email: encodeURIComponent(props.userEmail),
    client_reference_id: props.userId
  });

  const fullUrl = `${baseUrl}?${params.toString()}`;
  
  // Simple window.open works in both web and Capacitor
  // Using _blank opens in Safari on iOS which is important for users with saved Stripe Link credentials
  window.open(fullUrl, '_blank');
}

async function handlePayment() {
  isLoading.value = true;
  try {
    // Only show the disclosure on iOS
    if (window.Capacitor?.getPlatform() === 'ios') {
      const userConfirmed = await showExternalPaymentDisclosure();
      if (!userConfirmed) return;
    }
    
    await openPaymentLink();
  } catch (error) {
    console.error('Payment error:', error);
    await Dialog.alert({
      title: 'Payment Error',
      message: 'There was an error initiating the payment. Please try again.'
    });
  } finally {
    isLoading.value = false;
  }
}
</script>

Gestire diverse regioni

Poiché le nuove linee guida Apple si applicano solo alle app nell'App Store degli Stati Uniti, avrai bisogno di una strategia per rilevare la regione dell'utente e applicare il metodo di pagamento corretto. Ecco un approccio più affidabile tramite geolocalizzazione IP:

import { Capacitor } from '@capacitor/core';

async function determinePaymentMethod() {
  // Always use Stripe for Android
  if (Capacitor.getPlatform() !== 'ios') {
    return 'external';
  }
  
  try {
    // Use a geolocation service to determine user's country
    const response = await fetch('https://ipapi.co/json/');
    const locationData = await response.json();
    
    // Check if the user is in the United States
    if (locationData.country_code === 'US') {
      return 'external'; // Can use Stripe Payment Links
    } else {
      return 'iap'; // Must use In-App Purchases
    }
  } catch (error) {
    console.error('Error detecting region:', error);
    return 'iap'; // Default to IAP to be safe
  }
}

export async function processPayment(product, userEmail, userId) {
  const paymentMethod = await determinePaymentMethod();
  
  if (paymentMethod === 'external') {
    // Use Stripe Payment Links
    await initiateExternalPayment(userEmail, userId);
  } else {
    // Use Apple's In-App Purchase
    await initiateInAppPurchase(product.appleProductId);
  }
}

Questo approccio utilizza il servizio gratuito ipapi.co servizio per determinare il paese dell'utente in base al suo indirizzo IP. Potresti anche usare altri servizi di geolocalizzazione come MaxMind, o implementare questo controllo lato server per una maggiore sicurezza.

Nota: Sebbene questo approccio funzioni, ricorda che la geolocalizzazione tramite IP non è sempre accurata al 100%. Per applicazioni mission-critical, considera l'uso di più metodi di rilevamento o permetti agli utenti di selezionare manualmente la propria regione.

Rilevamento della posizione più accurato con i plugin Capacitor

Per un rilevamento della posizione più preciso, puoi usare il plugin Capacitor Geolocation insieme a @capgo/capacitor-nativegeocoder per determinare il paese dell'utente con maggiore accuratezza:

  1. Per prima cosa, installa i plugin necessari:
npm install @capacitor/geolocation @capgo/capacitor-nativegeocoder
  1. Configura i plugin nel tuo progetto Capacitor. Aggiungi quanto segue al tuo capacitor.config.ts:
import { CapacitorConfig } from '@capacitor/cli';

const config: CapacitorConfig = {
  // Your existing app configuration (appId, appName, etc.)
  plugins: {
    Geolocation: {
      // Request precise location access on iOS
      iosLocationAccuracy: 'reduced'
    }
  }
};

export default config;
  1. Implementa il rilevamento della regione basato sulla posizione:
import { Capacitor } from '@capacitor/core';
import { Geolocation } from '@capacitor/geolocation';
import { NativeGeocoder } from '@capgo/capacitor-nativegeocoder';

async function isUserInUSA() {
  try {
    // Request permission first
    const permissionStatus = await Geolocation.requestPermissions();
    
    if (permissionStatus.location === 'granted') {
      // Get current position
      const position = await Geolocation.getCurrentPosition({
        timeout: 10000,
        enableHighAccuracy: false
      });
      
      // Use NativeGeocoder to reverse geocode the coordinates
      const results = await NativeGeocoder.reverseGeocode({
        latitude: position.coords.latitude,
        longitude: position.coords.longitude,
        useLocale: true,
        maxResults: 1
      });
      
      if (results.addresses.length > 0) {
        // Check if the user is in the USA
        return results.addresses[0].countryCode === 'US';
      }
    }
    
    // If we couldn't determine location or permission denied, fall back to IP detection
    return await isUserInUSAByIP();
  } catch (error) {
    console.error('Error detecting location:', error);
    // Fall back to IP detection on error
    return await isUserInUSAByIP();
  }
}

async function isUserInUSAByIP() {
  try {
    const response = await fetch('https://ipapi.co/json/');
    const data = await response.json();
    return data.country_code === 'US';
  } catch (error) {
    console.error('Error detecting IP location:', error);
    return false; // Default to false to be safe
  }
}

export async function determinePaymentMethod() {
  // Always use Stripe for Android
  if (Capacitor.getPlatform() !== 'ios') {
    return 'external';
  }
  
  // Check if user is in the USA
  const isUSA = await isUserInUSA();
  return isUSA ? 'external' : 'iap';
}

export async function processPayment(product, userEmail, userId) {
  const paymentMethod = await determinePaymentMethod();
  
  if (paymentMethod === 'external') {
    // Use Stripe Payment Links
    await initiateExternalPayment(userEmail, userId);
  } else {
    // Use Apple's In-App Purchase
    await initiateInAppPurchase(product.appleProductId);
  }
}

Questa implementazione offre un modo più accurato per determinare se un utente si trova fisicamente negli Stati Uniti. Tenta prima di usare il GPS del dispositivo e il geocoder nativo per determinare il paese. Se fallisce (per problemi di permessi o altri errori), passa al rilevamento basato su IP.

Ricordati di aggiungere i permessi necessari ai tuoi file info.plist (iOS) e AndroidManifest.xml file (Android):

Per iOS (ios/App/App/Info.plist):

<key>NSLocationWhenInUseUsageDescription</key>
<string>We need your location to determine which payment method to use based on regional availability.</string>

Per Android (android/app/src/main/AndroidManifest.xml):

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Questo approccio è il modo più preciso per determinare se un utente ha diritto a opzioni di pagamento esterne secondo le nuove linee guida Apple.

Gestione degli Abbonamenti

Un grande vantaggio di Stripe è la possibilità di offrire e gestire abbonamenti. Ecco come gestire gli abbonamenti nella tua app Capacitor:

1. Creare una pagina di gestione abbonamenti

Aggiungi una pagina di gestione abbonamenti nella tua app per mostrare gli abbonamenti attivi dell'utente:

<template>
  <div class="subscription-manager">
    <div v-if="isLoading" class="loading-indicator">
      Loading subscription data...
    </div>
    
    <div v-else-if="subscription" class="subscription-info">
      <h2 class="mb-4 text-xl font-bold">Your Subscription</h2>
      
      <div class="mb-6 plan-details">
        <p><span class="font-medium">Plan:</span> {{ subscription.planName }}</p>
        <p><span class="font-medium">Status:</span> {{ subscription.status }}</p>
        <p><span class="font-medium">Renews:</span> {{ formatDate(subscription.currentPeriodEnd) }}</p>
      </div>
      
      <button 
        @click="manageSubscription" 
        class="py-3 w-full font-medium text-white bg-indigo-600 rounded-lg transition-colors hover:bg-indigo-700"
      >
        Manage Subscription
      </button>
    </div>
    
    <div v-else class="no-subscription">
      <p class="mb-4">You don't have an active subscription.</p>
      <button 
        @click="goToPricingPage" 
        class="py-3 w-full font-medium text-white bg-indigo-600 rounded-lg transition-colors hover:bg-indigo-700"
      >
        View Plans
      </button>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import { getUserSubscription } from '../services/subscription';

const subscription = ref(null);
const isLoading = ref(true);

onMounted(async () => {
  try {
    const userData = await getUserSubscription();
    subscription.value = userData.subscription;
  } catch (error) {
    console.error('Failed to load subscription:', error);
  } finally {
    isLoading.value = false;
  }
});

function formatDate(timestamp) {
  return new Date(timestamp * 1000).toLocaleDateString();
}

function manageSubscription() {
  // Open Stripe Customer Portal
  window.open(subscription.value.portalUrl, '_blank');
}

function goToPricingPage() {
  // Navigate to pricing page
  // router.push('/pricing');
}
</script>

2. Customer Portal per la gestione degli abbonamenti

Stripe offre un Customer Portal che permette agli utenti di gestire i propri abbonamenti. Puoi creare un link a questo portale dal tuo server:

// Server-side code (Node.js)
const stripe = require('stripe')('sk_your_stripe_secret_key');

async function createPortalSession(customerId) {
  const session = await stripe.billingPortal.sessions.create({
    customer: customerId,
    return_url: 'https://yourdomain.com/account',
  });
  
  return session.url;
}

Garantire la conformità con l'App Store

Per garantire che la tua implementazione sia conforme alle linee guida di Apple:

  1. Includi le informative corrette sugli acquisti esterni
  2. Implementa un modal sheet per informare gli utenti che stanno uscendo dall'app (come richiesto da Apple)
  3. Non tentare di aggirare la commissione di Apple sugli acquisti effettuati all'interno dell'app
  4. Comunica chiaramente agli utenti che Apple non è responsabile della transazione

Ecco un esempio di come implementare il modal di informativa richiesto:

import { Dialog } from '@capacitor/dialog';

async function showExternalPaymentDisclosure() {
  const { value } = await Dialog.confirm({
    title: 'Leaving App for Payment',
    message: 'You are about to leave this app to make a payment. Apple is not responsible for the privacy or security of payments that are not made through the App Store. All payment-related issues, including refunds, must be handled by our support team.',
    okButtonTitle: 'Continue',
    cancelButtonTitle: 'Cancel'
  });
  
  return value;
}

export async function initiateExternalPayment(userEmail, userId) {
  const userConfirmed = await showExternalPaymentDisclosure();
  
  if (userConfirmed) {
    await openPaymentLink(userEmail, userId);
  }
}

Test della tua implementazione

Per testare la tua implementazione:

  1. Clicca sul pulsante di pagamento nell'app: dovrebbe apparire l'informativa e poi aprirsi la pagina di pagamento Stripe
  2. Completa un pagamento di test usando una carta di test Stripe 4242 4242 4242 4242
  3. Dopo il pagamento, dovresti essere reindirizzato alla tua app tramite il universal link
  4. Verifica che il tuo webhook abbia ricevuto il checkout.session.completed evento

Conclusione

La possibilità di usare metodi di pagamento esterni per beni digitali nelle app iOS è un cambiamento importante che offre maggiore flessibilità agli sviluppatori. Anche se al momento riguarda solo le app nell'App Store degli Stati Uniti, rappresenta un'alternativa fondamentale al sistema di acquisti in-app di Apple.

Utilizzando gli Stripe Payment Links con Capacitor, puoi implementare rapidamente un checkout fluido rispettando le linee guida di Apple. Per gli utenti al di fuori degli Stati Uniti, dove il sistema di acquisti in-app di Apple è ancora obbligatorio, @capgo/native-purchases implementa direttamente StoreKit e Google Play Billing. Questo approccio ti offre anche i vantaggi dell'infrastruttura di pagamento di Stripe, commissioni di elaborazione più basse (3% vs 30%) e payout molto più rapidi (giorni invece di mesi) rispetto al sistema di Apple.

Ricorda che dovrai gestire direttamente tutto l'assistenza clienti e i rimborsi, poiché queste transazioni avvengono al di fuori dell'ecosistema Apple.

Hai già implementato gli Stripe Payment Links nella tua app Capacitor? Condividi la tua esperienza nei commenti qui sotto!

FAQ

D: Questo approccio è conforme alle linee guida di Apple?
R: Sì, a partire dal 1° maggio 2025, Apple consente il link a metodi di pagamento esterni per beni e servizi digitali nelle app distribuite nell'App Store degli Stati Uniti, a patto di includere le informative richieste.

D: Devo pagare la commissione di Apple se uso metodi di pagamento esterni?
D: No, uno dei principali vantaggi delle nuove regole è che i pagamenti elaborati al di fuori del sistema Apple non sono soggetti alla loro commissione.

D: La mia azienda deve avere sede negli Stati Uniti per approfittare di queste nuove regole?
D: No, qualsiasi azienda nel mondo può implementare metodi di pagamento esterni, purché l'app sia disponibile nell'App Store degli Stati Uniti e gli utenti che effettuano gli acquisti si trovino negli Stati Uniti. La normativa si applica al marketplace (US App Store) e alla posizione degli utenti, non alla sede della tua azienda. Ciò significa che gli sviluppatori in Europa, Asia, Sud America o altrove possono implementare gli Stripe Payment Links per i propri clienti negli Stati Uniti.

D: Cosa succede se un utente al di fuori degli Stati Uniti prova a usare l'opzione di pagamento esterna?
D: Dovresti implementare il rilevamento della regione (come mostrato nell'articolo) per offrire opzioni di pagamento esterne solo agli utenti negli Stati Uniti. Per le altre regioni, dovrai continuare a usare il sistema di acquisto in-app di Apple.

D: Posso usarlo per beni fisici o servizi consumati al di fuori dell'app?
D: Sì, Apple ha sempre permesso metodi di pagamento esterni per beni fisici e servizi consumati al di fuori dell'app (come il ride-sharing o il food delivery).

Continua con Stripe Payments in Capacitor: Nuove linee guida Apple

Se stai usando Stripe Payments in Capacitor: nuove linee guida Apple per pianificare sicurezza e compliance, collegalo a Crittografia per i dettagli di implementazione in Encryption, Conformità per i dettagli di implementazione in Compliance, Scanner di sicurezza Capgo per il workflow di Capgo Security Scanner, Sicurezza Capgo per il workflow di Capgo Security, e Trust Center di Capgo per il workflow di Capgo Trust Center.

Live update per le app Capacitor

Quando un bug del web layer è live, rilascia il fix tramite Capgo invece di aspettare giorni per l'approvazione degli store. Gli utenti ricevono l'update in background, mentre le modifiche native restano nel normale percorso di review.

Le ultime dal nostro blog

Capgo ti offre i migliori insight per creare un'app mobile davvero professionale.