Kanorioでは、注文の支払い、配送状況の更新、フォームの送信、送信ドメインの問題、クォータのアラート、トラフィックの節目など、サイトで特定のイベントが発生した際に、リアルタイムでシステムに通知を送ることができます。Zapier、Make、n8n、または独自のカスタムコードと連携することで、スプレッドシートへのデータ書き込み、チームチャットへの通知転送、サポートチケットの作成、ERPやCRMとの同期などを自動化できます。
設定は、サイトコンソールの「技術設定」セクションにある「連携」タブで行います。Webhookはビジネスプランの機能であり、サイトの所有者と管理者のみが追加・管理できます。その他のメンバーは、URL、シークレットキー、配信ログを閲覧することはできません。
サイトごとに最大5つまでWebhookを追加できます。
各エンドポイントを展開すると、「購読イベント」を設定できます。
現在サポートされているイベント(フィールドの詳細は末尾の「イベントリファレンス」を参照):
| イベント | トリガー | イベントコード |
|---|---|---|
| 注文支払い完了 | 購入者が支払いを完了したとき | ec.order.paid |
| 配送状況更新 | 荷物が発送、店舗到着、配達完了、または例外が発生したとき | ec.shipment.statusChanged |
| フォーム送信 | 訪問者がフォームを送信したとき(質問と回答を含む) | customers.form.submitted |
| 送信ドメイン劣化 | 送信ドメインの認証に失敗したとき | customers.sendingDomain.degraded |
| メッセージングクォータ警告 | クォータの枯渇、自動チャージ、上限到達、支払い失敗時 | customers.messagingQuota.alert |
Webhookの配信は、これらの購読設定のみに依存します。内の各シナリオパネルに「N個のエンドポイントが購読中」や「未接続」と表示されることがありますが、実際の制御は自動化ではなくここで行われます。
Webhookは通知メールの代わりにはなりません。Webhookを追加した後も、所有者宛の通知メール(新しい注文やフォーム送信など)は引き続き送信されます。配送状況更新のチーム向けメールはデフォルトで無効になっています。チーム向けメールを切り替えるには、「自動化」で設定してください。
エンドポイントを展開すると「最近の配信」を確認できます:イベント、結果、HTTPステータス、時刻。各エントリを展開すると、試行回数、レイテンシ、次回の再試行時刻、エラー理由が表示されます。過去7日以内の通知は「表示」してペイロードを確認したり、「再送信」して再度試行したりできます。再送信では同じ配信IDが使用されるため、受信側で重複排除が可能です。
「テスト送信」は失敗制限回数にはカウントされませんので、トラブルシューティングに活用してください。
Kanorioは固定IPからWebhookを送信します。受信側でホワイトリストによる制限を行っている場合は、以下の3つのIPv4アドレスすべてを追加してください(初期配信、テスト、手動再送信は最初の2つから、自動再試行は3つ目から送信されます)。
| 目的 | IP |
|---|---|
| 初期配信、テスト、手動再送信 | <MAIN_EGRESS_IP_1> |
| 初期配信、テスト、手動再送信 | <MAIN_EGRESS_IP_2> |
| 自動再試行 | 168.144.105.51 |
ホワイトリスト登録は保護を強化するものであり、署名検証の代わりにはなりません。必ず X-Kanorio-Signature を検証してください(後述の「エンジニア向け」を参照)。IPアドレスが変更される場合は、ここで告知を行い、一定期間は新旧両方のIPを稼働させます。
いいえ。WebhookはKanorio経由でメールを送信しないため、メールクォータにはカウントされません。
エンドポイントへの配信は一時停止されます。設定とキーは保持され、リストには「プラン上限超過」と表示されます。ビジネスプランにアップグレードすると直ちに再開されます。
受信側の応答が遅い、またはエラーが発生した場合にKanorioが再試行を行うためです。手動で再送信した場合も同様です。X-Kanorio-Delivery(またはJSON内の id)を使用して、すでに処理済みかどうかを判断してください。
現在はZapierやMake経由で転送できます。WebhookでKanorioの通知を受け取り、それをSlackチャンネルやLINEに送信してください。
Webhookは注文やフォームのデータをKanorio外部のシステムに送信するため、URLや署名シークレットは所有者と管理者のみが閲覧可能です。その他のメンバーはエンドポイント名とステータスのみを確認できます。
個別のサンドボックスはありません。「テスト送信」を使用して接続を確認し、「コンテンツを表示」で実際のイベントペイロードを確認してください。開発中は、webhook.siteのようなサービスにエンドポイントを向けて形式を確認できます。
各通知は Content-Type: application/json を持つ POST リクエストで、以下のヘッダーが含まれます。
| ヘッダー | 内容 |
|---|---|
X-Kanorio-Event |
| トラフィックの節目 | 累計サイト閲覧数が100または500を超えたとき | site.analytics.milestone |
| 連携の一時停止 | 連続した失敗によりWebhookが一時停止されたとき(そのエンドポイントには送信されません) | customers.teamDestination.disabled |
| テストイベント | 「テスト送信」がクリックされたとき | team.test |
イベントコード(JSONの event と同じ) |
X-Kanorio-Delivery | 配信ID(JSONの id と同じ。再試行や再送信でも変更されません) |
X-Kanorio-Signature | 署名(形式 t=timestamp,v1=signature。キーローテーション中は2つの v1 値が存在する場合があります) |
User-Agent | Kanorio-Notifications/1.0 |
受信側からの2xx応答は成功とみなされ、レスポンスボディは無視されます。8秒以内に応答してください。処理に時間がかかる場合は、まず200を返し、非同期で処理を行ってください。Kanorioはリダイレクトに従わないため、3xx応答は失敗として扱われます。
すべてのイベントJSONは共通のシェルを共有しているため、受信側の設定は一度で済みます。
{ "version": "1", "id": "3f9c2a…", "event": "ec.order.paid", "occurredAt": "2026-09-29T12:00:00.000Z", "websiteId": "cmk…", "title": "New order #1024, NT$1,280", "summary": "'My Store' received a paid order.", "fields": [{ "label": "Order ID", "value": "#1024" }], "data": { "…": "Varies by event, see reference below" }, "actionUrl": "https://app.kanorio.com/store/transactions?tx=…" }
| フィールド | 型 | 説明 |
|---|---|---|
version | string | 現在は "1"。フィールドの追加ではバージョンは変わりませんが、削除や名前変更はバージョンアップをトリガーし、ここで告知されます |
id | string | 配信ID(32文字)。X-Kanorio-Delivery と同じ。再試行/再送信でも変更されません。重複排除に使用してください |
event | string | イベントコード(上記の表を参照) |
occurredAt | string | イベント発生時刻(ISO 8601, UTC) |
websiteId | string | サイトID。エンドポイントは作成元のサイトのイベントのみを受信します |
title, summary | string | チャット転送用に最適化された、サイト言語にローカライズされたタイトルと要約 |
fields | array | 人間が読みやすい詳細(注文ID、金額、フォーム回答)の { label, value } 配列。ラベルはサイト言語により変わるため、プログラムロジックには data を使用してください |
data | object | 言語非依存の生イベントデータ。イベントごとのフィールドは以下を参照 |
actionUrl | string | null | このデータを表示するためのKanorioダッシュボードへのリンク |
以下は各イベントの data フィールドです。「Nullable」はフィールドが null になる可能性があることを示します。
ec.order.paid 注文支払い完了購入者が支払いを完了した際に送信されます(注文ごとに1回)。
| フィールド | 型 | Nullable | 説明 |
|---|---|---|---|
orderId | string | 注文ID(ダッシュボードURLの ?tx= と同じ) | |
orderNumber | number | ✓ | 人間が読みやすい注文番号(例:1024)。非常に古い注文には存在しない場合があります |
amount | number | 合計支払額(商品+送料)。通貨の最小単位(ISO 4217)で表記:NT$1,280は 128000、US$12.80は 1280、JPY ¥1,280は 1280。表示額に変換するには、通貨の小数点以下の桁数分だけ10で割ってください | |
currency | string | ISO 4217大文字(例:TWD, USD) | |
itemCount | number | 商品数 | |
customerName | string | ✓ | 購入者名 |
customerEmail | string | ✓ | 購入者メールアドレス |
ec.shipment.statusChanged 配送状況更新発送、到着、配達完了、または例外ステータスになった際に送信されます(配送ごとにステータス変更ごとに1回)。
| フィールド | 型 | Nullable | 説明 |
|---|---|---|---|
orderId | string | 注文ID | |
orderNumber | number | ✓ | 注文番号 |
shipmentId | string | 配送ID。1つの注文に複数の配送が含まれる場合があります | |
status | string | IN_TRANSIT(発送)、AT_STORE(到着)、DELIVERED(配達完了)、EXCEPTION(例外) | |
carrier | string | 物流サービスコード(例:PAYUNI_LOGISTICS, MANUAL) | |
trackingNumber | string | ✓ | 追跡番号 |
storeName | string | ✓ | コンビニ名(宅配の場合は null) |
customers.form.submitted フォーム送信訪問者がフォームを送信し、スパムチェックを通過した際に送信されます(送信ごとに1回)。
| フィールド | 型 | Nullable | 説明 |
|---|---|---|---|
formId | string | フォームID | |
formName | string | フォーム名 | |
submissionId | string | 送信ID | |
submitter | object | { name, email, phone }。各Nullable。フォームフィールドから自動識別されます | |
answers | array | 質問ごとのオブジェクト配列(以下の表を参照) |
answers[] アイテム:
| フィールド | 型 | 説明 |
|---|---|---|
fieldId | string | 質問ID(フォームごとに固定)。label の代わりに使用してください |
type | string | 型:short_text, long_text, email, phone, name, choice, date, time, rating, file |
label | string | 質問文 |
value | string | string[] | number | null | 回答データ。単一選択は文字列、複数選択は文字列配列、評価は数値、日付/時刻は文字列(YYYY-MM-DD, HH:mm)、ファイルはファイルID。空の場合は null |
display | string | 人間が読みやすい文字列(fields と同じ)。ファイル質問の場合はファイル名 |
customers.sendingDomain.degraded 送信ドメイン劣化認証済みのカスタム送信ドメインの認証が失敗した際に送信されます(ドメインごとに1日1回)。
| フィールド | 型 | 説明 |
|---|---|---|
domain | string | 劣化が発生したドメイン |
customers.messagingQuota.alert メッセージングクォータ警告クォータステータスが変更された際に送信されます。
| フィールド | 型 | 説明 |
|---|---|---|
reason | string | exhausted, auto_upgraded, auto_upgrade_limit, payment_failed |
quota | number | 現在の期間のクォータ |
levels | number | 現在の自動アップグレードレベル |
periodStart | string | 期間開始時刻(ISO 8601) |
site.analytics.milestone トラフィックの節目累計サイト閲覧数が節目を超えた際に送信されます(節目ごとに1回)。
| フィールド | 型 | 説明 |
|---|---|---|
milestone | number | 100 または 500 |
customers.teamDestination.disabled 連携の一時停止Webhookエンドポイントが自動的に一時停止された際に送信されます(連続失敗または410応答)。他の正常なエンドポイントにのみ送信されます。
| フィールド | 型 | 説明 |
|---|---|---|
destinationId | string | 一時停止されたエンドポイントID |
failures | number | 連続失敗回数 |
lastError | string | 最後のエラー(例:HTTP 503, タイムアウト) |
team.test テストイベント「テスト送信」がクリックされた際に送信されます(1回のみ、再試行なし、配信履歴に記録されません)。
検証手順:
X-Kanorio-Signature から t とすべての v1 を抽出します。t、ピリオド、リクエストボディ(未パース、再シリアライズされた生データ) を連結します(例:1790000000.{"version":"1",…})。v1 と比較します。一致した場合のみ受け入れます。Node.jsの例:
import { createHmac, timingSafeEqual } from "node:crypto"; function verify(rawBody, header, secret) { const parts = header.split(",").map((part) => part.split("=")); const t = parts.find(([key]) => key === "t")?.[1]; const signatures = parts.filter(([key]) => key === "v1").map(([, value]) => value); if (!t || Math.abs(Date.now() / 1000 - Number(t)) > 300) return false; const expected = createHmac("sha256", secret).update(`${t}.${rawBody}`).digest("hex"); return signatures.some( (v1) => v1.length === expected.length && timingSafeEqual(Buffer.from(expected), Buffer.from(v1)) ); }
Zapier、Make、n8nなどのサービスは通常カスタム検証ロジックをサポートしていませんが、受信URLにランダムなパスが含まれるため、一般的に検証は不要です。
シークレットは、統合リストのエンドポイントを展開し「表示」をクリックすることで確認できます。漏洩が疑われる場合は「新しいシークレットを生成」をクリックしてください:
v1)が含まれ、どちらかが一致すれば成功となります。