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

# Public Cancellation API

> Add order cancellation anywhere in your Shopify store. Build cancel buttons into emails, support pages, chatbots, or custom forms using our public API endpoint.

<Note>
  The Public Cancellation API lets you add self-service order cancellation anywhere—post-purchase emails, support pages, chatbots, or custom forms. No app embed required.
</Note>

## Why use the Cancellation API

<CardGroup cols={2}>
  <Card title="Cancellation Anywhere" icon="globe" color="#8b5cf6">
    Add cancel buttons to emails, FAQ pages, chatbot flows, or any custom interface outside your store.
  </Card>

  <Card title="No App Embed Needed" icon="code" color="#10b981">
    Works independently of the Revize customer portal. Just call the API endpoint.
  </Card>

  <Card title="Your Rules Apply" icon="shield" color="#f59e0b">
    The API respects your cancellation time windows and eligibility rules automatically.
  </Card>

  <Card title="Simple Integration" icon="plug" color="#ef4444">
    One endpoint, simple request format. Easy to integrate with any system or platform.
  </Card>
</CardGroup>

## API endpoint

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

**Parameters:**

* `shop-domain-slug` — Your Shopify store's domain without `.myshopify.com` (e.g., `my-store` from `my-store.myshopify.com`)

## Request format

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

| Field          | Type   | Required | Description                                 |
| -------------- | ------ | -------- | ------------------------------------------- |
| `order_number` | string | Yes      | The order number including the # symbol     |
| `email`        | string | Yes      | Customer's email address used for the order |

## Response codes

The API returns a `status` field indicating the result:

| Status            | Description                                     |
| ----------------- | ----------------------------------------------- |
| `SUCCESS`         | Order cancelled successfully                    |
| `ORDER_NOT_FOUND` | Order doesn't exist or email doesn't match      |
| `NOT_CANCELLABLE` | Order cannot be cancelled (policy restrictions) |
| `ORDER_FULFILLED` | Order already fulfilled, cannot cancel          |
| `NOT_EDITABLE`    | Order is locked for editing                     |
| `CANCEL_DISABLED` | Cancellation feature not enabled for this store |
| `APP_INACTIVE`    | Revize app is not active                        |
| `SHOP_NOT_FOUND`  | Shop not found in system                        |
| `DOMAIN_MISSING`  | Shop domain slug missing from request           |
| `FAILED`          | General operation failure                       |

## Example integration

Here's a JavaScript example for calling the 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 section

Add a cancellation form to any page in your Shopify theme. This ready-to-use section handles all API calls and displays appropriate messages.

<Accordion title="Complete Shopify Section 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>

## Common use cases

<Tabs>
  <Tab title="Support Pages">
    **Self-service cancellation on FAQ/Help pages**

    Add the cancellation form to your support or FAQ pages so customers can cancel orders without contacting support.

    * Reduces support tickets
    * 24/7 availability
    * Instant processing
  </Tab>

  <Tab title="Post-Purchase Emails">
    **Cancel button in order confirmation emails**

    Add a "Cancel Order" link in your transactional emails that opens a cancellation page on your store.

    * Convenient for customers
    * Catches impulse cancel requests early
    * Reduces "how do I cancel?" inquiries
  </Tab>

  <Tab title="Chatbots">
    **Automated cancellation via chat**

    Integrate the API with chatbots (Gorgias, Zendesk, etc.) to handle cancellation requests automatically.

    * Instant response
    * No agent involvement needed
    * Works 24/7
  </Tab>
</Tabs>

## Setup requirements

The Public Cancellation API is an advanced feature that requires enablement by our team.

<Steps>
  <Step title="Contact us to enable">
    [Reach out to our team](/support/contact) to enable the Public Cancellation API for your store.
  </Step>

  <Step title="Configure refund settings">
    Set your refund method in **Payments & Refunds**—original payment method or store credit.
  </Step>

  <Step title="Get your integration details">
    We'll provide your shop domain slug and any custom configuration needed for your use case.
  </Step>

  <Step title="Test with draft orders">
    Create test orders to verify the API works correctly before going live.
  </Step>
</Steps>

<Note>
  This feature is available on Pro plans. [Contact us](/support/contact) for pricing and setup assistance.
</Note>

## Frequently asked questions

<AccordionGroup>
  <Accordion title="Does the API respect my cancellation rules?" icon="shield">
    Yes. The API automatically applies your edit window settings, order restrictions, and refund policies. Orders outside the edit window or with blocking tags cannot be cancelled via API.
  </Accordion>

  <Accordion title="How are refunds processed?" icon="credit-card">
    Refunds are processed according to your Revize payment settings—either to the original payment method or as store credit, exactly like cancellations through the customer portal.
  </Accordion>

  <Accordion title="Can I use this for third-party integrations?" icon="plug">
    Absolutely. The API is designed for external integrations—chatbots, email service providers, custom apps, or any system that can make HTTP requests.
  </Accordion>

  <Accordion title="Is authentication required?" icon="key">
    The API uses order number + email verification for security. No API keys are required, making integration simple while ensuring only order owners can cancel.
  </Accordion>
</AccordionGroup>

<Note>
  The Public Cancellation API extends self-service cancellation beyond the Revize portal. Use it to meet customers wherever they are—emails, support pages, or chatbots.
</Note>

## Related features

* [Cancel Order](/features/cancel-order) — standard self-service cancellation through the portal
* [Order Edit Restrictions](/setup/order-edit-restrictions) — control which orders can be cancelled
* [Payments & Refunds](/setup/payments-and-refunds) — configure refund processing
