# Journal Wrappers

A family of write endpoints that all do the same thing in different clothes: each takes a header/line **document**, and on `process` turns it into standard general-journal lines and posts them through Business Central's own posting engine. One endpoint per document type, plain-language names like `customerPayments`, `vendorRefunds` or `bankGLEntries`, so a caller never has to hand-build a journal line or know a Business Central document-type code. They are all backed by **one shared staging table and one posting engine**; the endpoint you POST to is what tells the engine the party and the resulting entry type.

> **Note:** This family is switched on per company. The ten ledger endpoints follow the **Ledger documents** switch and `expenses` follows the **Expenses** switch, both on the Features tab of **eOne Integration Setup**. While a switch is off, its endpoints return an error naming the feature. See [Overview](https://eonesolutions.github.io/eone-bc-integration/home.md).

## The endpoints

| Endpoint | Records | Party | Posts as |
| --- | --- | --- | --- |
| [`customerPayments`](https://eonesolutions.github.io/eone-bc-integration/core-customerPayments.md) | Money received from a customer | Customer | Payment |
| [`customerRefunds`](https://eonesolutions.github.io/eone-bc-integration/core-customerRefunds.md) | Money refunded to a customer | Customer | Refund |
| [`customerCreditMemos`](https://eonesolutions.github.io/eone-bc-integration/core-customerCreditMemos.md) | A credit memo issued to a customer | Customer | Credit Memo |
| [`customerInvoices`](https://eonesolutions.github.io/eone-bc-integration/core-customerInvoices.md) | A direct customer invoice (a debit to the customer) | Customer | Invoice |
| [`vendorPayments`](https://eonesolutions.github.io/eone-bc-integration/core-vendorPayments.md) | Money paid to a vendor | Vendor | Payment |
| [`vendorRefunds`](https://eonesolutions.github.io/eone-bc-integration/core-vendorRefunds.md) | A refund received from a vendor | Vendor | Refund |
| [`vendorCreditMemos`](https://eonesolutions.github.io/eone-bc-integration/core-vendorCreditMemos.md) | A credit memo from a vendor | Vendor | Credit Memo |
| [`vendorInvoices`](https://eonesolutions.github.io/eone-bc-integration/core-vendorInvoices.md) | A direct vendor invoice (a debit against the vendor) | Vendor | Invoice |
| [`employeePayments`](https://eonesolutions.github.io/eone-bc-integration/core-employeePayments.md) | An employee reimbursement | Employee | Payment |
| [`expenses`](https://eonesolutions.github.io/eone-bc-integration/core-expenses.md) | An employee expense report | G/L distribution | : |
| [`bankGLEntries`](https://eonesolutions.github.io/eone-bc-integration/core-bankGLEntries.md) | A generic bank / G/L journal entry (fees, accruals, adjustments) | G/L distribution | : |

## Two families

**Ledger movements** (customer, vendor and employee) post against a party with a balancing bank/cash line. The endpoint derives both the amount **sign** and the Gen. Journal Document Type from the endpoint itself (see *Amounts are positive* below).

- **Applying documents.** `payments` and `refunds`, settle posted documents, so they carry an `applications` child collection: one line per settled document. The line amounts may total less than the header `amount`, leaving the difference on the party's account, and may never total more.
- **Originating documents.** `invoices` and `creditMemos`, raise or reduce a balance in their own right, so they need **no** application lines: a header `amount` posts on its own. (You *may* still add application lines for the rare case of applying an invoice to an on-account prepayment.)

**G/L distribution** documents ([expenses](https://eonesolutions.github.io/eone-bc-integration/core-expenses.md) and [bank / G/L entries](https://eonesolutions.github.io/eone-bc-integration/core-bankGLEntries.md)) instead carry a lines collection of G/L distributions and post one G/L line per line plus a single balancing line. Each has its own collection, [expenseLines](https://eonesolutions.github.io/eone-bc-integration/core-expenseLines.md) and [bankGLEntryLines](https://eonesolutions.github.io/eone-bc-integration/core-bankGLEntryLines.md).

> **Note:** The wrappers do not all sit behind one feature switch. The nine party-facing endpoints answer to **Ledger documents**, `expenses` to **Expenses**, and `bankGLEntries` to **Bank / G/L entries**. Turn on the one you are calling. See [Feature switches](https://eonesolutions.github.io/eone-bc-integration/home.md).

## One settlement, one ledger entry

A payment that settles five invoices posts **one** customer, vendor or employee ledger entry for the money that moved, not five. The party's statement shows the one receipt they actually sent you, and the five invoices close underneath it as five detailed ledger entries.

Business Central does this with an applies-to id. The engine marks each settled document's open entry with the amount this document applies to it. It then posts a single party line carrying that id, and posting closes every marked entry against it. You send nothing extra: put one application line per document you are settling, exactly as before, and the engine decides the shape.

- **One document settled**: the party line names it directly, and no ledger entry is marked. Nothing about a single settlement changed.
- **Several documents settled**: one party line for the applied total, carrying the applies-to id.
- **The balancing bank or cash line stays one line** for the whole document, whichever shape applies.

`appliedAmount` and `numberOfApplications` count your application lines, not journal lines, so they read the same as they always did.

> **Caution:** A document is refused if one of its targets is already being applied by something else, such as an unposted journal line someone left in a batch. The message names the applies-to id holding it. Post or clear that application, then process the document.

## Check a staged document from its own payload

Every party-facing endpoint returns four read-only roll-ups over its application lines, so SmartConnect can judge a staged document from the response rather than reading the English text in `errorMessage` (which is also translated).

| Field | What it tells you |
| --- | --- |
| `appliedAmount` | The sum of the application lines. |
| `numberOfApplications` | How many application lines the document has. |
| `applicationsResolved` | How many of them already point at a posted document. |
| `applicationsAwaitingInvoice` | How many still name a document by `integrationId` that has not posted yet. |

**Does it balance?** The header `amount` is a ceiling, not a target. The engine accepts a document whenever `appliedAmount` is at or below `amount`, which covers the originating invoice or credit memo that carries no application lines at all (`numberOfApplications` = `0`, `appliedAmount` = `0`). What `validate` and `process` both reject is `appliedAmount` **above** `amount`: nothing on the header covers it. The rejection names both figures.

A shortfall is not a rejection. The difference posts against the party unapplied and waits on their account, the way a part-paid receipt behaves in Business Central. SmartConnect therefore decides for itself whether a shortfall was intended: compare `appliedAmount` with `amount`, both of which come back on every read and every write echo, and only send the document when they agree if an exact match is what your process requires.

**Why is it waiting?** `status` = **Awaiting Invoice** says the document is parked. `applicationsAwaitingInvoice` and `applicationsResolved` say how much of it is parked and how much is ready. That also carries the wrong-party warning: when a payment waits on an `integrationId` whose unposted document belongs to a different customer, vendor or employee, the warning itself is prose in `errorMessage`, but the counts beside it stay machine-readable.

### The unapplied remainder

`amount` less `appliedAmount` is what the document leaves on the party's account. SmartConnect sends nothing extra for it: `process` writes the remainder as one more party line with no applies-to reference, and the bank or cash line still moves the full header `amount`, so the journal balances.

That is the same line you get by POSTing an application with neither `appliesToInvoiceNumber` nor `appliesToInvoiceIntegrationId`, which is how a remainder was entered by hand before. Both take one code path, so the automatic remainder and the hand-written one post identically. Write it by hand when the remainder deserves a note of its own: that line's `comment` becomes the journal line description, where the automatic remainder carries the header description.

A `comment` reaches the journal line description only where one application line owns that line, which means an unapplied line or a document settling a single target. Several settled documents share one journal line, and a note about one of them would misdescribe the rest, so the header description stands. Every comment is still readable against the processed document in the eOne Processed Documents history.

### `appliedAmount` here, `totalAmount` on the distribution endpoints

The two families name the same roll-up differently, and deliberately keep it that way. `appliedAmount` and the `totalAmount` on [expenses](https://eonesolutions.github.io/eone-bc-integration/core-expenses.md) and [bankGLEntries](https://eonesolutions.github.io/eone-bc-integration/core-bankGLEntries.md) are both the sum of the child lines. What differs is what the sum is for: a ledger document also carries a caller-declared header `amount`, so its sum is a **check** against that, and the name says what the lines did. A distribution document has no separate header amount, so its sum **is** the document total and there is nothing to balance. The ledger endpoints do not publish a second `totalAmount` column, because on a part-applied document it would return `appliedAmount` while reading like the document's value.

## Amounts are positive; the engine sets the sign

Send every amount as a **positive magnitude**, the header `amount` and each application-line `amount`. The engine derives the debit/credit direction from the document type, so a caller never has to know that, for example, a customer receipt is a *negative* entry against the customer:

- A **customer payment** of `1000` posts the customer at −1000 (credit, reducing the receivable) and the bank at +1000 (debit).
- A **customer invoice** of `1000` posts the customer at +1000 (debit) and the balancing account at −1000 (credit).

The balancing line always carries the opposite sign of the party line, and applying a payment to an invoice is handled by Business Central's own application once the engine sets the applies-to link, you never manage the invoice's sign.

## Money withheld before it arrived

A payment often reaches the bank net of somebody else's cut - a card or PSP fee, a marketplace commission. Send the gross on `amount` and the withheld part on `deductionAmount` plus `deductionAccountNumber`, and the document posts all three sides: the party is credited everything they paid, the fee goes to its own account, and the bank line takes only what landed. Stripe's gross / fee / net maps straight onto it.

```
amount 100.00, deductionAmount 3.10, deductionAccountNumber 60400

  Customer        credit  100.00     settles the full amount they paid
  Merchant fees   debit     3.10     deductionAccountNumber
  Bank            debit    96.90     what actually arrived
```

Both fields go together, the deduction must be less than the document amount, and only the **applying** documents accept one - an invoice or credit memo moves no cash, so there is nothing for a fee to be withheld from.

> **Caution:** Do not use a deduction for realized FX, a payment discount or application rounding. Business Central posts all three by itself - from the currency's realized gain/loss accounts, the posting groups' payment-discount accounts, and the currency's application rounding precision - so a deduction on top books the same thing twice. It balances either way, which means nothing will complain.

## It posts like a hand-entered journal

Name the target journal with `journalTemplateName` + `journalBatchName`, or leave them blank to use the defaults on the **eOne Integration Setup** page. The generated lines **inherit that journal's**, source code, reason code, posting no. series, document numbering and Copy-VAT setup.

**Dates** default the way the journal UI does: leave `postingDate` blank and it takes the **work date**; leave `documentDate` blank and it takes the posting date. **External Document No.**: when *Ext. Doc. No. Mandatory* is enabled (Sales & Receivables / Purchases & Payables Setup), an `invoice` or `creditMemo` must carry `externalDocumentNumber`, and `process` reports it up front rather than failing deep in posting.

## Vendor payment remittance

All four vendor endpoints - `vendorPayments`, `vendorRefunds`, `vendorCreditMemos` and `vendorInvoices` - accept the remittance details a payment file or check needs (`recipientBankAccount`, `creditorNumber`, `paymentReference` and `bankPaymentType`) carried onto the vendor journal line so the payment journal can export (SEPA / ISO 20022) or print them. They are ignored for non-vendor documents.

The remittance details ride the party line that settles a document, so on a credit memo or an invoice they take effect once the document carries application lines. A credit memo or invoice posted as a bare header settles nothing, and posts without them.

## The three actions, and how you learn what happened

Every endpoint in this family carries the same three bound actions:

- `validate` runs the posting checks and writes nothing. The staged document is still there afterwards, and the response points back at it.
- `process` turns the document into journal lines, left as an unposted draft or posted, according to the mode below.
- `post` processes the document **and posts it**, whatever the mode says. This is how SmartConnect commits one document to the ledger without an administrator putting the whole endpoint on Auto Post. Only the lines that document just wrote are posted, so other drafts sitting in the same journal batch are left alone, and the approval gate still applies: a document that needs approval and has not got it is refused by `post` exactly as it is by `process`.

A staged document deletes itself the moment its journal lines exist, so `process` and `post` cannot answer with the document you called them on. They answer with the [Processed Documents](https://eonesolutions.github.io/eone-bc-integration/core-processedDocuments.md) row written by the same call, and the response carries that row's location. It holds `status`, `postedDocumentNumber`, `postedPostingDate` and `glTransactionNumber`: after `post` the posted figures are already filled in, and after `process` the row sits at **Processed** until the draft is posted in Business Central. The same row is addressable by the `integrationId` you sent the document with, so the outcome stays readable even if your client discards the returned location, and a webhook on Processed Documents pushes it to you instead.

A rejected call changes nothing. The staged document stays where it was, `errorMessage` describes the problem, and the call can be corrected and retried.

Every step a staged document takes is also published on the [Document events](https://eonesolutions.github.io/eone-bc-integration/core-documentEvents.md) feed: `stagedDocumentPendingApproval`, `Approved`, `AwaitingInvoice`, `AwaitingLines`, `Drafted` and `Posted`, plus `stagedDocumentErrored` with the error text on the event itself. Subscribe there and SmartConnect reacts to the step directly, instead of polling documents for a status change.

## Processing is configurable

How a staged document reaches the ledger is set per environment on the eOne Integration Setup page:

- **Manual** (call `process` or `post`, or use the in-product page)
- **Auto Draft to Journal** (a background job builds the draft lines)
- **Auto Post** (the job builds and posts them).

An optional approval gate works the same across every endpoint: set **Requires Approval** for the endpoint and enable a Business Central approval workflow, and a licensed user approves the document in the client before it processes. The API cannot approve (the read-only `status` / `errorMessage` fields report where the document is). See [Operating staged documents](https://eonesolutions.github.io/eone-bc-integration/operating-staged-documents.md) for the approval workflow and [Customer Payments](https://eonesolutions.github.io/eone-bc-integration/core-customerPayments.md) for the fully worked example.
