# Versandoptionen dynamisch anpassen Aktualisieren Sie die Versandoptionen basierend auf der Versandadresse eines Kunden/einer Kundin. # Gehostete Seite > This is a Gehostete Seite for when payment-ui is stripe-hosted. View the full page at https://docs.stripe.com/payments/checkout/custom-shipping-options?payment-ui=stripe-hosted. Die Integration der gehosteten Seite unterstützt keine dynamische Anpassung der Versandoptionen. Um die Versandoptionen dynamisch anzupassen, verwenden Sie stattdessen die Integration [Eingebettete Seite](https://docs.stripe.com/payments/checkout/custom-shipping-options.md?payment-ui=embedded-form) oder [Bezahlvorgang-Elemente](https://docs.stripe.com/payments/checkout/custom-shipping-options.md?payment-ui=embedded-components). # Eingebettete Seite > This is a Eingebettete Seite for when payment-ui is embedded-form. View the full page at https://docs.stripe.com/payments/checkout/custom-shipping-options?payment-ui=embedded-form. Erfahren Sie, wie Sie die Versandoptionen basierend auf der Adresse, die Ihr Kunde/Ihre Kundin beim Bezahlvorgang eingibt, dynamisch aktualisieren. ### Anwendungsszenarien - **Adresse validieren**: Bestätigen Sie, ob Sie ein Produkt an die Adresse eines Kunden/einer Kundin senden können, indem Sie Ihre eigenen nutzerdefinierten Validierungsregeln verwenden. Sie können auch eine individuelle Nutzeroberfläche für Kundinnen/Kunden erstellen, um ihre bevorzugte Adresse zu bestätigen. - **Relevante Versandoptionen anzeigen**: Nur verfügbare Versandmethoden basierend auf der Kundenadresse anzeigen. Zeigen Sie beispielsweise den Versand über Nacht nur für Lieferungen in Ihrem Land an. - **Versandraten dynamisch berechnen**: Berechnen und Anzeigen der Versandkosten basierend auf der Lieferadresse eines Kunden/einer Kundin. - **Versandkosten basierend auf der Bestellsumme aktualisieren**: Bieten Sie Versandkosten basierend auf der Versandadresse oder der Bestellsumme an, z. B. kostenlosen Versand für Bestellungen über 100 USD. Informationen zu Bezahlvorgängen, bei denen Mengenänderungen oder Cross-Selling zulässig sind, finden Sie unter [Dynamische Aktualisierung von Posten](https://docs.stripe.com/payments/checkout/dynamically-update-line-items.md). ### Beschränkungen - Wird nur im [Zahlungsmodus](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-mode) unterstützt. [Versandraten](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-shipping_options) sind im Abonnementmodus nicht verfügbar. - Unterstützt keine Aktualisierungen als Reaktion auf Änderungen von außerhalb der Bezahlseite. ## Checkout-Sitzung erstellen [Serverseitig] Erstellen Sie von Ihrem Server aus eine *Checkout-Sitzung* (A Checkout Session represents your customer's session as they pay for one-time purchases or subscriptions through Checkout. After a successful payment, the Checkout Session contains a reference to the Customer, and either the successful PaymentIntent or an active Subscription). - Set the [ui_mode](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-ui_mode) to `embedded_page`. - Legen Sie die [permissions.update_shipping_details](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-permissions-update_shipping_details) auf `server_only` fest. - Legen Sie [shipping_address_collection.allowed_countries](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-shipping_address_collection-allowed_countries) auf die Liste der Länder, in die Sie den Versand anbieten möchten. - Legen Sie die [shipping_options.shipping_rate_data](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-shipping_options-shipping_rate_data) fest, mit der eine Dummy-Versandrate mit einem Versandbetrag von 0 USD erstellt wird. Standardmäßig aktualisiert der Client von Stripe Checkout automatisch die [shipping_details](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-collected_information-shipping_details) des [Checkout Session](https://docs.stripe.com/api/checkout/sessions/object.md)-Objekts mit den Versandinformationen, die die Kundin/der Kunde eingibt, einschließlich des [Namens](https://docs.stripe.com/api/checkout/sessions/update.md#update_checkout_session-collected_information-shipping_details-name) und der [Adresse](https://docs.stripe.com/api/checkout/sessions/update.md#update_checkout_session-collected_information-shipping_details-address) der Kundin/des Kunden. > Wenn [permissions.update_shipping_details](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-permissions-update_shipping_details) auf `server_only` festgelegt ist, wird die automatische clientseitige Aktualisierung deaktiviert, und nur Ihr Server kann die Versanddaten mithilfe Ihres Stripe-Geheimschlüssels aktualisieren. ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d ui_mode=embedded_page \ -d "permissions[update_shipping_details]=server_only" \ -d "shipping_address_collection[allowed_countries][0]=US" \ -d "shipping_options[0][shipping_rate_data][display_name]=Dummy shipping" \ -d "shipping_options[0][shipping_rate_data][type]=fixed_amount" \ -d "shipping_options[0][shipping_rate_data][fixed_amount][amount]=0" \ -d "shipping_options[0][shipping_rate_data][fixed_amount][currency]=usd" \ -d "line_items[0][price]={{PRICE_ID}}" \ -d "line_items[0][quantity]=1" \ -d mode=payment \ --data-urlencode "return_url=https://example.com/return" ``` ## Versandoptionen anpassen [Serverseitig] Erstellen Sie von Ihrem Server aus einen neuen Endpoint, um die Versandoptionen basierend auf der Versandadresse der Kundin/des Kunden zu berechnen. 1. [Rufen](https://docs.stripe.com/api/checkout/sessions/retrieve.md) Sie die [Checkout-Sitzung](https://docs.stripe.com/api/checkout/sessions/object.md) anhand der `checkoutSessionId` aus dem Anfragetext ab. 1. Überprüfen Sie die Versanddetails der Kundin/des Kunden aus dem Anfragetext. 1. Berechnen Sie die Versandoptionen basierend auf der Versandadresse der Kundin/des Kunden und den Einzelposten der [Checkout-Sitzung](https://docs.stripe.com/api/checkout/sessions/object.md). 1. [Aktualisieren](https://docs.stripe.com/api/checkout/sessions/update.md) Sie die [Checkout-Sitzung](https://docs.stripe.com/api/checkout/sessions/object.md) mit den [shipping_details](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-collected_information-shipping_details) und den [shipping_options](https://docs.stripe.com/api/checkout/sessions/update.md#update_checkout_session-shipping_options) der Kundin/des Kunden. #### Ruby ```ruby require 'sinatra' require 'json' require 'stripe' set :port, 4242 # Set your secret key. Remember to switch to your live secret key in production! # See your keys here: https://dashboard.stripe.com/apikeys Stripe.api_key = "<>" # Return a boolean indicating whether the shipping details are valid def validate_shipping_details(shipping_details) # TODO: Remove error and implement... raise NotImplementedError.new(<<~MSG) Validate the shipping details the customer has entered. MSG end # Return an array of the updated shipping options or the original options if no update is needed def calculate_shipping_options(shipping_details, session) # TODO: Remove error and implement... raise NotImplementedError.new(<<~MSG) Calculate shipping options based on the customer's shipping details and the Checkout Session's line items. MSG end post '/calculate-shipping-options' do content_type :json request.body.rewind request_data = JSON.parse(request.body.read) checkout_session_id = request_data['checkout_session_id'] shipping_details = request_data['shipping_details'] # 1. Retrieve the Checkout Session session = Stripe::Checkout::Session.retrieve(checkout_session_id) # 2. Validate the shipping details if !validate_shipping_details(shipping_details) return { type: 'error', message: "We can't ship to your address. Please choose a different address." }.to_json end # 3. Calculate the shipping options shipping_options = calculate_shipping_options(shipping_details, session) # 4. Update the Checkout Session with the customer's shipping details and shipping options if shipping_options Stripe::Checkout::Session.update(checkout_session_id, { collected_information: { shipping_details: shipping_details }, shipping_options: shipping_options }) return { type: 'object', value: { succeeded: true } }.to_json else return { type: 'error', message: "We can't find shipping options. Please try again." }.to_json end end ``` ## Checkout verbinden [Clientseitig] #### HTML + JS Checkout ist als Teil von [Stripe.js](https://docs.stripe.com/js.md) verfügbar. Nehmen Sie das Stripe.js-Skript in Ihre Seite auf, indem Sie es zum Header Ihrer HTML-Datei hinzufügen. Als Nächstes erstellen Sie einen leeren DOM-Knoten (Container), der zum Verbinden verwendet wird. ```html
``` Initialisieren Sie Stripe.js mit Ihrem veröffentlichbaren API-Schlüssel. ```javascript // Set your publishable key: remember to change this to your live publishable key in production // See your keys here: https://dashboard.stripe.com/apikeys const stripe = Stripe('<>'); ``` Erstellen Sie eine asynchrone `fetchClientSecret`-Funktion, die eine Anfrage an Ihren Server stellt, um die [Checkout-Sitzung](https://docs.stripe.com/api/checkout/sessions/object.md) zu erstellen und das Client-Geheimnis abzurufen. Erstellen Sie eine asynchrone `onShippingDetailsChange`-Funktion, die Ihren Server auffordert, die Versandoptionen anhand der Versandadresse der Kundin/des Kunden zu berechnen. Stripe Checkout ruft die Funktion auf, wenn das Formular kundenseitig mit den Versanddetails ausgefüllt wird. ```javascript initialize(); async function initialize() { // Fetch Checkout Session and retrieve the client secret const fetchClientSecret = async () => { const response = await fetch("/create-checkout-session", { method: "POST", }); const { clientSecret } = await response.json(); return clientSecret; }; // Call your backend to set shipping options const onShippingDetailsChange = async (shippingDetailsChangeEvent) => { const {checkoutSessionId, shippingDetails} = shippingDetailsChangeEvent; const response = await fetch("/calculate-shipping-options", { method: "POST", body: JSON.stringify({ checkout_session_id: checkoutSessionId, shipping_details: shippingDetails, }) }) if (response.type === 'error') { return Promise.resolve({type: "reject", errorMessage: response.message}); } else { return Promise.resolve({type: "accept"}); } }; // Initialize Checkout const checkout = await stripe.createEmbeddedCheckoutPage({ fetchClientSecret, onShippingDetailsChange, }); // Mount Checkout checkout.mount('#checkout'); } ``` #### React Installieren Sie [react-stripe-js](https://docs.stripe.com/sdks/stripejs-react.md) und den Stripe.js-Loader von npm: ```bash npm install --save @stripe/react-stripe-js @stripe/stripe-js ``` Initialisieren Sie die `stripe`-Instanz mit Ihrem veröffentlichbaren API-Schlüssel. ```jsx import {loadStripe} from '@stripe/stripe-js'; // Make sure to call `loadStripe` outside of a component’s render to avoid // recreating the `Stripe` object on every render. const stripePromise = loadStripe('<>'); ``` Um die eingebettete Checkout-Komponente zu verwenden, erstellen Sie einen `EmbeddedCheckoutProvider`. Erstellen Sie eine asynchrone `fetchClientSecret`-Funktion, die eine Anfrage an Ihren Server stellt, um die [Checkout-Sitzung](https://docs.stripe.com/api/checkout/sessions/object.md) zu erstellen und das Client-Geheimnis abzurufen. Erstellen Sie eine asynchrone `onShippingDetailsChange`-Funktion, die Ihren Server auffordert, die Versandoptionen anhand der Versandadresse der Kundin/des Kunden zu berechnen. Stripe Checkout ruft die Funktion auf, wenn das Formular kundenseitig mit den Versanddetails ausgefüllt wird. Übergeben Sie `stripePromise` an den Anbieter und die Funktionen an die vom Anbieter akzeptierte Eigenschaft `options`. ```jsx import * as React from 'react'; import { EmbeddedCheckoutProvider, EmbeddedCheckout } from '@stripe/react-stripe-js'; const App = () => { const fetchClientSecret = useCallback(() => { // Create a Checkout Session return fetch("/create-checkout-session", { method: "POST", }) .then((res) => res.json()) .then((data) => data.clientSecret); }, []); // Call your backend to set shipping options const onShippingDetailsChange = async (shippingDetailsChangeEvent) => { const {checkoutSessionId, shippingDetails} = shippingDetailsChangeEvent; const response = await fetch("/calculate-shipping-options", { method: "POST", body: JSON.stringify({ checkout_session_id: checkoutSessionId, shipping_details: shippingDetails, }) }) if (response.type === 'error') { return Promise.resolve({type: "reject", errorMessage: response.message}); } else { return Promise.resolve({type: "accept"}); } }; const options = {fetchClientSecret, onShippingDetailsChange}; return (
) } ``` > Geben Sie in Ihrer Funktion `onShippingDetailsChange` stets ein `Promise` zurück und lösen Sie dieses mit einem [ResultAction](https://docs.stripe.com/js/embedded_checkout/create#embedded_checkout_create-options-onShippingDetailsChange-ResultAction)-Objekt auf. Der Checkout-Client aktualisiert die Nutzeroberfläche basierend auf dem Ergebnis Ihrer `onShippingDetailsChange`-Funktion. - Wenn das Ergebnis `type: "accept"` hat, werden auf der Checkout-Nutzeroberfläche die Versandoptionen angezeigt, die Sie auf Ihrem Server festgelegt haben. - Wenn das Ergebnis `type: "reject"` hat, zeigt die Checkout-Nutzeroberfläche die Fehlermeldung an, die Sie im Ergebnis festgelegt haben. Optional können Sie `onShippingDetailsChange` abhören und eine benutzerdefinierte Nutzeroberfläche erstellen, in der Kundinnen/Kunden ihre bevorzugte Adresse aus mehreren möglichen Adressen auswählen und bestätigen können. Checkout wird in einem iFrame gerendert, der Zahlungsdaten sicher über eine HTTPS-Verbindung an Stripe sendet. > Vermeiden Sie es, Checkout in einem anderen iFrame zu platzieren, da bei einigen Zahlungsmethoden die Weiterleitung an eine andere Seite zur Zahlungsbestätigung erforderlich ist. ## Integration testen Befolgen Sie diese Schritte, um Ihre Integration zu testen und sicherzustellen, dass Ihre nutzerdefinierten Versandoptionen korrekt funktionieren. 1. Richten Sie eine Sandbox-Umgebung ein, die die Einrichtung Ihrer Produktionsumgebung widerspiegelt. Verwenden Sie Ihre Sandbox-API-Schlüssel von Stripe für diese Umgebung. 1. Simulieren Sie verschiedene Versandadressen, um zu überprüfen, ob Ihre Funktion `calculateShippingOptions` verschiedene Szenarien korrekt verarbeitet. 1. Überprüfen Sie die serverseitige Logik, indem Sie Log- oder Debugging-Tools verwenden, um zu bestätigen, dass Ihr Server Folgendes tut: - Ruft die [Checkout-Sitzung](https://docs.stripe.com/api/checkout/sessions/object.md) ab. - Überprüft die Versanddetails. - Berechnet die Versandoptionen. - Aktualisiert die [Checkout-Sitzung](https://docs.stripe.com/api/checkout/sessions/object.md) mit den neuen Versanddetails und -optionen. Stellen Sie sicher, dass die Aktualisierungsantwort die neuen Versanddetails und -optionen enthält. 1. Überprüfen Sie die clientseitige Logik, indem Sie den Bezahlvorgang mehrmals in Ihrem Browser abschließen. Achten Sie darauf, wie die Nutzeroberfläche aktualisiert wird, nachdem Sie die Versanddetails eingegeben haben. Stellen Sie sicher, dass: - Die Funktion `onShippingDetailsChange` wird erwartungsgemäß aufgerufen. - Die Versandoptionen werden basierend auf der angegebenen Adresse korrekt aktualisiert. - Fehlermeldungen werden ordnungsgemäß angezeigt, wenn der Versand nicht verfügbar ist. 1. Geben Sie ungültige Versandadressen ein oder simulieren Sie Serverfehler, um den Umgang mit Fehlern sowohl serverseitig als auch clientseitig zu testen.