PayPalPlugin icon indicating copy to clipboard operation
PayPalPlugin copied to clipboard

[Bug] Partial refund executed multiple times on PayPal panel

Open thomsult opened this issue 11 months ago • 4 comments

SyliusPayPalPlugin version affected: 1.5.0 Sylius version affected: 1.11.0

Description

Hello everyone,

I encountered an issue with the PayPal plugin in Sylius: when I perform a partial refund of an order using the refund-plugin, it appears correctly in my Sylius admin panel.

However, on PayPal, the refund is executed multiple times, as if it were being repeated automatically. Once the order is fully refunded, the payments are marked as completed.

Steps to reproduce

  • Use Sylius with the refund-plugin and the paypal-plugin.
  • Perform a partial refund via the refund-plugin.
  • Observe the behavior: - The refund is correctly recorded in Sylius. - On PayPal, multiple refund transactions are executed successively until the full order amount is refunded.

Expected behavior

When a partial refund is issued, PayPal should only execute one refund for the requested amount, without repetition.

Thanks in advance for your help! 🙏

Additional Information

I don’t know if this issue is related, but I am also experiencing the same problem with Payplug: partial refunds seem to be executed multiple times as well. SyliusPayPlugPlugin

thomsult avatar Jan 30 '25 15:01 thomsult

@thomsult have you found a workaround ? thx

wadjeroudi avatar May 13 '25 13:05 wadjeroudi

When you refund on the Paypal dashboard, this triggers the “refund” webhook, which applies the refund transition to the payment. There's a callback on this transition that calls the PayPal API for a full refund.

The simplest solution is to remove the webhook from PayPal's developer dashboard. Another solution is to override RefundOrderAction (service: sylius_paypal.controller.webhook.refund_order) to remove the refund transition application.

rv-garnier avatar May 14 '25 10:05 rv-garnier

The PayPal plugin does not provide an out-of-the-box integration with the RefundPlugin — in particular, it does not handle partial refunds. The logic currently implemented in the PayPal plugin only covers full refunds.

If you need partial refund support, you would have to implement your own logic that listens to the appropriate refund events and interacts with PayPal accordingly. One way to achieve this is to create a service implementing the following interface:

namespace App\Refund;

use Sylius\RefundPlugin\Event\UnitsRefunded;
use Sylius\RefundPlugin\ProcessManager\UnitsRefundedProcessStepInterface;

interface PayPalRefundInterface extends UnitsRefundedProcessStepInterface
{
    public function next(UnitsRefunded $event): void;
}

This custom implementation would allow you to handle partial refunds and send the correct refund amount to PayPal without triggering multiple full refund operations.

tomkalon avatar Aug 13 '25 10:08 tomkalon

Hi @tomkalon,

Thanks for clarifying that the PayPal plugin currently only supports full refunds and does not integrate directly with the RefundPlugin for partial refunds.

Your suggestion about implementing a custom service that listens to UnitsRefunded events makes sense. I’ll look into creating a service implementing UnitsRefundedProcessStepInterface (as in your example) to handle partial refund logic and ensure the correct amount is sent to PayPal without triggering multiple full refunds.

Thanks again for the guidance!

thomsult avatar Aug 16 '25 21:08 thomsult