Troubleshooting
"This order can't be returned" and the customer disagrees
Run the verdict yourself:
php craft boomerang/returns/show RMA-00042
Eligibility is one verdict with a per-line trace, so it tells you which line was refused and why, rather than only that something was. The usual causes, in order of how often they happen:
- the order is outside
returnWindowDays, or outside the reason's own window - the line has already been returned in full on an earlier RMA
- the order is not complete
- the line is a shipping or discount adjustment rather than a purchasable
The customer says the portal won't find their order
A guest lookup needs the order number and the email together, and a wrong number and a wrong email are answered with the same sentence — deliberately, so the form cannot be used to enumerate order numbers. So "no such order" genuinely can mean "the email is wrong".
The lookup is also rate limited per IP per hour. A customer who has just tried eleven times will be refused even with the right details.
A transition refused and the RMA didn't move
That is the design. Side effects run before the state is written, so a refund the gateway refuses aborts the whole transition — the RMA stays where it was and the reason is on its history.
Read the history panel on the RMA: the failure is a row on it, with the gateway's own message.
A refund partially went through
services\Refunds::issue() writes refundedAmount after every successful gateway refund, before
it throws. An order paid across three transactions where the second is refused therefore records the
first refund and stops.
The RMA will show a refundedAmount lower than its resolutionAmount. Refund the remainder from
the order's own transactions in Commerce, then move the RMA on.
Restocking ran twice
It didn't. Restock::apply() is idempotent per item through qtyRestocked. If the numbers look
wrong, check whether something else in the install is also adjusting inventory on the same event.
Inventory went negative
If committed is negative, something is using InventoryRestockMovement for goods that were already
fulfilled — that model moves committed → available and is for an order that was never shipped.
Boomerang uses an ADJUST-type UpdateInventoryLevel, which cannot cause this.
"Impossible to access an attribute on a string variable"
A public string property backing an enum shadows its own getter in Twig. Use state.getKind(),
item.getCondition(), return.getResolution(), event.getType(),
reason.getDefaultCondition() — see Enums in templates.
A state or reason can't be saved after an import
Craft's HandleValidator rejects hyphens. A row seeded or imported with a handle like in-transit
inserts fine — a migration and an import both bypass validation — and then cannot ever be re-saved
from the edit screen.
Rename the handle to camelCase (inTransit). Transition lists are stored as handles, so fix them in
the same pass or the list will point at nothing.
The store-credit gateway isn't at checkout
Check, in this order:
- the plugin is on Pro — the wallet is a Pro feature
- a Store Credit (Boomerang) gateway exists in Commerce → Settings → Gateways
- the gateway's
isFrontendEnabledis on — that is the property, notenabled - the customer is signed in — a wallet belongs to a customer, not to a cart
- the customer's balance is above zero, counting only unexpired lots
Credit vanished
Two possibilities, and the history tells them apart:
- it expired — expiry is enforced in the balance on read, not only by the cron, so an unrun
boomerang/credit/expiredoes not let expired credit be spent - it is on hold — an authorization that was never captured holds the money. Release them with
php craft boomerang/credit/release-holds
A deleted customer's credit disappeared, then came back
Craft soft-deletes users, so the CASCADE foreign key on users.id does not fire when a
customer is deleted. That is correct for credit: a restored customer gets their balance back.
An RMA whose order is gone
Expected, and supported. orderId is SET NULL, and the order's number, reference, date and email
are copied onto the RMA when it is created. In several jurisdictions "what did we do about this
return" is a question a merchant is required to be able to answer after the order itself has aged
out.
Emails aren't arriving
A state change never fails because mail did. Anything that runs during a transition fails closed on money and open on chrome, so a dead mail server logs a row on the RMA's history and otherwise lets the transition through. Check the history panel — the attempt is recorded there.