From Trading Partner cXML to Infor LN Sales Order: How a European Life-Sciences Manufacturer Automated EDI Order Intake with Azure Integration Services

Summary

A global life-sciences and laboratory equipment supplier sends purchase orders to our customer (BÜCHI’s customer-centric vision accelerates innovation using Azure Integration Services | Microsoft) as machine-generated cXML OrderRequest.xml documents. The customer runs Infor LN, which expects a SalesOrder BOD delivered through the Infor ION I/O Box. Between the two sat a translation problem that was being solved by hand.

Every order arriving from the trading partner had to be read, interpreted and re-keyed into Infor LN by the order desk. That worked at low volume. It did not scale, it delayed order confirmation by hours, and it introduced transcription errors on the fields that matter most — quantities, delivery dates and ship-to addresses.

We closed that gap with Azure Integration Services: API Management as the secure front door, Blob Storage as the immutable archive, Service Bus for asynchronous decoupling and retries, Azure Functions in C# for the cXML-to-BOD translation, and a write into the Infor ION I/O Box SQL database from which ION creates the sales order in LN. Key Vault and App Configuration hold secrets and environment-specific values; Application Insights makes every transaction traceable end to end.

The result is a straight-through process: Partner posts cXML → Archive → Queue → Transform to BOD → I/O Box → Infor ION → Sales Order in LN.

This article covers how the interface was designed, how the mapping and its business rules were kept maintainable, how failures are handled and replayed, and the guardrails that keep an asynchronous EDI interface trustworthy in production.

This Blog Explains

  1. Why manual order entry from EDI purchase orders stops scaling, and what it costs.
  2. How a partner cXML OrderRequest is received, archived and queued on Azure.
  3. How the cXML document is translated into an Infor Process.SalesOrder BOD.
  4. How conditional business rules — partner cross-references, note construction, ship-date fallbacks — are kept out of hard-coded logic.
  5. How multi-line orders are looped into SalesOrderPosition blocks.
  6. How the BOD is handed to Infor LN through the ION I/O Box.
  7. How failures are retried, dead-lettered and replayed without asking the partner to resend.
  8. How a single transaction ID makes the whole interface searchable in Application Insights.

From Manual Order Entry to Automated Order Intake

For manufacturers that sell through large, process-driven customers, the order does not arrive as a phone call or an email attachment. It arrives as a machine-generated EDI document, posted to an endpoint at any hour of the day, in a format defined entirely by the buyer.

Our customer — a European division of a global life-sciences and laboratory equipment supplier — runs Infor LN as its ERP. Their key trading partner sends purchase orders as cXML OrderRequest.xml documents. Infor LN, on the other side, expects a Process.SalesOrder BOD delivered through the Infor ION I/O Box.

Both systems were working exactly as designed. The problem lived in the space between them, and that space was being crossed by a person with a keyboard.

A purchase order that arrives electronically and is then typed in by hand is not an integrated process. It is a manual process with an electronic first step.

The objective of the project was therefore narrow and concrete: when the trading partner posts an order, a sales order should appear in Infor LN — correctly mapped, without human intervention, and with enough visibility that the support team can prove it happened.

The Business Challenge

On the surface this looks like a file conversion. In practice, five things made it anything but.

1. Two Schemas That Share Almost No Vocabulary

cXML is a flat, attribute-heavy commerce format. The Infor BOD is a deeply nested OAGIS structure with an ApplicationArea envelope, a DataArea payload and a UserArea carrying LN-specific properties. Almost every field required transformation rather than a straight copy.

2. Business Logic Hidden Inside the Mapping

The partner’s identity codes had to be cross-referenced to Infor LN business partner IDs — with different values in Test and Production. Header comments needed a hardcoded Remark: prefix. Goods marks, customer references and order numbers had to be concatenated into a single footer note, skipping the values that did not arrive so no blank lines were left behind.

3. A Ship Date With a Rule of Its Own

Requested ship date could not simply be copied. If the line carries a date, use it. If it is missing, or in the past, use the current date. If the order has multiple lines with different dates, take the earliest. A rule that reads as one sentence in a specification becomes a decision tree in code.

4. Line-Level Repetition

A single order can contain many ItemOut elements, each of which becomes a SalesOrderPosition block in the BOD, carrying its own item ID, quantity, required delivery date and note.

5. No Second Chances, and No Visibility

The exchange is asynchronous and real-time. If a message failed silently, the first sign of trouble would be the customer asking why their order had not shipped. Operations needed to answer “what happened to this order?” without raising a support ticket.

Manual re-keying was the fallback, and it carried exactly the costs you would expect: order entry delays measured in hours, transcription errors on quantities and delivery dates, and a team doing work that added no value.

Solution Overview

We built the interface on Azure Integration Services as a set of small, independently deployable components rather than one monolithic job.

The solution uses:

  1. Azure API Management
  2. Azure Blob Storage
  3. Azure Service Bus
  4. Azure Functions (C#)
  5. Infor ION I/O Box (SQL)
  6. Azure Key Vault and App Configuration
  7. Application Insights

The high-level process is:

Trading Partner (cXML OrderRequest.xml)
            |
            v
     Azure API Management
            |
            +--> Azure Blob Storage (raw payload archive)
            |
            v
     Azure Service Bus
            |
            v
  Azure Function - cXML to BOD translation
            |
            v
     Infor ION I/O Box (SQL)
            |
            v
        Infor ION
            |
            v
   Sales Order created in Infor LN

End-to-end message flow, from partner endpoint to Infor LN sales order.

The exchange runs in real time and asynchronously. The partner is acknowledged immediately; Infor LN is never in the request path.

Functional Integration Approach

The design was deliberately centred on the document, not on the systems. The cXML order is the unit of work; everything downstream — archive, queue message, telemetry, dead letter — is keyed by a single transaction ID minted the moment that document arrives. That one decision is what later made the interface supportable.

Receiving the Purchase Order: Azure API Management

The trading partner posts the cXML document to a dedicated endpoint exposed through Azure API Management. APIM handles authentication, IP restrictions, throttling and payload size limits, and returns an immediate acknowledgement so the sender is never held open while downstream processing runs.

The raw payload is then archived to Azure Blob Storage exactly as received, before a single transformation touches it.

POST https://<apim-host>/edi/v1/orderrequest
Ocp-Apim-Subscription-Key: <key>
Content-Type: application/xml

<cXML payloadID="20260825T0930-4471@partner.com" timestamp="...">
  <Header>
    <From><Credential domain="NetworkID">
      <Identity>TMO_11</Identity>
    </Credential></From>
  </Header>
  <Request>
    <OrderRequest>
      <OrderRequestHeader orderID="4500123456" ...>
      <ItemOut quantity="12" requestedDeliveryDate="2026-09-04" ...>
    </OrderRequest>
  </Request>
</cXML>

Inbound cXML purchase order, abbreviated.

Archive first, transform second. An immutable copy of what the partner actually sent is worth more during an incident than any amount of logging around the code that failed.

Decoupling the Interface: Azure Service Bus

The archived message is published to an Azure Service Bus topic. This is the point where the interface stops being synchronous.

  1. The partner is decoupled from Infor LN’s availability. An LN maintenance window delays orders; it does not reject them.
  2. Ordering is preserved where it matters, using sessions keyed by partner.
  3. Retry and dead-lettering come from the platform rather than from custom code.
  4. Volume spikes are absorbed by the queue instead of by the downstream system.

Translating cXML into the Infor Process.SalesOrder BOD

An Azure Function written in C# performs the translation. It parses the cXML, applies the mapping and the business rules, and emits a Process.SalesOrder BOD.

The target structure is conceptually:

ProcessSalesOrder
├── ApplicationArea
│   ├── Sender/LogicalID        (lid://infor.eil.ais)
│   ├── Sender/ConfirmationCode (OnError)
│   ├── CreationDateTime
│   └── BODID                   (infor.eil.ais_{payloadID})
└── DataArea
    └── SalesOrder
        └── SalesOrderHeader
            ├── CustomerParty / ShipToParty / BillToParty
            ├── AlternateDocumentID, DocumentDateTime
            ├── Note (Header / Footer)
            ├── RequestedShipDateTime
            ├── TransportationTerm/IncotermsCode
            └── UserArea
                ├── Property (ln.OrderType, ln.OrderSeries, ...)
                └── SalesOrderPosition  [repeats per ItemOut]

Target Process.SalesOrder BOD structure.

A representative slice of the mapping:

Source (cXML)Target (Process.SalesOrder BOD)Rule
/cXML/@payloadIDApplicationArea/BODIDPrefixed with the logical ID
Header/From/Credential/IdentitySalesOrderHeader/CustomerParty/PartyIDs/IDCross-referenced to the LN business partner
OrderRequestHeader/@orderIDSalesOrderHeader/AlternateDocumentID/IDDirect
OrderRequestHeader/CommentsSalesOrderHeader/Note[@type=Header]Prefixed with “Remark:”
Extrinsic GoodsMark / CustomerReference / CustomerOrderNumberSalesOrderHeader/Note[@type=Footer]Concatenated, one per line, empty values skipped
ItemOut/@requestedDeliveryDateSalesOrderHeader/RequestedShipDateTimeEarliest valid line date, else current date
ItemOut/ItemID/SupplierPartIDSalesOrderPosition/Item/ItemID/IDDirect, per line
ItemOut/@quantitySalesOrderPosition/QuantityDirect, per line

The Business Rules Hidden Inside the Mapping

The temptation with a mapping this dense is to bury it in code. We deliberately did not.

The straightforward field-to-field moves — item ID, quantity, addresses, postal codes, country codes — are declarative. The conditional rules live in named, unit-tested methods, so the method name reads like the specification it came from rather than a nest of if statements.

// The specification, expressed once, tested once.
public DateTime ResolveRequestedShipDate(IEnumerable<OrderLine> lines,
                                         DateTime today)
{
    var candidates = lines
        .Select(l => l.RequestedDeliveryDate)
        .Where(d => d.HasValue && d.Value.Date >= today.Date)
        .Select(d => d!.Value.Date)
        .ToList();

    // No usable line date, or every date is in the past.
    return candidates.Count == 0 ? today.Date : candidates.Min();
}

One business rule, one method, one name that matches the specification.

The environment-sensitive values — the partner identity cross-reference, the LN order type and order series defaults — come from Azure App Configuration. Secrets and connection strings come from Azure Key Vault, accessed through managed identity so nothing is stored in the Function’s settings.

The partner IDs that differ between Test and Production are configuration, not constants. That single separation is what let the same build move between environments without a code change.

The payoff shows up the first time the customer adds a trading partner or changes an address rule. That is a configuration change and a test, not a release.

Writing to the Infor ION I/O Box

A second Function writes the generated BOD into the Infor ION I/O Box SQL database, which is the supported handoff point into the Infor stack. Infor ION then picks the document up and creates the sales order in Infor LN. From that moment the order is a first-class LN document and follows the standard fulfilment process.

Two details matter here. The write is idempotent — the BODID derived from the partner’s payload ID is used to detect a document that has already been inserted, so a Service Bus redelivery cannot create a duplicate sales order. And the insert is the only point in the interface that touches a database directly, which keeps the Infor-specific surface area small and easy to change.

Handling Exceptions, Retries and Replay

This is the part of an EDI interface that determines whether people trust it, and it is worth over-investing in.

Failures Are Loud, Not Silent

When the processing service cannot complete a message — a malformed payload, an unreachable I/O Box, a mapping rule with no valid input — it throws rather than swallowing the exception. Service Bus retries with exponential backoff, and a message that exhausts its retries lands in the dead-letter queue with the failure reason attached. Nothing disappears.

Replay Is a First-Class Operation

Because the original cXML sits untouched in Blob Storage, reprocessing a failed order after a fix means re-publishing the archived message. There is no request to the trading partner to resend, and no manual reconstruction of what the document contained.

Message processing
        |
        v
   Success? ----- yes ----> Written to I/O Box, telemetry: Completed
        |
        no
        |
        v
  Service Bus retry (exponential backoff)
        |
   retries exhausted
        |
        v
  Dead-letter queue + Application Insights alert
        |
        v
  Fix, then replay archived payload from Blob Storage

Failure path: retry, dead-letter, alert, replay.

Technical Architecture

At a technical level the solution is a small set of Azure resources, each doing one job.

ComponentRole in the interface
Azure API ManagementSecure, throttled entry point for partner cXML; immediate acknowledgement
Azure Blob StorageImmutable archive of the original payload for replay and audit
Azure Service BusAsynchronous decoupling, ordered delivery, retries, dead-lettering
Azure Functions (C#)cXML parsing, business rules, BOD generation, idempotent I/O Box write
Infor ION I/O Box (SQL)Supported handoff into Infor LN via ION
Azure Key VaultConnection strings and credentials, accessed by managed identity
Azure App ConfigurationEnvironment-specific settings and cross-reference values
Application InsightsCorrelated telemetry, transaction search, alerting

The same platform pattern already backs other back-office integrations for the group, including SAP Business One through its Service Layer, so the Infor LN adapter slotted into an architecture the team had already proven rather than starting from zero.

Monitoring with Application Insights

Telemetry is written at every stage of the pipeline — received, archived, queued, transformed, written to I/O Box — and every entry carries the same transaction ID that was minted when the payload first hit APIM.

That means support can search one ID and see the full lifecycle of an order, including the exact stage a failure occurred at and the payload that caused it.

traces
| where customDimensions.TransactionId == "<transaction-id>"
| project timestamp, message, customDimensions.Stage,
          customDimensions.OrderId
| order by timestamp asc

One query answers “where is this order?”

Alerts on dead-letter queue depth and on failure counts in Application Insights mean the team hears about a problem before the customer does. Validation runs from both ends: the telemetry trail confirms each translation step completed, and the order itself is verified in Infor LN.

Designing the Integration Around Business Events

One of the lessons worth carrying out of this implementation is that integration design should start with the business document, not with the API surface.

The partner’s cXML contains many fields. Infor LN cares about a subset of them, arranged differently, with defaults and cross-references applied. The integration layer is responsible for that translation:

Partner document (cXML)
        |
        v
Business interpretation (rules, cross-references, defaults)
        |
        v
ERP document (Process.SalesOrder BOD -> Infor LN Sales Order)

An interface that copies fields is a converter. An interface that applies the business’s rules to those fields is an integration. Only the second one removes work from people.

Business Impact

1. Orders Reach Infor LN in Near Real Time

What used to wait for someone to open a file now lands as an LN sales order within seconds of the partner posting it.

2. Manual Re-Keying Is Eliminated

And with it the transcription errors on quantities, delivery dates and ship-to addresses that were the most common cause of order rework.

3. Order Intake Scales Without Headcount

Volume peaks are absorbed by the queue rather than by the order desk. A busy week no longer means overtime.

4. Consistent Interpretation of Every Order

The ship-date rule, the note construction and the partner cross-reference are implemented once and applied identically to every document, instead of being interpreted differently by different people.

5. Every Transaction Is Traceable

A single ID answers “where is this order?” in seconds, and failures are recoverable by replay rather than by re-entry.

6. A Reusable Foundation

Order acknowledgements, shipment notices and invoices can follow the same route without new infrastructure. The expensive part — the secure front door, the queue, the telemetry model, the deployment pipeline — is already built.

Design Constraints and Guardrails

An asynchronous EDI interface should not be designed as though every downstream system is always available and every payload is well formed. A few guardrails carry most of the weight:

  1. Idempotency by BODID. A redelivered message can never create a second sales order.
  2. Archive before transform. The original payload is stored before any logic runs, so replay is always possible.
  3. Bounded retries. Messages retry with backoff and then dead-letter, rather than looping indefinitely against a system that is down.
  4. Secrets outside code. Key Vault and managed identity, with no credentials in application settings or source control.
  5. Environment parity. The only difference between Test and Production is configuration, which removes an entire class of deployment defect.
  6. Alert on the queue, not just the logs. Dead-letter depth is the earliest reliable signal that something needs a human.

Final Thoughts

EDI-to-ERP integration is rarely hard because of the file format. It is hard because the business rules live in the gaps between two schemas, because failures happen at 2 a.m., and because the people who depend on the interface have no way to see inside it.

Azure Integration Services gave us the building blocks to address all three: a secure and throttled front door, a queue that absorbs both load and outages, transformation logic that stays readable and testable, and telemetry that turns a black box into something the support team can query.

For this customer, the shift is from order entry to order intake. The order desk no longer types orders; it handles the exceptions the system surfaces — which is a materially different, and much smaller, job.

Key Takeaway

The goal is not to convert a file. It is to make the trading partner’s order become an ERP document on its own, with the business’s rules applied consistently and every step visible when something goes wrong.

For organizations connecting trading partners, ERPs or logistics platforms, the same architectural approach extends to order acknowledgements, shipment notices and invoices — keeping the ERP at the centre of the business process while the integration layer absorbs the differences between systems.

Ready to automate order intake between your trading partners and your ERP? Reach out to the CloudFronts team at transform@cloudfronts.com — we can help you design event-driven integrations across Azure, Infor LN, SAP and the Microsoft stack.

ArunKumar Kalapurathu SivanPillai

Senior Technical Architect and Azure Integration Specialist · CloudFronts

[Short bio — experience, specialization in Azure Integration Services, ERP integrations, certifications, and areas of interest. Replace this block before publishing.]


Share Story :

SEARCH BLOGS :

FOLLOW CLOUDFRONTS BLOG :


Categories

Secured By miniOrange