開発者
Webhook
注文が動いたり出品が変わった瞬間にサーバーへイベントをPOSTするので、ポーリングの必要はありません。署名付きで約1日再試行し、APIのすべてのルートで同じです。
エンドポイントを設定
イベント
すべてのイベントは同じエンベロープです。data にはタイプ固有のフィールドが入ります。
idstring- evt_ で始まります。すべての再試行で同じで、webhook-idヘッダーにも入ります。
typestring- 以下のイベントのいずれか。
api_versionstring- data が書かれるバージョン:エンドポイントのもの。
created_atstring- 発生した日時。受け取る前のこともあります。
testboolean- テストイベントでは true。
dataobject- 完全なオブジェクトを取得するためのIDと、変更内容。
POST /hooks/ninjabuy HTTP/1.1
Host: acme-goods.com
Content-Type: application/json
User-Agent: NinjaBuy-Webhooks/1.0
webhook-id: evt_4m2x
webhook-timestamp: 1793685600
webhook-signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4=
{
"id": "evt_4m2x",
"type": "order.shipped",
"api_version": "2026-11",
"created_at": "2026-11-03T06:00:00Z",
"test": false,
"data": {
"order": "ord_3n7q",
"external_id": "1012",
"shipment": "shp_5r8w",
"carrier": "YunExpress",
"tracking_number": "YT2630812345678",
"tracking_url": "https://t.17track.net/en#nums=YT2630812345678",
"shipping_charged": { "amount": "134.52", "currency": "CNY" },
"pushed_to_channel": true
}
}イベント
order.created
Shopifyストアまたは API から注文が当社に届きました。paid または awaiting_payment。
{
"id": "evt_1a7c",
"type": "order.created",
"api_version": "2026-11",
"created_at": "2026-11-01T09:14:02Z",
"test": false,
"data": {
"order": "ord_3n7q",
"external_id": "1012",
"source": "shopify",
"status": "buying",
"payment_status": "paid",
"lines": [
{
"line": "lin_9a2c",
"variant": "var_41hz",
"sku": "5187209554",
"quantity": 1
}
]
}
}order.paid
注文が残高から支払われました。チャージを待っていた注文でも発生します。
{
"id": "evt_1a9f",
"type": "order.paid",
"api_version": "2026-11",
"created_at": "2026-11-01T11:02:40Z",
"test": false,
"data": {
"order": "ord_3n8a",
"external_id": "1013",
"amount": { "amount": "57.00", "currency": "CNY" },
"paid_from": "balance",
"was_awaiting_payment": true
}
}order.bought
出品者に支払いました。当社倉庫に届くまで、明細は with_seller です。
{
"id": "evt_2c4e",
"type": "order.bought",
"api_version": "2026-11",
"created_at": "2026-11-01T13:30:05Z",
"test": false,
"data": {
"order": "ord_3n7q",
"external_id": "1012",
"lines": [
{
"line": "lin_9a2c",
"sku": "5187209554",
"quantity": 1,
"status": "with_seller"
}
]
}
}order.checked
商品は当社倉庫にあり、写真付きで検品済みです。次は梱包です。
{
"id": "evt_9w1c",
"type": "order.checked",
"api_version": "2026-11",
"created_at": "2026-11-02T03:20:11Z",
"test": false,
"data": {
"order": "ord_3n7q",
"external_id": "1012",
"fulfillment_order": "fo_7k2m",
"lines": [
{
"line": "lin_9a2c",
"qc": "passed",
"photos": [
"https://media.ninjabuy.com/qc/ord_3n7q/1.webp",
"https://media.ninjabuy.com/qc/ord_3n7q/2.webp"
]
}
]
}
}order.shipped
荷物が追跡番号付きで出荷され、送料が確定しました。注文元のストアにも追跡情報があります。
{
"id": "evt_4m2x",
"type": "order.shipped",
"api_version": "2026-11",
"created_at": "2026-11-03T06:00:00Z",
"test": false,
"data": {
"order": "ord_3n7q",
"external_id": "1012",
"shipment": "shp_5r8w",
"carrier": "YunExpress",
"tracking_number": "YT2630812345678",
"tracking_url": "https://t.17track.net/en#nums=YT2630812345678",
"shipping_charged": { "amount": "134.52", "currency": "CNY" },
"pushed_to_channel": true
}
}product.cost_changed
出品者が価格を変更し、同期ルールが行った対応:価格変更、一時停止、通知。
{
"id": "evt_8q0d",
"type": "product.cost_changed",
"api_version": "2026-11",
"created_at": "2026-11-04T02:10:00Z",
"test": false,
"data": {
"product": "prd_1x0a",
"variant": "var_2b7k",
"sku": "4410923871",
"cost": {
"from": { "amount": "42.00", "currency": "CNY" },
"to": { "amount": "48.00", "currency": "CNY" }
},
"action": "repriced",
"price": {
"from": { "amount": "18.99", "currency": "USD" },
"to": { "amount": "20.99", "currency": "USD" }
},
"rule": "rule_default"
}
}product.out_of_stock
出品者のバリエーションが売り切れ、あなたの棚にもありません:チャンネルで0に設定しました。
{
"id": "evt_2b9n",
"type": "product.out_of_stock",
"api_version": "2026-11",
"created_at": "2026-11-04T02:11:30Z",
"test": false,
"data": {
"product": "prd_8f2k",
"variant": "var_41j0",
"sku": "5187209555",
"warehouse_on_hand": 0,
"channels_updated": [
{
"channel": "shopify",
"shop": "acme-goods.myshopify.com",
"available": 0
}
]
}
}qc.issue
検品で商品に問題が見つかりました:色やサイズの違い、損傷、部品の欠品。respond_by までに選択してください。応答がなければ保留し、ご連絡します。
{
"id": "evt_6c3h",
"type": "qc.issue",
"api_version": "2026-11",
"created_at": "2026-11-02T03:20:11Z",
"test": false,
"data": {
"order": "ord_3n7q",
"external_id": "1012",
"fulfillment_order": "fo_7k2m",
"line": "lin_9a2c",
"sku": "5187209554",
"issue": "wrong_color",
"note": "Received grey, ordered black.",
"photos": ["https://media.ninjabuy.com/qc/ord_3n7q/3.webp"],
"choices": ["ship_anyway", "exchange", "refund"],
"respond_by": "2026-11-05T03:20:11Z"
}
}署名
配信はStandard Webhooks方式で署名されるので、すでにお使いのライブラリで検証できます。すべての配信に3つのヘッダーが付きます:
| ヘッダー | 保持するもの |
|---|---|
| webhook-id | イベントID。 |
| webhook-timestamp | この試行を送信した日時(Unix秒)。 |
| webhook-signature | v1、カンマ、そしてシークレットで計算した id.timestamp.body の base64 HMAC-SHA256。ローテーション中はスペース区切りで2つ。 |
キーはwhsec_の後のシークレットをbase64デコードしたものです。届いたままの生のボディに署名し、5分以上ずれたタイムスタンプは拒否してください。傍受したリクエストを再送されないようにするためです。
配信を検証
standardwebhooksライブラリで、または数行の自作コードで:
再試行と順序
10秒以内に2xx以外が返ると失敗とみなし、再試行します。毎回同じwebhook-idで、新しいタイムスタンプと署名を付けます:
| 試行 | 前の試行の後 |
|---|---|
| 1 | すぐに |
| 2 | 5秒 |
| 3 | 5分 |
| 4 | 30分 |
| 5 | 2時間 |
| 6 | 5時間 |
| 7 | 10時間 |
| 8 | 10時間(最後) |
- 最後の試行の後、配信は失敗になります。配信リストから再送してください。
- 5日間すべての配信が失敗したエンドポイントは、メールでお知らせした後に無効化されます。再度有効にすると、直近3日間に届かなかったものを送信します。
- イベントは重複したり順不同で届くことがあります。idで重複を除き、順序が重要な場合はオブジェクトを取得して、イベントではなくそのステータスを信頼してください。