# Versandoptionen dynamisch anpassen Erfahren Sie, wie Sie unterschiedliche Versandkosten für Ihre Kund/innen erstellen. 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. - Nicht kompatibel mit dem [Express Checkout Element](https://docs.stripe.com/elements/express-checkout-element.md). Wallets wie Apple Pay und Google Pay erfassen die Versandadresse direkt, wodurch der auf Server beschränkte Aktualisierungsablauf umgangen wird. Wenn `permissions.update_shipping_details` auf `server_only` gesetzt ist, werden diese Wallets automatisch deaktiviert. > #### Payment Intents API > > Wenn Sie die Payment Intents API verwenden, müssen Sie die Versandoptionen manuell aktualisieren und den Zahlung basierend auf einer ausgewählten Versandoption ändern oder einen neuen PaymentIntent mit angepassten Beträgen erstellen. ## Aktualisierungsberechtigungen für die Checkout-Sitzung konfigurieren [Serverseitig] Legen Sie die [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 fest, in die Sie den Versand anbieten möchten. Wenn Sie die Checkout-Sitzung erstellen, übergeben Sie die Option [permissions.update_shipping_details=server_only](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-permissions-update_shipping_details), um die clientseitige Methode [updateShippingAddress](https://docs.stripe.com/js/custom_checkout/update_shipping_address) zu deaktivieren und die Aktualisierung der Versandadresse und der Versandoptionen von Ihrem Server zu aktivieren. ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -d ui_mode=elements \ -d "permissions[update_shipping_details]=server_only" \ -d "shipping_address_collection[allowed_countries][0]=US" \ -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 einen Endpoint auf Ihrem Server, um die auf der jeweiligen Versandadresse der Kund/innen basierenden Versandoptionen 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) mit der `checkoutSessionId` aus dem Anfragekörper ab. 2. Überprüfen Sie die Versanddetails der Kundin/des Kunden aus dem Anfragetext. 3. Berechnen Sie die Versandoptionen basierend auf der jeweiligen Versandadresse der Kund/innen und den Posten in der Checkout-Sitzung. 4. [Aktualisieren](https://docs.stripe.com/api/checkout/sessions/update.md) Sie die Checkout-Sitzung mit den [shipping_details](https://docs.stripe.com/api/checkout/sessions/object.md#checkout_session_object-collected_information-shipping_details) der Kund/innen und den [shipping_options](https://docs.stripe.com/api/checkout/sessions/update.md#update_checkout_session-shipping_options). #### Ruby ```ruby require 'sinatra' require 'json' require 'stripe' set :port, 4242 # Don't put any keys in code. See https://docs.stripe.com/keys-best-practices. client = Stripe::StripeClient.new('<>') # 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 = client.v1.checkout.sessions.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 client.v1.checkout.sessions.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 ``` ## Client-SDK aktualisieren [Clientseitig] #### HTML + JS Initialisieren Sie Stripe.js ```javascript const stripe = Stripe('<>'); ``` #### React Initialisieren Sie das `stripe`-Beispiel. ```bash npm install --save @stripe/react-stripe-js@^5.0.0 @stripe/stripe-js@^8.0.0 ``` ```javascript import {loadStripe} from '@stripe/stripe-js'; const stripe = loadStripe("<>"); ``` ## Server-Aktualisierungen anfordern [Clientseitig] #### HTML + JS Erstellen Sie eine asynchrone Funktion, die eine Anfrage an Ihren Server stellt, um die Versandoptionen zu aktualisieren, und schließen Sie sie in [runServerUpdate](https://docs.stripe.com/js/custom_checkout/run_server_update) ein. Wenn die Anfrage erfolgreich ist, wird das [Sitzungsobjekt](https://docs.stripe.com/js/custom_checkout/session_object) mit den neuen Versandoptionen aktualisiert. Im folgenden Codebeispiel wird gezeigt, wie die Versandoptionen mit dem `AddressElement` aktualisiert werden. ```html
``` ```javascript // mount the Shipping Address Element const shippingAddressElement = checkout.createShippingAddressElement(); shippingAddressElement.mount('#shipping-address-element'); const toggleViews = (isEditing) => { document.getElementById('shipping-form').style.display = isEditing ? 'block' : 'none'; document.getElementById('shipping-display').style.display = isEditing ? 'none' : 'block'; } const displayAddress = (address) => { const displayDiv = document.getElementById('address-display'); displayDiv.innerHTML = `
${address.name}
${address.address.line1}
${address.address.city}, ${address.address.state} ${address.address.postal_code}
`; } const updateShippingOptions = async (shippingDetails) => { const response = await fetch("/calculate-shipping-options", { method: "POST", headers: { 'Content-type': 'application/json' }, body: JSON.stringify({ checkout_session_id: 'session_id', shipping_details: shippingDetails }) }); const result = await response.json(); if (result.type === 'error') { document.getElementById('error-message').textContent = result.message; toggleViews(true); } else { document.getElementById('error-message').textContent = ''; toggleViews(false); displayAddress(actions.getSession().shippingAddress); } return result; } const handleSave = async () => { const addressElement = await checkout.getShippingAddressElement(); if (!addressElement) { return; } const result = await addressElement.getValue(); if (!result.complete) { return; } try { await checkout.runServerUpdate(() => updateShippingOptions(result.value)); } catch (error) { document.getElementById('error-message').textContent = error?.message; toggleViews(true); } } // Event Listeners document.getElementById('save-button').addEventListener('click', handleSave); document.getElementById('edit-button').addEventListener('click', () => toggleViews(true)); ``` #### React Erstellen Sie eine asynchrone Funktion, die eine Anfrage an Ihren Server stellt, um die Versandoptionen zu aktualisieren, und schließen Sie sie in [runServerUpdate](https://docs.stripe.com/js/custom_checkout/run_server_update) ein. Wenn die Anfrage erfolgreich ist, wird das [Sitzungsobjekt](https://docs.stripe.com/js/custom_checkout/session_object) mit den neuen Versandoptionen aktualisiert. Im folgenden Codebeispiel wird gezeigt, wie die Versandoptionen mit dem `AddressElement` aktualisiert werden. ```jsx import React from 'react'; import {useCheckoutElements, ShippingAddressElement} from '@stripe/react-stripe-js/checkout'; const Shipping = () => { const [editing, setEditing] = React.useState(true); const [error, setError] = React.useState(null); const checkoutState = useCheckoutElements(); if (checkoutState.type === 'loading') { return (
Loading...
); } else if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } const {runServerUpdate, id, shippingAddress, getShippingAddressElement} = checkoutState.checkout; const updateShippingOptions = async (shippingDetails) => { const response = await fetch("/calculate-shipping-options", { method: "POST", headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ checkout_session_id: id, shipping_details: shippingDetails, }) }); if (response.type === 'error') { setError(response.message); setEditing(true); } else { setError(null); setEditing(false); } return result; } const handleEdit = (event) => { event.preventDefault(); setEditing(true); } const handleSave = async () => { const addressElement = getShippingAddressElement(); if (!addressElement) { return; } const aeValue = await addressElement.getValue(); if (!aeValue.complete) { return; } try { await runServerUpdate(() => updateShippingOptions(aeValue.value)); } catch (e) { setError(e?.message); setEditing(true); } } if (!editing && shippingAddress) { const {line1, line2, city, postal_code, state, country} = shippingAddress.address; return (
{shippingAddress.name}
{line1}
{line2}
{city} {state} {postal_code} {country}
); } return (
{error &&
{error}
}
); }; ``` ## 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. 2. Simulieren Sie verschiedene Versandadressen, um zu überprüfen, ob Ihre Funktion `calculateShippingOptions` verschiedene Szenarien korrekt verarbeitet. 3. Ü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. 4. Ü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 `runServerUpdate` wird erwartungsgemäß aufgerufen. - Die Versandoptionen werden basierend auf der angegebenen Adresse korrekt aktualisiert. - Fehlermeldungen werden ordnungsgemäß angezeigt, wenn der Versand nicht verfügbar ist. 5. Geben Sie ungültige Versandadressen ein oder simulieren Sie Serverfehler, um den Umgang mit Fehlern sowohl serverseitig als auch clientseitig zu testen.