> ## Documentation Index
> Fetch the complete documentation index at: https://docs.revize.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Öffentliche Stornierungs-API

> Füge die Bestellstornierung überall in deinem Shopify-Store hinzu. Baue Stornieren-Buttons in E-Mails, Support-Seiten, Chatbots oder eigene Formulare über unseren öffentlichen API-Endpoint ein.

<Note>
  Mit der öffentlichen Stornierungs-API kannst du Self-Service-Stornierung überall hinzufügen – Post-Purchase-E-Mails, Support-Seiten, Chatbots oder eigene Formulare. Kein App-Embed erforderlich.
</Note>

## Warum die Stornierungs-API nutzen

<CardGroup cols={2}>
  <Card title="Stornierung überall" icon="globe" color="#8b5cf6">
    Füge Stornieren-Buttons in E-Mails, FAQ-Seiten, Chatbot-Flows oder beliebigen Oberflächen außerhalb deines Stores hinzu.
  </Card>

  <Card title="Kein App-Embed nötig" icon="code" color="#10b981">
    Funktioniert unabhängig vom Revize-Kundenportal. Einfach den API-Endpoint aufrufen.
  </Card>

  <Card title="Deine Regeln gelten" icon="shield" color="#f59e0b">
    Die API berücksichtigt automatisch deine Stornierungs-Zeitfenster und Berechtigungsregeln.
  </Card>

  <Card title="Einfache Integration" icon="plug" color="#ef4444">
    Ein Endpoint, einfaches Request-Format. Leicht in beliebige Systeme oder Plattformen zu integrieren.
  </Card>
</CardGroup>

## API-Endpoint

<CodeGroup>
  ```bash Endpoint theme={null}
  POST https://revize.untechnickle.com/api/public/v1/{shop-domain-slug}/cancel_order
  ```
</CodeGroup>

**Parameter:**

* `shop-domain-slug` — Die Domain deines Shopify-Stores ohne `.myshopify.com` (z. B. `my-store` von `my-store.myshopify.com`)

## Request-Format

<CodeGroup>
  ```json Request Body theme={null}
  {
    "order_number": "#2667",
    "email": "customer@example.com"
  }
  ```
</CodeGroup>

| Feld           | Typ    | Erforderlich | Beschreibung                                                      |
| -------------- | ------ | ------------ | ----------------------------------------------------------------- |
| `order_number` | string | Ja           | Die Bestellnummer einschließlich des #-Symbols                    |
| `email`        | string | Ja           | E-Mail-Adresse des Kunden, die für die Bestellung verwendet wurde |

## Response-Codes

Die API gibt ein `status`-Feld zurück, das das Ergebnis angibt:

| Status            | Beschreibung                                                        |
| ----------------- | ------------------------------------------------------------------- |
| `SUCCESS`         | Bestellung erfolgreich storniert                                    |
| `ORDER_NOT_FOUND` | Bestellung existiert nicht oder E-Mail stimmt nicht überein         |
| `NOT_CANCELLABLE` | Bestellung kann nicht storniert werden (Richtlinieneinschränkungen) |
| `ORDER_FULFILLED` | Bestellung bereits ausgeliefert, Stornierung nicht möglich          |
| `NOT_EDITABLE`    | Bestellung ist für die Bearbeitung gesperrt                         |
| `CANCEL_DISABLED` | Stornierungsfunktion für diesen Store nicht aktiviert               |
| `APP_INACTIVE`    | Revize-App ist nicht aktiv                                          |
| `SHOP_NOT_FOUND`  | Shop nicht im System gefunden                                       |
| `DOMAIN_MISSING`  | Shop-Domain-Slug fehlt im Request                                   |
| `FAILED`          | Allgemeiner Fehler bei der Operation                                |

## Beispiel-Integration

Hier ein JavaScript-Beispiel zum Aufruf der API:

<CodeGroup>
  ```javascript Fetch Example theme={null}
  async function cancelOrder(orderNumber, email) {
    const shopDomain = 'your-store'; // Without .myshopify.com
    const apiUrl = 'https://revize.untechnickle.com';
    
    try {
      const response = await fetch(
        `${apiUrl}/api/public/v1/${shopDomain}/cancel_order`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json'
          },
          body: JSON.stringify({
            order_number: orderNumber,
            email: email
          })
        }
      );
      
      const result = await response.json();
      
      if (result.success === true || result.status === 'SUCCESS') {
        console.log('Order cancelled successfully');
        return { success: true };
      } else {
        console.log('Cancellation failed:', result.status);
        return { success: false, status: result.status };
      }
    } catch (error) {
      console.error('Error:', error);
      return { success: false, status: 'FAILED' };
    }
  }
  ```
</CodeGroup>

## Shopify-Theme-Sektion

Füge ein Stornierungsformular zu einer beliebigen Seite in deinem Shopify-Theme hinzu. Diese einsatzbereite Sektion verwaltet alle API-Aufrufe und zeigt passende Nachrichten an.

<Accordion title="Vollständiger Shopify-Sektions-Code" icon="code">
  ```liquid order-cancellation-form.liquid theme={null}
  <div class="order-cancel-section">
    <div class="order-cancel-container">
      <div class="order-cancel-form">
        {% if section.settings.show_heading %}
          <h2>{{ section.settings.heading }}</h2>
        {% endif %}
        
        {% if section.settings.show_description %}
          <p class="form-description">{{ section.settings.description }}</p>
        {% endif %}
        
        <form id="cancelOrderForm">
          <div class="form-group">
            <label for="orderNumber">{{ section.settings.order_label }}</label>
            <input 
              type="text" 
              id="orderNumber" 
              name="orderNumber" 
              required
              placeholder="{{ section.settings.order_placeholder }}"
            >
            <small>{{ section.settings.order_help_text }}</small>
          </div>
          
          <div class="form-group">
            <label for="email">{{ section.settings.email_label }}</label>
            <input 
              type="email" 
              id="email" 
              name="email" 
              required
              placeholder="{{ section.settings.email_placeholder }}"
            >
          </div>
          
          <button type="submit" id="submitBtn">{{ section.settings.button_text }}</button>
          <div id="message"></div>
        </form>
      </div>
    </div>
  </div>

  <script>
  document.getElementById('cancelOrderForm').addEventListener('submit', async (e) => {
    e.preventDefault();
    
    const submitBtn = document.getElementById('submitBtn');
    const messageDiv = document.getElementById('message');
    
    submitBtn.disabled = true;
    submitBtn.textContent = 'Processing...';
    messageDiv.textContent = '';
    messageDiv.className = '';
    
    const orderNumber = document.getElementById('orderNumber').value.trim();
    const email = document.getElementById('email').value.trim();
    
    const shopDomain = {{ shop.permanent_domain | json }};
    const domainSlug = shopDomain.replace('.myshopify.com', '');
    const apiUrl = {{ section.settings.api_url | json }};
    
    const statusMessages = {
      'SUCCESS': {{ section.settings.msg_success | json }},
      'ORDER_NOT_FOUND': {{ section.settings.msg_order_not_found | json }},
      'NOT_CANCELLABLE': {{ section.settings.msg_not_cancellable | json }},
      'ORDER_FULFILLED': {{ section.settings.msg_order_fulfilled | json }},
      'NOT_EDITABLE': {{ section.settings.msg_not_editable | json }},
      'CANCEL_DISABLED': {{ section.settings.msg_cancel_disabled | json }},
      'APP_INACTIVE': {{ section.settings.msg_app_inactive | json }},
      'FAILED': {{ section.settings.msg_failed | json }}
    };
    
    const buttonText = {{ section.settings.button_text | json }};
    
    try {
      const response = await fetch(`${apiUrl}/api/public/v1/${domainSlug}/cancel_order`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'Accept': 'application/json'
        },
        body: JSON.stringify({
          order_number: orderNumber,
          email: email
        })
      });
      
      const result = await response.json();
      
      if (result.success === true || result.status === 'SUCCESS') {
        messageDiv.className = 'success';
        messageDiv.textContent = statusMessages['SUCCESS'];
        document.getElementById('cancelOrderForm').reset();
      } else {
        messageDiv.className = 'error';
        messageDiv.textContent = statusMessages[result.status] || statusMessages['FAILED'];
      }
      
    } catch (error) {
      console.error('Error:', error);
      messageDiv.className = 'error';
      messageDiv.textContent = statusMessages['FAILED'];
    } finally {
      submitBtn.disabled = false;
      submitBtn.textContent = buttonText;
    }
  });
  </script>

  <style>
  .order-cancel-section {
    padding: {{ section.settings.section_padding_top }}px 0 {{ section.settings.section_padding_bottom }}px;
    background: {{ section.settings.background_color }};
  }

  .order-cancel-container {
    max-width: 1200px;
    margin: 0 auto;
    padding: 0 20px;
  }

  .order-cancel-form {
    max-width: {{ section.settings.form_width }}px;
    margin: 0 auto;
    padding: {{ section.settings.form_padding }}px;
    border: 1px solid {{ section.settings.border_color }};
    border-radius: {{ section.settings.border_radius }}px;
    background: {{ section.settings.form_background }};
  }

  .order-cancel-form h2 {
    margin-bottom: 10px;
    font-size: {{ section.settings.heading_size }}px;
    color: {{ section.settings.heading_color }};
    text-align: {{ section.settings.text_align }};
  }

  .order-cancel-form .form-description {
    margin-bottom: 24px;
    color: {{ section.settings.description_color }};
    text-align: {{ section.settings.text_align }};
  }

  .form-group {
    margin-bottom: 20px;
    text-align: left;
  }

  .form-group label {
    display: block;
    margin-bottom: 8px;
    font-weight: 600;
    font-size: 14px;
  }

  .form-group input {
    width: 100%;
    padding: 12px;
    border: 1px solid {{ section.settings.input_border_color }};
    border-radius: 4px;
    font-size: 14px;
    box-sizing: border-box;
  }

  .form-group small {
    display: block;
    margin-top: 4px;
    color: #666;
    font-size: 12px;
  }

  button {
    width: 100%;
    padding: 14px;
    background: {{ section.settings.button_background }};
    color: {{ section.settings.button_text_color }};
    border: none;
    border-radius: 4px;
    font-size: 16px;
    font-weight: 600;
    cursor: pointer;
  }

  button:disabled {
    opacity: 0.5;
    cursor: not-allowed;
  }

  #message {
    margin-top: 20px;
    padding: 12px;
    border-radius: 4px;
    text-align: center;
  }

  #message.success {
    background: #d4edda;
    color: #155724;
  }

  #message.error {
    background: #f8d7da;
    color: #721c24;
  }
  </style>

  {% schema %}
  {
    "name": "Order Cancellation Form",
    "settings": [
      {
        "type": "text",
        "id": "api_url",
        "label": "API URL",
        "default": "https://revize.untechnickle.com"
      },
      {
        "type": "text",
        "id": "heading",
        "label": "Heading",
        "default": "Cancel Your Order"
      },
      {
        "type": "textarea",
        "id": "description",
        "label": "Description",
        "default": "Enter your order number and email to cancel your order"
      },
      {
        "type": "text",
        "id": "button_text",
        "label": "Button Text",
        "default": "Cancel Order"
      },
      {
        "type": "textarea",
        "id": "msg_success",
        "label": "Success Message",
        "default": "Your order has been cancelled successfully!"
      },
      {
        "type": "textarea",
        "id": "msg_order_not_found",
        "label": "Order Not Found",
        "default": "We couldn't find an order with that number and email."
      },
      {
        "type": "textarea",
        "id": "msg_not_cancellable",
        "label": "Not Cancellable",
        "default": "This order cannot be cancelled due to our cancellation policy."
      },
      {
        "type": "textarea",
        "id": "msg_order_fulfilled",
        "label": "Order Fulfilled",
        "default": "This order has already been fulfilled and cannot be cancelled."
      },
      {
        "type": "textarea",
        "id": "msg_failed",
        "label": "General Error",
        "default": "Unable to process your request. Please try again."
      }
    ],
    "presets": [{ "name": "Order Cancellation Form" }]
  }
  {% endschema %}
  ```
</Accordion>

## Häufige Anwendungsfälle

<Tabs>
  <Tab title="Support-Seiten">
    **Self-Service-Stornierung auf FAQ-/Hilfeseiten**

    Füge das Stornierungsformular zu deinen Support- oder FAQ-Seiten hinzu, damit Kunden Bestellungen ohne Support-Kontakt stornieren können.

    * Reduziert Support-Tickets
    * 24/7 verfügbar
    * Sofortige Verarbeitung
  </Tab>

  <Tab title="Post-Purchase-E-Mails">
    **Stornieren-Button in Bestellbestätigungs-E-Mails**

    Füge in deinen transaktionalen E-Mails einen „Bestellung stornieren"-Link hinzu, der eine Stornierungsseite in deinem Store öffnet.

    * Bequem für Kunden
    * Fängt spontane Stornierungswünsche frühzeitig ab
    * Reduziert „Wie kann ich stornieren?"-Anfragen
  </Tab>

  <Tab title="Chatbots">
    **Automatisierte Stornierung per Chat**

    Integriere die API mit Chatbots (Gorgias, Zendesk etc.), um Stornierungsanfragen automatisch zu bearbeiten.

    * Sofortige Antwort
    * Kein Eingreifen eines Agenten nötig
    * Funktioniert 24/7
  </Tab>
</Tabs>

## Setup-Voraussetzungen

Die öffentliche Stornierungs-API ist eine erweiterte Funktion, die durch unser Team aktiviert werden muss.

<Steps>
  <Step title="Kontaktiere uns zur Aktivierung">
    [Wende dich an unser Team](/de/support/contact), um die öffentliche Stornierungs-API für deinen Store zu aktivieren.
  </Step>

  <Step title="Rückerstattungseinstellungen konfigurieren">
    Lege deine Rückerstattungsmethode in **Payments & Refunds** fest – ursprüngliche Zahlungsmethode oder Store Credit.
  </Step>

  <Step title="Integrationsdetails erhalten">
    Wir stellen dir deinen Shop-Domain-Slug und alle für deinen Anwendungsfall nötigen individuellen Konfigurationen zur Verfügung.
  </Step>

  <Step title="Mit Test-Bestellungen testen">
    Erstelle Testbestellungen, um zu prüfen, dass die API korrekt funktioniert, bevor du live gehst.
  </Step>
</Steps>

<Note>
  Diese Funktion ist auf Pro-Plänen verfügbar. [Kontaktiere uns](/de/support/contact) für Preise und Setup-Unterstützung.
</Note>

## Häufig gestellte Fragen

<AccordionGroup>
  <Accordion title="Beachtet die API meine Stornierungsregeln?" icon="shield">
    Ja. Die API wendet deine Bearbeitungsfenster-Einstellungen, Bestelleinschränkungen und Rückerstattungsrichtlinien automatisch an. Bestellungen außerhalb des Bearbeitungsfensters oder mit blockierenden Tags können nicht per API storniert werden.
  </Accordion>

  <Accordion title="Wie werden Rückerstattungen verarbeitet?" icon="credit-card">
    Rückerstattungen werden gemäß deinen Revize-Zahlungseinstellungen verarbeitet – entweder auf die ursprüngliche Zahlungsmethode oder als Store Credit, genau wie bei Stornierungen über das Kundenportal.
  </Accordion>

  <Accordion title="Kann ich das für Drittanbieter-Integrationen nutzen?" icon="plug">
    Absolut. Die API ist für externe Integrationen ausgelegt – Chatbots, E-Mail-Service-Provider, eigene Apps oder beliebige Systeme, die HTTP-Requests senden können.
  </Accordion>

  <Accordion title="Ist eine Authentifizierung erforderlich?" icon="key">
    Die API verwendet die Verifizierung über Bestellnummer + E-Mail zur Absicherung. Es sind keine API-Schlüssel erforderlich, was die Integration einfach macht und gleichzeitig sicherstellt, dass nur Bestellinhaber stornieren können.
  </Accordion>
</AccordionGroup>

<Note>
  Die öffentliche Stornierungs-API erweitert die Self-Service-Stornierung über das Revize-Portal hinaus. Nutze sie, um Kunden dort abzuholen, wo sie sind – in E-Mails, auf Support-Seiten oder in Chatbots.
</Note>

## Verwandte Funktionen

* [Bestellung stornieren](/de/features/cancel-order) — Standard-Self-Service-Stornierung über das Portal
* [Bestellbearbeitungs-Einschränkungen](/de/setup/order-edit-restrictions) — Steuere, welche Bestellungen storniert werden können
* [Zahlungen & Rückerstattungen](/de/setup/payments-and-refunds) — Konfiguriere die Rückerstattungs-Abwicklung
