payment-details embedded component pops empty, disappear, and re-pops before displaying info about payment
When using the payment-details embedded component (alone, without the payments embedded component)... no matter if called from a button "View payment details" or if executed on page load... it always pops empty, disappear, and re-pops before displaying info about payment. How to fix it?
Stripe talks about this popping behaviour here, but couldn't find a way to actually fix it. https://docs.stripe.com/connect/get-started-connect-embedded-components#reacting-to-component-display PS.: I am using the pure version import { loadConnectAndInitialize } from '@stripe/connect-js/pure';
Could you attach a video of this behavior?
https://github.com/user-attachments/assets/1d37bed4-a802-4149-b809-163772ec3028
This isn't an known issue and seems like a bug, could you provide a small github repo that reproduces this issue? Thanks!
It could be related to the state updated asynchronously (e.g., after an API call). In that case, the component might render before the state is populated, causing it to briefly appear empty and re-render when it is updated.
Hey everyone, I'm getting the same issue. I checked that there're no async state updates.
@dvadri have you found a solution?
Hi guys, I haven't found the solution yet. I'm using Laravel v11:
This is the html of the page from the video:
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0" />
@vite(['resources/css/app.css', 'resources/js/payment.js'])
</head>
<body>
<button id="view" wire:ignore class="m-3 p-3 bg-red-100 rounded">View Payment Details</button> <br>
<div id="spinner" wire:ignore></div>
<div id="payment-details-container" wire:ignore></div>
</body>
</html>
This is the payment.js:
import { loadConnectAndInitialize } from "@stripe/connect-js/pure";
let paymentIntentId = 'pi_example123';
console.log(paymentIntentId);
let shop_id = 'exampleShop123';
console.log(shop_id);
const viewButton = document.getElementById('view');
viewButton.addEventListener('click', function() {
const fetchClientSecret = async () => {
// Fetch the AccountSession client secret
const response = await fetch('/account_session', {
method: "POST",
headers: {
"X-CSRF-TOKEN": "{{ csrf_token() }}",
},
body: JSON.stringify({
shop_id: shop_id,
}),
});
if (!response.ok) {
// Handle errors on the client side here
const {error} = await response.json();
console.error('An error occurred: ', error);
return undefined;
} else {
const {clientSecret: clientSecret} = await response.json();
return clientSecret;
}
}
const stripeConnectInstance = loadConnectAndInitialize({
// This is your test publishable API key.
publishableKey: "pk_test_example123",
fetchClientSecret: fetchClientSecret,
});
// Include this element in your HTML
const paymentDetails = stripeConnectInstance.create('payment-details');
paymentDetails.setPayment(paymentIntentId);
const container = document.getElementById("payment-details-container");
container.appendChild(paymentDetails);
// use setOnClose to set a callback function to close payment-details
paymentDetails.setOnClose(() => {
paymentDetails.remove();
});
});
This is the app.js (that Laravel uses):
import './bootstrap';
import { loadConnectAndInitialize } from '@stripe/connect-js/pure';
// Ensure the loadConnectAndInitialize is accessible globally
window.loadConnectAndInitialize = loadConnectAndInitialize;
---x---
Another problem I just spotted... I also think the payment-details embedded component isn't showing all the disputes related to a single charge. I tested using the 4000000404000079 (multiple dispute card from Stripe) and only one of the disputes appeared, while in the regular stripe dashboard for the conected account (when accessing from the platform account) both disputes appeared. I also noticed the retrieve charge api won't list all the disputes under the 'dispute' parameter, but just shows one. This might explain it and be all interconnected. Can someone from Stripe check if it's a bug? Because otherwise connected accountes without dashboard access won't be able to counterdispute one of the disputes!!!
@dvadri Looking at this code - can you console log the code in your click listener and verify it is running only once? I believe the video you shared indicates that 2 separate payment details components are mounted onto the page at the same time (one after another)
@dvadri And regarding multiple disputes, we do not currently support multiple disputes management in embedded, but that shouldn't be causing your issue