PHP code example of wiseadmin / wise-webhook

1. Go to this page and download the library: Download wiseadmin/wise-webhook library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

wiseadmin / wise-webhook example snippets


use wise\webhook\server\WebhookServer;
use think\facade\Log;

$result = WebhookServer::create()
    ->url('https://hooks.slack.com/services/T000/B000/XXXX')
    ->payload(['text' => 'Order #123 paid!'])
    ->useSecret('my-signing-secret')
    ->onSending(function (string $url, array $payload) {
        Log::info("Preparing to send to {$url}");
    })
    ->onSent(function (string $url, string $response, int $durationMs) {
        Log::info("Webhook sent to {$url} in {$durationMs}ms");
    })
    ->onFailed(function (string $url, string $error, int $attempt) {
        Log::error("Webhook failed to {$url} (attempt {$attempt}): {$error}");
    })
    ->dispatch();

[
    'success'     => true,
    'response'    => 'ok',
    'code'        => 200,
    'duration_ms' => 128,
]

use wise\webhook\server\WebhookServer;
use wise\support\backoff\BackoffStrategy;

WebhookServer::create()
    ->url('https://example.com/webhooks')
    ->payload(['order_id' => 123, 'status' => 'paid'])
    ->maxRetries(5)
    ->backoffStrategy(BackoffStrategy::exponential(1000, 60000))
    ->queue('webhooks')          // 指定队列名
    ->dispatchToQueue();         // 推入队列,立即返回 void

$result = WebhookServer::create()
    ->url('https://api.example.com/hooks')
    ->payload(['event' => 'user.created'])
    ->method('PUT')
    ->timeout(30)            // 超时 30s
    ->connectTimeout(5)      // 连接超时 5s
    ->withHeaders(['Authorization' => 'Bearer xxx'])
    ->meta(['tenant_id' => 42])   // 追踪元数据,随记录落库
    ->verifySsl(false)       // 本地调试时关闭 SSL 校验
    ->dispatch();

// 订单金额达到阈值才通知财务系统
WebhookServer::create()
    ->url('https://finance.example.com/webhook')
    ->payload(['order_id' => $order->id, 'amount' => $order->amount])
    ->dispatchIf($order->amount >= 10000);

// 非测试环境才发送
WebhookServer::create()
    ->url('https://log.example.com/webhook')
    ->payload(['msg' => 'daily report'])
    ->dispatchUnless(app()->isDebug());

'client' => [
    'endpoints' => [
        'stripe' => [
            'signing_secret'   => env('STRIPE_WEBHOOK_SECRET'),
            'signature_header' => 'Stripe-Signature',
            'processor_class'  => \app\webhook\HandleStripeWebhook::class,
        ],
        'github' => [
            'signing_secret'   => env('GITHUB_WEBHOOK_SECRET'),
            'signature_header' => 'X-Hub-Signature-256',
            'processor_class'  => \app\webhook\HandleGitHubWebhook::class,
        ],
    ],
],

use wise\webhook\client\middleware\VerifyWebhookSignature;

// 通用端点:URL 段自动提取端点名
Route::post('webhooks/:endpoint', 'webhook/Webhook@receive')
    ->middleware(VerifyWebhookSignature::class);

// 固定端点:中间件参数显式指定端点名
Route::post('webhooks/stripe', 'webhook/Webhook@stripe')
    ->middleware(VerifyWebhookSignature::class . ':stripe');

use wise\webhook\client\WebhookClient;
use think\Request;

class Webhook extends BaseController
{
    public function receive(Request $request, string $endpoint = null)
    {
        $receiver = WebhookClient::receiver();
        $result = $receiver->receive($request, $endpoint);
        return json($result);
    }
}

use wise\webhook\client\contract\WebhookProcessorInterface;
use wise\webhook\client\model\WebhookReceiveModel;
use think\Request;
use think\facade\Log;

class HandleStripeWebhook implements WebhookProcessorInterface
{
    public function handle(WebhookReceiveModel $webhookCall, Request $request): void
    {
        $type = $webhookCall->payload['type'] ?? '';

        match ($type) {
            'payment_intent.succeeded' => $this->handlePaymentSucceeded($webhookCall),
            'charge.refunded'          => $this->handleRefunded($webhookCall),
            default                    => Log::info("Unhandled Stripe event: {$type}"),
        };
    }

    protected function handlePaymentSucceeded(WebhookReceiveModel $webhookCall): void
    {
        // 执行业务逻辑,例如更新订单为已支付
        $data = $webhookCall->payload['data']['object'] ?? [];
        Log::info('Payment succeeded', $data);
    }

    protected function handleRefunded(WebhookReceiveModel $webhookCall): void
    {
        // ...
    }
}

use wise\webhook\server\contract\SignerInterface;

class MySigner implements SignerInterface
{
    public function calculateSignature(string $payload, string $secret): string
    {
        return hash_hmac('sha512', $payload, $secret);
    }

    public function signatureHeaderName(): string
    {
        return 'X-My-Signature';
    }
}

$result = WebhookServer::create()
    ->url('https://example.com/hooks')
    ->payload(['event' => 'test'])
    ->useSecret('secret')
    ->signer(MySigner::class)
    ->dispatch();

use wise\webhook\client\contract\SignatureValidatorInterface;
use think\Request;

class MySignatureValidator implements SignatureValidatorInterface
{
    public function isValid(Request $request, array $config): bool
    {
        $secret = $config['signing_secret'] ?? '';
        $header = $request->header($config['signature_header'] ?? 'X-Signature', '');
        $body   = $request->getContent();
        return hash_equals(hash_hmac('sha256', $body, $secret), (string) $header);
    }
}

'endpoints' => [
    'myapp' => [
        'signing_secret'      => env('MY_WEBHOOK_SECRET'),
        'signature_validator' => \app\webhook\MySignatureValidator::class,
    ],
],

use wise\webhook\facade\Webhook;

// 创建发送调用
$call = Webhook::serverCreate()
    ->url('https://example.com/hooks')
    ->payload(['event' => 'order.created'])
    ->dispatch();

// 获取接收器
$result = Webhook::clientReceiver()->receive($request, 'stripe');

use think\facade\Event;
use wise\webhook\server\event\WebhookSent;
use wise\webhook\server\event\WebhookFailed;

// 发送成功
Event::listen(WebhookSent::class, function (WebhookSent $event) {
    \think\facade\Log::info("Webhook sent", [
        'url' => $event->url,
        'code' => $event->responseCode,
        'duration_ms' => $event->durationMs,
    ]);
});

// 发送失败(无论是否还会重试)
Event::listen(WebhookFailed::class, function (WebhookFailed $event) {
    if (!$event->willRetry) {
        // 最终失败,触发告警
        \think\facade\Log::error("Webhook permanently failed: {$event->error}", [
            'url' => $event->url,
        ]);
    }
});

public static function create(): WebhookCall

['success' => true, 'id' => 123, 'message' => 'Webhook received and queued']
// 失败:['success' => false, 'id' => null, 'message' => '端点未配置' / '签名验证失败']

public static function receiver(): WebhookReceiver

'server' => [
    'dispatch' => [
        'default_mode' => 'queue',
    ],
],
bash
php think migrate:run
bash
# 执行迁移创建数据表
php think migrate:run