Skip to content

WooCommerce refunds are never exported — no CreditNote object, no refund hook #17

Description

@Pichinov-Jose

Repository: SplashSync/Wordpress
Plugin version: 2.1.0 (code identical at current master HEAD)
WooCommerce: 11.0.1 · Target node: Dolibarr module 2.23.3
Type: feature gap

Summary

WooCommerce records refunds as first-class objects — one shop_order_refund post per refund,
carrying its own amount, date, reason, author and gateway reference. The connector ignores them
entirely. There is no CreditNote object type, and no hook on the refund lifecycle, so a refund
never reaches the target node in any form.

The result is an accounting divergence that grows silently: the shop knows money went back, the ERP
does not, and the source invoice stays settled at its full amount forever.

What the connector exposes today

src/Objects/  ->  Address.php  Invoice.php  Order.php  Page.php  Post.php  Product.php  ThirdParty.php

No CreditNote. And no refund hook anywhere in the plugin:

grep -rniE "woocommerce_(order_refunded|refund_created|refund_deleted)" src/   ->  no match

refund appears in exactly four places, all of them about the order status, never about the
refund object:

src/Core/InvoiceStatusManager.php:36      "cancelled", "refunded", "trash",
src/Core/OrderStatusManager.php:39        OrderStatus::CANCELED => array("cancelled", "refunded", "trash"),
src/Objects/Order/PaymentsTrait.php:100   if ($this->object->get_date_paid() && ("refunded" != $this->object->get_status()))
src/Objects/Order/StatusTrait.php:180     case 'refunded':

Why the status mapping does not cover it

That mapping only fires on a full refund, which moves the order to wc-refunded. A partial
refund leaves the order in completed or processing — WooCommerce's intended behaviour — so
nothing whatsoever changes in what Splash exports. The order is committed again with the same
totals, and the target sees no difference.

Even for a full refund, mapping to OrderStatus::CANCELED tells the ERP the order was cancelled, not
that a refund was issued for a given amount on a given date. Those are different accounting events
and only one of them is true.

Measured on a production install

shop_order_refund posts 448
orders carrying _stripe_refund_id 359
refunds visible to the target node 0

Cross-checking one season against the Dolibarr node: 34 refunded orders, 2 991,20 €, all present
in WooCommerce, none of them present in the ERP — no credit note, no negative payment, no bank
movement. All 34 source invoices are still paye = 1 at their full amount.

The data is all there

Per shop_order_refund post:

Meta Content
_refund_amount refunded amount
_refund_reason free-text reason
_refunded_by user id who issued it
_refunded_payment 1 if it went through the gateway, empty if recorded manually
post_date when
post_parent the order it belongs to

And on the parent order, for Stripe: _stripe_refund_id (re_… / pyr_…) and _transaction_id
(ch_… / py_…).

_refunded_payment is worth passing through as-is: it is the difference between "the money left" and
"someone typed a number into the admin", and the target cannot guess it.

WooCommerce also exposes this natively — $order->get_refunds(), WC_Order_Refund::get_amount(),
get_reason(), get_refunded_by() — so no direct meta reads are needed.

The other half of the chain already exists

SplashSync/Dolibarr ships a CreditNote object (src/Objects/CreditNote.php), whose CRUDTrait
sets type = Facture::TYPE_CREDIT_NOTE on create and whose trigger dispatches credit notes back as
CreditNote. The target is ready to receive them. Only the source side is missing.

Suggested implementation

  1. A CreditNote object type, listing shop_order_refund posts, with the refund amount, date,
    reason, gateway reference, and an object link to the source order or invoice.
  2. Hooks on the refund lifecyclewoocommerce_order_refunded and woocommerce_refund_deleted
    — committing CreditNote / SPL_A_CREATE and SPL_A_DELETE. Both fire reliably in WooCommerce for
    admin, REST and gateway-initiated refunds.
  3. Line detail where it exists. WooCommerce can attach line items to a refund, but rarely does:
    on this install, 4 line items across 448 refunds. So a single-line credit note at the refund
    amount must be the supported case, with line detail as a bonus rather than a requirement.

Related

Linking the resulting credit note to the right invoice requires fk_facture_source on the Dolibarr
side, which is not exposed either — filed separately on SplashSync/Dolibarr.

Activity

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

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