mothership-ec / cog-mothership-returns

Mothership Returns Cogule
Other
0 stars 1 forks source link

Refunding only refunds a single payment object #177

Open thomasjthomasj opened 9 years ago

thomasjthomasj commented 9 years ago

Bug description

Processing refunds on instances of PayableInterface only refunds a single payment, when it's feasible that there could be multiple payments against them.

An example of this bug in action is when a customer has bought an item, returned it with an exchange for a more expensive item, then returned that and asked for a refund. This means that there are two payments against the order - the original payment (£75), then the difference in price between the original purchase and the exchange item (£75), meaning that the total amount paid is £150.

When the client attempted to refund the customer, an error in Stripe occurred as a refund of £150 was attempted to be paid against a £75 payment.

We need to be able to loop through the payments and refund them accordingly. However, I'm not sure exactly how this works, as we will need to find a way of deciding which payments need refunding first. We will also probably need to implement a BC break in Commerce as we should add a getPayments() method to the PayableInterface. I have made a start on fixing this issue in commerce here but it will require a bit more working out.

How can this be replicated?

Related Issues / Trello Card / Code?

Anything else to add? (Screenshots, background context, etc)

jamiefreeman commented 9 years ago

https://github.com/messagedigital/cog-mothership-returns/blob/develop/src/Controller/OrderReturn/Refund.php

thomasjthomasj commented 9 years ago

In the class linked above, we should sort out the following method:

    public function success(PayableInterface $payable, $reference, MethodInterface $method)
    {
        $payment = null;
        foreach ($payable->item->order->payments as $p) {
            $payment = $p;
        }
        $this->get('return.edit')->refund($payable, $method, $payable->getPayableAmount(), $payment, $reference);
        $successUrl = $this->generateUrl('ms.commerce.return.view', array(
            'returnID' => $payable->id,
        ), UrlGeneratorInterface::ABSOLUTE_URL);
        // Create json response with the success url
        $response = new JsonResponse;
        $response->setData([
            'url' => $successUrl,
        ]);
        return $response;
    }

It's still working with the assumption that the PayableInterface is an order, and makes extensive use of public properties where it would be safer to get these things using methods