Vendor check issued
Fires when a check (cheque) payment is issued to a vendor. The moment a vendor cheque record moves into Payment status from a status in which it had not been issued yet, and the cheque recipient is a vendor, the event publishes the cheque details (bank account, number, amount, currency, payee, voucher and transaction date), enabling downstream payment reconciliation, positive-pay file generation, or vendor notification workflows.
| Event class | MGCLatticeVendorCheckIssuedBusinessEvent |
| Contract class | MGCLatticeVendorCheckIssuedBusinessEventContract |
| Category | Accounts payable |
| Module | ModuleAxapta::Vendor |
| Label IDs | VendorCheckIssuedBusinessEventName / VendorCheckIssuedBusinessEventDescription |
| Trigger | BankChequeTable.update() -> orig().ChequeStatus is Created, NotPrinted or Testprint && this.ChequeStatus == Payment && this.RecipientType == BankChequeRecipientType::Vend |
Trigger / Hook
- Extension class:
MGCLatticeBankChequeTable_Table_Extension,[ExtensionOf(tableStr(BankChequeTable))] - Chain of Command method signature:
public void update()(no parameters) - Firing condition (decided by
MGCLatticeVendorCheckIssuedBusinessEvent::isCheckIssue):- Captures
orig().ChequeStatusbefore callingnext update(). - Fires only when a cheque is issued: the new status is
ChequeStatus::Paymentand the original status is one in which the cheque had not been issued yet,Created,NotPrintedorTestprint. Later updates of a cheque that is already in Payment status do not fire again. - Recipient filter:
this.RecipientType == BankChequeRecipientType::Vend, so only vendor cheques fire this event (customer, bank, ledger and unknown recipients are excluded).
- Captures
- When it happens in the standard flow: a vendor cheque moves to Payment status when the check is generated from a vendor payment journal (Generate payments with a check method of payment), through
BankChequeTable::setChequeStatus, which sets the status together with the payee, amount, voucher and date in the same update. Check generation happens before the payment journal is posted, so the event can arrive before the payment is posted, andvoucherandtransDatecome from the payment journal line. A replacement check issued for a canceled one (France) is issued the same way and raises the event for the new check number. - Returning to Payment is not an issue: when a bank check reversal journal is created, the cheque goes to
CancelPending; if an unposted line of that journal is deleted, D365 writes the cheque back fromCancelPendingtoPayment. That transition does not raise the event, and neither does a return to Payment fromCancelled,RejectedorVoid. - Reused check numbers: when a generated payment is rejected and its check number is reused, D365 voids the first issue and sets the number back to
Created; generating the payment again is a new issue of that number and raises the event again. TreatlegalEntity+bankAccountId+checkNumber+voucheras the key of one issue. - Timing: the event is sent inside the transaction that updates the cheque.
send()writes it to the business events commit log in that transaction and it is delivered after commit, so a check run that rolls back never delivers the event. - Updates that bypass the table's
update()method (doUpdate(), or set-based updates with data methods skipped) do not raise it. - Enablement gate: wrapped in
BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeVendorCheckIssuedBusinessEvent))so the event is sent only when activated against an endpoint.
public void update()
{
ChequeStatus origStatus = this.orig().ChequeStatus;
next update();
if (MGCLatticeVendorCheckIssuedBusinessEvent::isCheckIssue(origStatus, this.ChequeStatus, this.RecipientType))
{
if (BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeVendorCheckIssuedBusinessEvent)))
{
MGCLatticeVendorCheckIssuedBusinessEvent::newFromBankChequeTable(this).send();
}
}
}
public static boolean isCheckIssue(ChequeStatus _previousStatus, ChequeStatus _newStatus, BankChequeRecipientType _recipientType)
{
if (_newStatus != ChequeStatus::Payment || _recipientType != BankChequeRecipientType::Vend)
{
return false;
}
switch (_previousStatus)
{
case ChequeStatus::Created:
case ChequeStatus::NotPrinted:
case ChequeStatus::Testprint:
return true;
}
return false;
}
Payload Contract
One row per [DataMember], in declaration order (sourced from MGCLatticeVendorCheckIssuedBusinessEventContract.initialize(BankChequeTable)):
| JSON field | Display label | Type / EDT | Source | Notes |
|---|---|---|---|---|
legalEntity | Legal Entity | DataAreaId | _bankChequeTable.DataAreaId | Company ID of the cheque record, in lower case (for example usmf) |
bankAccountId | Bank Account ID | CompanyBankAccountId | _bankChequeTable.AccountID | The bank account the cheque draws on |
checkNumber | Check Number | BankChequeNum | _bankChequeTable.ChequeNum | Cheque/check number. The field is right-aligned and stored left-padded with spaces (20 characters), so the value can arrive with leading spaces; trim before matching |
amount | Amount | AmountCur | _bankChequeTable.AmountCur | Cheque amount in transaction currency |
currencyCode | Currency Code | CurrencyCode | _bankChequeTable.CurrencyCode | Transaction currency code |
recipientName | Recipient Name | BankNegInstRecipientName | _bankChequeTable.BankNegInstRecipientName | Payee name recorded on the cheque; may be empty |
vendorAccount | Vendor Account | CustVendAC | _bankChequeTable.RecipientAccountNum | Vendor account number of the payee |
transDate | Transaction Date | TransDate | _bankChequeTable.TransDate | Cheque transaction date; "\/Date(ms)\/" form |
voucher | Voucher | Voucher | _bankChequeTable.Voucher | Voucher of the payment journal line |
Every Lattice event also carries the Lattice ordering and correlation envelope, inherited from MGCLatticeBusinessEventContractBase: eventSequence (Int64 - increasing across the whole catalog and all companies, allocated when the event is raised; it orders the events of one record, gaps are normal and permanent, see the README), correlationId (String - always Scope:Key; groups emissions that belong to one logical run and defaults to Event: plus a GUID unique to this emission) and schemaVersion (Int - the payload shape version; 1 for this contract). D365 F&O also adds its standard envelope fields to every business event payload: BusinessEventId, BusinessEventLegalEntity, ContextRecordSubject, ControlNumber, EventId, EventTime, EventTimeIso8601, InitiatingUserAADObjectId, MajorVersion, MinorVersion, and ParentContextRecordSubjects. Do not rely on the order of members in the delivered JSON.
This event does not join a run: correlationId is unique to each emission.
Example Payload
{
"BusinessEventId": "MGCLatticeVendorCheckIssuedBusinessEvent",
"ControlNumber": 5012846,
"EventId": "1B2C3D4E-5F60-7A8B-9C0D-1E2F3A4B5C6D",
"EventTime": "\/Date(1790251658000)\/",
"EventTimeIso8601": "2026-09-24T12:07:38.6039383Z",
"MajorVersion": 0,
"MinorVersion": 0,
"BusinessEventLegalEntity": "USMF",
"ContextRecordSubject": "",
"InitiatingUserAADObjectId": "{AAFBB770-F9F1-69C3-6770-2D0DCF834376}",
"ParentContextRecordSubjects": [],
"eventSequence": 48451,
"correlationId": "Event:c83e1a7f-0b5d-4e29-a6f4-3d7b9e0c2f15",
"schemaVersion": 1,
"legalEntity": "usmf",
"bankAccountId": "USMF OPER",
"checkNumber": " 792",
"amount": 2117.85,
"currencyCode": "USD",
"recipientName": "Acme Office Supplies",
"vendorAccount": "1001",
"transDate": "\/Date(1790208000000)\/",
"voucher": "APPM001247"
}
Activation
In the D365FO client, go to System administration > Setup > Business events > Business events catalog. Find this event by name ("Vendor check issued") or by filtering the Category column to Accounts payable, select the event, and use Activate to bind it to an endpoint (event grid, Azure Service Bus, Power Automate, etc.). Once activated, the event sends every time a vendor cheque is issued.