vanthao03596 / laravel-paddle-webhooks
在 Laravel 应用中处理 paddle webhooks
Requires
- php: ^7.4 || ^8.0
- ext-openssl: *
- illuminate/support: ^7.0|^8.0
- spatie/laravel-webhook-client: ^2.7.4
Requires (Dev)
- nunomaduro/collision: ^3.0|^5.3
- orchestra/testbench: ^4.8|^5.2|^6.0
- phpunit/phpunit: ^9.3
- vimeo/psalm: ^4.8
README
Paddle 可以通过 webhooks 通知您的应用事件。此包可以帮助您处理这些 webhooks。默认情况下,它将验证所有传入请求的 Paddle 签名。所有有效的调用都将记录到数据库中。您可以轻松定义当特定事件触发您的应用时应调度的作业或事件。
此包不会处理在验证 webhook 请求后以及正确调用作业或事件后应该做什么。您仍然需要自己编写任何工作(例如,关于支付的工作)的代码。
强烈建议在使用此包之前阅读 Paddle 上的关于 webhooks 的完整文档。
安装
您可以通过 composer 安装此包
composer require vanthao03596/laravel-paddle-webhooks
服务提供器将自动注册自身。
您必须使用以下命令发布配置文件
php artisan vendor:publish --provider="Vanthao03596\PaddleWebhooks\PaddleWebhooksServiceProvider" --tag="config"
这是将要发布到 config/paddle-webhooks.php
的配置文件内容
这是已发布配置文件的内容
return [ /* * Paddle will sign each webhook using a public key to create signature . You can find the used public key at the * webhook configuration settings: https://vendors.paddle.com/public-key. */ 'signing_secret' => env('PADDLE_PUBLIC_KEY'), /* * You can define the job that should be run when a certain webhook hits your application * here. The key is the name of the Paddle event type. * * You can find a list of Paddle webhook types here: * https://developer.paddle.com/webhook-reference/intro. */ 'jobs' => [ // 'subscription_created' => \App\Jobs\PaddleWebhooks\HandleSubscriptionCreated::class, // 'payment_succeeded' => \App\Jobs\PaddleWebhooks\HandlePaymentSucceeded::class, ], /* * The classname of the model to be used. The class should equal or extend * Vanthao03596\PaddleWebhooks\ProcessPaddleWebhookJob. */ 'model' => \Vanthao03596\PaddleWebhooks\ProcessPaddleWebhookJob::class, /** * This class determines if the webhook call should be stored and processed. */ 'profile' => \Spatie\WebhookClient\WebhookProfile\ProcessEverythingWebhookProfile::class, /* * When disabled, the package will not verify if the signature is valid. * This can be handy in local environments. */ 'verify_signature' => env('PADDLE_SIGNATURE_VERIFY', true), ];
接下来,您必须使用以下命令发布迁移
php artisan vendor:publish --provider="Spatie\WebhookClient\WebhookClientServiceProvider" --tag="migrations"
迁移发布后,您可以通过运行迁移来创建 webhook_calls
表
php artisan migrate
最后,注意路由:在 Paddle 控制台,您必须配置 Paddle webhooks 应该击中您的应用的 URL。在您的应用的 routes 文件中,您必须将此路由传递给 Route::paddleWebhooks
Route::paddleWebhooks('webhook-route-configured-at-the-paddle-dashboard');
幕后,这将在此包提供的控制器上注册一个 POST
路由。因为 Paddle 没有获取 csrf-token 的方法,所以您必须将该路由添加到 VerifyCsrfToken
中间件的 except
数组中
protected $except = [ 'webhook-route-configured-at-the-paddle-dashboard', ];
用法
Paddle 会为几种事件类型发送 webhooks。您可以在 Paddle 文档中找到 事件类型的完整列表。
Paddle 将为击中您的应用 webhook url 的所有请求签名。此包将自动验证签名是否有效。如果签名无效,则请求可能不是由 Paddle 发送的。
除非发生严重错误,否则此包将始终对 webhook 请求响应 200
。发送 200
将防止 Paddle 重复发送相同的事件。所有带有有效签名的 webhook 请求都将记录在 webhook_calls
表中。该表有一个 payload
列,其中保存了传入 webhook 的整个有效负载。
如果签名无效,则请求将不会记录在 webhook_calls
表中,但会抛出一个 Vanthao03596\PaddleWebhooks\Exceptions\WebhookFailed
异常。如果在 webhook 请求过程中发生错误,则抛出的异常将保存在 exception
列中。在这种情况下,控制器将发送 500
而不是 200
。
此包提供两种处理 webhook 请求的方式:您可以选择排队一个作业或监听包将触发的事件。
使用作业处理 webhook 请求
如果您想在特定事件类型到来时执行某些操作,可以定义一个执行该工作的作业。以下是一个此类作业的示例
<?php namespace App\Jobs\PaddleWebhooks; use Illuminate\Bus\Queueable; use Illuminate\Queue\SerializesModels; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Contracts\Queue\ShouldQueue; use Spatie\WebhookClient\Models\WebhookCall; class HandleChargeableSource implements ShouldQueue { use InteractsWithQueue, Queueable, SerializesModels; /** @var \Spatie\WebhookClient\Models\WebhookCall */ public $webhookCall; public function __construct(WebhookCall $webhookCall) { $this->webhookCall = $webhookCall; } public function handle() { // do your work here // you can access the payload of the webhook call with `$this->webhookCall->payload` } }
强烈建议您将此作业设置为可排队,因为这将最小化webhook请求的响应时间。这允许您处理更多的Paddle webhook请求并避免超时。
创建作业后,您必须在paddle-webhooks.php
配置文件的jobs
数组中注册它。键应该是Paddle事件类型的名称,其中,只有履行webhook将返回履行
// config/paddle-webhooks.php 'jobs' => [ 'subscription_created' => \App\Jobs\PaddleWebhooks\HandleSubscriptionCreated::class ],
使用事件处理webhook请求
您可以选择监听此包将触发的事件,而不是在webhook请求到来时排队作业以执行某些工作。每当有效的请求击中您的应用程序时,该包将触发一个paddle-webhooks::<事件名称>
事件。
事件的负载将是为传入请求创建的WebhookCall
实例。
让我们看看如何监听此类事件。在EventServiceProvider
中,您可以注册监听器。
/** * The event listener mappings for the application. * * @var array */ protected $listen = [ 'paddle-webhooks::subscription_created' => [ App\Listeners\ChargeSource::class, ], ];
以下是一个此类监听器的示例
<?php namespace App\Listeners; use Illuminate\Contracts\Queue\ShouldQueue; use Spatie\WebhookClient\Models\WebhookCall; class ChargeSource implements ShouldQueue { public function handle(WebhookCall $webhookCall) { // do your work here // you can access the payload of the webhook call with `$webhookCall->payload` } }
强烈建议您将事件监听器设置为可排队,因为这将最小化webhook请求的响应时间。这允许您处理更多的Paddle webhook请求并避免超时。
上述示例只是Laravel中处理事件的一种方式。要了解其他选项,请阅读Laravel处理事件的文档。
高级用法
重试处理webhook
所有传入的webhook请求都写入数据库。当处理webhook调用时出现问题时,这一点非常有价值。您可以在调查并修复失败原因后轻松重试处理webhook调用,如下所示
use Spatie\WebhookClient\Models\WebhookCall; use Spatie\PaddleWebhooks\ProcessPaddleWebhookJob; dispatch(new ProcessPaddleWebhookJob(WebhookCall::find($id)));
执行自定义逻辑
您可以通过指定自己的模型来在paddle-webhooks
配置文件的model
键中添加一些自定义逻辑,这些逻辑应在排队的作业调度之前和/或之后执行。您可以通过指定自己的模型在paddle-webhooks
配置文件的model
键中这样做。该类应该扩展Spatie\PaddleWebhooks\ProcessPaddleWebhookJob
。
以下是一个示例
use Spatie\PaddleWebhooks\ProcessPaddleWebhookJob; class MyCustomPaddleWebhookJob extends ProcessPaddleWebhookJob { public function handle() { // do some custom stuff beforehand parent::handle(); // do some custom stuff afterwards } }
确定是否应处理请求
您可以使用自己的逻辑来确定是否应处理请求。您可以通过指定自己的配置文件在paddle-webhooks
配置文件的profile
键中这样做。该类应实现Spatie\WebhookClient\WebhookProfile\WebhookProfile
。
Paddle有时可能会发送一个webhook请求超过一次。在这个例子中,我们将确保只有在请求之前未处理的情况下才处理请求。
use Illuminate\Http\Request; use Spatie\WebhookClient\Models\WebhookCall; use Spatie\WebhookClient\WebhookProfile\WebhookProfile; class PaddleWebhookProfile implements WebhookProfile { public function shouldProcess(Request $request): bool { return ! WebhookCall::where('payload->id', $request->get('id'))->exists(); } }
处理多个签名密钥
您可能希望包处理多个端点和密钥。以下是配置该行为的方法。
如果您正在使用Route::paddleWebhooks
宏,您可以按如下方式附加configKey
Route::paddleWebhooks('webhook-url/{configKey}');
或者,如果您正在手动定义路由,您可以像这样添加configKey
Route::post('webhook-url/{configKey}', '\Vanthao03596\PaddleWebhooks\PaddleWebhooksController');
如果此路由参数存在,verify中间件将使用不同的配置密钥查找密钥,即将给定的参数值附加到默认配置密钥上。例如,如果Paddle将请求发送到webhook-url/my-named-secret
,则添加一个名为signing_secret_my-named-secret
的新配置。
Connect的示例配置可能如下所示
// secret for when Paddle posts to webhook-url/account 'signing_secret_account' => 'whsec_abc', // secret for when Paddle posts to webhook-url/connect 'signing_secret_connect' => 'whsec_123',
测试
composer test
变更日志
请参阅CHANGELOG以了解最近的变化。
贡献
请参阅CONTRIBUTING以获取详细信息。
安全漏洞
请参阅我们的安全策略,了解如何报告安全漏洞。
致谢
许可证
MIT 许可证(MIT)。请参阅许可证文件以获取更多信息。