Skip to content

Partial refunds use tax-excluded amount for customers with price_display_method = 1 #69

@muyncky

Description

@muyncky

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

  1. Have a customer in a group with price_display_method = 1 (prices displayed excluding VAT)
  2. Customer places an order and pays via Pay.
  3. Create a partial refund (credit slip) for one or more products
  4. 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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions