-
Notifications
You must be signed in to change notification settings - Fork 7
Description
Description
When a partial refund (credit slip) is created in PrestaShop for customers in a group with price_display_method = 1 (prices displayed excluding VAT), the module sends the tax-excluded amount to Pay. instead of the tax-included amount. This results in customers receiving less money back than they should.
The bug does not occur for customers with price_display_method = 0 (prices displayed including VAT).
Note: This bug is still present in the latest version (5.3.0). See: paynlpaymentmethods.php#L632
Environment
- PrestaShop version: 8.1.7
- PHP version: 8.x
- Module version: 4.17.7 (also verified in 5.3.0)
Root Cause
In hookActionOrderSlipAdd(), the module uses $product['amount'] from the productList:
foreach ($productList as $key => $product) {
if (!empty($product['amount']) && $product['amount'] > 0) {
$refundAmount += $product['amount'];
}
}The amount field comes from PrestaShop's OrderRefundCalculator::flattenCheckedProductRefunds() and its value depends on the customer group's price_display_method:
price_display_method = 0(Tax included):amount= price including VAT ✅price_display_method = 1(Tax excluded):amount= price excluding VAT ❌
Since customers always pay including VAT, refunds should always be the VAT-inclusive amount.
Steps to Reproduce
- Have a customer in a group with
price_display_method = 1(prices displayed excluding VAT) - Customer places an order and pays via Pay.
- Create a partial refund (credit slip) for one or more products
- Check the amount sent to Pay. in the logs
Expected Behavior
The refund amount sent to Pay. should match the credit slip total including VAT.
Actual Behavior
The refund amount sent to Pay. equals the credit slip total excluding VAT.
Example:
| Credit slip (incl VAT) | Credit slip (excl VAT) | Sent to Pay. |
|---|---|---|
| €20.44 | €16.90 | €16.90 ❌ |
| €63.22 | €52.25 | €52.25 ❌ |
Suggested Fix
PrestaShop provides total_refunded_tax_incl in the productList which is always VAT-inclusive regardless of price_display_method. The module should use this field instead:
public function hookActionOrderSlipAdd(array $params)
{
// ...
foreach ($productList as $key => $product) {
// Use total_refunded_tax_incl (always VAT-inclusive) instead of amount
if (!empty($product['total_refunded_tax_incl']) && $product['total_refunded_tax_incl'] > 0) {
$refundAmount += $product['total_refunded_tax_incl'];
} elseif (!empty($product['amount']) && $product['amount'] > 0) {
// Fallback for backwards compatibility
$refundAmount += $product['amount'];
}
}This solution is not tested.
Impact
All partial refunds for customers in groups with price_display_method = 1 are affected. Customers receive less money back than shown on their credit slip (the VAT portion is missing from the refund).