Giter VIP home page Giter VIP logo

Comments (15)

seminarian avatar seminarian commented on June 8, 2024 1

I remember encountering this.

There are multiple scenarios possibly:

  1. Customer goes back and starts a new payment for same order content.
  2. 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 use createPaymentIntent
  • 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.

seminarian avatar seminarian commented on June 8, 2024 1

@martijnvdbrug

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.

nicoes avatar nicoes commented on June 8, 2024 1

Thanks for all the input. Great that this has been moved to the backlog

from vendure.

michaelbromley avatar michaelbromley commented on June 8, 2024 1

Yes correct. The only way to prevent it from executing would be to actively remove that OrderProcess from the array. Source reference:

await awaitPromiseOrObservable(process.onTransitionEnd(fromState, toState, data));

from vendure.

martijnvdbrug avatar martijnvdbrug commented on June 8, 2024

👀 Joining this issue :-)

from vendure.

martijnvdbrug avatar martijnvdbrug commented on June 8, 2024

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.

martijnvdbrug avatar martijnvdbrug commented on June 8, 2024

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.

michaelbromley avatar michaelbromley commented on June 8, 2024

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.

martijnvdbrug avatar martijnvdbrug commented on June 8, 2024

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.

michaelbromley avatar michaelbromley commented on June 8, 2024

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.

martijnvdbrug avatar martijnvdbrug commented on June 8, 2024

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.

martijnvdbrug avatar martijnvdbrug commented on June 8, 2024

Seeking input

Ok, so the proposed solution is:

  1. We will transition to ArrangingPayment before redirecting the customer to Mollie
  2. When an order is transitioned from ArrangingPayment back into AddingItems 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.

michaelbromley avatar michaelbromley commented on June 8, 2024

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.

martijnvdbrug avatar martijnvdbrug commented on June 8, 2024

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 to AddingItems
  • 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.

martijnvdbrug avatar martijnvdbrug commented on June 8, 2024

After discusssing with @nicoes we opted for the following solution:

Transition to ArrangingPayment after payment

  • When createMolliePaymentIntent is called, we leave the order in AddingItems, but we do check if it's transitionable to ArrangingPayment (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 to ArrangingPayment 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)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.