Skip to content

Fix 100x over-refund for small amounts: treat integer refund amounts as cents - #19

Open
nickygerritsen wants to merge 1 commit into
MultiSafepay:masterfrom
Lets-Talk-NL:fix/refund-amount-cents-mismatch
Open

nickygerritsen wants to merge 1 commit into
MultiSafepay:masterfrom
Lets-Talk-NL:fix/refund-amount-cents-mismatch

Conversation

@nickygerritsen

Copy link
Copy Markdown

Problem

The admin refund UI always sends the amount as an integer number of cents (MultiSafepayApi.service.js: Math.round(amount * 100)), but RefundController::normalizeRefundAmount() guesses the unit of integer input: any integer ≤ the order total is interpreted as full units (euros) instead of cents.

As a result, every refund whose cent value is smaller than the order's total in units is multiplied by 100:

  • Refunding €0.20 on a €25.00 order → UI sends 20 → 20 <= 25 → interpreted as €20.00 → €20.00 refunded (reproduced on 4.3.0 against the test API).
  • Refunding €5.00 on a €1,000.00 order → UI sends 500 → 500 <= 1000 → €500.00 refunded.

The larger the order, the larger the window: any refund up to 1% of the order total triggers the bug, and the money actually leaves the merchant's account.

Fix

Integer input (no decimal separator) is now always interpreted as cents, matching what the shipped admin UI sends. Decimal input ("9.99", "9,99") keeps its meaning of full units. The order-total-based guessing (and the now-unused $orderAmountTotal parameter) is removed, so the interpretation of an amount no longer depends on the order it is refunded against.

Tests

  • Updated testNormalizeRefundAmountParsesDecimalsAndCentsCorrectly to cover the regression case ("20" → €0.20) and adjusted the refund() happy-path test to send cents like the admin UI does.
  • All 25 unit tests in tests/Unit/Storefront/Controller/RefundController*Test.php pass.
  • Verified end-to-end on a Shopware 6.7.5 instance against the MultiSafepay test API: refunding with raw amount 20 on a €25 order now creates a €0.20 refund (previously €20.00).

🤖 Generated with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant