-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
(medusa-payment-stripe): serialization error #2948
Comments
Thanks for filing the issue. We'll make sure to attend to this in the coming week :) cc @adrien2p |
I can see that there are two hooks that hit your server. Can you confirm that multiple stripe providers are available in the cart region? I believe that this behavior should not happen again with the latest improvements to the cart payment session management flow. Could I get you to test the next release when it is out? cc @olivermrbl |
Hi, I seem to have stumbled upon this issue. I have only one payment provider in the region (only Stripe), and only one webhook, but this hook has multiple actions linked to it (I tried to add all of them :)) ). Once I disabled the webhook, this issue disappeared, also when I set only one action on the webhook. Versions: |
Experiencing the same issue For us, we also enabled every option available in webhooks. What are the implications if we were to disable the webhooks ? |
@GamfaleanuVlad @quiloos39 This is expected behavior when requests race to complete a serializable transactional operation. Correct me if I am wrong, but the cart is, in fact, completed, right? If so, I suggest you add a retry mechanism to your storefront that will idempotently attempt to complete the cart. If you are using our client, retries can be configured in the options when creating it. Idempotency is supported out of the box. You just need to handle the keys in your storefront. I recommend reading through this guide. @chemicalkosek I know you've had this issue as well. Feel free to pitch in. |
Yeah I think this is a race condition when storefront tries to complete the cart at the same time as webhook. I handle it sort of like this on the storefront
Might not be the prettiest but never failed me in production so I refuse to touch it. |
@chemicalkosek I've added similar logic to projects myself, and I think it's a reasonable approach to ensure a good customer experience. I will close this issue for now, as this is expected behavior. |
As an addition I have noticed that the default hook doesn't create the order when I'm actually using a modified version of webhook where I also complete the cart if no order exists on PS. Beware: In default webhook the cart completion takes into account only But if somebody uses the new Stripe PaymentElement with other payment methods, the |
@chemicalkosek if I may ask in your stray:
@chemicalkosek in my case the webhook has already completed the cart, hence reset the cart. When I try to fetch the cart from the storefront it simply returns the newly created cart after my checkout has completed. How do you manage to safely try to complete the order, if there is an concurrent update issue (due to webhook completing cart) then simply forward to the order confirmation. The problem is I cannot fetch the order since the cart is already reset 🤷 |
@fxmb Yes the cart can be reset in the store context beforehand because it has a truthy I attach the return_url: `${
process.env.NODE_ENV === 'production'
? `https://${hostname}/order-completed?cartId=${cart.id}`
: `http://localhost:8000/order-completed?cartId=${cart.id}`
}`, Then on the return_url page I do like this: const { cart: cartFromContext } = useCart();
const stripe = useStripe();
const { onPaymentCompleted, resetCart } = useStore();
const router = useRouter();
useEffect(() => {
if (stripe && router.isReady) {
(async () => {
const { paymentIntent, error } = await stripe.retrievePaymentIntent(
router.query.payment_intent_client_secret
);
if (error) {
console.error('Stripe retrieve payment error: ', error);
} else if (paymentIntent && paymentIntent.status === 'succeeded') {
console.log('webhook should take care of order already');
// check if order already exists (created in stripe webhook)
await medusaClient.orders
.retrieveByCartId(router.query.cartId)
.then(({ order }) => {
console.log('webhook took care of order');
// Cart is reset in store context if it has completed_at truthy
// Hence we'll skip the reset again if a different cart is in context already
if (router.query.cartId === cartFromContext?.id) {
resetCart();
}
router.push({
pathname: '/order-summary',
query: { orderId: order.id },
});
})
.catch((err) => {
console.error(err);
// complete the cart if webhook haven't done that yet.
console.log('no order yet. frontend is creating order');
onPaymentCompleted();
});
} else {
showNotification({
title: 'Error',
autoClose: false,
message: 'Payment failed. Try again.',
});
router.push('/checkout');
}
})();
}
}, [router, onPaymentCompleted, stripe, resetCart, cartFromContext.id]);
return (
<div className="mt-4">
<Loader /> <br />
We are checking your payment.
<br />
Don't leave this page
</div>
); Does that help? |
Thank you so much @chemicalkosek ! Makes a lot of sense. I thought about attaching the cart.id to the return_url but wasnt sure if that is a recommended pattern. Thanks! |
@fxmb The cartId will be also at So you can get it also from here. Edit: Sorry, metadata is not available when using publishable api key. |
@chemicalkosek huge shoutout! This works like a charm! |
@fxmb While reading my code I see that this check } else if (paymentIntent && paymentIntent.status === 'succeeded') { Should actually be: } else if (paymentIntent &&
(paymentIntent.status === 'succeeded' || paymentIntent.status === "requires_capture")) { or something like that. In my case I have autocapture on Stripe side |
Bug report
Describe the bug
In #2601, there is an error when the Stripe webhook is configured related to concurrent requests trying to complete the cart. It seems the error still occurs in the latest version.
System information
Medusa version (including plugins):
Node.js version: v16.18.0
Database: PSQL v15.1
Operating system: Windows 11
Steps to reproduce the behaviour
Expected behaviour
After checkout proceed to the order confirmation page.
Code snippets
Additional context
I downloaded the older version when it was solved in 1.6.5 (medusa-payment-stripe: v1.1.48) and it worked without any problems.
The text was updated successfully, but these errors were encountered: