POST /apiv2/reports/webhooks
ลงทะเบียน URL แล้ว NETTS จะเรียกไปยัง URL นั้นเมื่อรายงานพร้อมใช้งาน แทนที่คุณจะต้องคอยสอบถามสถานะ (polling)
ปลายทางเหล่านี้ถูกแยกต่างหากจาก เว็บฮุกของคำสั่งซื้อ การลงทะเบียนที่นั่นจะไม่ได้เป็นการสมัครรับการแจ้งเตือนรายงาน และในทางกลับกันก็เช่นเดียวกัน รูปแบบข้อมูลที่ส่งผ่านเครือข่าย — ลายเซ็น ส่วนหัว พฤติกรรมการลองใหม่ — เหมือนกันทุกประการ ดังนั้นตัวจัดการ (handler) ที่เขียนขึ้นสำหรับอันหนึ่งจึงสามารถใช้งานร่วมกับอีกอันได้
URL ฐานของปลายทาง
https://netts.io/apiv2/reports/webhooksส่วนหัวของคำขอ
| ส่วนหัว | จำเป็น | คำอธิบาย |
|---|---|---|
X-API-KEY | ใช่ | คีย์ API จากแดชบอร์ด |
X-Real-IP | ใช่ | ที่อยู่จากรายการที่อนุญาต (whitelist) ของคีย์ |
ตัวหลักและตัวสำรอง
สูงสุดสองปลายทางต่อหนึ่งบัญชี primary จะได้รับทุกอย่าง backup จะถูกใช้งานเฉพาะหลังจากที่การส่งไปยังตัวหลักหมดความพยายามแล้วเท่านั้น — และมันจะถูกลงลายเซ็นด้วยรหัสลับของมันเอง ไม่ใช่ของตัวหลัก
การลงทะเบียน
curl -s -X POST 'https://netts.io/apiv2/reports/webhooks' \
-H 'X-API-KEY: your-api-key' \
-H 'X-Real-IP: 203.0.113.10' \
-H 'Content-Type: application/json' \
-d '{"url": "https://example.com/netts/reports", "role": "primary"}'{
"status": "success",
"code": 10000,
"data": {
"id": 1,
"url": "https://example.com/netts/reports",
"role": "primary",
"is_active": true,
"created_at": "2026-09-06 17:05:12+00:00",
"updated_at": "2026-09-06 17:05:12+00:00",
"secret": "whsec_<64 hex characters>"
}
}รหัสลับจะแสดงเพียงครั้งเดียวที่นี่ มันจะไม่ถูกส่งกลับมาอีกเลย — ไม่ว่าจะจากการเรียกดูรายการ หรือจากปลายทางการอ่านค่า บันทึกเก็บไว้ทันทีที่คุณได้รับ หากทำหาย ให้สร้างอันใหม่:
curl -s -X POST 'https://netts.io/apiv2/reports/webhooks/1/rotate-secret' \
-H 'X-API-KEY: your-api-key' -H 'X-Real-IP: 203.0.113.10'การหมุนเวียนคีย์ใหม่จะมีผลทันทีและรหัสลับเดิมจะหยุดการตรวจสอบความถูกต้อง ดังนั้นให้ปรับใช้ค่าใหม่ก่อนหากคุณไม่สามารถยอมรับช่วงเวลาที่ระบบสะดุดได้
การจัดการ
| วิธีการ | เส้นทาง | การดำเนินการ |
|---|---|---|
GET | /apiv2/reports/webhooks | ดูรายการของคุณ โดยไม่มีรหัสลับ |
GET | /apiv2/reports/webhooks/{id} | อ่านค่ารายการเดียว |
PATCH | /apiv2/reports/webhooks/{id} | เปลี่ยน url หรือหยุดชั่วคราวด้วย is_active: false |
DELETE | /apiv2/reports/webhooks/{id} | ลบออก |
URL ต้องเป็น HTTPS สาธารณะ ที่อยู่แบบ Loopback, ที่อยู่ส่วนบุคคล และ link-local จะถูกปฏิเสธ รวมถึงข้อมูลประจำตัวภายใน URL ด้วยเช่นกัน สิ่งใดก็ตามที่ถูกปฏิเสธจะส่งกลับมาเป็น 422 พร้อมเหตุผล การตรวจสอบนี้จะทำงานอีกครั้งทันทีก่อนการส่งข้อมูลแต่ละครั้ง ดังนั้นปลายทางที่ภายหลังแปลงค่าไปเป็นที่อยู่ส่วนบุคคลจะหยุดรับข้อมูล
สิ่งที่เราส่งให้
{
"event": "report.ready",
"delivery_id": 4,
"order_id": "REPxxxxxxxxxxxx",
"order_type": "statement",
"client_request_id": "stmt-2026-09-usdt",
"status": "done",
"format": "csv",
"download_url": "/apiv2/reports/REPxxxxxxxxxxxx/download",
"expires_at": "2026-10-06 15:48:04+00:00",
"artifact": { "sha256": "…", "size_bytes": 696 },
"confirmed_at": "2026-09-06T15:48:04Z"
}| ฟิลด์ | คำอธิบาย |
|---|---|
event | report.ready — คีย์สำหรับกำหนดเส้นทางไปยังตัวจัดการของคุณ |
delivery_id | คีย์สำหรับกรองข้อมูลซ้ำ ส่งมาในส่วนหัว X-Netts-Delivery ด้วยเช่นกัน |
order_id | หมายเลขคำสั่งซื้อที่คุณได้รับเมื่อส่งรายงานเข้าคิว |
order_type | statement หรือ balance_at_date |
download_url | เส้นทางสำหรับดาวน์โหลดไฟล์ ซึ่งสัมพันธ์กับ https://netts.io |
artifact.sha256 | ค่า Checksum เพื่อให้คุณสามารถตรวจสอบไฟล์ที่ดาวน์โหลดมาได้ |
confirmed_at | UTC |
การประทับเวลาทั้งหมดเป็นรูปแบบ UTC
การตรวจสอบความถูกต้องของลายเซ็น
X-Netts-Signature: sha256=<hex>
X-Netts-Timestamp: <unix seconds>
X-Netts-Delivery: <delivery_id>ลายเซ็นคือ HMAC-SHA256 บน "<timestamp>." + raw body ซึ่งคำนวณด้วยรหัสลับของปลายทางที่ได้รับคำขอ ให้เปรียบเทียบข้อมูลแบบเวลาคงที่ (constant time) และปฏิเสธสิ่งใดก็ตามที่มีการประทับเวลาอยู่นอกช่วง ±5 นาที
import hmac, hashlib, time
def verify(raw_body: bytes, sig_header: str, ts_header: str, secret: str) -> bool:
if abs(time.time() - int(ts_header)) > 300: # ป้องกัน replay
return False
signed = f"{ts_header}.".encode() + raw_body
expected = "sha256=" + hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, sig_header)ลงลายเซ็นด้วยรหัสลับของ URL ที่คำขอส่งมาถึง: ตัวหลักและตัวสำรองมีรหัสลับที่แตกต่างกัน
การส่งข้อมูลเป็นแบบส่งอย่างน้อยหนึ่งครั้ง (at-least-once)
การตอบกลับที่ขาดหายไปจะทำให้เกิดการลองใหม่ ดังนั้นเหตุการณ์เดิมอาจถูกส่งมาซ้ำสองครั้งได้
- กำจัดข้อมูลซ้ำด้วย
delivery_idการส่งซ้ำจะต้องไม่มีผลกระทบต่อระบบฝั่งคุณ (no-op) - ตรวจสอบความถูกต้องของลายเซ็นก่อนดำเนินการ, ไม่ใช่ตรวจสอบหลังจากนั้น
- ตอบกลับ
2xxหลังจากที่คุณบันทึกเหตุการณ์เรียบร้อยแล้วเท่านั้น สถานะอื่นใดนอกเหนือจากนี้ หรือการหมดเวลา (timeout) จะถือเป็นความล้มเหลวและจะถูกลองใหม่
การลองใหม่ไปยังปลายทางหนึ่งจะมีระยะห่างที่ 1 นาที, 5 นาที, 15 นาที, 1 ชั่วโมง, 6 ชั่วโมง และ 24 ชั่วโมง — รวมทั้งหมดหกครั้ง กินเวลามากกว่า 31 ชั่วโมงเล็กน้อย เมื่อครบกำหนดแล้วและคุณได้ลงทะเบียน backup ไว้ การส่งข้อมูลจะย้ายไปที่นั่นและกำหนดการจะเริ่มนับใหม่ด้วยรหัสลับของตัวสำรองเอง ค่า delivery_id จะยังคงเดิมตลอด ดังนั้นเหตุการณ์ที่ล้มเหลวบนตัวหลักและสำเร็จบนตัวสำรองจึงยังคงเป็นเหตุการณ์เดียวกัน
ระบบไม่รองรับการเปลี่ยนเส้นทาง (redirects)
ขีดจำกัดอัตราการส่ง
10 คำขอต่อวินาที ต่อหนึ่งปลายทาง โดยแชร์การใช้งานร่วมกันระหว่างไคลเอนต์ทั้งหมด
ข้อผิดพลาด
การลงทะเบียนจะตอบกลับเป็น 201, การลบจะตอบกลับเป็น 204 โดยไม่มีเนื้อหา, กรณีอื่นทั้งหมดจะตอบกลับเป็น 200
| HTTP | ความหมาย |
|---|---|
401 | คีย์ขาดหายไปหรือไม่ถูกต้อง หรือ IP ต้นทางไม่ได้อยู่ใน whitelist |
404 | ไม่พบปลายทางดังกล่าวในบัญชีของคุณ |
409 | บทบาทที่ร้องขอถูกใช้งานแล้ว — role primary is already taken |
422 | URL ถูกปฏิเสธ หรือเนื้อหา PATCH ไม่มีข้อมูลที่จะเปลี่ยนแปลง |
429 | เกินขีดจำกัดอัตราการส่ง |
URL ที่ถูกปฏิเสธจะส่งกลับมาเป็น 422 พร้อมระบุเหตุผลอย่างชัดเจน เพื่อให้คุณสามารถแสดงผลให้แก่ผู้ที่ป้อนข้อมูลได้:
{"status": "error", "code": -4, "msg": "url: Value error, invalid webhook_url: resolved address 127.0.0.1 is not public"}ข้อความที่ใช้คือ only https:// URLs are allowed, credentials in URL are not allowed, และ resolved address <ip> is not public ข้อความสุดท้ายจะทำการแปลงที่อยู่ ณ เวลาลงทะเบียนและอีกครั้งทันทีก่อนการส่งข้อมูลแต่ละครั้ง ดังนั้นชื่อโฮสต์ที่ภายหลังชี้ไปยังที่อยู่ส่วนบุคคลจะหยุดรับข้อมูล
เรื่องที่เกี่ยวข้อง
- ไฟล์รายงานรายการเดินบัญชี — การสั่งรายงานที่จะกระตุ้นให้เกิดการแจ้งเตือนนี้
- เว็บฮุกของคำสั่งซื้อ — ระบบลงทะเบียนแยกต่างหากสำหรับเหตุการณ์ Energy, Bandwidth และการเปิดใช้งาน