Skip to content

ภาพรวม Webhook

GameSO ส่ง webhook notification ไปยัง Merchant เมื่อ order มีการเปลี่ยนแปลงสถานะ ช่วยให้ Merchant รับทราบผลลัพธ์แบบ real-time โดยไม่ต้อง poll API

Webhook Events

Eventเมื่อไหร่
order.completedเมื่อทุก item ใน order เสร็จสมบูรณ์
order.failedเมื่อ order ล้มเหลว

ขั้นตอนการทำงาน

1. Merchant สร้าง order


2. ระบบประมวลผล items


3. Order เสร็จ/ล้มเหลว


4. GameSO ส่ง POST request ไปยัง Webhook URL ของ Merchant


5. Merchant ตอบกลับ HTTP 200

ข้อกำหนดของ Webhook Endpoint

Merchant ต้องมี HTTP endpoint ที่:

  • รับ POST request
  • ตอบกลับ HTTP 200 ภายใน 30 วินาที
  • รองรับ Content-Type: application/json
  • แนะนำให้ใช้ HTTPS

WARNING

หาก endpoint ตอบกลับช้าเกิน 30 วินาที หรือตอบกลับ status code ที่ไม่ใช่ 2xx ระบบจะถือว่า delivery ล้มเหลว

Retry Policy

หาก webhook delivery ล้มเหลว ระบบจะ retry อัตโนมัติ:

Retryหลังจาก
ครั้งที่ 11 นาที
ครั้งที่ 25 นาที
ครั้งที่ 330 นาที

หลังจาก retry ครบ 3 ครั้งแล้วยังล้มเหลว ระบบจะหยุด retry

ตัวอย่าง Webhook Handler

javascript
const express = require("express");
const crypto = require("crypto");
const app = express();

app.use(express.json());

app.post("/webhooks/gameso", (req, res) => {
    // 1. ตรวจสอบ signature ก่อน
    const signature = req.headers["x-webhook-signature"];
    const payload = JSON.stringify(req.body);
    const secret = process.env.GAMESO_WEBHOOK_SECRET;

    const expectedSig = crypto
        .createHmac("sha256", secret)
        .update(payload)
        .digest("hex");

    if (signature !== `sha256=${expectedSig}`) {
        return res.status(401).json({ error: "Invalid signature" });
    }

    // 2. ประมวลผล event
    const { event, data } = req.body;

    if (event === "order.completed") {
        console.log(`Order ${data.order_number} completed!`);
        // อัพเดทสถานะในระบบของคุณ
    } else if (event === "order.failed") {
        console.log(
            `Order ${data.order_number} failed: ${data.failure_message}`,
        );
        // จัดการ error
    }

    // 3. ตอบกลับ 200 ทันที
    res.status(200).json({ received: true });
});
python
import hmac
import hashlib
import json
import os
from flask import Flask, request, jsonify

app = Flask(__name__)

@app.route('/webhooks/gameso', methods=['POST'])
def gameso_webhook():
    # 1. ตรวจสอบ signature
    signature = request.headers.get('X-Webhook-Signature', '')
    payload = request.get_data(as_text=True)
    secret = os.environ['GAMESO_WEBHOOK_SECRET']

    expected = 'sha256=' + hmac.new(
        secret.encode(), payload.encode(), hashlib.sha256
    ).hexdigest()

    if not hmac.compare_digest(signature, expected):
        return jsonify({'error': 'Invalid signature'}), 401

    # 2. ประมวลผล event
    body = request.json
    event = body['event']
    data = body['data']

    if event == 'order.completed':
        print(f"Order {data['order_number']} completed!")
        # อัพเดทสถานะในระบบของคุณ
    elif event == 'order.failed':
        print(f"Order {data['order_number']} failed: {data['failure_message']}")

    # 3. ตอบกลับ 200
    return jsonify({'received': True}), 200
php
<?php
// 1. ตรวจสอบ signature
$signature = $_SERVER['HTTP_X_WEBHOOK_SIGNATURE'] ?? '';
$payload = file_get_contents('php://input');
$secret = getenv('GAMESO_WEBHOOK_SECRET');

$expected = 'sha256=' . hash_hmac('sha256', $payload, $secret);

if (!hash_equals($signature, $expected)) {
    http_response_code(401);
    echo json_encode(['error' => 'Invalid signature']);
    exit;
}

// 2. ประมวลผล event
$body = json_decode($payload, true);
$event = $body['event'];
$data = $body['data'];

if ($event === 'order.completed') {
    // อัพเดทสถานะในระบบของคุณ
    error_log("Order {$data['order_number']} completed!");
} elseif ($event === 'order.failed') {
    error_log("Order {$data['order_number']} failed: {$data['failure_message']}");
}

// 3. ตอบกลับ 200
http_response_code(200);
echo json_encode(['received' => true]);

ขั้นตอนถัดไป

GameSO API Documentation