I am migrating a site from using Stripe Checkout v2 to v3 using the client side PHP code (everything here in test mode). I have successfully setup the checkout process and after payment get redirected to the success page.
On the success page I have put the webhook code as I want to validate the payment has been made, then display a form.
The webhook has been setup in the Stripe Dashboard, and is showing as "Succeeded" in the webhook logs.
Here is the PHP code for the checkout:
require('includes/stripe/stripe-v3/init.php');
\Stripe\Stripe::setApiKey('sk_test_...');
$session = \Stripe\Checkout\Session::create([
'payment_method_types' => ['card'],
'line_items' => [[
'name' => 'Example',
'description' => 'Example description',
'images' => ['https://example/com/image.png'],
'amount' => 99,
'currency' => 'gbp',
'quantity' => 1,
]],
'success_url' => 'https://example.com/test-payment.php?checkout=v3&payment=success&session_id={CHECKOUT_SESSION_ID}',
'cancel_url' => 'https://example.com/test-payment?payment=failed',
]);
$session_id = $session->id;
And here's the JavaScript:
var stripe = Stripe('pk_test_4iEnGexyFSJgXFumnmEXWDlG');
function checkout_redirect() {
stripe.redirectToCheckout({
// Make the id field from the Checkout Session creation API response
// available to this file, so you can provide it as parameter here
// instead of the {{CHECKOUT_SESSION_ID}} placeholder.
sessionId: '<?php echo $session_id; ?>'
}).then(function (result) {
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer
// using `result.error.message`.
});
}
Then this is the code to validate the webhook within test-payment.php:
require('includes/stripe/stripe-v3/init.php');
\Stripe\Stripe::setApiKey('sk_test_...');
$endpoint_secret = 'whsec_...';
$payload = @file_get_contents('php://input');
$sig_header = $_SERVER['HTTP_STRIPE_SIGNATURE'];
$event = null;
try {
$event = \Stripe\Webhook::constructEvent(
$payload, $sig_header, $endpoint_secret
);
} catch(\UnexpectedValueException $e) {
// Invalid payload
http_response_code(400); // PHP 5.4 or greater
exit();
} catch(\Stripe\Error\SignatureVerification $e) {
// Invalid signature
http_response_code(400); // PHP 5.4 or greater
exit();
}
// Handle the checkout.session.completed event
if ($event->type == 'checkout.session.completed') {
$session = $event->data->object;
// Fulfill the purchase...
handle_checkout_session($session);
}
http_response_code(200);
When being redirected to test-payment.php it's failing on the "SignatureVerification" with the following error:
exception 'Stripe\Error\SignatureVerification' with message 'Unable to extract timestamp and signatures from header'
I have tried to echo $_SERVER['HTTP_STRIPE_SIGNATURE'] but it's empty, so I'm thinking that might be the problem but am stumped on how to fix it.
Any ideas guys? Or is there an easier way to validate a payment has been made?