Comments (15)
I remember encountering this.
There are multiple scenarios possibly:
- Customer goes back and starts a new payment for same order content.
- Customer goes back and starts a new payment for a changed order content.
So depending on the scenario, different limitions / checks should probably be applied.
Perhaps a solution could be the Mollie Plugin:
- Enforcing an order to be in
ArrangingPayment
for being able to usecreatePaymentIntent
- Store the paymentIntent on the Order.
- If other requests are being received it can just return the same paymentIntent
- If the Order transitions back to
AddingItems
it can remove the paymentIntent stored on the Order. (I don't think it's possible to delete it at Mollie's side though)
This will probably tackle the issue reported. It won't be perfect but I will be an improvement.
I think I remember the "Payment API" of Mollie to be a limitation in removing payment intents/updating them/..
Would a more refined payment handling be possible with the "Order API" of Mollie?
This last paragraph should probably be checked for correctness, as mentioned it's been a while.
from vendure.
The Mollie Plugin now uses the order API, so indeed with a reference to the Mollie order, we are able to cancel the order and create a new one.
Just make sure this statement correct. I remember something about payments not always being cancelable: https://docs.mollie.com/reference/v1/payments-api/cancel-payment#:~:text=Some%20payment%20methods%20are%20cancellable,the%20payment%20can%20be%20canceled.
How would you cancel the Mollie order when transitioning to AddingItems? I guess we can listen for OrderTransitionEvent, but that will make it async. I guess this is fine, but if you are REALLY quick you could still pay for your order twice
Not sure about that, the backend could probably track if it got succesfully cancelled or if it's a different amount to be paid.
Perhaps this decision can happen in Vendure Backend when a new paymentIntent is requested?
from vendure.
Thanks for all the input. Great that this has been moved to the backlog
from vendure.
Yes correct. The only way to prevent it from executing would be to actively remove that OrderProcess from the array. Source reference:
from vendure.
👀 Joining this issue :-)
from vendure.
Thanks for yout input @seminarian. The Mollie Plugin now uses the order API, so indeed with a reference to the Mollie order, we are able to cancel the order and create a new one.
How would you cancel the Mollie order when transitioning to AddingItems
? I guess we can listen for OrderTransitionEvent
, but that will make it async. I guess this is fine, but if you are REALLY quick you could still pay for your order twice
from vendure.
Perhaps this decision can happen in Vendure Backend when a new paymentIntent is requested?
Even better indeed! I guess to keep things simple, we always cancel the current mollie-order with payments when a new pament intent is created.
I guess when the order or one of the payments couldn't be cancelled, we just log an error and create a new order with payments, just as we do now.
from vendure.
How would you cancel the Mollie order when transitioning to AddingItems? I guess we can listen for OrderTransitionEvent, but that will make it async. I guess this is fine, but if you are REALLY quick you could still pay for your order twice
If we use a custom OrderProcess we could put this check in the inTransitionEnd hook which would execute non-async (i.e. serially with the state transition) which should prevent the edge case you mention.
@martijnvdbrug do you have any capacity to work on this in the near future?
from vendure.
How would you cancel the Mollie order when transitioning to AddingItems? I guess we can listen for OrderTransitionEvent, but that will make it async. I guess this is fine, but if you are REALLY quick you could still pay for your order twice
If we use a custom OrderProcess we could put this check in the inTransitionEnd hook which would execute non-async (i.e. serially with the state transition) which should prevent the edge case you mention.
Thats an option, but it feels pretty intrusive if a payment plugin installs a custom order process. Plus a consumer could define their own order process, breaking the payment plugin. @seminarian s suggestion for doing it on new payment creation also works ai think.
@martijnvdbrug do you have any capacity to work on this in the near future?
Yep, still working together with Nico, and its causing issues, so I will be picking this up.
from vendure.
it feels pretty intrusive if a payment plugin installs a custom order process
Remember that the orderOptions.process
is an array, so all the configured processes compose together as a pipeline. So you would just create a bare-bones OrderProcess which only adds the specific logic for this check. All other processes that are already configured will still run as usual.
And great to hear you can work on this 👍
from vendure.
Remember that the
orderOptions.process
is an array, so all the configured processes compose together as a pipeline. So you would just create a bare-bones OrderProcess which only adds the specific logic for this check. All other processes that are already configured will still run as usual.And great to hear you can work on this 👍
Ahh I see it now. Thanks. mergeStrategy: 'replace'
is only for actual state transitions, so an onTransitionEnd
would always be called and can not be overridden?
from vendure.
Seeking input
Ok, so the proposed solution is:
- We will transition to
ArrangingPayment
before redirecting the customer to Mollie - When an order is transitioned from
ArrangingPayment
back intoAddingItems
we cancel the Mollie order (if possible)
The question still remains, who will transition the order back into AddingItems
? Is it the storefront? The customer could still have another tab open with the storefront, so on what event would you transition an order back to AddingItems
?
from vendure.
So do you mean that the createMolliePaymentIntent
mutation will do the state transition automatically to ArrangingPayment
(if not already in that state)?
The question still remains, who will transition the order back into AddingItems?
I would leave this as a concern of the storefront implementation.
from vendure.
So, we are struggling a bit on when the storefront should transition an order back to AddingItems
. When does the storefront know that the order is in ArrangingPayment
. There are some possibilities, but none seem very clean:
- Refetch active order when a Browser tab gets focus again. If in
ArrangingPayment
, transition back toAddingItems
- Check for Order State Errors on every mutation, so that we know when to first transition back to adding items.
- Time based checks: Refetch order in browser every X seconds
Any suggestions are welcome :-)
from vendure.
After discusssing with @nicoes we opted for the following solution:
Transition to ArrangingPayment
after payment
- When
createMolliePaymentIntent
is called, we leave the order inAddingItems
, but we do check if it's transitionable toArrangingPayment
(This is how we do that) - We store the Mollie order ID on the Vendure order.
- When the Mollie webhook comes in to Vendure with status
paid
, we transition toArrangingPayment
and add the payment to the order. - This in turn transitions to
PaymentSettled
if the total amount has been paid. - If a customer calls
createMolliePaymentIntent
again, the plugin will check if a mollie order ID is already present on the order. If so, it cancels the previous Mollie order (if possible) and starts a new Mollie order. - If it's not possible to cancel the Mollie order for whatever reason, that's unfortunate, but we leave it. We will still prevent the bulk of the duplicate payments with this, and we don't want to block new payment intents from customers.
What does it not solve
A customer can still open a new tab with the storefront after a Mollie Checkout has been started and add items to the active order. If the customer then finalizes payment with the old Mollie order, the Vendure order will go to ArrangingAdditionalPayment
. This is something the storefront could handle, but doesn't have to.
Why not transition to ArrangingPayment
before going to Mollie checkout?
It's quite a big change for the storefront compared to the current way of working. All mutations need to check if the order is in AddingItems
or catch the OrderModificationError
.
The proposed solution doesn't require any changes on frontend. The issue where an order goes to ArrangingAdditionalPayment
instead of PaymentSettled
can optionally be handled on the storefront's confirmation page, but is not required.
from vendure.
Related Issues (20)
- Enhance EmailSendEvent with Metadata HOT 2
- Show the email in the chip of the customers HOT 2
- Stand-alone CLI script Error on Bootstrap Worker HOT 1
- Unabled to create new Admin UI routes using React HOT 1
- Error: Could not load the "sharp" module using the linux-x64 runtime[Fixed] HOT 8
- SplitOrder not persisting shippingLines in SellerOrder HOT 1
- BUG: Failed to create a province! HOT 1
- Entity Hydrator randomly mixes nested relations
- Add eligible promotions query for active order HOT 1
- Zones in Channel Detail do not get updated after creating a new one
- throw new QueryRunnerAlreadyReleasedError() HOT 3
- OrderItemPriceCalculationStrategy is not used on order modification
- Extend AuthenticationMethod type to also return the externalIdentifier field from the DB table authentication_method
- [EmailPlugin] Cannot read properties of undefined (reading 'headers') in production HOT 2
- Extra allocation when canceling order HOT 1
- Support pnpm for UI extension compilation HOT 1
- Custom Fields Permission in Admin UI affect the shop-api
- As a Vendor, I am unable to edit a Customer. Additionally, the Customer section is empty. The error message displayed is: `Variable "$id" of required type "ID!" was not provided.`
- Add Payment To Order in a different channel than the default
- Facets codes are globally unique instead of channel unique HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from vendure.