I trying to connect 3D secure payment for a website, it is working fine in test environment with test cards but when I switched with live keys, it is not generating pop up to user for confirmation. it complete the payment without confirmation. through this i get the client secret key
$intent = \Stripe\PaymentIntent::create([
'amount' => $amount * 100,
'currency' => $results->currency,
'payment_method' => $paymentMethodId,
'confirmation_method' => 'automatic',
'description' => "Booking",
'customer' => $user_stripe_customer,
'receipt_email' => $user->email,
]);
On clients Side
formsub.addEventListener('submit', function(event) {
event.preventDefault();
// Create a FormData object to gather form data
const formData = new FormData(event.currentTarget);
// Convert form data to a plain JavaScript object
const submitData = Object.fromEntries(formData);
// Disable the button and change its appearance
bookBtn.disabled = true;
bookBtn.innerText = 'Loading';
bookBtn.style.backgroundColor = 'blue';
// Create a PaymentMethod with Stripe
stripe.createPaymentMethod({
type: 'card',
card: card,
}).then(function(result) {
if (result.error) {
console.error(result.error.message);
bookBtn.disabled = false;
bookBtn.innerText = 'Book Now';
bookBtn.style.backgroundColor = '';
errorCard.innerHTML =
`<p style="color:red;">Error: ${result.error.message}</p>`;
} else {
// Call your server to create a PaymentIntent
fetch('/payment', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-CSRF-TOKEN': '{{ csrf_token() }}',
},
body: JSON.stringify({
data: submitData,
payment_method: result.paymentMethod.id,
}), // Sending data as JSON
}).then(function(response) {
return response.json();
}).then(function(data) {
if (data.client_secret) {
stripe.confirmCardPayment(data.client_secret, {
payment_method: result.paymentMethod.id,
}).then(function(confirmResult) {
if (confirmResult.error) {
handleConfirmError(confirmResult);
} else {
handlePaymentSuccess(confirmResult
.paymentIntent);
}
});
} else {
errorCard.innerHTML =
`<p style="color:red;">Error: ${data.message}</p>`;
// Reset button appearance after an error
bookBtn.disabled = false;
bookBtn.innerText = 'Book Now';
bookBtn.style.backgroundColor = '';
}
});
}
});
});
function handleConfirmError(confirmResult) {
if (confirmResult.error.payment_intent &&
confirmResult.error.payment_intent.status === 'requires_action') {
// Handle 3D Secure authentication
stripe.handleCardAction(confirmResult.error.payment_intent.client_secret)
.then(function(actionResult) {
if (actionResult.error) {
console.error(actionResult.error.message);
bookBtn.disabled = false;
bookBtn.innerText = 'Book Now';
bookBtn.style.backgroundColor = '';
errorCard.innerHTML =
`<p style="color:red;">Error: ${actionResult.error.message}</p>`;
} else {
// Re-confirm the PaymentIntent after 3D Secure
stripe.confirmCardPayment(confirmResult.error.payment_intent.client_secret, {
payment_method: result.paymentMethod.id,
}).then(function(result) {
if (result.error) {
console.error(result.error.message);
errorCard.innerHTML =
`<p style="color:red;">Error: ${result.error.message}</p>`;
// Reset button appearance after an error
bookBtn.disabled = false;
bookBtn.innerText = 'Book Now';
bookBtn.style.backgroundColor = '';
} else {
// Payment succeeded, redirect or show success message
console.log(result.paymentIntent);
}
});
}
});
} else {
console.error(confirmResult.error.message);
errorCard.innerHTML = `<p style="color:red;">Error: ${confirmResult.error.message}</p>`;
// Reset button appearance after an error
bookBtn.disabled = false;
bookBtn.innerText = 'Book Now';
bookBtn.style.backgroundColor = '';
}
}
I know some cards don't support 3D but i use a card on other site and it did 3D payment from that site.
It's totally depends on the card issuer to request or doesn't request 3DS on a specific transaction (they hold the final decision).
Your code shouldn't have any issue, but you can look at Stripe Radar setting to loosen the 3DS rules, ie. using "Request 3D Secure if 3D Secure is recommended for card" to request 3DS most frequent as possible.