Stripe Payment Links in Capacitor-Apps gemäß den neuen Apple-Richtlinien
Seit dem 1. Mai 2025 hat Apple erhebliche Änderungen an seinen App Store Review Guidelines vorgenommen, nachdem das Gericht im Fall Epic v. Appleentschieden hatte. Diese Änderungen erlauben es App-Entwicklern in den USA nun, auf externe Zahlungsmethoden für digitale Güter und Dienste zu verlinken und damit Alternativen zum In-App-Kauf-System von Apple zu schaffen.
Der Epic-Kampf, der die mobilen Zahlungen für immer veränderte
Der Weg zu diesem Moment war lang und umstritten. Alles begann im August 2020, als Epic Games, der Entwickler des extrem beliebten Spiels Fortnite, die App Store-Richtlinien von Apple bewusst missachtete, indem es eine direkte Zahlungsoption einführte, die die 30%-Provision von Apple umging. Apple entfernte Fortnite umgehend aus dem App Store, woraufhin Epic eine Klage einreichte, die die Kontrolle von Apple über die iOS-App-Verteilung und In-App-Zahlungen in Frage stellte.
Nach jahrelangen Rechtsstreitigkeiten, Berufungen und Gegenberufungen haben die Gerichte endlich entschieden, dass Apple Entwickler dazu zwingen muss, Nutzer auf alternative Zahlungsmethoden außerhalb ihrer Apps zu verweisen. Diese Entscheidung verändert die Ökonomie des App-Store-Ökosystems grundlegend, das seit seiner Einführung 2008 nach demselben grundlegenden Finanzmodell funktioniert.
Das endgültige Urteil – Keine weiteren Berufungen
Was dieses Urteil besonders bedeutsam macht, ist, dass es endgültig ist und nicht weiter angefochten werden kann. Der Supreme Court hat Anfang 2025 die Berufung von Apple abgelehnt und damit die Entscheidung des unteren Gerichts zum geltenden Recht gemacht. Das bedeutet, dass Entwickler externe Zahlungsmethoden mit der Gewissheit implementieren können, dass Apple diese Entscheidung nicht durch weitere rechtliche Schritte rückgängig machen kann.
Gleichbehandlung durch das Gesetz garantiert
Wichtig ist, dass das Urteil ausdrücklich feststellt, dass Apple Apps, die externe Zahlungsmethoden nutzen, nicht diskriminieren darf. Das Gericht hat Apple konkret davon abgehalten:
- Zusätzliche Gebühren zu erheben oder zusätzliche Anforderungen an Apps zu stellen, die externe Zahlungsmethoden nutzen
- Apps, die ausschließlich das IAP-System von Apple nutzen, in Suchergebnissen oder bei Empfehlungen bevorzugt zu behandeln
- Technische Maßnahmen zu ergreifen, um externe Zahlungserlebnisse im Vergleich zum eigenen System von Apple zu verschlechtern
- Übermäßige Offenlegungspflichten über grundlegende Verbraucherinformationen hinaus aufzuerlegen
Diese expliziten Schutzmaßnahmen bedeuten, dass Entwickler Stripe oder andere externe Zahlungsanbieter implementieren können, ohne sich vor subtiler Vergeltung oder Diskriminierung durch Apple fürchten zu müssen. Das Spielfeld ist rechtlich geebnet, und Apple muss alle Apps gleich behandeln, unabhängig von der gewählten Zahlungsmethode.
Das Urteil stellt eine der bedeutendsten Herausforderungen für den Ansatz von Apples ummauertem Garten dar und markiert einen Wendepunkt dafür, wie die Monetarisierung mobiler Apps funktionieren kann. Für Entwickler, die sich lange über die 30% Provision von Apple beschwert haben (reduziert auf 15% für kleine Unternehmen), bietet dieses Urteil einen Weg zu höheren Gewinnmargen und mehr Kontrolle über das Kundenerlebnis.
Finanzielle Vorteile der Nutzung von Stripe gegenüber Apples In-App-Käufen
Die finanziellen Auswirkungen dieser Änderung sind für Entwickler erheblich:
-
Reduzierte Zahlungsgebühren: Apple berechnet typischerweise eine 30% Provision auf In-App-Käufe (15% für kleine Unternehmen), während die Gebühr von Stripe nur etwa 2,9% + 0,30 $ pro Transaktion beträgt. Dieser Unterschied kann Ihre Umsatzmargen erheblich steigern.
-
Schnellere Auszahlungen: Bei Apple müssen Sie typischerweise 45-90 Tage warten, bis Sie Ihr Geld erhalten. Stripe überweist Zahlungen hingegen innerhalb von 2-3 Werktagen auf Ihr Bankkonto.
-
Vereinfachter Erstattungsprozess: Bearbeiten Sie Erstattungen direkt über das Dashboard von Stripe, anstatt das komplexere Erstattungssystem von Apple zu durchlaufen.
Diese Kosteneinsparungen und die verbesserte Liquidität können einen entscheidenden Unterschied machen, insbesondere für kleinere Entwickler und Unternehmen.
In diesem Artikel zeigen wir, wie du Stripe Payment Links in deiner Capacitor-App implementierst, um von diesen neuen Regeln zu profitieren und gleichzeitig die Compliance mit Apples aktualisierten Richtlinien.
Diese Implementierung basiert auf Stripes offizieller Dokumentation zu Payment Links, speziell angepasst für Capacitor-Apps.
Die neuen Richtlinien verstehen
Die aktualisierten App Store Review Guidelines erlauben es Entwicklern nun, Nutzer zu externen Websites für die Zahlungsabwicklung zu leiten, insbesondere für digitale Güter und Abonnements. Diese Änderung gilt derzeit nur für Apps, die im US-App Store vertrieben werden.
Wichtige Punkte zum Verständnis:
- Du kannst nun in deiner App auf externe Zahlungsoptionen für digitale Güter verlinken
- Dies gilt nur für Apps im US-App Store
- Du musst weiterhin Apples Offenlegungspflichten einhalten
- You remain responsible for all customer support and refund handling
Stripe Payment Links in deiner Capacitor-App einrichten
Lass uns die technische Implementierung durchgehen:
Schritt 1: Payment Link im Stripe Dashboard erstellen
Erstelle zuerst einen Payment Link in deinem Stripe Dashboard:
- Gehe im Stripe Dashboard zum Bereich „Payment Links“
- Klicke auf „+ Neu“, um einen neuen Payment Link zu erstellen
- Definiere die Details deines Produkts oder Abonnements
- Wähle unter den Einstellungen „Nach Zahlung“ die Option „Keine Bestätigungsseite anzeigen“
- Setze einen Universal Link als Erfolgs-URL (wir konfigurieren das später)
- Klicke auf „Link erstellen“, um deinen Payment Link zu generieren
Schritt 2: Universal Links in deiner Capacitor-App einrichten
Um Nutzer nach Abschluss der Zahlung zurück in deine App zu leiten, konfiguriere Universal Links:
- Erstelle ein
apple-app-site-associationDatei auf Ihrer Domain:
{
"applinks": {
"apps": [],
"details": [
{
"appIDs": ["YOURTEAMID.com.yourdomain.yourapp"],
"components": [
{
"/": "/checkout_redirect*",
"comment": "Matches any URL whose path starts with /checkout_redirect"
}
]
}
]
}
}
-
Bereitstellen dieser Datei unter
https://yourdomain.com/.well-known/apple-app-site-association -
Stellen Sie sicher, dass es mit dem korrekten MIME-Typ ausgeliefert wird
application/json -
Konfigurieren Sie Ihre Capacitor-App, um Universal Links zu verarbeiten, indem Sie die entsprechende Berechtigung hinzufügen. Zuerst in Ihrer
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;
- Fügen Sie die Berechtigung „Associated Domains“ zu Ihrem Xcode-Projekt hinzu:
- Xcode-Projekt öffnen
- App-Ziel auswählen
- Zu „Signing & Capabilities“ gehen
- Auf „+ Capability“ klicken und „Associated Domains“ auswählen
- Füge
applinks:yourdomain.com
Schritt 3: Fallback-Seite erstellen
Erstelle eine Fallback-Seite unter der Redirect-URL, um Fälle abzudecken, in denen die App nicht installiert ist:
<!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>
Schritt 4: Implementiere den Zahlungsbutton in deiner Capacitor App
Füge nun den Zahlungsbutton zu deiner App hinzu:
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');
}
Warum Safari wichtig ist: Das Öffnen des Zahlungslinks in Safari (via
window.open) anstatt in einem In-App-Browser ist von Vorteil, da Nutzer, die ihre Zahlungsinformationen zuvor bei Stripe Link gespeichert haben, ihre Zugangsdaten automatisch verfügbar haben. Das sorgt für einen reibungsloseren Checkout, bei dem Nutzer ihre Kreditkartendaten nicht erneut eingeben müssen, was Reibung und Abbruchraten deutlich reduziert.
Schritt 5: Behandle Universal Links in deiner App
Konfiguriere deine App so, dass sie die Universal Links verarbeitet, wenn Nutzer zurückgeleitet werden:
- Installiere zuerst das App-Plugin:
npm install @capacitor/app
- Registriere das App-Plugin in deiner 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
}
Schritt 6: Richte einen Webhook für die Bestellabwicklung ein
Konfiguriere schließlich einen Webhook auf deinem Server, um erfolgreiche Zahlungen zu verarbeiten:
// 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'));
Android-Kompatibilität
Seien wir klar: Das Urteil im Fall Epic gegen Apple hat die Landschaft mobiler Zahlungen grundlegend verändert. Es betrifft nicht nur iOS-Apps direkt, sondern stärkt auch die Position von Android-Entwicklern, die externe Zahlungsmethoden nutzen.
Android-Entwickler können externe Zahlungslösungen nun mit voller Sicherheit implementieren. Der Präzedenzfall des Apple-Urteils schützt Entwickler plattformübergreifend wirksam vor potenziellen künftigen Einschränkungen. Diese Gerichtsentscheidung hat bestätigt, was viele Android-Entwickler seit Jahren tun: alternative Zahlungsoptionen mit niedrigeren Gebühren anzubieten.
Der Google Play Store war bei externen Zahlungsmethoden immer weniger restriktiv als Apple. Da nun ein rechtlicher Präzedenzfall besteht, ist das Risiko, Stripe oder andere externe Zahlungsanbieter in Android-Apps zu implementieren, praktisch null. Sie können diese Implementierungen mit dem Wissen vorantreiben, dass Sie auf festem rechtlichem Boden stehen.
Die für iOS beschriebene Implementierung funktioniert auf Android-Geräten nahezu identisch. Da der Google Play Store keine gleichen Einschränkungen für externe Zahlungsmethoden kennt, können Sie denselben Ansatz mit Stripe Payment Links verwenden, ohne spezielle Offenlegungsdialoge zu benötigen.
Um Deep Linking (das Äquivalent zu Universal Links auf iOS) zu handhaben, müssen Sie:
- App Links in Ihrer
AndroidManifest.xmleinrichten, um die Redirect-URL zu verarbeiten - Erstelle ein
.well-known/assetlinks.jsonDatei auf Ihrer Domain mit den Details Ihrer App - Verwenden Sie denselben
appUrlOpenListener-Logik zur Verarbeitung erfolgreicher Zahlungen
Der Vorteil von Capacitor ist, dass der eigentliche Zahlungsfluss code nach der Implementierung der plattformspezifischen Konfigurationen auf beiden Plattformen identisch bleibt.
Zahlungs-UI erstellen
Hier ist ein Beispiel für eine Zahlungsbutton-Komponente in Vue, die du in deine Capacitor-App einbauen kannst:
<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>
Unterschiedliche Regionen behandeln
Da die neuen Apple-Richtlinien nur für Apps im US-App Store gelten, brauchst du eine Strategie, um die Region der Nutzer zu erkennen und die passende Zahlungsmethode anzuwenden. Hier ist ein zuverlässigerer Ansatz mit IP-Geolokalisierung:
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);
}
}
Dieser Ansatz nutzt den kostenlosen ipapi.co Service, um das Land des Nutzers anhand seiner IP-Adresse zu bestimmen. Du kannst auch andere Geolokalisierungsdienste wie MaxMind verwenden oder diese Prüfung serverseitig implementieren, um die Sicherheit zu erhöhen.
Hinweis: Obwohl dieser Ansatz funktioniert, ist wichtig zu bedenken, dass IP-Geolokalisierung nicht immer zu 100 % genau ist. Für kritische Anwendungen solltest du mehrere Erkennungsmethoden verwenden oder Nutzern erlauben, ihre Region manuell auszuwählen.
Präzisere Standorterkennung mit Capacitor-Plugins
Für eine präzisere Standorterkennung kannst du das Capacitor-Geolocation-Plugin zusammen mit @capgo/capacitor-nativegeocoder verwenden, um das Land des Nutzers genauer zu bestimmen:
- Installiere zuerst die erforderlichen Plugins:
npm install @capacitor/geolocation @capgo/capacitor-nativegeocoder
- Konfiguriere die Plugins in deinem Capacitor-Projekt. Füge Folgendes zu deiner
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;
- Implementiere die standortbasierte Regionenerkennung:
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);
}
}
Diese Implementierung bietet eine genauere Methode, um festzustellen, ob sich ein Nutzer physisch in den USA befindet. Zuerst wird versucht, das GPS des Geräts und den nativen Geocoder zur Länderbestimmung zu nutzen. Schlägt das fehl (z. B. aufgrund von Berechtigungsproblemen oder anderen Fehlern), wird auf die IP-basierte Erkennung zurückgegriffen.
Denke daran, die erforderlichen Berechtigungen in deine info.plist (iOS) und AndroidManifest.xml (Android)-Dateien hinzuzufügen:
Für 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>
Für Android (android/app/src/main/AndroidManifest.xml):
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Mit diesem Ansatz erhältst du die genaueste Methode, um zu bestimmen, ob ein Nutzer gemäß den neuen Apple-Richtlinien für externe Zahlungsoptionen qualifiziert ist.
Abonnements verwalten
Ein wesentlicher Vorteil von Stripe für Zahlungen ist die Möglichkeit, Abonnements anzubieten und zu verwalten. So gehst du bei der Abonnementverwaltung in deiner Capacitor-App vor:
1. Eine Abonnement-Verwaltungsseite erstellen
Füge in deiner App eine Seite zur Abonnement-Verwaltung hinzu, um die aktiven Abonnements des Nutzers anzuzeigen:
<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 für das Abo-Management
Stripe bietet ein Customer Portal, in dem Nutzer ihre Abonnements verwalten können. Du kannst auf deinem Server einen Link zu diesem Portal erstellen:
// 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;
}
App Store Compliance sicherstellen
Um sicherzustellen, dass deine Implementierung den Apple-Richtlinien entspricht:
- Passende Hinweise zu externen Käufen einbauen
- Ein Modal Sheet implementieren, das Nutzer darüber informiert, dass sie die App verlassen (wie von Apple gefordert)
- Versuchen Sie nicht, Apples Provision für In-App-Käufe zu umgehen
- Kommuniziere klar, dass Apple nicht für die Transaktion verantwortlich ist
Hier ist ein Beispiel, wie du das erforderliche Hinweis-Modal implementierst:
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);
}
}
Deine Implementierung testen
Um deine Implementierung zu testen:
- Klicke in deiner App auf den Payment-Button; dieser sollte den Hinweis anzeigen und dann die Stripe-Zahlungsseite öffnen
- Führe eine Testzahlung mit der Stripe-Testkarte durch
4242 4242 4242 4242 - Nach der Zahlung solltest du über den Universal Link zurück in deine App weitergeleitet werden
- Prüfe, ob dein Webhook das
checkout.session.completedEvent
Fazit
Die Möglichkeit, externe Zahlungsoptionen für digitale Güter in iOS-Apps zu nutzen, ist eine bedeutende Änderung, die Entwicklern mehr Flexibilität bietet. Obwohl diese Änderung derzeit nur für Apps im US-App Store gilt, bietet sie eine wichtige Alternative zum In-App-Kauf-System von Apple.
Mit Stripe Payment Links und Capacitor kannst du schnell ein schlankes Checkout-Erlebnis umsetzen und gleichzeitig die Richtlinien von Apple einhalten. Für Nutzer außerhalb der USA, für die das In-App-Kauf-System von Apple weiterhin gilt, @capgo/native-purchases implementiert StoreKit und Google Play Billing direkt. Dieser Ansatz bietet dir zudem den Vorteil der robusten Zahlungsinfrastruktur von Stripe, geringerer Bearbeitungsgebühren (3 % statt 30 %) und deutlich schnellerer Auszahlungen (Tage statt Monate) im Vergleich zum In-App-Kauf-System von Apple.
Denke daran, dass du den gesamten Kundensupport und alle Rückerstattungsanfragen direkt bearbeiten musst, da diese Transaktionen außerhalb des Ökosystems von Apple stattfinden.
Hast du Stripe Payment Links in deiner Capacitor-App implementiert? Teile deine Erfahrungen in den Kommentaren unten!
FAQs
F: Ist dieser Ansatz mit den Richtlinien von Apple konform?
A: Ja, seit dem 1. Mai 2025 erlaubt Apple das Verlinken externer Zahlungsmethoden für digitale Güter und Dienste in Apps, die im US-App-Store verteilt werden, sofern die erforderlichen Hinweise enthalten sind.
F: Muss ich die Provision von Apple zahlen, wenn ich externe Zahlungsmethoden nutze?
A: Nein, einer der großen Vorteile der neuen Regeln ist, dass Zahlungen, die außerhalb des Systems von Apple abgewickelt werden, nicht deren Provision unterliegen.
F: Muss mein Unternehmen in den Vereinigten Staaten ansässig sein, um von diesen neuen Regeln zu profitieren?
A: Nein, jedes Unternehmen aus der ganzen Welt kann externe Zahlungsmethoden implementieren, solange deine App im US-App-Store verfügbar ist und die kaufenden Nutzer sich in den Vereinigten Staaten befinden. Die Regelung gilt für den Marktplatz (US-App-Store) und den Standort der Nutzer, nicht für den Standort deines Unternehmens. Das bedeutet, dass Entwickler aus Europa, Asien, Südamerika oder wo auch immer Stripe Payment Links für ihre US-Kunden implementieren können.
F: Was passiert, wenn ein Nutzer außerhalb der USA versucht, die externe Zahlungsoption zu nutzen?
A: Du solltest eine Regionserkennung implementieren (wie im Artikel gezeigt), um externe Zahlungsoptionen nur Nutzern in den USA anzubieten. Für andere Regionen solltest du weiterhin das In-App-Kauf-System von Apple verwenden.
F: Kann ich dies für physische Güter oder Dienste nutzen, die außerhalb der App konsumiert werden?
A: Ja, Apple hat externe Zahlungsmethoden für physische Waren und Dienstleistungen, die außerhalb der App konsumiert werden (wie Fahrdienste oder Lieferdienste), immer erlaubt.
Weiter geht's: Stripe Payments in Capacitor: Neue Apple-Richtlinien
Wenn du es nutzt Stripe Payments in Capacitor: Neue Apple Guidelines um Sicherheit und Compliance zu planen, verbinden Sie es mit Verschlüsselung für die Implementierungsdetails in Encryption, Konformität für das Implementierungsdetail in Compliance, Capgo Security-Scanner für den Produkt-Workflow im Capgo Security Scanner, Capgo Sicherheit für den Produkt-Workflow in Capgo Security und Capgo Trust Center für den Produkt-Workflow im Capgo Trust Center.