# Bieten Sie die Abonnementverwaltung unter iOS mit einer Kundenportalseite Richten Sie ein Kundenportal ein und öffnen Sie es in einem Browser aus Ihrer App. Für digitale Produkte, Inhalte und Abos, die in den Vereinigten Staaten oder im Europäischen Wirtschaftsraum (EWR) verkauft werden, kann Ihre App Apple Pay akzeptieren, indem sie zu einer externen Zahlung weiterleitet. In diesem Leitfaden wird beschrieben, wie Sie ein [Kundenportal](https://docs.stripe.com/customer-management.md) für die Verwaltung von Abos konfigurieren und Ihre Kundinnen und Kund von Ihrer App dorthin weiterleiten. ![Einmalige Zahlung](https://b.stripecdn.com/docs-statics-srv/assets/subscriptions_hero.647ac1dba5270dbf75e15c456c6bcf0d.png) Verlassen Sie die App, um Abonnements und Zahlungsmethoden zu verwalten ## Sie werden Folgendes entwickeln > In diesem Leitfaden wird nur die Abonnementverwaltung beschrieben. Wenn Sie Abonnementkäufe einrichten, finden Sie weitere Informationen unter [Zahlungen für digitale Waren in iOS mit einer vorgefertigten Zahlungsseite akzeptieren](https://docs.stripe.com/mobile/digital-goods/checkout.md). Dieser Leitfaden bietet Informationen zu den folgenden Vorgehensweisen: - Richten Sie eine Kundenportalseite ein, über die Kundinnen/Kunden Abonnements verwalten können. - Verwenden Sie *universelle Links* (Use Universal links on iOS and macOS to link directly to in-app content. They're standard HTTPS links, so the same URL works for your website and your app), um Nutzer/innen vom Kundenportal zurück zu Ihrer App zu leiten - Überwachen Sie *Webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests), um den Abonnementstatus Ihrer Kundschaft zu aktualisieren ## Was nicht behandelt wird In diesem Leitfaden wird gezeigt, wie Sie ein [Kundenportal](https://docs.stripe.com/customer-management.md) von Stripe einrichten und von Ihrer App aus darauf verlinken. Nicht behandelt wird: - **Käufe von Abonnements**: Informationen zur Verwendung von Stripe Checkout für den Verkauf von In-App-Waren und Abonnements finden Sie unter [Zahlungen für digitale Waren in iOS mit einer vorgefertigten Zahlungsseite akzeptieren](https://docs.stripe.com/mobile/digital-goods/checkout.md). - **Nutzerauthentifizierung**: Falls Sie noch keinen Authentifizierungsanbieter haben, können Sie einen Drittanbieter wie [Sign in with Apple](https://developer.apple.com/sign-in-with-apple/) oder [Firebase Authentication](https://firebase.google.com/docs/auth) verwenden. - **Native In-App-Käufe**: Um In-App-Käufe mit StoreKit umzusetzen, besuchen Sie [den Leitfaden zu In-App-Käufen von Apple](https://developer.apple.com/in-app-purchase/). ## Konfigurieren Sie das Portal Zunächst müssen Sie sich [für ein Stripe-Konto registrieren](https://dashboard.stripe.com/register/). Bevor Sie das Kundenportal integrieren, definieren Sie im Dashboard, was Ihre Nutzer/innen mit dem Portal tun können. Wählen Sie Ihre Einstellungen für *Sandboxes* (A sandbox is an isolated test environment that allows you to test Stripe functionality in your account without affecting your live integration. Use sandboxes to safely experiment with new features and changes) und den Live-Modus basierend auf Ihrem Produkt- und Preiskatalog. > Wenn Sie das Kundenportal in Verbindung mit Stripe Connect nutzen, müssen Sie darauf achten, dass Sie das Kundenportal für die Plattform und nicht für ein verbundenes Konto konfigurieren. Wenn Sie mehrere Portalkonfigurationen für verschiedene Kundengruppen erstellen möchten (oder wenn Sie eine *Connect* (Connect is Stripe's solution for multi-party businesses, such as marketplace or software platforms, to route payments between sellers, customers, and other recipients)-Plattform haben und die Konfigurationen für Ihre verbundenen Konten verwalten möchten), können Sie dafür die [API](https://docs.stripe.com/api/customer_portal/configurations/object.md) verwenden: ```curl curl https://api.stripe.com/v1/billing_portal/configurations \ -u "<>:" \ -d "features[invoice_history][enabled]=true" ``` ### Produktkatalog einrichten Wenn Sie Kundinnen und Kunden gestatten, Upgrades oder Downgrades durchzuführen oder die Mengen ihrer Abonnements zu ändern, müssen Sie auch einen Produktkatalog einrichten. Dazu gehören die Produkte und Preise, auf die Ihre Kundinnen und Kunden ein Upgrade oder Downgrade durchführen können, sowie die Abonnements, für die sie Mengen aktualisieren können. Weitere Informationen zum Erstellen von Produkten und Preisen finden Sie unter [Produkt erstellen](https://docs.stripe.com/products-prices/manage-prices.md#create-product). Wenn Sie das Kundenportal nur für die Rechnungsstellung verwenden, müssen Sie keinen Produktkatalog erstellen. Das Portal zeigt die folgenden Attribute Ihres Produktkatalogs an: - **Name und Beschreibung des Produkts**: Diese Attribute können im Dashboard und über die API bearbeitet werden. - **Mengenbeschränkungen pro Produkt**: Diese Attribute sind im Dashboard bearbeitbar. - **Preis, Währung und Abrechnungsintervall**: Diese Attribute sind fest und werden nur einmal bei der Erstellung im Dashboard und in der API festgelegt. ### Erfassung von Steuer-IDs aktivieren Wenn Sie [Stripe Tax](https://docs.stripe.com/tax.md) verwenden, um automatisch Steuern für Abonnements oder Rechnungen einzuziehen, können Sie Kundinnen/Kunden erlauben, ihre Steuer-IDs im Kundenportal festzulegen und zu aktualisieren. Stripe Billing fügt die Steuer-IDs zu den *Rechnungen* (Invoices are statements of amounts owed by a customer. They track the status of payments from draft through paid or otherwise finalized. Subscriptions automatically generate invoices, or you can manually create a one-off invoice) der Kundinnen/Kunden hinzu. Damit Kundinnen/Kunden ihre Steuer-IDs selbst festlegen können, gehen Sie zu den [Kundenportaleinstellungen](https://dashboard.stripe.com/settings/billing/portal) und aktivieren Sie **Steuer-ID**. Weitere Informationen finden Sie unter „So funktionieren Kunden-Steuer-IDs mit [Abonnements](https://docs.stripe.com/billing/customer/tax-ids.md) und [Rechnungen](https://docs.stripe.com/invoicing/taxes/account-tax-ids.md)“. Hier erfahren Sie, wie Sie [Stripe Tax einrichten](https://docs.stripe.com/tax/set-up.md), [Steuern für wiederkehrende Zahlungen erheben](https://docs.stripe.com/billing/taxes/collect-taxes.md), [Steuern in Ihren nutzerdefinierten Zahlungsabläufen einziehen](https://docs.stripe.com/tax/custom.md#existing-customer) und [Steuersätze für Posten und Rechnungen festlegen](https://docs.stripe.com/tax/invoicing.md). ### Vorschau und Test Klicken Sie beim Konfigurieren Ihrer Einstellungen auf **Vorschau**, um eine Vorschau des Portals anzuzeigen. Dadurch wird eine schreibgeschützte Version des Portals geöffnet, die es Ihnen ermöglicht, zu sehen, wie Ihre Kundinnen und Kunden ihre Abonnements und Rechnungsdetails verwalten können. Nachdem Sie Ihre Einstellungen gespeichert haben, können Sie das Portal starten und es mit einer Kundin oder einem Kunden in einer Sandbox testen. Gehen Sie im Dashboard auf eine Kundin oder einen Kunden, klicken Sie auf **Aktionen**, und wählen Sie dann **Kundenportal öffnen**. Sie können eine Vorschau des Portals nur als schreibgeschützte Version anzeigen, wenn sich Ihr Dashboard in einer Sandbox befindet. Wenn Sie keine Vorschau des Portals anzeigen und testen können, überprüfen Sie Ihre Einstellungen, um sicherzustellen, dass Ihre Konfiguration in einer Sandbox gespeichert ist. Damit die Vorschau und das Testen funktionieren, müssen Sie auch über die Berechtigung zum Bearbeiten im Dashboard verfügen. ## Stripe einrichten [Serverseitig] ### Serverseitig #### Ruby ```bash # Available as a gem sudo gem install stripe ``` ```ruby # If you use bundler, you can add this line to your Gemfile gem 'stripe' ``` Installieren Sie als Nächstes die Stripe CLI. Mit der CLI können Sie die erforderlichen [Webhook](https://docs.stripe.com/webhooks.md#test-webhook)-Tests durchführen. Weitere Installationsoptionen finden Sie unter [Mit der Stripe-CLI loslegen](https://docs.stripe.com/stripe-cli.md). ### Clientseitig Das [Stripe iOS SDK](https://github.com/stripe/stripe-ios) ist Open Source, [vollständig dokumentiert](https://stripe.dev/stripe-ios/index.html) und kompatibel mit Apps, die iOS 13 oder höher unterstützen. #### Swift Package Manager Führen Sie zur Installation des SDK die folgenden Schritte aus: 1. Wählen Sie in Xcode **Datei** > **Add Package Dependencies** (Paketabhängigkeiten hinzufügen) aus und geben Sie als Repository-URL `https://github.com/stripe/stripe-ios-spm` ein. 1. Wählen auf unserer [Veröffentlichungsseite](https://github.com/stripe/stripe-ios/releases) die neueste Version aus. 1. Fügen Sie das Produkt **StripePaymentSheet** zum [Ziel Ihrer App](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app) hinzu. #### CocoaPods 1. Falls noch nicht geschehen, installieren Sie bitte die aktuellste Version von [CocoaPods](https://guides.cocoapods.org/using/getting-started.html). 1. Wenn Sie keine bestehende [Podfile](https://guides.cocoapods.org/syntax/podfile.html) haben, führen Sie folgenden Befehl aus, um eine zu erstellen: ```bash pod init ``` 1. Fügen Sie folgende Zeile in Ihre `Podfile` ein: ```podfile pod 'StripePaymentSheet' ``` 1. Führen Sie folgenden Befehl aus: ```bash pod install ``` 1. Vergessen Sie nicht, ab jetzt in Zukunft anstelle der Datei `.xcodeproj` die Datei `.xcworkspace` zum Öffnen Ihres Projekts in Xcode zu verwenden. 1. Führen Sie für zukünftige Updates auf die jeweils aktuelle Version des SDK Folgendes aus: ```bash pod update StripePaymentSheet ``` #### Carthage 1. Falls noch nicht geschehen, installieren Sie bitte die aktuelle Version von [Carthage](https://github.com/Carthage/Carthage#installing-carthage). 1. Fügen Sie folgende Zeile in Ihre `Cartfile` ein: ```cartfile github "stripe/stripe-ios" ``` 1. Befolgen Sie die [Carthage-Installationsanweisungen](https://github.com/Carthage/Carthage#if-youre-building-for-ios-tvos-or-watchos). Vergewissern Sie sich, dass Sie alle [hier](https://github.com/stripe/stripe-ios/tree/master/StripePaymentSheet/README.md#manual-linking) aufgeführten erforderlichen Frameworks einbetten. 1. Führen Sie für zukünftige Updates auf die aktuelle Version unseres SDK einfach folgenden Befehl aus: ```bash carthage update stripe-ios --platform ios ``` #### Manuelles Framework 1. Gehen Sie auf unsere [GitHub-Release-Seite](https://github.com/stripe/stripe-ios/releases/latest), laden Sie **Stripe.xcframework.zip** herunter und entpacken Sie die Datei. 1. Ziehen Sie **StripePaymentSheet.xcframework** in den Abschnitt **Embedded Binaries** (Eingebettete Binärdateien) der Einstellungen unter **General** (Allgemeines) Ihres Xcode-Projekts. Aktivieren Sie dabei die Option **Copy items if needed** (Elemente kopieren, falls nötig). 1. Wiederholen Sie Schritt 2 für alle [hier](https://github.com/stripe/stripe-ios/tree/master/StripePaymentSheet/README.md#manual-linking) aufgeführten erforderlichen Frameworks. 1. Wiederholen Sie für zukünftige Updates auf die jeweils aktuelle Version des SDK die Schritte 1–3. > Details zur aktuellen SDK-Version und zu vorherigen Versionen finden Sie auf der Seite [Releases](https://github.com/stripe/stripe-ios/releases) auf GitHub. Um bei Veröffentlichung einer neuen Version eine Benachrichtigung zu erhalten, [achten Sie auf die Releases zum jeweiligen Repository](https://help.github.com/en/articles/watching-and-unwatching-releases-for-a-repository#watching-releases-for-a-repository). Sie müssen auch Ihren [veröffentlichbaren Schlüssel](https://dashboard.stripe.com/apikeys) festlegen, damit das SDK API Aufrufe an Stripe tätigen kann. Um schnell loszulegen, können Sie dies während der Integration auf dem Client fest codieren, aber den veröffentlichbaren Schlüssel von Ihrem Server in der Produktionsumgebung abrufen. ```swift // Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys STPAPIClient.shared.publishableKey = "<>" ``` ## Eine Portalsitzung erstellen [Serverseitig] Wenn Kundinnen/Kunden Änderungen an ihrem Abonnement vornehmen möchten, generieren Sie eine URL für die Portalseite unter Verwendung ihrer Stripe-Kunden-ID über die Portal Session API. #### Node.js ```javascript // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. // Find your keys at https://dashboard.stripe.com/apikeys. const stripe = require('stripe')('<>'); app.get('/customer_portal_url', async (req, res) => { // Replace this with your actual customer lookup logic const customerId = 'cus_...'; // Get this from your database const billingSession = await stripe.billingPortal.sessions.create({ customer: customerId, return_url: 'https://example.com/portal_redirect', }); res.json({ url: billingSession.url }); }) ``` ## Universelle Links einrichten [Clientseitig] [Serverseitig] *Universelle Links* (Use Universal links on iOS and macOS to link directly to in-app content. They're standard HTTPS links, so the same URL works for your website and your app) ermöglichen es dem Kundenportal, einen Deep-Link zu Ihrer App herzustellen. So konfigurieren Sie einen universellen Link: 1. Fügen Sie Ihrer Domain eine `apple-app-site-association`-Datei hinzu. 1. Fügen Sie Ihrer App eine Berechtigung für die zugewiesenen Domains (“Associated Domains”) hinzu. 1. Fügen Sie eine Fallbackseite für Ihre Portal-Umleitungs-URLs hinzu. #### Definieren Sie die zugewiesenen Domains Fügen Sie Ihrer Domain eine Datei unter **.well-known/apple-app-site-association** hinzu, um die URLs zu definieren, die Ihre App verarbeitet. Stellen Sie Ihrer App-ID die Team-ID voran, die Sie auf der [Mitgliedschafts-Seite des Apple Developer Portals](https://developer.apple.com/account) finden. ```json { "applinks": { "apps": [], "details": [ { "appIDs": [ "A28BC3DEF9.com.example.MyApp1", "A28BC3DEF9.com.example.MyApp1-Debug" ], "components": [ { "/": "/checkout_redirect*", "comment": "Matches any URL whose path starts with /checkout_redirect" } ] } ] } } ``` Sie müssen der Datei den MIME-Typ `application/json` hinzufügen. Mit `curl -I` bestätigen Sie den Inhaltstyp. ```bash curl -I https://example.com/.well-known/apple-app-site-association ``` Auf der Seite [Zugewiesene Domains unterstützen](https://developer.apple.com/documentation/xcode/supporting-associated-domains) von Apple finden Sie weitere Einzelheiten hierzu. #### Fügen Sie Ihrer App eine Berechtigung für die zugewiesenen Domains (“Associated Domains”) hinzu. 1. Öffnen Sie den Bereich **Signierung & Kapazitäten** der Zielanwendung Ihrer App. 1. Klicken Sie auf **+ Funktion** und wählen Sie dann **Zugewiesene Domains** aus. 1. Fügen Sie einen Eintrag für `applinks:example.com` zur Liste der **Zugewiesenen Domains** hinzu. Weitere Informationen zu universellen Links finden Sie auf der Seite [Universelle Links für Entwickler](https://developer.apple.com/ios/universal-links/) von Apple. Obgleich iOS Links an die in Ihrer `apple-app-site-association`-Datei definierten URLs abruft, kann es zu Situationen kommen, in denen die Umleitung Ihre App nicht öffnen kann. Erstellen Sie in Ihrem `return_url` eine Fallback-Seite. Sie können beispielsweise [ein benutzerdefiniertes URL-Schema für Ihre App definieren](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app) und es verwenden, um eine Verknüpfung herzustellen, falls der universelle Link fehlschlägt. ## Öffnen Sie das Kundenportal in Safari [Clientseitig] Fügen Sie eine Schaltfläche hinzu, um das Kundenportal in Ihrer App zu öffnen. Diese Schaltfläche: 1. Ruft Ihren serverseitigen Endpoint auf, um eine Portalsitzung zu erstellen. 1. Gibt die URL der Portalseite an den Client zurück. 1. Öffnet die URL in Safari. ```swift import Foundation import SwiftUI import StoreKit struct SubscriptionManagementView: View { @EnvironmentObject var myBackend: MyServer var body: some View { // Check if payments are blocked by Parental Controls on this device. if !SKPaymentQueue.canMakePayments() { Text("Payments are disabled on this device.") } else { Button { myBackend.createCustomerPortalSession { url in UIApplication.shared.open(url, options: [:], completionHandler: nil) } } label: { Text("Manage subscriptions") }.onOpenURL { url in // Handle the universal link from the customer portal. // Implement any necessary behavior, such as refreshing the customer's subscription status. } } } } ``` ## Änderungen am Status von Kundenabonnements verarbeiten [Serverseitig] Wenn Kundinnen/Kunden über das Kundenportal Änderungen an ihrem Abonnementstatus vornehmen, sendet Stripe Ihnen *Webhooks* (A webhook is a real-time push notification sent to your application as a JSON payload through HTTPS requests) wie `customer.subscription.created`, `customer.subscription.deleted` und `customer.subscription.updated`. Eine vollständige Liste der Ereignisse und Informationen dazu finden Sie unter [Webhooks mit Abonnements verwenden](https://docs.stripe.com/billing/subscriptions/webhooks.md). Stellen Sie sicher, dass Sie alle Ereignisse verarbeiten, die erforderlich sind, um den Status der von Ihnen konfigurierten Abonnements genau zu überwachen. Zu Testzwecken können Sie Ereignisse im [Dashboard](https://dashboard.stripe.com/events) überwachen oder die [Stripe-CLI](https://docs.stripe.com/webhooks.md#test-webhook) verwenden. Richten Sie in der Produktion einen Webhook-Endpoint ein und abonnieren Sie die entsprechenden Ereignistypen. Wenn Sie Ihren `STRIPE_WEBHOOK_SECRET`-Schlüssel nicht kennen, klicken Sie auf den [Webhook](https://dashboard.stripe.com/webhooks)-Link im Dashboard, um ihn anzuzeigen. #### Node.js ```javascript const express = require('express'); const app = express(); // Set your secret key. Remember to switch to your live secret key in production. // See your keys here: https://dashboard.stripe.com/apikeys const stripe = require('stripe')('') app.post('/webhook', async (req, res) => { let data; let eventType; // Check if webhook signing is configured. const webhookSecret = "{{STRIPE_WEBHOOK_SECRET}}" // Beispiel: whsec_c7681Dm if (webhookSecret) { // Retrieve the event by verifying the signature using the raw body and secret. let event; let signature = req.headers["stripe-signature"]; try { event = stripe.webhooks.constructEvent( req.body, signature, webhookSecret ); } catch (err) { console.log(`⚠️ Webhook signature verification failed.`); return res.sendStatus(400); } // Extract the object from the event. data = event.data; eventType = event.type; } else { // Webhook signing is recommended, but if the secret is not configured in `config.js`, // retrieve the event data directly from the request body. data = req.body.data; eventType = req.body.type; } switch (eventType) { case 'customer.subscription.created': { const subscription = event.data.object; const customerId = subscription.customer; myUserDB.setUserSubscriptionIsActive(customerId, true); break; } case 'customer.subscription.deleted': { const subscription = event.data.object; const customerId = subscription.customer; myUserDB.setUserSubscriptionIsActive(customerId, false); break; } // Add other relevant event types as needed } res.sendStatus(200); // Acknowledge receipt of the webhook }) ``` ## Optional: Deep Link zu bestimmten Seiten Möglicherweise möchten Sie die Arbeitsabläufe zwischen Ihrer eigenen App und Stripe weiter anpassen. Deep-Links im Kundenportal ermöglichen es Ihnen, direkt auf eine Seite zu verlinken, auf der die angegebene Aktion ausgeführt werden kann, und das Weiterleitungsverhalten nach Abschluss der Aktion durch den/die Kund/in anzupassen. Erfahren Sie mehr über die Verwendung von [Deep-Links im Kundenportal](https://docs.stripe.com/customer-management/portal-deep-links.md). ## See also - [Self-Service für Kundinnen/Kunden mit einem Kundenportal](https://docs.stripe.com/customer-management.md) - [Lebenszyklus eines Abonnements](https://docs.stripe.com/billing/subscriptions/overview.md#subscription-lifecycle) - [Testen von Abonnements](https://docs.stripe.com/billing/testing.md)