Automattic / woocommerce-payments

Accept payments via credit card. Manage transactions within WordPress.
https://wordpress.org/plugins/woocommerce-payments/
Other
172 stars 69 forks source link

WC-pay disputes are disrupting WC-admin analytics #526

Open LevinMedia opened 4 years ago

LevinMedia commented 4 years ago

When an order is disputed, we need to track the money that is returned to the customer via wc-admin analytics.

At the moment, we're doing nothing, which is throwing off the analytics, and displaying incorrect data in the orders list, as well as order details screen. Behind the scenes, we need to ensure we're refunding any tax and shipping appropriately as well.

If the disputed amount is the same as the order total (It usually is) the order status should change to refunded.

Example:

The second order was disputed. The original total should be crossed out, and the new total should be zero. The order status should read refunded.

Screen Shot 2020-03-20 at 1 15 08 PM

The order details screen should display the order as if it were refunded for the disputed amount. I'll open a separate issue about including new order notes in the case of a disputed order.

For reference here are the order details for the order that was disputed - we'll need this to make sense of the analytics below.

Screen Shot 2020-03-20 at 1 54 37 PM

Now here's the result of the disputed payment in the revenue report:

Screen Shot 2020-03-20 at 1 45 41 PM

cc @Automattic/isotope

LevinMedia commented 4 years ago

HT to @dechov - This scope of this issue does not consider what happens if a dispute is resolved in the merchants favor.

The short of it is, the merchant gets their money back, however we don't currently allow for the reversal of a refund, so we might need to do something tricky to make it work.

There are some other considerations there as well, such as what happens to the status of an oder if a dispute is won as well. (Another good case for separating payment and order status)

cc: @peterfabian for any thoughts proton might have about returning previously refunded dispute money to a merchant, how we keep track of it, and indicate it in order status. 🙌

thenbrent commented 4 years ago

The other question is whether the $15 dispute fee should be accounted for in the analytics? And if so, should it be accounted for against the order?

Technically, if an order has been disputed and the dispute is lost, the order cost the merchant $15, so a negative total of $15 would make sense. There is no concept or precedent in WC for this kind of negative total order amount being used to reflect a dispute fee from the payment processor (AFAIK).

thenbrent commented 4 years ago

The short of it is, the merchant gets their money back, however we don't currently allow for the reversal of a refund, so we might need to do something tricky to make it work.

I'd steer clear of handling disputes exactly the same as refunds. It opens up a few gotchas. For example, what if an order is refunded and then later disputed? For example, as part of a Credit not processed dispute. Do you refund the order twice and deduct 2x the order amount from the analytics? An order shouldn't be refunded twice.

Disputes are different to refunds. They should be handled distinctly.

Perhaps WC core could/should have a new dispute custom order type, like shop_order_dispute (in the same way, they have a shop_order_refund custom order type.) This object can the be used to store and account for both the amount of the order being deducted, and the dispute fee, in analytics and elsewhere within WooCommerce by both WC Pay and other gateways.

In line with that, WC Pay isn't the only gateway that needs to handle disputes. How are they handled by the Stripe or Authorize.net CIM extensions now?

There are some other considerations there as well, such as what happens to the status of an oder if a dispute is won as well. (Another good case for separating payment and order status)

I'd expect the order status to revert to the status before the dispute was initiated (e.g. if it was still processing, the status goes back to processing, if it was completed, it becomes compelted).

A disputed custom order type and status could resolve both of these issues. When the payment on an order is disputed, a special "dispute" order type can be created, which acts the same as a refund and stores information about the dispute, including the fee, disputed amount etc.

LevinMedia commented 4 years ago

The other question is whether the $15 dispute fee should be accounted for in the analytics? And if so, should it be accounted for against the order?

Inline with that, WC Pay isn't the only gateway that needs to handle disputes. How are they handled by the Stripe or Authorize.net CIM extensions now?

@thenbrent as of now, I'm inclined to say no. We don't track any of the gateway imposed fees inside the analytics package right now. Working that in would be a pretty major refactor to the way analytics work. Stripe fees are only tracked through the stripe dashboard, although they're mentioned on the order detail page. Otherwise, gateway fees aren't showing up in the analytics. Same is true for Shopify, and metorik.

Disputes are different to refunds. They should be handled distinctly.

Okay, I'm with you on this 100% Poor choice of wording in the title. I'll update it.

Perhaps WC core could/should have a new dispute custom order type, like shop_order_dispute (in the same way, they have a shop_order_refund custom order type.) This object can the be used to store and account for both the amount of the order being deducted, and the dispute fee, in analytics and elsewhere within WooCommerce by both WC Pay and other gateways.

This sounds pretty good to me. As I mentioned earlier, we're not doing any tracking of the gateway fees in analytics, but it might come in handy down the line.

dechov commented 4 years ago

In line with that, WC Pay isn't the only gateway that needs to handle disputes. How are they handled by the Stripe or Authorize.net CIM extensions now?

@thenbrent I don't know about Authorize.net (though I don't see anything about disputes in the webhooks [src]), but Stripe sets the order to "On hold" when a dispute comes in [src]. (Handling other dispute webhooks is tracked in https://github.com/woocommerce/woocommerce-gateway-stripe/issues/1098) Does/could the analytics piece exclude the order based on the status?

thenbrent commented 4 years ago

The analytics do take an order's status into account (they are also updated after an order's status is changed). But on-hold orders are included in the revenue analytics, so if we follow the Stripe extension's behaviour, we'll still see the issue.

on-hold can mean a few different things in WC, so I don't think we can propose that behaviour be changed either. (As David said, "Another good case for separating payment and order status".)

A new Disputed status could be a solution (likely in WC core, rather than WC Pay.)

jrodger commented 4 years ago

There are a few things blocking progress on this issue, I'll try to break down what we need to look at first so we can start making progress again:

jrodger commented 3 years ago

I've removed the "blocked" status from this issue, we've made sufficient progress on the points above to start looking at this again:

LevinMedia commented 3 years ago

The other question is whether the $15 dispute fee should be accounted for in the analytics? And if so, should it be accounted for against the order?

Technically, if an order has been disputed and the dispute is lost, the order cost the merchant $15, so a negative total of $15 would make sense. There is no concept or precedent in WC for this kind of negative total order amount being used to reflect a dispute fee from the payment processor (AFAIK).

@thenbrent My short answer there is yes, we should account for the 15 dollar fee.

At the end of the day, this fee amount should be deducted from the net sales total. however, in order to disambiguate it from refunds or the amount paid for products I think it should be accounted for separately from both the net sales, discounts and returns.

Adding a new "fees" column, and integrating it on the appropriate reports would solve this issue. I assume there are other areas within WooCommerce that would likely benefit from this column as well (shipping, perhaps?)

The new net sales calculation would look like: gross sales - returns - discounts - fees = net sales

The fee summary number / column could be display conditionally, and only appear if the selected date range and filter combinations include an order that was assessed a fee.

cc: @elizaan36

LevinMedia commented 3 years ago

My short answer there is yes, we should account for the 15 dollar fee.

@thenbrent - I'm already having second thoughts about that statement. I'm going to do a little design exploration around this in the next week or two and we can circle back on it.

thenbrent commented 3 years ago

Adding a new "fees" column, and integrating it on the appropriate reports would solve this issue.

Just to complicate matters, WooCommerce already has a concept of a "fee" line item, which is usually a fee levied to the shopper, not a fee levied on the merchant. We could reuse the same fee API, but right now, it's included in the Gross Sales of analytics (I expect) rather than being split out.

vbelolapotkov commented 2 years ago

Sending back for triage due to the lack of activity for the long time

htdat commented 2 years ago

Sending back for triage due to the lack of activity for the long time

FYI. Per this comment by David https://github.com/Automattic/woocommerce-payments/issues/526#issuecomment-776276361, I am moving this issue to queue Product review for ZenHub board WooCommerce Payments Backlog.

haszari commented 5 months ago

Marking as an enhancement. Based on the discussion above, we'll need to design and consider the solution across WooPayments and WooCommerce core.

Perhaps WC core could/should have a new dispute custom order type, like shop_order_dispute (in the same way, they have a shop_order_refund custom order type.) This object can the be used to store and account for both the amount of the order being deducted, and the dispute fee, in analytics and elsewhere within WooCommerce by both WC Pay and other gateways.

Note we have issue open for exploring a disputed status: