# Verwalten von Abonnements unter iOS Akzeptieren Sie wiederkehrende Zahlungen und verwalten Sie Berechtigungen mit dem BillingSDK für iOS. Akzeptieren Sie Abonnement-Zahlungen, lassen Sie Kunden ihre Abonnements verwalten und verwalten Sie[Berechtigungen](https://docs.stripe.com/billing/entitlements.md) direkt in Ihrer iOS-App mit dem[BillingSDK für iOS](https://github.com/stripe-samples/billing-ios-sdk). Das SDK bietet vordefinierte Nutzeroberfläche-Komponenten zum Anzeigen von Kaufschaltflächen, zum Präsentieren des [Kundenportals](https://docs.stripe.com/customer-management/activate-no-code-customer-portal.md) sowie zum Überprüfen der Berechtigungen für Gate-Premium-Funktionen. ## Bevor Sie beginnen Um das BillingSDK für iOS zu verwenden, benötigen Sie Folgendes: - Ein Backend-Server zum Erstellen von [Kunden-Sitzungen](https://docs.stripe.com/api/customer_sessions.md) - Ein Stripe-Konto mit Zugriff auf die private Vorschau - iOS 15.0 oder höher und macOS 12.0 oder höher - Xcode 15.0 oder höher ## Sie werden Folgendes entwickeln Dieser Leitfaden bietet Informationen zu den folgenden Vorgehensweisen: - Richten Sie einen Server Endpoint ein, um [Kundensitzugngen](https://docs.stripe.com/api/customer_sessions.md) zu erstellen - Installieren und Konfigurieren des BillingSDK für iOS - Anzeigen von Kauf-Schaltflächen für Abonnement-Käufe - Überprüfen von Berechtigungen für Gate-Premium-Funktionen - Präsentieren des Kundenportals für die Abonnement-Verwaltung - Behandeln von Fehlern und Verwalten des Sitzungsstatus Eine vollständige Beispiel-App finden Sie in der [BillingSDK für das iOS-Repository](https://github.com/stripe-samples/billing-ios-sdk). ## Einrichten Ihres Backends [Server] Erstellen Sie ein Server-Endpoint zum[Generieren von Kundensitzungen](https://docs.stripe.com/api/customer_sessions/create.md) für authentifizierte Nutzer/innen. Diese Sitzungen authentifizieren Ihre iOS-App sicher mit den Abrechnungs-APIs von Stripe. ### Erstellen Sie einen Endpoint der Kundensitzung Der Endpoint muss folgende Anforderungen erfüllen: 1. Überprüfen, ob die/der Nutzer/in authentifiziert ist 1. Erstellen oder Abrufen der Stripe [Kunden-ID](https://docs.stripe.com/api/customers/object.md) für die Nutzerin / den Nutzer 1. Erstellen Sie eine Kundensitzung mit aktivierten erforderlichen Komponenten 1. Geben Sie die Sitzungsdetails an Ihre App zurück Hier ist ein Beispiel für eine Implementierung: ```javascript import 'dotenv/config'; import express from 'express'; import Stripe from 'stripe'; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY || '', { apiVersion: '2025-07-30.basil', }); const app = express(); app.use(express.json()); app.post('/authenticate', async (req, res) => { try { // Replace with your auth; return 401 if the user is not logged in const user = authUser(req); if (!user) { res.status(401).json({ error: { type: 'no_session_present' } }); return; } const customerSession = await stripe.customerSessions.create({ customer: user.stripeCustomerId, components: { buy_button: { enabled: true }, active_entitlements: { enabled: true }, customer_portal: { enabled: true }, } as any, }); res.json({ clientSecret: customerSession.client_secret, expiresAt: customerSession.expires_at, customer: customerSession.customer as string, }); } catch (err) { res.status(500).json({ error: { message: 'Internal server error' } }); } }); app.listen(3000); ``` ### Format der Antwort Der Endpoint muss die folgenden Felder zurückgeben, um eine erfolgreiche Authentifizierung zu gewährleisten: | Feld | Typ | Beschreibung | | -------------- | ------------ | ---------------------------------------------------------------------------------------- | | `clientSecret` | Zeichenfolge | Der geheime Schlüssel der Kundensitzung, der zum Authentifizieren des SDK verwendet wird | | `expiresAt` | Zahl | Ablaufzeitstempel in Sekunden seit Epoch | | `customer` | Zeichenfolge | Die Stripe-Kunden-ID | Wenn die Authentifizierung fehlschlägt, geben Sie HTTP 401 zurück, um den nicht authentifizierten Status des SDK auszulösen. ## Installieren und Konfigurieren des SDK [iOS] Das BillingSDK für iOS bietet eine native iOS-Oberfläche für die Abonnementverwaltung und die Zugriffssteuerung auf Funktionen. ### Hinzufügen des SDK zu Ihrem Projekt Installieren Sie während der privaten Vorschau das BillingSDK-Paket: 1. Öffnen Sie Ihr Projekt in Xcode 1. Wählen Sie **Datei** → **Paketabhängigkeiten hinzufügen** aus. 1. Tippen Sie `https://github.com/stripe-samples/billing-ios-sdk` in das Feld **Paket-URL suchen oder eingeben** ein 1. Wählen Sie `BillingSDK` und klicken Sie auf **Paket hinzufügen** ### Konfigurieren des SDK Initialisieren Sie das SDK in einer freigegebenen Klasse, um die Einrichtung und Authentifizierung des BillingSDK durchzuführen: ```swift import Foundation import BillingSDK import SwiftUI class BillingManager { static let shared = BillingManager() public let billing: BillingSDK private init() { // Initialize with your publishable key and set how long entitlements can be stale before needing to refresh. let configuration = BillingSDK.Configuration( publishableKey: "pk_test_…", maximumStaleEntitlementsDuration: TimeInterval(60 * 5) ) self.billing = BillingSDK(configuration: configuration) // Set up authentication (see below for implementation) setupCustomerSessionProvider() // Add entitlement change listener (see below for implementation) setupEntitlementListener() } } ``` > Das SDK kümmert sich intern um die Threadsicherheit – Sie können seine Methoden sicher von jedem Thread aus aufrufen. ### Einrichten des Anbieters für Kundensitzungen Fügen Sie die Authentifizierungsmethode Ihrem Abrechnung-Manager hinzu: ```swift import Foundation import BillingSDK extension BillingManager { func setupCustomerSessionProvider() { billing.setCustomerSessionProvider { [weak self] () async -> UBCustomerSessionDetails? in await self?.fetchCustomerSession() } } private func fetchCustomerSession() async -> UBCustomerSessionDetails? { // Configure request to your backend endpoint guard let url = URL(string: "https://your-backend.example.com/customer-session") else { print("Invalid URL") return nil } var request = URLRequest(url: url) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") // Send any additional headers needed to authenticate the user, for example, an auth token. request.setValue("Bearer \(authToken)", forHTTPHeaderField: "Authorization") do { // Make the request let (data, response) = try await URLSession.shared.data(for: request) guard let httpResponse = response as? HTTPURLResponse else { print("Invalid response format") return nil } switch httpResponse.statusCode { case 200: // Parse the successful response let decoder = JSONDecoder() decoder.dateDecodingStrategy = .secondsSince1970 return try decoder.decode(UBCustomerSessionDetails.self, from: data) case 401: // User not authenticated - SDK will enter unauthenticated state print("Authentication required") return nil default: print("Unexpected status code: \(httpResponse.statusCode)") return nil } } catch { print("Session provider error: \(error.localizedDescription)") return nil } } // Call this method when your user signs out func handleSignOut() async { await billing.reset() // Clear session data and caches } } ``` > Das BillingSDK ruft Ihren Sitzungsanbieter automatisch auf, wenn es sich bei Stripe authentifizieren muss. Wenn der Anbieter `nil` zurückgibt, geht das SDK in einen nicht authentifizierten Zustand über. ## Schaltflächen zum Kauf von Abonnements anzeigen [iOS] Kauf-Schaltflächen bieten ein vordefiniertes Nutzeroberfläche-Element, mit dem Kunden Abonnements erwerben können. Jede Schaltfläche ist mit einem bestimmten Produkt und Preis in Ihrem Stripe-Konto verknüpft. ### Erstellen Sie Kauf-Schaltfächen im Dashboard Folgen Sie den Anweisungen in [diesem Leitfaden](https://docs.stripe.com/payment-links/buy-button.md), um Kauf-Schaltflächen im Dashboard zu erstellen. Wenn Sie die Funktionalität zur Berechtigungsprüfung verwenden möchten, stellen Sie sicher, dass die von Ihnen erstellten Produkte über angehängte [Berechtigungen](https://docs.stripe.com/billing/entitlements.md) verfügen. ### Anzeigen einer Schaltfläche „Kaufen“ ```swift import SwiftUI import BillingSDK struct SubscriptionView: View { @State private var buyButton: BuyButton? @State private var isLoading = true @State private var errorMessage: String? // Replace with your buy button ID from the Dashboard let buttonId = "buy_btn_1Abcdef123456" var body: some View { VStack { if isLoading { ProgressView("Loading subscription options...") } else if let buyButton = buyButton { // Display the prebuilt buy button UI // Alternatively the BuyButton class also provides all the data to render // a custom UI element. buyButton.view() .frame(height: 56) .padding(.horizontal) } else if let errorMessage = errorMessage { Text("Error: \(errorMessage)") .foregroundColor(.red) Button("Retry") { loadBuyButton() } } } .onAppear { loadBuyButton() } } func loadBuyButton() { isLoading = true errorMessage = nil Task { do { // Fetch the button from Stripe buyButton = try await BillingManager.shared.billing.getBuyButton(id: buttonId) isLoading = false } catch { errorMessage = "Failed to load buy button" isLoading = false } } } } ``` > „Kaufen“-Schaltflächen funktionieren auch, wenn Nutzer/innen nicht authentifiziert sind. Das SDK erstellt bei Bedarf während des Kaufs einen neuen Stripe-Kunden. ## Überprüfen und Validieren von Berechtigungen [iOS] Mit Berechtigungen können Sie den Zugriff auf Premium-Funktionen basierend auf den aktiven Abonnements einer Kundin oder eines Kunden regeln. ### Überprüfen einer bestimmten Berechtigung Überprüfen, ob ein/e Nutzer/in Zugriff auf eine bestimmte Funktion hat: ```swift func checkPremiumAccess() async { do { let hasPremiumAccess = try await BillingManager.shared.billing.hasEntitlement(lookupKey: "premium_tier") if hasPremiumAccess { // User has premium access - enable features unlockPremiumFeatures() } else { // User doesn't have access - show upsell showPremiumUpsell() } } catch { showErrorMessage("Couldn't verify entitlements status") } } ``` ### Abrufen aller aktiven Berechtigungen Rufen Sie alle Berechtigungen ab, auf die die Kundin / der Kunde Zugriff hat: ```swift func loadUserEntitlements() async { do { // Force refresh ensures we get the latest data from the server let entitlements = try await BillingManager.shared.billing.getActiveEntitlements(forceRefresh: true) // Map entitlements to app features let features = entitlements.map { $0.lookupKey } updateAvailableFeatures(features) } catch { handleError(error) } } ``` ### Überwachen von Berechtigungsänderungen Richten Sie einen Listener ein, der Sie benachrichtigt, wenn sich Berechtigungen ändern: ```swift import Foundation import BillingSDK extension BillingManager { func setupEntitlementListener() { billing.onEntitlementsChanged { updatedEntitlements in // Update UI based on new entitlements DispatchQueue.main.async { self.updateAppFeatures(based: updatedEntitlements) self.refreshUI() } } } } ``` > Wenn keine Sitzung vorhanden ist, `getActiveEntitlements()` wird ein leerer Array zurückgegeben. ## Präsentieren des Kundenportals [iOS] Über das Kundenportal können Abonnenten ihre Abonnements, Zahlungsmethoden und Abrechnungsdaten verwalten. ### Zeigen Sie das Kundenportal an Präsentieren Sie das Portal, wenn Nutzer/innen ihr Abonnement verwalten müssen: ```swift func manageSubscriptionTapped() { Task { do { let portal = try await BillingManager.shared.billing.getCustomerPortal() // Show portal within your app (recommended) portal.presentCustomerPortal(from: self) } catch { if let billingError = error as? BillingSDKError { switch billingError { case .unauthenticated: // User needs to log in first showLoginPrompt() default: // Handle other errors showErrorMessage("Could not load subscription management") } } else { showErrorMessage("Could not load subscription management") } } } } ``` > Für das Kundenportal ist eine aktive authentifizierte Sitzung erforderlich. Wenn die/der Nutzer/in nicht angemeldet ist, löst das SDK einen`.unauthenticated`-Fehler aus. ### Externe Umleitung (optional) Sie können das Portal auch in einem Browser öffnen: ```swift let portal = try await BillingManager.shared.billing.getCustomerPortal() portal.redirectToCustomerPortal() // Opens in default browser ``` ## Verwaltung von Sitzungen [iOS] ### Verwaltung von Sitzungen Setzen Sie das SDK zurück, wenn sich Benutzer abmelden, um Sitzungsdaten und Caches zu löschen: ```swift func signOut() async { // Clear your app's auth state UserDefaults.standard.removeObject(forKey: "auth_token") // Reset the BillingSDK state await BillingManager.shared.billing.reset() // Navigate to login screen showLoginScreen() } ``` ## Ihre Integration testen Verwenden Sie während der Entwicklung Ihre [Sandbox API Schlüssel](https://docs.stripe.com/keys.md#obtain-api-keys) und Sandbox Kunden-IDs, um echte Gebühren zu vermeiden. ### Test-Szenarien Testen Sie die folgenden häufigen Szenarien: | Szenario | Schritte | | ---------------------------- | ----------------------------------------------------------------------------- | | Kauf eines neuen Abonnements | Einer/einem neuen Nutzer/in eine „Kaufen“-Schaltfläche anzeigen | | Abonnementverwaltung | Verwenden des Kundenportals zum Ändern von Plänen | | Überprüfung der Berechtigung | Überprüfen einer Premium-Funktion mit`hasEntitlement` | | Fehlerbehebung | Testen Sie die Funktion mit ungültigen Schlüsseln oder abgelaufenen Sitzungen | | Abmeldungsablauf | Überprüfen Sie, dass `billing.reset()` die zwischengespeicherte Daten löscht | ## See also - [Berechtigungen](https://docs.stripe.com/billing/entitlements.md) - [Konfigurieren Sie das Kundenportal](https://docs.stripe.com/customer-management/integrate-customer-portal.md) - [Funktionsweise von Abonnements](https://docs.stripe.com/billing/subscriptions/overview.md)