Implementierung von Stripe Payment Links in Capacitor Apps gemäß neuen Apple-Richtlinien
Seit dem 1. Mai 2025 hat Apple infolge des Gerichtsurteils in den App Store Review Guidelines wesentliche Änderungen vorgenommen Epic v. Apple Fallerhebliche Änderungen an den App Store Review Guidelines vorgenommen. Diese Änderungen erlauben es App-Entwicklern in den USA nun explizit, für digitale Güter und Dienste auf externe Zahlungsmethoden zu verlinken, was Alternativen zu Apples In-App-Kauf-System schafft.
Der epische Kampf, der Mobile Payments für immer veränderte
Der Weg zu diesem Moment war lang und voller Kontroversen. Alles begann im August 2020, als Epic Games, der Entwickler des extrem populären Spiels Fortnite, bewusst gegen die App Store-Richtlinien von Apple verstieß. Sie implementierten eine direkte Zahlungsoption, um Apples 30 % Provision zu umgehen. Apple entfernte Fortnite daraufhin umgehend aus dem App Store, woraufhin Epic mit einer Klage reagierte, um Apples Kontrolle über den iOS-App-Vertrieb und In-App-Zahlungen anzufechten.
Nach jahrelangen Rechtsstreitigkeiten, Berufungen und Gegenberufungen urteilten die Gerichte schließlich, dass Apple Entwicklern erlauben muss, Nutzer auf alternative Zahlungsmethoden außerhalb ihrer Apps zu leiten. Diese Entscheidung verändert die Wirtschaftlichkeit des App Store-Ökosystems grundlegend, das seit seiner Gründung im Jahr 2008 nach demselben Finanzmodell funktioniert hat.
Das endgültige Urteil – keine Berufung mehr möglich
Besonders bedeutsam ist, dass dieses Urteil endgültig ist und nicht weiter angefochten werden kann. Der Supreme Court lehnte Apples Berufung Anfang 2025 ab, wodurch die Entscheidung der Vorinstanz rechtskräftig wurde. 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 gesetzlich garantiert
Am wichtigsten ist, dass das Urteil explizit festlegt, dass Apple Apps, die externe Zahlungsmethoden nutzen, nicht diskriminieren darf. Das Gericht untersagte Apple insbesondere:
- Zusätzliche Gebühren für Apps, die externe Zahlungsmethoden nutzen, oder zusätzliche Anforderungen an diese stellen
- Bevorzugung von Apps in Suchergebnissen oder Feature-Platzierungen, die ausschließlich das IAP-System von Apple nutzen
- Technische Maßnahmen, um externe Zahlungserlebnisse schlechter als Apples eigenes System zu gestalten
- Aufbürden belastender Offenlegungspflichten, die über grundlegende Verbraucherinformationen hinausgehen
Diese expliziten Schutzmaßnahmen bedeuten, dass Entwickler Stripe oder andere externe Zahlungsanbieter implementieren können, ohne subtile Vergeltungsmaßnahmen oder Diskriminierung durch Apple befürchten zu müssen. Die Spielregeln wurden rechtlich angeglichen, und Apple muss alle Apps unabhängig von ihrer Wahl der Zahlungsmethode gleich behandeln.
Das Urteil stellt eine der bedeutendsten Herausforderungen für Apples Walled-Garden-Ansatz dar und markiert einen Wendepunkt für die Monetarisierung von Mobile Apps. Für Entwickler, die sich lange über Apples 30 % Provision (reduziert auf 15 % für kleine Unternehmen) beschwert haben, bietet dieses Urteil einen Weg zu höheren Gewinnmargen und mehr Kontrolle über das Kundenerlebnis.
Finanzielle Vorteile von Stripe gegenüber Apples In-App-Käufen
Die finanziellen Auswirkungen dieser Änderung sind für Entwickler erheblich:
-
Geringere Gebühren für die Zahlungsabwicklung: Apple erhebt typischerweise eine Provision von 30 % 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 deutlich erhöhen.
-
Schnellere Auszahlungen: Bei Apple dauert es meist 45–90 Tage, bis du dein Geld erhältst. Stripe hingegen zahlt Zahlungen innerhalb von 2–3 Werktagen auf dein Bankkonto aus.
-
Vereinfachter Refund-Prozess: Erstelle Rückerstattungen direkt über das Stripe-Dashboard, anstatt das komplexere System von Apple zu nutzen.
Diese Kosteneinsparungen und der verbesserte Cashflow können entscheidend sein, besonders für kleinere Entwickler und Unternehmen.
In diesem Artikel zeigen wir dir, wie du Stripe Payment Links in deiner Capacitor App implementierst, um von diesen neuen Regeln zu profitieren und gleichzeitig die Apple- aktualisierten Richtlinien einzuhalten.
Diese Implementierung basiert auf der offiziellen Stripe-Dokumentation für Payment Links, speziell angepasst für Capacitor Apps.
Die neuen Richtlinien verstehen
Die aktualisierten App Store Review Guidelines erlauben es Entwicklern nun, Nutzer für Zahlungen auf externe Websites zu leiten, speziell für digitale Güter und Abos. Dies gilt aktuell nur für Apps im US App Store.
Wichtige Punkte im Überblick:
- Du kannst jetzt externe Zahlungsoptionen für digitale Güter in deiner App verlinken
- Dies gilt nur für Apps im US App Store
- Du musst weiterhin die Offenlegungspflichten von Apple einhalten
- Du bleibst für den gesamten Kundensupport und die Rückerstattungen verantwortlich
Einrichten von Stripe Payment Links in deiner Capacitor App
Schauen wir uns die technische Umsetzung an:
Schritt 1: Payment Link im Stripe Dashboard erstellen
Erstelle zuerst einen Payment Link in deinem Stripe Dashboard:
- Navigiere zum Bereich „Payment Links“ in deinem Stripe Dashboard
- Klicke auf „+ New“, um einen neuen Payment Link zu erstellen
- Lege deine Produkt- oder Abonnement-Details fest
- Wähle unter „After payment“ die Option „Don’t show confirmation page“
- Setze einen Universal Link als Success 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 deiner Domain:
{
"applinks": {
"apps": [],
"details": [
{
"appIDs": ["YOURTEAMID.com.yourdomain.yourapp"],
"components": [
{
"/": "/checkout_redirect*",
"comment": "Matches any URL whose path starts with /checkout_redirect"
}
]
}
]
}
}
-
Hoste diese Datei unter
https://yourdomain.com/.well-known/apple-app-site-association -
Stelle sicher, dass sie mit dem korrekten MIME-Type ausgeliefert wird
application/json -
Konfiguriere deine Capacitor App so, dass sie Universal Links verarbeitet, indem du das passende Entitlement hinzufügst. Zuerst in deinem
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üge das Associated Domains Entitlement zu deinem Xcode-Projekt hinzu:
- Öffne dein Xcode-Projekt
- Wähle dein App-Target aus
- Gehe zu „Signing & Capabilities“
- Klicke auf „+ Capability“ und wähle „Associated Domains“
- Füge
applinks:yourdomain.com
Schritt 3: Eine Fallback-Seite erstellen
Erstelle eine Fallback-Seite unter der Redirect-URL, um Fälle abzufangen, 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: Den Payment-Button in deiner Capacitor App implementieren
Füge nun den Payment-Button 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 Payment-Links in Safari (via
window.open) anstatt in einem In-App-Browser ist vorteilhaft, da Nutzer, die ihre Zahlungsdaten bereits bei Stripe Link gespeichert haben, ihre Zugangsdaten automatisch zur Verfügung haben. Dies sorgt für einen reibungsloseren Checkout, bei dem Nutzer ihre Kreditkartendaten nicht erneut eingeben müssen, was Reibungsverluste und Abbruchraten deutlich reduziert.
Schritt 5: Universal Links in deiner App handhaben
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: Webhook für die Auftragsabwicklung einrichten
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
Klartext: Das Epic vs. Apple-Urteil hat die mobile Zahlungslandschaft grundlegend verändert. Es wirkt sich nicht nur direkt auf iOS-Apps aus, sondern stärkt auch die Position von Android-Entwicklern, die bereits externe Zahlungsmethoden nutzen.
Android-Entwickler können externe Zahlungslösungen jetzt völlig bedenkenlos implementieren. Der durch das Apple-Urteil geschaffene Präzedenzfall schützt Entwickler plattformübergreifend vor möglichen künftigen Einschränkungen. Diese Gerichtsentscheidung bestätigt, was viele Android-Entwickler seit Jahren tun: alternative Zahlungsoptionen mit niedrigeren Gebühren anzubieten.
Der Google Play Store war bei externen Zahlungsmethoden schon immer weniger restriktiv als Apple. Mit dem nun geschaffenen rechtlichen Präzedenzfall besteht praktisch kein Risiko mehr, Stripe oder andere externe Zahlungsanbieter in Android-Apps zu integrieren. Du kannst diese Implementierungen mit dem Wissen angehen, auf rechtlich sicherem Boden zu stehen.
Die hier beschriebene Implementierung für iOS funktioniert nahezu identisch für Android-Geräte. Da der Google Play Store nicht dieselben Einschränkungen für externe Zahlungsmethoden hat, kannst du exakt denselben Stripe-Payment-Links-Ansatz nutzen, ohne spezielle Disclosure-Dialoge zu benötigen.
Um Deep Linking (entspricht Universal Links unter iOS) zu handhaben, musst du:
- Richte App Links in deiner
AndroidManifest.xmlum die Redirect-URL zu verarbeiten - Erstelle einen
.well-known/assetlinks.jsonDatei auf deiner Domain mit den App-Details - Verwende dieselbe
appUrlOpenListener-Logik, um erfolgreiche Zahlungen zu verarbeiten
Das Schöne an Capacitor ist, dass nach der Implementierung der plattformspezifischen Konfigurationen der eigentliche Payment-Flow code auf beiden Plattformen gleich bleibt.
Erstellen eines Payment-UI
Hier ist ein Beispiel für eine Payment-Button-Komponente in Vue, die du deiner Capacitor App hinzufügen 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>
Umgang mit verschiedenen Regionen
Da die neuen Apple-Richtlinien nur für Apps im US App Store gelten, benötigst du eine Strategie, um die Region der Nutzer zu erkennen und die passende Zahlungsmethode anzuwenden. Hier ist ein zuverlässigerer Ansatz mittels IP-Geolocation:
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 ein Dienst, der das Land des Nutzers anhand der IP-Adresse ermittelt. Alternativ kannst du Geolocation-Dienste wie MaxMind nutzen oder diesen Check für mehr Sicherheit serverseitig implementieren.
Hinweis: Dieser Ansatz funktioniert zwar, aber beachte, dass IP-Geolocation nicht immer zu 100 % genau ist. Für geschäftskritische Apps solltest du mehrere Erkennungsmethoden nutzen oder Nutzern die manuelle Regionswahl erlauben.
Präzisere Standorterkennung mit Capacitor Plugins
Für eine genauere Standorterkennung kannst du das Capacitor Geolocation Plugin zusammen mit @capgo/capacitor-nativegeocoder nutzen, um das Land des Nutzers präziser zu bestimmen:
- Installiere zuerst die benötigten 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 Regionserkennung:
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 zu prüfen, ob sich ein Nutzer physisch in den USA befindet. Zuerst wird versucht, das Land via GPS und nativem Geocoder zu ermitteln. Schlägt dies fehl (z. B. durch Berechtigungsprobleme), erfolgt ein Fallback auf die IP-basierte Erkennung.
Vergiss nicht, die erforderlichen Berechtigungen in deiner info.plist (iOS) und AndroidManifest.xml (Android) Datei 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 ermittelst du am genauesten, ob ein Nutzer gemäß den neuen Apple-Richtlinien für externe Zahlungsoptionen berechtigt ist.
Abonnements verwalten
Ein großer Vorteil von Stripe ist die Möglichkeit, Abonnements anzubieten und zu verwalten. So implementierst du das Subscription-Management in deiner Capacitor App:
1. Eine Seite für das Abo-Management erstellen
Füge deiner App eine Seite 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, mit dem Nutzer ihre Abonnements selbst verwalten können. Du kannst von deinem Server aus 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 einbinden
- Implementieren Sie ein Modal-Sheet, das Nutzer darüber informiert, dass sie die App verlassen (wie von Apple vorgeschrieben)
- Versuchen Sie nicht, Apples Provision für In-App-Käufe zu umgehen
- Kommunizieren Sie klar an die Nutzer, dass Apple nicht für die Transaktion verantwortlich ist
Hier ist ein Beispiel für die Implementierung des erforderlichen Disclosure-Modals:
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);
}
}
Ihre Implementierung testen
Um Ihre Implementierung zu testen:
- Klicken Sie in Ihrer App auf den Payment-Button; dieser sollte das Disclosure anzeigen und dann die Stripe-Zahlungsseite öffnen
- Führen Sie eine Testzahlung mit einer Stripe-Testkarte durch
4242 4242 4242 4242 - Nach der Zahlung sollten Sie über den Universal Link zurück in Ihre App geleitet werden
- Prüfen Sie, ob Ihr Webhook den
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. Auch wenn dies aktuell nur für Apps im US App Store gilt, bietet es eine wichtige Alternative zu Apples In-App-Kauf-System.
Durch die Nutzung von Stripe Payment Links mit Capacitor können Sie schnell einen optimierten Checkout implementieren und gleichzeitig die Apple-Richtlinien einhalten. Für Nutzer außerhalb der USA, wo das In-App-Kauf-System von Apple weiterhin gilt, @capgo/native-purchases implementiert StoreKit und Google Play Billing direkt. Dieser Ansatz bietet zudem die Vorteile der robusten Stripe-Zahlungsinfrastruktur, geringerer Gebühren (3 % statt 30 %) und deutlich schnellerer Auszahlungen (Tage statt Monate) im Vergleich zu Apples In-App-Kauf-System.
Beachten Sie, dass Sie den gesamten Kundensupport und Rückerstattungen selbst abwickeln müssen, da diese Transaktionen außerhalb von Apples Ökosystem stattfinden.
Haben Sie Stripe Payment Links bereits in Ihrer Capacitor App implementiert? Teilen Sie Ihre Erfahrungen unten in den Kommentaren!
FAQs
F: Ist dieser Ansatz konform mit den Apple-Richtlinien?
A: Ja, seit dem 1. Mai 2025 erlaubt Apple die Verlinkung zu externen Zahlungsmethoden für digitale Güter und Dienste in Apps im US App Store, sofern die erforderlichen Hinweise enthalten sind.
F: Muss ich Apple eine Provision zahlen, wenn ich externe Zahlungsmethoden nutze?
A: Nein, einer der größten Vorteile der neuen Regeln ist, dass Zahlungen, die außerhalb von Apples System abgewickelt werden, nicht ihrer Provision unterliegen.
F: Muss mein Unternehmen in den USA ansässig sein, um von diesen neuen Regeln zu profitieren?
A: Nein, jedes Unternehmen weltweit kann externe Zahlungsmethoden implementieren, solange die App im US App Store verfügbar ist und die Käufer in den USA ansässig sind. Die Regelung bezieht sich auf den Marktplatz (US App Store) und den Standort der Nutzer, nicht auf den Sitz Ihres Unternehmens. Das bedeutet, dass Entwickler aus Europa, Asien, Südamerika oder anderswo Stripe Payment Links für ihre Kunden in den USA nutzen können.
F: Was passiert, wenn ein Nutzer außerhalb der USA versucht, die externe Zahlungsoption zu nutzen?
A: Sie sollten eine Regionserkennung implementieren (wie im Artikel gezeigt), um externe Zahlungsoptionen nur Nutzern in den USA anzubieten. Für andere Regionen sollten Sie weiterhin das In-App-Kaufsystem von Apple verwenden.
F: Kann ich dies für physische Güter oder Dienstleistungen verwenden, die außerhalb der App konsumiert werden?
A: Ja, Apple hat externe Zahlungsmethoden für physische Güter und Dienstleistungen, die außerhalb der App genutzt werden (wie Ride-Sharing oder Essenslieferungen), schon immer erlaubt.
Weiter geht's mit Stripe Payments in Capacitor: Neue Apple Richtlinien
Wenn Sie ... verwenden Stripe Payments in Capacitor: Neue Apple-Richtlinien nutzen, um Security und Compliance zu planen, verbinden Sie es mit Verschlüsselung für die Implementierungsdetails bei der Verschlüsselung, Compliance für die Implementierungsdetails 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.