Ocriva Logo

Documents

การตั้งค่าและทดสอบ

ตั้งค่า Webhook Endpoint กำหนด Event ยืนยันลายเซ็น และทดสอบการส่งข้อมูล

webhookssetuptestingsecurity

Published: 3/31/2026

การตั้งค่าและทดสอบ

คู่มือนี้พาคุณผ่านการสร้าง Webhook Endpoint ใน Dashboard ของ Ocriva การยืนยันลายเซ็นใน Application Code ของคุณ การทดสอบ Delivery แบบ Local และการอ่าน Webhook Logs เพื่อ Debug ความล้มเหลว


การสร้าง Webhook Endpoint

ขั้นตอนที่ 1 — ไปที่ Webhooks

ไปที่ Organization Settings และเลือกแท็บ Webhooks คลิก Add Endpoint ที่มุมบนขวา

ขั้นตอนที่ 2 — กำหนดค่า Endpoint

กรอกข้อมูลในฟอร์ม Endpoint:

Fieldจำเป็นคำอธิบาย
Nameใช่Label ที่อ่านได้ เช่น Production ERP Receiver
URLใช่URL เต็มที่ Ocriva จะ POST ไป เช่น https://api.yourapp.com/webhooks/ocriva
Eventsใช่เลือก Event Type หนึ่งรายการหรือมากกว่าที่ต้องการ Subscribe
Secretไม่String สุ่มที่ใช้เซ็นชื่อ Delivery (แนะนำอย่างยิ่ง)
Custom Headersไม่HTTP Header เพิ่มเติมที่ต้องการใส่ใน Delivery ทุกครั้ง
Descriptionไม่หมายเหตุสำหรับทีมของคุณ

ขั้นตอนที่ 3 — เลือก Events

เลือก Event ที่ Endpoint นี้ควรรับ คุณสามารถ Subscribe ได้ทุกรูปแบบ:

  • document.uploaded — ได้รับไฟล์แล้ว ก่อนประมวลผล
  • document.processed — ประมวลผลสำเร็จพร้อมข้อมูลที่ดึงออกมา
  • document.failed — ประมวลผลล้มเหลว
  • batch.uploaded — ได้รับ Batch ของไฟล์แล้ว
  • batch.completed — ทุกไฟล์ใน Batch เสร็จสิ้น
  • template.created / template.updated / template.deleted — Template Lifecycle

ขั้นตอนที่ 4 — บันทึกและยืนยัน

คลิก Save Status ของ Endpoint จะเริ่มเป็น active Ocriva จะเริ่ม Deliver Event ทันที คุณสามารถหยุดชั่วคราวหรือปิดการใช้งาน Endpoint ได้ตลอดเวลาจากการตั้งค่า Endpoint

IMPORTANT

ยืนยันลายเซ็น Webhook เสมอใน Production โดยไม่มีการยืนยันลายเซ็น Server ใด ๆ ที่รู้ URL ของ Endpoint ของคุณสามารถส่ง Webhook Payload ปลอมเข้ามาในระบบของคุณได้ การเพิ่ม Secret ใช้เวลา 30 วินาที แต่ขจัดความเสี่ยงนี้ได้อย่างสมบูรณ์


การยืนยันลายเซ็น

เมื่อคุณตั้งค่า Secret บน Endpoint Ocriva จะคำนวณ HMAC-SHA256 Digest ของ Request Body ดิบโดยใช้ Secret ของคุณเป็น Key และใส่ค่านั้นใน Header X-Webhook-Signature เป็น sha256={hex_digest}

Server ของคุณควร:

  1. อ่าน Request Body ดิบเป็น Bytes — อย่า Parse JSON ก่อน
  2. คำนวณ HMAC-SHA256(body, secret) โดยใช้ Secret เดียวกัน
  3. เปรียบเทียบ Digest ที่คำนวณได้กับค่าใน X-Webhook-Signature
  4. ปฏิเสธ Request (ส่งคืน 401) หากไม่ตรงกัน

ตัวอย่างการยืนยันใน Node.js

const crypto = require('crypto');
 
function verifyWebhook(body, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(body))
    .digest('hex');
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

ตัวอย่าง Express.js Middleware

const crypto = require('crypto');
const express = require('express');
 
const app = express();
 
// ใช้ Raw Body Parser สำหรับ Route ของ Webhook — ห้ามใช้ express.json() ที่นี่
app.post('/webhooks/ocriva', express.raw({ type: 'application/json' }), (req, res) => {
  const signature = req.headers['x-webhook-signature'];
  const secret = process.env.OCRIVA_WEBHOOK_SECRET;
 
  if (!signature || !secret) {
    return res.status(401).json({ error: 'Missing signature or secret' });
  }
 
  const expectedSig = crypto
    .createHmac('sha256', secret)
    .update(req.body)
    .digest('hex');
 
  const sigBuffer = Buffer.from(signature.replace('sha256=', ''));
  const expectedBuffer = Buffer.from(expectedSig);
 
  if (sigBuffer.length !== expectedBuffer.length ||
      !crypto.timingSafeEqual(sigBuffer, expectedBuffer)) {
    return res.status(401).json({ error: 'Invalid signature' });
  }
 
  // ลายเซ็นถูกต้อง — Parse และจัดการ Event
  const event = JSON.parse(req.body.toString());
 
  switch (event.eventType) {
    case 'document.processed':
      // จัดการข้อมูลที่ดึงออกมา
      break;
    case 'document.failed':
      // จัดการความล้มเหลว
      break;
    default:
      // ไม่สนใจ Event ที่ไม่รู้จัก
  }
 
  // ตอบกลับด้วย 2xx เสมอและอย่างรวดเร็ว
  res.status(200).json({ received: true });
});

WARNING

Endpoint ของคุณต้องตอบกลับด้วย Status Code 2xx ภายใน Timeout ที่กำหนด (ค่าเริ่มต้น 30 วินาที) ถ้า Logic การประมวลผลของคุณใช้เวลานานกว่านั้น เช่น การเขียนลงฐานข้อมูล การเรียก External API หรือการคำนวณหนัก ๆ ให้ส่งคืน 200 ทันทีแล้วส่งงานไปยัง Background Queue แทน Response ที่ช้าทำให้เกิด Delivery Failure และ Retry โดยไม่จำเป็น


นโยบาย Retry

ถ้า Ocriva ไม่ได้รับ Response 2xx — หรือ Request Timeout — จะ Retry อัตโนมัติ:

ครั้งDelay
ครั้งแรกทันที
ครั้งที่ 2ประมาณ 30 วินาทีหลังจาก Failure ครั้งแรก
ครั้งที่ 3ประมาณ 5 นาทีหลังจาก Failure ครั้งที่สอง

หลังจากพยายาม 3 ครั้งแล้วล้มเหลว Delivery จะถูกทำเครื่องหมายว่า failed ใน Log และไม่มีการ Retry อีก คุณสามารถตรวจสอบ Delivery ที่ล้มเหลวใน Webhook Logs และ Trigger ซ้ำด้วยตนเองหากจำเป็น

นับว่าสำเร็จเมื่อ: Response HTTP มี Status Code 2xx (200–299)

นับว่าล้มเหลวเมื่อ: Status ที่ไม่ใช่ 2xx, Connection Refused, DNS Error หรือ Timeout


การทดสอบ Webhook

Manual Trigger ผ่าน API

คุณสามารถส่ง Test Event ไปยัง Endpoint ใด ๆ โดยไม่ต้องรอ Activity จริง โดยใช้ Trigger Endpoint:

curl -X POST https://api.ocriva.com/webhooks/{organizationId}/trigger \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "endpointId": "wh_endpoint_id",
    "eventType": "document.processed"
  }'

คำสั่งนี้ส่ง Sample Payload สำหรับ Event Type ที่ระบุไปยัง Endpoint ของคุณและบันทึกผลการ Delivery

Local Development ด้วย ngrok

เมื่อพัฒนาแบบ Local Server localhost ของคุณไม่สามารถเข้าถึงได้จาก Ocriva ใช้ ngrok (หรือ Tunnel Tool อื่นที่คล้ายกัน) เพื่อ Expose Port Local ของคุณไปยัง Internet:

# ติดตั้ง ngrok จาก https://ngrok.com แล้วรัน:
ngrok http 3000

ngrok ให้ URL HTTPS สาธารณะเช่น https://abc123.ngrok.io ใช้ URL นั้นเป็น Webhook Endpoint URL ใน Ocriva ระหว่างการพัฒนา

TIP

Web Inspector ของ ngrok (เปิดได้ที่ http://localhost:4040 ขณะที่ ngrok กำลังทำงาน) แสดง Request และ Response ทุกรายการแบบ Real-time คุณสามารถ Replay Request ใด ๆ ได้ด้วยคลิกเดียว มีประโยชน์มากเมื่อต้องปรับปรุง Handler Logic โดยไม่ต้อง Re-trigger Event

ตรวจสอบ Test Delivery

หลังจาก Trigger Test:

  1. ตรวจสอบ Log ของ Application ของคุณ — ยืนยันว่า Request มาถึงและจัดการอย่างถูกต้อง
  2. เปิดแท็บ Webhook Logs ใน Ocriva Dashboard — ค้นหา Delivery และยืนยันว่าแสดง Status 200
  3. ถ้า Delivery ล้มเหลว ให้ขยาย Log Entry เพื่อดู Error และ Response Body ทั้งหมด

Webhook Logs

ทุก Delivery Attempt ถูกเก็บไว้ใน Webhook Logs วิธีดู:

  1. ไปที่ Organization SettingsWebhooks
  2. คลิกที่ Endpoint
  3. เลือกแท็บ Logs

แต่ละ Log Entry แสดง:

คอลัมน์คำอธิบาย
Timestampเวลาที่พยายาม Deliver
Event TypeEvent ที่ทำให้เกิด Delivery
Statussuccess หรือ failed
HTTP StatusResponse Code ที่ Server ของคุณส่งคืน
Response Timeเวลาที่ Server ของคุณใช้ตอบสนอง (ms)
Errorข้อความ Error ถ้า Delivery ล้มเหลว

คุณยังดึง Log ผ่าน API ได้:

GET /webhooks/{organizationId}/logs

และสถิติระดับ Endpoint (จำนวน Request ทั้งหมด อัตราความสำเร็จ เวลาตอบสนองเฉลี่ย):

GET /webhooks/{organizationId}/stats

Best Practices

ตอบกลับทันที ประมวลผลทีหลัง

Endpoint ของคุณควรส่งคืน 200 OK ให้เร็วที่สุด — ควรน้อยกว่า 1 วินาที อย่าเรียก Database Write, External API หรือการคำนวณหนัก ๆ แบบ Synchronous ใน Webhook Handler ให้ Push Event ไปยัง Queue (BullMQ, SQS, Redis ฯลฯ) แทนแล้วประมวลผลแบบ Asynchronous

app.post('/webhooks/ocriva', express.raw({ type: 'application/json' }), async (req, res) => {
  // ยืนยันลายเซ็นก่อน (เร็ว)
  if (!verifySignature(req)) return res.status(401).end();
 
  const event = JSON.parse(req.body.toString());
 
  // เพิ่มเข้า Queue สำหรับ Background Processing (เร็ว)
  await queue.add('webhook-event', event);
 
  // ตอบกลับทันที
  res.status(200).json({ received: true });
});

จัดการ Duplicate Events

เนื่องจาก Retry และสภาพของเครือข่าย Endpoint ของคุณอาจได้รับ Event เดิมมากกว่าหนึ่งครั้ง ควร Implement Handler ที่เป็น Idempotent โดยตรวจสอบว่าคุณได้ประมวลผล eventId นั้นแล้วหรือยังก่อนดำเนินการ

async function handleDocumentProcessed(event) {
  const alreadyProcessed = await db.events.findOne({ eventId: event.eventId });
  if (alreadyProcessed) return; // ข้าม Duplicate
 
  await db.events.insert({ eventId: event.eventId, processedAt: new Date() });
  // ... ส่วนที่เหลือของ Handler
}

ยืนยันลายเซ็นเสมอใน Production

อย่าข้ามการยืนยันลายเซ็นใน Production Middleware เพียงบรรทัดเดียวปกป้องระบบของคุณจาก Event ปลอมและผลข้างเคียงที่ไม่ต้องการ

ตั้งชื่อ Endpoint ให้สื่อความหมาย

ตั้งชื่อ Endpoint ตามวัตถุประสงค์และสภาพแวดล้อม: Production — ERP Invoice Receiver, Staging — Slack Notifier ทำให้อ่าน Log ได้ง่ายขึ้นมากเมื่อมีปัญหาเกิดขึ้น

ติดตามอัตราการล้มเหลว

ตรวจสอบ Webhook Stats เป็นประจำ อัตราการล้มเหลวที่สูงขึ้นบน Endpoint มักบ่งบอกถึงปัญหาของ Server ก่อนที่จะกลายเป็นเหตุการณ์ใหญ่