Download the PHP package wiseadmin/wise-webhook without Composer

On this page you can find all versions of the php package wiseadmin/wise-webhook. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package wise-webhook

Wise-Webhook

基于 ThinkPHP 6/8 的 Webhook 发送与接收双面解决方案,深度集成 WiseAdmin 生态 发送侧(Server)提供流式构建器 + HMAC 签名 + 可配置重试/退避 + 按 host 断路器 + 队列发送; 接收侧(Client)提供多端点签名验证 + 防重放 + 防时序攻击中间件 + 队列异步处理。 版本:v1.0 | PHP >= 7.4 | ThinkPHP ^6.0 || ^8.0

PHP Version ThinkPHP Packagist


目录


概述

Wise-Webhook 是 WiseAdmin 生态的 Webhook 组件,同时解决对外发送与对内接收两个方向的问题:

包设计对标社区成熟的 spatie/laravel-webhook-client / spatie/laravel-webhook-server 思路,但在 WiseAdmin 中进一步补齐了数据库持久化、队列重试退避、断路器熔断、双面统一门面等工程化能力。

设计理念

设计原则 说明
双面统一 一个包同时提供发送(Server)与接收(Client)能力,并通过 WebhookManager / Facade 统一入口
可扩展 签名器、签名验证器、业务处理器均为接口契约,可自由替换
工程化 数据库持久化、队列重试退避、per-host 断路器、SSRF 防护内置开箱即用
安全优先 hash_equals 防时序攻击、时间戳容差防重放、内部地址拦截防 SSRF

核心特性

Server 侧(发送)

Client 侧(接收)


架构设计

双面分层

发送请求处理流程(Server)

接收请求处理流程(Client)


安装与配置

前置条件

通过 Composer 安装

发布配置与创建数据表

包在 composer.json 的 extra.think.migrate-path 中声明了迁移路径,WebhookServiceProvider::boot() 通过 RegistersMigrations trait 在 CLI 模式下自动注册迁移目录,因此:

环境变量种子

WebhookServiceProvider 实现了 EnvSeedProvider,会向 .env 声明两个外部平台的入站签名密钥占位(绝不在安装时生成假值,由用户在 GitHub / Stripe 平台获取后填写):

变量 类型 说明
GITHUB_WEBHOOK_SECRET external GitHub Webhook 签名密钥
STRIPE_WEBHOOK_SECRET external Stripe Webhook 签名密钥

快速上手

Server 侧:发送 Webhook

1. 同步发送

dispatch() 返回结构:

2. 队列异步发送(推荐)

注意:onSending / onSent / onFailed 闭包无法序列化,仅同步模式可用;队列模式通过事件(WebhookSent / WebhookFailed)传递结果。

3. 自定义 HTTP 行为

4. 条件发送

Client 侧:接收 Webhook

1. 配置端点 config/wise-webhook.php

2. 定义路由

3. 编写控制器

4. 编写业务处理器

说明:WebhookProcessorInterface::handle() 收到的 $webhookCall 是从数据库加载的 WebhookReceiveModel,包含 payload / headers / signature / source_ip 等完整信息,无需再访问原始网络请求。

自定义签名器(Server 发送)

实现 SignerInterface,替换默认 HMAC-SHA256 签名方式:

使用:

自定义签名验证器(Client 接收)

适配私有平台的特殊签名格式,实现 SignatureValidatorInterface:

在端点配置中通过 signature_validator 指定:

组合 Facade

wise\webhook\facade\Webhook 提供 Server / Client 统一门面:

事件监听


API 参考

WebhookCall 发送构建器

命名空间:wise\webhook\server。核心类,流式构建一次 Webhook 发送。

方法 参数 返回 说明
create() 无 WebhookCall 静态工厂,从配置初始化默认值(签名器、超时、重试、退避、回调)
url(string $url) 目标 URL $this 设置目标 URL
payload(array $payload) 请求体数组 $this 设置请求体(发送前 JSON 编码)
useSecret(string $secret) 签名密钥 $this 设置签名密钥(非空才签名)
signer(string $signerClass) SignerInterface 类名 $this 自定义签名器类名
method(string $method) POST/PUT/PATCH/GET 等 $this 设置 HTTP 方法(自动转大写)
timeout(int $seconds) 秒 $this 请求超时
connectTimeout(int $seconds) 秒 $this 连接超时
maxRetries(int $max) 次数 $this 最大重试次数(不含首次)
backoffStrategy(BackoffStrategy $strategy) 退避策略 $this 自定义退避策略
withHeaders(array $headers) 头数组 $this 追加额外请求头
meta(array $meta) 元数据 $this 追加追踪元数据
verifySsl(bool $verify) 布尔 $this 是否校验 SSL 证书
queue(?string $name) 队列名 $this 设置发送队列名
onSending(callable $cb) fn(string $url, array $payload) $this 发送前回调(仅同步)
onSent(callable $cb) fn(string $url, string $response, int $durationMs) $this 成功回调(仅同步)
onFailed(callable $cb) fn(string $url, string $error, int $attempt) $this 失败回调(仅同步)
dispatch() 无 array\|void 按 default_mode 发送(sync 同步 / queue 队列)
dispatchSync() 无 array 同步阻塞发送,返回 {success,response,code,duration_ms}
dispatchToQueue(?string $queue = null) 队列名(可选) void 推入队列异步发送
dispatchIf(bool $condition) 布尔 ?array 条件为真才发送
dispatchUnless(bool $condition) 布尔 ?array 条件为假才发送
toArray() 无 array 序列化为队列传输数组
hasCallbacks() 无 bool 是否配置了闭包回调
getOnSendingCallback() / getOnSentCallback() / getOnFailedCallback() 无 ?callable 获取回调
getUrl() / getSecret() 无 string\|?string 获取 URL / 密钥

WebhookServer 静态入口

命名空间:wise\webhook\server。仅一个静态工厂方法,等价于 WebhookCall::create()。

WebhookReceiver 接收编排器

命名空间:wise\webhook\client。编排「接收 → 签名验证 → 存储 → 队列」完整流程。

方法 参数 返回 说明
receive(Request $request, ?string $endpointName = null) 请求、端点名 array{success,id,message} 接收并处理一个 Webhook 请求
validateOnly(Request $request, string $endpointName) 请求、端点名 bool 仅验证签名,不存储不处理

receive() 返回示例:

WebhookClient 静态入口

命名空间:wise\webhook\client。创建接收器。

模型方法

WebhookSendModel(发送记录,表 webhook_sends)

命名空间:wise\webhook\server\model。JSON 字段 payload/headers/meta 自动序列化。

方法 参数 返回 说明
markSending() 无 $this 标记为发送中
markSuccess(int $responseCode, string $responseBody, int $durationMs) 状态码/响应体/耗时 $this 标记发送成功
markFailed(string $errorMessage, int $attempt) 错误/次数 $this 标记发送失败
incrementAttempt() 无 $this 递增重试次数

状态取值(status):pending / sending / success / failed。

WebhookReceiveModel(接收记录,表 webhook_receives)

命名空间:wise\webhook\client\model。JSON 字段 payload/headers/meta 自动序列化。

方法 参数 返回 说明
markProcessing() 无 $this 标记处理中
markProcessed() 无 $this 标记处理完成(写入 processed_at)
markFailed(string $errorMessage) 错误 $this 标记处理失败
markRejected(string $reason) 原因 $this 标记签名被拒
incrementAttempt() 无 $this 递增重试次数

状态取值(status):pending / processing / processed / failed / rejected。

接口契约

接口 命名空间 方法 说明
SignerInterface wise\webhook\server\contract calculateSignature(string $payload, string $secret): string;signatureHeaderName(): string 发送侧签名器
SignatureValidatorInterface wise\webhook\client\contract isValid(Request $request, array $config): bool 接收侧签名验证器
WebhookProcessorInterface wise\webhook\client\contract handle(WebhookReceiveModel $webhookCall, Request $request): void 接收侧业务处理器

内置实现:

BackoffStrategy 退避策略

命名空间:wise\support\backoff(由 wise-support 提供)。四种工厂方法与核心方法:

方法 说明
BackoffStrategy::linear(int $stepMs = 1000) 线性退避:step, step×2, step×3...
BackoffStrategy::exponential(int $baseMs = 1000, ?int $maxMs = 60000) 指数退避:base, base×2, base×4...(maxMs 加顶)
BackoffStrategy::fixed(int $delayMs = 5000) 固定延迟
BackoffStrategy::custom(array $delaysMs) 自定义序列,超出用最后值
delayForAttempt(int $attempt) 计算第 N 次重试延迟(毫秒)
toArray(?int $maxAttempts = null) 序列化策略 / 生成延迟数组

该策略天然兼容 wise-support 的 retry() 函数与队列 Job 的 backoff() 方法。


配置参考

config/wise-webhook.php 真实配置键、默认值与含义:

server 段

配置键 默认值 说明
server.dispatch.default_mode 'sync' 默认发送模式:sync(同步)| queue(队列)
server.signer \wise\webhook\server\signer\DefaultSigner::class 默认签名器类名
server.queue 'webhooks' 默认发送队列名
server.retry.max_attempts 3 最大重试次数
server.retry.backoff_method 'linear' 退避方式:linear|exponential|fixed|custom
server.retry.backoff_base_ms 1000 基础延迟(毫秒)
server.retry.backoff_max_ms 60000 最大延迟(毫秒,仅 exponential 生效)
server.http.timeout 15 请求超时(秒)
server.http.connect_timeout 5 连接超时(秒)
server.http.method 'POST' 默认 HTTP 方法
server.http.verify_ssl true 是否校验 SSL 证书
server.headers ['Content-Type'=>'application/json; charset=utf-8','User-Agent'=>'WiseAdmin-Webhook/1.0'] 默认请求头(自动添加)
server.signature_header 'X-Signature' 签名头名称
server.callbacks.on_sending null 全局发送前回调 fn(string $url, array $payload): void
server.callbacks.on_sent null 全局成功回调 fn(string $url, string $response, int $durationMs): void
server.callbacks.on_failed null 全局失败回调 fn(string $url, string $error, int $attempt): void

client 段

配置键 默认值 说明
client.endpoints [] 多端点配置数组(示例注释见 config 文件)
client.defaults.signature_validator \wise\webhook\client\validator\DefaultSignatureValidator::class 默认签名验证器
client.defaults.processor_class \wise\webhook\client\handler\LogOnlyProcessor::class 默认业务处理器
client.defaults.signature_header 'X-Signature' 默认签名头名称
client.defaults.store_webhook_calls true 是否将接收记录落库
client.defaults.queue 'webhooks' 接收处理队列名
client.defaults.timeout 30 处理超时(秒)
client.defaults.tolerance_seconds 300 时间戳容差(秒,防重放攻击)

每个端点可覆盖的键:signing_secret、signature_header、signature_validator、processor_class、store_webhook_calls、queue、timeout、tolerance_seconds。

circuit 段

配置键 默认值 说明
circuit.failure_threshold 5 连续失败多少次后熔断
circuit.timeout 120 熔断后冷却时间(秒)
circuit.key_prefix 'wise_webhook:cb' Redis key 前缀

事件列表

Server 事件(wise\webhook\server\event)

事件类 触发时机 主要属性
WebhookSending HTTP 请求发出前 url, payload, headers, meta, attempt
WebhookSent 响应码为 2xx url, payload, response, responseCode, durationMs, meta, attempt
WebhookFailed 响应非 2xx 或网络错误 url, payload, error, responseCode, attempt, maxAttempts, willRetry, meta

Client 事件(wise\webhook\client\event)

事件类 触发时机 主要属性
WebhookAccepted 中间件签名验证通过 endpointName, request
WebhookReceived 接收请求存储到数据库后 webhookCall, request, endpointName
WebhookRejected 签名验证失败 / 端点未配置 endpointName, request, reason
WebhookProcessed Processor 处理完成 webhookCall, endpointName, result

错误码

Server 侧(号段 100100~100199)

常量 值 默认消息 关联异常
ErrorCode::SEND_FAILED 100101 Webhook 发送失败 WebhookSendException(HTTP 500 或覆盖码)

另有 ServiceUnavailableException(GeneralErrorCode::SERVICE_UNAVAILABLE,值 151,HTTP 503)——断路器 OPEN 时抛出,由队列任务捕获后触发退避重试,不立即丢弃。

Client 侧(号段 100000~100099)

常量 值 默认消息 关联异常
ErrorCode::SIGNATURE_INVALID 100001 Webhook 签名验证失败 InvalidSignatureException(HTTP 403)
ErrorCode::RECEPTION_ERROR 100002 Webhook 接收处理失败 WebhookReceptionException(HTTP 400)

数据库表结构

webhook_sends(Webhook 发送记录表)

字段 类型 说明
id INT PK AUTO_INCREMENT 主键
url VARCHAR(1024) 目标 URL
method VARCHAR(10) HTTP 方法,默认 POST
payload TEXT 请求体 JSON
headers TEXT 请求头 JSON
signature VARCHAR(512) 签名值
status VARCHAR(32) 状态:pending / sending / success / failed,默认 pending
response_code INT HTTP 响应码
response_body TEXT 响应体
error_message TEXT 错误信息
attempt INT 当前重试次数,默认 0
max_attempts INT 最大重试次数,默认 3
duration_ms INT 请求耗时(毫秒)
meta TEXT 元数据 JSON
create_time DATETIME 创建时间
update_time DATETIME 更新时间

索引:idx_status(status)、idx_create_time(create_time)、idx_status_time(status, create_time)。

webhook_receives(Webhook 接收记录表)

字段 类型 说明
id INT PK AUTO_INCREMENT 主键
endpoint_name VARCHAR(128) 端点名称
payload TEXT 请求体 JSON
headers TEXT 请求头 JSON(已过滤 cookie/set-cookie/authorization)
signature VARCHAR(512) 接收到的签名
status VARCHAR(32) 状态:pending / processing / processed / failed / rejected,默认 pending
error_message TEXT 错误信息
attempt INT 当前重试次数,默认 0
max_attempts INT 最大重试次数,默认 3
source_ip VARCHAR(50) 请求来源 IP
meta TEXT 元数据 JSON
create_time DATETIME 创建时间
update_time DATETIME 更新时间
processed_at DATETIME 处理完成时间

索引:idx_endpoint_status(endpoint_name, status)、idx_status(status)、idx_create_time(create_time)。

表名前缀由项目 database.php 的 prefix 决定(如 ws_),模型通过 protected $name = 'webhook_sends' 自动拼接。


CLI 命令

新版本迁移引擎(RegistersMigrations)会直接扫描各包原始迁移目录,因此已发布过迁移后,即使删除复制的迁移文件也可通过 migrate:run 重建。


与其他 wise-* 包协作


目录结构


常见问题

Q: 队列发送模式下如何感知发送结果?

队列模式下闭包回调不可用,请监听 WebhookSent / WebhookFailed 事件。WebhookFailed 的 willRetry 属性可判断是否还有重试机会,willRetry=false 时即为最终失败。

Q: 发送失败后会自动重试吗?

会。同步模式 dispatchSync() 内部不会自动重试(一次 send() 即抛异常,由调用方决定),但队列模式 CallWebhookJob::fire() 会依据 max_retries 与退避策略延迟重试,超出次数后删除任务(可结合 WebhookFailed 事件监控)。

Q: 如何切换全局默认发送模式为队列?

修改 config/wise-webhook.php:

之后所有 dispatch() 将默认走队列。亦可单次调用 ->dispatchToQueue() 覆盖。

Q: 自定义端点如何接收?

  1. 在 config/wise-webhook.php 的 client.endpoints 增加端点(含 signing_secret);
  2. 定义路由并挂载 VerifyWebhookSignature 中间件(通用 :endpoint 或显式 :name);
  3. 控制器中 WebhookClient::receiver()->receive($request, $endpoint);
  4. 实现 WebhookProcessorInterface 并在端点配置指定 processor_class。

Q: 不需要签名校验的公开 Webhook 端点怎么办?

不要配置 signing_secret(为空则验证失败并拒绝),或完全不加 VerifyWebhookSignature 中间件、直接调用 WebhookReceiver::receive()。若需校验可选用自定义 SignatureValidatorInterface。

Q: 为什么发送请求被拒绝了?

CallWebhookJob::sendRequest() 内置 SSRF 防护,会拒绝向 127.0.0.0/8、10.0.0.0/8、172.16.0.0/12、192.168.0.0/16、169.254.0.0/16、0.0.0.0/8、100.64.0.0/10 等内部/保留网段发送。生产环境请使用公网地址;本地联调如需关闭,需调整代码或使用 verifySsl(false) 仅关闭 SSL(不关闭 SSRF)。

Q: 表前缀如何配置?

遵循 ThinkPHP 约定,在 database.php 的 prefix 配置(如 ws_),模型会自动拼接为 ws_webhook_sends / ws_webhook_receives。


依赖关系

必需(require)

依赖 版本要求 说明
php >= 7.4 核心语言
topthink/framework ^6.0 || ^8.0 ThinkPHP 框架
ext-json * JSON 编码/解码
ext-curl * HTTP 请求底层
wise-support(monorepo 内) * 退避、熔断、异常、服务注册等共享能力

可选(suggest)

依赖 说明
topthink/think-queue 用于异步发送和处理 Webhook(强烈建议)
topthink/think-migration 用于数据库迁移建表

开发依赖(require-dev)

依赖 版本 说明
phpunit/phpunit ^9.0 单元测试
mockery/mockery ^1.5 Mock 框架

迁移


许可证

Apache-2.0 License


更多信息请参考 WiseAdmin 框架文档及相关演示插件。


All versions of wise-webhook with dependencies

PHP Build Version
Package Version
Requires php Version >=8.1
topthink/framework Version ^8.0
ext-json Version *
ext-curl Version *
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package wiseadmin/wise-webhook contains the following files

Loading the files please wait ...