Skip to content

OpexMX with SAP through OpexFlow

Reference for sending OpexMX postings to SAP through OpexFlow: signed webhook, once-per-event check, mapping to the SAP middleware, document number write-back, dead letters with replay, and a nightly reconcile.

Updated

Find it: Management → API & Integrations (Admin group) → Webhooks for the OpexMX side. The flow itself is built and run in OpexFlow.

Maintenance work creates SAP documents: spare parts issued to a work order, and labour and cost confirmed when the order closes. This page describes the path that carries those postings from OpexMX to SAP so that each one is either confirmed by SAP or visible as an open item.

Status of this page

This path was tested against a simulated SAP middleware, not a live SAP system. The document numbers in the test are not real SAP documents, and the alert email went to a test mailbox. The recorded evidence is the OpexFlow case study OpexMX to SAP: confirmed delivery for every posting.

Field mapping, document types and the SAP interface (middleware REST, IDoc or BAPI) are set per installation.

The parts

PartRole
OpexMXRaises the event and sends it as a signed webhook. Receives the SAP document number back
OpexFlowChecks, de-duplicates, maps and delivers the event, keeps a record of both sides, and flags what did not arrive
SAP middlewareThe interface in front of SAP that accepts the posting and answers with a document number or a refusal

The flow

OpexMX sends a signed webhook for each posting event. One flow in OpexFlow sits between OpexMX and the SAP middleware and runs these steps in order:

  1. Signed webhook. The request carries an event id and a signature. A request that fails the signature check is refused with 401 and never enters the flow.
  2. Dedupe on event id. Each event id is accepted once. A resend of the same event id is recognised and dropped, so SAP is not posted to twice.
  3. Map. The event is mapped to the SAP payload. In the test, a goods issue (movement type 261) or a PM order confirmation.
  4. Ledger, OpexMX side. The event is written to a ledger on the OpexMX side.
  5. POST to the SAP middleware. The payload is sent with an Idempotency-Key header.
  6. Ledger, SAP side. SAP's answer is written to a ledger on the SAP side.
  7. Write back. The SAP document number is returned to OpexMX, which stores it on the transaction.
  8. Reconcile. A scheduled node compares the two ledgers.

What OpexMX sends

The OpexMX webhook sender, as implemented in the product code:

  • delivers a POST with a JSON body that has a unique event id, the event type, the tenant and the record data
  • signs the request. The X-Webhook-Signature header holds a timestamp and an HMAC-SHA256 of the timestamp and body, made with the webhook secret. X-Webhook-Id, X-Webhook-Timestamp and X-Webhook-Event are also sent
  • subscribes per tenant by event type, with wildcards such as work_order.*
  • times out after 30 seconds and writes every attempt to a delivery log
  • shows webhook health from the last 10 deliveries: healthy at 80% success or more, degraded at 50% or more, otherwise failing

When SAP refuses or is down

CaseWhat happens
SAP accepts the postingThe answer is 201. The document number goes to the ledger and back to OpexMX
The same event is sent againRecognised by its event id. No second posting
The signature is wrongRefused at the door with 401. Nothing reaches SAP
SAP refuses the posting (a 4xx answer)The record is parked in Dead letters with its original payload and SAP's message. An email goes to the operations mailbox. A person can correct the record and replay it
SAP is down (a 5xx answer)OpexFlow answers OpexMX with 503 so the delivery can be retried. It does not go to Dead letters

The two failure types are treated differently on purpose. A refusal such as a blocked cost centre will fail again unless someone changes the record, so it is parked for a person. An outage is temporary, so the delivery is retried.

Dead letters, correct and replay

A refused posting does not vanish and does not block the others. It sits in Dead letters with the exact record that was sent and SAP's error text. A person edits the payload and replays it into the flow. Each action is recorded under their sign-in.

In the test, SAP answered 422 with the message "KI235 cost center blocked". The record was parked, and the alert email named the work order, plant, cost centre, amount and SAP error.

Nightly reconcile

At 01:00 a reconcile node compares the OpexMX ledger with the SAP ledger by event id. A gap becomes an exception case with a status, an assignee and a history. It is worked rather than read: assign it, investigate, then resolve it as matched, correction posted or written off.

In the test run OpexMX held 5 events and SAP held 4. Four matched. The one gap was the refused posting, so the dead letter and the reconcile agreed.

The reconcile gives a second, independent view of each posting. A posting that was accepted by the middleware but never reached SAP, or one that never left OpexMX, shows up here even if no error was raised along the way.

Health and SLA

The Health and SLA view lists every external call the flow makes, with calls, errors, retries and latency. In the test window the SAP call had 7 calls, 3 errors and 2 retries, which matches the one refusal and the two 503 answers.

Scope and open points

  • Tested against a simulated SAP middleware. No live SAP system was used.
  • In the test, the retry after a 503 was carried out by the sending side. The OpexMX webhook sender in the current product code retries after a network error or timeout (by default 3 attempts, 60 seconds then 120 seconds) and logs a non-success response as a failed delivery without sending it again. Confirm the retry behaviour of the sender for your OpexMX version before relying on recovery from a 503.
  • The write-back of the SAP document number goes to an endpoint on the OpexMX side. In the test that endpoint was a stand-in. How the number is stored on the transaction is set per installation.
  • The email alert is sent over SMTP to an operations mailbox that you configure.

Native SAP sync

OpexMX also has a built-in sync engine for SAP ECC 6 (integration type sap_ecc6). It uses the same model as the Epicor sync: scheduled runs, a watermark per entity and direction, and dead letters with replay. It covers work orders, assets, parts (materials) and purchase orders. It is a different path from this one. It moves master and transactional records on a schedule, while the flow on this page proves delivery of individual postings.

Related