Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Hondaman900's avatar

How to handle payload back from Stripe payment link and webhooks

I'm trying to implement Stripe payment links in my project, but am getting stuck trying to process the webhook response and payload. I'm trying to get the webhook response payload with which to complete the transaction in code, but I can't get any life from the job handler.

I know Stripe is working, as the link sends the user to a checkout form which, when completed, sets up a new Stripe account for them and takes the payment. I know laravel-stripe-webhooks is working as the Stripe CLI tells me the transactions are completing and getting a 200 response, and the package is writing the payload to my database. Stripe CLI output I just can't get anything out of the job to run with to complete the coding on my end of the transaction. None of the searches I have done have revealed any answer to my issues.

This is a Laravel 6 project using Spatie's laravel-stripe-webhooks package, running locally with Laragon and using Stripe-CLI to monitor and tunnel Stripe responses. I have a payment link generated by my Stripe account on a page, and a route pointing to stripeWebhooks as required.

My route in web.php

Route::stripeWebhooks('stripe-webhook');

In stripe-webhooks.php

'jobs' => [
			'customer_subscription_created' => \App\Jobs\StripeWebhooks\CustomerSubscriptionCreatedJob::class,
],

In CustomerSubscriptionCreatedJob.php

<?php

namespace App\Jobs\StripeWebhooks;

use App\User;
use App\Payment;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Spatie\WebhookClient\Models\WebhookCall;
use Illuminate\Support\Facades\Log;

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

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


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

    public function handle()
    {
        $charge = $this->webhookCall->payload['data']['object'];
        $payload = $this->webhookCall->payload; //@file_get_contents('php://input');
        dd($payload);
        $user = User::where('stripe_customer_id', $charge['customer'])->first();
        Log::error($charge);
        Log::error($payload);
        if ($user) {
            Payment::create([
                    'user_id' => $user->id,
                    'payment_amount' => $charge['amount'],
                    //'stripe_id' => $charge['id']
                    'role_id' => $user->role_id
            ]);
        }
        
        echo("HELLOOOOO");
        dd($charge);
        // do your work here

        // you can access the payload of the webhook call with `$this->webhookCall->payload`
    }
}`

In my VerifyCsrfToken.php I have:

   protected $except = [
        'stripe-webhook',
        'stripe/*',
        'webhooks/stripe',
    ];

The job should write a new record to my Payment table, which it doesn't. None of the dd() calls above work or do anything. Logging doesn't add to any logs anywhere. I was thinking that since the payment link sends the user to the Stripe website that perhaps the dd() calls had nowhere to render, so I tried outputting to a log, just to get some response from this, to no avail. I'm not getting any errors or any signs of life, but, as mentioned, I know the fundamentals are working up to and including the payload delivery.

What am I missing? I feel like there's a magic key I need to unlock this. I have followed the Stripe and Spatie docs to no avail and am out of options. I just need the payload to process and move forward. Can anyone guide me through this please?

0 likes
10 replies
webrobert's avatar

I think postman will help you. The challenge with webhooks can be you don’t see what is happening.

Hondaman900's avatar

I now have this working and the payload being sent to the logfile. To be honest, I'm not sure what changed, but suspect realigning the Stripe CLI, with the job and the webhook connected some dots and it now works. I must have had a mismatch in the naming between steps.

The part that's still not working is where I check for $user. Inside the job code, Auth::User() returns null. So now I can process the payload, but am stuck trying to figure out how I can get my own user's ID so that I can assign the purchase to their account. Seems like while within the job the user scope is missing...?

[EDIT] In retrospect I believe the reason my job starting working "for no reason" was because I rebooted my dev laptop. I wasn't aware that Laravel jobs are cached and therefore my changes in code weren't propagating through, making debugging impossible. I think the reboot reset everything to the correct code which then started to work. Just adding this to help the next person trolling for answers.

kokoshneta's avatar

@Hondaman900 Your job is called by a webhook request coming from Stripe’s servers – there is no user at all.

Hondaman900's avatar

So how does one connect the current user ID to the purchase? The purchases are make using payment links, so I can't pre-package an identifier into call to Stripe. Would the current browser session be a safe place to hold an identifier to use with the payload data to process the purchase?

The challenge here is that the user, when on the Stripe site in the checkout, could use any email they like with their payment details, so I can't be sure of a unique e-mail to use for a registration, and if it's already used, I don't have a user ID to let them know there's a problem.

How do I programmatically record my user's intent to purchase, and then when Stripe confirms the new customer is set up, connect the two together so that my user owns the account they just purchased? There must be some accepted way to process this faithfully.

Hondaman900's avatar

Thanks @webrobert, that was interesting but the solutions and approaches all required installation of, and specific elements of, Cashier. I can't implement Cashier on this working site.

The Stripe payment links allow a subscription to be paid for with a free-trial baked in. This generates a new account in Stripe for the free trial sub, but I need to let the purchasing user (on my end this can only be purchased by an authenticated user) know they're good and add the new stripe customer ID (from the payload) to the new user's records in my app. That way the user can now access the new account they just purchased and it functions correctly in the app.

It goes like this:

  • User fills out form -> provides me with new account login email to setup new user account in the app
  • User clicks payment link -> Stripe takes card details and sets up new customer on their end with free-trial period
  • Stripe sends back customer-created payload -> I now have confirmation of a payment accepted and a new Stripe customer ID
  • I now need to update new app user record with their new Stripe ID for their account to function as paid-for.

This last step is killing me. I have a new user on my end. I have a new Stripe customer and ID from Stripe. I need to programmatically connect them (i.e., record the new Stripe customer ID in the correct app user record) and ensure I don't connect the wrong user to someone else's purchase.

Is this too risky to pass in a session variable or cookie? Not sure how else to transverse these two systems.

Someone else must have solved this pickle before me and I'm hoping there's an "Ah-hah!" solution that I'm missing.

webrobert's avatar

@Hondaman900 yeah the workflow mentioned is similar... you have to save a token from stripe with the user in step 1 or 2. So you can match it up in the return from stripe.

Hondaman900's avatar

I got it! You CAN add parameters to the Stripe payment link that come back in the payload.

I found this article in the Stripe docs, Use URL parameters to customize the checkout experience

When I started searching on using metadata with Stripe payment links (after your using the word "metadata" above) and found a reference to this resource.

Many thanks, I think I'm good to go now :)

1 like
GvidoBlueFox's avatar

Also, you can get the session ID and save it in your database. You can use this ID to get data at any time.

Please or to participate in this conversation.