Giter VIP home page Giter VIP logo

laravel-stripe-webhooks's Introduction

Handle Stripe Webhooks in a Laravel application

Latest Version on Packagist GitHub Workflow Status Check & fix styling Total Downloads

Stripe can notify your application of events using webhooks. This package can help you handle those webhooks. Out of the box it will verify the Stripe signature of all incoming requests. All valid calls will be logged to the database. You can easily define jobs or events that should be dispatched when specific events hit your app.

This package will not handle what should be done after the webhook request has been validated and the right job or event is called. You should still code up any work (eg. regarding payments) yourself.

Before using this package we highly recommend reading the entire documentation on webhooks over at Stripe.

Support us

We invest a lot of resources into creating best in class open source packages. You can support us by buying one of our paid products.

We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on our contact page. We publish all received postcards on our virtual postcard wall.

Upgrading

Please see UPGRADING for details.

Installation

You can install the package via composer:

composer require spatie/laravel-stripe-webhooks

The service provider will automatically register itself.

You must publish the config file with:

php artisan vendor:publish --provider="Spatie\StripeWebhooks\StripeWebhooksServiceProvider"

This is the contents of the config file that will be published at config/stripe-webhooks.php:

return [
    /*
     * Stripe will sign each webhook using a secret. You can find the used secret at the
     * webhook configuration settings: https://dashboard.stripe.com/account/webhooks.
     */
    'signing_secret' => env('STRIPE_WEBHOOK_SECRET'),

    /*
     * You can define a default job that should be run for all other Stripe event type
     * without a job defined in next configuration.
     * You may leave it empty to store the job in database but without processing it.
     */
    'default_job' => '',

    /*
     * You can define the job that should be run when a certain webhook hits your application
     * here. The key is the name of the Stripe event type with the `.` replaced by a `_`.
     *
     * You can find a list of Stripe webhook types here:
     * https://stripe.com/docs/api#event_types.
     */
    'jobs' => [
        // 'source_chargeable' => \App\Jobs\StripeWebhooks\HandleChargeableSource::class,
        // 'charge_failed' => \App\Jobs\StripeWebhooks\HandleFailedCharge::class,
    ],

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

    /**
     * This class determines if the webhook call should be stored and processed.
     */
    'profile' => \Spatie\StripeWebhooks\StripeWebhookProfile::class,

    /*
     * Specify a connection and or a queue to process the webhooks
     */
    'connection' => env('STRIPE_WEBHOOK_CONNECTION'),
    'queue' => env('STRIPE_WEBHOOK_QUEUE'),

    /*
     * When disabled, the package will not verify if the signature is valid.
     * This can be handy in local environments.
     */
    'verify_signature' => env('STRIPE_SIGNATURE_VERIFY', true),
];

In the signing_secret key of the config file you should add a valid webhook secret. You can find the secret used at the webhook configuration settings on the Stripe dashboard.

Next, you must publish the migration with:

php artisan vendor:publish --provider="Spatie\WebhookClient\WebhookClientServiceProvider" --tag="webhook-client-migrations"

After the migration has been published you can create the webhook_calls table by running the migrations:

php artisan migrate

Finally, take care of the routing: At the Stripe dashboard you must configure at what url Stripe webhooks should hit your app. In the routes file of your app you must pass that route to Route::stripeWebhooks:

Route::stripeWebhooks('webhook-route-configured-at-the-stripe-dashboard');

Behind the scenes this will register a POST route to a controller provided by this package. Because Stripe has no way of getting a csrf-token, you must add that route to the except array of the VerifyCsrfToken middleware:

protected $except = [
    'webhook-route-configured-at-the-stripe-dashboard',
];

Usage

Stripe will send out webhooks for several event types. You can find the full list of events types in the Stripe documentation.

Stripe will sign all requests hitting the webhook url of your app. This package will automatically verify if the signature is valid. If it is not, the request was probably not sent by Stripe.

Unless something goes terribly wrong, this package will always respond with a 200 to webhook requests. Sending a 200 will prevent Stripe from resending the same event over and over again. Stripe might occasionally send a duplicate webhook request more than once. This package makes sure that each request will only be processed once. All webhook requests with a valid signature will be logged in the webhook_calls table. The table has a payload column where the entire payload of the incoming webhook is saved.

If the signature is not valid, the request will not be logged in the webhook_calls table but a Spatie\StripeWebhooks\WebhookFailed exception will be thrown. If something goes wrong during the webhook request the thrown exception will be saved in the exception column. In that case the controller will send a 500 instead of 200.

There are two ways this package enables you to handle webhook requests: you can opt to queue a job or listen to the events the package will fire.

Handling webhook requests using jobs

If you want to do something when a specific event type comes in you can define a job that does the work. Here's an example of such a job:

<?php

namespace App\Jobs\StripeWebhooks;

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`
    }
}

We highly recommend that you make this job queueable, because this will minimize the response time of the webhook requests. This allows you to handle more stripe webhook requests and avoid timeouts.

After having created your job you must register it at the jobs array in the stripe-webhooks.php config file. The key should be the name of the stripe event type where but with the . replaced by _. The value should be the fully qualified classname.

// config/stripe-webhooks.php

'jobs' => [
    'source_chargeable' => \App\Jobs\StripeWebhooks\HandleChargeableSource::class,
],

In case you want to configure one job as default to process all undefined event, you may set the job at default_job in the stripe-webhooks.php config file. The value should be the fully qualified classname.

By default, the configuration is an empty string '', which will only store the event in database but without handling.

// config/stripe-webhooks.php
'default_job' => \App\Jobs\StripeWebhooks\HandleOtherEvent::class,

Handling webhook requests using events

Instead of queueing jobs to perform some work when a webhook request comes in, you can opt to listen to the events this package will fire. Whenever a valid request hits your app, the package will fire a stripe-webhooks::<name-of-the-event> event.

The payload of the events will be the instance of WebhookCall that was created for the incoming request.

Let's take a look at how you can listen for such an event. In the EventServiceProvider you can register listeners.

/**
 * The event listener mappings for the application.
 *
 * @var array
 */
protected $listen = [
    'stripe-webhooks::source.chargeable' => [
        App\Listeners\ChargeSource::class,
    ],
];

Here's an example of such a listener:

<?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`
    }
}

We highly recommend that you make the event listener queueable, as this will minimize the response time of the webhook requests. This allows you to handle more Stripe webhook requests and avoid timeouts.

The above example is only one way to handle events in Laravel. To learn the other options, read the Laravel documentation on handling events.

Advanced usage

Retry handling a webhook

All incoming webhook requests are written to the database. This is incredibly valuable when something goes wrong while handling a webhook call. You can easily retry processing the webhook call, after you've investigated and fixed the cause of failure, like this:

use Spatie\WebhookClient\Models\WebhookCall;
use Spatie\StripeWebhooks\ProcessStripeWebhookJob;

dispatch(new ProcessStripeWebhookJob(WebhookCall::find($id)));

Performing custom logic

You can add some custom logic that should be executed before and/or after the scheduling of the queued job by using your own model. You can do this by specifying your own model in the model key of the stripe-webhooks config file. The class should extend Spatie\StripeWebhooks\ProcessStripeWebhookJob.

Here's an example:

use Spatie\StripeWebhooks\ProcessStripeWebhookJob;

class MyCustomStripeWebhookJob extends ProcessStripeWebhookJob
{
    public function handle()
    {
        // do some custom stuff beforehand

        parent::handle();

        // do some custom stuff afterwards
    }
}

Determine if a request should be processed

You may use your own logic to determine if a request should be processed or not. You can do this by specifying your own profile in the profile key of the stripe-webhooks config file. The class should implement Spatie\WebhookClient\WebhookProfile\WebhookProfile.

In this example we will make sure to only process a request if it wasn't processed before.

use Illuminate\Http\Request;
use Spatie\WebhookClient\Models\WebhookCall;
use Spatie\WebhookClient\WebhookProfile\WebhookProfile;

class StripeWebhookProfile implements WebhookProfile
{
    public function shouldProcess(Request $request): bool
    {
        return ! WebhookCall::where('payload->id', $request->get('id'))->exists();
    }
}

Handling multiple signing secrets

When using Stripe Connect you might want to the package to handle multiple endpoints and secrets. Here's how to configurate that behaviour.

If you are using the Route::stripeWebhooks macro, you can append the configKey as follows:

Route::stripeWebhooks('webhook-url/{configKey}');

Alternatively, if you are manually defining the route, you can add configKey like so:

Route::post('webhook-url/{configKey}', '\Spatie\StripeWebhooks\StripeWebhooksController');

If this route parameter is present the verify middleware will look for the secret using a different config key, by appending the given the parameter value to the default config key. E.g. If Stripe posts to webhook-url/my-named-secret you'd add a new config named signing_secret_my-named-secret.

Example config for Connect might look like:

// secret for when Stripe posts to webhook-url/account
'signing_secret_account' => 'whsec_abc',
// secret for when Stripe posts to webhook-url/connect
'signing_secret_connect' => 'whsec_123',

Transforming the Webhook payload into a Stripe Object

You can transform the Webhook payload into a Stripe object to assist in accessing its various methods and properties.

To do this, use the Stripe\Event::constructFrom($payload) method with the WebhookCall's payload:

use Stripe\Event;

// ...

public function handle(WebhookCall $webhookCall)
{
    /** @var \Stripe\StripeObject|null */
    $stripeObject = Event::constructFrom($webhookCall->payload)->data?->object;
}

For example, if you have setup a Stripe webhook for the invoice.created event, you can transform the payload into a StripeInvoice object:

/** @var \Stripe\StripeInvoice|null */
$stripeInvoice = Event::constructFrom($webhookCall->payload)->data?->object;

// $stripeInvoice->status
// $stripeInvoice->amount_due
// $stripeInvoice->amount_paid
// $stripeInvoice->amount_remaining

foreach ($stripeInvoice->lines as $invoiceLine) {
    // ...
}

About Cashier

Laravel Cashier allows you to easily handle Stripe subscriptions. You may install it in the same application together with laravel-stripe-webhooks. There are no known conflicts.

Changelog

Please see CHANGELOG for more information about what has changed recently.

Testing

composer test

Contributing

Please see CONTRIBUTING for details.

Security

If you've found a bug regarding security please mail [email protected] instead of using the issue tracker.

Credits

A big thank you to Sebastiaan Luca who generously shared his Stripe webhook solution that inspired this package.

License

The MIT License (MIT). Please see License File for more information.

laravel-stripe-webhooks's People

Contributors

adrianmrn avatar aerni avatar akoepcke avatar alexvanderbist avatar andzandz avatar ankurk91 avatar brendt avatar diogogomeswww avatar faks avatar flatcapco avatar freekmurze avatar jaulz avatar juukie avatar kduma avatar keatliang2005 avatar khuthaily avatar laravel-shift avatar mansoorkhan96 avatar maximepvrt avatar mstaack avatar patinthehat avatar riasvdv avatar rubenvanassche avatar ryanito avatar sebastiandedeyne avatar srmklive avatar stefanzweifel avatar stevebauman avatar travisobregon avatar wanghanlin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

laravel-stripe-webhooks's Issues

laravel 7 support

When does laravel 7 will be supported?

spatie/laravel-stripe-webhooks 2.2.0 requires illuminate/support ~5.8.0|^6.0 -> satisfiable by laravel/framework[6.x-dev], illuminate/support[5.8.x-dev, 6.x-dev, v5.8.0, v5.8.11, v5.8.12, v5.8.14, v5.8.15, v5.8.17, v5.8.18, v5.8.19, v5.8.2, v5.8.20, v5.8.22, v5.8.24, v5.8.27, v5.8.28, v5.8.29, v5.8.3, v5.8.30, v5.8.31, v5.8.32, v5.8.33, v5.8.34, v5.8.35, v5.8.36, v5.8.4, v5.8.8, v5.8.9, v6.0.0, v6.0.1, v6.0.2, v6.0.3, v6.0.4, v6.1.0, v6.10.0, v6.11.0, v6.12.0, v6.13.0, v6.13.1, v6.14.0, v6.15.0, v6.15.1, v6.16.0, v6.17.0, v6.17.1, v6.18.0, v6.18.1, v6.18.10, v6.18.11, v6.18.12, v6.18.13, v6.18.14, v6.18.15, v6.18.16, v6.18.17, v6.18.18, v6.18.19, v6.18.2, v6.18.20, v6.18.21, v6.18.22, v6.18.23, v6.18.24, v6.18.25, v6.18.26, v6.18.27, v6.18.28, v6.18.29, v6.18.3, v6.18.30, v6.18.31, v6.18.32, v6.18.33, v6.18.34, v6.18.35, v6.18.36, v6.18.4, v6.18.5, v6.18.6, v6.18.7, v6.18.8, v6.18.9, v6.2.0, v6.3.0, v6.4.1, v6.5.0, v6.5.1, v6.5.2, v6.6.0, v6.6.1, v6.6.2, v6.7.0, v6.8.0].
- spatie/laravel-stripe-webhooks 2.2.1 requires illuminate/support ~5.8.0|^6.0 -> satisfiable by laravel/framework[6.x-dev], illuminate/support[5.8.x-dev, 6.x-dev, v5.8.0, v5.8.11, v5.8.12, v5.8.14, v5.8.15, v5.8.17, v5.8.18, v5.8.19, v5.8.2, v5.8.20, v5.8.22, v5.8.24, v5.8.27, v5.8.28, v5.8.29, v5.8.3, v5.8.30, v5.8.31, v5.8.32, v5.8.33, v5.8.34, v5.8.35, v5.8.36, v5.8.4, v5.8.8, v5.8.9, v6.0.0, v6.0.1, v6.0.2, v6.0.3, v6.0.4, v6.1.0, v6.10.0, v6.11.0, v6.12.0, v6.13.0, v6.13.1, v6.14.0, v6.15.0, v6.15.1, v6.16.0, v6.17.0, v6.17.1, v6.18.0, v6.18.1, v6.18.10, v6.18.11, v6.18.12, v6.18.13, v6.18.14, v6.18.15, v6.18.16, v6.18.17, v6.18.18, v6.18.19, v6.18.2, v6.18.20, v6.18.21, v6.18.22, v6.18.23, v6.18.24, v6.18.25, v6.18.26, v6.18.27, v6.18.28, v6.18.29, v6.18.3, v6.18.30, v6.18.31, v6.18.32, v6.18.33, v6.18.34, v6.18.35, v6.18.36, v6.18.4, v6.18.5, v6.18.6, v6.18.7, v6.18.8, v6.18.9, v6.2.0, v6.3.0, v6.4.1, v6.5.0, v6.5.1, v6.5.2, v6.6.0, v6.6.1, v6.6.2, v6.7.0, v6.8.0].
- Can only install one of: laravel/framework[6.x-dev, v7.26.0].

Maximum execution time of 60+2 seconds exceeded

Hi!

I just installed your package and tried to get it up and running. When I did however, I started getting the following exception:

Fatal error: Maximum execution time of 60+2 seconds exceeded (terminated) in /Users/WesleyIntranet/Projects/vetona/vendor/stripe/stripe-php/lib/HttpClient/CurlClient.php on line 254

This happens when I press the submit button on my form and try to create a stripe source.

Is this a known issue or should I investigate further?

Thanks!

This library not work in php 7.4

Getting a issue on
ParseError
syntax error, unexpected '$url' (T_VARIABLE), expecting ')'

::Composer\Autoload\includeFile
vendor/spatie/laravel-webhook-client/src/WebhookClientServiceProvider.php:28

Route::macro('webhooks', fn (string $url, string $name = 'default') => Route::post($url, '\Spatie\WebhookClient\WebhookController')->name("webhook-client-{$name}"));

My version is PHP 7.4.24 (cli) (built: Sep 26 2021 20:47:23) ( NTS )
Laravel Version is v8.61.0

phpinfo()
PHP Version => 7.4.24

Composer.lock
"name": "spatie/laravel-webhook-client",
"version": "2.7.5",

Not hitting job?

Hi. I've installed the package and all works bar when i call a job to be fired on the webhook.

If i fire the charge.succeeded test in Stripe it hits the server and adds a entry into the database, but it completely bypasses the config.jobs

use App\Jobs\StripeWebhooks\HandleFailedCharge;
use App\Jobs\StripeWebhooks\HandleSucceededCharge;

'jobs' => [
        // 'source_chargeable' => \App\Jobs\StripeWebhooks\HandleChargeableSource::class,
        'charge_failed' => HandleFailedCharge::class,
        'charge_succeeded' => HandleSucceededCharge::class,
    ],

The Succeeded charge job as a temporary thing should Log the id and return a response, but it doesnt do either:

<?php

namespace App\Jobs\StripeWebhooks;

use App\Models\Admin\Ledger;
use App\Models\User;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;
use Mail;
use Spatie\StripeWebhooks\StripeWebhookCall;

class HandleSucceededCharge implements ShouldQueue
{
	use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

	/** @var \Spatie\StripeWebhooks\StripeWebhookCall */
	public $webhookCall;

	public function __construct(StripeWebhookCall $webhookCall)
	{
		$this->webhookCall = $webhookCall;
	}

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {

    	\Log::info('Charge Succeeded for - ' . $this->webhookCall->payload['data']['object']['id']);
    	$user_id = Ledger::where('transaction_id',$this->webhookCall->payload['data']['object']['id'])->pluck('user_id')->first();
    	$user = User::where('id', $user_id)->first();

    	Log::info($user);
    	return new Response('Payment Succeeded Success - ' . json_encode($payload['data']['object']['id'] ), 200);
    }
}

Any ideas ?

Cheers

Payment intent listener not been fired

hi, i'm trying to manage a payment_intent.succeeded event... in my event listenet provider i have

'stripe-webhooks::payment_intent.succeeded' => [
            'App\Listeners\SuccededSourceListener',
],

but my listenet is never fired... the webhook is correctly implemented, infact if i try with a Stripe WebHook test, the request is 200 with a json message ''ok''
any idea?

thanks a lot

Support for Multiple Signing Secrets?

Hi there, great package!

I see the signing secret is put into the config as a single key/value. What if we have multiple signing secrets for multiple environments and endpoints? Looks like config only supports a single signing key.

I could workaround this by extending, but would rather not.

Multiple webhook secret key

Hello dear and thanks for your module.

I am sorry but i really don't understand what to do with multiple webhook secret.

It can be really usefull if you can just add to me a little explanation.

I have 2 webhook with 2 secrets :

1 for charge.succeeded
2 for customer.subscription.created

My Routes on file web.php is configured like that :

Route::stripeWebhooks('success-paid/{configKey}');
Route::stripeWebhooks('success-subscription/{configKey}');

Url of webhook in stripe are :

https://mydomain.name/success-paid/charge
https://mydomain.name/success-paid/subs

Now what i really don't understand is WHERE i have to specifiy the two secret keys ? I put information on config/stripe-webhook.php :

'signing_secret_charge' => env('STRIPE_WEBHOOK_SECRET'),
'signing_secret_subs' => env('STRIPE_WEBHOOK_SECRET_SUBS'),

But the web hook isn't reachable and i am lost

Thanks a lot it can be usefull for other people too ;)

Support for PHP8

This package does not presently support PHP8. I was going to do a pull request, but I saw that the tests in the package test for Laravel 6, which presents dependency issues.

Perhaps bump this package to version 3.0 and drop support for older PHP/Laravel versions.

Is there a way to specify queue categories while dispatching webhook jobs?

Hie,

By default the ProcessStripeWebhookJob stores queues as 'default' and related job in config files do the same.

I was able to extend ProcessStripeWebhookJob and specify onQueue method on related jobs attached on config file as below

dispatch(new $jobClass($this->webhookCall))->onQueue('high');

But, the ProcessStripeWebhookJob when called is set to default. Even if I extend it, i will mess up with other part of the code.

Please help us specify onQueue on these jobs.

Thanks

The signature is invalid when doing valet share and stripe cli

Ok, I am not sure what I am missing but I get the signature is invalid on the cli test.
Here are my steps:

  1. valet share mysite.test
    I get
ngrok by @inconshreveable                                                                                                                                                                   (Ctrl+C to quit)

Session Status                online
Account                       John H (Plan: Free)
Version                       2.3.35
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://randomgunk.ngrok.io -> http://birdies.test:60
Forwarding                    https://randomgunk.ngrok.io -> http://birdies.test:60
  1. start up stripe listen --forward-to https://randomgunk.ngrok.io/api/v1/stripe
Ready! Your webhook signing secret is whsec_MYSUPERSECRETKEY (^C to quit)
  1. I add that key in my stripe-webhooks.php
'signing_secret' => 'whsec_MYSUPERSECRETKEY',
  1. finally I push the stripe trigger
stripe trigger invoice.payment_failed

I get 500 errors for everything and ngrok reports:


    "class": "Spatie\\WebhookClient\\Exceptions\\WebhookFailed",
    "message": "The signature is invalid.",
    "code": 0,
    "file": "/Users/John/code/curriki-pledge/vendor/spatie/laravel-webhook-client/src/Exceptions/WebhookFailed.php:11",

Funny thing is - If I put https://randomgunk.ngrok.io/api/v1/stripe in stripe dashboard as the webhook and send a test (using the dashboard webkey) it comes back 200?

PHP 7.3 and Laravel 7.6.1

Is there an option to install using those versions? Probably I will upgrade to PHP 7.4 tho.
cheers

Job class not found

Using version 2.5, Laravel 8, PHP 8.

When the web hook is sent, my application responds with:

{
  "error": "Could not process webhook id `9` of type ` because the configured jobclass `App\\Jobs\\StripeWebhooks\\HandleCheckoutSessionComplete` does not exist."
}

I have confirmed the job class definitely exists. Previously, on Laravel 5.8 and package version 2.1 everything worked fine, but since updating I get the above error.

Need Help on Laravel publishing

After running
composer require spatie/laravel-stripe-webhooks command i published it through php artisan vendor:publish --provider="Spatie\StripeWebhooks\StripeWebhooksServiceProvider" --tag="migrations" command but no migration related to this is genrsted nor any config file

invoice.payment_succeeded

Dear,

How do I handle an event that get's sent to the laravel-stripe-webhooks handler that contains an underscore in it's event type? (eg. invoice.payment_succeeded)

I have tried:
'invoice.payment\_succeeded' => \App\Jobs\StripeInvoicePaymentSucceeded::class,
'invoice.payment_succeeded' => \App\Jobs\StripeInvoicePaymentSucceeded::class,
'invoice.paymentsucceeded' => \App\Jobs\StripeInvoicePaymentSucceeded::class,
'invoice.paymentSucceeded' => \App\Jobs\StripeInvoicePaymentSucceeded::class,
All of the above seem to have failed to trigger the actual job so far. They do appear in the webhook_calls table though.

With kind regards,

Andries Verbanck

Make webhook job queueable

Reading the docs I saw:

We highly recommend that you make this job queueable, because this will minimize the response time of the webhook requests. This allows you to handle more stripe webhook requests and avoid timeouts.

I have setup my jobs excatly like in the documentation, and my queues are set to use beanstalkd. Is there anything else I need to do in order to make my webhooks queueable?

Does it support webhooks for Stripe Connect?

Hello,

First, I want to thank you for your different packages. It helps me a lot as a freelancer.

I'm also using Stripe Connect but I do not see the option to add the secret key to use the webhook with Connect. It's a missing feature?

thank you

No return with test webhook

Hello,
I installed this good package but i have a problem with catching test webhook.
I tried to test catching webhook with an event and with a job but when i do a test on stripe i have a good answer (200) but no return.
I'm on laravel 5.7 with laravel stripe webhooks 1.1.1

I have this job in use

<?php

namespace App\Jobs\StripeWebhooks;

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Spatie\StripeWebhooks\StripeWebhookCall;
use Illuminate\Http\Request;
use Stripe\Stripe;
use Stripe\Charge;
use App\Models\Centre;

class HandleCustomerSubscriptionCreated implements ShouldQueue
{
    use InteractsWithQueue, Queueable, SerializesModels;

    /** @var \Spatie\StripeWebhooks\StripeWebhookCall */
    public $webhookCall;


    public function __construct(StripeWebhookCall $webhookCall)
    {
        $this->webhookCall = $webhookCall;

    }

    public function handle()
    {

        return "plop";
    }


}

And i tried with this event

<?php

namespace App\Listeners;


use Spatie\StripeWebhooks\StripeWebhookCall;

class HandleCustomerSubscriptionCreated
{
    public function handle(StripeWebhookCall $webhookCall)
    {
        return 'plop99';
    }
}

Event is in eventprovider

protected $listen = [
       'stripe-webhooks::customer.subscription.created' => [\App\Listeners\HandleCustomerSubscriptionCreated::class,],
'stripe-webhooks::source.chargeable' => [ \App\Listeners\ChargeSource::class,],
   ];

And job in stripe-webhooks.php

'jobs' => [
       /// 'source_chargeable' => \App\Jobs\HandleChargeableSource::class,
     'customer_subscription_created' => \App\Jobs\StripeWebhooks\HandleCustomerSubscriptionCreated::class,
    ],

This error is the same to this issue #36 but i don't have CASHIER_ENV=testing in my .env.
I have cleared cache.

If i try to do same thing with redirect route directly to a simple controller i have the correct return but when i use Jobs or event i can't do it.
I think i forget something somewhere but i don't found what. An idea ?

Spatie\WebhookClient\ProcessWebhookJob not found

I´ve got the error message Class \"Spatie\\WebhookClient\\ProcessWebhookJob\" not found at ...\\app\\Handler\\WebhookHandler.php:7.

WebhookHandler.php

<?php

namespace App\Handler;

use Spatie\WebhookClient\Jobs\ProcessWebhookJob;

class WebhookHandler extends ProcessWebhookJob
{
	public function handle()
	{
		//...
	}
}

How you can see, I´ve changed the path to Spatie\WebhookClient\Jobs\ProcessWebhookJob, because that is where the file is actually located. Now it works.

Maybe it should be changed in the documentation.

And thank you for this package!

401 (Unauthorized)

Hello, I'm stuck with webhook integration on my app.
I got always a 401 (Unauthorized) error.

What can I do?

(this happen also with empy job)

Migration not publishable

Heya, thanks for another awesome piece of software. I'm having an issue publishing the migration in a Laravel 8.54 setup:

$ php artisan vendor:publish --provider="Spatie\WebhookClient\WebhookClientServiceProvider" --tag="webhook-client-migrations"       
                                                                                                                                                                                                                                                              
No publishable resources for tag [webhook-client-migrations].
Publishing complete.

The package is installed properly and I can see the stub in vendor/spatie/laravel-webhook-client/database/migrations but it just doesn't want to be published :-(

Thanks for any help!

Pelle

PHP ^7.4 being used for spatie, but doesn't work with Laravel ^7.0.

syntax error, unexpected '$url' (T_VARIABLE), expecting ',' or ')' {"exception":"[object] (ParseError(code: 0): syntax error, unexpected '$url' (T_VARIABLE), expecting ',' or ')' at /home/vagrant/code/beastlybot/vendor/spatie/laravel-webhook-client/src/WebhookClientServiceProvider.php:28)

This is because you are using PHP 7.4 => functionality for short-handing functions. However, Laravel 7 doesn't seem tow ork with PHP 7.4, only ^7.2.

Webhook signature failed

Webhook Signature fails for me:

I have an activated Stripe account, using test environment keys I have added values to
STRIPE_KEY= STRIPE_SECRET= STRIPE_WEBHOOK_SECRET=
from appropriate webhook to .env and ran
artisan config:clear

Yet when I test through Stripe, I get the signature failed exception

The signature is invalid.

On Laravel Homestead. Laravel 7.

Added to VerifyCsrfToken Middleware

protected $except = [ 'stripe_webhooks' ];

At the top of my web.php routes file
Route::stripeWebhooks('stripe_webhooks');

Here' some error info.
The signature is invalid. {"exception":"[object] (Spatie\\WebhookClient\\Exceptions\\WebhookFailed(code: 0): The signature is invalid. at /home/vagrant/code/beastlybot/vendor/spatie/laravel-webhook-client/src/Exceptions/WebhookFailed.php:11)

Getting signature is invalid error in Test mode

Getting invalid signature error when triggering webhook call from Stripe dashboard. The signing_secret matches in both stripe dashboard and in code but still getting this issue all the time.

Job doesn't run

I've checked some issues about jobs and there is no answer that could solve the problem.

I did everything like in docs and Stripe CLI responses with 200 on every event, including charge.succeeded

Here is my stripe-webhooks.php:
Screenshot from 2020-06-22 14-14-38

You may say: "Clear the cache!", but I've already done it by running this:
php artisan cache:clear && php artisan route:clear && php artisan config:clear && php artisan view:clear && clear && php artisan serve

As you can see it clears all the caches. But if you don't believe me, here is the proof from tinker:
Screenshot from 2020-06-22 14-26-26

Here is the job (HandleSucceededCharge.php is located at App/Jobs/StripeWebhooks)
Screenshot from 2020-06-22 14-18-41

I tried to insert \Log::info('I am here, look!');, but it doesn't log anything, anywhere.

If you need anything else to see, be kind to ask, thanks.

Exception after upgrading Stripe from 2018-08-23 to 2018-09-06

Hello,

Immediately after upgrading my Stripe API version from 2018-08-23 to 2018-09-06, I started getting the following exception in my Laravel app:

The signature t=1536815026,v1=XXXXXXXXx found in the header named Stripe-Signature is invalid. Make sure that the services.stripe.webhook_signing_secret config key is set to the value you found on the Stripe dashboard. If you are caching your config try running php artisan cache:clear to resolve the problem.

Of course I tried php artisan cache:clear, without luck. I also verified the webhook signing secret in my Stripe dashboard and it seems to be correct.

Is there something specific to do when upgrading the Stripe API version?

Thanks,
Nicolas

Protect from duplicate events

This package doesn't seem to be safe from duplicate events. This could probably be implemented fairly easily by checking the id in the payload column of the webhook_calls table against the incoming webhook id.

I'm happy to draft a PR.

Typed property Spatie\WebhookClient\ProcessWebhookJob::$webhookCall must be an instance of Spatie\WebhookClient\Models\WebhookCall

So i keep getting this error when ever im trying make a source.charge

Typed property Spatie\WebhookClient\ProcessWebhookJob::$webhookCall must be an instance of Spatie\WebhookClient\Models\WebhookCall
I get this error when at the stripe dashboard.

I am using the 2.2.1 version since im still on laravel 5.8. But i have no idea what im doing wrong?

In my web.php i added the stripe-webhook
My config is as follow:
`<?php

return [

'signing_secret' => env('STRIPE_WEBHOOK_SK'),

'jobs' => [
    'source_chargeable' => \App\Jobs\StripeWebhooks\HandleChargeableSource::class,
    'charge_succeeded' => \App\Jobs\StripeWebhooks\HandleSucceededCharge::class,
],

'model' => \Spatie\StripeWebhooks\ProcessStripeWebhookJob::class,

];
`

But it doesnt even hit on of these jobs, what am i missing?

queue_connection sync vs database

Hi.
Thanks for reading my comment.
I have been using the wonderful package in my laravel project. currently the project is in development phase.
I am having a big confusion about (queue_connection sync vs database), I have read in multiple places that sync runs the Job on main thread and is not recommended for production.

Now, Suppose that the project is on production server with queue_connection=sync and 100 customers performs some action and generate 300 events. The project has subscribed to those events, now when all those events come and we have sync, most of them would be timed out and failed in stripe dashboard because the main thread would be blocked for couple of events and most of them would wait and in meantime the request would time out.
Am I right about this ?

What should be done in order to avoid this behavior and be able to entertain

  • multiple webhook events even though one event take ~10 second
  • Giving users the access to website as well so they can use the website normally.

P.S : This is my first time opening issue or comment. I apologize in advance for my bad English.

Error 404 when I try to handle stripe event

Hello,

I'm newbie with this package and I've some issue that I don't understand...

I follow exactly the readme file and I got a 404 error when I try to handle the stripe event with Stripe CLI.

I redirect the event with :

stripe listen --events checkout.session.completed --skip-verify --forward-to https://backend.bnb.local/api/webhook/checkout

and I have that in return :

> Ready! Your webhook signing secret is whsec_mSz72pL***************641iqZ7 (^C to quit) 2020-06-09 16:38:09 --> \checkout.session.completed\ [\evt_1Gs8aaLGS8l*******7PkQZPgp3\] 2020-06-09 16:38:09 <-- [404] POST https://backend.bnb.local/api/webhook/checkckout [\evt_1Gs8aaLGS*****k7PkQZPgp3\]

In my routes/api files :

Route::stripeWebhooks('https://backend.bnb.com/api/webhook/checkout');

In my EventServiceProvider :

protected $listen = [ 'stripe-webhooks::checkout.session.completed' => [ App\Listeners\HandleSubscriptions::class ] ];

I probably do something wrong but I don't find why...

How can I use this on Laravel 5.5?

php artisan vendor:publish --provider="Spatie\WebhookClient\WebhookClientServiceProvider" --tag="migrations"

isn't bringing over the migration so I am assuming 5.5 is too old to use? Is there a way to still use this with Laravel 5.5?

Jobs never called

Hi

Here ismy config

'jobs' => [
// 'source_chargeable' => \App\Jobs\StripeWebhooks\HandleChargeableSource::class,
// 'charge_failed' => \App\Jobs\StripeWebhooks\HandleFailedCharge::class,
'invoice_payment_action_required' => \App\Jobs\StripeWebhooks\HandlePaymentActionRequiredInvoice::class,
'invoice_payment_failed' => \App\Jobs\StripeWebhooks\HandlePaymentFailedInvoice::class
],

I can send webhook test from stripe. It seems to be ok and save in DB in table webhook_calls.

But The job never handle the event, any idea ?

Laravel 6 support

Hello Spatie,

This package currently throws an error when installed on a fresh Laravel 6 application.

Would be awesome if you could update the package's requirements soon after Laravel 6 ships next week!

Thank you and all the best,
Nicolas

Rejecting a webhook

Hi

I might be missing something really obvious here but I hit on this yesterday.

When testing I was occasionally receiving webhooks out of sequence from stripe. Eg: a subscription.updated hook came before the subscription.created.

Normally I’d deal with that by sending a non 200 response to stripe on the updated hook and that would cause it to retry again later, typically after the creation book has been received.

What’s the best way forward with this package to implement the same behaviour?

Failed install on laravel 5.7.3 when trying to update to 1.2.0

Hello,
I'm trying to install version 1.2.0 on my laravel project (5.7.3) but it is giving me some errors.
I've allready installed version 1.1.4 but when i try to update i get the following error.

`
Your requirements could not be resolved to an installable set of packages.

Problem 1
- Installation request for spatie/laravel-stripe-webhooks 1.2.0 -> satisfiable by spatie/laravel-stripe-webhooks[1.2.0].
- Conclusion: remove laravel/framework v5.7.3
- Conclusion: don't install laravel/framework v5.7.3
- spatie/laravel-stripe-webhooks 1.2.0 requires illuminate/support ~5.8.0 -> satisfiable by laravel/framework[5.8.x-dev], illuminate/support[5.8.x-dev, v5.8.0, v5.8.2, v5.8.3, v5.8.4].
- Can only install one of: laravel/framework[5.8.x-dev, v5.7.3].
- don't install illuminate/support 5.8.x-dev|don't install laravel/framework v5.7.3
- don't install illuminate/support v5.8.0|don't install laravel/framework v5.7.3
- don't install illuminate/support v5.8.2|don't install laravel/framework v5.7.3
- don't install illuminate/support v5.8.3|don't install laravel/framework v5.7.3
- don't install illuminate/support v5.8.4|don't install laravel/framework v5.7.3
- Installation request for laravel/framework (locked at v5.7.3, required as 5.7.*) -> satisfiable by laravel/framework[v5.7.3].
`

Is this a problem on my side or did the update break something?

Thanks,

Configuring Webhook endpoint URL correctly - and disabling Cashier default

Once you set the webhooks URL, how do you disable the default Cashier URL of /stripe/webhook?

According to the installation steps, you define your webhook APi endpoint like this:

In routes/web.php:

Route::stripeWebhooks('my_stripe_webhooks_endpoint');

In the VerifyCsrfToken middleware:

protected $except = [
    'my_stripe_webhooks_endpoint',
];

Now, when I use the stripe-cli (on localhost) and run stripe listen (and forward events to http://localhost:8000/my_stripe_webhooks_endpoint, as specified in the Stripe docs, I see a 500 POST response. Why, and how do i turn it to a 200 response that Stripe needs to see?

^COneStepAtATime:kb_backend_apis_laravel$ stripe listen --forward-to http://localhost:8000/my_stripe_webhooks_endpoint
> Ready! Your webhook signing secret is whsec_ER94Uk56z5nlcKrD1OREbX2Q9e1LgEXg (^C to quit)
2020-05-11 17:33:48   --> payment_intent.created [evt_0Ghm46DXGF9cqh5pIZatClX2]
2020-05-11 17:33:48  <--  [500] POST http://localhost:8000/my_stripe_webhooks_endpoint [evt_0Ghm46DXGF9cqh5pIZatClX2]
2020-05-11 17:35:58   --> payment_intent.created [evt_0Ghm6DDXGF9cqh5pdW88RL1W]
2020-05-11 17:35:58  <--  [500] POST http://localhost:8000/my_stripe_webhooks_endpoint [evt_0Ghm6DDXGF9cqh5pdW88RL1W]

On the other hand, this (Default) Cashier webhook route: stripe/webhook is still enabled, and responds with a 200 status code! Logs below from performing the same operation, except I forward the webhook events to /stripe/webhook:

How can I disable this default Cashier route, and make the one I want to use return a 200 response?

^COneStepAtATime:kb_backend_apis_laravel $ stripe listen --forward-to http://localhost:8000/stripe/webhook
> Ready! Your webhook signing secret is whsec_Ex94Uk56z5nlcKrD1OREbXVQ9e1LgEXg (^C to quit)
2020-05-11 17:51:46   --> payment_method.attached [evt_0GhmLTDXGF9cqh5p67406apI]
2020-05-11 17:51:46  <--  [200] POST http://localhost:8000/stripe/webhook [evt_0GhmLTDXGF9cqh5p67406apI]
2020-05-11 17:51:50   --> customer.source.created [evt_0GhmLTDXGF9cqh5pUVdieeIT]
2020-05-11 17:51:50  <--  [200] POST http://localhost:8000/stripe/webhook [evt_0GhmLTDXGF9cqh5pUVdieeIT]

Job call

I understand, here is teh exception

Symfony\Component\Debug\Exception\FatalThrowableError: Argument 1 passed to App\Jobs\StripeWebhooks\HandlePaymentFailedInvoice::__construct() must be an instance of App\Jobs\StripeWebhooks\WebhookCall, instance of Spatie\WebhookClient\Models\WebhookCall given, called in E:\Walky\walky\vendor\spatie\laravel-stripe-webhooks\src\ProcessStripeWebhookJob.php on line 28 in E:\Walky\walky\app\Jobs\StripeWebhooks\HandlePaymentFailedInvoice.php:25
Stack trace:

And the code

use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Spatie\WebhookClient\Models\WebhookCall;

class HandlePaymentActionRequiredInvoice implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

/** @var \Spatie\WebhookClient\Models\WebhookCall */
public $webhookCall;

/**
 * Create a new job instance.
 *
 * @return void
 */
public function __construct(WebhookCall $webhookCall)
{
    $this->webhookCall = $webhookCall;
}

/**

Custom exceptions in package

hi i am using your package from a while and its doing well , i just need you to help to handle job failed errors for telescope now i am getting 500 but i want to show the webhook name with 500 in telescope , is there any way to get the event name with error thanks

Webhook URL when using with Cashier

Hi,

I know in the readme it states that this package works with cashier. I believe then it should also work with Spark 6, right?

I have a question regarding the webhook url. Can it be the same as cashier/spark uses? or do we have to define a different one and only allow for the events cashier does not handle?

thanks

Error: Operator does not exist: text ->> unknown with latest change on Postgres

With the latest change (#87) we are seeing errors on our Postgres database:

operator does not exist: text ->> unknown
LINE 1: (select * from "webhook_calls" where "payload"->>'id'...

In the original migration, the payload field is defined and created as text. On a Postgres database, you can not use json and jsonb operators on text fields.

You can use the operator in question if we first cast the "payload" to ::json, but this may not apply to all database types... for example:

select "payload"->>'id' from webhook_calls;
-- vs
select "payload"::json->>'id' from webhook_calls;

Am I missing an upgrade step? For now I created a custom StripeWebhookProfile with this change... but others may be having a similar issue.

I can't get webhook call.

I can't get webhook call cause HTTP_STRIPE_SIGNATURE that is unavailable to me by
Route::stripeWebhooks('stripe-webhook');

Thanks.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.