How is your route defined for the webhook?
Stripe Webhooks and Auth
Hi, I intend to utilise webhooks on Stripe to keep my data relatively in sync with the stripe system. Particularly when it comes to whole or partial refunds. I have tried sending test webhooks to my application and they keep being routed to a login page. I am using the "out of the box" authentication provided by Laravel via the command "php artisan make:auth" How would I exclude my webhooks route from the auth middleware, and still keep my database secure?
/* Stripe Webhooks */ Route::post('/stripe/webhook', 'WebhooksController@handle');
Can you post your WebhooksController?
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class WebhooksController extends Controller
{
public function handle()
{
dd(request()->all());
}
}
assign the guest middleware to your controller , that could work?
public function __construct() {
$this->middleware('guest');
}
@vapenation I would actually go further, because I am paranoid. ;-)
I would create a new middleware that checks the IP address of the requester to make sure it is an actual Stripe webhook call.
Both good calls @vapenation & @kobear. I'll take a look once I have completed the bit of the project I am currently working on.
You can use webhook handler of the cashier package
https://laravel.com/docs/5.4/billing#handling-stripe-webhooks
Hey James, did you ever get this figured out, I am having the same issue.
Yeah, I'd suggest the Cashier package as well. You don't have to use all of it, but its webhook management is great. Basically you just add a row to your routes that looks like Route::stripeWebhooks('webhook-from-stripe'); or similar. Then you can have a config object that looks like:
return [
'signing_secret' => $signSecret,
'model' => App\Models\System\StripeWebhookCall::class,
'jobs' => [
// HandleAccountEvent
'account.application.authorized' => App\Jobs\StripeWebhooks\HandleAccountEvent::class,
'account.updated' => App\Jobs\StripeWebhooks\HandleAccountEvent::class,
// HandleBalanceEvent
'balance_available' => App\Jobs\StripeWebhooks\HandleBalanceEvent::class,
// HandleChargeableEvent
'source_chargeable' => App\Jobs\StripeWebhooks\HandleChargeableSource::class,
(etc...)
And then your actual jobs would be something like:
public function handle ()
{
switch ($this->type) {
case 'customer.source.created':
$this->customerSourceCreated();
break;
case 'customer.updated':
$this->customerUpdated();
break;
case 'customer.deleted':
$this->customerDeleted();
break;
case 'customer.created':
$this->customerCreated();
break;
}
}
/**
* @throws \App\Exceptions\Webhooks\WebhookDetailNotFound
*/
protected function customerSourceCreated ()
{
$this->getUserFrom('data.object.customer');
if (CustomerSource::addSource($this->payload) === true) {
Log::info('[' . $this->webhookCall->id . '] New funding source added for ' . $this->user->name . '.');
} else {
Log::error($this->id . 'Source could not be added to customer.');
}
}
If you do decide to go this route, here's a tip that I learned the hard way... Build a StripeWebhookHandler class and have other classes that extend it (one for accounts, one for customers, one for subscriptions, one for billing, etc), because you're going to want to split these things up but still allow them to share some features, like the following __construct method:
/**
* StripeHandler constructor.
*
* @param \App\Models\System\StripeWebhookCall $stripeWebhookCall
*/
public function __construct (StripeWebhookCall $stripeWebhookCall)
{
$this->webhookCall = $stripeWebhookCall;
$this->payload = array_dot($this->webhookCall->payload);
$this->type = $this->payload['type'];
$this->queue = 'StripeQueue';
}
I've been working with Laravel/Stripe integrations for the past year, so feel free to ask me if you have any questions! :)
Please or to participate in this conversation.