#sameed-editz_webhooks

1 messages · Page 1 of 1 (latest)

uneven spadeBOT
#

👋 Welcome to your new thread!

⏲️ We'll be here soon! Typically we respond in a few minutes, but sometimes we might take a bit longer if the server is busy or if you have a particularly tricky question.

⏱️ We close idle threads, which makes them read-only. Once a thread is closed it won't be reopened, but you can always start a new thread if you have another question.

🔗 This thread will always be available, even after it's closed. You can find it again using Discord's search, or you can save this link: https://discord.com/channels/841573134531821608/1336635325946269767

📝 Have more to share? Add more details, code, screenshots, videos, etc. below.

upbeat current
#

Hi, let me help you with this.

frail ferry
#

hii

upbeat current
#

On which object do you set the metadata?

frail ferry
#

can i send u the laravel cashier code?

#
public function checkout(Plan $plan)
    {
        if (!$plan) {
            return redirect()->route('pricing');
        }

        /** @var \App\Models\User $user **/
        $user = Auth::user();

        try {
            if ($plan->lifetime) {
                $checkoutSession = $user->checkout($plan->stripe_plan_id, [
                    'success_url' => route('checkout.success') . '?session_id={CHECKOUT_SESSION_ID}', // Route to redirect to after a successful payment
                    'cancel_url' => route('checkout.cancel'),
                    'metadata' => [
                        'plan_id' => $plan->id,
                        'lifetime' => true
                    ],
                ]);
            } else {
                $checkoutSession = $user->newSubscription('default', $plan->stripe_plan_id)
                    ->checkout([
                        'success_url' => route('checkout.success') . '?session_id={CHECKOUT_SESSION_ID}', // Route to redirect to after a successful payment
                        'cancel_url' => route('checkout.cancel'),
                        'metadata' => [
                            'plan_id' => $plan->id,
                        ],
                    ]);
            }

            session(['checkout_session_id' => $checkoutSession->id]);

            return $checkoutSession;
        } catch (\Exception $e) {
            Log::error('Checkout failed: ' . $e->getMessage());
            return redirect()->route('pricing')->with([
                'status' => 'error',
                'message' => 'Checkout process failed. Please try again.',
            ]);
        }
    }
#

hey?

#

how about i explain what am i doing?

upbeat current
#

You're trying to get the metadata from the Checkout Session, right?

frail ferry
#

im trying to get the meta data on charge.succeed webhook

#

that i pass during the checkout session

#

how about i explain the code? for you

upbeat current
#

I don't need that, thanks.

frail ferry
#

okay

upbeat current
#

This means the metadata exists on the Checkout Session object.
You need to fetch the Checkout Session object, and you will be able to see the metadata.

#

I suggest you to listen to checkout.session.completed Event instead, which contains the Checkout Session object.

frail ferry
#

uhm it exists on checkout session object but i dont want it from there

#

actually the thing is in my code, i have a event listener that listens for webhook events

if (!in_array($eventType, [
            'customer.subscription.created',
            'customer.subscription.updated',
            'customer.subscription.deleted'
        ])) {
            return;
        }

as u already know whenever a subscription is created or updated then the checkout session is also called and when i do single product checkout then the checkout session is also recieved how i can difference between the which type of checkout session i have received, i would like to see, is it a subscription checkout session or a single product checkout session

uneven spadeBOT
frail ferry
#

@upbeat current @left basin uhm sorry for mentioning? but...

left basin
#

hi! I'm taking over this thread.

frail ferry
#

okay sorry vanya

upbeat current
upbeat current
#

What do you mean?

frail ferry
# frail ferry ``` public function checkout(Plan $plan) { if (!$plan) { ...

let me explain what this part of code is doing

im using laravel 11 with mysql database

i have a plans table that have a column named lifetime as boolean and every plan have stripe price id also with it

if that plan is supposed to be a lifetime plan that would include a price id of a one-off price/fee

and my code will generate a checkout session of a product not a subscription one

and if that plan is supposed to be a subscription typa one then my code will generate a checkout session of subscription one

so now im having a problem

i have listener fro stripe webhooks that listens for stripe events

if the incoming event is a between any of these

'customer.subscription.created',
'customer.subscription.updated',

i would assume that a user bought a subscription plan or completed a subscription checkout session

what if i receive a event named as

charge.succeeded

then i would assume that user completed product typa checkout session and i would like to take the meta data passed on that checkout session to proceed to save the purchase record in my database table

but im having a problem here that charge.succeed event doesnt have any type of meta data with it

#

@left basin @upbeat current

left basin
#

if you are using Checkout Session, then the main even you should listen to is checkout.session.completed. with this event you can know what exactly the customer bought, and check the metadata stored on the Checkout Session.

frail ferry
left basin
#

the payload of the event contains a full Checkout Session object. there you can see the mode of the Session (payment or subscription), and also see the exact Product/Price sold

frail ferry
#

let me check that

#

by this?

left basin
#

I don't understand your question

frail ferry
#

lol

#

thanks

#

sorry for it

#

thank you for helping

#

have a nice day

#

brooooooooooo im tried of finding a solution

#

i need help

left basin
#

I'm happy to help. what's your question?

frail ferry
#

i already explained man

left basin
#

did you try what I suggested above?

the payload of the event contains a full Checkout Session object. there you can see the mode of the Session (payment or subscription), and also see the exact Product/Price sold

frail ferry
#

okay ill try this also

#

oh yes

#

it worked

#

it provided a mode

#

which indicates

#

is it a payment or subscription

left basin
#

yep 🙂

frail ferry
#

but bro

#

i have aquestion

frail ferry
#

when a subscription is renewed like example
3 feb is renewel date of user subscrition and user payment method is charged then what type of webhook events are called?

#

would the checkout.session.completed is called then at that moment?

left basin
frail ferry
#

what

left basin
#

what's your question?

frail ferry
#

then what type of event should i listen?

#

what type of event should i listen that would include the price details and meta data on a product checkout or subscription checkout
and also when a subscription is renewed or cancel or deleted?

left basin
#

it depends on what you want to do.

  • to track new subscriptions: checkout.session.completed (which contains a Checkout Session in the payload)
  • to track recurring payments of existing subscriptions invoice.paid (which contains an Invoice in the payload, but you can make extra API calls to retrieve the corresponding Checkout Session if needed)
  • to track deleted subscriptions: customer.subscriptions.deleted (which contains a Subscription in the payload, but you can make extra API calls to retrieve the corresponding Checkout Session if needed)
frail ferry
#

hey

#
'customer.subscription.created',
'customer.subscription.updated',
#

are these gets called when a subscription is created or renewed?

left basin
#

I'm not sure I understand the question.

  • customer.subscription.created -> when subscription is created
  • customer.subscription.updated -> when subscription is updated
#

but if you are using Checkout Session you should ignore customer.subscription.created

frail ferry
#

okay

uneven spadeBOT
frail ferry
#

@carmine pulsar hey brother can u understand my code? i have some question regarding it, its laravel/php code

carmine pulsar
#

What's the question?

frail ferry
#

i have a stripe webhook listener

#

The listener only processes three specific Stripe events:

checkout.session.completed
customer.subscription.updated
customer.subscription.deleted
How It Routes Events:

If the event type is checkout.session.completed, it calls the handleCheckoutSessionCompleted() method.
If the event is either customer.subscription.updated or customer.subscription.deleted, it routes the event to the appropriate method:
handleSubscriptionUpdated() for updates.
handleSubscriptionDeleted() for deletions.
2. Handling the Checkout Session Completed Event
Method: handleCheckoutSessionCompleted()

Purpose:
This event is triggered when a customer successfully completes a Checkout session in Stripe. It carries metadata that you set during session creation.

What It Does:

Retrieves the Stripe Customer ID:
It extracts the customer ID from the session and looks up the corresponding user in your database.

Retrieves Metadata:
It checks the session's metadata to determine:

The plan_id (to identify which plan was purchased).
Whether the purchase is a lifetime purchase (by checking if lifetime is set to 'true').
Plan Lookup:
It retrieves the plan from your local database using the provided plan_id.

Processing Based on Purchase Type:

Lifetime Purchase:
If the plan is marked as lifetime:
It deletes all previous purchase records for that user.
It creates a new purchase record with an expires_at date set to a far-future date (or null if you prefer) and marks it as a lifetime purchase.
Recurring Subscription:
If the purchase is for a subscription:
It calculates a new expiration date based on the plan's duration (using your helper method).
It then creates a new purchase record with that expiration date, marking it as a recurring subscription.

#
  1. Handling the Subscription Updated Event
    Method: handleSubscriptionUpdated()

Purpose:
This event is fired when a customer’s subscription is updated—this could be due to a renewal, an upgrade/downgrade, or any other change.

What It Does:

Retrieves Customer and Plan Information:
It extracts the customer ID from the subscription payload and uses it to find the user. It then extracts the price ID (assumed to be from the first item in the subscription) and looks up the corresponding plan in your database.

Extends the Subscription:
It then finds an active purchase for the user (i.e., one that has not expired) and calculates a new expiration date by adding the plan’s duration to the current expiration date. The purchase record is then updated with the new expiration date.

  1. Handling the Subscription Deleted Event
    Method: handleSubscriptionDeleted()

Purpose:
This event is triggered when a customer's subscription is deleted or canceled.

What It Does:

Retrieves the Customer:
It obtains the customer ID from the event payload and locates the corresponding user.

Marks Purchases as Inactive:
It then updates all active purchase records for that user, marking them as inactive to reflect that the subscription is no longer in effect.

#

is it enough for a subscription management renewel or creation and product payments?

carmine pulsar
#

Sorry, that's just a huge wall of text. What's the specific issue?

frail ferry
#

ahh

#

actually im working with stripe with first time

#

and i have implemented a stripe webhook listener

#

that listens for 3 events

'checkout.session.completed',
'customer.subscription.updated',
'customer.subscription.deleted'

and im using the first checkout session event for first time subscription or product checkouts
and using the subscritpion updated when a subscription is renewed as far i got to know about this event and last one for when subscription ends

#

are there any more do i need to listen?

carmine pulsar
#

You should use invoice.paid instead of customer.subscription.updated

frail ferry
#

but invoice.paid is always gets called even with first time subscriptions or product checkouts

carmine pulsar
carmine pulsar
frail ferry
carmine pulsar
#

Yep

frail ferry
#

can u explain these four reasons

subscription: No longer in use. Applies to subscriptions from before May 2018 where no distinction was made between updates, cycles, and thresholds.
subscription_create: A new subscription was created.
subscription_cycle: A subscription advanced into a new period.
subscription_threshold: A subscription reached a billing threshold.
subscription_update: A subscription was updated.

carmine pulsar
#

I think they're explained there, no?

frail ferry
#

what does it mean by cycle?

carmine pulsar
#

Oh, that's what you want actually

#

i.e when the new billing period starts (next month or whatever)

frail ferry
#

so i should only listen for this and ignore the rest

carmine pulsar
#

You probably want update to in scenarios where a customer may upgrade/downgrade their sub and generates a new invoice

frail ferry
carmine pulsar
#

Then it'd be subscription_cycle

frail ferry
#

and update one for when is it upgrade or downgrade

carmine pulsar
#

Yes

frail ferry
#

hey brother how to test subscriptions using this clock i cant understand it still

carmine pulsar
#

Did you follow the guide?

frail ferry
#

yeah i created one

carmine pulsar
#

Created what?