Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error refunding order items #873

Closed
jdG- opened this issue May 10, 2021 · 4 comments
Closed

Error refunding order items #873

jdG- opened this issue May 10, 2021 · 4 comments
Assignees
Labels
type: bug 🐛 Something isn't working

Comments

@jdG-
Copy link
Contributor

jdG- commented May 10, 2021

Describe the bug
When I try to refund an order with the admin ui and the refund fails, I can’t try to refund again (checkboxes are missing)
image
image

{
    "data": {
        "order": {
            "id": "9aef1be1-37eb-4b19-946c-6e6cb611cf45",
            "createdAt": "2021-04-20T12:19:42.484Z",
            "updatedAt": "2021-04-20T12:20:00.165Z",
            "code": "6MDZB2LUZ3GPXCHP",
            "state": "PaymentSettled",
            "lines": [
                {
                    "id": "0a15be29-fb84-4c09-9610-dff97d9ff4a3",
                    "unitPrice": 739,
                    "unitPriceWithTax": 780,
                    "quantity": 1,
                    "items": [
                        {
                            "id": "dfccb246-d434-4411-b746-dfd52afef5b5",
                            "unitPrice": 739,
                            "unitPriceWithTax": 780,
                            "taxRate": 5.5,
                            "refundId": "98236d06-4bf7-4b63-8157-dcf074a643d6",
                            "cancelled": false,
                            "fulfillment": null,
                            "__typename": "OrderItem"
                        }
                    ],
                    "linePrice": 739,
                    "lineTax": 41,
                }
            ],
            "total": 739,
            "totalWithTax": 780,
            "currencyCode": "EUR",
            "shipping": 0,
            "shippingWithTax": 0,
            "payments": [
                {
                    "id": "9c2d2642-49d0-4c50-9fe9-546af17d5601",
                    "createdAt": "2021-04-20T12:20:00.165Z",
                    "transactionId": "af2765af-e9ae-4f2f-92c3-e87d827eb3d7",
                    "amount": 780,
                    "method": "card",
                    "state": "Settled",
                    "nextStates": [
                        "Cancelled"
                    ],
                    "errorMessage": null,
                    "metadata": {},
                    "refunds": [
                        {
                            "id": "98236d06-4bf7-4b63-8157-dcf074a643d6",
                            "createdAt": "2021-05-10T14:37:57.662Z",
                            "state": "Failed",
                            "items": 780,
                            "adjustment": 0,
                            "total": 780,
                            "paymentId": "9c2d2642-49d0-4c50-9fe9-546af17d5601",
                            "reason": "Customer request",
                            "transactionId": "af2765af-e9ae-4f2f-92c3-e87d827eb3d7",
                            "method": "card",
                            "metadata": {
                                "errorMessage": "Error during card refund"
                            },
                            "orderItems": [
                                {
                                    "id": "dfccb246-d434-4411-b746-dfd52afef5b5",
                                    "__typename": "OrderItem"
                                }
                            ],
                            "__typename": "Refund"
                        }
                    ],
                    "__typename": "Payment"
                }
            ],
        }
    }
}

To Reproduce
Steps to reproduce the behavior:

  1. Create a new order with one item
  2. Proceed to payment
  3. On admin ui, make a refund that fails
  4. Try to do another refund for this order on the admin ui, the checkboxes will be missing.
  5. Try to call directly the refundOrder, you will have an AlreadyRefundedError. If I apply this fix I have a QuantityTooGreatError

Expected behavior
Be able to relaunch a refundOrder mutation if the first one fails.

Environment (please complete the following information):

  • @vendure/core version: 1.0.0-beta.8
  • Nodejs version: v12.20.2
  • Database (mysql/postgres etc): postgres

Additional context
Add any other context about the problem here.

@jdG- jdG- added the type: bug 🐛 Something isn't working label May 10, 2021
@michaelbromley
Copy link
Member

Thanks for the report. The root problem here is that the data model is not ideal on this point: it would be better to have a many-to-many relation from OrderItem <-> Refund. However, I'm not going to change the data model now since I don't want to introduce a breaking change at this stage. I think a workable solution can be implement on the current model:

  1. When attempting to refund, we look not only at whether an OrderItem currently has an associated Refund, but also at the state of that Refund. If it is "Failed" then we proceed with the next refund attempt.
  2. Upon processing the second refund attempt, we replace the OrderItem.refund relation with this second Refund (whether or not it succeeded).
  3. This cause a slight loss of data: the first Refund will no longer be associated with the OrderItems it was refunding. In practice I think this won't matter, but as a precaution we can add a special metadata object which enumerates the IDs & names of the OrderItems before we remove the relation.

@jdG-
Copy link
Contributor Author

jdG- commented May 11, 2021

Ok, I think a similar problem is happening with multiple payments now. If someone purchases an item with 2 or more payment methods and we need to refund the order, Method # 1 will be refunded but we will not be able to refund Method # 2.

@michaelbromley
Copy link
Member

michaelbromley commented May 11, 2021

The refund system is supposed to be able to deal with multiple payments (see the e2e test here), but it's a very complex area of the code base so there could be a bug there perhaps.

If you are able to reliably reproduce the issue you describe, please open an separate issue for that.

edit: I did identify an issue with the Admin UI which does not allow refunds more than the selected Payment amount. This is an artificial constraint since the server will start by refunding that payment, and then if the refund total is not covered it will attempt to refund against any remaining Payments. I will fix this as part of the work I'm doing on this issue.

@michaelbromley
Copy link
Member

This was a really meaty issue to fix! I did indeed find issues with the implementation of refunds when there are multiple Payments on an Order. I added some more e2e tests for these.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug 🐛 Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants