#Payment polling
1 messages · Page 1 of 1 (latest)
I guess you should first take a deep breath and consider the tone of your question.
Please keep a respectful tone.
If you are experiencing problems and errors, I would recommend opening an issue on our GitHub repository. We attend to those on a daily basis.
I am sorry to hear you've had a bad experience so far. I'd love to try to make up for it!
I'm sorry, it was indeed a rant post, I shouldn't have done that
I'm sorry, shouldn't have made a rant post, did it out of frustration since I'm missing deadline a bit.
It's not that it's bad experience, the Medusa is extremely decent, probably the only proper self hosted open source solution, but documentation is a bit unclear, though AI massively helps.
Also the problem disappeared for some reason randomly without changing anything? I'm not sure what happened there, my authorizePayment did return correct status, which was PENDING at the moment, I used completeCheckout.mutateAsync() and tried to test retrying payment authorization continuously since I'm integrating blockchain payment gateway, and for some reason I just started getting duplicate payment error, I couldn't find the root of the issue after reading into the architecture and asking AI.
What could have happened here?
Don't worry, frustration happens to all of us. Just trying to help out, dont let it control u 🙂
Regarding documentation you can open an issue if some parts are unclear and potentially open PR to cover that. That's the beauty of open source after all. Each of us can help to bring it to a better state than what we initially found, consider that the team as any of us is limited on resources so everything cant be done at fast peace.
I think what could have happened is that the cart-completion failed in one of its steps, presumably after the payment authorization step, since you get the duplicate error message. I believe leveraging our idempotency mechanism will resolve your issues. You can read more about the concept here: https://medusajs.com/blog/idempotency-nodejs-express-open-source/
Essentially, the idempotency key mechanism allows you to retry the cart-completion flow and it will start from the step where it failed the first time around.
To see if this is in fact your issue, you can start by finding the idempotency in the database that is related to the cart in question, and retry the cart-completion with the header Idempotency-Key: your_key
Obviously, it is not ideal to do it manually everytime, so you can build a retry flow in your client, that adds the header to the subsequent request (after the one that failed).
Does this make sense?
I believe reading through the cart-completion strategy will help your understanding: https://github.com/medusajs/medusa/blob/afd79c9c3906d9c6c1aa4dfa5c6f1c8cc9d76d3e/packages/medusa/src/strategies/cart-completion.ts#L72
Let me know if I can assist!
Hmm, so idempotency is not generated and used in your checkout hooks from the get-go?
It is stated in docs that the idempotency key should be generated automatically if it doesn't exist already, I actually looked through it but didn't really find where can I get it if it's already generated.
I was trying to use prebuilt functionality as much as possible to not invent the wheel, especially since your storefront template is mainly used for testing so I don't want to charge my client for something that won't be used in production because basically we are building a template of our own
Yes it is generated automatically. But you will have to pass it to retrying requests, otherwise a new one will be generated.
This is why you should be able to find the idempotency for your cart in your database. Try this one:
select * from idempotency_key where request_params @> '{ "id": "your-cart-id" }'
And you will probably find, that there are many keys in your case, since you've retried the request many times without passing any idempotency key.
Yes, indeed, I found a lot of keys.
But it's still not exactly clear how to use it. Should I obtain it when authorizing payment and pass it as a part of session data?
And then can I somehow pass it to your completeCheckout or useCart hooks instead of writing my own request?
It should be passed as a header Idempotency-Key: key
The retry logic is something you will have to write yourself because it depends on the client, but essentially, you need to re-use the idempotency key created in the first request, in the subsequent retrying request.
Something like this:
medusaClient.carts.complete(cartId, {
"Idempotency-Key": "some-key", // header
})
.catch(err => {
// check error and retry with idempotency key
})
This will make the cart completion flow start from the failed step
Ok, understanding it a bit now.
"The key created in the first request" though, not getting it, I need to get it from my database and pass as a part of session data?
I'm using https://github.com/medusajs/nextjs-starter-medusa by the way if this changes something
Ok I found it being generated in the completion request when using completeCheckout.mutateAsync(), how do I reuse it in this case though?
Hey, I succeeded after all!
I'm encountering a new issue, this one is weird for real. Calling carts.complete triggers authorizePayment only once, subsequent requests go through but function doesn't seem to get invoced, for now it should just log to console, it's not happening though...
It will only trigger each successful step once, if you use the idempotency key. That's the idea.
Understood, what should I use to create polling mechanism then? Ideally I need to attempt authorization until it's authorized of course
The current code on frontend:
let idempotencyKey: string | undefined = undefined;
async function completeCart(cartId: any) {
try {
const customHeaders = { "Idempotency-Key": idempotencyKey };
const response = await medusaClient.carts.complete(cartId, customHeaders);
idempotencyKey = response.response.headers["idempotency-key"]
console.log("Cart completed successfully:", response.data);
} catch (error) {
console.error("Error completing cart:", error);
}
}
function onClick(cartId: any) {
completeCart(cartId);
setInterval(() => {
completeCart(cartId);
}, 5000);
}
return (
<Button disabled={submitting || notReady} onClick={() => onClick(cart?.id)}>
{submitting ? <Spinner /> : "Checkout"}
</Button>
)
How often does the authorization fail in your case? If it's often, it would be good to have a retry-mechanism. But usually, it only happens in very rare scenarios
It should basically keep trying to authorize payment every 30 seconds until it is done. Transaction may take minutes
Is there any other way to invoke some function that may get payment status? If it's possible I could try getting payment status instead of trying to authorize and then only authorize once
привет
Прив
Может ты мне подскажешь? Вкратце - пытаюсь сделать повторяющиеся попытки авторизации платежа, проходит только первая попытка. Фронт нынешний это темплейт на нексте, используется чисто для тестирования, так что прям суперправильное исполнение не нужно, надо просто чтоб работало чтоб можно было потыкать
My russian is really basic, I see what you mean but I think oliver helps fine and know very good medusa as he is one of the founders
And I didn't gone so far in the use of it
Good luck
Oh, I thought you know russian too lmeow, I'd answer you in Ukrainian to show some class if I had the keyboard layout :D
It seems like I just need to do a last bit of puzzle on my frontend and I feel like I'm just nagging Oliver with basic questions, but It's so close to completion, I blew couple weeks on payment processing already and it's so damn close and I can finally close the milestone and get paid :D
If the authorization might take minutes in your case, you might want to avoid Long Runnnig Transaction, maybe you would like something a bit more custom and create an end point that creates the tax lines and try to authorize the payment, then do some polling to check that the session is authorized or not and if it gets authorized then complete the cart. Would that work @ocean lotus ?
I'm not sure it will work for blockchain transactions.
User gets the invoice, selects currency, creates payment in the invoice where he get's deposit address.
When user clicks "checkout" the invoice link is opened and polling should start waiting for user to deposit funds and for blockchain to return appropriate status.
Payment authorization basically checks payment status in my implementation since it's the only one that can be easily called from the frontend by calling "medusaClient.carts.complete", to check payment status I need to get JWT token by sending auth request to payment processor, then JWT token is used to get list of payments and filter out one specific payment ID that I need and then start getting it's status.
Payment polling
СПАСИБО
Stop mocking me 💀
It's no my intention, it was pretty gentle, sorry for miss understanding me
I though you will be happy to see that someone is learning russian in the community
I just said **hello ** and now it just mean thank you
Anyway I wish you to succeed in solving your issue
Oh, I'm sorry hahah, I didn't mean to bash you or something, I thought you are just mocking me
Absolutely not
And, honestly, even though I speak russian myself a bit too much I would be way happier if you learned Ukrainian :D
Ohhh sorry sorry in fact it's Ukrainian
Sorry I don't make a diffrence between the two, I am really at a basic level
It's so close yet so far, ehh
It's not ukrainian hahah, спасибо in ukrainan is дякую for example
Okey now I understand my fault, sorry again
Northern Kharkiv here, ready to die each day of the week 💪
Nah man it's nothing to be sorry about lol, I never accused you of anything hahah
K, let's hope Oliver answers again, if he sees random conversation he may miss my initial question :D