Skip to content

PRE-3715: Allow Oney refunds based on the PayPlug API refund window - #336

Merged
hdelaforce-payplug merged 2 commits into
developfrom
feature/PRE-3715_remove-oney-48h-refund-delay
Oct 22, 2026
Merged

hdelaforce-payplug merged 2 commits into
developfrom
feature/PRE-3715_remove-oney-48h-refund-delay

Conversation

@hdelaforce-payplug

@hdelaforce-payplug hdelaforce-payplug commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Description

Oney refunds are no longer held back by a hardcoded 48h delay. The refund window returned by the PayPlug API (refundable_after / refundable_until) is now the only rule, which matches the PrestaShop and WooCommerce plugins.

  • Removed the local 48h rule. RefundPaymentGeneratedHandler blocked a refund for 48h after the last payment and after the last processed refund, so successive partial refunds were blocked too. The private checks, the now-unused $orderRepository / $translator constructor arguments and OneyGatewayFactory::REFUND_WAIT_TIME_IN_HOURS are gone.
  • RefundUnitsCommandCreatorDecorator::canOneyRefundBeMade() is now the single local check, run on the admin refund form before the refund is dispatched:
    • refused when now < refundable_after, with "The Oney refund will only be possible from %date%."
    • refused when now > refundable_until, with "The Oney refund period ended on %date%…"
    • the exact boundary instants are now accepted (they were rejected before);
    • a missing or null bound means no restriction on that side. Before, it raised an undefined-property warning and showed the misleading 48h message. The PayPlug API stays the final authority and still rejects an out-of-window refund, with nothing recorded locally.
    • %date% is built with IntlDatePatternGenerator (skeleton yMMMdjmmz) in the translator locale and the PHP default timezone. It shows the locale's medium date, hours:minutes and a short timezone name, for example "Jan 1, 2100, 12:00 PM UTC" or "1 janv. 2100, 13:00 UTC+1".
  • Translations (en/fr/it): ui.oney_transaction_less_than_forty_eight_hours is replaced by ui.oney_refund_not_available_before and ui.oney_refund_period_expired.

Motivation: merchants had to wait an arbitrary 48h before refunding an Oney order, and again 48h between two partial refunds, even when the API already allowed the refund.

Related issue(s): PRE-3715. Possibly related to PRE-3710 (multi-line Oney refund error), but not claimed as fixed: see Notes for reviewer.


Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue) [x]
  • ✨ New feature (non-breaking change that adds functionality) [x]
  • 💥 Breaking change (fix or feature that causes existing functionality to change and that could impact other libs) [x]
  • 🔧 Refactor (no functional changes, code improvement only) [ ]
  • 📦 Dependency update [ ]
  • 🔒 Security fix [ ]
  • 📝 Documentation update [ ]

Checklist

Code Quality

  • Code is linted and formatted
  • No unnecessary commented-out code or debug logs
  • No hardcoded values (use env variables or config)

Testing

  • Unit tests added / updated
  • New/changed code is covered by tests — SonarCloud Quality Gate (coverage on new code) passes on the sonarcloud CI job

Security & Ops

  • No sensitive data or secrets introduced
  • Logging and error handling are appropriate

Notes for reviewer

Scope. This PR contains only the Oney refund-window change, plus a follow-up commit that adds the timezone to the displayed date. An earlier version of this branch also carried a Sylius 2.3 provider-compatibility change and two CI changes (refund-plugin update in the Makefile, Node 22). Those were dropped when the branch was rebuilt on develop. They did not land on develop: develop caps Sylius below 2.3 in CI instead (PRE-3673). Sylius 2.3 compatibility is left for a separate ticket.

Breaking changes. All of these are documented in the CHANGELOG 2.0.0 "Breaking changes for anyone extending the plugin" table. 2.0.0 is still unreleased.

  • OneyGatewayFactory::REFUND_WAIT_TIME_IN_HOURS is removed, not deprecated. The class is final and nothing reads the constant any more.
  • Translation key ui.oney_transaction_less_than_forty_eight_hours is removed. It is replaced by the two new keys, which take a %date% parameter.
  • RefundPaymentGeneratedHandler::__construct() drops $orderRepository and $translator. The class is final and container-built.

The behaviour change is intended: a refund that was blocked for less than 48h is now allowed whenever the API allows it.

Testing.

Check (PHP 8.3) Result
PHPUnit (run file by file) Pass. 72 of 77 files ran, 727+ tests, 0 failures. See "Not run" for the other 5.
PHPStan (level max) No errors
ECS No errors
PHPMD No new violations
CI on the previous head (52665b7) All checks green, including the PHP 8.4 matrix and SonarCloud

New tests:

  • tests/PHPUnit/Creator/RefundUnitsCommandCreatorDecoratorTest.php (16 tests) covers:
    • inside the window, and the exact refundable_after boundary;
    • before and after the window, with the dated messages, which must now include a timezone marker and no seconds;
    • every null or missing bound combination;
    • fr locale with the Europe/Paris timezone;
    • two refunds in a row;
    • the existing 10-cent minimum;
    • non-Oney gateways, which never call the API.
  • tests/PHPUnit/MessageHandler/RefundPaymentGeneratedHandlerTest.php: an Oney refund on a just-created payment reaches the API, and an API refusal records nothing.

Not run:

  • 5 PHPUnit files locally. UnifiedAuthenticationControllerTest, PayPlugApiClientFactoryTest, UnifiedApiOperationStatusFetcherTest, UnifiedApiPaymentCreatorTest and UnifiedApiRefundCreatorTest were stopped by a local-only debug statement in vendor/. They ran green in CI on the previous head.
  • Behat. It cannot boot locally (Lakion\Behat\MinkDebugExtension not found). The four 48h scenarios in features/admin/refunding_oney_payment.feature were replaced by window-based ones, and the context, mocker and ui.xml were updated, but they were never executed. The date assertions check the Jan 1, 2100 / Jan 1, 2020 prefix, which the timezone change keeps.
  • Manual TEST environment. Oney 3x/4x full and partial refunds, with and without fees, still need checking (acceptance criterion 4). In particular, check whether the API itself moves refundable_after after a first partial refund. If it does, successive refunds stay blocked by the API, now with an accurate date. That is why PRE-3710 is not claimed as fixed.

Unticked checklist items:

  • SonarCloud: it passed on the previous head; the timezone commit still has to go through CI.
  • Logging and error handling: this PR does not change it. A failing PayPlugApiClient::retrieve() (timeout, 404) in the decorator still surfaces as an admin 500, as before. It is out of scope for this story and a possible follow-up.

Scope notes:

  • The local window check guards the admin refund-units form only. The Sylius refund payment transition and refunds made from the PayPlug portal never had a local Oney check, and that is unchanged.
  • RefundHistoryRepositoryInterface::findLastProcessedRefundForPayment() no longer has a caller. It is kept on purpose because it is on a public interface.
  • The displayed time uses the PHP default timezone (Sylius 2.2 has no channel or admin timezone). The timezone is now shown next to the time, so a merchant in another zone can read it correctly.

Changelog: CHANGELOG.md 2.0.0, with entries under Changed and Removed, plus three rows in the BC table.

@hdelaforce-payplug hdelaforce-payplug changed the title Feature/pre 3715 remove oney 48h refund delay PRE-3715: Allow Oney refunds based on the PayPlug API refund window Oct 8, 2026
@hdelaforce-payplug
hdelaforce-payplug force-pushed the feature/PRE-3715_remove-oney-48h-refund-delay branch 5 times, most recently from e693723 to 6ae66b5 Compare October 9, 2026 13:46

@claude claude Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Claude Code Review

Claude Code Review is paused for this repository. To reconnect it, an admin of this repository's GitHub organization (or the account owner, for personal repositories) who can also manage your Claude organization's Code Review settings needs to re-link GitHub in Code Review settings. This is a one-time step.

Tip: disable this comment in your organization's Code Review settings.

Comment thread src/Creator/RefundUnitsCommandCreatorDecorator.php Outdated
Comment thread CHANGELOG.md
@adumont-payplug
adumont-payplug force-pushed the feature/PRE-3715_remove-oney-48h-refund-delay branch from 6ae66b5 to 52665b7 Compare October 20, 2026 08:59
@hdelaforce-payplug
hdelaforce-payplug merged commit 4f278b0 into develop Oct 22, 2026
12 of 13 checks passed
@hdelaforce-payplug
hdelaforce-payplug deleted the feature/PRE-3715_remove-oney-48h-refund-delay branch October 22, 2026 12:36
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.

2 participants