Webhooks
Updated:
ポーリングの代わりに、HTTPSエンドポイントで注文に関するイベントを受信できます。Webhookは、イベントの順序。イベントログはWebhookの有無にかかわらず利用可能であるため、いつでもポーリングに切り替えることができます。
設定
応答には以下が返されます
webhook_secret(whsec_…) を一度実行します。これを保存してください:これにより、すべてのウェブフックに署名が行われます。変更
callback_url新しいシークレットを発行します。以前のシークレットは24時間、Webhookへの署名を継続します。この間、X-PS-Signature2つの署名があります。
依頼内容
プロパティ | 価値 |
|---|---|
方法 |
|
見出し |
|
本文 | 例えば、次のようなイベント:イベントの順序; |
成功 | 任意 |
納品 | 少なくとも1回、順序は保証されません。重複を排除するには、 |
POST /hooks/proxy HTTP/1.1
Host: agent.example.com
Content-Type: application/json; charset=utf-8
User-Agent: ProxySeller-Webhooks/1
X-PS-Timestamp: 1762077838
X-PS-Signature: v1=5f0c2a…9e
{"event_id":"evt_01JZ8QA2C4E6G8J0K2M4P6R8T0","type":"order.active","created_at":"2026-11-02T10:03:58Z","api_version":"v1","order_id":"ord_01JZ8Q7K5N2R4T6V8X0Z2B4D6F","wallet":"0x857b06519e91e3a54538791bdbb0e22373e36b66","attempt":1,"data":{"lines":[{"line_id":"1","status":"active","delivered":2,"qty":2}],"expires_at":"2026-12-02T23:59:59Z"}}署名の確認
X-PS-Signature: v1=hex(HMAC-SHA256(key, timestamp + "." + raw_body))
key— 全体(UTF-8)のバイト数webhook_secretstring、以下を含むwhsec_接頭辞。timestamp— の価値X-PS-Timestamp、Unix秒。raw_body— JSONの解析を行う前の、受け取ったままの本文。秘密の変更が行われてから24時間の間、ヘッダーは
v1=<current>,v1=<previous>: いずれかに一致する場合は、リクエストを受け入れてください。タイムスタンプがあなたの時計と300秒以上ずれているリクエストは却下してください。
Python
import hashlib
import hmac
import time
def verify(secret: str, timestamp: str, signature_header: str, raw_body: bytes, tolerance: int = 300) -> bool:
if abs(time.time() - int(timestamp)) > tolerance:
return False
expected = hmac.new(secret.encode(), timestamp.encode() + b"." + raw_body, hashlib.sha256).hexdigest()
candidates = [part.strip()[3:] for part in signature_header.split(",") if part.strip().startswith("v1=")]
return any(hmac.compare_digest(expected, candidate) for candidate in candidates)Node.js
import crypto from 'node:crypto';
function verify(secret, timestamp, signatureHeader, rawBody, toleranceSeconds = 300) {
if (Math.abs(Date.now() / 1000 - Number(timestamp)) > toleranceSeconds) return false;
const expected = crypto.createHmac('sha256', secret).update(`${timestamp}.`).update(rawBody).digest('hex');
return signatureHeader.split(',').map((s) => s.trim()).filter((s) => s.startsWith('v1='))
.some((s) => s.length === expected.length + 3
&& crypto.timingSafeEqual(Buffer.from(s.slice(3)), Buffer.from(expected)));
}再試行
ルール | 価値 |
|---|---|
最初の試作 | イベント発生から30秒以上経過した後 |
再試行 | 1分後、5分後、30分後、2時間後、6時間後、12時間後、24時間後:約44.6時間で8回の試行 |
古すぎる | 約45.6時間以上経過したイベントは送信されません |
サーキットブレーカー | 3回連続で失敗すると、そのオーダーの残りのイベントは次の挑戦まで待機状態になります。 |
無効化 | イベントの最後の試行が失敗し、かつそのイベントが作成されて以来、URLがWebhookを一切受け付けていない場合、そのURLへの配信は無効化されます。注文自体には影響はありません。 |
無効になっているURLを有効にするには、以下の形式で再度送信してください。更新順序: 同じURLは1時間に1回まで、新しいURLはいつでも可能です。見逃したイベントは常にイベントの順序.
callback_url のルール
見積書の発行時およびPATCH。これに違反した場合は、400 invalid_request:
ルール | 詳細 |
|---|---|
印刷可能なASCII形式、最大2048文字 |
|
|
|
URLにはログインIDやパスワードを含めないでください |
|
断片なし |
|
ポート443のみ |
|
パブリックDNS名、正規のIPv4アドレス、または括弧で囲まれたIPv6アドレス |
|
ホストのすべてのアドレスはパブリックです |
|
サービス自体のホストではありません |
|
配信のたびにDNSが再確認され、リクエストは確認済みのアドレスにのみ送信されます。