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

> Shopifyストア内のどこにでも注文キャンセル機能を追加できます。当社の公開APIエンドポイントを使って、メール、サポートページ、チャットボット、カスタムフォームにキャンセルボタンを組み込みます。

<Note>
  公開キャンセルAPIを使うと、購入後メール、サポートページ、チャットボット、カスタムフォームなど、どこにでもセルフサービスの注文キャンセルを追加できます。アプリの埋め込みは不要です。
</Note>

## キャンセルAPIを使う理由

<CardGroup cols={2}>
  <Card title="どこからでもキャンセル" icon="globe" color="#8b5cf6">
    メール、FAQページ、チャットボットフロー、ストア外のあらゆるカスタムインターフェースにキャンセルボタンを追加できます。
  </Card>

  <Card title="アプリ埋め込み不要" icon="code" color="#10b981">
    Revize顧客ポータルとは独立して動作します。APIエンドポイントを呼び出すだけです。
  </Card>

  <Card title="あなたのルールが適用" icon="shield" color="#f59e0b">
    APIはキャンセル時間枠と適格性ルールを自動的に尊重します。
  </Card>

  <Card title="シンプルな統合" icon="plug" color="#ef4444">
    1つのエンドポイント、シンプルなリクエスト形式。あらゆるシステムやプラットフォームと簡単に統合できます。
  </Card>
</CardGroup>

## APIエンドポイント

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

**パラメータ：**

* `shop-domain-slug` — Shopifyストアのドメインから`.myshopify.com`を除いた部分（例：`my-store.myshopify.com`の場合は`my-store`）

## リクエスト形式

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

| フィールド          | 型      | 必須 | 説明                  |
| -------------- | ------ | -- | ------------------- |
| `order_number` | string | はい | #記号を含む注文番号          |
| `email`        | string | はい | 注文に使用されたお客様のメールアドレス |

## レスポンスコード

APIは結果を示す`status`フィールドを返します。

| Status            | 説明                          |
| ----------------- | --------------------------- |
| `SUCCESS`         | 注文が正常にキャンセルされました            |
| `ORDER_NOT_FOUND` | 注文が存在しないか、メールが一致しません        |
| `NOT_CANCELLABLE` | 注文をキャンセルできません（ポリシー制限）       |
| `ORDER_FULFILLED` | 注文はすでにフルフィルメント済みでキャンセルできません |
| `NOT_EDITABLE`    | 注文の編集がロックされています             |
| `CANCEL_DISABLED` | このストアでキャンセル機能が有効になっていません    |
| `APP_INACTIVE`    | Revizeアプリがアクティブではありません      |
| `SHOP_NOT_FOUND`  | ストアがシステム内で見つかりません           |
| `DOMAIN_MISSING`  | リクエストにストアドメインスラグがありません      |
| `FAILED`          | 一般的な操作の失敗                   |

## 統合の例

APIを呼び出すJavaScriptの例です。

<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テーマセクション

Shopifyテーマの任意のページにキャンセルフォームを追加できます。すぐに使えるこのセクションは、すべてのAPI呼び出しを処理し、適切なメッセージを表示します。

<Accordion title="完全な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>

## よくあるユースケース

<Tabs>
  <Tab title="サポートページ">
    **FAQ／ヘルプページでのセルフサービスキャンセル**

    サポートやFAQページにキャンセルフォームを追加し、お客様がサポートに連絡せずに注文をキャンセルできるようにします。

    * サポートチケットを削減
    * 24時間365日利用可能
    * 即時処理
  </Tab>

  <Tab title="購入後メール">
    **注文確認メールのキャンセルボタン**

    トランザクションメールに「Cancel Order」リンクを追加し、ストアのキャンセルページを開くようにします。

    * お客様にとって便利
    * 衝動的なキャンセルリクエストを早期に捉える
    * 「どうやってキャンセルする？」という問い合わせを削減
  </Tab>

  <Tab title="チャットボット">
    **チャット経由の自動キャンセル**

    APIをチャットボット（Gorgias、Zendeskなど）と統合し、キャンセルリクエストを自動処理します。

    * 即時応答
    * エージェントの介入不要
    * 24時間365日動作
  </Tab>
</Tabs>

## セットアップ要件

公開キャンセルAPIは、当社チームによる有効化が必要な高度な機能です。

<Steps>
  <Step title="有効化のためにお問い合わせ">
    [当社チームにご連絡](/ja/support/contact)いただき、ストアの公開キャンセルAPIを有効化します。
  </Step>

  <Step title="返金設定の構成">
    **Payments & Refunds**で返金方法（元の支払い方法またはストアクレジット）を設定します。
  </Step>

  <Step title="統合詳細の取得">
    ユースケースに必要なストアドメインスラグとカスタム設定を提供します。
  </Step>

  <Step title="下書き注文でテスト">
    本番運用前にテスト注文を作成して、APIが正しく動作することを確認します。
  </Step>
</Steps>

<Note>
  この機能はProプランで利用可能です。価格やセットアップサポートについては[お問い合わせ](/ja/support/contact)ください。
</Note>

## よくある質問

<AccordionGroup>
  <Accordion title="APIは私のキャンセルルールを尊重しますか？" icon="shield">
    はい。APIは編集ウィンドウ設定、注文制限、返金ポリシーを自動的に適用します。編集ウィンドウ外の注文やブロックタグ付き注文はAPI経由でキャンセルできません。
  </Accordion>

  <Accordion title="返金はどう処理されますか？" icon="credit-card">
    返金はRevizeの支払い設定に従って、元の支払い方法またはストアクレジットとして処理されます。これは顧客ポータル経由のキャンセルと同じです。
  </Accordion>

  <Accordion title="サードパーティ統合に使用できますか？" icon="plug">
    もちろんです。APIは外部統合用に設計されています。チャットボット、メール配信サービス、カスタムアプリ、HTTPリクエストを行えるあらゆるシステムで利用できます。
  </Accordion>

  <Accordion title="認証は必要ですか？" icon="key">
    APIはセキュリティのため、注文番号 + メールの確認を使用します。APIキーは不要で、統合がシンプルでありながら、注文の所有者だけがキャンセルできるようにします。
  </Accordion>
</AccordionGroup>

<Note>
  公開キャンセルAPIは、Revizeポータルを超えてセルフサービスキャンセルを拡張します。メール、サポートページ、チャットボットなど、お客様がいる場所で対応するために使用しましょう。
</Note>

## 関連機能

* [注文のキャンセル](/ja/features/cancel-order) — ポータル経由の標準セルフサービスキャンセル
* [注文編集の制限](/ja/setup/order-edit-restrictions) — どの注文をキャンセル可能にするかを制御
* [支払いと返金](/ja/setup/payments-and-refunds) — 返金処理を設定
