在使用 spatie webhook 客户端和 ngrok 测试 webhook 时,我一直找不到 404

I keep getting 404 not found while testing webhook with spatie webhook client and ngrok

我正在使用带有 ngrok 和 spatie webhook-client 的支付网关 Paystack 测试 webhook,我的路由在 route/api.php。当事件被触发时,我在状态响应中不断收到 404 not found。但是,如果将 webhook 路由移动到 web.php 路由,我会收到响应 419 未知状态。不知道为什么。 拜托我是新手,下面就来学习一下吧。

**Route in api.php**

Route::webhooks('paystack-webhook');

VerifyCsrfToken.php

protected $except = [
    'https://17c5dbf1bd87.ngrok.io/paystack/webhook',
];

webhook-client.php

  <?php

  return [
      'configs' => [
      [
            /*
             * This package supports multiple webhook receiving endpoints. If you only have
             * one endpoint receiving webhooks, you can use 'default'.
            */
            'name' => 'default',

            /*
             * We expect that every webhook call will be signed using a secret. This secret
             * is used to verify that the payload has not been tampered with.
            */
            'signing_secret' => env('PAYSTACK_SECRET_KEY'),

            /*
             * The name of the header containing the signature.
            */
            'signature_header_name' => 'x-paystack-signature',

            /*
             *  This class will verify that the content of the signature header is valid.
             *
             * It should implement \Spatie\WebhookClient\SignatureValidator\SignatureValidator
            */
            'signature_validator' => App\Handler\CustomSignatureValidator::class,

            /*
             * This class determines if the webhook call should be stored and processed.
            */
            'webhook_profile' => \Spatie\WebhookClient\WebhookProfile\ProcessEverythingWebhookProfile::class,

            /*
             * This class determines the response on a valid webhook call.
            */
            'webhook_response' => \Spatie\WebhookClient\WebhookResponse\DefaultRespondsTo::class,

            /*
             * The classname of the model to be used to store call. The class should be equal
             * or extend Spatie\WebhookClient\Models\WebhookCall.
            */
            'webhook_model' => \Spatie\WebhookClient\Models\WebhookCall::class,

            /*
             * The class name of the job that will process the webhook request.
             *
             * This should be set to a class that extends \Spatie\WebhookClient\ProcessWebhookJob.
            */
             'process_webhook_job' => App\Handler\ProcessWebhook::class,
        ],
    ],
];

ProcessWebhook.php

<?php

namespace App\Handler;

//App/Handler/ProcessWebhook.php
use \Spatie\WebhookClient\ProcessWebhookJob;

//The class extends "ProcessWebhookJob" class as that is the class 
//that will handle the job of processing our webhook before we have 
//access to it.class ProcessWebhook extends ProcessWebhookJob

class ProcessWebhook extends ProcessWebhookJob
{

    public function handle() {

        $data = json_decode($this->webhookCall, true);
        //Do something with the event

        logger($data['payload']);
        http_response_code(200); //Acknowledge you received the response
    }
}

CustomSignatureValidator.php

<?php

//App/Handler/CustomSignatureValidator.php


namespace App\Handler;

use Illuminate\Http\Request;

use Spatie\WebhookClient\Exceptions\WebhookFailed;

use Spatie\WebhookClient\WebhookConfig;

use Spatie\WebhookClient\SignatureValidator\SignatureValidator;


class PaystackSignature implements SignatureValidator
{

    public function isValid(Request $request, WebhookConfig $config): bool
    {
        $signature = $request->header($config->signatureHeaderName);
    
        if (! $signature) {
            return false;
        }
 
        $signingSecret = $config->signingSecret;

        if (empty($signingSecret)) {
     
            throw WebhookFailed::signingSecretNotSet();
        }
 
        $computedSignature = hash_hmac('sha512', $request->getContent(), $signingSecret);
 
        return hash_equals($signature, $computedSignature);
    }
}

回应

路由列表

你在这里有些地方不匹配。假设您想通过 web 处理 webhook。那么你必须在你的 web.php 文件中放置一条路线。 (如果您使用域路由,请确保将其放在路由文件的底部,或者为了安全起见,将其放在底部)

Route::webhooks('paystack/webhook');

然后将该路由添加到您的验证 csrf 中间件,除了

protected $except = [
    'paystack/*',
];

然后您的 paystack 网络钩子 url 将是

ngrock-generated-host/paystack/webhook

现在如果你想通过 api 处理它然后把路由放在 api.php 文件

Route::webhooks('paystack/webhook');

你不需要把它放在 verify csrf 中间件之外,因为它会被 api 处理。你的 paystack 网络钩子 url 将是

ngrock-generated-host/api/paystack/webhook