# In-App-Zahlungen annehmen Erstellen Sie mit dem Zahlungs-Element eine maßgeschneiderte Integration von Zahlungen in Ihrer iOS-, Android- oder React Native-App. Das Zahlungs-Element ist eine anpassbare Komponente, die eine Liste von Zahlungsmethoden anzeigt, die Sie in jeden Bildschirm Ihrer App einfügen können. Wenn Kunden/Kundinnen mit den Zahlungsmethoden in der Liste interagieren, öffnet die Komponente einzelne Unterseiten, um die Zahlungsdetails erfassen zu können. > #### Support für die Accounts v2 API > > Das Payment Sheet unterstützt *kundenkonfigurierte Konten* (Account configurations represent role-based functionality that you can enable for accounts, such as merchant, customer, or recipient) nicht. Es unterstützt nur `Customer`-Objekte. # Zahlung akzeptieren > This is a Zahlung akzeptieren for when platform is ios and type is payment. View the full page at https://docs.stripe.com/payments/mobile/accept-payment-embedded?platform=ios&type=payment. Mit einem PaymentIntent-Ablauf können Sie eine Zahlung in Ihrer App abwickeln. Bei dieser Integration rendern Sie das Zahlungs-Element, erstellen einen *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) und bestätigen eine Zahlung in Ihrer App. ## Stripe einrichten [Serverseitig] [Clientseitig] ### Serverseitig Diese Integration erfordert Endpoints auf Ihrem Server, die mit der Stripe-API kommunizieren können. Nutzen Sie unsere offiziellen Bibliotheken für den Zugriff auf die Stripe-API von Ihrem Server aus: #### 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' ``` ### Client-seitig 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. Zunächst können Sie den veröffentlichbaren Schlüssel während der Integration auf dem Client codieren, aber den veröffentlichbaren Schlüssel von Ihrem Server in der Produktion 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 = "<>" ``` ## Zahlungsmethoden aktivieren Zeigen Sie Ihre [Einstellungen für Zahlungsmethoden](https://dashboard.stripe.com/settings/payment_methods) an und aktivieren Sie die Zahlungsmethoden, die Sie unterstützen möchten. Sie müssen mindestens eine Zahlungsmethode aktiviert haben, um einen *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) zu erstellen. Standardmäßig aktiviert Stripe Karten und andere gängige Zahlungsmethoden, mit denen Sie mehr Kundinnen und Kunden erreichen können. Wir empfehlen jedoch, zusätzliche Zahlungsmethoden zu aktivieren, die für Ihr Unternehmen und Ihre Kundschaft relevant sind. Weitere Informationen zur Unterstützung von Produkten und Zahlungsmethoden finden Sie auf der Seite [Unterstützte Zahlungsmethoden](https://docs.stripe.com/payments/payment-methods/payment-method-support.md) und der [Preisseite](https://stripe.com/pricing/local-payment-methods) für Gebühren. ## Zahlungsdaten erfassen [Clientseitig] Das eingebettete Mobile Payment Element ist so konzipiert, dass es auf der Bezahlseite Ihrer nativen mobilen App platziert wird. Das Element zeigt eine Liste mit Zahlungsmethoden an, die Sie an das Erscheinungsbild Ihrer App anpassen können. Wenn Kundinnen/Kunden auf die Zeile **Karte** tippen, wird ein Formular geöffnet, in dem sie ihre Zahlungsdetails eingeben können. Die Schaltfläche im Formular zeigt standardmäßig **Fortfahren** an und schließt das Formular, wenn darauf getippt wird, sodass Ihre Kundinnen/Kunden die Zahlung in Ihrem Bezahlvorgang abschließen können. ![Payment Element](https://b.stripecdn.com/docs-statics-srv/assets/ios-embedded.b5867c116d537ffcb920dd80ebdfc741.png) Sie können die Schaltfläche auch so konfigurieren, dass die Zahlung sofort abgeschlossen wird, anstatt fortzufahren. Führen Sie dazu [diesen Schritt](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#embedded-let-customer-pay-immediately) aus, nachdem Sie der Anleitung gefolgt sind. #### UIKit ### Initialisieren des Zahlungs-Elements Rufen Sie `create` auf, um EmbeddedPaymentElement mit einer `EmbeddedPaymentElement.Configuration` und einer [PaymentSheet.IntentConfiguration](https://github.com/stripe/stripe-ios/blob/master/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheetIntentConfiguration.swift) zu instanziieren. Das Configuration-Objekt enthält universelle Konfigurationsoptionen für EmbeddedPaymentElement, die sich zwischen den Zahlungen nicht ändern, z. B. `returnURL`. Das`IntentConfiguration`-Objekt enthält Details über die spezifische Zahlung wie Betrag und Währungen sowie einen Rückruf `confirmationTokenConfirmHandler`. Lassen Sie die Implementierung vorerst leer. Nach der erfolgreichen Initialisierung legen Sie dessen Eigenschaften `presentingViewController` und `delegate` fest. ```swift import StripePaymentSheet class MyCheckoutVC: UIViewController { func createEmbeddedPaymentElement() async throws -> EmbeddedPaymentElement { let intentConfig = PaymentSheet.IntentConfiguration( mode: .payment(amount: 1099, currency: "USD") ) { [weak self] confirmationToken in return await self?.handleConfirmationToken(confirmationToken) } var configuration = EmbeddedPaymentElement.Configuration() configuration.returnURL = "your-app://stripe-redirect" // Use the return url you set up in the previous step let embeddedPaymentElement = try await EmbeddedPaymentElement.create(intentConfiguration: intentConfig, configuration: configuration) embeddedPaymentElement.presentingViewController = self embeddedPaymentElement.delegate = self return embeddedPaymentElement } func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // You'll implement this in the "Confirm the payment" section below } } ``` ### Hinzufügen der Ansicht Zahlungs-Elemente Nachdem EmbeddedPaymentElement erfolgreich initialisiert wurde, platzieren Sie seine Ansicht in der Nutzeroberfläche des Bezahlvorgangs. > Die Ansicht muss in einer scrollbaren Ansicht enthalten sein, z. B. UIScrollView, da sie keine feste Größe hat und die Höhe nach dem ersten Rendern ändern kann. ```swift class MyCheckoutVC: UIViewController { // ... private(set) var embeddedPaymentElement: EmbeddedPaymentElement? private lazy var checkoutButton: UIButton = { let checkoutButton = UIButton(type: .system) checkoutButton.backgroundColor = .systemBlue checkoutButton.layer.cornerRadius = 5.0 checkoutButton.clipsToBounds = true checkoutButton.setTitle("Checkout", for: .normal) checkoutButton.setTitleColor(.white, for: .normal) checkoutButton.translatesAutoresizingMaskIntoConstraints = false checkoutButton.isEnabled = embeddedPaymentElement?.paymentOption != nil checkoutButton.addTarget(self, action: #selector(didTapConfirmButton), for: .touchUpInside) return checkoutButton }() // ... @objc func didTapConfirmButton() { // You'll implement this in the "Confirm the payment" section below } override func viewDidLoad() { super.viewDidLoad() Task { @MainActor in do { // Create a UIScrollView let scrollView = UIScrollView() scrollView.translatesAutoresizingMaskIntoConstraints = false self.view.addSubview(scrollView) // Create the Payment Element let embeddedPaymentElement = try await createEmbeddedPaymentElement() embeddedPaymentElement.delegate = self embeddedPaymentElement.presentingViewController = self self.embeddedPaymentElement = embeddedPaymentElement // Add its view to the scroll view scrollView.addSubview(embeddedPaymentElement.view) // Add your own checkout button to the scroll view scrollView.addSubview(checkoutButton) // Set up layout constraints embeddedPaymentElement.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), embeddedPaymentElement.view.topAnchor.constraint(equalTo: scrollView.topAnchor), embeddedPaymentElement.view.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor), embeddedPaymentElement.view.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor), checkoutButton.topAnchor.constraint(equalTo: embeddedPaymentElement.view.bottomAnchor, constant: 4.0), checkoutButton.leadingAnchor.constraint(equalTo: scrollView.safeAreaLayoutGuide.leadingAnchor, constant: 4.0), checkoutButton.trailingAnchor.constraint(equalTo: scrollView.safeAreaLayoutGuide.trailingAnchor, constant: -4.0), ]) } catch { // Handle view not being added to view } } } } ``` An dieser Stelle können Sie Ihre App ausführen und das eingebettete Mobile Payment Element sehen. ### Umgang mit Änderungen bei der Höhe Die Ansicht des EmbeddedPaymentElement kann vergrößert oder verkleinert werden, was sich auf das Layout der Ansicht auswirken kann. Verarbeiten Sie Höhenänderungen, indem Sie die Delegatmethode `embeddedPaymentElementDidUpdateHeight` implementieren. Die Ansicht von EmbeddedPaymentElement ruft diese Methode in einem Animationsblock auf, der seine Höhe aktualisiert. Es wird erwartet, dass Ihre Implementierung `setNeedsLayout()` und `layoutIfNeeded()` in der Bildlaufansicht aufruft, die die Ansicht des EmbeddedPaymentElement enthält, um eine reibungslose Animation der Höhenänderung zu ermöglichen. ```swift extension MyCheckoutVC: EmbeddedPaymentElementDelegate { func embeddedPaymentElementDidUpdateHeight(embeddedPaymentElement: StripePaymentSheet.EmbeddedPaymentElement) { // Handle layout appropriately self.view.setNeedsLayout() self.view.layoutIfNeeded() } } ``` Es wird empfohlen, dass Sie testen, ob die Ansicht ordnungsgemäß auf Höhenänderungen reagiert. Rufen Sie dazu `testHeightChange()` in EmbeddedPaymentElement auf, um das Ein- und Ausblenden eines Mandats innerhalb des Elements zu simulieren. Stellen Sie sicher, dass Sie sich nach dem Aufruf von `testHeightChange()` Ihre Scrollansicht reibungslos anpasst. ```swift class MyCheckoutVC: UIViewController { override func viewDidLoad() { // This is only for testing purposes: #if DEBUG Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true) { [weak self] _ in Task { @MainActor in self?.embeddedPaymentElement?.testHeightChange() } } #endif } } ``` ### (Optional) Ausgewählte Zahlungsoption anzeigen Wenn Sie auf Details zur vom Kunden ausgewählten Zahlungsoption zugreifen müssen, wie ein Label (z. B. „····4242“), ein Bild (z. B. ein VISA-Logo) oder Abrechnungsdetails, die in Ihrer Nutzeroberfläche angezeigt werden sollen, verwenden Sie die Eigenschaft `paymentOption` von EmbeddedPaymentElement. Um benachrichtigt zu werden, wenn sich die `paymentOption` ändert, implementieren Sie die Delegatmethode `embeddedPaymentElementDidUpdatePaymentOption`. ```swift extension MyCheckoutVC: EmbeddedPaymentElementDelegate { func embeddedPaymentElementDidUpdatePaymentOption(embeddedPaymentElement: EmbeddedPaymentElement) { print("The payment option changed: \(embeddedPaymentElement.paymentOption)") checkoutButton.isEnabled = embeddedPaymentElement.paymentOption != nil } } ``` ### (Optional) Zahlungsangaben aktualisieren Wenn der Kunde/die Kundin Aktionen durchführt, die die Zahlungsdetails ändern (z. B. das Anwenden eines Rabattcodes), aktualisieren Sie die `EmbeddedPaymentElement`-Instanz, um die neuen Werte widerzugeben, indem Sie die `update`-Methode aufrufen. Bei einigen Zahlungsmethoden, wie Apple Pay und Google Pay, wird der Betrag in der Nutzeroberfläche angezeigt. Stellen Sie daher sicher, dass er immer korrekt und aktuell ist. Wenn der Aktualisierungsaufruf abgeschlossen ist, aktualisieren Sie Ihre Nutzeroberfläche. Durch den Aktualisierungsaufruf kann sich die aktuell ausgewählte Zahlungsoption des Kunden/der Kundin ändern. ```swift extension MyCheckoutVC { func update() { Task { @MainActor in var updatedIntentConfig = oldIntentConfig // Update the amount to reflect the price after applying the discount code updatedIntentConfig.mode = PaymentSheet.IntentConfiguration.Mode.payment(amount: 999, currency: "USD") let result = await embeddedPaymentElement?.update(intentConfiguration: updatedIntentConfig) switch result { case .canceled, nil: // Do nothing; this happens when a subsequent `update` call cancels this one break case .failed(let error): // Display error to user in an alert, let users retry case .succeeded: // Update your UI in case the payment option changed } } } } ``` ### Zahlung bestätigen Wenn der/die Kund/in auf die Checkout-Schaltfläche tippt, rufen Sie `embeddedPaymentElement.confirm()` auf, um die Zahlung abzuschließen. Achten Sie darauf, die Nutzerinteraktion während der Bestätigung zu deaktivieren. ```swift extension MyCheckoutVC { @objc func didTapConfirmButton() { Task { @MainActor in guard let embeddedPaymentElement else { return } self.view.isUserInteractionEnabled = false // Disable user interaction, show a spinner, and so on before calling confirm. let result = await embeddedPaymentElement.confirm() switch result { case .completed: // Payment completed - show a confirmation screen. case .failed(let error): self.view.isUserInteractionEnabled = true // Encountered an unrecoverable error. You can display the error to the user, log it, and so on. case .canceled: self.view.isUserInteractionEnabled = true // Customer canceled - you should probably do nothing. break } } } } ``` Implementieren Sie als Nächstes den Rückruf `confirmationTokenConfirmHandler`, den Sie zuvor an`PaymentSheet.IntentConfiguration` übergeben haben, um eine Anfrage an Ihren Server zu senden. Ihr Server erstellt einen PaymentIntent und gibt sein Client-Geheimnis zurück. Weitere Informationen zu diesem Prozess finden Sie unter [Erstellen eines PaymentIntent](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#submit-payment). Wenn die Anfrage zurückkommt, geben Sie das Client-Geheimnis Ihrer Serverantwort zurück oder geben Sie einen Fehler aus. Das EmbeddedPaymentElement bestätigt den PaymentIntent mithilfe des Client-Geheimnisses oder zeigt die lokalisierte Fehlermeldung in seiner Nutzeroberfläche an (entweder [errorDescription](https://developer.apple.com/documentation/foundation/localizederror/2946895-errordescription) oder [localizedDescription](https://developer.apple.com/documentation/foundation/nserror/1414418-localizeddescription)). Nach Abschluss der Bestätigung ist das EmbeddedPaymentElement nicht mehr verwendbar. Leiten Sie die/den Nutzer/in stattdessen zu einem Belegbildschirm oder einer ähnlichen Seite weiter. ```swift extension MyCheckoutVC { func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // Make a request to your own server. Pass `confirmationToken.stripeId` if using server-side confirmation, and return the client secret or throw an error. let myServerClientSecret = try await fetchIntentClientSecret(...) } } ``` #### SwiftUI ### Initialisieren des Zahlungs-Elements Rufen Sie `load` auf, um EmbeddedPaymentElementViewModel mit einer `EmbeddedPaymentElement.Configuration` und einer [PaymentSheet.IntentConfiguration](https://github.com/stripe/stripe-ios/blob/master/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheetIntentConfiguration.swift) zu laden. Das Configuration-Objekt enthält universelle Konfigurationsoptionen für EmbeddedPaymentElement, die sich zwischen den Zahlungen nicht ändern, z. B. `returnURL`. Das `IntentConfiguration`-Objekt enthält Details über die spezifische Zahlung wie den Betrag und die Währungen, sowie einen `confirmationTokenConfirmHandler`-Rückruf. Lassen Sie die Implementierung vorerst leer. ```swift import SwiftUI import StripePaymentSheet struct MyEmbeddedCheckoutView: View { // Store an `EmbeddedPaymentElementViewModel` as a `@StateObject` @StateObject var embeddedViewModel = EmbeddedPaymentElementViewModel() var body: some View { ScrollView { // Empty scroll view for now } .task { do { if !embeddedViewModel.isLoaded { // Load the view model with your configuration try await loadEmbeddedViewModel() } } catch { // On load failure, implement retry logic (automatic retry or user-triggered through UI). } } } private func loadEmbeddedViewModel() async throws { let intentConfiguration = PaymentSheet.IntentConfiguration( mode: .payment(amount: 1099, currency: "USD") ) { confirmationToken in try await self.handleConfirmationToken(confirmationToken) } var configuration = EmbeddedPaymentElement.Configuration() configuration.returnURL = "your-app://stripe-redirect" // Use the return url you set up in the previous step try await embeddedViewModel.load(intentConfiguration: intentConfiguration, configuration: configuration) } func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // You'll implement this in the "Confirm the payment" section below } } ``` ### Hinzufügen der Ansicht Zahlungs-Elemente Nachdem EmbeddedPaymentElementViewModel erfolgreich geladen wurde, fügen Sie in der Nutzeroberfläche Ihres Bezahlvorgangs EmbeddedPaymentElementView hinzu. > Die Ansicht muss in einer scrollbaren Ansicht wie ScrollView enthalten sein, da sie keine feste Größe hat und sich die Höhe nach dem ersten Rendern ändern kann. ```swift struct MyEmbeddedCheckoutView: View { var body: some View { ScrollView { // isLoaded becomes true only after a successful call to `embeddedViewModel.load()` if embeddedViewModel.isLoaded { EmbeddedPaymentElementView(viewModel: embeddedViewModel) } } } } ``` An dieser Stelle können Sie Ihre App ausführen und das eingebettete Mobile Payment Element sehen. ### Umgang mit Änderungen bei der Höhe Der EmbeddedPaymentElementView kann vergrößert oder verkleinert werden, was sich auf das Layout der Ansicht auswirken kann. Der EmbeddedPaymentElementView behandelt dies automatisch, wenn er sich in einer ScrollView befindet. Es wird empfohlen, dass Sie testen, ob die Ansicht ordnungsgemäß auf Höhenänderungen reagiert. Rufen Sie dazu `testHeightChange()` in EmbeddedPaymentElementViewModel auf, um das Ein- und Ausblenden eines Mandat innerhalb des Elements zu simulieren. Stellen Sie sicher, dass Sie sich nach dem Aufruf von `testHeightChange()` Ihre Scrollansicht reibungslos anpasst. ```swift struct MyEmbeddedCheckoutView: View { var body: some View { ScrollView { if embeddedViewModel.isLoaded { EmbeddedPaymentElementView(viewModel: embeddedViewModel) // For testing only #if DEBUG Button("Test height change") { embeddedViewModel.testHeightChange() } #endif } } } } ``` ### (Optional) Ausgewählte Zahlungsoption anzeigen Wenn Sie auf Details zur vom Kunden ausgewählten Zahlungsoption zugreifen müssen, wie ein Label (z. B. „····4242“), ein Bild (z. B. ein VISA-Logo) oder Rechnungsdetails, die in Ihrer Nutzeroberfläche angezeigt werden sollen, verwenden Sie die Eigenschaft `paymentOption` von EmbeddedPaymentElementViewModel. Wenn Kundinnen und Kunden eine Zahlungsmethode auswählen, die ein Formularblatt öffnet, wird die Zahlungsoption aktualisiert, nachdem sie im Formular auf **Weiter** getippt haben. ```swift struct MyEmbeddedCheckoutView: View { var body: some View { ScrollView { if embeddedViewModel.isLoaded { // ... // A real integration probably wouldn't show the selected payment option on the same screen as the embedded payment element. We display it as an example. if let paymentOption = embeddedViewModel.paymentOption { HStack { Image(uiImage: paymentOption.image) .resizable() .aspectRatio(contentMode: .fit) .frame(height: 30) Text(paymentOption.label) Spacer() } .padding() } } } } } ``` ### (Optional) Zahlungsangaben aktualisieren Wenn der Kunde/die Kundin Aktionen durchführt, die die Zahlungsdetails ändern (z. B. das Anwenden eines Rabattcodes), aktualisieren Sie die `EmbeddedPaymentElementViewModel`-Instanz, um die neuen Werte widerzugeben, indem Sie die `update`-Methode aufrufen. Bei einigen Zahlungsmethoden, wie Apple Pay und Google Pay, wird der Betrag in der Nutzeroberfläche angezeigt. Stellen Sie daher sicher, dass er immer korrekt und aktuell ist. Wenn die Aktualisierung abgeschlossen ist, wurde möglicherweise die aktuell ausgewählte Zahlungsoption des Kunden/der Kundin geändert. ```swift extension MyEmbeddedCheckoutView { func update() { Task { @MainActor in var updatedIntentConfig = oldIntentConfig updatedIntentConfig.mode = PaymentSheet.IntentConfiguration.Mode.payment(amount: 999, currency: "USD") let result = await embeddedViewModel.update(intentConfiguration: updatedIntentConfig) switch result { case .canceled: // Do nothing; this happens when a subsequent `update` call cancels this one break case .failed(let error): // Display error to user in an alert, let users retry case .succeeded: // Update your UI in case the payment option changed } } } } ``` ### Zahlung bestätigen Wenn Kundinnen/Kunden auf die Checkout-Schaltfläche tippen, rufen Sie `embeddedViewModel.confirm()` auf, um die Zahlung abzuschließen. Achten Sie darauf, die Nutzerinteraktion während der Bestätigung zu deaktivieren. ```swift extension MyEmbeddedCheckoutView { func didTapConfirmButton() { Task { @MainActor in // Be sure to disable user interaction during confirm (not shown in this example) let result = await embeddedViewModel.confirm() switch result { case .completed: // Payment completed - show a confirmation screen. case .failed(let error): // Encountered an unrecoverable error. Re-enable user interaction, display the error to the user, log it, and so on. case .canceled: // Customer canceled - re-enable user interaction and let them try again. break } } } } ``` Implementieren Sie als Nächstes den Rückruf `confirmationTokenConfirmHandler`, den Sie zuvor an`PaymentSheet.IntentConfiguration` übergeben haben, um eine Anfrage an Ihren Server zu senden. Ihr Server erstellt einen PaymentIntent und gibt sein Client-Geheimnis zurück. Weitere Informationen zu diesem Prozess finden Sie unter [Erstellen eines PaymentIntent](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#submit-payment). Geben Sie das Client Secret aus der Serverantwort zurück oder geben Sie einen Fehler. Das EmbeddedPaymentElement bestätigt den PaymentIntent mithilfe des Client-Geheimnisses oder zeigt die lokalisierte Fehlermeldung in seiner Nutzeroberfläche an (entweder [errorDescription](https://developer.apple.com/documentation/foundation/localizederror/2946895-errordescription) oder [localizedDescription](https://developer.apple.com/documentation/foundation/nserror/1414418-localizeddescription)). Nach Abschluss der Bestätigung kann das EmbeddedPaymentElement nicht mehr verwendet werden. Leiten Sie die Nutzerin oder den Nutzer stattdessen zu einem Zahlungsbeleg oder einer ähnlichen Seite weiter. ```swift extension MyEmbeddedCheckoutView { func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // Make a request to your own server. Pass confirmationToken.stripeId if using server-side confirmation. // Return the client secret or throw an error return try await MyAPIClient.shared.createIntent(confirmationTokenId: confirmationToken.stripeId) } } ``` ## Optional: Ausgewählte Zahlungsoption löschen Wenn Sie Zahlungsoptionen außerhalb von EmbeddedPaymentElement haben, müssen Sie möglicherweise die ausgewählte Zahlungsoption löschen. Verwenden Sie dazu die `clearPaymentOption` API, um die ausgewählte Zahlungsoption zu deaktivieren. #### UIKit ```swift extension MyCheckoutVC: UIViewController { func deselectPaymentMethod() { embeddedPaymentElement?.clearPaymentOption() } } ``` #### SwiftUI ```swift @available(iOS 15.0, *) extension MyEmbeddedCheckoutView { func deselectPaymentMethod() { embeddedViewModel.clearPaymentOption() } } ``` ## Optional: Mandat selbst anzeigen Standardmäßig zeigt das eingebettete Mobile Payment Element Mandate und rechtliche Haftungsausschlüsse an, um die Einhaltung gesetzlicher Vorschriften zu gewährleisten. Dieser Text muss sich in der Nähe Ihrer Schaltfläche „Kaufen“ befinden. Deaktivieren Sie ggf. die Anzeige in der Ansicht und zeigen Sie sie stattdessen selbst an. > Ihre Integration muss den Mandatstext anzeigen, um die Konformität zu gewährleisten. Stellen Sie sicher, dass URLs im Text mithilfe von UITextView oder Ähnlichem geöffnet werden können. #### UIKit ```swift var configuration = EmbeddedPaymentElement.Configuration(...) configuration.embeddedViewDisplaysMandateText = true ... let mandateTextView = UITextView() mandateTextView.attributedText = embeddedPaymentElement.paymentOption.mandateText ``` #### SwiftUI ```swift var configuration = EmbeddedPaymentElement.Configuration(...) configuration.embeddedViewDisplaysMandateText = true ... if let attributedText = embeddedViewModel.paymentOption?.mandateText { Text(AttributedString(attributedText)) } ``` ## Optional: Lassen Sie den Kunden/die Kundin sofort im Formular bezahlen ![Eingebettetes Zahlungs-Element](https://b.stripecdn.com/docs-statics-srv/assets/embedded-pay-immediate.057c691220d43158ac8000de10815ed9.png) Um die Schaltfläche im Formular zur sofortigen Bestätigung der Zahlung zu konfigurieren, legen Sie `formSheetAction` für Ihr `EmbeddedPaymentElement.Configuration`-Objekt fest. Der Completion-Block wird mit dem Ergebnis der Zahlung ausgeführt, nachdem das Formular geschlossen wurde. Die eingebettete Nutzeroberfläche kann nach Abschluss der Zahlung nicht verwendet werden. Wir empfehlen daher, dass Ihre Implementierung die Nutzer/innen zu einem anderen Bildschirm weiterleitet, z. B. einem Zahlungsbeleg-Bildschirm. ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.formSheetAction = .confirm(completion: { result in switch result { case .completed: // Payment completed. You can for example, show a confirmation screen. print("Completed") case .failed(let error): // Encountered an unrecoverable error. You can display the error to the user, log it, etc. print(error) case .canceled: // Customer canceled - you should probably do nothing. break } }) ``` ## PaymentIntent erstellen [Serverseitig] Erstellen Sie auf Ihrem Server a *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) durch Angabe eines Betrags und einer Währung. Sie können Zahlungsmethoden über das [Dashboard](https://dashboard.stripe.com/settings/payment_methods) verwalten. Stripe handhabt die Rückgabe geeigneter Zahlungsmethoden basierend auf Faktoren wie Betrag, Währung und Zahlungsablauf der Transaktion. Um zu verhindern, dass böswillige Kundinnen und Kunden ihre eigenen Preise wählen, sollten Sie den Preis immer auf der Serverseite (einer vertrauenswürdigen Umgebung) festlegen und nicht auf dem Client. Wenn der Aufruf erfolgreich ist, geben Sie den PaymentIntent *das Client-Geheimnis* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) zurück. Wenn der Aufruf fehlschlägt, [beheben Sie den Fehler](https://docs.stripe.com/error-handling.md) und geben eine Fehlermeldung mit einer kurzen Erklärung an Ihre Kundin/Ihren Kunden zurück. > Überprüfen Sie, ob alle IntentConfiguration-Eigenschaften mit Ihrem PaymentIntent (zum Beispiel `setup_future_usage`, `amount` und `currency`) übereinstimmen. #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') post '/create-intent' do data = JSON.parse request.body.read params = { amount: 1099, currency: 'usd', automatic_payment_methods: {enabled: true}, } begin intent = client.v1.payment_intents.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` ## Rückgabe-URL einrichten [Clientseitig] Der Kunde/Die Kundin verlässt ggf. Ihre App, um sich zu authentifizieren (z. B. in Safari oder einer Banking-App). Damit sie nach der Authentifizierung automatisch zu Ihrer App zurückkehren können, [konfigurieren Sie ein benutzerdefiniertes URL-Schema](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app) und richten Sie Ihren App-Delegate so ein, dass die URL an das SDK weitergeleitet wird. Stripe unterstützt keine [universellen Links](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content). #### SceneDelegate #### Swift ```swift // This method handles opening custom URL schemes (for example, "your-app://stripe-redirect") func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { guard let url = URLContexts.first?.url else { return } let stripeHandled = StripeAPI.handleURLCallback(with: url) if (!stripeHandled) { // This was not a Stripe url – handle the URL normally as you would } } ``` #### AppDelegate #### Swift ```swift // This method handles opening custom URL schemes (for example, "your-app://stripe-redirect") func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { let stripeHandled = StripeAPI.handleURLCallback(with: url) if (stripeHandled) { return true } else { // This was not a Stripe url – handle the URL normally as you would } return false } ``` #### SwiftUI #### Swift ```swift @main struct MyApp: App { var body: some Scene { WindowGroup { Text("Hello, world!").onOpenURL { incomingURL in let stripeHandled = StripeAPI.handleURLCallback(with: incomingURL) if (!stripeHandled) { // This was not a Stripe url – handle the URL normally as you would } } } } } ``` Legen Sie außerdem die [returnURL](https://github.com/stripe/stripe-ios/blob/aa3234a7fafde98c9203b6ed77e0278c04310eb0/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L70) für Ihr [EmbeddedPaymentElement.Configuration](https://github.com/stripe/stripe-ios/blob/aa3234a7fafde98c9203b6ed77e0278c04310eb0/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L12)-Objekt auf die URL für Ihre App fest. ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.returnURL = "your-app://stripe-redirect" ``` ## Ereignisse nach Zahlung verarbeiten [Serverseitig] Stripe sendet ein [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded)-Ereignis, wenn die Zahlung abgeschlossen ist. Verwenden Sie [Webhook-Tool im Dashboard](https://dashboard.stripe.com/webhooks) oder folgen Sie der [Webhook-Anleitung](https://docs.stripe.com/webhooks/quickstart.md), um diese Ereignisse zu empfangen und führen Sie Aktionen aus, wie beispielsweise das Senden einer Bestellbestätigung per E-Mail, das Protokollieren des Verkaufs in der Datenbank oder das Starten eines Versand-Workflows. Überwachen Sie diese Ereignisse, statt auf einen Callback vom Client zu warten. Auf dem Client könnten die Kund/innen das Browserfenster schließen oder die App beenden, bevor der Callback erfolgt ist. Bösartige Clients könnten dann die Antwort manipulieren. Wenn Sie Ihre Integration so einrichten, dass sie asynchrone Ereignisse überwacht, können Sie [verschiedene Arten von Zahlungsmethoden](https://stripe.com/payments/payment-methods-guide) mit einer einzelnen Integration akzeptieren. Neben der Abwicklung des `payment_intent.succeeded`-Ereignisses empfehlen wir die Abwicklung von diesen weiteren Ereignissen, wenn Sie Zahlungen mit dem Payment Element erfassen: | Ereignis | Beschreibung | Aktion | | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded) | Wird gesendet, wenn Kundinnen und Kunden eine Zahlung erfolgreich abgeschlossen haben. | Senden Sie den Kund/innen eine Auftragsbestätigung und *wickeln* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected) Sie die Bestellung ab. | | [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing) | Wird gesendet, wenn eine/e Kund/in eine Zahlung erfolgreich veranlasst hat, die Zahlung aber noch nicht abgeschlossen ist. Dieses Ereignis wird am häufigsten gesendet, wenn der Kunde/die Kundin eine Bankabbuchung veranlasst. In Zukunft folgt darauf entweder ein `payment_intent.succeeded`- oder ein `payment_intent.payment_failed`-Ereignis. | Senden Sie eine Bestellbestätigung an die Kund/innen, in der angegeben ist, dass die Zahlung noch aussteht. Bei digitalen Waren können Sie die Bestellung abwickeln, bevor Sie darauf warten, dass die Zahlung erfolgt. | | [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | Wird gesendet, wenn ein Kunde/eine Kundin einen Zahlungsversuch durchführt, die Zahlung jedoch fehlschlägt. | Wenn eine Zahlung von `processing` zu `payment_failed` übergeht, bieten Sie der Kundin/dem Kunden einen weiteren Zahlungsversuch an. | ## Integration testen #### Karten | Kartennummer | Szenario | So führen Sie den Test durch | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | | 4242424242424242 | Die Kartenzahlung ist erfolgreich und es ist keine Authentifizierung erforderlich. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 4000002500003155 | Für die Kartenzahlung ist eine *Authentifizierung* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase) erforderlich. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 4000000000009995 | Die Karte wird mit einem Ablehnungscode wie `insufficient_funds` abgelehnt. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 6205500000000000004 | Die UnionPay-Karte hat eine variable Länge von 13 bis 19 Ziffern. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | #### Bankumleitungen | Zahlungsmethode | Szenario | So führen Sie den Test durch | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Bancontact, iDEAL | Ihr/e Kund/in konnte sich auf der iDEAL-Weiterleitungsseite für eine auf Weiterleitung basierende Zahlungsmethode mit sofortiger Benachrichtigung nicht authentifizieren. | Wählen Sie eine beliebige, auf Weiterleitung basierende Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung fehlgeschlagen**. | | Pay by Bank | Ihr Kunde/Ihre Kundin zahlt erfolgreich mit einer auf Weiterleitung basierenden Zahlungsmethode mit [verzögerter Benachrichtigung](https://docs.stripe.com/payments/payment-methods.md#payment-notification). | Wählen Sie die Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung abschließen**. | | Pay by Bank | Ihr/e Kund/in konnte sich auf der iDEAL-Weiterleitungsseite für eine auf Weiterleitung basierende Zahlungsmethode mit verzögerter Benachrichtigung nicht authentifizieren. | Wählen Sie die Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung fehlgeschlagen**. | | BLIK | BLIK-Zahlungen können aus verschiedenen Gründen fehlschlagen. Es gibt sofortige Fehler (der Code ist abgelaufen oder ungültig), verzögerte Fehler (die Bank lehnt ab) oder Zeitüberschreitungen (der/die Kund/in hat nicht rechtzeitig reagiert). | Verwenden Sie E-Mail-Muster, um [die verschiedenen Fehler zu simulieren](https://docs.stripe.com/payments/blik/accept-a-payment.md#simulate-failures) | #### Banklastschriften | Zahlungsmethode | Szenario | So führen Sie den Test durch | | ---------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | SEPA-Lastschrift | Ihr/e Kund/in zahlt erfolgreich mit dem SEPA-Lastschriftverfahren. | Füllen Sie das Formular mit der Kontonummer `AT321904300235473204` aus. Die bestätigte PaymentIntent geht zunächst in den Status „wird verarbeitet“ und dann drei Minuten später in den Status „erfolgreich“ über. | | SEPA-Lastschrift | Der Status der PaymentIntent Ihres/Ihrer Kund/in wechselt von `processing` zu `requires_payment_method`. | Füllen Sie das Formular mit der Kontonummer `AT861904300235473202` aus. | Hier finden Sie weitere Informationen zum [Testen](https://docs.stripe.com/testing.md) Ihrer Integration. ## Kartenscannen aktivieren Um die Unterstützung für das Scannen von Karten für iOS zu aktivieren, setzen Sie `NSCameraUsageDescription` (**Datenschutz – Beschreibung Kameranutzung**) in der `Info.plist` Ihrer Anwendung und geben einen Grund für den Zugriff auf die Kamera an (z. B. „Zum Scannen von Karten“). ## Optional: Karten speichern [Serverseitig] [Clientseitig] `EmbeddedPaymentElement` kann es Kundinnen und Kunden ermöglichen, ihre Karte zu speichern, und die gespeicherten Karten des Kunden/der Kundin in die verfügbaren Zahlungsmethoden aufnehmen. Der Kunde/Die Kundin muss über ein zugehöriges, vom Kunden/von der Kundin konfiguriertes [Account](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer)-Objekt oder [Customer](https://docs.stripe.com/api/customers/create.md)-Objekt auf Ihrem Server verfügen. Um ein Kontrollkästchen zu aktivieren, mit dem der Kunde/die Kundin seine/ihre Karte speichern kann, erstellen Sie eine [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) mit `enabled` für `payment_method_save`. #### Accounts v2 ```javascript const stripe = require('stripe')('sk_test_your_secret_key'); app.post('/mobile-payment-element', async (req, res) => { // Use an existing Account ID if this is a returning customer. const customer_account = await stripe.v2.core.accounts.create(); const customerSession = await stripe.customerSessions.create({ customer_account: customer_account.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer_account: customer_account.id, }); }); ``` Konfigurieren Sie als Nächstes EmbeddedPaymentElement mit der ID des Kunden/der Kundin und dem Client-Geheimnis der CustomerSession. #### UIKit ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet var configuration = EmbeddedPaymentElement.Configuration() configuration.customer = .init(id: customerAccountId, customerSessionClientSecret: customerSessionClientSecret) self.embeddedPaymentElement = try await EmbeddedPaymentElement.create(..., configuration: configuration) ``` #### SwiftUI ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet var configuration = EmbeddedPaymentElement.Configuration() configuration.customer = .init(id: customerAccountId, customerSessionClientSecret: customerSessionClientSecret) try await embeddedViewModel.load(..., configuration: configuration) ``` #### Customers v1 ```javascript const stripe = require('stripe')('sk_test_your_secret_key'); app.post('/mobile-payment-element', async (req, res) => { // Use an existing Customer ID if this is a returning customer. const customer = await stripe.customers.create(); const customerSession = await stripe.customerSessions.create({ customer: customer.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer: customer.id, }); }); ``` Konfigurieren Sie als Nächstes EmbeddedPaymentElement mit der ID des Kunden/der Kundin und dem Client-Geheimnis der CustomerSession. #### UIKit ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet var configuration = EmbeddedPaymentElement.Configuration() configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret) self.embeddedPaymentElement = try await EmbeddedPaymentElement.create(..., configuration: configuration) ``` #### SwiftUI ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet var configuration = EmbeddedPaymentElement.Configuration() configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret) try await embeddedViewModel.load(..., configuration: configuration) ``` ## Optional: Zahlungsmethoden mit Verzögerung zulassen [Clientseitig] *Zahlungsmethoden mit Verzögerung* (A payment method that can't immediately return payment status when a customer attempts a transaction (for example, ACH debits). Businesses commonly hold an order in a pending state until payment is successful with these payment methods) garantieren nicht, dass Sie am Ende des Bezahlvorgangs Gelder von Ihrem Kunden/Ihrer Kundin erhalten, da die Abwicklung eine gewisse Zeit in Anspruch nimmt (z. B. bei US-Bankkonten, SEPA-Lastschrift, iDEAL und Bancontact) oder weil Kundinnen und Kunden aktiv werden müssen, um den Vorgang abzuschließen (z. B. OXXO, Konbini und Boleto). Standardmäßig zeigt EmbeddedPaymentElement keine Zahlungsmethoden mit Verzögerung an. Um die Funktion zu aktivieren, setzen Sie `allowsDelayedPaymentMethods` in Ihrer `EmbeddedPaymentElement.Configuration` auf „true“. Durch diesen Schritt allein werden keine bestimmten Zahlungsmethoden aktiviert. Er zeigt vielmehr an, dass Ihre App in der Lage ist, diese zu verarbeiten. Obwohl beispielsweise OXXO derzeit nicht von EmbeddedPaymentElement unterstützt wird, kann Ihre App OXXO als Zahlungsoption ohne zusätzliche Integrationsänderungen anzeigen, wenn es unterstützt wird und Sie auf die neueste SDK-Version aktualisiert haben. #### UIKit ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.allowsDelayedPaymentMethods = true self.embeddedPaymentElement = try await EmbeddedPaymentElement.create(..., configuration: configuration) ``` #### SwiftUI ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.allowsDelayedPaymentMethods = true try await embeddedViewModel.load(..., configuration: configuration) ``` Wenn die Kundin/der Kunde erfolgreich eine dieser Zahlungsmethoden mit Verzögerung in EmbeddedPaymentElement verwendet, lautet das zurückgegebene Zahlungsergebnis `.completed`. ## Optional: Apple Pay aktivieren > Wenn Ihr Zahlungsbildschirm eine spezielle **Apple Pay**-Schaltfläche enthält, folgen Sie dem [Apple Pay-Leitfaden](https://docs.stripe.com/apple-pay.md#present-payment-sheet) und verwenden Sie `ApplePayContext`, um Zahlungen über Ihre **Apple Pay**-Schaltfläche einzuziehen. Sie können `EmbeddedPaymentElement` verwenden, um andere Arten von Zahlungsmethoden zu handhaben. ### Eine Apple-Händler-ID registrieren Beantragen Sie eine Apple-Händler-ID, indem Sie sich auf der Apple Developer-Website [für eine neue Kennung registrieren](https://developer.apple.com/account/resources/identifiers/add/merchant). Tragen Sie eine Beschreibung und eine Kennung in das Formular ein. Die Beschreibung ist nur für Ihre internen Zwecke bestimmt und kann später geändert werden. Stripe empfiehlt, dass Sie den Namen Ihrer App als Kennung verwenden, zum Beispiel `merchant.com.{{YOUR_APP_NAME}}`. ### Neues Apple Pay-Zertifikat erstellen Erstellen Sie ein Zertifikat für Ihre App, um Zahlungsdaten zu verschlüsseln. Gehen Sie zu den [iOS-Zertifikateinstellungen](https://dashboard.stripe.com/settings/ios_certificates) im Dashboard, klicken Sie auf **Neue Anwendung hinzufügen** und befolgen Sie die Anleitung. Laden Sie eine Certificate Signing Request (CSR)-Datei herunter, um ein sicheres Zertifikat von Apple zu erhalten, mit dem Sie Apple Pay verwenden können. Eine CSR-Datei muss verwendet werden, um genau ein Zertifikat auszustellen. Wenn Sie Ihre Apple-Händler-ID wechseln, müssen Sie zu den [iOS-Zertifikateinstellungen](https://dashboard.stripe.com/settings/ios_certificates) im Dashboard gehen, um eine neue CSR und ein Zertifikat zu erhalten. ### Mit Xcode integrieren Fügen Sie Ihrer App die **Apple Pay**-Funktion hinzu. Öffnen Sie in Xcode Ihre Projekteinstellungen, klicken Sie auf die Registerkarte **Signing & Capabilities** (Anmeldung und Funktionen) und fügen Sie die **Apple Pay**-Funktion hinzu. Möglicherweise werden Sie an dieser Stelle aufgefordert, sich bei Ihrem Entwicklerkonto anzumelden. Wählen Sie die zuvor erstellte Händler-ID aus. Ihre App sollte nun Apple Pay unterstützen. ![](https://b.stripecdn.com/docs-statics-srv/assets/xcode.a701d4c1922d19985e9c614a6f105bf1.png) Apple Pay-Funktion in Xcode aktivieren ### Apple Pay hinzufügen #### Einmalige Zahlung Um Apple Pay zu EmbeddedPaymentElement hinzuzufügen, legen Sie [applePay](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L28) fest, nachdem Sie `EmbeddedPaymentElement.Configuration` mit Ihrer Apple-Händler-ID und dem [Ländercode](https://dashboard.stripe.com/settings/account) Ihres Unternehmens initialisiert haben. #### iOS (Swift) ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.applePay = .init( merchantId: "merchant.com.your_app_name", merchantCountryCode: "US" ) ``` #### Wiederkehrende Zahlungen Um Apple Pay zu EmbeddedPaymentElement hinzuzufügen, legen Sie [applePay](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L28) fest, nachdem Sie `EmbeddedPaymentElement.Configuration` mit Ihrer Apple-Händler-ID und dem [Ländercode](https://dashboard.stripe.com/settings/account) Ihres Unternehmens initialisiert haben. Gemäß den [Apple-Richtlinien](https://developer.apple.com/design/human-interface-guidelines/apple-pay#Supporting-subscriptions) für wiederkehrende Zahlungen müssen Sie auch zusätzliche Attribute für `PKPaymentRequest` festlegen. Fügen Sie in [ApplePayConfiguration.paymentRequestHandlers](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/paymentrequesthandler) einen Handler hinzu, um die [PKPaymentRequest.paymentSummaryItems](https://developer.apple.com/documentation/passkit/pkpaymentrequest/1619231-paymentsummaryitems) mit dem Betrag zu konfigurieren, den Sie berechnen möchten (z. B. 9,95 USD pro Monat). Sie können auch [Händler-Token](https://developer.apple.com/apple-pay/merchant-tokens/) übernehmen, indem Sie die Eigenschaften `recurringPaymentRequest` oder `automaticReloadPaymentRequest` für `PKPaymentRequest` festlegen. Weitere Informationen zur Verwendung wiederkehrender Zahlungen mit Apple Pay finden Sie in der [PassKit-Dokumentation von Apple](https://developer.apple.com/documentation/passkit/pkpaymentrequest). #### iOS (Swift) ```swift let customHandlers = EmbeddedPaymentElement.ApplePayConfiguration.Handlers( paymentRequestHandler: { request in // PKRecurringPaymentSummaryItem is available on iOS 15 or later if #available(iOS 15.0, *) { let billing = PKRecurringPaymentSummaryItem(label: "My Subscription", amount: NSDecimalNumber(string: "59.99")) // Payment starts today billing.startDate = Date() // Payment ends in one year billing.endDate = Date().addingTimeInterval(60 * 60 * 24 * 365) // Pay once a month. billing.intervalUnit = .month billing.intervalCount = 1 // recurringPaymentRequest is only available on iOS 16 or later if #available(iOS 16.0, *) { request.recurringPaymentRequest = PKRecurringPaymentRequest(paymentDescription: "Recurring", regularBilling: billing, managementURL: URL(string: "https://my-backend.example.com/customer-portal")!) request.recurringPaymentRequest?.billingAgreement = "You'll be billed $59.99 every month for the next 12 months. To cancel at any time, go to Account and click 'Cancel Membership.'" } request.paymentSummaryItems = [billing] request.currencyCode = "USD" } else { // On older iOS versions, set alternative summary items. request.paymentSummaryItems = [PKPaymentSummaryItem(label: "Monthly plan starting July 1, 2022", amount: NSDecimalNumber(string: "59.99"), type: .final)] } return request } ) var configuration = EmbeddedPaymentElement.Configuration() configuration.applePay = .init(merchantId: "merchant.com.your_app_name", merchantCountryCode: "US", customHandlers: customHandlers) ``` ### Sendungsverfolgung Um Informationen zur [Bestellverfolgung](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking) in iOS 16 oder höher hinzuzufügen, konfigurieren Sie einen [authorizationResultHandler](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/authorizationresulthandler) in Ihren `PaymentSheet.ApplePayConfiguration.Handlers`. Stripe ruft Ihre Implementierung auf, nachdem die Zahlung durchgeführt wurde, aber bevor iOS das Apple Pay-Formular schließt. Rufen Sie in Ihrer Implementierung von `authorizationResultHandler` die Bestelldetails für die abgeschlossene Bestellung von Ihrem Server ab. Fügen Sie die Details dem bereitgestellten [PKPaymentAuthorizationResult](https://developer.apple.com/documentation/passkit/pkpaymentauthorizationresult) hinzu und geben Sie das geänderte Ergebnis zurück. Weitere Informationen zur Sendungsverfolgung finden Sie in der [Apple-Dokumentation zu Wallet-Bestellungen](https://developer.apple.com/documentation/walletorders). #### iOS (Swift) ```swift let customHandlers = PaymentSheet.ApplePayConfiguration.Handlers( authorizationResultHandler: { result in do { // Fetch the order details from your service let myOrderDetails = try await MyAPIClient.shared.fetchOrderDetails(orderID: orderID) result.orderDetails = PKPaymentOrderDetails( orderTypeIdentifier: myOrderDetails.orderTypeIdentifier, // "com.myapp.order" orderIdentifier: myOrderDetails.orderIdentifier, // "ABC123-AAAA-1111" webServiceURL: myOrderDetails.webServiceURL, // "https://my-backend.example.com/apple-order-tracking-backend" authenticationToken: myOrderDetails.authenticationToken) // "abc123" // Return your modified PKPaymentAuthorizationResult return result } catch { return PKPaymentAuthorizationResult(status: .failure, errors: [error]) } } ) var configuration = EmbeddedPaymentElement.Configuration() configuration.applePay = .init(merchantId: "merchant.com.your_app_name", merchantCountryCode: "US", customHandlers: customHandlers) ``` ## Optional: Element anpassen Alle Anpassungen werden mithilfe des [EmbeddedPaymentElement.Configuration](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L12)-Objekts konfiguriert. ### Erscheinungsbild Passen Sie mit der [Appearance API](https://docs.stripe.com/elements/appearance-api/embedded-mobile.md?platform=ios) Farben, Schriftarten und mehr an das Erscheinungsbild Ihrer App an. ### Adressen der Nutzer/innen erfassen Erfassen Sie lokale und internationale Versand- und Rechnungsadressen von Ihren Kundinnen und Kunden mithilfe des [Address Element](https://docs.stripe.com/elements/address-element.md?platform=ios). ### Anzeigename des Händlers Geben Sie einen kundenorientierten Unternehmensnamen an, indem Sie [merchantDisplayName](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L66) festlegen. Standardmäßig handelt es sich dabei um den Namen Ihrer App. #### Swift ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.merchantDisplayName = "My app, Inc." ``` ### Dunkelmodus `EmbeddedPaymentElement` passt sich automatisch an die systemweiten Erscheinungsbildeinstellungen des Nutzers/der Nutzerin an (heller und dunkler Modus). Wenn Ihre App den dunklen Modus nicht unterstützt, können Sie den [Stil](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L51) auf den Modus `alwaysLight` oder `alwaysDark` festlegen. ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.style = .alwaysLight ``` ## Optional: Aktiveren der Funktion zur erneuten Erfassung der Prüfziffer/CVC bei Bestätigung Um die Prüfziffer einer gespeicherten Karte während der PaymentIntent-Bestätigung erneut einzuziehen, muss Ihre Integration Zahlungsdaten einziehen, bevor ein PaymentIntent erstellt wird. ### Intent-Konfiguration aktualisieren `PaymentSheet.IntentConfiguration` akzeptiert einen optionalen Parameter, mit dem gesteuert wird, wann die Prüfziffer/CVC für eine gespeicherte Karte erneut erfasst werden soll. ```swift let intentConfig = PaymentSheet.IntentConfiguration( mode: .payment(amount: 1099, currency: "USD"), confirmHandler: { confirmationToken in // Handle ConfirmationToken...}, requireCVCRecollection: true) ``` ### Parameter der Intent-Erstellung aktualisieren Um die Prüfziffer/CVC bei der Zahlungsbestätigung erneut zu erfassen, fügen Sie bei der Erstellung des PaymentIntent die beiden Parameter `customerId` und `require_cvc_recollection` ein. #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/create-intent' do data = JSON.parse request.body.read params = { amount: 1099, currency: 'usd', automatic_payment_methods: {enabled: true},customer: customer.id, payment_method_options: { card: {require_cvc_recollection: true} } } begin intent = client.v1.payment_intents.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` # Zahlungsmethode erfassen und speichern > This is a Zahlungsmethode erfassen und speichern for when platform is ios and type is setup. View the full page at https://docs.stripe.com/payments/mobile/accept-payment-embedded?platform=ios&type=setup. Ein SetupIntent-Ablauf ermöglicht es Ihnen, Zahlungsmethoden für zukünftige Zahlungen zu speichern, ohne eine Zahlung abzuwickeln. Bei dieser Integration rendern Sie das Zahlungs Element, erstellen einen *SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) und speichern die Zahlungsmethoden in Ihrer App. ## Stripe einrichten [Serverseitig] [Clientseitig] ### Serverseitig Diese Integration erfordert Endpoints auf Ihrem Server, die mit der Stripe-API kommunizieren können. Nutzen Sie unsere offiziellen Bibliotheken für den Zugriff auf die Stripe-API von Ihrem Server aus: #### 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' ``` ### Client-seitig 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. Zunächst können Sie den veröffentlichbaren Schlüssel während der Integration auf dem Client codieren, aber den veröffentlichbaren Schlüssel von Ihrem Server in der Produktion 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 = "<>" ``` ## Zahlungsmethoden aktivieren Zeigen Sie Ihre [Einstellungen für Zahlungsmethoden](https://dashboard.stripe.com/settings/payment_methods) an und aktivieren Sie die Zahlungsmethoden, die Sie unterstützen möchten. Sie müssen mindestens eine Zahlungsmethode aktiviert haben, um einen *SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) zu erstellen. Standardmäßig aktiviert Stripe Karten und andere gängige Zahlungsmethoden, mit denen Sie mehr Kundinnen und Kunden erreichen können. Wir empfehlen jedoch, zusätzliche Zahlungsmethoden zu aktivieren, die für Ihr Unternehmen und Ihre Kundschaft relevant sind. Weitere Informationen zur Unterstützung von Produkten und Zahlungsmethoden finden Sie auf der Seite [Unterstützte Zahlungsmethoden](https://docs.stripe.com/payments/payment-methods/payment-method-support.md) und der [Preisseite](https://stripe.com/pricing/local-payment-methods) für Gebühren. ## Legen Sie eine Kundin oder einen Kunden an [Serverseitig] Um eine Zahlungsmethode für zukünftige Zahlungen einzurichten, müssen Sie sie einem Objekt zuordnen, das Ihren Kunden/Ihre Kundin repräsentiert. Wenn Ihr Kunde/Ihre Kundin ein Konto erstellt oder die erste Transaktion mit Ihrem Unternehmen durchgeführt hat, erstellen Sie ein [Customer](https://docs.stripe.com/api/customers/create.md)-Objekt. ```curl curl -X POST https://api.stripe.com/v1/customers \ -u "<>:" ``` ## Zahlungsdaten erfassen [Clientseitig] Das eingebettete Mobile Payment Element ist so konzipiert, dass es auf der Bezahlseite Ihrer nativen mobilen App platziert wird. Das Element zeigt eine Liste mit Zahlungsmethoden an, die Sie an das Erscheinungsbild Ihrer App anpassen können. Wenn Kundinnen/Kunden auf die Zeile **Karte** tippen, wird ein Formular geöffnet, in dem sie ihre Zahlungsdetails eingeben können. Die Schaltfläche im Formular zeigt standardmäßig **Fortfahren** an und schließt das Formular, wenn darauf getippt wird. Dadurch können Ihre Kundinnen/Kunden die Einrichtung in Ihrem Bezahlvorgang abschließen. ![Payment Element](https://b.stripecdn.com/docs-statics-srv/assets/ios-embedded.b5867c116d537ffcb920dd80ebdfc741.png) Sie können die Schaltfläche so konfigurieren, dass die Einrichtung sofort abgeschlossen wird, anstatt fortzufahren. Führen Sie dazu [diesen Schritt](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#embedded-let-customer-pay-immediately) aus, nachdem Sie der Anleitung gefolgt sind. #### UIKit ### Initialisieren des Zahlungs-Elements Rufen Sie `create` auf, um EmbeddedPaymentElement mit einer `EmbeddedPaymentElement.Configuration` und einer [PaymentSheet.IntentConfiguration](https://github.com/stripe/stripe-ios/blob/master/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheetIntentConfiguration.swift) zu instanziieren. Das Configuration-Objekt enthält universelle Konfigurationsoptionen für EmbeddedPaymentElement, die sich zwischen den Zahlungen nicht ändern, z. B. `returnURL`. Das`IntentConfiguration`-Objekt enthält Details über die spezifische Zahlung wie Betrag und Währungen sowie einen Rückruf `confirmationTokenConfirmHandler`. Lassen Sie die Implementierung vorerst leer. Nach der erfolgreichen Initialisierung legen Sie dessen Eigenschaften `presentingViewController` und `delegate` fest. ```swift import StripePaymentSheet class MyCheckoutVC: UIViewController { func createEmbeddedPaymentElement() async throws -> EmbeddedPaymentElement { let intentConfig = PaymentSheet.IntentConfiguration( mode: .setup(currency: "USD") ) { [weak self] confirmationToken in return await self?.handleConfirmationToken(confirmationToken) } var configuration = EmbeddedPaymentElement.Configuration() configuration.returnURL = "your-app://stripe-redirect" // Use the return url you set up in the previous step let embeddedPaymentElement = try await EmbeddedPaymentElement.create(intentConfiguration: intentConfig, configuration: configuration) embeddedPaymentElement.presentingViewController = self embeddedPaymentElement.delegate = self return embeddedPaymentElement } func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // You'll implement this in the "Confirm the payment" section below } } ``` ### Hinzufügen der Ansicht Zahlungs-Elemente Nachdem EmbeddedPaymentElement erfolgreich initialisiert wurde, platzieren Sie seine Ansicht in der Nutzeroberfläche des Bezahlvorgangs. > Die Ansicht muss in einer scrollbaren Ansicht enthalten sein, z. B. UIScrollView, da sie keine feste Größe hat und die Höhe nach dem ersten Rendern ändern kann. ```swift class MyCheckoutVC: UIViewController { // ... private(set) var embeddedPaymentElement: EmbeddedPaymentElement? private lazy var checkoutButton: UIButton = { let checkoutButton = UIButton(type: .system) checkoutButton.backgroundColor = .systemBlue checkoutButton.layer.cornerRadius = 5.0 checkoutButton.clipsToBounds = true checkoutButton.setTitle("Checkout", for: .normal) checkoutButton.setTitleColor(.white, for: .normal) checkoutButton.translatesAutoresizingMaskIntoConstraints = false checkoutButton.isEnabled = embeddedPaymentElement?.paymentOption != nil checkoutButton.addTarget(self, action: #selector(didTapConfirmButton), for: .touchUpInside) return checkoutButton }() // ... @objc func didTapConfirmButton() { // You'll implement this in the "Confirm the payment" section below } override func viewDidLoad() { super.viewDidLoad() Task { @MainActor in do { // Create a UIScrollView let scrollView = UIScrollView() scrollView.translatesAutoresizingMaskIntoConstraints = false self.view.addSubview(scrollView) // Create the Payment Element let embeddedPaymentElement = try await createEmbeddedPaymentElement() embeddedPaymentElement.delegate = self embeddedPaymentElement.presentingViewController = self self.embeddedPaymentElement = embeddedPaymentElement // Add its view to the scroll view scrollView.addSubview(embeddedPaymentElement.view) // Add your own checkout button to the scroll view scrollView.addSubview(checkoutButton) // Set up layout constraints embeddedPaymentElement.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), embeddedPaymentElement.view.topAnchor.constraint(equalTo: scrollView.topAnchor), embeddedPaymentElement.view.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor), embeddedPaymentElement.view.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor), checkoutButton.topAnchor.constraint(equalTo: embeddedPaymentElement.view.bottomAnchor, constant: 4.0), checkoutButton.leadingAnchor.constraint(equalTo: scrollView.safeAreaLayoutGuide.leadingAnchor, constant: 4.0), checkoutButton.trailingAnchor.constraint(equalTo: scrollView.safeAreaLayoutGuide.trailingAnchor, constant: -4.0), ]) } catch { // Handle view not being added to view } } } } ``` An dieser Stelle können Sie Ihre App ausführen und das eingebettete Mobile Payment Element sehen. ### Umgang mit Änderungen bei der Höhe Die Ansicht des EmbeddedPaymentElement kann vergrößert oder verkleinert werden, was sich auf das Layout der Ansicht auswirken kann. Verarbeiten Sie Höhenänderungen, indem Sie die Delegatmethode `embeddedPaymentElementDidUpdateHeight` implementieren. Die Ansicht von EmbeddedPaymentElement ruft diese Methode in einem Animationsblock auf, der seine Höhe aktualisiert. Es wird erwartet, dass Ihre Implementierung `setNeedsLayout()` und `layoutIfNeeded()` in der Bildlaufansicht aufruft, die die Ansicht des EmbeddedPaymentElement enthält, um eine reibungslose Animation der Höhenänderung zu ermöglichen. ```swift extension MyCheckoutVC: EmbeddedPaymentElementDelegate { func embeddedPaymentElementDidUpdateHeight(embeddedPaymentElement: StripePaymentSheet.EmbeddedPaymentElement) { // Handle layout appropriately self.view.setNeedsLayout() self.view.layoutIfNeeded() } } ``` Es wird empfohlen, dass Sie testen, ob die Ansicht ordnungsgemäß auf Höhenänderungen reagiert. Rufen Sie dazu `testHeightChange()` in EmbeddedPaymentElement auf, um das Ein- und Ausblenden eines Mandats innerhalb des Elements zu simulieren. Stellen Sie sicher, dass Sie sich nach dem Aufruf von `testHeightChange()` Ihre Scrollansicht reibungslos anpasst. ```swift class MyCheckoutVC: UIViewController { override func viewDidLoad() { // This is only for testing purposes: #if DEBUG Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true) { [weak self] _ in Task { @MainActor in self?.embeddedPaymentElement?.testHeightChange() } } #endif } } ``` ### (Optional) Ausgewählte Zahlungsoption anzeigen Wenn Sie auf Details zur vom Kunden ausgewählten Zahlungsoption zugreifen müssen, wie ein Label (z. B. „····4242“), ein Bild (z. B. ein VISA-Logo) oder Abrechnungsdetails, die in Ihrer Nutzeroberfläche angezeigt werden sollen, verwenden Sie die Eigenschaft `paymentOption` von EmbeddedPaymentElement. Um benachrichtigt zu werden, wenn sich die `paymentOption` ändert, implementieren Sie die Delegatmethode `embeddedPaymentElementDidUpdatePaymentOption`. ```swift extension MyCheckoutVC: EmbeddedPaymentElementDelegate { func embeddedPaymentElementDidUpdatePaymentOption(embeddedPaymentElement: EmbeddedPaymentElement) { print("The payment option changed: \(embeddedPaymentElement.paymentOption)") checkoutButton.isEnabled = embeddedPaymentElement.paymentOption != nil } } ``` ### (Optional) Zahlungsangaben aktualisieren Wenn der Kunde/die Kundin Aktionen durchführt, die die Zahlungsdetails ändern (z. B. das Anwenden eines Rabattcodes), aktualisieren Sie die `EmbeddedPaymentElement`-Instanz, um die neuen Werte widerzugeben, indem Sie die `update`-Methode aufrufen. Bei einigen Zahlungsmethoden, wie Apple Pay und Google Pay, wird der Betrag in der Nutzeroberfläche angezeigt. Stellen Sie daher sicher, dass er immer korrekt und aktuell ist. Wenn der Aktualisierungsaufruf abgeschlossen ist, aktualisieren Sie Ihre Nutzeroberfläche. Durch den Aktualisierungsaufruf kann sich die aktuell ausgewählte Zahlungsoption des Kunden/der Kundin ändern. ```swift extension MyCheckoutVC { func update() { Task { @MainActor in var updatedIntentConfig = oldIntentConfig // Update the currency updatedIntentConfig.mode = PaymentSheet.IntentConfiguration.Mode.setup(currency: "USD") let result = await embeddedPaymentElement?.update(intentConfiguration: updatedIntentConfig) switch result { case .canceled, nil: // Do nothing; this happens when a subsequent `update` call cancels this one break case .failed(let error): // Display error to user in an alert, let users retry case .succeeded: // Update your UI in case the payment option changed } } } } ``` ### Einrichtung bestätigen Wenn Kundinnen/Kunden auf die Checkout-Schaltfläche tippen, rufen Sie `embeddedPaymentElement.confirm()` auf, um die Einrichtung abzuschließen. Achten Sie darauf, die Nutzerinteraktion während der Bestätigung zu deaktivieren. ```swift extension MyCheckoutVC { @objc func didTapConfirmButton() { Task { @MainActor in guard let embeddedPaymentElement else { return } self.view.isUserInteractionEnabled = false // Disable user interaction, show a spinner, and so on before calling confirm. let result = await embeddedPaymentElement.confirm() switch result { case .completed: // Setup completed - show a confirmation screen. case .failed(let error): self.view.isUserInteractionEnabled = true // Encountered an unrecoverable error. You can display the error to the user, log it, and so on. case .canceled: self.view.isUserInteractionEnabled = true // Customer canceled - you should probably do nothing. break } } } } ``` Implementieren Sie als Nächstes den Rückruf `confirmationTokenConfirmHandler`, den Sie zuvor an`PaymentSheet.IntentConfiguration` übergeben haben, um eine Anfrage an Ihren Server zu senden. Der Server erstellt einen SetupIntent und gibt sein Client-Geheimnis zurück. Weitere Informationen zu diesem Prozess finden Sie unter [Erstellen eines SetupIntent](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#submit-setup). Wenn die Anfrage zurückkommt, geben Sie das Client-Geheimnis Ihrer Serverantwort zurück oder geben Sie einen Fehler aus. Das EmbeddedPaymentElement bestätigt den PaymentIntent mithilfe des Client-Geheimnisses oder zeigt die lokalisierte Fehlermeldung in seiner Nutzeroberfläche an (entweder [errorDescription](https://developer.apple.com/documentation/foundation/localizederror/2946895-errordescription) oder [localizedDescription](https://developer.apple.com/documentation/foundation/nserror/1414418-localizeddescription)). Nach Abschluss der Bestätigung ist das EmbeddedPaymentElement nicht mehr verwendbar. Leiten Sie die/den Nutzer/in stattdessen zu einem Belegbildschirm oder einer ähnlichen Seite weiter. ```swift extension MyCheckoutVC { func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // Make a request to your own server. Pass `confirmationToken.stripeId` if using server-side confirmation, and return the client secret or throw an error. let myServerClientSecret = try await fetchIntentClientSecret(...) } } ``` #### SwiftUI ### Initialisieren des Zahlungs-Elements Rufen Sie `load` auf, um EmbeddedPaymentElementViewModel mit einer `EmbeddedPaymentElement.Configuration` und einer [PaymentSheet.IntentConfiguration](https://github.com/stripe/stripe-ios/blob/master/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheetIntentConfiguration.swift) zu laden. Das Configuration-Objekt enthält universelle Konfigurationsoptionen für EmbeddedPaymentElement, die sich zwischen den Zahlungen nicht ändern, z. B. `returnURL`. Das `IntentConfiguration`-Objekt enthält Details über die spezifische Zahlung wie den Betrag und die Währungen, sowie einen `confirmationTokenConfirmHandler`-Rückruf. Lassen Sie die Implementierung vorerst leer. ```swift import SwiftUI import StripePaymentSheet struct MyEmbeddedCheckoutView: View { // Store an `EmbeddedPaymentElementViewModel` as a `@StateObject` @StateObject var embeddedViewModel = EmbeddedPaymentElementViewModel() var body: some View { ScrollView { // Empty scroll view for now } .task { do { if !embeddedViewModel.isLoaded { // Load the view model with your configuration try await loadEmbeddedViewModel() } } catch { // On load failure, implement retry logic (automatic retry or user-triggered through UI). } } } private func loadEmbeddedViewModel() async throws { let intentConfiguration = PaymentSheet.IntentConfiguration( mode: .setup(currency: "USD") ) { confirmationToken in try await self.handleConfirmationToken(confirmationToken) } var configuration = EmbeddedPaymentElement.Configuration() configuration.returnURL = "your-app://stripe-redirect" // Use the return url you set up in the previous step try await embeddedViewModel.load(intentConfiguration: intentConfiguration, configuration: configuration) } func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // You'll implement this in the "Confirm the payment" section below } } ``` ### Hinzufügen der Ansicht Zahlungs-Elemente Nachdem EmbeddedPaymentElementViewModel erfolgreich geladen wurde, fügen Sie in der Nutzeroberfläche Ihres Bezahlvorgangs EmbeddedPaymentElementView hinzu. > Die Ansicht muss in einer scrollbaren Ansicht wie ScrollView enthalten sein, da sie keine feste Größe hat und sich die Höhe nach dem ersten Rendern ändern kann. ```swift struct MyEmbeddedCheckoutView: View { var body: some View { ScrollView { // isLoaded becomes true only after a successful call to `embeddedViewModel.load()` if embeddedViewModel.isLoaded { EmbeddedPaymentElementView(viewModel: embeddedViewModel) } } } } ``` An dieser Stelle können Sie Ihre App ausführen und das eingebettete Mobile Payment Element sehen. ### Umgang mit Änderungen bei der Höhe Der EmbeddedPaymentElementView kann vergrößert oder verkleinert werden, was sich auf das Layout der Ansicht auswirken kann. Der EmbeddedPaymentElementView behandelt dies automatisch, wenn er sich in einer ScrollView befindet. Es wird empfohlen, dass Sie testen, ob die Ansicht ordnungsgemäß auf Höhenänderungen reagiert. Rufen Sie dazu `testHeightChange()` in EmbeddedPaymentElementViewModel auf, um das Ein- und Ausblenden eines Mandat innerhalb des Elements zu simulieren. Stellen Sie sicher, dass Sie sich nach dem Aufruf von `testHeightChange()` Ihre Scrollansicht reibungslos anpasst. ```swift struct MyEmbeddedCheckoutView: View { var body: some View { ScrollView { if embeddedViewModel.isLoaded { EmbeddedPaymentElementView(viewModel: embeddedViewModel) // For testing only #if DEBUG Button("Test height change") { embeddedViewModel.testHeightChange() } #endif } } } } ``` ### (Optional) Ausgewählte Zahlungsoption anzeigen Wenn Sie auf Details zur vom Kunden ausgewählten Zahlungsoption zugreifen müssen, wie ein Label (z. B. „····4242“), ein Bild (z. B. ein VISA-Logo) oder Rechnungsdetails, die in Ihrer Nutzeroberfläche angezeigt werden sollen, verwenden Sie die Eigenschaft `paymentOption` von EmbeddedPaymentElementViewModel. Wenn Kundinnen und Kunden eine Zahlungsmethode auswählen, die ein Formularblatt öffnet, wird die Zahlungsoption aktualisiert, nachdem sie im Formular auf **Weiter** getippt haben. ```swift struct MyEmbeddedCheckoutView: View { var body: some View { ScrollView { if embeddedViewModel.isLoaded { // ... // A real integration probably wouldn't show the selected payment option on the same screen as the embedded payment element. We display it as an example. if let paymentOption = embeddedViewModel.paymentOption { HStack { Image(uiImage: paymentOption.image) .resizable() .aspectRatio(contentMode: .fit) .frame(height: 30) Text(paymentOption.label) Spacer() } .padding() } } } } } ``` ### (Optional) Zahlungsangaben aktualisieren Wenn der Kunde/die Kundin Aktionen durchführt, die die Zahlungsdetails ändern (z. B. das Anwenden eines Rabattcodes), aktualisieren Sie die `EmbeddedPaymentElementViewModel`-Instanz, um die neuen Werte widerzugeben, indem Sie die `update`-Methode aufrufen. Bei einigen Zahlungsmethoden, wie Apple Pay und Google Pay, wird der Betrag in der Nutzeroberfläche angezeigt. Stellen Sie daher sicher, dass er immer korrekt und aktuell ist. Wenn die Aktualisierung abgeschlossen ist, wurde möglicherweise die aktuell ausgewählte Zahlungsoption des Kunden/der Kundin geändert. ```swift extension MyEmbeddedCheckoutView { func update() { Task { @MainActor in var updatedIntentConfig = oldIntentConfig updatedIntentConfig.mode = PaymentSheet.IntentConfiguration.Mode.setup(currency: "USD") let result = await embeddedViewModel.update(intentConfiguration: updatedIntentConfig) switch result { case .canceled: // Do nothing; this happens when a subsequent `update` call cancels this one break case .failed(let error): // Display error to user in an alert, let users retry case .succeeded: // Update your UI in case the payment option changed } } } } ``` ### Einrichtung bestätigen Wenn Kundinnen/Kunden auf die Checkout-Schaltfläche tippen, rufen Sie `embeddedViewModel.confirm()` auf, um die Einrichtung abzuschließen. Achten Sie darauf, die Nutzerinteraktion während der Bestätigung zu deaktivieren. ```swift extension MyEmbeddedCheckoutView { func didTapConfirmButton() { Task { @MainActor in // Be sure to disable user interaction during confirm (not shown in this example) let result = await embeddedViewModel.confirm() switch result { case .completed: // Setup completed - show a confirmation screen. case .failed(let error): // Encountered an unrecoverable error. Re-enable user interaction, display the error to the user, log it, and so on. case .canceled: // Customer canceled - re-enable user interaction and let them try again. break } } } } ``` Implementieren Sie als Nächstes den Rückruf `confirmationTokenConfirmHandler`, den Sie zuvor an`PaymentSheet.IntentConfiguration` übergeben haben, um eine Anfrage an Ihren Server zu senden. Der Server erstellt einen SetupIntent und gibt sein Client-Geheimnis zurück. Weitere Informationen zu diesem Prozess finden Sie unter [Erstellen eines SetupIntent](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#submit-setup). Geben Sie das Client Secret aus der Serverantwort zurück oder geben Sie einen Fehler. Das EmbeddedPaymentElement bestätigt den PaymentIntent mithilfe des Client-Geheimnisses oder zeigt die lokalisierte Fehlermeldung in seiner Nutzeroberfläche an (entweder [errorDescription](https://developer.apple.com/documentation/foundation/localizederror/2946895-errordescription) oder [localizedDescription](https://developer.apple.com/documentation/foundation/nserror/1414418-localizeddescription)). Nach Abschluss der Bestätigung kann das EmbeddedPaymentElement nicht mehr verwendet werden. Leiten Sie die Nutzerin oder den Nutzer stattdessen zu einem Zahlungsbeleg oder einer ähnlichen Seite weiter. ```swift extension MyEmbeddedCheckoutView { func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // Make a request to your own server. Pass confirmationToken.stripeId if using server-side confirmation. // Return the client secret or throw an error return try await MyAPIClient.shared.createIntent(confirmationTokenId: confirmationToken.stripeId) } } ``` ## Optional: Ausgewählte Zahlungsoption löschen Wenn Sie Zahlungsoptionen außerhalb von EmbeddedPaymentElement haben, müssen Sie möglicherweise die ausgewählte Zahlungsoption löschen. Verwenden Sie dazu die `clearPaymentOption` API, um die ausgewählte Zahlungsoption zu deaktivieren. #### UIKit ```swift extension MyCheckoutVC: UIViewController { func deselectPaymentMethod() { embeddedPaymentElement?.clearPaymentOption() } } ``` #### SwiftUI ```swift @available(iOS 15.0, *) extension MyEmbeddedCheckoutView { func deselectPaymentMethod() { embeddedViewModel.clearPaymentOption() } } ``` ## Optional: Mandat selbst anzeigen Standardmäßig zeigt das eingebettete Mobile Payment Element Mandate und rechtliche Haftungsausschlüsse an, um die Einhaltung gesetzlicher Vorschriften zu gewährleisten. Dieser Text muss sich in der Nähe Ihrer Schaltfläche „Kaufen“ befinden. Deaktivieren Sie ggf. die Anzeige in der Ansicht und zeigen Sie sie stattdessen selbst an. > Ihre Integration muss den Mandatstext anzeigen, um die Konformität zu gewährleisten. Stellen Sie sicher, dass URLs im Text mithilfe von UITextView oder Ähnlichem geöffnet werden können. #### UIKit ```swift var configuration = EmbeddedPaymentElement.Configuration(...) configuration.embeddedViewDisplaysMandateText = true ... let mandateTextView = UITextView() mandateTextView.attributedText = embeddedPaymentElement.paymentOption.mandateText ``` #### SwiftUI ```swift var configuration = EmbeddedPaymentElement.Configuration(...) configuration.embeddedViewDisplaysMandateText = true ... if let attributedText = embeddedViewModel.paymentOption?.mandateText { Text(AttributedString(attributedText)) } ``` ## Optional: Lassen Sie die/den Kunden/Kundin die Einrichtung sofort auf dem Blatt bestätigen Um die Schaltfläche im Formular zur sofortigen Bestätigung der Einrichtung zu konfigurieren, legen Sie `formSheetAction` für Ihr `EmbeddedPaymentElement.Configuration`-Objekt fest. Der Completion-Block wird mit dem Ergebnis der Einrichtung ausgeführt, nachdem das Formular geschlossen wurde. Die eingebettete Nutzeroberfläche kann nach Abschluss der Einrichtung nicht verwendet werden. Wir empfehlen daher, dass Ihre Implementierung die Nutzer/innen zu einem anderen Bildschirm weiterleitet, z. B. einem Zahlungsbeleg-Bildschirm. ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.formSheetAction = .confirm(completion: { result in switch result { case .completed: // Setup completed. You can for example, show a confirmation screen. print("Completed") case .failed(let error): // Encountered an unrecoverable error. You can display the error to the user, log it, etc. print(error) case .canceled: // Customer canceled - you should probably do nothing. break } }) ``` ## SetupIntent erstellen [Serverseitig] Erstellen Sie einen *SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) auf Ihrem Server. Zahlungsmethoden können Sie über das [Dashboard](https://dashboard.stripe.com/settings/payment_methods) verwalten. Stripe wertet Einschränkungen der Zahlungsmethode und andere Parameter aus, um die Liste der unterstützten Zahlungsmethoden zu ermitteln. Wenn der Aufruf erfolgreich ist, geben Sie den SetupIntent *das Client-Geheimnis* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) zurück. Wenn der Aufruf fehlschlägt, [beheben Sie den Fehler](https://docs.stripe.com/error-handling.md) und geben eine Fehlermeldung mit einer kurzen Erklärung an Ihre Kundin/Ihren Kunden zurück. > Überprüfen Sie, ob alle IntentConfiguration-Eigenschaften mit Ihrem SetupIntent (zum Beispiel [Nutzung](https://docs.stripe.com/api/setup_intents/object.md#setup_intent_object-usage)) übereinstimmen. #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') post '/create-intent' do data = JSON.parse request.body.read params = { customer: ..., # The Customer ID you previously created automatic_payment_methods: {enabled: true}, } begin intent = client.v1.setup_intents.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` ## Rückgabe-URL einrichten [Clientseitig] Der Kunde/Die Kundin verlässt ggf. Ihre App, um sich zu authentifizieren (z. B. in Safari oder einer Banking-App). Damit sie nach der Authentifizierung automatisch zu Ihrer App zurückkehren können, [konfigurieren Sie ein benutzerdefiniertes URL-Schema](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app) und richten Sie Ihren App-Delegate so ein, dass die URL an das SDK weitergeleitet wird. Stripe unterstützt keine [universellen Links](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content). #### SceneDelegate #### Swift ```swift // This method handles opening custom URL schemes (for example, "your-app://stripe-redirect") func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { guard let url = URLContexts.first?.url else { return } let stripeHandled = StripeAPI.handleURLCallback(with: url) if (!stripeHandled) { // This was not a Stripe url – handle the URL normally as you would } } ``` #### AppDelegate #### Swift ```swift // This method handles opening custom URL schemes (for example, "your-app://stripe-redirect") func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { let stripeHandled = StripeAPI.handleURLCallback(with: url) if (stripeHandled) { return true } else { // This was not a Stripe url – handle the URL normally as you would } return false } ``` #### SwiftUI #### Swift ```swift @main struct MyApp: App { var body: some Scene { WindowGroup { Text("Hello, world!").onOpenURL { incomingURL in let stripeHandled = StripeAPI.handleURLCallback(with: incomingURL) if (!stripeHandled) { // This was not a Stripe url – handle the URL normally as you would } } } } } ``` Legen Sie außerdem die [returnURL](https://github.com/stripe/stripe-ios/blob/aa3234a7fafde98c9203b6ed77e0278c04310eb0/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L70) für Ihr [EmbeddedPaymentElement.Configuration](https://github.com/stripe/stripe-ios/blob/aa3234a7fafde98c9203b6ed77e0278c04310eb0/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L12)-Objekt auf die URL für Ihre App fest. ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.returnURL = "your-app://stripe-redirect" ``` ## Die gespeicherte Zahlungsmethode später belasten [Serverseitig] > `bancontact` und `ideal` sind standardmäßig einmalige Zahlungsmethoden. Wenn sie für die künftige Verwendung eingerichtet werden, erzeugen sie eine wiederverwendbare Art der Zahlungsmethode `sepa_debit`, sodass Sie `sepa_debit` verwenden müssen, um gespeicherte Zahlungsmethoden abzufragen. > #### Compliance > > Sie sind für die Einhaltung aller geltenden Gesetze, Vorschriften und Netzwerkregeln verantwortlich, wenn Sie die Zahlungsdaten von Kundinnen und Kunden speichern. Wenn Sie Ihren Endkundinnen und Endkunden zuvor genutzte Zahlungsmethoden für zukünftige Einkäufe anzeigen, dürfen Sie nur Zahlungsmethoden auflisten, für die Sie bereits eine kundenseitige Zustimmung eingeholt haben, dank der Sie die Details der Zahlungsmethode für diese spezifische zukünftige Verwendung speichern können. Verwenden Sie den Parameter [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay), um zwischen Zahlungsmethoden zu unterscheiden, die mit Kundinnen und Kunden verknüpft sind und Ihren Endkundinnen und Endkunden als gespeicherte Zahlungsmethode für zukünftige Einkäufe angezeigt werden können oder nicht. Um eine Zahlungsmethode zum Belasten zu finden, listen Sie die Zahlungsmethoden auf, die mit Ihrer Kundin/Ihrem Kunden verknüpft sind. In diesem Beispiel sind Karten aufgeführt, Sie können jedoch jeden unterstützten [Typ](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-type) auflisten. > #### Verwenden Sie die Accounts v2 API zum Darstellen von Kundinnen und Kunden > > Die Accounts v2 API ist allgemein für Connect-Nutzer/innen verfügbar und für andere Stripe-Nutzer/innen in der öffentlichen Vorschau. Wenn an der Accounts v2 Vorschau teilnehmen, müssen Sie eine [Vorschauversion](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) in Ihrem Code angeben. > > Um Zugriff auf die Accounts v2 Vorschau anzufordern, {% collect-email modal=true modal_link_text=“sign up.” list=“payin-payout-reuse-waitlist@stripe.com” send_direct_email=true intro_text=“Sind Sie am frühzeitigen Zugang zur Vorschau der Accounts v2 API interessiert?" body_text=“Wir sind gerade dabei, die Vorschau von Accounts v2 bereitzustellen. Um Zugang zu beantragen, geben Sie unten Ihre E-Mail-Adresse ein.” form_cta_text=“Registrieren” success_text=“Danke! Wir melden uns bald.” show_email_confirmation=wahr /%} > > Für die meisten Anwendungsfälle empfehlen wir, [Ihre Kundinnen und Kunden als vom Kunden bzw. von der Kundin konfigurierte Account-Objekte abzubilden](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md), anstatt [Customer](https://docs.stripe.com/api/customers.md)-Objekte zu verwenden. #### Accounts v2 ```curl curl -G https://api.stripe.com/v1/payment_methods \ -u "<>:" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d type=card ``` #### Customers v1 ```curl curl -G https://api.stripe.com/v1/payment_methods \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d type=card ``` Wenn Sie bereit sind, die Zahlung Ihrer Kundin/Ihres Kunden *off-session* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information) zu belasten, verwenden Sie die `Kunden`-ID oder das von der Kundin/dem Kunden/Kundin konfigurierte `Konto` und die `PaymentMethod`-ID, um einen `PaymentIntent` mit dem Betrag und der Währungen der Zahlung zu erstellen. Legen Sie einige weitere Parameter fest, um die Off-Session-Zahlung durchzuführen: - Legen Sie [off_session](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-off_session) auf true fest, um anzugeben, dass der Kunde/die Kundin sich während eines Bezahlvorgangs nicht in Ihrem Bezahlvorgang befindet und somit eine Authentifizierungsanfrage eines Partners, wie z. B. eines Kartenausstellers, einer Bank oder eines anderen Zahlungsinstituts, nicht erfüllen kann. Wenn ein Partner während Ihres Bezahlvorgangs eine Authentifizierung anfordert, fordert Stripe Ausnahmen unter Verwendung von Kunden/Kundinnen aus einer vorherigen *On-Session*-Transaktion an. Wenn die Bedingungen für die Ausnahme nicht erfüllt sind, kann der `PaymentIntent` einen Fehler ergeben. - Setzen Sie [„confirm“](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) auf „true“, um sofort nach Erstellung des `PaymentIntent` eine Bestätigung auszulösen. - Legen Sie [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) auf die ID der `PaymentMethod` fest. - Je nachdem, wie Sie Kundinnen/Kunden in Ihrer Integration darstellen, legen Sie entweder [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) auf die ID des kundenseitig konfigurierten `Kontos` oder [customer](https://docs.stripe.com/api.md#create_payment_intent-customer) auf die `Kunden`-ID fest. #### Accounts v2 ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=usd \ -d "automatic_payment_methods[enabled]=true" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d payment_method={{PAYMENT_METHOD_ID}} \ --data-urlencode "return_url=https://example.com/order/123/complete" \ -d off_session=true \ -d confirm=true ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=usd \ -d "automatic_payment_methods[enabled]=true" \ -d "customer={{CUSTOMER_ID}}" \ -d payment_method={{PAYMENT_METHOD_ID}} \ --data-urlencode "return_url=https://example.com/order/123/complete" \ -d off_session=true \ -d confirm=true ``` ## Integration testen #### Karten | Kartennummer | Szenario | So führen Sie den Test durch | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | | 4242424242424242 | Die Kartenzahlung ist erfolgreich und es ist keine Authentifizierung erforderlich. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 4000002500003155 | Für die Kartenzahlung ist eine *Authentifizierung* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase) erforderlich. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 4000000000009995 | Die Karte wird mit einem Ablehnungscode wie `insufficient_funds` abgelehnt. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 6205500000000000004 | Die UnionPay-Karte hat eine variable Länge von 13 bis 19 Ziffern. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | #### Bankumleitungen | Zahlungsmethode | Szenario | So führen Sie den Test durch | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Bancontact, iDEAL | Ihr/e Kund/in konnte sich auf der iDEAL-Weiterleitungsseite für eine auf Weiterleitung basierende Zahlungsmethode mit sofortiger Benachrichtigung nicht authentifizieren. | Wählen Sie eine beliebige, auf Weiterleitung basierende Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung fehlgeschlagen**. | | Pay by Bank | Ihr Kunde/Ihre Kundin zahlt erfolgreich mit einer auf Weiterleitung basierenden Zahlungsmethode mit [verzögerter Benachrichtigung](https://docs.stripe.com/payments/payment-methods.md#payment-notification). | Wählen Sie die Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung abschließen**. | | Pay by Bank | Ihr/e Kund/in konnte sich auf der iDEAL-Weiterleitungsseite für eine auf Weiterleitung basierende Zahlungsmethode mit verzögerter Benachrichtigung nicht authentifizieren. | Wählen Sie die Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung fehlgeschlagen**. | | BLIK | BLIK-Zahlungen können aus verschiedenen Gründen fehlschlagen. Es gibt sofortige Fehler (der Code ist abgelaufen oder ungültig), verzögerte Fehler (die Bank lehnt ab) oder Zeitüberschreitungen (der/die Kund/in hat nicht rechtzeitig reagiert). | Verwenden Sie E-Mail-Muster, um [die verschiedenen Fehler zu simulieren](https://docs.stripe.com/payments/blik/accept-a-payment.md#simulate-failures) | #### Banklastschriften | Zahlungsmethode | Szenario | So führen Sie den Test durch | | ---------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | SEPA-Lastschrift | Ihr/e Kund/in zahlt erfolgreich mit dem SEPA-Lastschriftverfahren. | Füllen Sie das Formular mit der Kontonummer `AT321904300235473204` aus. Die bestätigte PaymentIntent geht zunächst in den Status „wird verarbeitet“ und dann drei Minuten später in den Status „erfolgreich“ über. | | SEPA-Lastschrift | Der Status der PaymentIntent Ihres/Ihrer Kund/in wechselt von `processing` zu `requires_payment_method`. | Füllen Sie das Formular mit der Kontonummer `AT861904300235473202` aus. | Hier finden Sie weitere Informationen zum [Testen](https://docs.stripe.com/testing.md) Ihrer Integration. ## Kartenscannen aktivieren Um die Unterstützung für das Scannen von Karten für iOS zu aktivieren, setzen Sie `NSCameraUsageDescription` (**Datenschutz – Beschreibung Kameranutzung**) in der `Info.plist` Ihrer Anwendung und geben einen Grund für den Zugriff auf die Kamera an (z. B. „Zum Scannen von Karten“). ## Optional: Karten speichern [Serverseitig] [Clientseitig] `EmbeddedPaymentElement` kann es Kundinnen und Kunden ermöglichen, ihre Karte zu speichern, und die gespeicherten Karten des Kunden/der Kundin in die verfügbaren Zahlungsmethoden aufnehmen. Der Kunde/Die Kundin muss über ein zugehöriges, vom Kunden/von der Kundin konfiguriertes [Account](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer)-Objekt oder [Customer](https://docs.stripe.com/api/customers/create.md)-Objekt auf Ihrem Server verfügen. Um ein Kontrollkästchen zu aktivieren, mit dem der Kunde/die Kundin seine/ihre Karte speichern kann, erstellen Sie eine [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) mit `enabled` für `payment_method_save`. #### Accounts v2 ```javascript const stripe = require('stripe')('sk_test_your_secret_key'); app.post('/mobile-payment-element', async (req, res) => { // Use an existing Account ID if this is a returning customer. const customer_account = await stripe.v2.core.accounts.create(); const customerSession = await stripe.customerSessions.create({ customer_account: customer_account.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer_account: customer_account.id, }); }); ``` Konfigurieren Sie als Nächstes EmbeddedPaymentElement mit der ID des Kunden/der Kundin und dem Client-Geheimnis der CustomerSession. #### UIKit ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet var configuration = EmbeddedPaymentElement.Configuration() configuration.customer = .init(id: customerAccountId, customerSessionClientSecret: customerSessionClientSecret) self.embeddedPaymentElement = try await EmbeddedPaymentElement.create(..., configuration: configuration) ``` #### SwiftUI ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet var configuration = EmbeddedPaymentElement.Configuration() configuration.customer = .init(id: customerAccountId, customerSessionClientSecret: customerSessionClientSecret) try await embeddedViewModel.load(..., configuration: configuration) ``` #### Customers v1 ```javascript const stripe = require('stripe')('sk_test_your_secret_key'); app.post('/mobile-payment-element', async (req, res) => { // Use an existing Customer ID if this is a returning customer. const customer = await stripe.customers.create(); const customerSession = await stripe.customerSessions.create({ customer: customer.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer: customer.id, }); }); ``` Konfigurieren Sie als Nächstes EmbeddedPaymentElement mit der ID des Kunden/der Kundin und dem Client-Geheimnis der CustomerSession. #### UIKit ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet var configuration = EmbeddedPaymentElement.Configuration() configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret) self.embeddedPaymentElement = try await EmbeddedPaymentElement.create(..., configuration: configuration) ``` #### SwiftUI ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet var configuration = EmbeddedPaymentElement.Configuration() configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret) try await embeddedViewModel.load(..., configuration: configuration) ``` ## Optional: Zahlungsmethoden mit Verzögerung zulassen [Clientseitig] *Zahlungsmethoden mit Verzögerung* (A payment method that can't immediately return payment status when a customer attempts a transaction (for example, ACH debits). Businesses commonly hold an order in a pending state until payment is successful with these payment methods) garantieren nicht, dass Sie am Ende des Bezahlvorgangs Gelder von Ihrem Kunden/Ihrer Kundin erhalten, da die Abwicklung eine gewisse Zeit in Anspruch nimmt (z. B. bei US-Bankkonten, SEPA-Lastschrift, iDEAL und Bancontact) oder weil Kundinnen und Kunden aktiv werden müssen, um den Vorgang abzuschließen (z. B. OXXO, Konbini und Boleto). Standardmäßig zeigt EmbeddedPaymentElement keine Zahlungsmethoden mit Verzögerung an. Um die Funktion zu aktivieren, setzen Sie `allowsDelayedPaymentMethods` in Ihrer `EmbeddedPaymentElement.Configuration` auf „true“. Durch diesen Schritt allein werden keine bestimmten Zahlungsmethoden aktiviert. Er zeigt vielmehr an, dass Ihre App in der Lage ist, diese zu verarbeiten. Obwohl beispielsweise OXXO derzeit nicht von EmbeddedPaymentElement unterstützt wird, kann Ihre App OXXO als Zahlungsoption ohne zusätzliche Integrationsänderungen anzeigen, wenn es unterstützt wird und Sie auf die neueste SDK-Version aktualisiert haben. #### UIKit ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.allowsDelayedPaymentMethods = true self.embeddedPaymentElement = try await EmbeddedPaymentElement.create(..., configuration: configuration) ``` #### SwiftUI ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.allowsDelayedPaymentMethods = true try await embeddedViewModel.load(..., configuration: configuration) ``` Wenn die Kundin/der Kunde erfolgreich eine dieser Zahlungsmethoden mit Verzögerung in EmbeddedPaymentElement verwendet, lautet das zurückgegebene Zahlungsergebnis `.completed`. ## Optional: Apple Pay aktivieren > Wenn Ihr Zahlungsbildschirm eine spezielle **Apple Pay**-Schaltfläche enthält, folgen Sie dem [Apple Pay-Leitfaden](https://docs.stripe.com/apple-pay.md#present-payment-sheet) und verwenden Sie `ApplePayContext`, um Zahlungen über Ihre **Apple Pay**-Schaltfläche einzuziehen. Sie können `EmbeddedPaymentElement` verwenden, um andere Arten von Zahlungsmethoden zu handhaben. ### Eine Apple-Händler-ID registrieren Beantragen Sie eine Apple-Händler-ID, indem Sie sich auf der Apple Developer-Website [für eine neue Kennung registrieren](https://developer.apple.com/account/resources/identifiers/add/merchant). Tragen Sie eine Beschreibung und eine Kennung in das Formular ein. Die Beschreibung ist nur für Ihre internen Zwecke bestimmt und kann später geändert werden. Stripe empfiehlt, dass Sie den Namen Ihrer App als Kennung verwenden, zum Beispiel `merchant.com.{{YOUR_APP_NAME}}`. ### Neues Apple Pay-Zertifikat erstellen Erstellen Sie ein Zertifikat für Ihre App, um Zahlungsdaten zu verschlüsseln. Gehen Sie zu den [iOS-Zertifikateinstellungen](https://dashboard.stripe.com/settings/ios_certificates) im Dashboard, klicken Sie auf **Neue Anwendung hinzufügen** und befolgen Sie die Anleitung. Laden Sie eine Certificate Signing Request (CSR)-Datei herunter, um ein sicheres Zertifikat von Apple zu erhalten, mit dem Sie Apple Pay verwenden können. Eine CSR-Datei muss verwendet werden, um genau ein Zertifikat auszustellen. Wenn Sie Ihre Apple-Händler-ID wechseln, müssen Sie zu den [iOS-Zertifikateinstellungen](https://dashboard.stripe.com/settings/ios_certificates) im Dashboard gehen, um eine neue CSR und ein Zertifikat zu erhalten. ### Mit Xcode integrieren Fügen Sie Ihrer App die **Apple Pay**-Funktion hinzu. Öffnen Sie in Xcode Ihre Projekteinstellungen, klicken Sie auf die Registerkarte **Signing & Capabilities** (Anmeldung und Funktionen) und fügen Sie die **Apple Pay**-Funktion hinzu. Möglicherweise werden Sie an dieser Stelle aufgefordert, sich bei Ihrem Entwicklerkonto anzumelden. Wählen Sie die zuvor erstellte Händler-ID aus. Ihre App sollte nun Apple Pay unterstützen. ![](https://b.stripecdn.com/docs-statics-srv/assets/xcode.a701d4c1922d19985e9c614a6f105bf1.png) Apple Pay-Funktion in Xcode aktivieren ### Apple Pay hinzufügen #### Einmalige Zahlung Um Apple Pay zu EmbeddedPaymentElement hinzuzufügen, legen Sie [applePay](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L28) fest, nachdem Sie `EmbeddedPaymentElement.Configuration` mit Ihrer Apple-Händler-ID und dem [Ländercode](https://dashboard.stripe.com/settings/account) Ihres Unternehmens initialisiert haben. #### iOS (Swift) ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.applePay = .init( merchantId: "merchant.com.your_app_name", merchantCountryCode: "US" ) ``` #### Wiederkehrende Zahlungen Um Apple Pay zu EmbeddedPaymentElement hinzuzufügen, legen Sie [applePay](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L28) fest, nachdem Sie `EmbeddedPaymentElement.Configuration` mit Ihrer Apple-Händler-ID und dem [Ländercode](https://dashboard.stripe.com/settings/account) Ihres Unternehmens initialisiert haben. Gemäß den [Apple-Richtlinien](https://developer.apple.com/design/human-interface-guidelines/apple-pay#Supporting-subscriptions) für wiederkehrende Zahlungen müssen Sie auch zusätzliche Attribute für `PKPaymentRequest` festlegen. Fügen Sie in [ApplePayConfiguration.paymentRequestHandlers](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/paymentrequesthandler) einen Handler hinzu, um die [PKPaymentRequest.paymentSummaryItems](https://developer.apple.com/documentation/passkit/pkpaymentrequest/1619231-paymentsummaryitems) mit dem Betrag zu konfigurieren, den Sie berechnen möchten (z. B. 9,95 USD pro Monat). Sie können auch [Händler-Token](https://developer.apple.com/apple-pay/merchant-tokens/) übernehmen, indem Sie die Eigenschaften `recurringPaymentRequest` oder `automaticReloadPaymentRequest` für `PKPaymentRequest` festlegen. Weitere Informationen zur Verwendung wiederkehrender Zahlungen mit Apple Pay finden Sie in der [PassKit-Dokumentation von Apple](https://developer.apple.com/documentation/passkit/pkpaymentrequest). #### iOS (Swift) ```swift let customHandlers = EmbeddedPaymentElement.ApplePayConfiguration.Handlers( paymentRequestHandler: { request in // PKRecurringPaymentSummaryItem is available on iOS 15 or later if #available(iOS 15.0, *) { let billing = PKRecurringPaymentSummaryItem(label: "My Subscription", amount: NSDecimalNumber(string: "59.99")) // Payment starts today billing.startDate = Date() // Payment ends in one year billing.endDate = Date().addingTimeInterval(60 * 60 * 24 * 365) // Pay once a month. billing.intervalUnit = .month billing.intervalCount = 1 // recurringPaymentRequest is only available on iOS 16 or later if #available(iOS 16.0, *) { request.recurringPaymentRequest = PKRecurringPaymentRequest(paymentDescription: "Recurring", regularBilling: billing, managementURL: URL(string: "https://my-backend.example.com/customer-portal")!) request.recurringPaymentRequest?.billingAgreement = "You'll be billed $59.99 every month for the next 12 months. To cancel at any time, go to Account and click 'Cancel Membership.'" } request.paymentSummaryItems = [billing] request.currencyCode = "USD" } else { // On older iOS versions, set alternative summary items. request.paymentSummaryItems = [PKPaymentSummaryItem(label: "Monthly plan starting July 1, 2022", amount: NSDecimalNumber(string: "59.99"), type: .final)] } return request } ) var configuration = EmbeddedPaymentElement.Configuration() configuration.applePay = .init(merchantId: "merchant.com.your_app_name", merchantCountryCode: "US", customHandlers: customHandlers) ``` ### Sendungsverfolgung Um Informationen zur [Bestellverfolgung](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking) in iOS 16 oder höher hinzuzufügen, konfigurieren Sie einen [authorizationResultHandler](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/authorizationresulthandler) in Ihren `PaymentSheet.ApplePayConfiguration.Handlers`. Stripe ruft Ihre Implementierung auf, nachdem die Zahlung durchgeführt wurde, aber bevor iOS das Apple Pay-Formular schließt. Rufen Sie in Ihrer Implementierung von `authorizationResultHandler` die Bestelldetails für die abgeschlossene Bestellung von Ihrem Server ab. Fügen Sie die Details dem bereitgestellten [PKPaymentAuthorizationResult](https://developer.apple.com/documentation/passkit/pkpaymentauthorizationresult) hinzu und geben Sie das geänderte Ergebnis zurück. Weitere Informationen zur Sendungsverfolgung finden Sie in der [Apple-Dokumentation zu Wallet-Bestellungen](https://developer.apple.com/documentation/walletorders). #### iOS (Swift) ```swift let customHandlers = PaymentSheet.ApplePayConfiguration.Handlers( authorizationResultHandler: { result in do { // Fetch the order details from your service let myOrderDetails = try await MyAPIClient.shared.fetchOrderDetails(orderID: orderID) result.orderDetails = PKPaymentOrderDetails( orderTypeIdentifier: myOrderDetails.orderTypeIdentifier, // "com.myapp.order" orderIdentifier: myOrderDetails.orderIdentifier, // "ABC123-AAAA-1111" webServiceURL: myOrderDetails.webServiceURL, // "https://my-backend.example.com/apple-order-tracking-backend" authenticationToken: myOrderDetails.authenticationToken) // "abc123" // Return your modified PKPaymentAuthorizationResult return result } catch { return PKPaymentAuthorizationResult(status: .failure, errors: [error]) } } ) var configuration = EmbeddedPaymentElement.Configuration() configuration.applePay = .init(merchantId: "merchant.com.your_app_name", merchantCountryCode: "US", customHandlers: customHandlers) ``` ## Optional: Element anpassen Alle Anpassungen werden mithilfe des [EmbeddedPaymentElement.Configuration](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L12)-Objekts konfiguriert. ### Erscheinungsbild Passen Sie mit der [Appearance API](https://docs.stripe.com/elements/appearance-api/embedded-mobile.md?platform=ios) Farben, Schriftarten und mehr an das Erscheinungsbild Ihrer App an. ### Adressen der Nutzer/innen erfassen Erfassen Sie lokale und internationale Versand- und Rechnungsadressen von Ihren Kundinnen und Kunden mithilfe des [Address Element](https://docs.stripe.com/elements/address-element.md?platform=ios). ### Anzeigename des Händlers Geben Sie einen kundenorientierten Unternehmensnamen an, indem Sie [merchantDisplayName](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L66) festlegen. Standardmäßig handelt es sich dabei um den Namen Ihrer App. #### Swift ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.merchantDisplayName = "My app, Inc." ``` ### Dunkelmodus `EmbeddedPaymentElement` passt sich automatisch an die systemweiten Erscheinungsbildeinstellungen des Nutzers/der Nutzerin an (heller und dunkler Modus). Wenn Ihre App den dunklen Modus nicht unterstützt, können Sie den [Stil](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L51) auf den Modus `alwaysLight` oder `alwaysDark` festlegen. ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.style = .alwaysLight ``` # Zahlung annehmen und Zahlungsmethode speichern > This is a Zahlung annehmen und Zahlungsmethode speichern for when platform is ios and type is paymentsfu. View the full page at https://docs.stripe.com/payments/mobile/accept-payment-embedded?platform=ios&type=paymentsfu. Verwenden Sie die [Payment Intents API](https://docs.stripe.com/api/payment_intents.md), um Zahlungsdetails aus einem Einkauf zu speichern. Es gibt mehrere Anwendungsszenarien: - Belasten Sie das Konto eines Kunden/einer Kundin für eine E-Commerce-Bestellung und speichern Sie die Details für zukünftige Einkäufe. - Leiten Sie die erste Zahlung einer Reihe wiederkehrender Zahlungen ein. - Buchen Sie eine Anzahlung ab und speichern Sie die Details, um den vollen Betrag später abzubuchen. > #### Transaktionen mit vorhandener Karte > > Card-Present-Transaktionen, wie zum Beispiel Zahlungen über Stripe Terminal, verwenden ein anderes Verfahren zum Speichern der Zahlungsmethode. Weitere Informationen finden Sie in der [Terminal-Dokumentation](https://docs.stripe.com/terminal/features/saving-payment-details/save-after-payment.md). ## Konformität Sie sind dafür verantwortlich, alle geltenden Gesetze, Vorschriften und Netzwerkregeln einzuhalten, wenn Sie die Zahlungsdaten eines Kunden oder einer Kundin für die zukünftige Verwendung speichern, beispielsweise um dem Kunden oder der Kundin seine bzw. ihre Zahlungsmethode beim Bezahlvorgang für einen zukünftigen Kauf anzuzeigen oder um ihm Kosten in Rechnung zu stellen, wenn er Ihre Website oder App nicht aktiv nutzt. Bevor Sie die Zahlungsmethode eines Kunden oder einer Kundin speichern oder ihm Kosten in Rechnung stellen, stellen Sie bitte sicher, dass Sie: - Fügen Sie Ihrer Website oder App Bestimmungen hinzu, die darlegen, wie Sie Zahlungsmethoden speichern möchten, beispielsweise: - Die kundenseitige Zustimmung, eine Zahlung oder mehrere Zahlungen für bestimmte Transaktionen in deren Namen einzuleiten - Der erwartete Zeitpunkt und die voraussichtliche Häufigkeit von Zahlungen (z. B. Zahlungen für geplante Raten- oder Abonnementzahlungen oder für außerplanmäßige Aufstockungen). - Wie Sie den Zahlbetrag ermitteln. - Ihre Stornorichtlinie, wenn die Zahlungsmethode für einen Abonnementdienst ist. - Verwenden Sie eine gespeicherte Zahlungsmethode ausschließlich für den in Ihren Bedingungen angegebenen Zweck. - Bitte holen Sie die ausdrückliche Zustimmung des Kunden oder der Kundin für diese spezifische Verwendung ein. Fügen Sie beispielsweise ein Kontrollkästchen „Meine Zahlungsmethode für zukünftige Transaktionen speichern“ hinzu. - Bewahren Sie die schriftliche Zustimmung Ihrer Kundinnen und Kunden zu Ihren Bedingungen auf. ## Stripe einrichten [Serverseitig] [Clientseitig] ### Serverseitig Diese Integration erfordert Endpoints auf Ihrem Server, die mit der Stripe-API kommunizieren können. Nutzen Sie unsere offiziellen Bibliotheken für den Zugriff auf die Stripe-API von Ihrem Server aus: #### 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' ``` ### Client-seitig 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. Zunächst können Sie den veröffentlichbaren Schlüssel während der Integration auf dem Client codieren, aber den veröffentlichbaren Schlüssel von Ihrem Server in der Produktion 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 = "<>" ``` ## Zahlungsmethoden aktivieren Zeigen Sie Ihre [Einstellungen für Zahlungsmethoden](https://dashboard.stripe.com/settings/payment_methods) an und aktivieren Sie die Zahlungsmethoden, die Sie unterstützen möchten. Sie müssen mindestens eine Zahlungsmethode aktiviert haben, um einen *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) zu erstellen. Standardmäßig aktiviert Stripe Karten und andere gängige Zahlungsmethoden, mit denen Sie mehr Kundinnen und Kunden erreichen können. Wir empfehlen jedoch, zusätzliche Zahlungsmethoden zu aktivieren, die für Ihr Unternehmen und Ihre Kundschaft relevant sind. Weitere Informationen zur Unterstützung von Produkten und Zahlungsmethoden finden Sie auf der Seite [Unterstützte Zahlungsmethoden](https://docs.stripe.com/payments/payment-methods/payment-method-support.md) und der [Preisseite](https://stripe.com/pricing/local-payment-methods) für Gebühren. ## Legen Sie eine Kundin oder einen Kunden an [Serverseitig] Um eine Zahlungsmethode für zukünftige Zahlungen einzurichten, müssen Sie sie einem Objekt zuordnen, das Ihren Kunden/Ihre Kundin repräsentiert. Wenn Ihr Kunde/Ihre Kundin ein Konto erstellt oder die erste Transaktion mit Ihrem Unternehmen durchgeführt hat, erstellen Sie ein [Customer](https://docs.stripe.com/api/customers/create.md)-Objekt. ```curl curl -X POST https://api.stripe.com/v1/customers \ -u "<>:" ``` ## Zahlungsdaten erfassen [Clientseitig] Das eingebettete Mobile Payment Element ist so konzipiert, dass es auf der Bezahlseite Ihrer nativen mobilen App platziert wird. Das Element zeigt eine Liste mit Zahlungsmethoden an, die Sie an das Erscheinungsbild Ihrer App anpassen können. Wenn Kundinnen/Kunden auf die Zeile **Karte** tippen, wird ein Formular geöffnet, in dem sie ihre Zahlungsdetails eingeben können. Die Schaltfläche im Formular zeigt standardmäßig **Fortfahren** an und schließt das Formular, wenn darauf getippt wird, sodass Ihre Kundinnen/Kunden die Zahlung in Ihrem Bezahlvorgang abschließen können. ![Payment Element](https://b.stripecdn.com/docs-statics-srv/assets/ios-embedded.b5867c116d537ffcb920dd80ebdfc741.png) Sie können die Schaltfläche auch so konfigurieren, dass die Zahlung sofort abgeschlossen wird, anstatt fortzufahren. Führen Sie dazu [diesen Schritt](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#embedded-let-customer-pay-immediately) aus, nachdem Sie der Anleitung gefolgt sind. #### UIKit ### Initialisieren des Zahlungs-Elements Rufen Sie `create` auf, um EmbeddedPaymentElement mit einer `EmbeddedPaymentElement.Configuration` und einer [PaymentSheet.IntentConfiguration](https://github.com/stripe/stripe-ios/blob/master/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheetIntentConfiguration.swift) zu instanziieren. Das Configuration-Objekt enthält universelle Konfigurationsoptionen für EmbeddedPaymentElement, die sich zwischen den Zahlungen nicht ändern, z. B. `returnURL`. Das`IntentConfiguration`-Objekt enthält Details über die spezifische Zahlung wie Betrag und Währungen sowie einen Rückruf `confirmationTokenConfirmHandler`. Lassen Sie die Implementierung vorerst leer. Nach der erfolgreichen Initialisierung legen Sie dessen Eigenschaften `presentingViewController` und `delegate` fest. > Um Zahlungsmethoden im EmbeddedPaymentElement zu speichern, konfigurieren Sie `setupFutureUsage`. Sie können den Parameter [setupFutureUsage](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-setup_future_usage) für `IntentConfiguration` auf `onSession` oder `offSession` festlegen. Dieser Wert wird automatisch auf alle verfügbaren Zahlungsmethoden angewendet. ```swift import StripePaymentSheet class MyCheckoutVC: UIViewController { func createEmbeddedPaymentElement() async throws -> EmbeddedPaymentElement { let intentConfig = PaymentSheet.IntentConfiguration( mode: .payment(amount: 1099, currency: "USD", setupFutureUsage: .offSession) ) { [weak self] confirmationToken in return await self?.handleConfirmationToken(confirmationToken) } var configuration = EmbeddedPaymentElement.Configuration() configuration.returnURL = "your-app://stripe-redirect" // Use the return url you set up in the previous step let embeddedPaymentElement = try await EmbeddedPaymentElement.create(intentConfiguration: intentConfig, configuration: configuration) embeddedPaymentElement.presentingViewController = self embeddedPaymentElement.delegate = self return embeddedPaymentElement } func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // You'll implement this in the "Confirm the payment" section below } } ``` ### Hinzufügen der Ansicht Zahlungs-Elemente Nachdem EmbeddedPaymentElement erfolgreich initialisiert wurde, platzieren Sie seine Ansicht in der Nutzeroberfläche des Bezahlvorgangs. > Die Ansicht muss in einer scrollbaren Ansicht enthalten sein, z. B. UIScrollView, da sie keine feste Größe hat und die Höhe nach dem ersten Rendern ändern kann. ```swift class MyCheckoutVC: UIViewController { // ... private(set) var embeddedPaymentElement: EmbeddedPaymentElement? private lazy var checkoutButton: UIButton = { let checkoutButton = UIButton(type: .system) checkoutButton.backgroundColor = .systemBlue checkoutButton.layer.cornerRadius = 5.0 checkoutButton.clipsToBounds = true checkoutButton.setTitle("Checkout", for: .normal) checkoutButton.setTitleColor(.white, for: .normal) checkoutButton.translatesAutoresizingMaskIntoConstraints = false checkoutButton.isEnabled = embeddedPaymentElement?.paymentOption != nil checkoutButton.addTarget(self, action: #selector(didTapConfirmButton), for: .touchUpInside) return checkoutButton }() // ... @objc func didTapConfirmButton() { // You'll implement this in the "Confirm the payment" section below } override func viewDidLoad() { super.viewDidLoad() Task { @MainActor in do { // Create a UIScrollView let scrollView = UIScrollView() scrollView.translatesAutoresizingMaskIntoConstraints = false self.view.addSubview(scrollView) // Create the Payment Element let embeddedPaymentElement = try await createEmbeddedPaymentElement() embeddedPaymentElement.delegate = self embeddedPaymentElement.presentingViewController = self self.embeddedPaymentElement = embeddedPaymentElement // Add its view to the scroll view scrollView.addSubview(embeddedPaymentElement.view) // Add your own checkout button to the scroll view scrollView.addSubview(checkoutButton) // Set up layout constraints embeddedPaymentElement.view.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor), scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), embeddedPaymentElement.view.topAnchor.constraint(equalTo: scrollView.topAnchor), embeddedPaymentElement.view.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor), embeddedPaymentElement.view.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor), checkoutButton.topAnchor.constraint(equalTo: embeddedPaymentElement.view.bottomAnchor, constant: 4.0), checkoutButton.leadingAnchor.constraint(equalTo: scrollView.safeAreaLayoutGuide.leadingAnchor, constant: 4.0), checkoutButton.trailingAnchor.constraint(equalTo: scrollView.safeAreaLayoutGuide.trailingAnchor, constant: -4.0), ]) } catch { // Handle view not being added to view } } } } ``` An dieser Stelle können Sie Ihre App ausführen und das eingebettete Mobile Payment Element sehen. ### Umgang mit Änderungen bei der Höhe Die Ansicht des EmbeddedPaymentElement kann vergrößert oder verkleinert werden, was sich auf das Layout der Ansicht auswirken kann. Verarbeiten Sie Höhenänderungen, indem Sie die Delegatmethode `embeddedPaymentElementDidUpdateHeight` implementieren. Die Ansicht von EmbeddedPaymentElement ruft diese Methode in einem Animationsblock auf, der seine Höhe aktualisiert. Es wird erwartet, dass Ihre Implementierung `setNeedsLayout()` und `layoutIfNeeded()` in der Bildlaufansicht aufruft, die die Ansicht des EmbeddedPaymentElement enthält, um eine reibungslose Animation der Höhenänderung zu ermöglichen. ```swift extension MyCheckoutVC: EmbeddedPaymentElementDelegate { func embeddedPaymentElementDidUpdateHeight(embeddedPaymentElement: StripePaymentSheet.EmbeddedPaymentElement) { // Handle layout appropriately self.view.setNeedsLayout() self.view.layoutIfNeeded() } } ``` Es wird empfohlen, dass Sie testen, ob die Ansicht ordnungsgemäß auf Höhenänderungen reagiert. Rufen Sie dazu `testHeightChange()` in EmbeddedPaymentElement auf, um das Ein- und Ausblenden eines Mandats innerhalb des Elements zu simulieren. Stellen Sie sicher, dass Sie sich nach dem Aufruf von `testHeightChange()` Ihre Scrollansicht reibungslos anpasst. ```swift class MyCheckoutVC: UIViewController { override func viewDidLoad() { // This is only for testing purposes: #if DEBUG Timer.scheduledTimer(withTimeInterval: 5.0, repeats: true) { [weak self] _ in Task { @MainActor in self?.embeddedPaymentElement?.testHeightChange() } } #endif } } ``` ### (Optional) Ausgewählte Zahlungsoption anzeigen Wenn Sie auf Details zur vom Kunden ausgewählten Zahlungsoption zugreifen müssen, wie ein Label (z. B. „····4242“), ein Bild (z. B. ein VISA-Logo) oder Abrechnungsdetails, die in Ihrer Nutzeroberfläche angezeigt werden sollen, verwenden Sie die Eigenschaft `paymentOption` von EmbeddedPaymentElement. Um benachrichtigt zu werden, wenn sich die `paymentOption` ändert, implementieren Sie die Delegatmethode `embeddedPaymentElementDidUpdatePaymentOption`. ```swift extension MyCheckoutVC: EmbeddedPaymentElementDelegate { func embeddedPaymentElementDidUpdatePaymentOption(embeddedPaymentElement: EmbeddedPaymentElement) { print("The payment option changed: \(embeddedPaymentElement.paymentOption)") checkoutButton.isEnabled = embeddedPaymentElement.paymentOption != nil } } ``` ### (Optional) Zahlungsangaben aktualisieren Wenn der Kunde/die Kundin Aktionen durchführt, die die Zahlungsdetails ändern (z. B. das Anwenden eines Rabattcodes), aktualisieren Sie die `EmbeddedPaymentElement`-Instanz, um die neuen Werte widerzugeben, indem Sie die `update`-Methode aufrufen. Bei einigen Zahlungsmethoden, wie Apple Pay und Google Pay, wird der Betrag in der Nutzeroberfläche angezeigt. Stellen Sie daher sicher, dass er immer korrekt und aktuell ist. Wenn der Aktualisierungsaufruf abgeschlossen ist, aktualisieren Sie Ihre Nutzeroberfläche. Durch den Aktualisierungsaufruf kann sich die aktuell ausgewählte Zahlungsoption des Kunden/der Kundin ändern. ```swift extension MyCheckoutVC { func update() { Task { @MainActor in var updatedIntentConfig = oldIntentConfig // Update the amount to reflect the price after applying the discount code updatedIntentConfig.mode = PaymentSheet.IntentConfiguration.Mode.payment(amount: 999, currency: "USD", setupFutureUsage: .offSession) let result = await embeddedPaymentElement?.update(intentConfiguration: updatedIntentConfig) switch result { case .canceled, nil: // Do nothing; this happens when a subsequent `update` call cancels this one break case .failed(let error): // Display error to user in an alert, let users retry case .succeeded: // Update your UI in case the payment option changed } } } } ``` ### Zahlung bestätigen Wenn der/die Kund/in auf die Checkout-Schaltfläche tippt, rufen Sie `embeddedPaymentElement.confirm()` auf, um die Zahlung abzuschließen. Achten Sie darauf, die Nutzerinteraktion während der Bestätigung zu deaktivieren. ```swift extension MyCheckoutVC { @objc func didTapConfirmButton() { Task { @MainActor in guard let embeddedPaymentElement else { return } self.view.isUserInteractionEnabled = false // Disable user interaction, show a spinner, and so on before calling confirm. let result = await embeddedPaymentElement.confirm() switch result { case .completed: // Payment completed - show a confirmation screen. case .failed(let error): self.view.isUserInteractionEnabled = true // Encountered an unrecoverable error. You can display the error to the user, log it, and so on. case .canceled: self.view.isUserInteractionEnabled = true // Customer canceled - you should probably do nothing. break } } } } ``` Implementieren Sie als Nächstes den Rückruf `confirmationTokenConfirmHandler`, den Sie zuvor an`PaymentSheet.IntentConfiguration` übergeben haben, um eine Anfrage an Ihren Server zu senden. Ihr Server erstellt einen PaymentIntent und gibt sein Client-Geheimnis zurück. Weitere Informationen zu diesem Prozess finden Sie unter [Erstellen eines PaymentIntent](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#submit-payment). Wenn die Anfrage zurückkommt, geben Sie das Client-Geheimnis Ihrer Serverantwort zurück oder geben Sie einen Fehler aus. Das EmbeddedPaymentElement bestätigt den PaymentIntent mithilfe des Client-Geheimnisses oder zeigt die lokalisierte Fehlermeldung in seiner Nutzeroberfläche an (entweder [errorDescription](https://developer.apple.com/documentation/foundation/localizederror/2946895-errordescription) oder [localizedDescription](https://developer.apple.com/documentation/foundation/nserror/1414418-localizeddescription)). Nach Abschluss der Bestätigung ist das EmbeddedPaymentElement nicht mehr verwendbar. Leiten Sie die/den Nutzer/in stattdessen zu einem Belegbildschirm oder einer ähnlichen Seite weiter. ```swift extension MyCheckoutVC { func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // Make a request to your own server. Pass `confirmationToken.stripeId` if using server-side confirmation, and return the client secret or throw an error. let myServerClientSecret = try await fetchIntentClientSecret(...) } } ``` #### SwiftUI ### Initialisieren des Zahlungs-Elements Rufen Sie `load` auf, um EmbeddedPaymentElementViewModel mit einer `EmbeddedPaymentElement.Configuration` und einer [PaymentSheet.IntentConfiguration](https://github.com/stripe/stripe-ios/blob/master/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheetIntentConfiguration.swift) zu laden. Das Configuration-Objekt enthält universelle Konfigurationsoptionen für EmbeddedPaymentElement, die sich zwischen den Zahlungen nicht ändern, z. B. `returnURL`. Das `IntentConfiguration`-Objekt enthält Details über die spezifische Zahlung wie den Betrag und die Währungen, sowie einen `confirmationTokenConfirmHandler`-Rückruf. Lassen Sie die Implementierung vorerst leer. > Um Zahlungsmethoden im EmbeddedPaymentElement zu speichern, konfigurieren Sie `setupFutureUsage`. Sie können den Parameter [setupFutureUsage](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-setup_future_usage) in `IntentConfiguration` auf `onSession` oder`offSession` setzen. Dieser Wert gilt automatisch für alle verfügbaren Zahlungsmethoden. ```swift import SwiftUI import StripePaymentSheet struct MyEmbeddedCheckoutView: View { // Store an `EmbeddedPaymentElementViewModel` as a `@StateObject` @StateObject var embeddedViewModel = EmbeddedPaymentElementViewModel() var body: some View { ScrollView { // Empty scroll view for now } .task { do { if !embeddedViewModel.isLoaded { // Load the view model with your configuration try await loadEmbeddedViewModel() } } catch { // On load failure, implement retry logic (automatic retry or user-triggered through UI). } } } private func loadEmbeddedViewModel() async throws { let intentConfiguration = PaymentSheet.IntentConfiguration( mode: .payment(amount: 1099, currency: "USD", setupFutureUsage: .offSession) ) { confirmationToken in try await self.handleConfirmationToken(confirmationToken) } var configuration = EmbeddedPaymentElement.Configuration() configuration.returnURL = "your-app://stripe-redirect" // Use the return url you set up in the previous step try await embeddedViewModel.load(intentConfiguration: intentConfiguration, configuration: configuration) } func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // You'll implement this in the "Confirm the payment" section below } } ``` ### Hinzufügen der Ansicht Zahlungs-Elemente Nachdem EmbeddedPaymentElementViewModel erfolgreich geladen wurde, fügen Sie in der Nutzeroberfläche Ihres Bezahlvorgangs EmbeddedPaymentElementView hinzu. > Die Ansicht muss in einer scrollbaren Ansicht wie ScrollView enthalten sein, da sie keine feste Größe hat und sich die Höhe nach dem ersten Rendern ändern kann. ```swift struct MyEmbeddedCheckoutView: View { var body: some View { ScrollView { // isLoaded becomes true only after a successful call to `embeddedViewModel.load()` if embeddedViewModel.isLoaded { EmbeddedPaymentElementView(viewModel: embeddedViewModel) } } } } ``` An dieser Stelle können Sie Ihre App ausführen und das eingebettete Mobile Payment Element sehen. ### Umgang mit Änderungen bei der Höhe Der EmbeddedPaymentElementView kann vergrößert oder verkleinert werden, was sich auf das Layout der Ansicht auswirken kann. Der EmbeddedPaymentElementView behandelt dies automatisch, wenn er sich in einer ScrollView befindet. Es wird empfohlen, dass Sie testen, ob die Ansicht ordnungsgemäß auf Höhenänderungen reagiert. Rufen Sie dazu `testHeightChange()` in EmbeddedPaymentElementViewModel auf, um das Ein- und Ausblenden eines Mandat innerhalb des Elements zu simulieren. Stellen Sie sicher, dass Sie sich nach dem Aufruf von `testHeightChange()` Ihre Scrollansicht reibungslos anpasst. ```swift struct MyEmbeddedCheckoutView: View { var body: some View { ScrollView { if embeddedViewModel.isLoaded { EmbeddedPaymentElementView(viewModel: embeddedViewModel) // For testing only #if DEBUG Button("Test height change") { embeddedViewModel.testHeightChange() } #endif } } } } ``` ### (Optional) Ausgewählte Zahlungsoption anzeigen Wenn Sie auf Details zur vom Kunden ausgewählten Zahlungsoption zugreifen müssen, wie ein Label (z. B. „····4242“), ein Bild (z. B. ein VISA-Logo) oder Rechnungsdetails, die in Ihrer Nutzeroberfläche angezeigt werden sollen, verwenden Sie die Eigenschaft `paymentOption` von EmbeddedPaymentElementViewModel. Wenn Kundinnen und Kunden eine Zahlungsmethode auswählen, die ein Formularblatt öffnet, wird die Zahlungsoption aktualisiert, nachdem sie im Formular auf **Weiter** getippt haben. ```swift struct MyEmbeddedCheckoutView: View { var body: some View { ScrollView { if embeddedViewModel.isLoaded { // ... // A real integration probably wouldn't show the selected payment option on the same screen as the embedded payment element. We display it as an example. if let paymentOption = embeddedViewModel.paymentOption { HStack { Image(uiImage: paymentOption.image) .resizable() .aspectRatio(contentMode: .fit) .frame(height: 30) Text(paymentOption.label) Spacer() } .padding() } } } } } ``` ### (Optional) Zahlungsangaben aktualisieren Wenn der Kunde/die Kundin Aktionen durchführt, die die Zahlungsdetails ändern (z. B. das Anwenden eines Rabattcodes), aktualisieren Sie die `EmbeddedPaymentElementViewModel`-Instanz, um die neuen Werte widerzugeben, indem Sie die `update`-Methode aufrufen. Bei einigen Zahlungsmethoden, wie Apple Pay und Google Pay, wird der Betrag in der Nutzeroberfläche angezeigt. Stellen Sie daher sicher, dass er immer korrekt und aktuell ist. Wenn die Aktualisierung abgeschlossen ist, wurde möglicherweise die aktuell ausgewählte Zahlungsoption des Kunden/der Kundin geändert. ```swift extension MyEmbeddedCheckoutView { func update() { Task { @MainActor in var updatedIntentConfig = oldIntentConfig updatedIntentConfig.mode = PaymentSheet.IntentConfiguration.Mode.payment(amount: 999, currency: "USD", setupFutureUsage: .offSession) let result = await embeddedViewModel.update(intentConfiguration: updatedIntentConfig) switch result { case .canceled: // Do nothing; this happens when a subsequent `update` call cancels this one break case .failed(let error): // Display error to user in an alert, let users retry case .succeeded: // Update your UI in case the payment option changed } } } } ``` ### Zahlung bestätigen Wenn Kundinnen/Kunden auf die Checkout-Schaltfläche tippen, rufen Sie `embeddedViewModel.confirm()` auf, um die Zahlung abzuschließen. Achten Sie darauf, die Nutzerinteraktion während der Bestätigung zu deaktivieren. ```swift extension MyEmbeddedCheckoutView { func didTapConfirmButton() { Task { @MainActor in // Be sure to disable user interaction during confirm (not shown in this example) let result = await embeddedViewModel.confirm() switch result { case .completed: // Payment completed - show a confirmation screen. case .failed(let error): // Encountered an unrecoverable error. Re-enable user interaction, display the error to the user, log it, and so on. case .canceled: // Customer canceled - re-enable user interaction and let them try again. break } } } } ``` Implementieren Sie als Nächstes den Rückruf `confirmationTokenConfirmHandler`, den Sie zuvor an`PaymentSheet.IntentConfiguration` übergeben haben, um eine Anfrage an Ihren Server zu senden. Ihr Server erstellt einen PaymentIntent und gibt sein Client-Geheimnis zurück. Weitere Informationen zu diesem Prozess finden Sie unter [Erstellen eines PaymentIntent](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#submit-payment). Geben Sie das Client Secret aus der Serverantwort zurück oder geben Sie einen Fehler. Das EmbeddedPaymentElement bestätigt den PaymentIntent mithilfe des Client-Geheimnisses oder zeigt die lokalisierte Fehlermeldung in seiner Nutzeroberfläche an (entweder [errorDescription](https://developer.apple.com/documentation/foundation/localizederror/2946895-errordescription) oder [localizedDescription](https://developer.apple.com/documentation/foundation/nserror/1414418-localizeddescription)). Nach Abschluss der Bestätigung kann das EmbeddedPaymentElement nicht mehr verwendet werden. Leiten Sie die Nutzerin oder den Nutzer stattdessen zu einem Zahlungsbeleg oder einer ähnlichen Seite weiter. ```swift extension MyEmbeddedCheckoutView { func handleConfirmationToken(_ confirmationToken: STPConfirmationToken) async throws -> String { // Make a request to your own server. Pass confirmationToken.stripeId if using server-side confirmation. // Return the client secret or throw an error return try await MyAPIClient.shared.createIntent(confirmationTokenId: confirmationToken.stripeId) } } ``` ## Optional: Ausgewählte Zahlungsoption löschen Wenn Sie Zahlungsoptionen außerhalb von EmbeddedPaymentElement haben, müssen Sie möglicherweise die ausgewählte Zahlungsoption löschen. Verwenden Sie dazu die `clearPaymentOption` API, um die ausgewählte Zahlungsoption zu deaktivieren. #### UIKit ```swift extension MyCheckoutVC: UIViewController { func deselectPaymentMethod() { embeddedPaymentElement?.clearPaymentOption() } } ``` #### SwiftUI ```swift @available(iOS 15.0, *) extension MyEmbeddedCheckoutView { func deselectPaymentMethod() { embeddedViewModel.clearPaymentOption() } } ``` ## Optional: Mandat selbst anzeigen Standardmäßig zeigt das eingebettete Mobile Payment Element Mandate und rechtliche Haftungsausschlüsse an, um die Einhaltung gesetzlicher Vorschriften zu gewährleisten. Dieser Text muss sich in der Nähe Ihrer Schaltfläche „Kaufen“ befinden. Deaktivieren Sie ggf. die Anzeige in der Ansicht und zeigen Sie sie stattdessen selbst an. > Ihre Integration muss den Mandatstext anzeigen, um die Konformität zu gewährleisten. Stellen Sie sicher, dass URLs im Text mithilfe von UITextView oder Ähnlichem geöffnet werden können. #### UIKit ```swift var configuration = EmbeddedPaymentElement.Configuration(...) configuration.embeddedViewDisplaysMandateText = true ... let mandateTextView = UITextView() mandateTextView.attributedText = embeddedPaymentElement.paymentOption.mandateText ``` #### SwiftUI ```swift var configuration = EmbeddedPaymentElement.Configuration(...) configuration.embeddedViewDisplaysMandateText = true ... if let attributedText = embeddedViewModel.paymentOption?.mandateText { Text(AttributedString(attributedText)) } ``` ## Optional: Lassen Sie den Kunden/die Kundin sofort im Formular bezahlen ![Eingebettetes Zahlungs-Element](https://b.stripecdn.com/docs-statics-srv/assets/embedded-pay-immediate.057c691220d43158ac8000de10815ed9.png) Um die Schaltfläche im Formular zur sofortigen Bestätigung der Zahlung zu konfigurieren, legen Sie `formSheetAction` für Ihr `EmbeddedPaymentElement.Configuration`-Objekt fest. Der Completion-Block wird mit dem Ergebnis der Zahlung ausgeführt, nachdem das Formular geschlossen wurde. Die eingebettete Nutzeroberfläche kann nach Abschluss der Zahlung nicht verwendet werden. Wir empfehlen daher, dass Ihre Implementierung die Nutzer/innen zu einem anderen Bildschirm weiterleitet, z. B. einem Zahlungsbeleg-Bildschirm. ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.formSheetAction = .confirm(completion: { result in switch result { case .completed: // Payment completed. You can for example, show a confirmation screen. print("Completed") case .failed(let error): // Encountered an unrecoverable error. You can display the error to the user, log it, etc. print(error) case .canceled: // Customer canceled - you should probably do nothing. break } }) ``` ## PaymentIntent erstellen [Serverseitig] Erstellen Sie auf Ihrem Server a *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) durch Angabe eines Betrags und einer Währung. Sie können Zahlungsmethoden über das [Dashboard](https://dashboard.stripe.com/settings/payment_methods) verwalten. Stripe handhabt die Rückgabe geeigneter Zahlungsmethoden basierend auf Faktoren wie Betrag, Währung und Zahlungsablauf der Transaktion. Um zu verhindern, dass böswillige Kundinnen und Kunden ihre eigenen Preise wählen, sollten Sie den Preis immer auf der Serverseite (einer vertrauenswürdigen Umgebung) festlegen und nicht auf dem Client. Wenn der Aufruf erfolgreich ist, geben Sie den PaymentIntent *das Client-Geheimnis* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) zurück. Wenn der Aufruf fehlschlägt, [beheben Sie den Fehler](https://docs.stripe.com/error-handling.md) und geben eine Fehlermeldung mit einer kurzen Erklärung an Ihre Kundin/Ihren Kunden zurück. > Überprüfen Sie, ob alle IntentConfiguration-Eigenschaften mit Ihrem PaymentIntent (zum Beispiel `setup_future_usage`, `amount` und `currency`) übereinstimmen. #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') post '/create-intent' do data = JSON.parse request.body.read params = { customer: ..., # The Customer ID you previously created amount: 1099, currency: 'usd', setup_future_usage: 'off_session', automatic_payment_methods: {enabled: true}, } begin intent = client.v1.payment_intents.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` ## Rückgabe-URL einrichten [Clientseitig] Der Kunde/Die Kundin verlässt ggf. Ihre App, um sich zu authentifizieren (z. B. in Safari oder einer Banking-App). Damit sie nach der Authentifizierung automatisch zu Ihrer App zurückkehren können, [konfigurieren Sie ein benutzerdefiniertes URL-Schema](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app) und richten Sie Ihren App-Delegate so ein, dass die URL an das SDK weitergeleitet wird. Stripe unterstützt keine [universellen Links](https://developer.apple.com/documentation/xcode/allowing-apps-and-websites-to-link-to-your-content). #### SceneDelegate #### Swift ```swift // This method handles opening custom URL schemes (for example, "your-app://stripe-redirect") func scene(_ scene: UIScene, openURLContexts URLContexts: Set) { guard let url = URLContexts.first?.url else { return } let stripeHandled = StripeAPI.handleURLCallback(with: url) if (!stripeHandled) { // This was not a Stripe url – handle the URL normally as you would } } ``` #### AppDelegate #### Swift ```swift // This method handles opening custom URL schemes (for example, "your-app://stripe-redirect") func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { let stripeHandled = StripeAPI.handleURLCallback(with: url) if (stripeHandled) { return true } else { // This was not a Stripe url – handle the URL normally as you would } return false } ``` #### SwiftUI #### Swift ```swift @main struct MyApp: App { var body: some Scene { WindowGroup { Text("Hello, world!").onOpenURL { incomingURL in let stripeHandled = StripeAPI.handleURLCallback(with: incomingURL) if (!stripeHandled) { // This was not a Stripe url – handle the URL normally as you would } } } } } ``` Legen Sie außerdem die [returnURL](https://github.com/stripe/stripe-ios/blob/aa3234a7fafde98c9203b6ed77e0278c04310eb0/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L70) für Ihr [EmbeddedPaymentElement.Configuration](https://github.com/stripe/stripe-ios/blob/aa3234a7fafde98c9203b6ed77e0278c04310eb0/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L12)-Objekt auf die URL für Ihre App fest. ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.returnURL = "your-app://stripe-redirect" ``` ## Ereignisse nach Zahlung verarbeiten [Serverseitig] Stripe sendet ein [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded)-Ereignis, wenn die Zahlung abgeschlossen ist. Verwenden Sie [Webhook-Tool im Dashboard](https://dashboard.stripe.com/webhooks) oder folgen Sie der [Webhook-Anleitung](https://docs.stripe.com/webhooks/quickstart.md), um diese Ereignisse zu empfangen und führen Sie Aktionen aus, wie beispielsweise das Senden einer Bestellbestätigung per E-Mail, das Protokollieren des Verkaufs in der Datenbank oder das Starten eines Versand-Workflows. Überwachen Sie diese Ereignisse, statt auf einen Callback vom Client zu warten. Auf dem Client könnten die Kund/innen das Browserfenster schließen oder die App beenden, bevor der Callback erfolgt ist. Bösartige Clients könnten dann die Antwort manipulieren. Wenn Sie Ihre Integration so einrichten, dass sie asynchrone Ereignisse überwacht, können Sie [verschiedene Arten von Zahlungsmethoden](https://stripe.com/payments/payment-methods-guide) mit einer einzelnen Integration akzeptieren. Neben der Abwicklung des `payment_intent.succeeded`-Ereignisses empfehlen wir die Abwicklung von diesen weiteren Ereignissen, wenn Sie Zahlungen mit dem Payment Element erfassen: | Ereignis | Beschreibung | Aktion | | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded) | Wird gesendet, wenn Kundinnen und Kunden eine Zahlung erfolgreich abgeschlossen haben. | Senden Sie den Kund/innen eine Auftragsbestätigung und *wickeln* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected) Sie die Bestellung ab. | | [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing) | Wird gesendet, wenn eine/e Kund/in eine Zahlung erfolgreich veranlasst hat, die Zahlung aber noch nicht abgeschlossen ist. Dieses Ereignis wird am häufigsten gesendet, wenn der Kunde/die Kundin eine Bankabbuchung veranlasst. In Zukunft folgt darauf entweder ein `payment_intent.succeeded`- oder ein `payment_intent.payment_failed`-Ereignis. | Senden Sie eine Bestellbestätigung an die Kund/innen, in der angegeben ist, dass die Zahlung noch aussteht. Bei digitalen Waren können Sie die Bestellung abwickeln, bevor Sie darauf warten, dass die Zahlung erfolgt. | | [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | Wird gesendet, wenn ein Kunde/eine Kundin einen Zahlungsversuch durchführt, die Zahlung jedoch fehlschlägt. | Wenn eine Zahlung von `processing` zu `payment_failed` übergeht, bieten Sie der Kundin/dem Kunden einen weiteren Zahlungsversuch an. | ## Die gespeicherte Zahlungsmethode später belasten [Serverseitig] > `bancontact` und `ideal` sind standardmäßig einmalige Zahlungsmethoden. Wenn sie für die künftige Verwendung eingerichtet werden, erzeugen sie eine wiederverwendbare Art der Zahlungsmethode `sepa_debit`, sodass Sie `sepa_debit` verwenden müssen, um gespeicherte Zahlungsmethoden abzufragen. > #### Compliance > > Sie sind für die Einhaltung aller geltenden Gesetze, Vorschriften und Netzwerkregeln verantwortlich, wenn Sie die Zahlungsdaten von Kundinnen und Kunden speichern. Wenn Sie Ihren Endkundinnen und Endkunden zuvor genutzte Zahlungsmethoden für zukünftige Einkäufe anzeigen, dürfen Sie nur Zahlungsmethoden auflisten, für die Sie bereits eine kundenseitige Zustimmung eingeholt haben, dank der Sie die Details der Zahlungsmethode für diese spezifische zukünftige Verwendung speichern können. Verwenden Sie den Parameter [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay), um zwischen Zahlungsmethoden zu unterscheiden, die mit Kundinnen und Kunden verknüpft sind und Ihren Endkundinnen und Endkunden als gespeicherte Zahlungsmethode für zukünftige Einkäufe angezeigt werden können oder nicht. Um eine Zahlungsmethode zum Belasten zu finden, listen Sie die Zahlungsmethoden auf, die mit Ihrer Kundin/Ihrem Kunden verknüpft sind. In diesem Beispiel sind Karten aufgeführt, Sie können jedoch jeden unterstützten [Typ](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-type) auflisten. > #### Verwenden Sie die Accounts v2 API zum Darstellen von Kundinnen und Kunden > > Die Accounts v2 API ist allgemein für Connect-Nutzer/innen verfügbar und für andere Stripe-Nutzer/innen in der öffentlichen Vorschau. Wenn an der Accounts v2 Vorschau teilnehmen, müssen Sie eine [Vorschauversion](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) in Ihrem Code angeben. > > Um Zugriff auf die Accounts v2 Vorschau anzufordern, {% collect-email modal=true modal_link_text=“sign up.” list=“payin-payout-reuse-waitlist@stripe.com” send_direct_email=true intro_text=“Sind Sie am frühzeitigen Zugang zur Vorschau der Accounts v2 API interessiert?" body_text=“Wir sind gerade dabei, die Vorschau von Accounts v2 bereitzustellen. Um Zugang zu beantragen, geben Sie unten Ihre E-Mail-Adresse ein.” form_cta_text=“Registrieren” success_text=“Danke! Wir melden uns bald.” show_email_confirmation=wahr /%} > > Für die meisten Anwendungsfälle empfehlen wir, [Ihre Kundinnen und Kunden als vom Kunden bzw. von der Kundin konfigurierte Account-Objekte abzubilden](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md), anstatt [Customer](https://docs.stripe.com/api/customers.md)-Objekte zu verwenden. #### Accounts v2 ```curl curl -G https://api.stripe.com/v1/payment_methods \ -u "<>:" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d type=card ``` #### Customers v1 ```curl curl -G https://api.stripe.com/v1/payment_methods \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d type=card ``` Wenn Sie bereit sind, die Zahlung Ihrer Kundin/Ihres Kunden *off-session* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information) zu belasten, verwenden Sie die `Kunden`-ID oder das von der Kundin/dem Kunden/Kundin konfigurierte `Konto` und die `PaymentMethod`-ID, um einen `PaymentIntent` mit dem Betrag und der Währungen der Zahlung zu erstellen. Legen Sie einige weitere Parameter fest, um die Off-Session-Zahlung durchzuführen: - Legen Sie [off_session](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-off_session) auf true fest, um anzugeben, dass der Kunde/die Kundin sich während eines Bezahlvorgangs nicht in Ihrem Bezahlvorgang befindet und somit eine Authentifizierungsanfrage eines Partners, wie z. B. eines Kartenausstellers, einer Bank oder eines anderen Zahlungsinstituts, nicht erfüllen kann. Wenn ein Partner während Ihres Bezahlvorgangs eine Authentifizierung anfordert, fordert Stripe Ausnahmen unter Verwendung von Kunden/Kundinnen aus einer vorherigen *On-Session*-Transaktion an. Wenn die Bedingungen für die Ausnahme nicht erfüllt sind, kann der `PaymentIntent` einen Fehler ergeben. - Setzen Sie [„confirm“](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) auf „true“, um sofort nach Erstellung des `PaymentIntent` eine Bestätigung auszulösen. - Legen Sie [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) auf die ID der `PaymentMethod` fest. - Je nachdem, wie Sie Kundinnen/Kunden in Ihrer Integration darstellen, legen Sie entweder [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) auf die ID des kundenseitig konfigurierten `Kontos` oder [customer](https://docs.stripe.com/api.md#create_payment_intent-customer) auf die `Kunden`-ID fest. #### Accounts v2 ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=usd \ -d "automatic_payment_methods[enabled]=true" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d payment_method={{PAYMENT_METHOD_ID}} \ --data-urlencode "return_url=https://example.com/order/123/complete" \ -d off_session=true \ -d confirm=true ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=usd \ -d "automatic_payment_methods[enabled]=true" \ -d "customer={{CUSTOMER_ID}}" \ -d payment_method={{PAYMENT_METHOD_ID}} \ --data-urlencode "return_url=https://example.com/order/123/complete" \ -d off_session=true \ -d confirm=true ``` ## Integration testen #### Karten | Kartennummer | Szenario | So führen Sie den Test durch | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | | 4242424242424242 | Die Kartenzahlung ist erfolgreich und es ist keine Authentifizierung erforderlich. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 4000002500003155 | Für die Kartenzahlung ist eine *Authentifizierung* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase) erforderlich. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 4000000000009995 | Die Karte wird mit einem Ablehnungscode wie `insufficient_funds` abgelehnt. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 6205500000000000004 | Die UnionPay-Karte hat eine variable Länge von 13 bis 19 Ziffern. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | #### Bankumleitungen | Zahlungsmethode | Szenario | So führen Sie den Test durch | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Bancontact, iDEAL | Ihr/e Kund/in konnte sich auf der iDEAL-Weiterleitungsseite für eine auf Weiterleitung basierende Zahlungsmethode mit sofortiger Benachrichtigung nicht authentifizieren. | Wählen Sie eine beliebige, auf Weiterleitung basierende Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung fehlgeschlagen**. | | Pay by Bank | Ihr Kunde/Ihre Kundin zahlt erfolgreich mit einer auf Weiterleitung basierenden Zahlungsmethode mit [verzögerter Benachrichtigung](https://docs.stripe.com/payments/payment-methods.md#payment-notification). | Wählen Sie die Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung abschließen**. | | Pay by Bank | Ihr/e Kund/in konnte sich auf der iDEAL-Weiterleitungsseite für eine auf Weiterleitung basierende Zahlungsmethode mit verzögerter Benachrichtigung nicht authentifizieren. | Wählen Sie die Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung fehlgeschlagen**. | | BLIK | BLIK-Zahlungen können aus verschiedenen Gründen fehlschlagen. Es gibt sofortige Fehler (der Code ist abgelaufen oder ungültig), verzögerte Fehler (die Bank lehnt ab) oder Zeitüberschreitungen (der/die Kund/in hat nicht rechtzeitig reagiert). | Verwenden Sie E-Mail-Muster, um [die verschiedenen Fehler zu simulieren](https://docs.stripe.com/payments/blik/accept-a-payment.md#simulate-failures) | #### Banklastschriften | Zahlungsmethode | Szenario | So führen Sie den Test durch | | ---------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | SEPA-Lastschrift | Ihr/e Kund/in zahlt erfolgreich mit dem SEPA-Lastschriftverfahren. | Füllen Sie das Formular mit der Kontonummer `AT321904300235473204` aus. Die bestätigte PaymentIntent geht zunächst in den Status „wird verarbeitet“ und dann drei Minuten später in den Status „erfolgreich“ über. | | SEPA-Lastschrift | Der Status der PaymentIntent Ihres/Ihrer Kund/in wechselt von `processing` zu `requires_payment_method`. | Füllen Sie das Formular mit der Kontonummer `AT861904300235473202` aus. | Hier finden Sie weitere Informationen zum [Testen](https://docs.stripe.com/testing.md) Ihrer Integration. ## Optional: Setzen Sie SetupFutureUsage für einzelne Zahlungsmethoden (Preview) [Serverseitig] [Clientseitig] Für mehr Detailgenauigkeit legen Sie `setupFutureUsage` für bestimmte Zahlungsmethoden mit [PaymentSheet.IntentConfiguration.Mode.PaymentMethodOptions](https://github.com/stripe/stripe-ios/blob/master/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/PaymentSheetIntentConfiguration.swift#L116) fest. ```swift @_spi(PaymentMethodOptionsSetupFutureUsagePreview) import StripePaymentSheet class MyCheckoutVC: UIViewController { func createEmbeddedPaymentElement() async throws -> EmbeddedPaymentElement { let intentConfig = PaymentSheet.IntentConfiguration( mode: .payment( amount: 1099, currency: "USD",paymentMethodOptions: PaymentSheet.IntentConfiguration.Mode.PaymentMethodOptions( setupFutureUsageValues: [ .card: .offSession, .cashApp: .onSession ] ) ) ) { [weak self] confirmationToken in return try await self?.handleConfirmationToken(confirmationToken) } var configuration = EmbeddedPaymentElement.Configuration() configuration.returnURL = "your-app://stripe-redirect" // Use the return url you set up in the previous step let embeddedPaymentElement = try await EmbeddedPaymentElement.create(intentConfiguration: intentConfig, configuration: configuration) embeddedPaymentElement.presentingViewController = self embeddedPaymentElement.delegate = self return embeddedPaymentElement } } ``` Erfahren Sie mehr über [die `setupFutureUsage`-Werte](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-payment_method_options), die für jede Zahlung unterstützt werden. Stellen Sie als Nächstes sicher, dass Ihr Server das Feld `setup_future_usage` oder `Zahlung_method_options[X][setup_future_usage]` für den PaymentIntent nicht festlegt. Das SDK übernimmt die Einstellung automatisch anhand der `IntentConfiguration`. #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') post '/create-intent' do data = JSON.parse request.body.read params = { amount: 1099, currency: 'usd', confirmation_token: data['confirmation_token'], # In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: {enabled: true}, } begin intent = client.v1.payment_intents.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` ## Kartenscannen aktivieren Um die Unterstützung für das Scannen von Karten für iOS zu aktivieren, setzen Sie `NSCameraUsageDescription` (**Datenschutz – Beschreibung Kameranutzung**) in der `Info.plist` Ihrer Anwendung und geben einen Grund für den Zugriff auf die Kamera an (z. B. „Zum Scannen von Karten“). ## Optional: Karten speichern [Serverseitig] [Clientseitig] `EmbeddedPaymentElement` kann es Kundinnen und Kunden ermöglichen, ihre Karte zu speichern, und die gespeicherten Karten des Kunden/der Kundin in die verfügbaren Zahlungsmethoden aufnehmen. Der Kunde/Die Kundin muss über ein zugehöriges, vom Kunden/von der Kundin konfiguriertes [Account](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer)-Objekt oder [Customer](https://docs.stripe.com/api/customers/create.md)-Objekt auf Ihrem Server verfügen. Um ein Kontrollkästchen zu aktivieren, mit dem der Kunde/die Kundin seine/ihre Karte speichern kann, erstellen Sie eine [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) mit `enabled` für `payment_method_save`. #### Accounts v2 ```javascript const stripe = require('stripe')('sk_test_your_secret_key'); app.post('/mobile-payment-element', async (req, res) => { // Use an existing Account ID if this is a returning customer. const customer_account = await stripe.v2.core.accounts.create(); const customerSession = await stripe.customerSessions.create({ customer_account: customer_account.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer_account: customer_account.id, }); }); ``` Konfigurieren Sie als Nächstes EmbeddedPaymentElement mit der ID des Kunden/der Kundin und dem Client-Geheimnis der CustomerSession. #### UIKit ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet var configuration = EmbeddedPaymentElement.Configuration() configuration.customer = .init(id: customerAccountId, customerSessionClientSecret: customerSessionClientSecret) self.embeddedPaymentElement = try await EmbeddedPaymentElement.create(..., configuration: configuration) ``` #### SwiftUI ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet var configuration = EmbeddedPaymentElement.Configuration() configuration.customer = .init(id: customerAccountId, customerSessionClientSecret: customerSessionClientSecret) try await embeddedViewModel.load(..., configuration: configuration) ``` #### Customers v1 ```javascript const stripe = require('stripe')('sk_test_your_secret_key'); app.post('/mobile-payment-element', async (req, res) => { // Use an existing Customer ID if this is a returning customer. const customer = await stripe.customers.create(); const customerSession = await stripe.customerSessions.create({ customer: customer.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer: customer.id, }); }); ``` Konfigurieren Sie als Nächstes EmbeddedPaymentElement mit der ID des Kunden/der Kundin und dem Client-Geheimnis der CustomerSession. #### UIKit ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet var configuration = EmbeddedPaymentElement.Configuration() configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret) self.embeddedPaymentElement = try await EmbeddedPaymentElement.create(..., configuration: configuration) ``` #### SwiftUI ```swift @_spi(CustomerSessionBetaAccess) import StripePaymentSheet var configuration = EmbeddedPaymentElement.Configuration() configuration.customer = .init(id: customerId, customerSessionClientSecret: customerSessionClientSecret) try await embeddedViewModel.load(..., configuration: configuration) ``` ## Optional: Zahlungsmethoden mit Verzögerung zulassen [Clientseitig] *Zahlungsmethoden mit Verzögerung* (A payment method that can't immediately return payment status when a customer attempts a transaction (for example, ACH debits). Businesses commonly hold an order in a pending state until payment is successful with these payment methods) garantieren nicht, dass Sie am Ende des Bezahlvorgangs Gelder von Ihrem Kunden/Ihrer Kundin erhalten, da die Abwicklung eine gewisse Zeit in Anspruch nimmt (z. B. bei US-Bankkonten, SEPA-Lastschrift, iDEAL und Bancontact) oder weil Kundinnen und Kunden aktiv werden müssen, um den Vorgang abzuschließen (z. B. OXXO, Konbini und Boleto). Standardmäßig zeigt EmbeddedPaymentElement keine Zahlungsmethoden mit Verzögerung an. Um die Funktion zu aktivieren, setzen Sie `allowsDelayedPaymentMethods` in Ihrer `EmbeddedPaymentElement.Configuration` auf „true“. Durch diesen Schritt allein werden keine bestimmten Zahlungsmethoden aktiviert. Er zeigt vielmehr an, dass Ihre App in der Lage ist, diese zu verarbeiten. Obwohl beispielsweise OXXO derzeit nicht von EmbeddedPaymentElement unterstützt wird, kann Ihre App OXXO als Zahlungsoption ohne zusätzliche Integrationsänderungen anzeigen, wenn es unterstützt wird und Sie auf die neueste SDK-Version aktualisiert haben. #### UIKit ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.allowsDelayedPaymentMethods = true self.embeddedPaymentElement = try await EmbeddedPaymentElement.create(..., configuration: configuration) ``` #### SwiftUI ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.allowsDelayedPaymentMethods = true try await embeddedViewModel.load(..., configuration: configuration) ``` Wenn die Kundin/der Kunde erfolgreich eine dieser Zahlungsmethoden mit Verzögerung in EmbeddedPaymentElement verwendet, lautet das zurückgegebene Zahlungsergebnis `.completed`. ## Optional: Apple Pay aktivieren > Wenn Ihr Zahlungsbildschirm eine spezielle **Apple Pay**-Schaltfläche enthält, folgen Sie dem [Apple Pay-Leitfaden](https://docs.stripe.com/apple-pay.md#present-payment-sheet) und verwenden Sie `ApplePayContext`, um Zahlungen über Ihre **Apple Pay**-Schaltfläche einzuziehen. Sie können `EmbeddedPaymentElement` verwenden, um andere Arten von Zahlungsmethoden zu handhaben. ### Eine Apple-Händler-ID registrieren Beantragen Sie eine Apple-Händler-ID, indem Sie sich auf der Apple Developer-Website [für eine neue Kennung registrieren](https://developer.apple.com/account/resources/identifiers/add/merchant). Tragen Sie eine Beschreibung und eine Kennung in das Formular ein. Die Beschreibung ist nur für Ihre internen Zwecke bestimmt und kann später geändert werden. Stripe empfiehlt, dass Sie den Namen Ihrer App als Kennung verwenden, zum Beispiel `merchant.com.{{YOUR_APP_NAME}}`. ### Neues Apple Pay-Zertifikat erstellen Erstellen Sie ein Zertifikat für Ihre App, um Zahlungsdaten zu verschlüsseln. Gehen Sie zu den [iOS-Zertifikateinstellungen](https://dashboard.stripe.com/settings/ios_certificates) im Dashboard, klicken Sie auf **Neue Anwendung hinzufügen** und befolgen Sie die Anleitung. Laden Sie eine Certificate Signing Request (CSR)-Datei herunter, um ein sicheres Zertifikat von Apple zu erhalten, mit dem Sie Apple Pay verwenden können. Eine CSR-Datei muss verwendet werden, um genau ein Zertifikat auszustellen. Wenn Sie Ihre Apple-Händler-ID wechseln, müssen Sie zu den [iOS-Zertifikateinstellungen](https://dashboard.stripe.com/settings/ios_certificates) im Dashboard gehen, um eine neue CSR und ein Zertifikat zu erhalten. ### Mit Xcode integrieren Fügen Sie Ihrer App die **Apple Pay**-Funktion hinzu. Öffnen Sie in Xcode Ihre Projekteinstellungen, klicken Sie auf die Registerkarte **Signing & Capabilities** (Anmeldung und Funktionen) und fügen Sie die **Apple Pay**-Funktion hinzu. Möglicherweise werden Sie an dieser Stelle aufgefordert, sich bei Ihrem Entwicklerkonto anzumelden. Wählen Sie die zuvor erstellte Händler-ID aus. Ihre App sollte nun Apple Pay unterstützen. ![](https://b.stripecdn.com/docs-statics-srv/assets/xcode.a701d4c1922d19985e9c614a6f105bf1.png) Apple Pay-Funktion in Xcode aktivieren ### Apple Pay hinzufügen #### Einmalige Zahlung Um Apple Pay zu EmbeddedPaymentElement hinzuzufügen, legen Sie [applePay](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L28) fest, nachdem Sie `EmbeddedPaymentElement.Configuration` mit Ihrer Apple-Händler-ID und dem [Ländercode](https://dashboard.stripe.com/settings/account) Ihres Unternehmens initialisiert haben. #### iOS (Swift) ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.applePay = .init( merchantId: "merchant.com.your_app_name", merchantCountryCode: "US" ) ``` #### Wiederkehrende Zahlungen Um Apple Pay zu EmbeddedPaymentElement hinzuzufügen, legen Sie [applePay](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L28) fest, nachdem Sie `EmbeddedPaymentElement.Configuration` mit Ihrer Apple-Händler-ID und dem [Ländercode](https://dashboard.stripe.com/settings/account) Ihres Unternehmens initialisiert haben. Gemäß den [Apple-Richtlinien](https://developer.apple.com/design/human-interface-guidelines/apple-pay#Supporting-subscriptions) für wiederkehrende Zahlungen müssen Sie auch zusätzliche Attribute für `PKPaymentRequest` festlegen. Fügen Sie in [ApplePayConfiguration.paymentRequestHandlers](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/paymentrequesthandler) einen Handler hinzu, um die [PKPaymentRequest.paymentSummaryItems](https://developer.apple.com/documentation/passkit/pkpaymentrequest/1619231-paymentsummaryitems) mit dem Betrag zu konfigurieren, den Sie berechnen möchten (z. B. 9,95 USD pro Monat). Sie können auch [Händler-Token](https://developer.apple.com/apple-pay/merchant-tokens/) übernehmen, indem Sie die Eigenschaften `recurringPaymentRequest` oder `automaticReloadPaymentRequest` für `PKPaymentRequest` festlegen. Weitere Informationen zur Verwendung wiederkehrender Zahlungen mit Apple Pay finden Sie in der [PassKit-Dokumentation von Apple](https://developer.apple.com/documentation/passkit/pkpaymentrequest). #### iOS (Swift) ```swift let customHandlers = EmbeddedPaymentElement.ApplePayConfiguration.Handlers( paymentRequestHandler: { request in // PKRecurringPaymentSummaryItem is available on iOS 15 or later if #available(iOS 15.0, *) { let billing = PKRecurringPaymentSummaryItem(label: "My Subscription", amount: NSDecimalNumber(string: "59.99")) // Payment starts today billing.startDate = Date() // Payment ends in one year billing.endDate = Date().addingTimeInterval(60 * 60 * 24 * 365) // Pay once a month. billing.intervalUnit = .month billing.intervalCount = 1 // recurringPaymentRequest is only available on iOS 16 or later if #available(iOS 16.0, *) { request.recurringPaymentRequest = PKRecurringPaymentRequest(paymentDescription: "Recurring", regularBilling: billing, managementURL: URL(string: "https://my-backend.example.com/customer-portal")!) request.recurringPaymentRequest?.billingAgreement = "You'll be billed $59.99 every month for the next 12 months. To cancel at any time, go to Account and click 'Cancel Membership.'" } request.paymentSummaryItems = [billing] request.currencyCode = "USD" } else { // On older iOS versions, set alternative summary items. request.paymentSummaryItems = [PKPaymentSummaryItem(label: "Monthly plan starting July 1, 2022", amount: NSDecimalNumber(string: "59.99"), type: .final)] } return request } ) var configuration = EmbeddedPaymentElement.Configuration() configuration.applePay = .init(merchantId: "merchant.com.your_app_name", merchantCountryCode: "US", customHandlers: customHandlers) ``` ### Sendungsverfolgung Um Informationen zur [Bestellverfolgung](https://developer.apple.com/design/human-interface-guidelines/technologies/wallet/designing-order-tracking) in iOS 16 oder höher hinzuzufügen, konfigurieren Sie einen [authorizationResultHandler](https://stripe.dev/stripe-ios/stripepaymentsheet/documentation/stripepaymentsheet/paymentsheet/applepayconfiguration/handlers/authorizationresulthandler) in Ihren `PaymentSheet.ApplePayConfiguration.Handlers`. Stripe ruft Ihre Implementierung auf, nachdem die Zahlung durchgeführt wurde, aber bevor iOS das Apple Pay-Formular schließt. Rufen Sie in Ihrer Implementierung von `authorizationResultHandler` die Bestelldetails für die abgeschlossene Bestellung von Ihrem Server ab. Fügen Sie die Details dem bereitgestellten [PKPaymentAuthorizationResult](https://developer.apple.com/documentation/passkit/pkpaymentauthorizationresult) hinzu und geben Sie das geänderte Ergebnis zurück. Weitere Informationen zur Sendungsverfolgung finden Sie in der [Apple-Dokumentation zu Wallet-Bestellungen](https://developer.apple.com/documentation/walletorders). #### iOS (Swift) ```swift let customHandlers = PaymentSheet.ApplePayConfiguration.Handlers( authorizationResultHandler: { result in do { // Fetch the order details from your service let myOrderDetails = try await MyAPIClient.shared.fetchOrderDetails(orderID: orderID) result.orderDetails = PKPaymentOrderDetails( orderTypeIdentifier: myOrderDetails.orderTypeIdentifier, // "com.myapp.order" orderIdentifier: myOrderDetails.orderIdentifier, // "ABC123-AAAA-1111" webServiceURL: myOrderDetails.webServiceURL, // "https://my-backend.example.com/apple-order-tracking-backend" authenticationToken: myOrderDetails.authenticationToken) // "abc123" // Return your modified PKPaymentAuthorizationResult return result } catch { return PKPaymentAuthorizationResult(status: .failure, errors: [error]) } } ) var configuration = EmbeddedPaymentElement.Configuration() configuration.applePay = .init(merchantId: "merchant.com.your_app_name", merchantCountryCode: "US", customHandlers: customHandlers) ``` ## Optional: Element anpassen Alle Anpassungen werden mithilfe des [EmbeddedPaymentElement.Configuration](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L12)-Objekts konfiguriert. ### Erscheinungsbild Passen Sie mit der [Appearance API](https://docs.stripe.com/elements/appearance-api/embedded-mobile.md?platform=ios) Farben, Schriftarten und mehr an das Erscheinungsbild Ihrer App an. ### Adressen der Nutzer/innen erfassen Erfassen Sie lokale und internationale Versand- und Rechnungsadressen von Ihren Kundinnen und Kunden mithilfe des [Address Element](https://docs.stripe.com/elements/address-element.md?platform=ios). ### Anzeigename des Händlers Geben Sie einen kundenorientierten Unternehmensnamen an, indem Sie [merchantDisplayName](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L66) festlegen. Standardmäßig handelt es sich dabei um den Namen Ihrer App. #### Swift ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.merchantDisplayName = "My app, Inc." ``` ### Dunkelmodus `EmbeddedPaymentElement` passt sich automatisch an die systemweiten Erscheinungsbildeinstellungen des Nutzers/der Nutzerin an (heller und dunkler Modus). Wenn Ihre App den dunklen Modus nicht unterstützt, können Sie den [Stil](https://github.com/stripe/stripe-ios/blob/8be959abc141e360080efa88980afb325737a935/StripePaymentSheet/StripePaymentSheet/Source/PaymentSheet/Embedded/EmbeddedPaymentElementConfiguration.swift#L51) auf den Modus `alwaysLight` oder `alwaysDark` festlegen. ```swift var configuration = EmbeddedPaymentElement.Configuration() configuration.style = .alwaysLight ``` ## Optional: Aktiveren der Funktion zur erneuten Erfassung der Prüfziffer/CVC bei Bestätigung Um die Prüfziffer einer gespeicherten Karte während der PaymentIntent-Bestätigung erneut einzuziehen, muss Ihre Integration Zahlungsdaten einziehen, bevor ein PaymentIntent erstellt wird. ### Intent-Konfiguration aktualisieren `PaymentSheet.IntentConfiguration` akzeptiert einen optionalen Parameter, mit dem gesteuert wird, wann die Prüfziffer/CVC für eine gespeicherte Karte erneut erfasst werden soll. ```swift let intentConfig = PaymentSheet.IntentConfiguration( mode: .payment(amount: 1099, currency: "USD"), confirmHandler: { confirmationToken in // Handle ConfirmationToken...}, requireCVCRecollection: true) ``` ### Parameter der Intent-Erstellung aktualisieren Um die Prüfziffer/CVC bei der Zahlungsbestätigung erneut zu erfassen, fügen Sie bei der Erstellung des PaymentIntent die beiden Parameter `customerId` und `require_cvc_recollection` ein. #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/create-intent' do data = JSON.parse request.body.read params = { amount: 1099, currency: 'usd', automatic_payment_methods: {enabled: true},customer: customer.id, payment_method_options: { card: {require_cvc_recollection: true} } } begin intent = client.v1.payment_intents.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` # Zahlung akzeptieren > This is a Zahlung akzeptieren for when platform is android and type is payment. View the full page at https://docs.stripe.com/payments/mobile/accept-payment-embedded?platform=android&type=payment. Mit dem Zahlungs-Element können Sie mehrere Zahlungen über eine einzige Integration akzeptieren. Bei dieser Integration erstellen Sie einen benutzerdefinierten Zahlungsablauf, bei dem Sie das Zahlungs-Element rendern, den *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) erstellen und die Zahlung in Ihrer App bestätigen. ## Stripe einrichten [Serverseitig] [Clientseitig] Zunächst benötigen Sie ein Stripe-Konto. [Registrieren Sie sich jetzt](https://dashboard.stripe.com/register). ### Serverseitig Für diese Integration sind Endpoints auf Ihrem Server erforderlich, die mit der Stripe-API kommunizieren können. Nutzen Sie diese offiziellen Bibliotheken für den Zugriff auf die Stripe-API von Ihrem Server aus: #### 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' ``` ### Client-seitig Das [Stripe Android SDK](https://github.com/stripe/stripe-android) ist Open Source und [vollständig dokumentiert](https://stripe.dev/stripe-android/). Um das SDK zu installieren, fügen Sie `stripe-android` in den Block `dependencies` Ihrer [app/build.gradle](https://developer.android.com/studio/build/dependencies)-Datei ein: #### Kotlin ```kotlin plugins { id("com.android.application") id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.plugin.compose") } android { ... kotlinOptions { jvmTarget = "11" } buildFeatures { compose true } } dependencies { // ... // Stripe Android SDK implementation("com.stripe:stripe-android:23.8.0") // Include the financial connections SDK to support US bank account as a payment method implementation("com.stripe:financial-connections:23.8.0") } ``` > Details zur aktuellen SDK-Version und zu vorherigen Versionen finden Sie auf der Seite [Releases](https://github.com/stripe/stripe-android/releases) auf GitHub. Um bei Veröffentlichung eines neuen Release eine Benachrichtigung zu erhalten, [beobachten Sie Veröffentlichungen für das jeweilige Repository](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#configuring-your-watch-settings-for-an-individual-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. ```kotlin // Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys PaymentConfiguration.init(context, publishableKey = "<>") ``` ## Zahlungsmethoden aktivieren Zeigen Sie Ihre [Einstellungen für Zahlungsmethoden](https://dashboard.stripe.com/settings/payment_methods) an und aktivieren Sie die Zahlungsmethoden, die Sie unterstützen möchten. Sie müssen mindestens eine Zahlungsmethode aktiviert haben, um einen *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) zu erstellen. Standardmäßig aktiviert Stripe Karten und andere gängige Zahlungsmethoden, mit denen Sie mehr Kundinnen und Kunden erreichen können. Wir empfehlen jedoch, zusätzliche Zahlungsmethoden zu aktivieren, die für Ihr Unternehmen und Ihre Kundschaft relevant sind. Weitere Informationen zur Unterstützung von Produkten und Zahlungsmethoden finden Sie auf der Seite [Unterstützte Zahlungsmethoden](https://docs.stripe.com/payments/payment-methods/payment-method-support.md) und der [Preisseite](https://stripe.com/pricing/local-payment-methods) für Gebühren. ## Zahlungsdetails erfassen [Clientseitig] Das eingebettete Mobile Payment Element ist für die Verwendung auf der Bezahlseite Ihrer nativen mobilen App konzipiert. Das Element zeigt eine Liste mit Zahlungsmethoden an, die Sie an das Erscheinungsbild Ihrer App anpassen können. Wenn Kundinnen und Kunden auf die Zeile **Karte** tippen, wird ein Formular geöffnet, in dem sie die Details ihrer Zahlungsmethode eingeben können. Die Schaltfläche im Formular zeigt standardmäßig **Fortfahren** an und schließt das Formular, wenn darauf getippt wird, sodass Ihre Kundinnen und Kunden die Zahlung in Ihrem Bezahlvorgang abschließen können. ![Embedded Payment Element](https://b.stripecdn.com/docs-statics-srv/assets/android-embedded.1aefe2ca79ed073e350ec629a5af22d5.png) Alternativ können Sie die Schaltfläche so konfigurieren, dass die Zahlung sofort abgeschlossen wird, anstatt fortzufahren. Führen Sie dazu [diesen Schritt](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#embedded-let-customer-pay-immediately) aus, nachdem Sie der Anleitung gefolgt sind. ### Eingebettetes Payment Element initialisieren #### Jetpack Compose Initialisieren Sie eine Instanz von `EmbeddedPaymentElement` mithilfe der Funktion `rememberEmbeddedPaymentElement` mit einem `EmbeddedPaymentElement.Builder`. Übergeben Sie ein `CreateIntentWithConfirmationTokenCallback`. Lassen Sie die Implementierung vorerst leer. ```kotlin import com.stripe.android.paymentelement.EmbeddedPaymentElement import com.stripe.android.paymentelement.rememberEmbeddedPaymentElement @Composable fun CheckoutScreen() { val embeddedBuilder = remember { EmbeddedPaymentElement.Builder( createIntentCallback = { confirmationToken, -> TODO("You'll implement this in the "Confirm the payment" step") }, resultCallback = { result -> TODO("You'll implement this in the "Confirm the payment" step") }, ) } val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) } ``` #### Ansichten (klassisch) Initialisieren Sie eine Instanz von `EmbeddedPaymentElement` mithilfe der Funktion `rememberEmbeddedPaymentElement` mit einem `EmbeddedPaymentElement.Builder`. ```kotlin import com.stripe.android.paymentelement.EmbeddedPaymentElement import com.stripe.android.paymentelement.rememberEmbeddedPaymentElement @Composable fun CheckoutScreen() { val embeddedBuilder = remember { EmbeddedPaymentElement.Builder( createIntentCallback = { confirmationToken -> TODO("Completed in a later step.") }, resultCallback = { result -> TODO("Completed in a later step.") }, ) } val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) } ``` Das Embedded Mobile Payment Element wurde für die Jetpack Compose-Nutzeroberfläche entwickelt und stellt eine Methode `@Composable Content` zur Verfügung. Wenn Sie klassische Ansichten verwenden, müssen Sie das Embedded Payments Element in einen `ComposeView` verpacken. ```xml ``` ```kotlin class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.checkout_screen_layout) val composeView = findViewById(R.id.compose_view) composeView.setContent { CheckoutScreen() } } } ``` ### Eingebettetes Payment Element konfigurieren Das `Builder`-Objekt enthält Rückrufe, die für die Instanziierung von `EmbeddedPaymentElement` erforderlich sind, einschließlich des `CreateIntentCallback`. Lassen Sie die Implementierung vorerst leer. Rufen Sie nach der Instanziierung `configure` mit `EmbeddedPaymentElement.Configuration` und`PaymentSheet.IntentConfiguration` auf. Das `Configuration`-Objekt enthält allgemeine Konfigurationsoptionen für `EmbeddedPaymentElement`, die sich zwischen den Zahlungen nicht ändern. Das`IntentConfiguration`-Objekt enthält Details über die spezifische Zahlung, wie z. B. den Betrag und die Währungen. ```kotlin import com.stripe.android.paymentsheet.PaymentSheet @Composable fun CheckoutScreen() { val embeddedBuilder = .... val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) LaunchedEffect(embeddedPaymentElement) { embeddedPaymentElement.configure( intentConfiguration = PaymentSheet.IntentConfiguration(mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = 1099, currency = "USD",),// Optional intent configuration options... ), configuration = EmbeddedPaymentElement.Configuration.Builder("Powdur").build() ) } } ``` ### Ansicht „Eingebettetes Payment Element“ hinzufügen Sobald das `EmbeddedPaymentElement` erfolgreich initialisiert wurde, fügen Sie seinen `@Composable Content` in die Nutzeroberfläche Ihres Bezahlvorgangs ein. > Der Inhalt muss sich in einem scrollbaren Container befinden, da sich seine Höhe nach dem ersten Rendern ändern kann. ```kotlin @Composable fun CheckoutScreen() { val embeddedBuilder = .... val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) ..... val scrollState = rememberScrollState() Column( modifier = Modifier .fillMaxSize() .verticalScroll(scrollState) .padding(16.dp) ) { embeddedPaymentElement.Content() } } ``` An dieser Stelle können Sie Ihre App ausführen und das eingebettete Mobile Payment Element sehen. ### (Optional) Zahlungsangaben aktualisieren Wenn eine Kundin/ein Kunde die Zahlungsdetails ändert (z. B. durch Anwenden eines Rabattcodes), aktualisieren Sie die `EmbeddedPaymentElement`-Instanz. Wenn Sie die `configure`-Methode erneut verwenden, werden die neuen Werte synchronisiert und in der Nutzeroberfläche angezeigt. > Bei einigen Zahlungsmethoden, wie z. B. Google Pay, wird der Betrag in der Nutzeroberfläche angezeigt. Wenn eine Kundin/ein Kunde die Zahlung ändert und Sie das `EmbeddedPaymentElement`, zeigt die Nutzeroberfläche falsche Werte an. Wenn der Aufruf von `configure` abgeschlossen ist, werden `@Composable Content` und `paymentOption` automatisch mit den neuen Werten aktualisiert, die für den Aufruf `configure` bereitgestellt wurden. ```kotlin val intentConfiguration = PaymentSheet.IntentConfiguration( // Update the amount to reflect the price after applying the discount code mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = 999, currency = "USD", ), ) val configuration = EmbeddedPaymentElement.Configuration.Builder("Powdur") .build() LaunchedEffect(embeddedPaymentElement) { embeddedPaymentElement.configure( intentConfiguration = intentConfiguration, configuration = configuration, ) } ``` ### (Optional) Ausgewählte Zahlungsoption anzeigen Sie können Details zu den Zahlungsoptionen (z. B. die letzten 4 Ziffern, ein Kartenlogo oder Rechnungsinformationen) anzeigen, indem Sie auf die beobachtbare Eigenschaft `Flow` der `paymentOption` von Embedded Payment Element zugreifen. Wenn eine Kundin/ein Kunde eine Zahlungsmethode auswählt, die ein Formularblatt öffnet, wird die Zahlungsoption aktualisiert, nachdem sie bzw. er im Blatt auf **Weiter** geklickt hat. ```kotlin val selectedPaymentOption by embeddedPaymentElement.paymentOption.collectAsState() selectedPaymentOption?.let { paymentOption -> Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier .clickable( onClick = { }, ) .semantics { text = AnnotatedString(paymentOption.label) }, ) { Icon( painter = paymentOption.iconPainter, contentDescription = null, // decorative element modifier = Modifier.padding(horizontal = 4.dp), tint = Color.Unspecified, ) Text(text = paymentOption.label) } } ``` ### Zahlung bestätigen Wenn der Kunde/die Kundin auf die Checkout-Schaltfläche tippt, leiten Sie die Zahlung ein, indem Sie `embeddedPaymentElement.confirm()` aufrufen. Achten Sie darauf, die Nutzerinteraktion während der Bestätigung zu deaktivieren. Wenn ein Formular vorgelegt wird, ruft `EmbeddedPaymentElement` `confirm` auf, wenn die Nutzerin/der Nutzer auf **Handlungsaufforderung** klickt. Wenn die ausgewählte Zahlungsmethode keine Formularfelder aufweist, rufen Sie `confirm` auf, wenn die Nutzerin/der Nutzer unter `@Composable Content` auf **Handlungsaufforderung** klickt. ```kotlin Button( onClick = { embeddedPaymentElement.confirm() } ) { Text("Confirm payment") } ``` Implementieren Sie als Nächstes den Callback `createIntentCallback`, den Sie zuvor an `EmbeddedPaymentElement.Builder` übergeben haben, um eine Anfrage an Ihren Server zu senden. Ihr Server erstellt ein `PaymentIntent` und gibt sein Client-Geheimnis zurück, wie unter [PaymentIntent erstellen](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#submit-payment) erläutert. Wenn Sie die Anfrage erhalten, geben Sie das Ergebnis der Intent-Erstellung über `CreateIntentResult` mit dem Client-Geheimnis Ihrer Server Antwort oder einem Fehler zurück. Das `EmbeddedPaymentElement` bestätigt den PaymentIntent mit dem Client-Geheimnis oder zeigt die lokalisierte Fehlermeldung in der Nutzeroberfläche an. ```kotlin import com.stripe.android.paymentsheet.CreateIntentResult val embeddedBuilder = remember { val embeddedBuilder = EmbeddedPaymentElement.Builder( createIntentCallback = { confirmationToken ->// Make a request to your own server and receive a client secret or an error. val networkResult = ... if (networkResult.isSuccess) { CreateIntentResult.Success(networkResult.clientSecret) } else { CreateIntentResult.Failure(networkResult.exception) } }, resultCallback = { result ->when (result) { is EmbeddedPaymentElement.Result.Completed -> { // Payment completed - show a confirmation screen. } is EmbeddedPaymentElement.Result.Failed -> { // Encountered an unrecoverable error. You can display the error to the user, log it, and so on } is EmbeddedPaymentElement.Result.Canceled -> { // Customer canceled - you should probably do nothing. } } }, ) } ``` ## Optional: Ausgewählte Zahlungsoption löschen Wenn Sie Zahlungsoptionen außerhalb von `EmbeddedPaymentElement` haben, müssen Sie möglicherweise die ausgewählte Zahlungsoption löschen. Verwenden Sie dazu die `clearPaymentOption` API, um die ausgewählte Zahlungsoption zu deaktivieren. ```kotlin @Composable fun CheckoutScreen() { val embeddedPaymentElementBuilder = .... val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedPaymentElementBuilder) .... Button( onClick = embeddedPaymentElement::clearPaymentOption ) { Text("Select external payment option") } } ``` ## Optional: Mandat selbst anzeigen Um die Einhaltung gesetzlicher Vorschriften zu gewährleisten, zeigt das eingebettete Mobile Payment Element standardmäßig Mandate und Haftungsausschlüsse an. Dieser Text muss sich in der Nähe Ihrer Schaltfläche **Kaufen** befinden. Wenn Sie die Standardanzeige dieses Textes in der Ansicht deaktivieren, müssen Sie ihn selbst anzeigen. > Um die Vorschriften einzuhalten, muss Ihre Integration den Mandatstext korrekt anzeigen. Wenn Sie ihn selbst anzeigen, stellen Sie sicher, dass alle URLs korrekt gerendert werden, indem Sie den Text in ein zusammensetzbares `Text`-Objekt einfügen. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder("Merchant, Inc") .embeddedViewDisplaysMandateText(false) .build() .... val selectedPaymentOption by embeddedPaymentElement.paymentOption.collectAsState() selectedPaymentOption?.mandateText?.let { mandateText -> Text(mandateText) } ``` ## Optional: Lassen Sie den Kunden/die Kundin sofort im Formular bezahlen ![Eingebettetes Zahlungs-Element](https://b.stripecdn.com/docs-statics-srv/assets/embedded-pay-immediate.057c691220d43158ac8000de10815ed9.png) Um die Schaltfläche im Formular zur sofortigen Bestätigung der Zahlung zu konfigurieren, legen Sie `formSheetAction` für Ihr `EmbeddedPaymentElement.Configuration`-Objekt fest. Der Completion-Block wird mit dem Ergebnis der Zahlung ausgeführt, nachdem das Formular geschlossen wurde. Die eingebettete Nutzeroberfläche kann nach Abschluss der Zahlung nicht verwendet werden. Wir empfehlen daher, dass Ihre Implementierung die Nutzer/innen zu einem anderen Bildschirm weiterleitet, z. B. einem Zahlungsbeleg-Bildschirm. ```kotlin @Composable fun CheckoutScreen() { val embeddedBuilder = .... val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) LaunchedEffect(embeddedPaymentElement) { embeddedPaymentElement.configure( intentConfiguration = ...., configuration = EmbeddedPaymentElement.Configuration.Builder("Powdur") .formSheetAction(EmbeddedPaymentElement.FormSheetAction.Confirm) .build() ) } } ``` ## PaymentIntent erstellen [Serverseitig] Erstellen Sie auf Ihrem Server a *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) durch Angabe eines Betrags und einer Währung. Sie können Zahlungsmethoden über das [Dashboard](https://dashboard.stripe.com/settings/payment_methods) verwalten. Stripe handhabt die Rückgabe geeigneter Zahlungsmethoden basierend auf Faktoren wie Betrag, Währung und Zahlungsablauf der Transaktion. Um zu verhindern, dass böswillige Kundinnen und Kunden ihre eigenen Preise wählen, sollten Sie den Preis immer auf der Serverseite (einer vertrauenswürdigen Umgebung) festlegen und nicht auf dem Client. Wenn der Aufruf erfolgreich ist, geben Sie den PaymentIntent *das Client-Geheimnis* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) zurück. Wenn der Aufruf fehlschlägt, [beheben Sie den Fehler](https://docs.stripe.com/error-handling.md) und geben eine Fehlermeldung mit einer kurzen Erklärung an Ihre Kundin/Ihren Kunden zurück. > Überprüfen Sie, ob alle IntentConfiguration-Eigenschaften mit Ihrem PaymentIntent (zum Beispiel `setup_future_usage`, `amount` und `currency`) übereinstimmen. #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') post '/create-intent' do data = JSON.parse request.body.read params = { amount: 1099, currency: 'usd', automatic_payment_methods: {enabled: true}, } begin intent = client.v1.payment_intents.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` ## Ereignisse nach Zahlung verarbeiten [Serverseitig] Stripe sendet ein [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded)-Ereignis, wenn die Zahlung abgeschlossen ist. Verwenden Sie [Webhook-Tool im Dashboard](https://dashboard.stripe.com/webhooks) oder folgen Sie der [Webhook-Anleitung](https://docs.stripe.com/webhooks/quickstart.md), um diese Ereignisse zu empfangen und führen Sie Aktionen aus, wie beispielsweise das Senden einer Bestellbestätigung per E-Mail, das Protokollieren des Verkaufs in der Datenbank oder das Starten eines Versand-Workflows. Überwachen Sie diese Ereignisse, statt auf einen Callback vom Client zu warten. Auf dem Client könnten die Kund/innen das Browserfenster schließen oder die App beenden, bevor der Callback erfolgt ist. Bösartige Clients könnten dann die Antwort manipulieren. Wenn Sie Ihre Integration so einrichten, dass sie asynchrone Ereignisse überwacht, können Sie [verschiedene Arten von Zahlungsmethoden](https://stripe.com/payments/payment-methods-guide) mit einer einzelnen Integration akzeptieren. Neben der Abwicklung des `payment_intent.succeeded`-Ereignisses empfehlen wir die Abwicklung von diesen weiteren Ereignissen, wenn Sie Zahlungen mit dem Payment Element erfassen: | Ereignis | Beschreibung | Aktion | | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded) | Wird gesendet, wenn Kundinnen und Kunden eine Zahlung erfolgreich abgeschlossen haben. | Senden Sie den Kund/innen eine Auftragsbestätigung und *wickeln* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected) Sie die Bestellung ab. | | [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing) | Wird gesendet, wenn eine/e Kund/in eine Zahlung erfolgreich veranlasst hat, die Zahlung aber noch nicht abgeschlossen ist. Dieses Ereignis wird am häufigsten gesendet, wenn der Kunde/die Kundin eine Bankabbuchung veranlasst. In Zukunft folgt darauf entweder ein `payment_intent.succeeded`- oder ein `payment_intent.payment_failed`-Ereignis. | Senden Sie eine Bestellbestätigung an die Kund/innen, in der angegeben ist, dass die Zahlung noch aussteht. Bei digitalen Waren können Sie die Bestellung abwickeln, bevor Sie darauf warten, dass die Zahlung erfolgt. | | [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | Wird gesendet, wenn ein Kunde/eine Kundin einen Zahlungsversuch durchführt, die Zahlung jedoch fehlschlägt. | Wenn eine Zahlung von `processing` zu `payment_failed` übergeht, bieten Sie der Kundin/dem Kunden einen weiteren Zahlungsversuch an. | ## Integration testen #### Karten | Kartennummer | Szenario | So führen Sie den Test durch | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | | 4242424242424242 | Die Kartenzahlung ist erfolgreich und es ist keine Authentifizierung erforderlich. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 4000002500003155 | Für die Kartenzahlung ist eine *Authentifizierung* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase) erforderlich. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 4000000000009995 | Die Karte wird mit einem Ablehnungscode wie `insufficient_funds` abgelehnt. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 6205500000000000004 | Die UnionPay-Karte hat eine variable Länge von 13 bis 19 Ziffern. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | #### Bankumleitungen | Zahlungsmethode | Szenario | So führen Sie den Test durch | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Bancontact, iDEAL | Ihr/e Kund/in konnte sich auf der iDEAL-Weiterleitungsseite für eine auf Weiterleitung basierende Zahlungsmethode mit sofortiger Benachrichtigung nicht authentifizieren. | Wählen Sie eine beliebige, auf Weiterleitung basierende Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung fehlgeschlagen**. | | Pay by Bank | Ihr Kunde/Ihre Kundin zahlt erfolgreich mit einer auf Weiterleitung basierenden Zahlungsmethode mit [verzögerter Benachrichtigung](https://docs.stripe.com/payments/payment-methods.md#payment-notification). | Wählen Sie die Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung abschließen**. | | Pay by Bank | Ihr/e Kund/in konnte sich auf der iDEAL-Weiterleitungsseite für eine auf Weiterleitung basierende Zahlungsmethode mit verzögerter Benachrichtigung nicht authentifizieren. | Wählen Sie die Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung fehlgeschlagen**. | | BLIK | BLIK-Zahlungen können aus verschiedenen Gründen fehlschlagen. Es gibt sofortige Fehler (der Code ist abgelaufen oder ungültig), verzögerte Fehler (die Bank lehnt ab) oder Zeitüberschreitungen (der/die Kund/in hat nicht rechtzeitig reagiert). | Verwenden Sie E-Mail-Muster, um [die verschiedenen Fehler zu simulieren](https://docs.stripe.com/payments/blik/accept-a-payment.md#simulate-failures) | #### Banklastschriften | Zahlungsmethode | Szenario | So führen Sie den Test durch | | ---------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | SEPA-Lastschrift | Ihr/e Kund/in zahlt erfolgreich mit dem SEPA-Lastschriftverfahren. | Füllen Sie das Formular mit der Kontonummer `AT321904300235473204` aus. Die bestätigte PaymentIntent geht zunächst in den Status „wird verarbeitet“ und dann drei Minuten später in den Status „erfolgreich“ über. | | SEPA-Lastschrift | Der Status der PaymentIntent Ihres/Ihrer Kund/in wechselt von `processing` zu `requires_payment_method`. | Füllen Sie das Formular mit der Kontonummer `AT861904300235473202` aus. | Hier finden Sie weitere Informationen zum [Testen](https://docs.stripe.com/testing.md) Ihrer Integration. ## Optional: Karten speichern [Serverseitig] [Clientseitig] `EmbeddedPaymentElement` kann es Kundinnen und Kunden ermöglichen, ihre Karte zu speichern, und die gespeicherten Karten des Kunden/der Kundin in die verfügbaren Zahlungsmethoden aufnehmen. Der Kunde/Die Kundin muss über ein zugehöriges, vom Kunden/von der Kundin konfiguriertes [Account](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer)-Objekt oder [Customer](https://docs.stripe.com/api/customers/create.md)-Objekt auf Ihrem Server verfügen. Um ein Kontrollkästchen zu aktivieren, mit dem der Kunde/die Kundin seine/ihre Karte speichern kann, erstellen Sie eine [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) mit `enabled` für `payment_method_save`. #### Accounts v2 ```javascript // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. const stripe = require("stripe")("<>"); const express = require('express'); const app = express(); app.set('trust proxy', true); app.use(express.json()); app.post('/payment-sheet', async (req, res) => { // Use an existing Account ID if this is a returning customer. const customer_account = await stripe.v2.core.accounts.create(); const customerSession = await stripe.customerSessions.create({ customer_account: customer_account.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer_account: customer_account.id, }); }); ``` Als Nächstes konfigurieren Sie `EmbeddedPaymentElement` mit der ID des Kunden/der Kundin und dem Client-Geheimnis der `CustomerSession`. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Powdur") .customer( PaymentSheet.CustomerConfiguration.createWithCustomerSession( id = customerAccountId, clientSecret = customerSessionClientSecret, ) ) .build() embeddedPaymentElement.configure( intentConfiguration = // ... , configuration = configuration, ) ``` #### Customers v1 ```javascript // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. const stripe = require("stripe")("<>"); const express = require('express'); const app = express(); app.set('trust proxy', true); app.use(express.json()); app.post('/payment-sheet', async (req, res) => { // Use an existing Customer ID if this is a returning customer. const customer = await stripe.customers.create(); const customerSession = await stripe.customerSessions.create({ customer: customer.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer: customer.id, }); }); ``` Als Nächstes konfigurieren Sie `EmbeddedPaymentElement` mit der ID des Kunden/der Kundin und dem Client-Geheimnis der `CustomerSession`. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Powdur") .customer( PaymentSheet.CustomerConfiguration.createWithCustomerSession( id = customerId, clientSecret = customerSessionClientSecret, ) ) .build() embeddedPaymentElement.configure( intentConfiguration = // ... , configuration = configuration, ) ``` ## Optional: Zahlungsmethoden mit Verzögerung zulassen [Clientseitig] *Zahlungsmethoden mit Verzögerung* (A payment method that can't immediately return payment status when a customer attempts a transaction (for example, ACH debits). Businesses commonly hold an order in a pending state until payment is successful with these payment methods) garantieren nicht, dass Sie am Ende des Bezahlvorgangs Gelder von Ihrem Kunden/Ihrer Kundin erhalten, da einerseits die Abwicklung eine gewisse Zeit in Anspruch nimmt (z. B. bei US-Bankkonten, SEPA-Lastschrift, iDEAL, Bancontact und Sofort) oder weil Kundinnen und Kunden aktiv werden müssen, um den Vorgang abzuschließen (z. B. OXXO, Konbini und Boleto). Standardmäßig zeigt `EmbeddedPaymentElement` keine Zahlungsmethoden mit Verzögerung an, selbst wenn Sie diese akzeptieren. Um die von Ihnen aktivierten Zahlungsmethoden mit Verzögerung anzuzeigen, legen Sie `allowsDelayedPaymentMethods` in Ihrer `EmbeddedPaymentElement.Configuration` auf „true“ fest. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Powdur") .allowsDelayedPaymentMethods(true) .build() ``` Wenn Kundinnen/Kunden erfolgreich eine Zahlungsmethode mit Verzögerung in einem `EmbeddedPaymentElement` verwenden, lautet das zurückgegebene Zahlungsergebnis `EmbeddedPaymentElement.Result.Completed`. ## Optional: Google Pay aktivieren > Wenn Ihr Checkout-Bildschirm eine spezielle **Google Pay**-Schaltfläche enthält, befolgen Sie den [Google Pay-Leitfaden](https://docs.stripe.com/google-pay.md?platform=android). Sie können das eingebettete Payment Element verwenden, um andere Arten von Zahlungsmethoden zu verarbeiten. ### Integration einrichten Um Google Pay zu verwenden, aktivieren Sie zuerst die Google Pay API, indem Sie dem Tag `` Ihrer Datei **AndroidManifest.xml** Folgendes hinzufügen: ```xml ... ``` Weitere Informationen finden Sie in der [Google Pay API](https://developers.google.com/pay/api/android/guides/setup) für Android. ### Google Pay hinzufügen Um Google Pay zu Ihrer Integration hinzuzufügen, übergeben Sie [PaymentSheet.GooglePayConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-google-pay-configuration/index.html) mit Ihrer Google Pay-Umgebung (Produktion oder Test) sowie den [Ländercode Ihres Unternehmens](https://dashboard.stripe.com/settings/account) bei der Initialisierung von `EmbeddedPaymentElement.Configuration`. ```kotlin val googlePayConfiguration = PaymentSheet.GooglePayConfiguration( environment = PaymentSheet.GooglePayConfiguration.Environment.Test, countryCode = "US", currencyCode = "USD" // Required for Setup Intents, optional for Payment Intents ) val configuration = EmbeddedPaymentElement.Configuration.Builder("Merchant, Inc.") .googlePay(googlePayConfiguration) .build() ``` ### Google Pay testen Google bietet Ihnen die Möglichkeit, Zahlungen über seine [Testkartensuite](https://developers.google.com/pay/api/android/guides/resources/test-card-suite) zu testen. Sie können Stripe-[Testkarten](https://docs.stripe.com/testing.md) mit der Testsuite verwenden. In einem Land, in dem Google Pay unterstützt wird, müssen Sie Google Pay mit einem physischen Android-Gerät anstelle eines simulierten Geräts testen. Melden Sie sich mit einer echten in Google Wallet gespeicherten Karte bei einem Google-Konto auf Ihrem Testgerät an. ## Optional: Kartenscannen aktivieren Um den Support für das Scannen von Karten zu aktivieren, [fordern Sie Produktionszugriff](https://developers.google.com/pay/api/android/guides/test-and-deploy/request-prod-access) auf die Google Pay API über die [Google Pay & Wallet Console](https://pay.google.com/business/console?utm_source=devsite&utm_medium=devsite&utm_campaign=devsite) an. - Wenn Sie Google Pay aktiviert haben, ist die Funktion zum Scannen von Karten auf berechtigten Geräten automatisch auf unserer Nutzeroberfläche verfügbar. Weitere Informationen zu berechtigten Geräten finden Sie unter den [Einschränkungen der Google Pay API](https://developers.google.com/pay/payment-card-recognition/debit-credit-card-recognition) - **Wichtig:** Die Funktion zum Scannen von Karten wird nur in Builds angezeigt, die mit demselben in der [Google Pay & Wallet Console](https://pay.google.com/business/console) registrierten Signaturschlüssel signiert sind. Test- oder Fehlerbehebungs-Builds mit verschiedenen Signaturschlüsseln (z. B. Builds, die über Firebase App Tester verteilt werden) zeigen die Option **Karte scannen** an. Um Karten in Pre-Release-Builds zu testen, müssen Sie entweder: - oder Ihre Test-Builds mit Ihrem Produktions-Signaturschlüssel signieren - Fingerabdruck Ihres Test-Signaturschlüssels zur Google Pay and Wallet-Konsole hinzufügen Wenn Ihre App Google Pay nicht unterstützt, können Sie den Stripe-Kartenscanner verwenden. > Der Stripe-Kartenscanner befindet sich in der öffentlichen Vorschau. Um den Support für das Scannen von Karten zu aktivieren, fügen Sie dem `dependencies`-Block Ihrer Datei [app/build.gradle](https://developer.android.com/studio/build/dependencies) `stripecardscan` hinzu: #### Groovy ```groovy implementation 'com.stripe:stripecardscan:23.8.0' ``` ## Optional: Passen Sie das Tabellenblatt an Alle Anpassungen werden mithilfe des `EmbeddedPaymentElement.Configuration`-Objekts konfiguriert. ### Erscheinungsbild Passen Sie mit der [Appearance API](https://docs.stripe.com/elements/appearance-api/embedded-mobile.md?platform=android) Farben, Schriftarten und mehr an das Erscheinungsbild Ihrer App an. ### Adressen der Kund/innen erfassen Erfassen Sie Versand- und Rechnungsadressen von Ihren Kundinnen/Kunden mithilfe des [Address Element](https://docs.stripe.com/elements/address-element.md?platform=android). ### Den angezeigten Unternehmensnamen anpassen Geben Sie einen kundenorientierten Unternehmensnamen an, indem Sie `merchantDisplayName` festlegen. Wenn Sie keinen Namen angeben, ist der Standardwert der Name Ihrer App. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Merchant, Inc.") .build() ``` ### Standardabrechnungsdaten angeben Um Standardwerte für Abrechnungsdaten festzulegen, die in `EmbeddedPaymentElement` erfasst wurden, konfigurieren Sie die Eigenschaft `defaultBillingDetails`. Das `EmbeddedPaymentElement` füllt seine Felder vorab mit den von Ihnen angegebenen Werten aus. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Merchant, Inc.") .defaultBillingDetails( PaymentSheet.BillingDetails( address = PaymentSheet.Address( country = "US", ), email = "foo@bar.com" ) ) .build() ``` ### Erfassung von Abrechnungsdetails konfigurieren `BillingDetailsCollectionConfiguration` verwenden, um anzugeben, wie Sie Rechnungsdetails im `EmbeddedPaymentElement` erfassen möchten. Sie können den Namen, die E-Mail-Adresse, die Telefonnummer und die Adresse Ihrer Kundinnen und Kunden erfassen. Wenn Sie dem PaymentMethod-Objekt Standard-Abrechnungsdetails zuordnen möchten, auch wenn diese Felder nicht auf der Nutzeroberfläche erfasst werden, legen Sie `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` auf `true` fest. ```kotlin import com.stripe.android.paymentsheet.PaymentSheet.BillingDetailsCollectionConfiguration val billingDetails = PaymentSheet.BillingDetails( email = "foo@bar.com" ) val billingDetailsCollectionConfiguration = BillingDetailsCollectionConfiguration( attachDefaultsToPaymentMethod = true, name = BillingDetailsCollectionConfiguration.CollectionMode.Always, email = BillingDetailsCollectionConfiguration.CollectionMode.Never, address = BillingDetailsCollectionConfiguration.AddressCollectionMode.Full, ) val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Merchant, Inc.") .defaultBillingDetails(billingDetails) .billingDetailsCollectionConfiguration(billingDetailsCollectionConfiguration) .build() ``` > Wenden Sie sich an Ihren Rechtsbeistand bezüglich der Gesetze, die für das Erfassen von Informationen gelten. Erfassen Sie Telefonnummern nur, wenn Sie sie für die Transaktion benötigen. ## Optional: Aktiveren der Funktion zur erneuten Erfassung der Prüfziffer/CVC bei Bestätigung Um die Prüfziffer einer gespeicherten Karte während der PaymentIntent-Bestätigung erneut einzuziehen, muss Ihre Integration Zahlungsdaten einziehen, bevor ein PaymentIntent erstellt wird. ### Intent-Konfiguration aktualisieren `PaymentSheet.IntentConfiguration` akzeptiert einen optionalen Parameter, mit dem gesteuert wird, wann die Prüfziffer/CVC für eine gespeicherte Karte erneut erfasst werden soll. ```kotlin val intentConfig = PaymentSheet.IntentConfiguration( mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = 1099, currency = "usd", ),requireCvcRecollection = true, ) ``` ### Parameter der Intent-Erstellung aktualisieren Um die Prüfziffer/CVC bei der Zahlungsbestätigung erneut zu erfassen, fügen Sie bei der Erstellung des PaymentIntent die beiden Parameter `customerId` und `require_cvc_recollection` ein. #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/create-intent' do data = JSON.parse request.body.read params = { amount: 1099, currency: 'usd', automatic_payment_methods: {enabled: true},customer: customer.id, payment_method_options: { card: {require_cvc_recollection: true} }, } begin intent = client.v1.payment_intents.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` # Zahlungsmethode erfassen und speichern > This is a Zahlungsmethode erfassen und speichern for when platform is android and type is setup. View the full page at https://docs.stripe.com/payments/mobile/accept-payment-embedded?platform=android&type=setup. Mit einem SetupIntent-Ablauf können Sie Details zu Zahlungsmethoden erfassen und für zukünftige Zahlungen speichern, ohne eine Zahlung abzuwickeln. Bei dieser Integration erstellen Sie einen benutzerdefinierten Vorgang, in dem Sie das Zahlungs-Element rendern, den *SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) erstellen und das Speichern der Zahlungsmethode in Ihrer App bestätigen. ## Stripe einrichten [Serverseitig] [Clientseitig] Zunächst benötigen Sie ein Stripe-Konto. [Registrieren Sie sich jetzt](https://dashboard.stripe.com/register). ### Serverseitig Für diese Integration sind Endpoints auf Ihrem Server erforderlich, die mit der Stripe-API kommunizieren können. Nutzen Sie diese offiziellen Bibliotheken für den Zugriff auf die Stripe-API von Ihrem Server aus: #### 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' ``` ### Client-seitig Das [Stripe Android SDK](https://github.com/stripe/stripe-android) ist Open Source und [vollständig dokumentiert](https://stripe.dev/stripe-android/). Um das SDK zu installieren, fügen Sie `stripe-android` in den Block `dependencies` Ihrer [app/build.gradle](https://developer.android.com/studio/build/dependencies)-Datei ein: #### Kotlin ```kotlin plugins { id("com.android.application") id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.plugin.compose") } android { ... kotlinOptions { jvmTarget = "11" } buildFeatures { compose true } } dependencies { // ... // Stripe Android SDK implementation("com.stripe:stripe-android:23.8.0") // Include the financial connections SDK to support US bank account as a payment method implementation("com.stripe:financial-connections:23.8.0") } ``` > Details zur aktuellen SDK-Version und zu vorherigen Versionen finden Sie auf der Seite [Releases](https://github.com/stripe/stripe-android/releases) auf GitHub. Um bei Veröffentlichung eines neuen Release eine Benachrichtigung zu erhalten, [beobachten Sie Veröffentlichungen für das jeweilige Repository](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#configuring-your-watch-settings-for-an-individual-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. ```kotlin // Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys PaymentConfiguration.init(context, publishableKey = "<>") ``` ## Zahlungsmethoden aktivieren Zeigen Sie Ihre [Einstellungen für Zahlungsmethoden](https://dashboard.stripe.com/settings/payment_methods) an und aktivieren Sie die Zahlungsmethoden, die Sie unterstützen möchten. Sie müssen mindestens eine Zahlungsmethode aktiviert haben, um einen *SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) zu erstellen. Standardmäßig aktiviert Stripe Karten und andere gängige Zahlungsmethoden, mit denen Sie mehr Kundinnen und Kunden erreichen können. Wir empfehlen jedoch, zusätzliche Zahlungsmethoden zu aktivieren, die für Ihr Unternehmen und Ihre Kundschaft relevant sind. Weitere Informationen zur Unterstützung von Produkten und Zahlungsmethoden finden Sie auf der Seite [Unterstützte Zahlungsmethoden](https://docs.stripe.com/payments/payment-methods/payment-method-support.md) und der [Preisseite](https://stripe.com/pricing/local-payment-methods) für Gebühren. ## Kundin/Kunden erstellen [Serverseitig] Um eine Zahlungsmethode für zukünftige Zahlungen einzurichten, müssen Sie sie einem Objekt zuordnen, das Ihre Kundin/Ihre Kundin darstellt. Wenn Ihre Kundin/Kundin ein Konto erstellt oder die erste Transaktion mit Ihrem Unternehmen durchgeführt hat, erstellen Sie entweder ein kundenseitig konfiguriertes [Account](https://docs.stripe.com/api/v2/core/accounts/create.md)-Objekt mit der Accounts v2 API oder ein [Customer](https://docs.stripe.com/api/customers/create.md)-Objekt mit der Customers API. > #### Verwenden Sie die Accounts v2 API zum Darstellen von Kundinnen und Kunden > > Die Accounts v2 API ist allgemein für Connect-Nutzer/innen verfügbar und für andere Stripe-Nutzer/innen in der öffentlichen Vorschau. Wenn an der Accounts v2 Vorschau teilnehmen, müssen Sie eine [Vorschauversion](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) in Ihrem Code angeben. > > Um Zugriff auf die Accounts v2 Vorschau anzufordern, {% collect-email modal=true modal_link_text=“sign up.” list=“payin-payout-reuse-waitlist@stripe.com” send_direct_email=true intro_text=“Sind Sie am frühzeitigen Zugang zur Vorschau der Accounts v2 API interessiert?" body_text=“Wir sind gerade dabei, die Vorschau von Accounts v2 bereitzustellen. Um Zugang zu beantragen, geben Sie unten Ihre E-Mail-Adresse ein.” form_cta_text=“Registrieren” success_text=“Danke! Wir melden uns bald.” show_email_confirmation=wahr /%} > > Für die meisten Anwendungsfälle empfehlen wir, [Ihre Kundinnen und Kunden als vom Kunden bzw. von der Kundin konfigurierte Account-Objekte abzubilden](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md), anstatt [Customer](https://docs.stripe.com/api/customers.md)-Objekte zu verwenden. ```curl curl -X POST https://api.stripe.com/v1/customers \ -u "<>:" ``` ## Zahlungsdetails erfassen [Clientseitig] Das eingebettete Mobile Payment Element ist für die Verwendung auf der Bezahlseite Ihrer nativen mobilen App konzipiert. Das Element zeigt eine Liste mit Zahlungsmethoden an, die Sie an das Erscheinungsbild Ihrer App anpassen können. Wenn Kundinnen und Kunden auf die Zeile **Karte** tippen, wird ein Formular geöffnet, in dem sie die Details ihrer Zahlungsmethode eingeben können. Die Schaltfläche im Formular zeigt standardmäßig **Fortfahren** an und beendet das Blatt, wenn darauf getippt wird. Dadurch können Ihre Kundinnen und Kunden die Einrichtung in Ihrem Bezahlvorgang abschließen. ![Embedded Payment Element](https://b.stripecdn.com/docs-statics-srv/assets/android-embedded.1aefe2ca79ed073e350ec629a5af22d5.png) Sie können die Schaltfläche so konfigurieren, dass die Einrichtung sofort abgeschlossen wird, anstatt fortzufahren. Führen Sie dazu [diesen Schritt](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#embedded-let-customer-pay-immediately) aus, nachdem Sie der Anleitung gefolgt sind. ### Eingebettetes Payment Element initialisieren #### Jetpack Compose Initialisieren Sie eine Instanz von `EmbeddedPaymentElement` mithilfe der Funktion `rememberEmbeddedPaymentElement` mit einem `EmbeddedPaymentElement.Builder`. Übergeben Sie ein `CreateIntentWithConfirmationTokenCallback`. Lassen Sie die Implementierung vorerst leer. ```kotlin import com.stripe.android.paymentelement.EmbeddedPaymentElement import com.stripe.android.paymentelement.rememberEmbeddedPaymentElement @Composable fun CheckoutScreen() { val embeddedBuilder = remember { EmbeddedPaymentElement.Builder( createIntentCallback = { confirmationToken, -> TODO("You'll implement this in the "Confirm the payment" step") }, resultCallback = { result -> TODO("You'll implement this in the "Confirm the payment" step") }, ) } val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) } ``` #### Ansichten (klassisch) Initialisieren Sie eine Instanz von `EmbeddedPaymentElement` mithilfe der Funktion `rememberEmbeddedPaymentElement` mit einem `EmbeddedPaymentElement.Builder`. ```kotlin import com.stripe.android.paymentelement.EmbeddedPaymentElement import com.stripe.android.paymentelement.rememberEmbeddedPaymentElement @Composable fun CheckoutScreen() { val embeddedBuilder = remember { EmbeddedPaymentElement.Builder( createIntentCallback = { confirmationToken -> TODO("Completed in a later step.") }, resultCallback = { result -> TODO("Completed in a later step.") }, ) } val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) } ``` Das Embedded Mobile Payment Element wurde für die Jetpack Compose-Nutzeroberfläche entwickelt und stellt eine Methode `@Composable Content` zur Verfügung. Wenn Sie klassische Ansichten verwenden, müssen Sie das Embedded Payments Element in einen `ComposeView` verpacken. ```xml ``` ```kotlin class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.checkout_screen_layout) val composeView = findViewById(R.id.compose_view) composeView.setContent { CheckoutScreen() } } } ``` ### Eingebettetes Payment Element konfigurieren Das `Builder`-Objekt enthält Rückrufe, die für die Instanziierung von `EmbeddedPaymentElement` erforderlich sind, einschließlich des `CreateIntentCallback`. Lassen Sie die Implementierung vorerst leer. Rufen Sie nach der Instanziierung `configure` mit `EmbeddedPaymentElement.Configuration` und`PaymentSheet.IntentConfiguration` auf. Das `Configuration`-Objekt enthält allgemeine Konfigurationsoptionen für `EmbeddedPaymentElement`, die sich zwischen den Zahlungen nicht ändern. Das`IntentConfiguration`-Objekt enthält Details über die spezifische Zahlung, wie z. B. den Betrag und die Währungen. ```kotlin import com.stripe.android.paymentsheet.PaymentSheet @Composable fun CheckoutScreen() { val embeddedBuilder = .... val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) LaunchedEffect(embeddedPaymentElement) { embeddedPaymentElement.configure( intentConfiguration = PaymentSheet.IntentConfiguration(mode = PaymentSheet.IntentConfiguration.Mode.Setup( currency = "USD", ),// Optional intent configuration options... ), configuration = EmbeddedPaymentElement.Configuration.Builder("Powdur").build() ) } } ``` ### Ansicht „Eingebettetes Payment Element“ hinzufügen Sobald das `EmbeddedPaymentElement` erfolgreich initialisiert wurde, fügen Sie seinen `@Composable Content` in die Nutzeroberfläche Ihres Bezahlvorgangs ein. > Der Inhalt muss sich in einem scrollbaren Container befinden, da sich seine Höhe nach dem ersten Rendern ändern kann. ```kotlin @Composable fun CheckoutScreen() { val embeddedBuilder = .... val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) ..... val scrollState = rememberScrollState() Column( modifier = Modifier .fillMaxSize() .verticalScroll(scrollState) .padding(16.dp) ) { embeddedPaymentElement.Content() } } ``` An dieser Stelle können Sie Ihre App ausführen und das eingebettete Mobile Payment Element sehen. ### (Optional) Zahlungsangaben aktualisieren Wenn eine Kundin/ein Kunde die Zahlungsdetails ändert (z. B. durch Anwenden eines Rabattcodes), aktualisieren Sie die `EmbeddedPaymentElement`-Instanz. Wenn Sie die `configure`-Methode erneut verwenden, werden die neuen Werte synchronisiert und in der Nutzeroberfläche angezeigt. > Bei einigen Zahlungsmethoden, wie z. B. Google Pay, wird der Betrag in der Nutzeroberfläche angezeigt. Wenn eine Kundin/ein Kunde die Zahlung ändert und Sie das `EmbeddedPaymentElement`, zeigt die Nutzeroberfläche falsche Werte an. Wenn der Aufruf von `configure` abgeschlossen ist, werden `@Composable Content` und `paymentOption` automatisch mit den neuen Werten aktualisiert, die für den Aufruf `configure` bereitgestellt wurden. ```kotlin val intentConfiguration = PaymentSheet.IntentConfiguration( // Change paymentMethodTypes to customize the payment methods you want to accept mode = PaymentSheet.IntentConfiguration.Mode.Setup( currency = "USD", ), paymentMethodTypes = listOf("card") ) val configuration = EmbeddedPaymentElement.Configuration.Builder("Powdur") .build() LaunchedEffect(embeddedPaymentElement) { embeddedPaymentElement.configure( intentConfiguration = intentConfiguration, configuration = configuration, ) } ``` ### (Optional) Ausgewählte Zahlungsoption anzeigen Sie können Details zu den Zahlungsoptionen (z. B. die letzten 4 Ziffern, ein Kartenlogo oder Rechnungsinformationen) anzeigen, indem Sie auf die beobachtbare Eigenschaft `Flow` der `paymentOption` von Embedded Payment Element zugreifen. Wenn eine Kundin/ein Kunde eine Zahlungsmethode auswählt, die ein Formularblatt öffnet, wird die Zahlungsoption aktualisiert, nachdem sie bzw. er im Blatt auf **Weiter** geklickt hat. ```kotlin val selectedPaymentOption by embeddedPaymentElement.paymentOption.collectAsState() selectedPaymentOption?.let { paymentOption -> Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier .clickable( onClick = { }, ) .semantics { text = AnnotatedString(paymentOption.label) }, ) { Icon( painter = paymentOption.iconPainter, contentDescription = null, // decorative element modifier = Modifier.padding(horizontal = 4.dp), tint = Color.Unspecified, ) Text(text = paymentOption.label) } } ``` ### Einrichtung bestätigen Wenn der/die Kund/in auf die Checkout-Schaltfläche tippt, bestätigen Sie den SetupIntent, indem Sie `embeddedPaymentElement.confirm()` aufrufen. Achten Sie darauf, die Nutzerinteraktion während der Bestätigung zu deaktivieren. Wenn ein Formular vorgelegt wird, ruft `EmbeddedPaymentElement` `confirm` auf, wenn die Nutzerin/der Nutzer auf **Handlungsaufforderung** klickt. Wenn die ausgewählte Zahlungsmethode keine Formularfelder aufweist, rufen Sie `confirm` auf, wenn die Nutzerin/der Nutzer unter `@Composable Content` auf **Handlungsaufforderung** klickt. ```kotlin Button( onClick = { embeddedPaymentElement.confirm() } ) { Text("Confirm payment") } ``` Implementieren Sie als Nächstes den Rückruf `createIntentCallback`, den Sie zuvor an `EmbeddedPaymentElement.Builder` übergeben haben, um eine Anfrage an Ihren Server zu senden. Der Server erstellt einen SetupIntent und gibt sein Client-Geheimnis zurück, das im Schritt [Erstellen eines SetupIntent](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#submit-setup) erstellt wird. Wenn Sie die Anfrage erhalten, geben Sie das Ergebnis der Intent-Erstellung über `CreateIntentResult` mit dem Client-Geheimnis Ihrer Server Antwort oder einem Fehler zurück. Das `EmbeddedPaymentElement` bestätigt den SetupIntent mit dem Client-Geheimnis oder zeigt die lokalisierte Fehlermeldung in der Nutzeroberfläche an. ```kotlin import com.stripe.android.paymentsheet.CreateIntentResult val embeddedBuilder = remember { val embeddedBuilder = EmbeddedPaymentElement.Builder( createIntentCallback = { confirmationToken ->// Make a request to your own server and receive a client secret or an error. val networkResult = ... if (networkResult.isSuccess) { CreateIntentResult.Success(networkResult.clientSecret) } else { CreateIntentResult.Failure(networkResult.exception) } }, resultCallback = { result ->when (result) { is EmbeddedPaymentElement.Result.Completed -> { // Payment completed - show a confirmation screen. } is EmbeddedPaymentElement.Result.Failed -> { // Encountered an unrecoverable error. You can display the error to the user, log it, and so on } is EmbeddedPaymentElement.Result.Canceled -> { // Customer canceled - you should probably do nothing. } } }, ) } ``` ## Optional: Ausgewählte Zahlungsoption löschen Wenn Sie Zahlungsoptionen außerhalb von `EmbeddedPaymentElement` haben, müssen Sie möglicherweise die ausgewählte Zahlungsoption löschen. Verwenden Sie dazu die `clearPaymentOption` API, um die ausgewählte Zahlungsoption zu deaktivieren. ```kotlin @Composable fun CheckoutScreen() { val embeddedPaymentElementBuilder = .... val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedPaymentElementBuilder) .... Button( onClick = embeddedPaymentElement::clearPaymentOption ) { Text("Select external payment option") } } ``` ## Optional: Mandat selbst anzeigen Um die Einhaltung gesetzlicher Vorschriften zu gewährleisten, zeigt das eingebettete Mobile Payment Element standardmäßig Mandate und Haftungsausschlüsse an. Dieser Text muss sich in der Nähe Ihrer Schaltfläche **Kaufen** befinden. Wenn Sie die Standardanzeige dieses Textes in der Ansicht deaktivieren, müssen Sie ihn selbst anzeigen. > Um die Vorschriften einzuhalten, muss Ihre Integration den Mandatstext korrekt anzeigen. Wenn Sie ihn selbst anzeigen, stellen Sie sicher, dass alle URLs korrekt gerendert werden, indem Sie den Text in ein zusammensetzbares `Text`-Objekt einfügen. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder("Merchant, Inc") .embeddedViewDisplaysMandateText(false) .build() .... val selectedPaymentOption by embeddedPaymentElement.paymentOption.collectAsState() selectedPaymentOption?.mandateText?.let { mandateText -> Text(mandateText) } ``` ## Optional: Lassen Sie die/den Kunden/Kundin die Einrichtung sofort auf dem Blatt bestätigen Um die Schaltfläche im Formular zur sofortigen Bestätigung der Einrichtung zu konfigurieren, legen Sie `formSheetAction` für Ihr `EmbeddedPaymentElement.Configuration`-Objekt fest. Der Completion-Block wird mit dem Ergebnis der Einrichtung ausgeführt, nachdem das Formular geschlossen wurde. Die eingebettete Nutzeroberfläche kann nach Abschluss der Einrichtung nicht verwendet werden. Wir empfehlen daher, dass Ihre Implementierung die Nutzer/innen zu einem anderen Bildschirm weiterleitet, z. B. einem Zahlungsbeleg-Bildschirm. ```kotlin @Composable fun CheckoutScreen() { val embeddedBuilder = .... val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) LaunchedEffect(embeddedPaymentElement) { embeddedPaymentElement.configure( intentConfiguration = ...., configuration = EmbeddedPaymentElement.Configuration.Builder("Powdur") .formSheetAction(EmbeddedPaymentElement.FormSheetAction.Confirm) .build() ) } } ``` ## SetupIntent erstellen [Serverseitig] Erstellen Sie einen *SetupIntent* (The Setup Intents API lets you build dynamic flows for collecting payment method details for future payments. It tracks the lifecycle of a payment setup flow and can trigger additional authentication steps if required by law or by the payment method) auf Ihrem Server. Zahlungsmethoden können Sie über das [Dashboard](https://dashboard.stripe.com/settings/payment_methods) verwalten. Stripe wertet Einschränkungen der Zahlungsmethode und andere Parameter aus, um die Liste der unterstützten Zahlungsmethoden zu ermitteln. Wenn der Aufruf erfolgreich ist, geben Sie den SetupIntent *das Client-Geheimnis* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) zurück. Wenn der Aufruf fehlschlägt, [beheben Sie den Fehler](https://docs.stripe.com/error-handling.md) und geben eine Fehlermeldung mit einer kurzen Erklärung an Ihre Kundin/Ihren Kunden zurück. > Überprüfen Sie, ob alle IntentConfiguration-Eigenschaften mit Ihrem SetupIntent (zum Beispiel [Nutzung](https://docs.stripe.com/api/setup_intents/object.md#setup_intent_object-usage)) übereinstimmen. #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') post '/create-intent' do data = JSON.parse request.body.read params = { customer: ..., # The Customer ID you previously created automatic_payment_methods: {enabled: true}, } begin intent = client.v1.setup_intents.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` ## Die gespeicherte Zahlungsmethode später belasten [Serverseitig] > `bancontact` und `ideal` sind standardmäßig einmalige Zahlungsmethoden. Wenn sie für die künftige Verwendung eingerichtet werden, erzeugen sie eine wiederverwendbare Art der Zahlungsmethode `sepa_debit`, sodass Sie `sepa_debit` verwenden müssen, um gespeicherte Zahlungsmethoden abzufragen. > #### Compliance > > Sie sind für die Einhaltung aller geltenden Gesetze, Vorschriften und Netzwerkregeln verantwortlich, wenn Sie die Zahlungsdaten von Kundinnen und Kunden speichern. Wenn Sie Ihren Endkundinnen und Endkunden zuvor genutzte Zahlungsmethoden für zukünftige Einkäufe anzeigen, dürfen Sie nur Zahlungsmethoden auflisten, für die Sie bereits eine kundenseitige Zustimmung eingeholt haben, dank der Sie die Details der Zahlungsmethode für diese spezifische zukünftige Verwendung speichern können. Verwenden Sie den Parameter [allow_redisplay](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-allow_redisplay), um zwischen Zahlungsmethoden zu unterscheiden, die mit Kundinnen und Kunden verknüpft sind und Ihren Endkundinnen und Endkunden als gespeicherte Zahlungsmethode für zukünftige Einkäufe angezeigt werden können oder nicht. Um eine Zahlungsmethode zum Belasten zu finden, listen Sie die Zahlungsmethoden auf, die mit Ihrer Kundin/Ihrem Kunden verknüpft sind. In diesem Beispiel sind Karten aufgeführt, Sie können jedoch jeden unterstützten [Typ](https://docs.stripe.com/api/payment_methods/object.md#payment_method_object-type) auflisten. > #### Verwenden Sie die Accounts v2 API zum Darstellen von Kundinnen und Kunden > > Die Accounts v2 API ist allgemein für Connect-Nutzer/innen verfügbar und für andere Stripe-Nutzer/innen in der öffentlichen Vorschau. Wenn an der Accounts v2 Vorschau teilnehmen, müssen Sie eine [Vorschauversion](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) in Ihrem Code angeben. > > Um Zugriff auf die Accounts v2 Vorschau anzufordern, {% collect-email modal=true modal_link_text=“sign up.” list=“payin-payout-reuse-waitlist@stripe.com” send_direct_email=true intro_text=“Sind Sie am frühzeitigen Zugang zur Vorschau der Accounts v2 API interessiert?" body_text=“Wir sind gerade dabei, die Vorschau von Accounts v2 bereitzustellen. Um Zugang zu beantragen, geben Sie unten Ihre E-Mail-Adresse ein.” form_cta_text=“Registrieren” success_text=“Danke! Wir melden uns bald.” show_email_confirmation=wahr /%} > > Für die meisten Anwendungsfälle empfehlen wir, [Ihre Kundinnen und Kunden als vom Kunden bzw. von der Kundin konfigurierte Account-Objekte abzubilden](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md), anstatt [Customer](https://docs.stripe.com/api/customers.md)-Objekte zu verwenden. #### Accounts v2 ```curl curl -G https://api.stripe.com/v1/payment_methods \ -u "<>:" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d type=card ``` #### Customers v1 ```curl curl -G https://api.stripe.com/v1/payment_methods \ -u "<>:" \ -d "customer={{CUSTOMER_ID}}" \ -d type=card ``` Wenn Sie bereit sind, die Zahlung Ihrer Kundin/Ihres Kunden *off-session* (A payment is described as off-session if it occurs without the direct involvement of the customer, using previously-collected payment information) zu belasten, verwenden Sie die `Kunden`-ID oder das von der Kundin/dem Kunden/Kundin konfigurierte `Konto` und die `PaymentMethod`-ID, um einen `PaymentIntent` mit dem Betrag und der Währungen der Zahlung zu erstellen. Legen Sie einige weitere Parameter fest, um die Off-Session-Zahlung durchzuführen: - Legen Sie [off_session](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-off_session) auf true fest, um anzugeben, dass der Kunde/die Kundin sich während eines Bezahlvorgangs nicht in Ihrem Bezahlvorgang befindet und somit eine Authentifizierungsanfrage eines Partners, wie z. B. eines Kartenausstellers, einer Bank oder eines anderen Zahlungsinstituts, nicht erfüllen kann. Wenn ein Partner während Ihres Bezahlvorgangs eine Authentifizierung anfordert, fordert Stripe Ausnahmen unter Verwendung von Kunden/Kundinnen aus einer vorherigen *On-Session*-Transaktion an. Wenn die Bedingungen für die Ausnahme nicht erfüllt sind, kann der `PaymentIntent` einen Fehler ergeben. - Setzen Sie [„confirm“](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-confirm) auf „true“, um sofort nach Erstellung des `PaymentIntent` eine Bestätigung auszulösen. - Legen Sie [payment_method](https://docs.stripe.com/api.md#create_payment_intent-payment_method) auf die ID der `PaymentMethod` fest. - Je nachdem, wie Sie Kundinnen/Kunden in Ihrer Integration darstellen, legen Sie entweder [customer_account](https://docs.stripe.com/api/payment_intents/create.md#create_payment_intent-customer_account) auf die ID des kundenseitig konfigurierten `Kontos` oder [customer](https://docs.stripe.com/api.md#create_payment_intent-customer) auf die `Kunden`-ID fest. #### Accounts v2 ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=usd \ -d "automatic_payment_methods[enabled]=true" \ -d "customer_account={{CUSTOMERACCOUNT_ID}}" \ -d payment_method={{PAYMENT_METHOD_ID}} \ --data-urlencode "return_url=https://example.com/order/123/complete" \ -d off_session=true \ -d confirm=true ``` #### Customers v1 ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<>:" \ -d amount=1099 \ -d currency=usd \ -d "automatic_payment_methods[enabled]=true" \ -d "customer={{CUSTOMER_ID}}" \ -d payment_method={{PAYMENT_METHOD_ID}} \ --data-urlencode "return_url=https://example.com/order/123/complete" \ -d off_session=true \ -d confirm=true ``` ## Integration testen #### Karten | Kartennummer | Szenario | So führen Sie den Test durch | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | | 4242424242424242 | Die Kartenzahlung ist erfolgreich und es ist keine Authentifizierung erforderlich. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 4000002500003155 | Für die Kartenzahlung ist eine *Authentifizierung* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase) erforderlich. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 4000000000009995 | Die Karte wird mit einem Ablehnungscode wie `insufficient_funds` abgelehnt. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 6205500000000000004 | Die UnionPay-Karte hat eine variable Länge von 13 bis 19 Ziffern. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | #### Bankumleitungen | Zahlungsmethode | Szenario | So führen Sie den Test durch | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Bancontact, iDEAL | Ihr/e Kund/in konnte sich auf der iDEAL-Weiterleitungsseite für eine auf Weiterleitung basierende Zahlungsmethode mit sofortiger Benachrichtigung nicht authentifizieren. | Wählen Sie eine beliebige, auf Weiterleitung basierende Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung fehlgeschlagen**. | | Pay by Bank | Ihr Kunde/Ihre Kundin zahlt erfolgreich mit einer auf Weiterleitung basierenden Zahlungsmethode mit [verzögerter Benachrichtigung](https://docs.stripe.com/payments/payment-methods.md#payment-notification). | Wählen Sie die Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung abschließen**. | | Pay by Bank | Ihr/e Kund/in konnte sich auf der iDEAL-Weiterleitungsseite für eine auf Weiterleitung basierende Zahlungsmethode mit verzögerter Benachrichtigung nicht authentifizieren. | Wählen Sie die Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung fehlgeschlagen**. | | BLIK | BLIK-Zahlungen können aus verschiedenen Gründen fehlschlagen. Es gibt sofortige Fehler (der Code ist abgelaufen oder ungültig), verzögerte Fehler (die Bank lehnt ab) oder Zeitüberschreitungen (der/die Kund/in hat nicht rechtzeitig reagiert). | Verwenden Sie E-Mail-Muster, um [die verschiedenen Fehler zu simulieren](https://docs.stripe.com/payments/blik/accept-a-payment.md#simulate-failures) | #### Banklastschriften | Zahlungsmethode | Szenario | So führen Sie den Test durch | | ---------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | SEPA-Lastschrift | Ihr/e Kund/in zahlt erfolgreich mit dem SEPA-Lastschriftverfahren. | Füllen Sie das Formular mit der Kontonummer `AT321904300235473204` aus. Die bestätigte PaymentIntent geht zunächst in den Status „wird verarbeitet“ und dann drei Minuten später in den Status „erfolgreich“ über. | | SEPA-Lastschrift | Der Status der PaymentIntent Ihres/Ihrer Kund/in wechselt von `processing` zu `requires_payment_method`. | Füllen Sie das Formular mit der Kontonummer `AT861904300235473202` aus. | Hier finden Sie weitere Informationen zum [Testen](https://docs.stripe.com/testing.md) Ihrer Integration. ## Optional: Karten speichern [Serverseitig] [Clientseitig] `EmbeddedPaymentElement` kann es Kundinnen und Kunden ermöglichen, ihre Karte zu speichern, und die gespeicherten Karten des Kunden/der Kundin in die verfügbaren Zahlungsmethoden aufnehmen. Der Kunde/Die Kundin muss über ein zugehöriges, vom Kunden/von der Kundin konfiguriertes [Account](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer)-Objekt oder [Customer](https://docs.stripe.com/api/customers/create.md)-Objekt auf Ihrem Server verfügen. Um ein Kontrollkästchen zu aktivieren, mit dem der Kunde/die Kundin seine/ihre Karte speichern kann, erstellen Sie eine [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) mit `enabled` für `payment_method_save`. #### Accounts v2 ```javascript // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. const stripe = require("stripe")("<>"); const express = require('express'); const app = express(); app.set('trust proxy', true); app.use(express.json()); app.post('/payment-sheet', async (req, res) => { // Use an existing Account ID if this is a returning customer. const customer_account = await stripe.v2.core.accounts.create(); const customerSession = await stripe.customerSessions.create({ customer_account: customer_account.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer_account: customer_account.id, }); }); ``` Als Nächstes konfigurieren Sie `EmbeddedPaymentElement` mit der ID des Kunden/der Kundin und dem Client-Geheimnis der `CustomerSession`. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Powdur") .customer( PaymentSheet.CustomerConfiguration.createWithCustomerSession( id = customerAccountId, clientSecret = customerSessionClientSecret, ) ) .build() embeddedPaymentElement.configure( intentConfiguration = // ... , configuration = configuration, ) ``` #### Customers v1 ```javascript // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. const stripe = require("stripe")("<>"); const express = require('express'); const app = express(); app.set('trust proxy', true); app.use(express.json()); app.post('/payment-sheet', async (req, res) => { // Use an existing Customer ID if this is a returning customer. const customer = await stripe.customers.create(); const customerSession = await stripe.customerSessions.create({ customer: customer.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer: customer.id, }); }); ``` Als Nächstes konfigurieren Sie `EmbeddedPaymentElement` mit der ID des Kunden/der Kundin und dem Client-Geheimnis der `CustomerSession`. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Powdur") .customer( PaymentSheet.CustomerConfiguration.createWithCustomerSession( id = customerId, clientSecret = customerSessionClientSecret, ) ) .build() embeddedPaymentElement.configure( intentConfiguration = // ... , configuration = configuration, ) ``` ## Optional: Zahlungsmethoden mit Verzögerung zulassen [Clientseitig] *Zahlungsmethoden mit Verzögerung* (A payment method that can't immediately return payment status when a customer attempts a transaction (for example, ACH debits). Businesses commonly hold an order in a pending state until payment is successful with these payment methods) garantieren nicht, dass Sie am Ende des Bezahlvorgangs Gelder von Ihrem Kunden/Ihrer Kundin erhalten, da einerseits die Abwicklung eine gewisse Zeit in Anspruch nimmt (z. B. bei US-Bankkonten, SEPA-Lastschrift, iDEAL, Bancontact und Sofort) oder weil Kundinnen und Kunden aktiv werden müssen, um den Vorgang abzuschließen (z. B. OXXO, Konbini und Boleto). Standardmäßig zeigt `EmbeddedPaymentElement` keine Zahlungsmethoden mit Verzögerung an, selbst wenn Sie diese akzeptieren. Um die von Ihnen aktivierten Zahlungsmethoden mit Verzögerung anzuzeigen, legen Sie `allowsDelayedPaymentMethods` in Ihrer `EmbeddedPaymentElement.Configuration` auf „true“ fest. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Powdur") .allowsDelayedPaymentMethods(true) .build() ``` Wenn Kundinnen/Kunden erfolgreich eine Zahlungsmethode mit Verzögerung in einem `EmbeddedPaymentElement` verwenden, lautet das zurückgegebene Zahlungsergebnis `EmbeddedPaymentElement.Result.Completed`. ## Optional: Google Pay aktivieren > Wenn Ihr Checkout-Bildschirm eine spezielle **Google Pay**-Schaltfläche enthält, befolgen Sie den [Google Pay-Leitfaden](https://docs.stripe.com/google-pay.md?platform=android). Sie können das eingebettete Payment Element verwenden, um andere Arten von Zahlungsmethoden zu verarbeiten. ### Integration einrichten Um Google Pay zu verwenden, aktivieren Sie zuerst die Google Pay API, indem Sie dem Tag `` Ihrer Datei **AndroidManifest.xml** Folgendes hinzufügen: ```xml ... ``` Weitere Informationen finden Sie in der [Google Pay API](https://developers.google.com/pay/api/android/guides/setup) für Android. ### Google Pay hinzufügen Um Google Pay zu Ihrer Integration hinzuzufügen, übergeben Sie [PaymentSheet.GooglePayConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-google-pay-configuration/index.html) mit Ihrer Google Pay-Umgebung (Produktion oder Test) sowie den [Ländercode Ihres Unternehmens](https://dashboard.stripe.com/settings/account) bei der Initialisierung von `EmbeddedPaymentElement.Configuration`. ```kotlin val googlePayConfiguration = PaymentSheet.GooglePayConfiguration( environment = PaymentSheet.GooglePayConfiguration.Environment.Test, countryCode = "US", currencyCode = "USD" // Required for Setup Intents, optional for Payment Intents ) val configuration = EmbeddedPaymentElement.Configuration.Builder("Merchant, Inc.") .googlePay(googlePayConfiguration) .build() ``` ### Google Pay testen Google bietet Ihnen die Möglichkeit, Zahlungen über seine [Testkartensuite](https://developers.google.com/pay/api/android/guides/resources/test-card-suite) zu testen. Sie können Stripe-[Testkarten](https://docs.stripe.com/testing.md) mit der Testsuite verwenden. In einem Land, in dem Google Pay unterstützt wird, müssen Sie Google Pay mit einem physischen Android-Gerät anstelle eines simulierten Geräts testen. Melden Sie sich mit einer echten in Google Wallet gespeicherten Karte bei einem Google-Konto auf Ihrem Testgerät an. ## Optional: Kartenscannen aktivieren Um den Support für das Scannen von Karten zu aktivieren, [fordern Sie Produktionszugriff](https://developers.google.com/pay/api/android/guides/test-and-deploy/request-prod-access) auf die Google Pay API über die [Google Pay & Wallet Console](https://pay.google.com/business/console?utm_source=devsite&utm_medium=devsite&utm_campaign=devsite) an. - Wenn Sie Google Pay aktiviert haben, ist die Funktion zum Scannen von Karten auf berechtigten Geräten automatisch auf unserer Nutzeroberfläche verfügbar. Weitere Informationen zu berechtigten Geräten finden Sie unter den [Einschränkungen der Google Pay API](https://developers.google.com/pay/payment-card-recognition/debit-credit-card-recognition) - **Wichtig:** Die Funktion zum Scannen von Karten wird nur in Builds angezeigt, die mit demselben in der [Google Pay & Wallet Console](https://pay.google.com/business/console) registrierten Signaturschlüssel signiert sind. Test- oder Fehlerbehebungs-Builds mit verschiedenen Signaturschlüsseln (z. B. Builds, die über Firebase App Tester verteilt werden) zeigen die Option **Karte scannen** an. Um Karten in Pre-Release-Builds zu testen, müssen Sie entweder: - oder Ihre Test-Builds mit Ihrem Produktions-Signaturschlüssel signieren - Fingerabdruck Ihres Test-Signaturschlüssels zur Google Pay and Wallet-Konsole hinzufügen Wenn Ihre App Google Pay nicht unterstützt, können Sie den Stripe-Kartenscanner verwenden. > Der Stripe-Kartenscanner befindet sich in der öffentlichen Vorschau. Um den Support für das Scannen von Karten zu aktivieren, fügen Sie dem `dependencies`-Block Ihrer Datei [app/build.gradle](https://developer.android.com/studio/build/dependencies) `stripecardscan` hinzu: #### Groovy ```groovy implementation 'com.stripe:stripecardscan:23.8.0' ``` ## Optional: Passen Sie das Tabellenblatt an Alle Anpassungen werden mithilfe des `EmbeddedPaymentElement.Configuration`-Objekts konfiguriert. ### Erscheinungsbild Passen Sie mit der [Appearance API](https://docs.stripe.com/elements/appearance-api/embedded-mobile.md?platform=android) Farben, Schriftarten und mehr an das Erscheinungsbild Ihrer App an. ### Adressen der Kund/innen erfassen Erfassen Sie Versand- und Rechnungsadressen von Ihren Kundinnen/Kunden mithilfe des [Address Element](https://docs.stripe.com/elements/address-element.md?platform=android). ### Den angezeigten Unternehmensnamen anpassen Geben Sie einen kundenorientierten Unternehmensnamen an, indem Sie `merchantDisplayName` festlegen. Wenn Sie keinen Namen angeben, ist der Standardwert der Name Ihrer App. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Merchant, Inc.") .build() ``` ### Standardabrechnungsdaten angeben Um Standardwerte für Abrechnungsdaten festzulegen, die in `EmbeddedPaymentElement` erfasst wurden, konfigurieren Sie die Eigenschaft `defaultBillingDetails`. Das `EmbeddedPaymentElement` füllt seine Felder vorab mit den von Ihnen angegebenen Werten aus. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Merchant, Inc.") .defaultBillingDetails( PaymentSheet.BillingDetails( address = PaymentSheet.Address( country = "US", ), email = "foo@bar.com" ) ) .build() ``` ### Erfassung von Abrechnungsdetails konfigurieren `BillingDetailsCollectionConfiguration` verwenden, um anzugeben, wie Sie Rechnungsdetails im `EmbeddedPaymentElement` erfassen möchten. Sie können den Namen, die E-Mail-Adresse, die Telefonnummer und die Adresse Ihrer Kundinnen und Kunden erfassen. Wenn Sie dem PaymentMethod-Objekt Standard-Abrechnungsdetails zuordnen möchten, auch wenn diese Felder nicht auf der Nutzeroberfläche erfasst werden, legen Sie `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` auf `true` fest. ```kotlin import com.stripe.android.paymentsheet.PaymentSheet.BillingDetailsCollectionConfiguration val billingDetails = PaymentSheet.BillingDetails( email = "foo@bar.com" ) val billingDetailsCollectionConfiguration = BillingDetailsCollectionConfiguration( attachDefaultsToPaymentMethod = true, name = BillingDetailsCollectionConfiguration.CollectionMode.Always, email = BillingDetailsCollectionConfiguration.CollectionMode.Never, address = BillingDetailsCollectionConfiguration.AddressCollectionMode.Full, ) val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Merchant, Inc.") .defaultBillingDetails(billingDetails) .billingDetailsCollectionConfiguration(billingDetailsCollectionConfiguration) .build() ``` > Wenden Sie sich an Ihren Rechtsbeistand bezüglich der Gesetze, die für das Erfassen von Informationen gelten. Erfassen Sie Telefonnummern nur, wenn Sie sie für die Transaktion benötigen. # Zahlung annehmen und Zahlungsmethode speichern > This is a Zahlung annehmen und Zahlungsmethode speichern for when platform is android and type is paymentsfu. View the full page at https://docs.stripe.com/payments/mobile/accept-payment-embedded?platform=android&type=paymentsfu. Verwenden Sie die [Payment Intents API](https://docs.stripe.com/api/payment_intents.md), um Zahlungsdetails aus einem Einkauf zu speichern. Es gibt mehrere Anwendungsszenarien: - Belasten Sie das Konto eines Kunden/einer Kundin für eine E-Commerce-Bestellung und speichern Sie die Details für zukünftige Einkäufe. - Leiten Sie die erste Zahlung einer Reihe wiederkehrender Zahlungen ein. - Buchen Sie eine Anzahlung ab und speichern Sie die Details, um den vollen Betrag später abzubuchen. > #### Transaktionen mit vorhandener Karte > > Card-Present-Transaktionen, wie zum Beispiel Zahlungen über Stripe Terminal, verwenden ein anderes Verfahren zum Speichern der Zahlungsmethode. Weitere Informationen finden Sie in der [Terminal-Dokumentation](https://docs.stripe.com/terminal/features/saving-payment-details/save-after-payment.md). ## Konformität Sie sind dafür verantwortlich, alle geltenden Gesetze, Vorschriften und Netzwerkregeln einzuhalten, wenn Sie die Zahlungsdaten eines Kunden oder einer Kundin für die zukünftige Verwendung speichern, beispielsweise um dem Kunden oder der Kundin seine bzw. ihre Zahlungsmethode beim Bezahlvorgang für einen zukünftigen Kauf anzuzeigen oder um ihm Kosten in Rechnung zu stellen, wenn er Ihre Website oder App nicht aktiv nutzt. Bevor Sie die Zahlungsmethode eines Kunden oder einer Kundin speichern oder ihm Kosten in Rechnung stellen, stellen Sie bitte sicher, dass Sie: - Fügen Sie Ihrer Website oder App Bestimmungen hinzu, die darlegen, wie Sie Zahlungsmethoden speichern möchten, beispielsweise: - Die kundenseitige Zustimmung, eine Zahlung oder mehrere Zahlungen für bestimmte Transaktionen in deren Namen einzuleiten - Der erwartete Zeitpunkt und die voraussichtliche Häufigkeit von Zahlungen (z. B. Zahlungen für geplante Raten- oder Abonnementzahlungen oder für außerplanmäßige Aufstockungen). - Wie Sie den Zahlbetrag ermitteln. - Ihre Stornorichtlinie, wenn die Zahlungsmethode für einen Abonnementdienst ist. - Verwenden Sie eine gespeicherte Zahlungsmethode ausschließlich für den in Ihren Bedingungen angegebenen Zweck. - Bitte holen Sie die ausdrückliche Zustimmung des Kunden oder der Kundin für diese spezifische Verwendung ein. Fügen Sie beispielsweise ein Kontrollkästchen „Meine Zahlungsmethode für zukünftige Transaktionen speichern“ hinzu. - Bewahren Sie die schriftliche Zustimmung Ihrer Kundinnen und Kunden zu Ihren Bedingungen auf. ## Stripe einrichten [Serverseitig] [Clientseitig] Zunächst benötigen Sie ein Stripe-Konto. [Registrieren Sie sich jetzt](https://dashboard.stripe.com/register). ### Serverseitig Für diese Integration sind Endpoints auf Ihrem Server erforderlich, die mit der Stripe-API kommunizieren können. Nutzen Sie diese offiziellen Bibliotheken für den Zugriff auf die Stripe-API von Ihrem Server aus: #### 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' ``` ### Client-seitig Das [Stripe Android SDK](https://github.com/stripe/stripe-android) ist Open Source und [vollständig dokumentiert](https://stripe.dev/stripe-android/). Um das SDK zu installieren, fügen Sie `stripe-android` in den Block `dependencies` Ihrer [app/build.gradle](https://developer.android.com/studio/build/dependencies)-Datei ein: #### Kotlin ```kotlin plugins { id("com.android.application") id("org.jetbrains.kotlin.android") id("org.jetbrains.kotlin.plugin.compose") } android { ... kotlinOptions { jvmTarget = "11" } buildFeatures { compose true } } dependencies { // ... // Stripe Android SDK implementation("com.stripe:stripe-android:23.8.0") // Include the financial connections SDK to support US bank account as a payment method implementation("com.stripe:financial-connections:23.8.0") } ``` > Details zur aktuellen SDK-Version und zu vorherigen Versionen finden Sie auf der Seite [Releases](https://github.com/stripe/stripe-android/releases) auf GitHub. Um bei Veröffentlichung eines neuen Release eine Benachrichtigung zu erhalten, [beobachten Sie Veröffentlichungen für das jeweilige Repository](https://docs.github.com/en/github/managing-subscriptions-and-notifications-on-github/configuring-notifications#configuring-your-watch-settings-for-an-individual-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. ```kotlin // Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys PaymentConfiguration.init(context, publishableKey = "<>") ``` ## Zahlungsmethoden aktivieren Zeigen Sie Ihre [Einstellungen für Zahlungsmethoden](https://dashboard.stripe.com/settings/payment_methods) an und aktivieren Sie die Zahlungsmethoden, die Sie unterstützen möchten. Sie müssen mindestens eine Zahlungsmethode aktiviert haben, um einen *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) zu erstellen. Standardmäßig aktiviert Stripe Karten und andere gängige Zahlungsmethoden, mit denen Sie mehr Kundinnen und Kunden erreichen können. Wir empfehlen jedoch, zusätzliche Zahlungsmethoden zu aktivieren, die für Ihr Unternehmen und Ihre Kundschaft relevant sind. Weitere Informationen zur Unterstützung von Produkten und Zahlungsmethoden finden Sie auf der Seite [Unterstützte Zahlungsmethoden](https://docs.stripe.com/payments/payment-methods/payment-method-support.md) und der [Preisseite](https://stripe.com/pricing/local-payment-methods) für Gebühren. ## Kundin/Kunden erstellen [Serverseitig] Um eine Zahlungsmethode für zukünftige Zahlungen einzurichten, müssen Sie sie einem Objekt zuordnen, das Ihre Kundin/Ihre Kundin darstellt. Wenn Ihre Kundin/Kundin ein Konto erstellt oder die erste Transaktion mit Ihrem Unternehmen durchgeführt hat, erstellen Sie entweder ein kundenseitig konfiguriertes [Account](https://docs.stripe.com/api/v2/core/accounts/create.md)-Objekt mit der Accounts v2 API oder ein [Customer](https://docs.stripe.com/api/customers/create.md)-Objekt mit der Customers API. > #### Verwenden Sie die Accounts v2 API zum Darstellen von Kundinnen und Kunden > > Die Accounts v2 API ist allgemein für Connect-Nutzer/innen verfügbar und für andere Stripe-Nutzer/innen in der öffentlichen Vorschau. Wenn an der Accounts v2 Vorschau teilnehmen, müssen Sie eine [Vorschauversion](https://docs.stripe.com/api-v2-overview.md#sdk-and-api-versioning) in Ihrem Code angeben. > > Um Zugriff auf die Accounts v2 Vorschau anzufordern, {% collect-email modal=true modal_link_text=“sign up.” list=“payin-payout-reuse-waitlist@stripe.com” send_direct_email=true intro_text=“Sind Sie am frühzeitigen Zugang zur Vorschau der Accounts v2 API interessiert?" body_text=“Wir sind gerade dabei, die Vorschau von Accounts v2 bereitzustellen. Um Zugang zu beantragen, geben Sie unten Ihre E-Mail-Adresse ein.” form_cta_text=“Registrieren” success_text=“Danke! Wir melden uns bald.” show_email_confirmation=wahr /%} > > Für die meisten Anwendungsfälle empfehlen wir, [Ihre Kundinnen und Kunden als vom Kunden bzw. von der Kundin konfigurierte Account-Objekte abzubilden](https://docs.stripe.com/accounts-v2/use-accounts-as-customers.md), anstatt [Customer](https://docs.stripe.com/api/customers.md)-Objekte zu verwenden. ```curl curl -X POST https://api.stripe.com/v1/customers \ -u "<>:" ``` ## Zahlungsdetails erfassen [Clientseitig] Das eingebettete Mobile Payment Element ist für die Verwendung auf der Bezahlseite Ihrer nativen mobilen App konzipiert. Das Element zeigt eine Liste mit Zahlungsmethoden an, die Sie an das Erscheinungsbild Ihrer App anpassen können. Wenn Kundinnen und Kunden auf die Zeile **Karte** tippen, wird ein Formular geöffnet, in dem sie die Details ihrer Zahlungsmethode eingeben können. Die Schaltfläche im Formular zeigt standardmäßig **Fortfahren** an und schließt das Formular, wenn darauf getippt wird, sodass Ihre Kundinnen und Kunden die Zahlung in Ihrem Bezahlvorgang abschließen können. ![Embedded Payment Element](https://b.stripecdn.com/docs-statics-srv/assets/android-embedded.1aefe2ca79ed073e350ec629a5af22d5.png) Alternativ können Sie die Schaltfläche so konfigurieren, dass die Zahlung sofort abgeschlossen wird, anstatt fortzufahren. Führen Sie dazu [diesen Schritt](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#embedded-let-customer-pay-immediately) aus, nachdem Sie der Anleitung gefolgt sind. ### Eingebettetes Payment Element initialisieren #### Jetpack Compose Initialisieren Sie eine Instanz von `EmbeddedPaymentElement` mithilfe der Funktion `rememberEmbeddedPaymentElement` mit einem `EmbeddedPaymentElement.Builder`. Übergeben Sie ein `CreateIntentWithConfirmationTokenCallback`. Lassen Sie die Implementierung vorerst leer. ```kotlin import com.stripe.android.paymentelement.EmbeddedPaymentElement import com.stripe.android.paymentelement.rememberEmbeddedPaymentElement @Composable fun CheckoutScreen() { val embeddedBuilder = remember { EmbeddedPaymentElement.Builder( createIntentCallback = { confirmationToken, -> TODO("You'll implement this in the "Confirm the payment" step") }, resultCallback = { result -> TODO("You'll implement this in the "Confirm the payment" step") }, ) } val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) } ``` #### Ansichten (klassisch) Initialisieren Sie eine Instanz von `EmbeddedPaymentElement` mithilfe der Funktion `rememberEmbeddedPaymentElement` mit einem `EmbeddedPaymentElement.Builder`. ```kotlin import com.stripe.android.paymentelement.EmbeddedPaymentElement import com.stripe.android.paymentelement.rememberEmbeddedPaymentElement @Composable fun CheckoutScreen() { val embeddedBuilder = remember { EmbeddedPaymentElement.Builder( createIntentCallback = { confirmationToken -> TODO("Completed in a later step.") }, resultCallback = { result -> TODO("Completed in a later step.") }, ) } val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) } ``` Das Embedded Mobile Payment Element wurde für die Jetpack Compose-Nutzeroberfläche entwickelt und stellt eine Methode `@Composable Content` zur Verfügung. Wenn Sie klassische Ansichten verwenden, müssen Sie das Embedded Payments Element in einen `ComposeView` verpacken. ```xml ``` ```kotlin class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.checkout_screen_layout) val composeView = findViewById(R.id.compose_view) composeView.setContent { CheckoutScreen() } } } ``` ### Eingebettetes Payment Element konfigurieren Das `Builder`-Objekt enthält Rückrufe, die für die Instanziierung von `EmbeddedPaymentElement` erforderlich sind, einschließlich des `CreateIntentCallback`. Lassen Sie die Implementierung vorerst leer. Rufen Sie nach der Instanziierung `configure` mit `EmbeddedPaymentElement.Configuration` und`PaymentSheet.IntentConfiguration` auf. Das `Configuration`-Objekt enthält allgemeine Konfigurationsoptionen für `EmbeddedPaymentElement`, die sich zwischen den Zahlungen nicht ändern. Das`IntentConfiguration`-Objekt enthält Details über die spezifische Zahlung, wie z. B. den Betrag und die Währungen. > Um Zahlungsmethoden in `EmbeddedPaymentElement` zu speichern, konfigurieren Sie `setupFutureUsage`. Sie können den Parameter [setupFutureUsage](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-setup_future_usage) in `IntentConfiguration` auf `onSession` oder `offSession` setzen. Dieser Wert wird automatisch auf alle verfügbaren Zahlungsmethoden angewendet. ```kotlin import com.stripe.android.paymentsheet.PaymentSheet import com.stripe.android.paymentsheet.PaymentSheet.IntentConfiguration.SetupFutureUse @Composable fun CheckoutScreen() { val embeddedBuilder = .... val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) LaunchedEffect(embeddedPaymentElement) { embeddedPaymentElement.configure( intentConfiguration = PaymentSheet.IntentConfiguration(mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = 1099, currency = "USD",setupFutureUse = SetupFutureUse.OffSession,),// Optional intent configuration options... ), configuration = EmbeddedPaymentElement.Configuration.Builder("Powdur").build() ) } } ``` ### Ansicht „Eingebettetes Payment Element“ hinzufügen Sobald das `EmbeddedPaymentElement` erfolgreich initialisiert wurde, fügen Sie seinen `@Composable Content` in die Nutzeroberfläche Ihres Bezahlvorgangs ein. > Der Inhalt muss sich in einem scrollbaren Container befinden, da sich seine Höhe nach dem ersten Rendern ändern kann. ```kotlin @Composable fun CheckoutScreen() { val embeddedBuilder = .... val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) ..... val scrollState = rememberScrollState() Column( modifier = Modifier .fillMaxSize() .verticalScroll(scrollState) .padding(16.dp) ) { embeddedPaymentElement.Content() } } ``` An dieser Stelle können Sie Ihre App ausführen und das eingebettete Mobile Payment Element sehen. ### (Optional) Zahlungsangaben aktualisieren Wenn eine Kundin/ein Kunde die Zahlungsdetails ändert (z. B. durch Anwenden eines Rabattcodes), aktualisieren Sie die `EmbeddedPaymentElement`-Instanz. Wenn Sie die `configure`-Methode erneut verwenden, werden die neuen Werte synchronisiert und in der Nutzeroberfläche angezeigt. > Bei einigen Zahlungsmethoden, wie z. B. Google Pay, wird der Betrag in der Nutzeroberfläche angezeigt. Wenn eine Kundin/ein Kunde die Zahlung ändert und Sie das `EmbeddedPaymentElement`, zeigt die Nutzeroberfläche falsche Werte an. Wenn der Aufruf von `configure` abgeschlossen ist, werden `@Composable Content` und `paymentOption` automatisch mit den neuen Werten aktualisiert, die für den Aufruf `configure` bereitgestellt wurden. ```kotlin val intentConfiguration = PaymentSheet.IntentConfiguration( // Update the amount to reflect the price after applying the discount code mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = 999, currency = "USD", setupFutureUse = SetupFutureUse.OffSession, ), ) val configuration = EmbeddedPaymentElement.Configuration.Builder("Powdur") .build() LaunchedEffect(embeddedPaymentElement) { embeddedPaymentElement.configure( intentConfiguration = intentConfiguration, configuration = configuration, ) } ``` ### (Optional) Ausgewählte Zahlungsoption anzeigen Sie können Details zu den Zahlungsoptionen (z. B. die letzten 4 Ziffern, ein Kartenlogo oder Rechnungsinformationen) anzeigen, indem Sie auf die beobachtbare Eigenschaft `Flow` der `paymentOption` von Embedded Payment Element zugreifen. Wenn eine Kundin/ein Kunde eine Zahlungsmethode auswählt, die ein Formularblatt öffnet, wird die Zahlungsoption aktualisiert, nachdem sie bzw. er im Blatt auf **Weiter** geklickt hat. ```kotlin val selectedPaymentOption by embeddedPaymentElement.paymentOption.collectAsState() selectedPaymentOption?.let { paymentOption -> Row( verticalAlignment = Alignment.CenterVertically, modifier = Modifier .clickable( onClick = { }, ) .semantics { text = AnnotatedString(paymentOption.label) }, ) { Icon( painter = paymentOption.iconPainter, contentDescription = null, // decorative element modifier = Modifier.padding(horizontal = 4.dp), tint = Color.Unspecified, ) Text(text = paymentOption.label) } } ``` ### Zahlung bestätigen Wenn der Kunde/die Kundin auf die Checkout-Schaltfläche tippt, leiten Sie die Zahlung ein, indem Sie `embeddedPaymentElement.confirm()` aufrufen. Achten Sie darauf, die Nutzerinteraktion während der Bestätigung zu deaktivieren. Wenn ein Formular vorgelegt wird, ruft `EmbeddedPaymentElement` `confirm` auf, wenn die Nutzerin/der Nutzer auf **Handlungsaufforderung** klickt. Wenn die ausgewählte Zahlungsmethode keine Formularfelder aufweist, rufen Sie `confirm` auf, wenn die Nutzerin/der Nutzer unter `@Composable Content` auf **Handlungsaufforderung** klickt. ```kotlin Button( onClick = { embeddedPaymentElement.confirm() } ) { Text("Confirm payment") } ``` Implementieren Sie als Nächstes den Callback `createIntentCallback`, den Sie zuvor an `EmbeddedPaymentElement.Builder` übergeben haben, um eine Anfrage an Ihren Server zu senden. Ihr Server erstellt ein `PaymentIntent` und gibt sein Client-Geheimnis zurück, wie unter [PaymentIntent erstellen](https://docs.stripe.com/payments/mobile/accept-payment-embedded.md#submit-payment) erläutert. Wenn Sie die Anfrage erhalten, geben Sie das Ergebnis der Intent-Erstellung über `CreateIntentResult` mit dem Client-Geheimnis Ihrer Server Antwort oder einem Fehler zurück. Das `EmbeddedPaymentElement` bestätigt den PaymentIntent mit dem Client-Geheimnis oder zeigt die lokalisierte Fehlermeldung in der Nutzeroberfläche an. ```kotlin import com.stripe.android.paymentsheet.CreateIntentResult val embeddedBuilder = remember { val embeddedBuilder = EmbeddedPaymentElement.Builder( createIntentCallback = { confirmationToken ->// Make a request to your own server and receive a client secret or an error. val networkResult = ... if (networkResult.isSuccess) { CreateIntentResult.Success(networkResult.clientSecret) } else { CreateIntentResult.Failure(networkResult.exception) } }, resultCallback = { result ->when (result) { is EmbeddedPaymentElement.Result.Completed -> { // Payment completed - show a confirmation screen. } is EmbeddedPaymentElement.Result.Failed -> { // Encountered an unrecoverable error. You can display the error to the user, log it, and so on } is EmbeddedPaymentElement.Result.Canceled -> { // Customer canceled - you should probably do nothing. } } }, ) } ``` ## Optional: Ausgewählte Zahlungsoption löschen Wenn Sie Zahlungsoptionen außerhalb von `EmbeddedPaymentElement` haben, müssen Sie möglicherweise die ausgewählte Zahlungsoption löschen. Verwenden Sie dazu die `clearPaymentOption` API, um die ausgewählte Zahlungsoption zu deaktivieren. ```kotlin @Composable fun CheckoutScreen() { val embeddedPaymentElementBuilder = .... val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedPaymentElementBuilder) .... Button( onClick = embeddedPaymentElement::clearPaymentOption ) { Text("Select external payment option") } } ``` ## Optional: Mandat selbst anzeigen Um die Einhaltung gesetzlicher Vorschriften zu gewährleisten, zeigt das eingebettete Mobile Payment Element standardmäßig Mandate und Haftungsausschlüsse an. Dieser Text muss sich in der Nähe Ihrer Schaltfläche **Kaufen** befinden. Wenn Sie die Standardanzeige dieses Textes in der Ansicht deaktivieren, müssen Sie ihn selbst anzeigen. > Um die Vorschriften einzuhalten, muss Ihre Integration den Mandatstext korrekt anzeigen. Wenn Sie ihn selbst anzeigen, stellen Sie sicher, dass alle URLs korrekt gerendert werden, indem Sie den Text in ein zusammensetzbares `Text`-Objekt einfügen. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder("Merchant, Inc") .embeddedViewDisplaysMandateText(false) .build() .... val selectedPaymentOption by embeddedPaymentElement.paymentOption.collectAsState() selectedPaymentOption?.mandateText?.let { mandateText -> Text(mandateText) } ``` ## Optional: Lassen Sie den Kunden/die Kundin sofort im Formular bezahlen ![Eingebettetes Zahlungs-Element](https://b.stripecdn.com/docs-statics-srv/assets/embedded-pay-immediate.057c691220d43158ac8000de10815ed9.png) Um die Schaltfläche im Formular zur sofortigen Bestätigung der Zahlung zu konfigurieren, legen Sie `formSheetAction` für Ihr `EmbeddedPaymentElement.Configuration`-Objekt fest. Der Completion-Block wird mit dem Ergebnis der Zahlung ausgeführt, nachdem das Formular geschlossen wurde. Die eingebettete Nutzeroberfläche kann nach Abschluss der Zahlung nicht verwendet werden. Wir empfehlen daher, dass Ihre Implementierung die Nutzer/innen zu einem anderen Bildschirm weiterleitet, z. B. einem Zahlungsbeleg-Bildschirm. ```kotlin @Composable fun CheckoutScreen() { val embeddedBuilder = .... val embeddedPaymentElement = rememberEmbeddedPaymentElement(embeddedBuilder) LaunchedEffect(embeddedPaymentElement) { embeddedPaymentElement.configure( intentConfiguration = ...., configuration = EmbeddedPaymentElement.Configuration.Builder("Powdur") .formSheetAction(EmbeddedPaymentElement.FormSheetAction.Confirm) .build() ) } } ``` ## PaymentIntent erstellen [Serverseitig] Erstellen Sie auf Ihrem Server a *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) durch Angabe eines Betrags und einer Währung. Sie können Zahlungsmethoden über das [Dashboard](https://dashboard.stripe.com/settings/payment_methods) verwalten. Stripe handhabt die Rückgabe geeigneter Zahlungsmethoden basierend auf Faktoren wie Betrag, Währung und Zahlungsablauf der Transaktion. Um zu verhindern, dass böswillige Kundinnen und Kunden ihre eigenen Preise wählen, sollten Sie den Preis immer auf der Serverseite (einer vertrauenswürdigen Umgebung) festlegen und nicht auf dem Client. Wenn der Aufruf erfolgreich ist, geben Sie den PaymentIntent *das Client-Geheimnis* (The client secret is a unique key returned from Stripe as part of a PaymentIntent. This key lets the client access important fields from the PaymentIntent (status, amount, currency) while hiding sensitive ones (metadata, customer)) zurück. Wenn der Aufruf fehlschlägt, [beheben Sie den Fehler](https://docs.stripe.com/error-handling.md) und geben eine Fehlermeldung mit einer kurzen Erklärung an Ihre Kundin/Ihren Kunden zurück. > Überprüfen Sie, ob alle IntentConfiguration-Eigenschaften mit Ihrem PaymentIntent (zum Beispiel `setup_future_usage`, `amount` und `currency`) übereinstimmen. #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') post '/create-intent' do data = JSON.parse request.body.read params = { customer: ..., # The Customer ID you previously created amount: 1099, currency: 'usd', setup_future_usage: 'off_session', automatic_payment_methods: {enabled: true}, } begin intent = client.v1.payment_intents.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` ## Ereignisse nach Zahlung verarbeiten [Serverseitig] Stripe sendet ein [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md#event_types-payment_intent.succeeded)-Ereignis, wenn die Zahlung abgeschlossen ist. Verwenden Sie [Webhook-Tool im Dashboard](https://dashboard.stripe.com/webhooks) oder folgen Sie der [Webhook-Anleitung](https://docs.stripe.com/webhooks/quickstart.md), um diese Ereignisse zu empfangen und führen Sie Aktionen aus, wie beispielsweise das Senden einer Bestellbestätigung per E-Mail, das Protokollieren des Verkaufs in der Datenbank oder das Starten eines Versand-Workflows. Überwachen Sie diese Ereignisse, statt auf einen Callback vom Client zu warten. Auf dem Client könnten die Kund/innen das Browserfenster schließen oder die App beenden, bevor der Callback erfolgt ist. Bösartige Clients könnten dann die Antwort manipulieren. Wenn Sie Ihre Integration so einrichten, dass sie asynchrone Ereignisse überwacht, können Sie [verschiedene Arten von Zahlungsmethoden](https://stripe.com/payments/payment-methods-guide) mit einer einzelnen Integration akzeptieren. Neben der Abwicklung des `payment_intent.succeeded`-Ereignisses empfehlen wir die Abwicklung von diesen weiteren Ereignissen, wenn Sie Zahlungen mit dem Payment Element erfassen: | Ereignis | Beschreibung | Aktion | | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [payment_intent.succeeded](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.succeeded) | Wird gesendet, wenn Kundinnen und Kunden eine Zahlung erfolgreich abgeschlossen haben. | Senden Sie den Kund/innen eine Auftragsbestätigung und *wickeln* (Fulfillment is the process of providing the goods or services purchased by a customer, typically after payment is collected) Sie die Bestellung ab. | | [payment_intent.processing](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.processing) | Wird gesendet, wenn eine/e Kund/in eine Zahlung erfolgreich veranlasst hat, die Zahlung aber noch nicht abgeschlossen ist. Dieses Ereignis wird am häufigsten gesendet, wenn der Kunde/die Kundin eine Bankabbuchung veranlasst. In Zukunft folgt darauf entweder ein `payment_intent.succeeded`- oder ein `payment_intent.payment_failed`-Ereignis. | Senden Sie eine Bestellbestätigung an die Kund/innen, in der angegeben ist, dass die Zahlung noch aussteht. Bei digitalen Waren können Sie die Bestellung abwickeln, bevor Sie darauf warten, dass die Zahlung erfolgt. | | [payment_intent.payment_failed](https://docs.stripe.com/api/events/types.md?lang=php#event_types-payment_intent.payment_failed) | Wird gesendet, wenn ein Kunde/eine Kundin einen Zahlungsversuch durchführt, die Zahlung jedoch fehlschlägt. | Wenn eine Zahlung von `processing` zu `payment_failed` übergeht, bieten Sie der Kundin/dem Kunden einen weiteren Zahlungsversuch an. | ## Integration testen #### Karten | Kartennummer | Szenario | So führen Sie den Test durch | | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------- | | 4242424242424242 | Die Kartenzahlung ist erfolgreich und es ist keine Authentifizierung erforderlich. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 4000002500003155 | Für die Kartenzahlung ist eine *Authentifizierung* (Strong Customer Authentication (SCA) is a regulatory requirement in effect as of September 14, 2019, that impacts many European online payments. It requires customers to use two-factor authentication like 3D Secure to verify their purchase) erforderlich. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 4000000000009995 | Die Karte wird mit einem Ablehnungscode wie `insufficient_funds` abgelehnt. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | | 6205500000000000004 | Die UnionPay-Karte hat eine variable Länge von 13 bis 19 Ziffern. | Füllen Sie das Kreditkartenformular aus und geben Sie die Kreditkartennummer mit beliebiger Gültigkeitsdauer, CVC und Postleitzahl an. | #### Bankumleitungen | Zahlungsmethode | Szenario | So führen Sie den Test durch | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Bancontact, iDEAL | Ihr/e Kund/in konnte sich auf der iDEAL-Weiterleitungsseite für eine auf Weiterleitung basierende Zahlungsmethode mit sofortiger Benachrichtigung nicht authentifizieren. | Wählen Sie eine beliebige, auf Weiterleitung basierende Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung fehlgeschlagen**. | | Pay by Bank | Ihr Kunde/Ihre Kundin zahlt erfolgreich mit einer auf Weiterleitung basierenden Zahlungsmethode mit [verzögerter Benachrichtigung](https://docs.stripe.com/payments/payment-methods.md#payment-notification). | Wählen Sie die Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung abschließen**. | | Pay by Bank | Ihr/e Kund/in konnte sich auf der iDEAL-Weiterleitungsseite für eine auf Weiterleitung basierende Zahlungsmethode mit verzögerter Benachrichtigung nicht authentifizieren. | Wählen Sie die Zahlungsmethode aus, füllen Sie die erforderlichen Informationen aus und bestätigen Sie die Zahlung. Klicken Sie dann auf der Weiterleitungsseite auf **Testzahlung fehlgeschlagen**. | | BLIK | BLIK-Zahlungen können aus verschiedenen Gründen fehlschlagen. Es gibt sofortige Fehler (der Code ist abgelaufen oder ungültig), verzögerte Fehler (die Bank lehnt ab) oder Zeitüberschreitungen (der/die Kund/in hat nicht rechtzeitig reagiert). | Verwenden Sie E-Mail-Muster, um [die verschiedenen Fehler zu simulieren](https://docs.stripe.com/payments/blik/accept-a-payment.md#simulate-failures) | #### Banklastschriften | Zahlungsmethode | Szenario | So führen Sie den Test durch | | ---------------- | -------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | SEPA-Lastschrift | Ihr/e Kund/in zahlt erfolgreich mit dem SEPA-Lastschriftverfahren. | Füllen Sie das Formular mit der Kontonummer `AT321904300235473204` aus. Die bestätigte PaymentIntent geht zunächst in den Status „wird verarbeitet“ und dann drei Minuten später in den Status „erfolgreich“ über. | | SEPA-Lastschrift | Der Status der PaymentIntent Ihres/Ihrer Kund/in wechselt von `processing` zu `requires_payment_method`. | Füllen Sie das Formular mit der Kontonummer `AT861904300235473202` aus. | Hier finden Sie weitere Informationen zum [Testen](https://docs.stripe.com/testing.md) Ihrer Integration. ## Optional: Setzen Sie SetupFutureUsage für einzelne Zahlungsmethoden (Preview) [Serverseitig] [Clientseitig] Für mehr Detailgenauigkeit legen Sie `setupFutureUsage` für bestimmte Zahlungsmethoden mit [PaymentSheet.IntentConfiguration.Mode.PaymentMethodOptions](https://github.com/stripe/stripe-android/blob/master/paymentsheet/src/main/java/com/stripe/android/paymentsheet/PaymentSheet.kt#L433) fest. ```kotlin import com.stripe.android.model.PaymentMethod import com.stripe.android.paymentelement.PaymentMethodOptionsSetupFutureUsagePreview @OptIn(PaymentMethodOptionsSetupFutureUsagePreview::class) @Composable fun MyCheckoutScreen() { val embeddedPaymentElement = rememberEmbeddedPaymentElement( EmbeddedPaymentElement.Builder( createIntentCallback = { confirmationToken -> // Handle ConfirmationToken... } ) ) Column { embeddedPaymentElement.Content( intentConfiguration = PaymentSheet.IntentConfiguration( mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = 1099, currency = "usd",paymentMethodOptions = PaymentSheet.IntentConfiguration.Mode.PaymentMethodOptions( setupFutureUsageValues = mapOf( PaymentMethod.Type.Card to SetupFutureUse.OffSession, PaymentMethod.Type.CashAppPay to SetupFutureUse.OnSession ) ) ) ) ) } } ``` Erfahren Sie mehr über [die `setupFutureUsage`-Werte](https://docs.stripe.com/api/payment_intents/object.md#payment_intent_object-payment_method_options), die für jede Zahlung unterstützt werden. Stellen Sie als Nächstes sicher, dass Ihr Server das Feld `setup_future_usage` oder `Zahlung_method_options[X][setup_future_usage]` für den PaymentIntent nicht festlegt. Das SDK übernimmt die Einstellung automatisch anhand der `IntentConfiguration`. #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') post '/create-intent' do data = JSON.parse request.body.read params = { amount: 1099, currency: 'usd', confirmation_token: data['confirmation_token'], # In the latest version of the API, specifying the `automatic_payment_methods` parameter is optional because Stripe enables its functionality by default. automatic_payment_methods: {enabled: true}, } begin intent = client.v1.payment_intents.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` ## Optional: Karten speichern [Serverseitig] [Clientseitig] `EmbeddedPaymentElement` kann es Kundinnen und Kunden ermöglichen, ihre Karte zu speichern, und die gespeicherten Karten des Kunden/der Kundin in die verfügbaren Zahlungsmethoden aufnehmen. Der Kunde/Die Kundin muss über ein zugehöriges, vom Kunden/von der Kundin konfiguriertes [Account](https://docs.stripe.com/api/v2/core/accounts/create.md#v2_create_accounts-configuration-customer)-Objekt oder [Customer](https://docs.stripe.com/api/customers/create.md)-Objekt auf Ihrem Server verfügen. Um ein Kontrollkästchen zu aktivieren, mit dem der Kunde/die Kundin seine/ihre Karte speichern kann, erstellen Sie eine [CustomerSession](https://docs.stripe.com/api/customer_sessions.md) mit `enabled` für `payment_method_save`. #### Accounts v2 ```javascript // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. const stripe = require("stripe")("<>"); const express = require('express'); const app = express(); app.set('trust proxy', true); app.use(express.json()); app.post('/payment-sheet', async (req, res) => { // Use an existing Account ID if this is a returning customer. const customer_account = await stripe.v2.core.accounts.create(); const customerSession = await stripe.customerSessions.create({ customer_account: customer_account.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer_account: customer_account.id, }); }); ``` Als Nächstes konfigurieren Sie `EmbeddedPaymentElement` mit der ID des Kunden/der Kundin und dem Client-Geheimnis der `CustomerSession`. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Powdur") .customer( PaymentSheet.CustomerConfiguration.createWithCustomerSession( id = customerAccountId, clientSecret = customerSessionClientSecret, ) ) .build() embeddedPaymentElement.configure( intentConfiguration = // ... , configuration = configuration, ) ``` #### Customers v1 ```javascript // Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. const stripe = require("stripe")("<>"); const express = require('express'); const app = express(); app.set('trust proxy', true); app.use(express.json()); app.post('/payment-sheet', async (req, res) => { // Use an existing Customer ID if this is a returning customer. const customer = await stripe.customers.create(); const customerSession = await stripe.customerSessions.create({ customer: customer.id, components: { mobile_payment_element: { enabled: true, features: { payment_method_save: 'enabled', payment_method_redisplay: 'enabled', payment_method_remove: 'enabled' } }, }, }); res.json({ customerSessionClientSecret: customerSession.client_secret, customer: customer.id, }); }); ``` Als Nächstes konfigurieren Sie `EmbeddedPaymentElement` mit der ID des Kunden/der Kundin und dem Client-Geheimnis der `CustomerSession`. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Powdur") .customer( PaymentSheet.CustomerConfiguration.createWithCustomerSession( id = customerId, clientSecret = customerSessionClientSecret, ) ) .build() embeddedPaymentElement.configure( intentConfiguration = // ... , configuration = configuration, ) ``` ## Optional: Zahlungsmethoden mit Verzögerung zulassen [Clientseitig] *Zahlungsmethoden mit Verzögerung* (A payment method that can't immediately return payment status when a customer attempts a transaction (for example, ACH debits). Businesses commonly hold an order in a pending state until payment is successful with these payment methods) garantieren nicht, dass Sie am Ende des Bezahlvorgangs Gelder von Ihrem Kunden/Ihrer Kundin erhalten, da einerseits die Abwicklung eine gewisse Zeit in Anspruch nimmt (z. B. bei US-Bankkonten, SEPA-Lastschrift, iDEAL, Bancontact und Sofort) oder weil Kundinnen und Kunden aktiv werden müssen, um den Vorgang abzuschließen (z. B. OXXO, Konbini und Boleto). Standardmäßig zeigt `EmbeddedPaymentElement` keine Zahlungsmethoden mit Verzögerung an, selbst wenn Sie diese akzeptieren. Um die von Ihnen aktivierten Zahlungsmethoden mit Verzögerung anzuzeigen, legen Sie `allowsDelayedPaymentMethods` in Ihrer `EmbeddedPaymentElement.Configuration` auf „true“ fest. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Powdur") .allowsDelayedPaymentMethods(true) .build() ``` Wenn Kundinnen/Kunden erfolgreich eine Zahlungsmethode mit Verzögerung in einem `EmbeddedPaymentElement` verwenden, lautet das zurückgegebene Zahlungsergebnis `EmbeddedPaymentElement.Result.Completed`. ## Optional: Google Pay aktivieren > Wenn Ihr Checkout-Bildschirm eine spezielle **Google Pay**-Schaltfläche enthält, befolgen Sie den [Google Pay-Leitfaden](https://docs.stripe.com/google-pay.md?platform=android). Sie können das eingebettete Payment Element verwenden, um andere Arten von Zahlungsmethoden zu verarbeiten. ### Integration einrichten Um Google Pay zu verwenden, aktivieren Sie zuerst die Google Pay API, indem Sie dem Tag `` Ihrer Datei **AndroidManifest.xml** Folgendes hinzufügen: ```xml ... ``` Weitere Informationen finden Sie in der [Google Pay API](https://developers.google.com/pay/api/android/guides/setup) für Android. ### Google Pay hinzufügen Um Google Pay zu Ihrer Integration hinzuzufügen, übergeben Sie [PaymentSheet.GooglePayConfiguration](https://stripe.dev/stripe-android/paymentsheet/com.stripe.android.paymentsheet/-payment-sheet/-google-pay-configuration/index.html) mit Ihrer Google Pay-Umgebung (Produktion oder Test) sowie den [Ländercode Ihres Unternehmens](https://dashboard.stripe.com/settings/account) bei der Initialisierung von `EmbeddedPaymentElement.Configuration`. ```kotlin val googlePayConfiguration = PaymentSheet.GooglePayConfiguration( environment = PaymentSheet.GooglePayConfiguration.Environment.Test, countryCode = "US", currencyCode = "USD" // Required for Setup Intents, optional for Payment Intents ) val configuration = EmbeddedPaymentElement.Configuration.Builder("Merchant, Inc.") .googlePay(googlePayConfiguration) .build() ``` ### Google Pay testen Google bietet Ihnen die Möglichkeit, Zahlungen über seine [Testkartensuite](https://developers.google.com/pay/api/android/guides/resources/test-card-suite) zu testen. Sie können Stripe-[Testkarten](https://docs.stripe.com/testing.md) mit der Testsuite verwenden. In einem Land, in dem Google Pay unterstützt wird, müssen Sie Google Pay mit einem physischen Android-Gerät anstelle eines simulierten Geräts testen. Melden Sie sich mit einer echten in Google Wallet gespeicherten Karte bei einem Google-Konto auf Ihrem Testgerät an. ## Optional: Kartenscannen aktivieren Um den Support für das Scannen von Karten zu aktivieren, [fordern Sie Produktionszugriff](https://developers.google.com/pay/api/android/guides/test-and-deploy/request-prod-access) auf die Google Pay API über die [Google Pay & Wallet Console](https://pay.google.com/business/console?utm_source=devsite&utm_medium=devsite&utm_campaign=devsite) an. - Wenn Sie Google Pay aktiviert haben, ist die Funktion zum Scannen von Karten auf berechtigten Geräten automatisch auf unserer Nutzeroberfläche verfügbar. Weitere Informationen zu berechtigten Geräten finden Sie unter den [Einschränkungen der Google Pay API](https://developers.google.com/pay/payment-card-recognition/debit-credit-card-recognition) - **Wichtig:** Die Funktion zum Scannen von Karten wird nur in Builds angezeigt, die mit demselben in der [Google Pay & Wallet Console](https://pay.google.com/business/console) registrierten Signaturschlüssel signiert sind. Test- oder Fehlerbehebungs-Builds mit verschiedenen Signaturschlüsseln (z. B. Builds, die über Firebase App Tester verteilt werden) zeigen die Option **Karte scannen** an. Um Karten in Pre-Release-Builds zu testen, müssen Sie entweder: - oder Ihre Test-Builds mit Ihrem Produktions-Signaturschlüssel signieren - Fingerabdruck Ihres Test-Signaturschlüssels zur Google Pay and Wallet-Konsole hinzufügen Wenn Ihre App Google Pay nicht unterstützt, können Sie den Stripe-Kartenscanner verwenden. > Der Stripe-Kartenscanner befindet sich in der öffentlichen Vorschau. Um den Support für das Scannen von Karten zu aktivieren, fügen Sie dem `dependencies`-Block Ihrer Datei [app/build.gradle](https://developer.android.com/studio/build/dependencies) `stripecardscan` hinzu: #### Groovy ```groovy implementation 'com.stripe:stripecardscan:23.8.0' ``` ## Optional: Passen Sie das Tabellenblatt an Alle Anpassungen werden mithilfe des `EmbeddedPaymentElement.Configuration`-Objekts konfiguriert. ### Erscheinungsbild Passen Sie mit der [Appearance API](https://docs.stripe.com/elements/appearance-api/embedded-mobile.md?platform=android) Farben, Schriftarten und mehr an das Erscheinungsbild Ihrer App an. ### Adressen der Kund/innen erfassen Erfassen Sie Versand- und Rechnungsadressen von Ihren Kundinnen/Kunden mithilfe des [Address Element](https://docs.stripe.com/elements/address-element.md?platform=android). ### Den angezeigten Unternehmensnamen anpassen Geben Sie einen kundenorientierten Unternehmensnamen an, indem Sie `merchantDisplayName` festlegen. Wenn Sie keinen Namen angeben, ist der Standardwert der Name Ihrer App. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Merchant, Inc.") .build() ``` ### Standardabrechnungsdaten angeben Um Standardwerte für Abrechnungsdaten festzulegen, die in `EmbeddedPaymentElement` erfasst wurden, konfigurieren Sie die Eigenschaft `defaultBillingDetails`. Das `EmbeddedPaymentElement` füllt seine Felder vorab mit den von Ihnen angegebenen Werten aus. ```kotlin val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Merchant, Inc.") .defaultBillingDetails( PaymentSheet.BillingDetails( address = PaymentSheet.Address( country = "US", ), email = "foo@bar.com" ) ) .build() ``` ### Erfassung von Abrechnungsdetails konfigurieren `BillingDetailsCollectionConfiguration` verwenden, um anzugeben, wie Sie Rechnungsdetails im `EmbeddedPaymentElement` erfassen möchten. Sie können den Namen, die E-Mail-Adresse, die Telefonnummer und die Adresse Ihrer Kundinnen und Kunden erfassen. Wenn Sie dem PaymentMethod-Objekt Standard-Abrechnungsdetails zuordnen möchten, auch wenn diese Felder nicht auf der Nutzeroberfläche erfasst werden, legen Sie `billingDetailsCollectionConfiguration.attachDefaultsToPaymentMethod` auf `true` fest. ```kotlin import com.stripe.android.paymentsheet.PaymentSheet.BillingDetailsCollectionConfiguration val billingDetails = PaymentSheet.BillingDetails( email = "foo@bar.com" ) val billingDetailsCollectionConfiguration = BillingDetailsCollectionConfiguration( attachDefaultsToPaymentMethod = true, name = BillingDetailsCollectionConfiguration.CollectionMode.Always, email = BillingDetailsCollectionConfiguration.CollectionMode.Never, address = BillingDetailsCollectionConfiguration.AddressCollectionMode.Full, ) val configuration = EmbeddedPaymentElement.Configuration.Builder(merchantDisplayName = "Merchant, Inc.") .defaultBillingDetails(billingDetails) .billingDetailsCollectionConfiguration(billingDetailsCollectionConfiguration) .build() ``` > Wenden Sie sich an Ihren Rechtsbeistand bezüglich der Gesetze, die für das Erfassen von Informationen gelten. Erfassen Sie Telefonnummern nur, wenn Sie sie für die Transaktion benötigen. ## Optional: Aktiveren der Funktion zur erneuten Erfassung der Prüfziffer/CVC bei Bestätigung Um die Prüfziffer einer gespeicherten Karte während der PaymentIntent-Bestätigung erneut einzuziehen, muss Ihre Integration Zahlungsdaten einziehen, bevor ein PaymentIntent erstellt wird. ### Intent-Konfiguration aktualisieren `PaymentSheet.IntentConfiguration` akzeptiert einen optionalen Parameter, mit dem gesteuert wird, wann die Prüfziffer/CVC für eine gespeicherte Karte erneut erfasst werden soll. ```kotlin val intentConfig = PaymentSheet.IntentConfiguration( mode = PaymentSheet.IntentConfiguration.Mode.Payment( amount = 1099, currency = "usd", ),requireCvcRecollection = true, ) ``` ### Parameter der Intent-Erstellung aktualisieren Um die Prüfziffer/CVC bei der Zahlungsbestätigung erneut zu erfassen, fügen Sie bei der Erstellung des PaymentIntent die beiden Parameter `customerId` und `require_cvc_recollection` ein. #### Ruby ```ruby require 'stripe' # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. # Find your keys at https://dashboard.stripe.com/apikeys. client = Stripe::StripeClient.new('<>') post '/create-intent' do data = JSON.parse request.body.read params = { amount: 1099, currency: 'usd', automatic_payment_methods: {enabled: true},customer: customer.id, payment_method_options: { card: {require_cvc_recollection: true} }, } begin intent = client.v1.payment_intents.create(params) {client_secret: intent.client_secret}.to_json rescue Stripe::StripeError => e {error: e.error.message}.to_json end end ``` # Zahlung akzeptieren > This is a Zahlung akzeptieren for when platform is react-native and type is payment. View the full page at https://docs.stripe.com/payments/mobile/accept-payment-embedded?platform=react-native&type=payment. Mit dem Zahlungs-Element können Sie mehrere Zahlungen über eine einzige Integration akzeptieren. Bei dieser Integration erstellen Sie einen benutzerdefinierten Zahlungsablauf, bei dem Sie das Zahlungs-Element rendern, den *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) erstellen und die Zahlung in Ihrer App bestätigen. ## Stripe einrichten [Serverseitig] [Clientseitig] ### Serverseitig Diese Integration erfordert Endpoints auf Ihrem Server, die mit der Stripe-API kommunizieren können. Nutzen Sie unsere offiziellen Bibliotheken für den Zugriff auf die Stripe-API von Ihrem Server aus: #### 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' ``` ### Client-seitig Das [React Native SDK](https://github.com/stripe/stripe-react-native) ist Open Source und vollständig dokumentiert. Intern werden [native iOS](https://github.com/stripe/stripe-ios) und [Android](https://github.com/stripe/stripe-android) SDKs verwendet. Um das React Native SDK von Stripe zu installieren, führen Sie einen der folgenden Befehle im Verzeichnis Ihres Projekts aus (je nachdem, welchen Paket-Manager Sie verwenden): #### yarn ```bash yarn add @stripe/stripe-react-native ``` #### npm ```bash npm install @stripe/stripe-react-native ``` Installieren Sie als Nächstes einige weitere erforderliche Abhängigkeiten: - Für iOS wechseln Sie in das Verzeichnis **ios** und führen Sie `pod install` aus, um sicherzustellen, dass Sie auch die erforderlichen nativen Dependencies installiert haben. - Für Android müssen keine Abhängigkeiten mehr installiert werden. > Wir empfehlen Ihnen, die [offizielle Anleitung zu TypeScript](https://reactnative.dev/docs/typescript#adding-typescript-to-an-existing-project) zu befolgen, um TypeScript zu unterstützen. ### Stripe Initialisierung Um Stripe in Ihrer React Native-App zu initialisieren, umschließen Sie entweder Ihren Zahlungsbildschirm mit der Komponente `StripeProvider` oder verwenden Sie die Initialisierungsmethode `initStripe`. Nur der [veröffentlichbare API-Schlüssel](https://docs.stripe.com/keys.md#obtain-api-keys) in `publishableKey` ist erforderlich. Das folgende Beispiel zeigt, wie Stripe mithilfe der Komponente `StripeProvider` initialisiert wird. ```jsx import { useState, useEffect } from 'react'; import { StripeProvider } from '@stripe/stripe-react-native'; function App() { const [publishableKey, setPublishableKey] = useState(''); const fetchPublishableKey = async () => { const key = await fetchKey(); // fetch key from your server here setPublishableKey(key); }; useEffect(() => { fetchPublishableKey(); }, []); return ( {/* Your app code here */} ); } ``` > Verwenden Sie Ihre API-[Testschlüssel](https://docs.stripe.com/keys.md#obtain-api-keys) beim Testen und Entwickeln Ihrer App und Ihre [Live-Modus](https://docs.stripe.com/keys.md#test-live-modes)-Schlüssel beim Veröffentlichen Ihrer App. ## Zahlungsmethoden aktivieren Zeigen Sie Ihre [Einstellungen für Zahlungsmethoden](https://dashboard.stripe.com/settings/payment_methods) an und aktivieren Sie die Zahlungsmethoden, die Sie unterstützen möchten. Sie müssen mindestens eine Zahlungsmethode aktiviert haben, um einen *PaymentIntent* (The Payment Intents API tracks the lifecycle of a customer checkout flow and triggers additional authentication steps when required by regulatory mandates, custom Radar fraud rules, or redirect-based payment methods) zu erstellen. Standardmäßig aktiviert Stripe Karten und andere gängige Zahlungsmethoden, mit denen Sie mehr Kundinnen und Kunden erreichen können. Wir empfehlen jedoch, zusätzliche Zahlungsmethoden zu aktivieren, die für Ihr Unternehmen und Ihre Kundschaft relevant sind. Weitere Informationen zur Unterstützung von Produkten und Zahlungsmethoden finden Sie auf der Seite [Unterstützte Zahlungsmethoden](https://docs.stripe.com/payments/payment-methods/payment-method-support.md) und der [Preisseite](https://stripe.com/pricing/local-payment-methods) für Gebühren. ## Zahlungsdetails erfassen [Clientseitig] ### Eingebettetes Payment Element initialisieren Verwenden Sie den Hook `useEmbeddedPaymentElement`, um das Embedded Payment Element in Ihrer React Native-App zu erstellen und anzuzeigen. Dieser Hook benötigt zwei Konfigurationsobjekte: - `EmbeddedPaymentElementConfiguration`: Allgemeine Einstellungen (z. B. `returnURL`). - `IntentConfiguration`: Zahlungsspezifische Details (z. B. Betrag, Währungen und Rückruf `confirmationTokenConfirmHandler`). Der Hook gibt ein Objekt mit der React-Komponente `embeddedPaymentElementView` und anderen Hilfsmethoden zurück. Eine vollständige Liste der Optionen und Rückgabewerte finden Sie in der [Stripe React Native SDK-Dokumentation](https://stripe.dev/stripe-react-native/api-reference/interfaces/UseEmbeddedPaymentElementResult.html). > Eine Implementierung von `confirmationTokenConfirmHandler` ist erforderlich, jedoch können Sie es für diesen Schritt als leere Funktion belassen und später implementieren. ```jsx import { useState, useCallback, useEffect } from 'react'; import { useEmbeddedPaymentElement, IntentConfiguration, EmbeddedPaymentElementConfiguration, IntentCreationCallbackParams, } from '@stripe/stripe-react-native'; function MyCheckoutComponent() { const [intentConfig, setIntentConfig] = useState(null); const [elementConfig, setElementConfig] = useState(null); const initialize = useCallback(() => { const newIntentConfig: IntentConfiguration = { mode: { amount: 1099, currencyCode: 'USD', }, confirmationTokenConfirmHandler: async ( confirmationToken, callback: (params: IntentCreationCallbackParams) => void ) => { // You'll implement this in the "Confirm the payment" section below }, }; const newElementConfig: EmbeddedPaymentElementConfiguration = { merchantDisplayName: 'Your Business Name', returnURL: 'your-app://stripe-redirect', }; setIntentConfig(newIntentConfig); setElementConfig(newElementConfig); }, []); const { embeddedPaymentElementView, paymentOption, confirm, update, clearPaymentOption, loadingError, isLoaded, } = useEmbeddedPaymentElement( intentConfig!, elementConfig! ); useEffect(() => { initialize(); }, [initialize]); } ``` ### Ansicht „Eingebettetes Payment Element“ hinzufügen Nachdem der `useEmbeddedPaymentElement`-Hook erfolgreich initialisiert wurde, fügen Sie `embeddedPaymentElementView` in Ihre Komponente ein, um das eingebettete Payment Element in der Nutzeroberfläche Ihres Bezahlvorgangs anzuzeigen. > Wenn `isLoaded` niemals `true` wird, verifizieren Sie, dass `embeddedPaymentElementView` jederzeit im Renderbaum Ihrer Komponente verbleibt. Auf Android muss die native Ansicht installiert werden, damit die Initialisierung abgeschlossen ist. Verwenden Sie Opazität, um die Sichtbarkeit zu steuern, anstatt die Ansicht bedingt darzustellen, wie im untenstehenden Beispiel gezeigt. ```jsx import { View, Text, ActivityIndicator } from 'react-native'; function MyCheckoutComponent() { // Other component code remains the same return ( {/* Handle loading errors through the loadingError property */} {loadingError && ( Failed to load payment form: {loadingError.message || String(loadingError)} )} {/* Keep the view in the render tree for Android, control visibility with opacity */} {embeddedPaymentElementView} {/* Show loading indicator while the view is loading */} {!loadingError && !isLoaded && ( )} ); } ``` Jetzt können Sie Ihre App ausführen und das eingebettete Mobile Payment Element sehen. ### (Optional) Ausgewählte Zahlungsoption anzeigen Der Hook `useEmbeddedPaymentElement` stellt die Eigenschaft `paymentOption` in seinem Rückgabeobjekt bereit. Sie können damit auf Details zur ausgewählten Zahlungsoption des Kunden/der Kundin zugreifen, z. B. auf ein Label (z. B. “····4242”), ein Bild (z. B. ein VISA-Logo) oder Abrechnungsdetails, die auf Ihrer Nutzeroberfläche angezeigt werden. Die Eigenschaft `paymentOption` ist reaktiv, d. h. sie wird automatisch aktualisiert, wenn sich die ausgewählte Zahlungsoption ändert. Sie müssen keine separate Delegatmethode implementieren. Stattdessen können Sie diese Eigenschaft direkt in Ihrer Komponente verwenden, und React rendert die Komponente erneut, wenn sich die `paymentOption` ändert. ```jsx import { View, Text, Image } from 'react-native'; function MyCheckoutComponent() { // Other component code remains the same return ( // Other component code remains the same // Display the currently selected payment option (label and image) {paymentOption?.image && ( )} Selected: {paymentOption?.label ?? 'None'} ); } ``` ### (Optional) Zahlungsangaben aktualisieren Wenn der Kunde/die Kundin Aktionen durchführt, die die Zahlungsdetails ändern (z. B. das Anwenden eines Rabattcodes), aktualisieren Sie die `EmbeddedPaymentElement`-Instanz, um die neuen Werte widerzuspiegeln, indem Sie die update-Methode aufrufen. Bei einigen Zahlungsmethoden, wie Apple Pay und Google Pay, wird der Betrag in der Nutzeroberfläche angezeigt. Stellen Sie daher sicher, dass er immer korrekt und aktuell ist. Wenn der Update-Aufruf abgeschlossen ist, aktualisieren Sie Ihre Nutzeroberfläche. Durch den Aktualisierungsaufruf kann sich die aktuell ausgewählte Zahlungsoption des Kunden/der Kundin ändern. > Verwenden Sie stets `await` beim Aufrufen der `update`-API, um sicherzustellen, dass die Ladezustände korrekt sequenziert werden. Ohne `await` kann der Ladeindikator verschwinden, bevor das Update abgeschlossen ist. ```jsx import { useState, useCallback } from 'react'; import { View, Button, ActivityIndicator } from 'react-native'; function MyCheckoutComponent() { // Other component code remains the same const [isUpdating, setIsUpdating] = useState(false); const handleUpdate = useCallback(async () => { // Create a new IntentConfiguration object with updated values const updatedIntentConfig: IntentConfiguration = { ...intentConfig!, mode: { amount: 999, // Updated amount after applying discount code currencyCode: 'USD', }, }; setIsUpdating(true); try { await update(updatedIntentConfig); } catch (error) { // Handle any unexpected errors console.error('Unexpected error during update:', error); } finally { setIsUpdating(false); } }, [intentConfig, update]); // Example of how to use the handleUpdate function const applyDiscountCode = useCallback(async (discountCode: string) => { // Validate discount code with your server try { const response = await fetch('https://your-server.com/apply-discount', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ discountCode }), }); if (response.ok) { // Update the intent configuration with the new amount await handleUpdate(); } } catch (error) { console.error('Failed to apply discount:', error); } }, [handleUpdate]); return ( {/* Hide view and show loading indicator during update */} {embeddedPaymentElementView} {isUpdating && ( )}