# Dynamisches Aktualisieren von Rabatten Erfahren Sie, wie Sie Rabattcodes während des Bezahlvorgangs anwenden und ändern. > #### Private Vorschau > > Dynamische Rabatte befinden sich in der privaten Vorschau. Erfahren Sie, wie Sie dynamisch Rabatte für eine [Checkout-Sitzung](https://docs.stripe.com/api/checkout/sessions/object.md) hinzufügen oder entfernen. ### Anwendungsszenarien In diesem Leitfaden wird beschrieben, wie eine Vernetzung mit Ihrem internen Rabattsystem durchführen, um dynamische Rabatte zu erstellen. Sie können aber auch: - **Treuerabatte anwenden**: Wenden Sie automatisch Rabatte basierend auf der Treuestufe der Kundinnen/Kunden oder der Kaufhistorie an. - **Warenkorbwertaktionen**: Fügen Sie Rabatte hinzu, wenn die Gesamtsumme der Bestellung bestimmte Schwellenwerte überschreitet (z. B. 10 USD Rabatt auf Bestellungen über 100 USD). - **Kurzfristige Angebote**: Wenden Sie zeitlich begrenzte Aktionsrabatte an oder entfernen Sie abgelaufene Rabattcodes. - **Standortbezogene Rabatte**: Wenden Sie regionsspezifische Rabatte basierend auf der Versandadresse des Kunden/der Kundin an. - **Kundenspezifische Angebote**: Erstellen Sie personalisierte Rabattbeträge basierend auf Kundensegmenten oder vorherigem Kaufverhalten. > #### Payment Intents API > > Wenn Sie die Payment Intents API verwenden, können Sie Rabatte anwenden, indem Sie den Zahlungsbetrag manuell berechnen und ändern oder indem Sie einen neuen PaymentIntent mit angepassten Beträgen erstellen. ## SDK einrichten [Serverseitig] Verwenden Sie unsere offiziellen Bibliotheken, um von Ihrer Anwendung aus auf die Stripe API zuzugreifen: #### Ruby ```bash gem install stripe -v 15.1.0-beta.2 ``` ## Server-SDK aktualisieren [Serverseitig] Um diese Vorschaufunktion zu verwenden, aktualisieren Sie zunächst Ihr SDK, um den Beta-Header `checkout_server_update_beta=v1` zu verwenden. #### Ruby ```ruby # Don't put any keys in code. Use a secrets vault or environment # variable to supply keys to your integration. This example # shows how to set a secret key for illustration purposes only. # # See https://docs.stripe.com/keys-best-practices and find your # keys at https://dashboard.stripe.com/apikeys. Stripe.api_key = '<>' Stripe.api_version = '2025-03-31.basil; checkout_server_update_beta=v1;' ``` ## Aktualisierungsberechtigungen für die Checkout-Sitzung konfigurieren [Serverseitig] Übergeben Sie beim Erstellen der Checkout-Sitzung die Option [permissions.update_discounts=server_only](https://docs.stripe.com/api/checkout/sessions/create.md#create_checkout_session-permissions-update_discounts), um die Anwendung clientseitiger Rabatte zu deaktivieren und die Aktualisierung von Rabatten von Ihrem Server aus zu aktivieren. ```curl curl https://api.stripe.com/v1/checkout/sessions \ -u "<>:" \ -H "Stripe-Version: 2025-03-31.basil; checkout_server_update_beta=v1;" \ -d ui_mode=custom \ -d "permissions[update_discounts]"=server_only \ -d "line_items[0][price]"="{{PRICE_ID}}" \ -d "line_items[0][quantity]"=1 \ -d mode=payment \ --data-urlencode return_url="https://example.com/return" ``` ## Dynamisches Aktualisieren von Rabatten [Serverseitig] Erstellen Sie einen Endpoint auf Ihrem Server, um Rabatte auf die Checkout-Sitzung anzuwenden. Sie rufen diesen in einem späteren Schritt über das Frontend auf. > Client-seitiger Code wird in einer Umgebung ausgeführt, die von dem/der Nutzer/in kontrolliert wird. Böswillige Nutzer/innen können Ihre clientseitige Validierung umgehen, Anfragen abfangen und ändern oder neue Anfragen an Ihren Server erstellen. Beim Erstellen eines Endpoints empfehlen wir Folgendes: - Erstellen Sie Endpoints für bestimmte Kundeninteraktionen, anstatt sie allgemein zu gestalten. Beispiel: „Treuerabatte anwenden“ statt einer allgemeinen „Aktualisieren“-Aktion. Spezifische Endpoints können beim Schreiben und Pflegen der Validierungslogik helfen. - Übergeben Sie [Sitzungsdaten](https://docs.stripe.com/js/custom_checkout/session_object) nicht direkt vom Client an Ihren Endpoint. Bösartige Clients können Anfragedaten ändern, was sie zu einer unzuverlässigen Quelle für die Bestimmung des Status der Checkout-Sitzung macht. Übergeben Sie stattdessen die [Sitzungs-ID](https://docs.stripe.com/js/custom_checkout/session_object#custom_checkout_session_object-id) an Ihren Server und verwenden Sie diese, um die Daten sicher von der Stripe API abzurufen. #### 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 discounts are valid. def validate_discounts(discounts, session # Basic validation - ensure we only have one discount if any return true if discounts.empty? || discounts == "" # Ensure only one discount is being applied return false if discounts.is_a?(Array) && discounts.length > 1 # Add your own validation logic here # For example, validate promo codes against your internal system true end # Return an array of the updated discounts or the original ones if no update is needed. def recompute_discounts(discounts, session) # If removing discounts, return empty return [] if discounts.empty? || discounts == "" # Example: Access your internal discounts system # This could be based on customer ID, promo codes, cart value, and so on customer_id = session.customer || session.client_reference_id cart_total = session.amount_total # Example internal discount calculation discount_amount = calculate_customer_discount(customer_id, cart_total) if discount_amount > 0 # Create a dynamic discount using coupon_data [{ coupon_data: { name: "Customer Discount", amount_off: discount_amount, currency: session.currency || 'usd' } }] else # No discount applicable [] end end # Example function to integrate with your internal discounts system def calculate_customer_discount(customer_id, cart_total) # Example logic - replace with your actual discount system # This could check: # - Customer loyalty tier # - Active promotions # - Cart value thresholds # - Seasonal discounts # Example: 10% off for carts over 100 USD, max 20 USD discount if cart_total > 10000 # 100 USD in cents discount = [cart_total * 0.1, 2000].min # Max 20 USD discount discount.to_i else 0 end end post '/update-discounts' do content_type :json request.body.rewind request_data = JSON.parse(request.body.read) checkout_session_id = request_data['checkout_session_id'] discounts = request_data['discounts'] # 1. Retrieve the Checkout Session session = Stripe::Checkout::Session.retrieve(checkout_session_id) # 2. Validate the discounts if !validate_discounts(discounts, session) return { type: 'error', message: 'Your discounts are invalid. Please refresh your session.' }.to_json end # 3. Recompute the discounts with your custom logic discounts = recompute_discounts(discounts, session) # 4. Update the Checkout Session with the new discounts if discounts Stripe::Checkout::Session.update(checkout_session_id, { discounts: discounts, }) return { type: 'object', value: { succeeded: true } }.to_json else return { type: 'error', message: "We could not update your discounts. Please try again." }.to_json end end ``` ## Client-SDK aktualisieren [Clientseitig] #### HTML + JS Initialisieren Sie Stripe.js mit dem Beta-Header `custom_checkout_server_updates_1`. ```javascript const stripe = Stripe('<>', { betas: ['custom_checkout_server_updates_1'], }); ``` #### React Übergeben Sie den Beta-Header `custom_checkout_server_updates_1`, wenn Sie die `stripe`-Instanz initialisieren. ```javascript import {loadStripe} from '@stripe/stripe-js'; const stripe = loadStripe("<>", { betas: ['custom_checkout_server_updates_1'], }); ``` ## Server-Aktualisierungen anfordern [Clientseitig] #### HTML + JS Senden Sie von Ihrem Frontend aus eine Aktualisierungsanfrage an Ihren Server und schließen Sie sie in [runServerUpdate](https://docs.stripe.com/js/custom_checkout/run_server_update) ein. Eine erfolgreiche Anfrage aktualisiert das [Sitzungsobjekt](https://docs.stripe.com/js/custom_checkout/session_object) mit dem neuen Rabatt. ```html ``` ```javascript document.getElementById('apply-customer-discount') .addEventListener("click", async (event) => { const updateCheckout = () => { return fetch("/apply-customer-discount", { method: "POST", headers: { "Content-type": "application/json", }, body: JSON.stringify({ checkout_session_id: actions.getSession().id, }) }); }; const response = await checkout.runServerUpdate(updateCheckout); if (!response.ok) { // Handle error state return; } // Update UI to reflect the applied discount event.target.textContent = "Discount Applied!"; event.target.disabled = true; }); ``` #### React Senden Sie von Ihrem Frontend aus eine Aktualisierungsanfrage an Ihren Server und schließen Sie sie in [runServerUpdate](https://docs.stripe.com/js/custom_checkout/run_server_update) ein. Eine erfolgreiche Anfrage aktualisiert das [Sitzungsobjekt](https://docs.stripe.com/js/custom_checkout/session_object) mit dem neuen Rabatt. ```jsx import React from 'react'; import {useCheckout} from '@stripe/react-stripe-js/checkout'; const ApplyDiscountButton = () => { const [isDiscountApplied, setIsDiscountApplied] = React.useState(false); const checkoutState = useCheckout(); if (checkoutState.type === 'loading') { return (
Loading...
); } else if (checkoutState.type === 'error') { return (
Error: {checkoutState.error.message}
); } const {runServerUpdate, id} = checkoutState.checkout; const updateCheckout = () => fetch("/apply-customer-discount", { method: "POST", headers: { 'Content-type': 'application/json', }, body: JSON.stringify({ checkout_session_id: id, }) }); const handleClick = async () => {const response = await runServerUpdate(updateCheckout); if (!response.ok) { // set error state return; } // Update UI to reflect the applied discount setIsDiscountApplied(true); }; return ( ); }; ``` ## Integration testen Befolgen Sie diese Schritte, um Ihre Integration zu testen und sicherzustellen, dass Ihre dynamischen Rabatte 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 Rabattszenarien, um zu überprüfen, ob Ihre Funktion `recomputeDiscounts` 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. - Validiert Rabattanfragen. - Berechnet aktualisierte Rabatte basierend auf Ihrer Geschäftslogik neu. - Aktualisiert die [Checkout-Sitzung](https://docs.stripe.com/api/checkout/sessions/object.md) mit den neuen Rabatten, wenn Ihre nutzerdefinierten Bedingungen erfüllt sind. Stellen Sie sicher, dass die aktualisierte Antwort die neuen Rabatte enthält. Standardmäßig enthält die Antwort das Rabattfeld nicht, es sei denn, die Anfrage [erweitert](https://docs.stripe.com/api/expanding_objects.md) das Objekt. 1. Überprüfen Sie die clientseitige Logik, indem Sie den Bezahlvorgang mehrmals in Ihrem Browser abschließen. Achten Sie darauf, wie die Nutzeroberfläche nach dem Anwenden eines Rabatts aktualisiert wird. Stellen Sie sicher, dass: - Die Funktion [runServerUpdate](https://docs.stripe.com/js/custom_checkout/run_server_update) wird wie erwartet aufgerufen. - Rabatte werden basierend auf Ihrer Geschäftslogik korrekt angewendet. - Die Gesamtsumme des Bezahlvorgangs wird aktualisiert, um den angewendeten Rabatt widerzuspiegeln. - Fehlermeldungen werden ordnungsgemäß angezeigt, wenn ein Rabatt nicht angewendet werden konnte. 1. Testen Sie verschiedene Rabattszenarien, einschließlich ungültiger Rabattanfragen, oder simulieren Sie Serverfehler, um den Umgang mit Fehlern sowohl serverseitig als auch clientseitig zu testen.