Scenario: Post a vendor prepayment invoice for a purchase order
Goal. A vendor asks for part of an order's price up front, a deposit or advance, and sends a prepayment invoice for it. Your procurement or invoice-capture system posts that invoice against the purchase order from outside D365, as the order's Prepayment and Invoice > Prepayment invoice actions do: the order gets its prepayment (a percentage of the order total or a fixed amount), and the prepayment is posted as a vendor invoice of type prepayment under the vendor's invoice number. The prepayment can then be paid, and later applied to the order's final invoice.
When to use. Purchase orders with prepayment terms, before the goods arrive and before the order's first invoice. To pay a vendor in advance without a prepayment invoice, record the payment as a prepayment line marked against the order (Pay vendors, Part C). The order's regular receipt and invoice follow Receive and invoice a purchase order.
Prerequisites
- Security.
MGCLatticeAccountsPayableServiceMaintain, which also grants the order's confirmation, receipt and invoice, grantspostPurchasePrepaymentInvoiceand its batch variant. It is in dutyMGCLatticeIntegrationServiceOperationsDuty(integration operator and administrator roles). The read-back entityVendInvoiceJourBiEntitiesis a standard entity and needs D365's own privileges. See Security model. - D365 configuration in the legal entity:
- a Purchase prepayment account in the inventory posting (Inventory management > Setup > Posting > Posting, Purchase order tab). USMF has one rule for all items and vendors;
- posting definitions turned off in the general ledger parameters: prepayments are not available with them;
- a procurement category for the prepayment that is not the category of any line of the order (USMF
Training, in hierarchy "Procurement - Office Supplies"); - the vendor (USMF
US-101) not on hold for invoicing.
- The purchase order. An order of type Purchase order (USMF
00001042: 10 xD0001at 50.00 USD) that is not in review or finalized, is not intercompany, and has no posted invoice yet. - Lattice. A valid license (an expired or invalid one refuses the call with
LicenseNotValid). To name the order by your own key, sendPurchaseOrderIdExternalKeywithExternalSystem(Use your own keys).
Steps
The operation is postPurchasePrepaymentInvoice on MGCLatticePurchaseOrderPostingService in service group
MGCLatticeAccountsPayableServiceGroup. Send a POST with an OAuth 2.0 bearer token and the request in
_request (see Trial and day-one guide).
-
Post the prepayment invoice. Name the order, the vendor's invoice number, the prepayment and its category:
POST https://<your-environment>/api/services/MGCLatticeAccountsPayableServiceGroup/MGCLatticePurchaseOrderPostingService/postPurchasePrepaymentInvoice{"_request": {"RequestId": "c2f8a4d6-1e3b-4a7c-9d05-6b8e2f4a1c39","LegalEntityId": "USMF","UserContext": "Admin","PurchaseOrderId": "00001042","VendorInvoiceNumber": "PP-0001","PrepaymentPercent": 10,"PrepaymentCategoryName": "Training","PostingDate": "2026-10-08"}}- The prepayment. Send
PrepaymentPercent(greater than 0, at most 100, of the order total) orPrepaymentAmount(a fixed amount in the order currency, at most the order total), not both.PrepaymentDescriptionis optional. When the category name exists in several procurement category hierarchies, addPrepaymentCategoryHierarchyName. - An order that already has a prepayment (set up on the order in D365, for example) is invoiced for it: leave the prepayment members out, or send the same values. A different percentage, amount or category is refused; change the prepayment on the order in D365.
- The invoice.
VendorInvoiceNumberis required and becomes the posted invoice number, with the usual duplicate checks.InvoiceDatedefaults as on a vendor invoice;PostingDatedefaults to today.
The prepayment and its invoice are created and posted in one transaction: a failed posting leaves neither behind.
- The prepayment. Send
-
Read the result.
DocumentIdis the purchase order andPostedDocumentIdthe voucher of the posted prepayment invoice. The message names the invoice, amount and voucher, for examplePrepayment invoice PP-0001 of 50.00 USD was posted for purchase order 00001042 on voucher APINV000213.The whole prepayment still available to invoice is invoiced, so a second call for the same order is refused. -
Pay the prepayment like any other vendor invoice, for example with Pay vendors.
-
Receive the goods and apply the prepayment to the final invoice. Post the product receipt as usual (Receive and invoice a purchase order). To have the prepayment reduce the order's final invoice, enter that invoice as a pending vendor invoice in D365, use Apply prepayment on it, and post it (Post a pending vendor invoice).
The bulk variant postPurchasePrepaymentInvoiceBatch takes { "_requests": [ ... ] } and answers one result
per item. The operation is synchronous only and has no preview.
How to verify
- The response:
Successtrue,Status3,DocumentIdthe order,PostedDocumentIdthe voucher. - The invoice:
VendInvoiceJourBiEntitieslists it as a prepayment invoice, for exampleGET https://<your-environment>/data/VendInvoiceJourBiEntities?cross-company=true&$filter=dataAreaId eq 'usmf' and PurchId eq '00001042' and InvoiceId eq 'PP-0001'&$select=InvoiceType,LedgerVoucher,InvoiceAmountreturnsInvoiceTypeVendorAdvanceand the returned voucher inLedgerVoucher. - The vendor:
LatticeVendorTransactions(filter onVendorAccountNumberandInvoiceId eq 'PP-0001') shows the open prepayment invoice. - In D365: open the order (Procurement and sourcing > Purchase orders > All purchase orders); Purchase > Prepayment shows the prepayment with nothing left available to invoice. The invoice journal (Accounts payable > Inquiries and reports > Invoices > Invoice journal) shows the invoice as a prepayment invoice on the returned voucher.
- The call: System administration > Inquiries > Lattice > Services > Service call log, or
LatticeServiceCallLogsfiltered on yourRequestId.
When it goes wrong
A failed call answers Success false, Status 4, an ErrorCode and the message "Prepayment invoice posting
failed due to validation or business rule constraints."; the reasons are in Errors. Nothing is created.
| ErrorCode | Typical cause (text in Errors) | What to do |
|---|---|---|
ValidationFailed (1) | No VendorInvoiceNumber; "Send either PrepaymentPercent or PrepaymentAmount, not both."; "Purchase order ... has no prepayment yet: send PrepaymentPercent or PrepaymentAmount." (or PrepaymentCategoryName); a value not greater than zero or a percentage above 100; a fixed amount above the order total; an unknown category, or one that exists in several hierarchies ("... send PrepaymentCategoryHierarchyName."); a category used on the order's lines; "Purchase order ... already has a prepayment (...). Send the same prepayment or none to invoice it; change it on the purchase order in D365." | Correct the request and resend. |
DocumentNotFound (2) | Unknown purchase order | Check the order number and LegalEntityId. |
InvalidStatus (3) | The order is not of type Purchase order, is in review or finalized, is intercompany, "already has a posted invoice", "has a pending prepayment invoice ...", "has no prepayment left to invoice", or its vendor is on hold for invoicing | A prepayment invoice is possible only before the order's first invoice. Post or delete a pending prepayment invoice in D365 first. |
ConfigurationMissing (11) | "Purchase order prepayments are not available in legal entity ... because posting definitions are enabled in the general ledger parameters." | Prepayments need posting definitions turned off. |
BusinessRule (4) | D365 refused the posting, for example a vendor invoice number already used or no Purchase prepayment account (its messages in Errors) | Fix the cause, then resend. |
PreviewUnsupported (10) | PreviewMode true | Send without PreviewMode. Nothing was run. |
TransientRuntime (6) | A runtime fault; IsRetryable true | Resend with the same RequestId. |
LicenseNotValid (12) | The Lattice license is expired or invalid | Renew the license, then resend. |
Retries are safe. Resending a successful request with the same RequestId posts nothing again: the answer
repeats the original voucher with the message Duplicate request detected. Original request processed at ....
Reference
- API reference: section 2 (Purchase Order Posting Service) and section 19 (Bulk Operations)
- Endpoint payload specification:
MGCLatticePurchaseOrderPostingService - Security model
- Cross-reference keys:
PurchaseOrderIdExternalKey - Receive and invoice a purchase order, Pay vendors