I am testing webhook with payment gateway Paystack with ngrok and spatie webhook-client, with my route in the route/api.php. and I keep getting 404 not found at the status response when the event is triggered. But if the webhook route is moved to web.php route I get response 419 unknown state. don't know why. Please I am new to all these just following to learn.
**Route in api.php**
Route::webhooks('paystack-webhook');
and 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);
}
}
Response
Route List
you are mismatching some things here. let's say you want to handle the webhook through web. then you have to put a route in your web.php
file. (make sure to put it at the bottom of your route file if you use domain routing or to be safe put it just at the bottom)
Route::webhooks('paystack/webhook');
then add that route to your verify csrf middleware except
protected $except = [
'paystack/*',
];
and then your webhook url for paystack will be
ngrock-generated-host/paystack/webhook
now if you want to handle it through api then put the route at api.php
file
Route::webhooks('paystack/webhook');
you need not to put it at the except of verify csrf middleware as it will be handled with api. and your webhook url for paystack will be
ngrock-generated-host/api/paystack/webhook