Proxy-seller

웹훅

Updated:

폴링 대신, HTTPS 엔드포인트에서 주문 관련 이벤트를 수신할 수 있습니다. 웹훅은 다음과 동일한 이벤트를 전달합니다. 순서별 이벤트. 이벤트 로그는 웹훅 유무와 관계없이 계속 사용할 수 있으므로, 언제든지 폴링 방식으로 대체할 수 있습니다.

설정

  • 통과 callback_url in 주문하기, 또는 나중에 다음을 사용하여 설정하십시오. 업데이트 순서.

  • 응답 내용은 다음과 같습니다. webhook_secret (whsec_…) 한 번만. 이를 저장해 두세요: 모든 웹훅에 서명하는 데 사용됩니다.

  • 변경 callback_url 새로운 비밀번호를 발급합니다. 이전 비밀번호는 24시간 동안 웹훅 서명에 계속 사용됩니다. 이 기간 동안 X-PS-Signature 서명이 두 개 있습니다.

요청

속성

가치

방법

POST to callback_url

제목

Content-Type: application/json; charset=utf-8, User-Agent: ProxySeller-Webhooks/1, X-PS-Timestamp, X-PS-Signature

본문

다음과 같은 하나의 이벤트: 이벤트 순서; attempt 는 배송 시도 횟수입니다(1, 2, …).

성공

모든 2xx 5초 이내. 리다이렉트는 따르지 않으며, 응답 본문은 읽지 않습니다.

납품

적어도 한 번, 순서는 보장되지 않습니다. 중복을 제거하려면 다음을 적용하십시오. event_id

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_secret string, 다음을 포함하여 whsec_ 접두사.

  • timestamp — 의 가치 X-PS-Timestamp, 유닉스 초.

  • raw_body — JSON 파싱을 수행하기 전, 수신된 그대로의 본문.

  • 비공개 변경 후 24시간 동안 헤더는 v1=<current>,v1=<previous>: 해당 항목 중 하나라도 일치하면 요청을 수락하십시오.

  • 시간 표시가 귀하의 시계와 300초 이상 차이가 나는 요청은 거부하십시오.

파이썬

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이 웹훅을 수신하지 않은 경우, 해당 URL로의 전송이 비활성화됩니다. 주문 자체에는 영향을 미치지 않습니다.

비활성화된 URL을 활성화하려면 다음을 포함하여 다시 전송하십시오. 업데이트 순서: 동일한 URL은 시간당 최대 한 번만 허용되며, 새로운 URL은 언제든지 가능합니다. 놓친 이벤트는 항상 이벤트 순서.

callback_url 규칙

견적서 발행 시점에 확인되었으며, PATCH. 이를 위반할 경우 400 invalid_request:

규칙

상세 정보

인쇄 가능한 ASCII, 최대 2048자

/callback_url: must be a printable URL up to 2048 characters

https 만

/callback_url: only https is allowed

URL에 로그인 정보나 비밀번호가 포함되어서는 안 됩니다.

/callback_url: credentials in URL are not allowed

단편 없음

/callback_url: fragment is not allowed

443번 포트 전용

/callback_url: only port 443 is allowed

공개 DNS 이름, 표준 IPv4 주소 또는 괄호 안에 표기된 IPv6 주소

/callback_url: host must be a public DNS name, /callback_url: IPv4 address must be a canonical dotted quad

호스트의 모든 주소는 공개되어 있습니다.

/callback_url: host resolves to a private or reserved address, /callback_url: host does not resolve

서비스 자체의 호스트가 아닙니다.

/callback_url: host is not allowed

모든 전달 전에 DNS를 다시 확인하며, 요청은 확인된 주소로만 전송됩니다.

On this page

웹훅 | Proxy-seller