Skip to main content

Customer credit limit exceeded

Fires when D365's standard credit limit check finds that a customer's exposure - the open balance counted by the Credit limit type parameter plus the amount of the document being checked - is greater than the credit limit in effect. The check runs wherever D365 validates credit (sales orders, sales order posting, free text invoices, and Credit management), so a credit or collections team can react in real time: alert the account manager, open a collections case, or hold fulfillment in an external system. It complements Customer hold status changed, which fires only when the customer's Blocked status changes.

Event classMGCLatticeCustomerCreditLimitExceededBusinessEvent
Contract classMGCLatticeCustomerCreditLimitExceededBusinessEventContract
CategoryAccounts receivable
ModuleModuleAxapta::Customer
Label IDsCustomerCreditLimitExceededBusinessEventName / CustomerCreditLimitExceededBusinessEventDescription
TriggerCustCreditLimit.check() -> when the check returns false (credit limit exceeded)

Trigger / Hook​

  • Extension class: MGCLatticeCustCreditLimit_Class_Extension, [ExtensionOf(classStr(CustCreditLimit))].
  • CoC method signature: public boolean check().
  • Firing condition: after next check(), the event is sent when the check returns false. The standard check only evaluates credit when Credit limit type (Accounts receivable parameters) is not None and the customer has a non-zero credit limit, or when the customer has Mandatory credit limit set; it then returns false when balance + order balance is greater than the credit limit and the order balance is greater than zero. (For a Russian agreement credit line the comparison uses the agreement's limit.) The check returns false whichever Message when exceeding credit limit option (warning or error) is configured, so the event fires in both modes.
  • Coverage: no D365 subclass overrides check(), so the wrapper runs for every credit limit check class - CustCreditLimit (customer level), CustCreditLimit_SalesTable (sales order), CustCreditLimit_SalesParmTable (sales order update/posting), CustCreditLimit_CustInvoiceTable (free text invoice) and the Credit management variants (CredManCustCreditLimit, CredManCustCreditLimit_SalesTable, CredManCustCreditLimit_SalesParmTable). The class that ran is reported in triggeringContext.
  • Repeats: the event is not edge-triggered. Every check that finds the customer over the limit sends a new event, so the same document can raise it more than once (for example at different stages of one sales order). Treat it as "exposure is over the limit right now" and de-duplicate on your side.
  • Timing: send() joins whatever database transaction the caller has open. If that transaction is rolled back, the event is rolled back with it and never delivered; if the check runs outside a transaction, the event is delivered even if the user then abandons the document.
  • Enablement gate: BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeCustomerCreditLimitExceededBusinessEvent)) is evaluated together with the check result.
public boolean check()
{
boolean ret = next check();

if (!ret && BusinessEventsConfigurationReader::isBusinessEventEnabled(classStr(MGCLatticeCustomerCreditLimitExceededBusinessEvent)))
{
MGCLatticeCustomerCreditLimitExceededBusinessEvent::newFromCustCreditLimit(this).send();
}

return ret;
}

Payload Contract​

One row per [DataMember], in declaration order. initialize() reads the customer from CustCreditLimit.custTable() and the balances from CustCreditLimit.balance(), which returns the [balance, orderBalance] pair the check compares. The credit limit is taken from the same check instance. Every amount is in the legal entity's accounting currency, reported in accountingCurrencyCode.

JSON fieldDisplay labelType / EDTSourceNotes
legalEntityLegal EntityDataAreaIdCustTable.DataAreaIdCompany of the customer being checked, in lower case (for example usmf).
customerAccountCustomer AccountCustAccountCustTable.AccountNumCustomer account number.
customerNameCustomer NamestrCustTable.name()Party name resolved by the display method when the contract is built.
creditLimitMSTCredit Limit MSTAmountMSTCustCreditLimit.latticeEffectiveCreditLimit()The limit the check compared with: the agreement credit limit when an agreement credit line applies, otherwise CustCreditLimit.getCurrentCreditMax(), which is the Credit management credit limit when credit management parameters are enabled and CustTable.CreditMax otherwise. In accounting currency.
accountingCurrencyCodeAccounting Currency CodeCurrencyCodeLedger::accountingCurrency() of the customer's legal entityThe currency of creditLimitMST, balanceMST, orderBalanceMST and totalExposureMST. The customer's own transaction currency plays no part in the check.
balanceMSTBalance MSTAmountMSTfirst element of CustCreditLimit.balance()The customer's existing balance counted by the check, in accounting currency. What it includes depends on Credit limit type: Balance, Balance + packing slip or product receipt, or Balance+All.
orderBalanceMSTOrder Balance MSTAmountMSTsecond element of CustCreditLimit.balance()The amount of the document being checked (plus any amount the caller added), in accounting currency.
totalExposureMSTTotal Exposure MSTAmountMSTbalanceMST + orderBalanceMSTThe exposure that exceeded the limit.
triggeringContextTriggering ContextstrclassId2Name(classIdGet(CustCreditLimit))Name of the credit limit check class that ran, for example CustCreditLimit_SalesTable or CustCreditLimit_CustInvoiceTable (see Trigger / Hook).

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 inside the business transaction, not when it commits; it orders the events of one business record, gaps are permanent and normal, and it must not be used to re-sequence the whole stream), correlationId (String, always Scope:Key - groups emissions that belong to one logical run; an event that joins no run carries Event: followed by a lower-case 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.

Example Payload​

{
"BusinessEventId": "MGCLatticeCustomerCreditLimitExceededBusinessEvent",
"ControlNumber": 5637148655,
"EventId": "9C2E47B1-0F63-4A8D-B25E-7D14C9A06F38",
"EventTime": "\/Date(1790256004000)\/",
"EventTimeIso8601": "2026-09-24T13:20:04.5796083Z",
"MajorVersion": 0,
"MinorVersion": 0,
"BusinessEventLegalEntity": "USMF",
"ContextRecordSubject": "",
"InitiatingUserAADObjectId": "{EB743BFD-612B-2E20-885C-DBB321B2409F}",
"ParentContextRecordSubjects": [],
"eventSequence": 48266,
"correlationId": "Event:5e8b1d24-7c3f-4a90-8b6e-0f2d9c1a7e53",
"schemaVersion": 1,
"legalEntity": "usmf",
"customerAccount": "US-003",
"customerName": "Forest Wholesales",
"creditLimitMST": 50000.00,
"accountingCurrencyCode": "USD",
"balanceMST": 46250.00,
"orderBalanceMST": 8400.00,
"totalExposureMST": 54650.00,
"triggeringContext": "CustCreditLimit_SalesTable"
}

Activation​

In the D365FO client, go to System administration > Setup > Business events > Business events catalog. Find this event by name ("Customer credit limit exceeded") or by filtering the Category column to Accounts receivable. Select it and use Activate to bind it to a configured endpoint (for example, an Azure Service Bus queue, Event Grid topic, or HTTPS webhook). The event can only fire where D365 actually runs credit limit checks: set Credit limit type in Accounts receivable parameters to a value other than None and give customers a credit limit, or set Mandatory credit limit on the customer.