Reputation: 31
I have integrated Stripe in my symfony project for subscriptions, the subscription to plans from stripe and payment it works just fine, but the problem is that i couldn't implement the webhook in the right way so i can know if a subscription is created, payed etc.
what i have done so far: in my subscription controller i created the route to the webhook:
class SubscriptionController extends AbstractController
{
/**
* webhook page
*
* @Route("/bonsai_webhook",name="webhookPage")
*/
public function bonsai_webook(Request $request,Response $response){
\Stripe\Stripe::setApiKey('sk_test_...');
$webhookSecret = "whsec_...";
$event = $request->query;
// Parse the message body and check the signature
$signature = $request->headers->get('stripe-signature');
if ($webhookSecret) {
try {
$event = \Stripe\Webhook::constructEvent(
$request->getcontent(),
$signature,
$webhookSecret
);
} catch (\Exception $e) {
return new JsonResponse([['error' => $e->getMessage(),'status'=>403]]);
}
} else {
$request->query;
}
$type = $event['type'];
$object = $event['data']['object'];
$manager = $this->getDoctrine()->getManager();
$today = date("Y-m-d",strtotime('today'));
switch ($type) {
case 'checkout.session.completed':
// Payment is successful and the subscription is created.
// You should provision the subscription.
$user->setSubEndDate($today);
$manager->persist($user);
$manager->flush();
break;
case 'invoice.paid':
// Continue to provision the subscription as payments continue to be made.
// Store the status in your database and check when a user accesses your service.
// This approach helps you avoid hitting rate limits.
break;
case 'invoice.payment_failed':
// The payment failed or the customer does not have a valid payment method.
// The subscription becomes past_due. Notify your customer and send them to the
// customer portal to update their payment information.
break;
// ... handle other event types
default:
// Unhandled event type
}
return new JsonResponse([['session'=>$session,'status'=>200]]);
}
when i run./stripe listen --forward-to https://localhost:8000/bonsai_webhook
and try to create a subscription i got
customer.created [evt_1IYs4HKoLZxEIn3zDY5tFGZV]
2021-03-25 13:13:41 [307] POST http://localhost:8000/bonsai_webhook [evt_1IZ2SeKoLZxEIn3zvx1urxJ1]
and in in the webhook route i got [{"error":"Unable to extract timestamp and signatures from header","status":403}]
there is no stripe signature is always empty , and i don't know what i did wrong.
i also added some logs
$logger->info($request->headers->get('stripe-signature'),$request->headers->all());
$logger->error($request->headers->get('stripe-signature'),$request->headers->all());
$logger->critical($request->headers->get('stripe-signature'),$request->headers->all());
and i did never receive the logs from the trigger create.subscription.event
so my question is: how to get the stripe signature ? and i hope its the only thing missing in my code.
Thank you.
Upvotes: 2
Views: 2569
Reputation: 2518
In a more recent version of stripe
(e.g. 1.11.0 and above) the certificate check can be skipped using --skip-verify
.
So in any case someone is stumble upon the same issue like the author:
# listen on HTTPS but do not verify SSL/TLS certificate
stripe listen --forward-to https://localhost:8000/bonsai_webhook --skip-verify
Upvotes: 1
Reputation: 31
I just figure it out with the help of the stripe communit, my server was trying to redirect to a https:// URL(that's what the 307 redirect is). Setting https:// in the webhook URL doesn't work because it's a self-signed certificate. And the solution was to disable SSL/HTTPS entirely on the local application, instead i switched to an https environement on a server .
Upvotes: 0
Reputation: 6495
The error you're seeing indicates the HTTPS certificate you're using locally isn't recognized as valid by Stripe CLI.
I recommend trying the command with http://
instead of https://
:
./stripe listen --forward-to http://localhost:8000/bonsai_webhook
If your web server allows insecure local connections that should get things working.
Upvotes: 2