Closed bulecampur closed 9 months ago
Hi, with Stripe do you have the confirmed order in your vendure environment? @prasmalla do you have any feedback?
Ok, it seems like I only see it in Stripe. In Vendure I see it as "Adding Items" not as Payment processed. Edit: I can see the payments in Vendure now as Payment Settled. But the original issue is still there.
This is the Stripe Component
import {
$,
component$,
noSerialize,
useContext,
useStore,
useVisibleTask$,
} from '@builder.io/qwik';
import { useLocation } from '@builder.io/qwik-city';
import type { Stripe, StripeElements } from '@stripe/stripe-js';
import { loadStripe } from '@stripe/stripe-js';
import { APP_STATE } from '~/constants';
import { ENV_VARIABLES } from '~/env';
import { createStripePaymentIntentMutation } from '~/providers/shop/checkout/checkout';
import CreditCardIcon from '../icons/CreditCardIcon';
import XCircleIcon from '../icons/XCircleIcon';
let _stripe: Promise<Stripe | null>;
function getStripe(publishableKey: string) {
if (!_stripe && publishableKey) {
_stripe = loadStripe(publishableKey);
}
return _stripe;
}
const stripePromise = getStripe(ENV_VARIABLES.VITE_STRIPE_PUBLISHABLE_KEY);
export default component$(() => {
const appState = useContext(APP_STATE);
const baseUrl = useLocation().url.origin;
const store = useStore({
clientSecret: '',
resolvedStripe: noSerialize({} as Stripe),
stripeElements: noSerialize({} as StripeElements),
error: '',
});
useVisibleTask$(async () => {
store.clientSecret = await createStripePaymentIntentMutation();
await stripePromise.then((stripe) => {
store.resolvedStripe = noSerialize(stripe as Stripe);
store.stripeElements = noSerialize(stripe?.elements({ clientSecret: store.clientSecret }));
store.stripeElements?.create('payment').mount('#payment-form');
});
});
return (
<div class="flex flex-col items-center max-w-xs">
<div id="payment-form" class="mb-8"></div>
{store.error !== '' && (
<div class="rounded-md bg-red-50 p-4 mb-8">
<div class="flex">
<div class="flex-shrink-0">
<XCircleIcon />
</div>
<div class="ml-3">
<h3 class="text-sm font-medium text-red-800">We ran into a problem with payment!</h3>
<p class="text-sm text-red-700 mt-2">{store.error}</p>
</div>
</div>
</div>
)}
<button
class="flex px-6 bg-primary-600 hover:bg-primary-700 items-center justify-center space-x-2 py-3 border border-transparent text-base font-medium rounded-md shadow-sm text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary-500"
disabled={!_stripe}
onClick$={$(async () => {
const result = await store.stripeElements?.submit();
if (!result?.error) {
const result = await store.resolvedStripe?.confirmPayment({
elements: store.stripeElements,
clientSecret: store.clientSecret,
confirmParams: {
return_url: `${baseUrl}/checkout/confirmation/${appState.activeOrder.code}`,
},
});
if (result?.error) {
store.error = result.error.message as string;
}
} else {
store.error = result.error.message as string;
}
})}
>
<CreditCardIcon />
<span>Pay with Stripe</span>
</button>
</div>
);
});`
Ok, it seems like I only see it in Stripe. In Vendure I see it as "Adding Items" not as Payment processed.
Ignore this, I can see it in Vendure now - I just had to update the Stripe Webhook for the Stripe Test Environment. So it does show as Payment Settled as expected. But the issue with the Order Confirmation Page is still there
have not seen this issue before, do you have a repo for us to reproduce this behavior?
I have created a repo that demonstrates the error: one would need a Stripe test api though and the linked Vendure backend. Here is the repo https://github.com/bulecampur/stripe-confirmation-page Excuse the atrocious buttons, I have not configured the checkout pages yet so they are difficult to see. right now (basically white on white). I am guessing since the Stripe Component redirects towards a page but the state has not changed to "Confirmation", the stripe link cannot find anything. This may also be why items are left in the cart. If we use the dummy payment provider, it generates the page through onForward$. Is this a correct assessment?
So I looked further at it and the behavior now is the following:
This could lead to confusion by the customers. Í tried to add a UseVisibileTask$ to automatically reload the page with useNavigate. But this does not work. Are there any suggestions? What could be the issue? Do you not see this issue in your implementation?
I think the error is here _.Stripe returns the returnurl, but it does not load the confirmation page, yet. why is not working?
Note that the error is on a deploy to Cloudflare pages. Is it a routing error or is it a timing error? Maybe my Vendure has not transitioned to the state paymentSettled the moment the confirmation page is loaded? And only transitions after as the stripe plugin gets confirmation from stripe. Does it work on your clean deploy of the qwik Vendure storefront? I'm just throwing around guesses...
maybe you can add a timeout here for testing purpose. You redirecting here, isn'it?
Yes, thanks for the suggestion, I will try it.
Get BlueMail for Android
On Jan 23, 2024, 6:08 PM, at 6:08 PM, Giorgio Boa @.***> wrote:
maybe you can add a timeout here for testing purpose. You redirecting here, isn'it?
-- Reply to this email directly or view it on GitHub: https://github.com/vendure-ecommerce/storefront-qwik-starter/issues/145#issuecomment-1906531690 You are receiving this because you authored the thread.
Message ID: @.***>
maybe you can add a timeout here for testing purpose. You redirecting here, isn'it?
So when I come through stripe, it resolves (timeout 5000 ms), however the store.order is null. When I reload manually, it actually loads the order.
🤔 Is It grabbing the correct order code from the URL?
Yes, the order code is correct as per console.log
You can execute the gql call in the browser by changing this code. We can look at the network tab to see the response.
You can execute the gql call in the browser by changing this code. We can look at the network tab to see the response.
What should I change exactly?
So I tried to log what is happening. When I land via stripe and I console.log the activeOrder from the context, it still shows up. This should not happen right? Whereas the order retrieved by the query returns null. When I manually reload, the activeOrder does not show anymore meaning that it has transitioned and the order by code query now returns the correct order.
I see. The order retrieved by the query should always return the confirmed order.
Ok, so it seems like there is a 5-10 seconds delay until the confirmed order is ready. Using window.reload with a timer eventually gets there. But can that be the solution though?
Did you check the vendure dashboard? Is it slow there too?
The backend seems to work fine, it's probably just waiting for the stripe confirmation via webhook? that causes this time dissonance. For now I have patched this with:
useVisibleTask$(async () => { const delayDuration = 5000; // Set the delay duration in milliseconds setTimeout(async () => { // Check if store.order is null before calling the navigate function if (store.order === null) { // Reload the page if order is still null location.reload(); } }, delayDuration); });
also using this in production on cloudflare with timeout to refresh the page but it's for the business logic. does it work without the refresh in your local env?
I think you need to jump through additional hoops to test stripe locally, isn't that the case? So I did not test it locally yet.
Hi, I am building a store with your wonderful template - thank you so much for this. I have made some customization but they should not touch the issue I have been having since the issue is related to the Stripe Plugin, which I have not touched.
The issue is that when an order is paid via Stripe (Test mode), the payment is made and registered in Stripe but the client is not redirected to the confirmation page. It also seems like the confirmation page was not created.
This is not true for the dummy payment handler, which creates the payment.
What am I doing wrong here or is this an issue in the code? It seems like the issue is with onForward$, which is only triggered by the payment component, not by the Stripe Payment component. Instead Stripe points towards a page that does not exist yet because it has not transitioned the state. Or is it a different issue?
How can I get Stripe Payment to trigget onForward$() ?