Case study · NetSuite OneWorld

Applying one customer payment across multiple subsidiaries

A customer pays once. The invoices it settles were raised by three different entities. NetSuite has no native answer for that, so we built one.

OneWorld Intercompany SuiteScript Cash application
The situation

One remittance, several entities

A multi-entity client sells to customers who buy from more than one of its subsidiaries. The customer does not care about that structure. They receive several invoices and pay them with one transfer.

Inside NetSuite, that single receipt then has to settle invoices belonging to entities it does not sit in — and a customer payment in OneWorld can only be applied to invoices in its own subsidiary. Everything else has to be moved with an intercompany journal.

Done by hand that is: work out which invoices belong where, raise a journal for each other subsidiary, get it approved, apply it there, and reconcile what is left. Every time a customer pays across entities. Which, for this client, was most weeks.

Why there is no setting for this

The constraint is structural, not a gap

A customer payment record belongs to a subsidiary. That is not a limitation anyone forgot to lift — it is what keeps each entity's books its own, and it is the reason intercompany accounts exist at all. The money genuinely has to move between entities, and that movement has to be recorded.

So the work is not to bypass the constraint. It is to do everything the constraint requires, automatically and correctly, the way a careful accountant would do it by hand.

By hand
  • Identify which invoices sit in which subsidiary
  • Apply the ones in the payment's own entity
  • Raise an intercompany journal for each other entity
  • Route it for approval and wait
  • Apply the journal against those invoices
  • Reconcile whatever is left over
What we built
  • Invoices grouped by subsidiary automatically
  • Same-entity invoices applied directly
  • One journal raised per other entity, correctly accounted
  • Left pending approval unless told otherwise
  • Applied on the far side once approved
  • Remainder reported rather than absorbed
The build

What it does

A user picks the invoices a receipt covers — across every entity in the customer's group, in one list. From there it runs on its own: invoices are grouped by subsidiary, the ones in the payment's own entity are applied straight to it, and every other subsidiary gets a single intercompany journal raised, accounted and applied on the far side.

Credit memos are offered alongside invoices, since a credit in the payment's own subsidiary raises what the receipt can settle. Credits belonging to other entities are deliberately not offered: NetSuite will only surface a payment the credits in its own subsidiary, so listing one from elsewhere meant it could be selected, silently skipped, and the funds it promised never arrive.

The engineering

Three decisions that mattered

The shape of the solution is the easy part. These are the three places where the obvious implementation is quietly wrong.

01

Never guess the intercompany accounts

An intercompany journal needs a due-to and a due-from account. The straightforward approach is to configure them once and fall back to a default. That default is the problem: it works in the account it was written for, and in any other account it posts to two arbitrary accounts. The journal balances, so nothing complains. The error is silent and it is in the ledger.

So the accounts are derived from NetSuite's own data instead. An intercompany account carries an elimination flag, and its type says which side it is — receivable for what an affiliate owes, payable for what is owed to one. Where that lookup is ambiguous or finds nothing, the script refuses to post and says why, rather than choosing.

02

Make the journal balance by construction

A receipt rarely covers the invoices selected against it exactly. Somebody short-pays, or picks more than the payment holds. The journal's total and its receivable lines then have to agree — and if they are computed independently, one capped at the payment and the other at the invoices' full remaining, they will not. NetSuite rejects the entry as soon as a selection exceeds the receipt.

The fix is to decide what each invoice receives once, then derive both sides of the entry from that allocation. Amounts are rounded to the cent as they are allocated rather than at the end, so the sum is exact rather than exact to within a floating-point error.

03

Do not approve on someone else's behalf

The script could approve the journals it raises, and the whole application would finish in one step. It does not, by default. Approving a posting on someone's behalf is a decision that belongs to the person whose ledger it is, not an assumption to make on their behalf.

Unticked, the journal is created pending approval and the application stops there. Once it is approved, applying again picks up that same journal rather than raising a second one. An account that wants the single step can turn it on deliberately.

Why this matters beyond the feature. All three are the same decision in different clothes: when the automation is not certain, it stops and says so instead of proceeding. That is the difference between something a controller will let near the general ledger and something they will not.
The outcome

A multi-entity receipt became a two-minute task

Cash application across entities stopped being a manual reconstruction and became a selection: tick the invoices, review what the script says it will do, and let it post. The intercompany journals it raises are ordinary NetSuite records, visible and auditable, following the client's own approval rules.

The same engine now runs inside BankSync, where it applies receipts that arrived on a bank statement rather than ones keyed by hand.

If this sounds familiar

Running OneWorld and reconciling across entities by hand?

Cross-subsidiary cash application is one of a handful of NetSuite problems that has no configuration answer — it needs building, and it needs building carefully, because the failure modes are silent and land in the ledger.

We have built this one. If you are doing it by hand every month, it is worth a conversation.

Talk it through with someone who has built it

No discovery deck. A conversation about what your close actually looks like.

Get in touch