I'm working on a project which has two types of products: subscriptions and event registration.
I'm using Stripe Checkout Session for both. As their process is different, I'm using two webhooks; one for each.
e.g:
http://example.com/payment/subscription_webhooks.php
http://example.com/payment/event_webhooks.php
The problem is that once a checkout session is completed, whatever if it's for subscriptions or event registration, both webhooks are triggered.
I'm looking for a solution to define which webhook should be triggered.
Have 1 end point for both session.complete triggers, but send metadata to the endpoint and throw an IF statement into your listener so you can see which session you're listening for.
Here is some code I wrote up.
Checkout Session A:
$checkout_session = \Stripe\Checkout\Session::create([
'payment_method_types' => ['card'],
'line_items' => [[
'price_data' => [
'currency' => 'gbp',
'unit_amount' => '1000',
'product_data' => [
'name' => 'Example Product',
],
],
'quantity' => 1,
]],
'metadata' => ["session" => "session_a"],
'mode' => 'payment',
'success_url' => "https://www.example.co.uk/success",
'cancel_url' => "https://www.example.co.uk/cancel",
]);
Checkout Session B:
$checkout_session = \Stripe\Checkout\Session::create([
'payment_method_types' => ['card'],
'line_items' => [[
'price_data' => [
'currency' => 'gbp',
'unit_amount' => '1000',
'product_data' => [
'name' => 'Example Product',
],
],
'quantity' => 1,
]],
'metadata' => ["session" => "session_b"],
'mode' => 'payment',
'success_url' => "https://www.example.co.uk/success",
'cancel_url' => "https://www.example.co.uk/cancel",
]);
Take note that the metadata is different in the 2 above examples.
Now, use SWITCH and CASE to find which one you're listening for.
Webhook
$payload = @file_get_contents('php://input');
$event = null;
try {
$event = \Stripe\Event::constructFrom(json_decode($payload, true));
} catch(\UnexpectedValueException $e) {
http_response_code(400);
exit();
}
switch($event->data->object->metadata['package']) {
case 'session_a':
// Do your Session A stuff, SQL etc
break;
case 'session_b':
// Do your Session B stuff, SQL etc
}
Some useful tips:
You can pass the session ID from your checkout.session start through to your success page or hook, then grab data...
Checkout session page
'success_url' => "https://www.example.co.uk/success?session_id={CHECKOUT_SESSION_ID}",
session_id={CHECKOUT_SESSION_ID} is exactly as I've written it, you don't actually need to enter the checkout session ID, just literally copy it exactly like its written.
Hook page or Success page
if($_GET['session_id']){
$session_id = $_GET['session_id'];
}
$stripe = new \Stripe\StripeClient('API key');
$session_data = $stripe->checkout->sessions->retrieve($session_id,[]);
$payment_status = $session_data->payment_status;
$payment_address0 = $session_data->shipping->name;
$payment_address1 = $session_data->shipping->address->line1;
$payment_address2 = $session_data->shipping->address->line2;
$payment_address3 = $session_data->shipping->address->city;
$payment_address4 = $session_data->shipping->address->country;
$payment_address5 = $session_data->shipping->address->postal_code;
$payment_buyer_email = $session_data->customer_details->email;
$payment_metadata = $session_data->metadata->user_id;
You can grab data, just checkout the Stripe docs for the JSON response.
Anyone learning Stripe, all seems real confusing, but keep trying, testing, var_dump your results etc and you'll soon see what's happening.
You only need 1 webhook endpoint, then you handle switch case (or if else) for each event of these subscription (subscriptions and event registration in your case).
And i as you, i don't know how to distinguish what event for subscriptions, and what for event registration.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With