> ## 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.

# API pública de cancelación

> Agrega cancelación de pedidos en cualquier lugar de tu tienda Shopify. Construye botones de cancelación en correos, páginas de soporte, chatbots o formularios personalizados usando nuestro endpoint de API público.

<Note>
  La API pública de cancelación te permite agregar cancelación de pedidos en autoservicio en cualquier lugar: correos posteriores a la compra, páginas de soporte, chatbots o formularios personalizados. No se requiere app embed.
</Note>

## Por qué usar la API de cancelación

<CardGroup cols={2}>
  <Card title="Cancelación en cualquier lugar" icon="globe" color="#8b5cf6">
    Agrega botones de cancelación a correos, páginas de FAQ, flujos de chatbot o cualquier interfaz personalizada fuera de tu tienda.
  </Card>

  <Card title="Sin necesidad de app embed" icon="code" color="#10b981">
    Funciona independientemente del portal del cliente de Revize. Solo llama al endpoint de la API.
  </Card>

  <Card title="Tus reglas se aplican" icon="shield" color="#f59e0b">
    La API respeta automáticamente tus ventanas de tiempo de cancelación y reglas de elegibilidad.
  </Card>

  <Card title="Integración simple" icon="plug" color="#ef4444">
    Un endpoint, formato de solicitud simple. Fácil de integrar con cualquier sistema o plataforma.
  </Card>
</CardGroup>

## Endpoint de la API

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

**Parámetros:**

* `shop-domain-slug` — El dominio de tu tienda Shopify sin `.myshopify.com` (p. ej., `my-store` de `my-store.myshopify.com`)

## Formato de solicitud

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

| Campo          | Tipo   | Requerido | Descripción                                          |
| -------------- | ------ | --------- | ---------------------------------------------------- |
| `order_number` | string | Sí        | El número de pedido incluyendo el símbolo #          |
| `email`        | string | Sí        | Dirección de correo del cliente usada para el pedido |

## Códigos de respuesta

La API devuelve un campo `status` indicando el resultado:

| Estado            | Descripción                                                   |
| ----------------- | ------------------------------------------------------------- |
| `SUCCESS`         | Pedido cancelado exitosamente                                 |
| `ORDER_NOT_FOUND` | El pedido no existe o el correo no coincide                   |
| `NOT_CANCELLABLE` | El pedido no puede cancelarse (restricciones de política)     |
| `ORDER_FULFILLED` | El pedido ya fue cumplido, no puede cancelarse                |
| `NOT_EDITABLE`    | El pedido está bloqueado para edición                         |
| `CANCEL_DISABLED` | La función de cancelación no está habilitada para esta tienda |
| `APP_INACTIVE`    | La app Revize no está activa                                  |
| `SHOP_NOT_FOUND`  | Tienda no encontrada en el sistema                            |
| `DOMAIN_MISSING`  | Falta el slug del dominio de la tienda en la solicitud        |
| `FAILED`          | Error general de operación                                    |

## Ejemplo de integración

Aquí tienes un ejemplo de JavaScript para llamar a la 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>

## Sección de tema de Shopify

Agrega un formulario de cancelación a cualquier página en tu tema de Shopify. Esta sección lista para usar maneja todas las llamadas a la API y muestra mensajes apropiados.

<Accordion title="Código completo de sección de Shopify" 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>

## Casos de uso comunes

<Tabs>
  <Tab title="Páginas de soporte">
    **Cancelación en autoservicio en páginas de FAQ/Ayuda**

    Agrega el formulario de cancelación a tus páginas de soporte o FAQ para que los clientes puedan cancelar pedidos sin contactar a soporte.

    * Reduce los tickets de soporte
    * Disponibilidad 24/7
    * Procesamiento instantáneo
  </Tab>

  <Tab title="Correos posteriores a la compra">
    **Botón de cancelación en correos de confirmación de pedido**

    Agrega un enlace "Cancelar pedido" en tus correos transaccionales que abra una página de cancelación en tu tienda.

    * Conveniente para los clientes
    * Captura solicitudes de cancelación impulsivas temprano
    * Reduce las consultas de "¿cómo cancelo?"
  </Tab>

  <Tab title="Chatbots">
    **Cancelación automatizada vía chat**

    Integra la API con chatbots (Gorgias, Zendesk, etc.) para manejar solicitudes de cancelación automáticamente.

    * Respuesta instantánea
    * No se necesita intervención de agente
    * Funciona 24/7
  </Tab>
</Tabs>

## Requisitos de configuración

La API pública de cancelación es una función avanzada que requiere habilitación por parte de nuestro equipo.

<Steps>
  <Step title="Contáctanos para habilitar">
    [Contacta a nuestro equipo](/es/support/contact) para habilitar la API pública de cancelación para tu tienda.
  </Step>

  <Step title="Configurar ajustes de reembolso">
    Establece tu método de reembolso en **Pagos & Reembolsos**: método de pago original o crédito de tienda.
  </Step>

  <Step title="Obtén tus detalles de integración">
    Te proporcionaremos tu slug de dominio de tienda y cualquier configuración personalizada necesaria para tu caso de uso.
  </Step>

  <Step title="Prueba con pedidos borrador">
    Crea pedidos de prueba para verificar que la API funcione correctamente antes de salir en vivo.
  </Step>
</Steps>

<Note>
  Esta función está disponible en los planes Pro. [Contáctanos](/es/support/contact) para precios y asistencia de configuración.
</Note>

## Preguntas frecuentes

<AccordionGroup>
  <Accordion title="¿La API respeta mis reglas de cancelación?" icon="shield">
    Sí. La API aplica automáticamente la configuración de tu ventana de edición, las restricciones de pedido y las políticas de reembolso. Los pedidos fuera de la ventana de edición o con etiquetas de bloqueo no se pueden cancelar vía API.
  </Accordion>

  <Accordion title="¿Cómo se procesan los reembolsos?" icon="credit-card">
    Los reembolsos se procesan según tu configuración de pagos de Revize, ya sea al método de pago original o como crédito de tienda, exactamente como las cancelaciones a través del portal del cliente.
  </Accordion>

  <Accordion title="¿Puedo usar esto para integraciones de terceros?" icon="plug">
    Absolutamente. La API está diseñada para integraciones externas: chatbots, proveedores de servicios de correo, apps personalizadas o cualquier sistema que pueda hacer solicitudes HTTP.
  </Accordion>

  <Accordion title="¿Se requiere autenticación?" icon="key">
    La API usa verificación por número de pedido + correo electrónico para seguridad. No se requieren claves API, lo que hace que la integración sea simple mientras se asegura que solo los propietarios del pedido puedan cancelar.
  </Accordion>
</AccordionGroup>

<Note>
  La API pública de cancelación extiende la cancelación en autoservicio más allá del portal de Revize. Úsala para encontrarte con los clientes donde estén: correos, páginas de soporte o chatbots.
</Note>

## Funciones relacionadas

* [Cancelar pedido](/es/features/cancel-order) — cancelación estándar en autoservicio a través del portal
* [Restricciones de edición de pedidos](/es/setup/order-edit-restrictions) — controla qué pedidos se pueden cancelar
* [Pagos & Reembolsos](/es/setup/payments-and-refunds) — configura el procesamiento de reembolsos
