Is your feature request related to a problem? Please describe.
Looking at vendure's payment plugins I see that current payment workflow is:
- Client call
createStripePaymentIntent through shop-ai or some method, which creates an entity in payment gateway.
- Client make a payment through payment form.
- An incoming webhook informs vendure about successfull payment.
- Vendure calls
addPaymentToOrder, which calls createPayment method on appropriate payment handler.
Basically, this scheme is okay, but problem arises when client want to specify more than one payments in the order.
Say an order has total - 100$.
- Client adds a gift card or bonus payment to an order - 20$. It does not cover order's total.
- Client creates a stripe payment intent through
createStripePaymentIntent. But stripe payment plugin force order.totalWithTax field as amount, so amount result is 100$.
- Client see 100$ amount in payment form, which is wrong.
What I would like to see:
- Client adds a gift card or bonus payment to an order - 20$. It does not cover order's total.
- Client adds a stripe payment intent through classical
addPaymentToOrder, with amount 80$, because it calculates by formula: order.totalWithTax - all authorized/settled payments.
createPayment handler returns an object, like { state: 'pending or created', metadata: { url: 'stripe payment url' } }
- Client uses an url from metadata to go to payment page, where amount to pay is 80$, which is right.
- An incoming webhook informs vendure about successfull payment.
- Vendure calls
transitionPaymentToState which automatically transit a payment as well as an order to appropriate state.
I understand that I am completely able to implement this, thanks to vendure's extensible mechanisms, but it's cool to have a solid pattern here.
Describe the solution you'd like
- Do not add new mutations, like
createStripePaymentIntent. It generates an additional logic on storefront side. Imagine you have 3-4 connected payment plugins - your storefront or multiple storefronts should support every mutation for every provider.
- Use traditional
addPaymentToOrder to add new payments. It worth to place payment url into predefined field for that, not to metadata directly. Any of your storefront will be able to pay with any payment provider without an additional logic in unified way.
- Consider adding new payment state 'Pending'. Right after payment creation, payment handler may transit to state 'Pending' (Created -> Pending), so it means payment plugin waits user to be paid with payment url/form.
Describe alternatives you've considered
@vrosa
doesn't that depend on the implementation of this additional payment, e.g. gift card? I would expect the order.totalWithTax to be $80 by the time createStripePaymentIntent is called because that's what the customer is going to be charged. Other platforms, e.g. Shopify, also consider subTotal or total to the be amount after the gift card has been applied.
Not sure how Vendure's paid gift card plugin will behave but I would expect it to subtract the amount from the order's total.
Additional context
@michaelbromley
The gift card plugin I'm working on actually treats gift cards/store credit as a payment method, in the way described by Alexander. One reason for this is to do with the issue of how to deal with something like a return - if I buy 2 t-shirts @ $20 each, and then use a Promotion-style discount to make the order total $0, then Vendure is actually treating each OrderItem as having a value of $0 - i.e. the value of OrderItem.proratedUnitPrice will be 0. So for the purposes of returns & refunds, this indicates that the amount to refund would be $0, which is not correct.
Treating the gift card as a payment method allows us to model the actual transaction values more accurately - i.e. if I use a gift card to "pay" for the above order, then a return of 1 t-shirt implies a refund/re-credit of $20.
So I think it does make sense to take into account any existing payments on this line when creating the Stripe payment intent.
Slack thread: https://vendure-ecommerce.slack.com/archives/CKYMF0ZTJ/p1656064741229719
Is your feature request related to a problem? Please describe.
Looking at vendure's payment plugins I see that current payment workflow is:
createStripePaymentIntentthrough shop-ai or some method, which creates an entity in payment gateway.addPaymentToOrder, which callscreatePaymentmethod on appropriate payment handler.Basically, this scheme is okay, but problem arises when client want to specify more than one payments in the order.
Say an order has total - 100$.
createStripePaymentIntent. But stripe payment plugin forceorder.totalWithTaxfield as amount, so amount result is 100$.What I would like to see:
addPaymentToOrder, with amount 80$, because it calculates by formula: order.totalWithTax - all authorized/settled payments.createPaymenthandler returns an object, like { state: 'pending or created', metadata: { url: 'stripe payment url' } }transitionPaymentToStatewhich automatically transit a payment as well as an order to appropriate state.I understand that I am completely able to implement this, thanks to vendure's extensible mechanisms, but it's cool to have a solid pattern here.
Describe the solution you'd like
createStripePaymentIntent. It generates an additional logic on storefront side. Imagine you have 3-4 connected payment plugins - your storefront or multiple storefronts should support every mutation for every provider.addPaymentToOrderto add new payments. It worth to place payment url into predefined field for that, not to metadata directly. Any of your storefront will be able to pay with any payment provider without an additional logic in unified way.Describe alternatives you've considered
@vrosa
doesn't that depend on the implementation of this additional payment, e.g. gift card? I would expect the order.totalWithTax to be $80 by the time createStripePaymentIntent is called because that's what the customer is going to be charged. Other platforms, e.g. Shopify, also consider subTotal or total to the be amount after the gift card has been applied.
Not sure how Vendure's paid gift card plugin will behave but I would expect it to subtract the amount from the order's total.
Additional context
@michaelbromley
The gift card plugin I'm working on actually treats gift cards/store credit as a payment method, in the way described by Alexander. One reason for this is to do with the issue of how to deal with something like a return - if I buy 2 t-shirts @ $20 each, and then use a Promotion-style discount to make the order total $0, then Vendure is actually treating each OrderItem as having a value of $0 - i.e. the value of OrderItem.proratedUnitPrice will be 0. So for the purposes of returns & refunds, this indicates that the amount to refund would be $0, which is not correct.
Treating the gift card as a payment method allows us to model the actual transaction values more accurately - i.e. if I use a gift card to "pay" for the above order, then a return of 1 t-shirt implies a refund/re-credit of $20.
So I think it does make sense to take into account any existing payments on this line when creating the Stripe payment intent.
Slack thread: https://vendure-ecommerce.slack.com/archives/CKYMF0ZTJ/p1656064741229719