Skip to content

Invoices and Refunds

Matt MacDougall edited this page Sep 9, 2026 · 1 revision

Invoices and refunds

The invoice flow exchanges NetSuite cash sales. The refund flow imports NetSuite credit memos and cash refunds into store credit memos. Enable each required flow separately; these features are off by default unless configured.

Store invoice → NetSuite cash sale

An invoice save queues invoice_save when invoice export is enabled and the invoice is not marked to skip export or already linked. The exporter initializes a CashSale from the order's NetSuite SalesOrder, removes unrelated initialized lines, maps the invoice quantities and amounts, applies tax/discount plugins, and submits the cash sale. Its internal ID is saved on the store invoice.

The order must already be linked to a valid NetSuite sales order. Initializing a cash sale also depends on the account's transaction, payment, and permission configuration.

# Magento invoice entity ID
bin/magento netsuite:utils:processrecord --type=invoice_export --id=123

The manual command processes directly. Reconcile uncertain previous writes before using it; it is not a guarantee against creating a second remote cash sale.

NetSuite cash sale → store invoice

A cash sale is eligible when it has not already been imported under its NetSuite ID and createdFrom identifies a linked store order. The mapper builds invoice items and totals and saves the resulting invoice with its NetSuite identity. Changes to an already-imported cash sale do not constitute a general invoice-update flow.

# NetSuite CashSale internal ID, despite the invoice_import alias
bin/magento netsuite:utils:processrecord --type=invoice_import --id=123

There is no registered importer for the separate NetSuite Invoice record type. The invoice_import command alias refers to CashSale in this package. Invoice counters imported on an order are also distinct from invoice documents.

For an intentional historical cash-sale import, use the date-range command in Scheduling and CLI. It searches creation dates, not modification dates.

NetSuite refund → store credit memo

Enable Import Credit Memos and/or Import Cash Refunds as required. Both processors use the credit-memo mapper.

NetSuite custom field Meaning in this implementation
custbody_rw_cf_so_origin NetSuite SalesOrder internal ID used to find the original linked store order. Required for the repository to construct the credit memo.
custbody_rw_cf_refund_in_magento When true, construct the credit memo through the order's invoice; this requires exactly one invoice. Otherwise construct it from the order.

The mapper matches products to order items by NetSuite product identity, handles configurable relationships, ignores configured tax/discount item lines, and maps refund amounts, adjustment, subtotal, and tax.

Remote record/status Store credit-memo state
CreditMemo: Open Open
CreditMemo: Fully Applied Refunded
CreditMemo: Cancel Canceled
Unrecognized credit-memo status Open fallback
CashRefund Open

The code saves a credit memo through the repository. It does not invoke a payment-management refund operation. The custom field's name must not be treated as proof that money has been refunded through the store's payment gateway.

The import repository constructs a new credit memo rather than looking up an existing credit memo to update. Verify repeat-import and remote-edit behavior in the target installation before replaying refund records. There is no registered refund_import utility alias.

Boundaries

There is no store credit-memo export processor and no return-authorization/RMA importer. The inherited get_returns setting does not add an RMA workflow. Partial transactions, multiple invoices, duplicate delivery, payment effects, and accounting reconciliation need explicit sandbox acceptance.

Sources: invoice observer, cash-sale export, cash-sale import, invoice mappers, refund processors, credit-memo repository, refund mapper, status mapping, CLI registrations.

Clone this wiki locally