ediverse Explore the platform

Spotlight PEPPOL BIS Billing 3.0 The EU e-invoicing mandate is here — France Sept 2026, Belgium Jan 2026, Germany 2025.

cXML PunchOutOrderMessage

Message that closes a punchout session and transfers the cart the user built at the supplier back to the buyer's ERP. Posted by the browser, not the supplier server — a critical detail of the flow.

Purpose

When the user clicks "Checkout" inside the supplier catalog, the supplier does not post the cart server-to-server. It generates an HTML page with a hidden <form> containing the PunchOutOrderMessage cXML and submits that form from the user's browser, which relays it to the BrowserFormPost URL announced by the ERP at setup.

The ERP correlates the returned cart with the original request via the BuyerCookie — that is the only link between the PunchOutSetupRequest and this message. The PunchOutOrderMessage is not an order in the cXML sense: it is a cart that will be converted into an OrderRequest after internal ERP approval.

XML structure

The DTD declares: PunchOutOrderMessage (BuyerCookie, PunchOutOrderMessageHeader, ItemIn*). The useful content is therefore three blocks: the cookie that correlates the session, a header that summarises totals, and the list of items the user put in the cart.

The PunchOutOrderMessageHeader is declared as (SourcingStatus?, Total, ShipTo?, Shipping?, Tax?, SupplierOrderInfo?). Only Total is required by content. The operationAllowed attribute is #REQUIRED and signals what the buyer can do with the cart later: create (use as-is), inspect (read-only revisit) or edit (reopen for modification — implies the supplier stores state to be able to restore it).

xml punchout-order-message.cxml.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.069/cXML.dtd">
<cXML payloadID="260513.150500.poom@supplier.example"
      timestamp="2026-05-13T15:05:00+00:00"
      version="1.2.069">
  <Header>
    <From>
      <Credential domain="DUNS"><Identity>987654321</Identity></Credential>
    </From>
    <To>
      <Credential domain="DUNS"><Identity>123456789</Identity></Credential>
    </To>
    <Sender>
      <Credential domain="DUNS">
        <Identity>987654321</Identity>
        <SharedSecret>shared-secret-here</SharedSecret>
      </Credential>
      <UserAgent>supplier-catalog/3.2</UserAgent>
    </Sender>
  </Header>
  <Message>
    <PunchOutOrderMessage>
      <BuyerCookie>session-abc-12345</BuyerCookie>
      <PunchOutOrderMessageHeader operationAllowed="edit">
        <Total>
          <Money currency="USD">129.97</Money>
        </Total>
        <ShipTo>
          <Address>
            <Name xml:lang="en">Acme Corp — London site</Name>
            <PostalAddress>
              <Street>10 Cheapside</Street>
              <City>London</City>
              <PostalCode>EC2V 6AA</PostalCode>
              <Country isoCountryCode="GB">United Kingdom</Country>
            </PostalAddress>
          </Address>
        </ShipTo>
      </PunchOutOrderMessageHeader>
      <ItemIn quantity="3" lineNumber="1">
        <ItemID>
          <SupplierPartID>SKU-A100</SupplierPartID>
        </ItemID>
        <ItemDetail>
          <UnitPrice><Money currency="USD">29.99</Money></UnitPrice>
          <Description xml:lang="en">Ergonomic office chair, black</Description>
          <UnitOfMeasure>EA</UnitOfMeasure>
          <Classification domain="UNSPSC">56101504</Classification>
          <ManufacturerName>Acme Furniture</ManufacturerName>
        </ItemDetail>
      </ItemIn>
      <ItemIn quantity="2" lineNumber="2">
        <ItemID>
          <SupplierPartID>SKU-B200</SupplierPartID>
        </ItemID>
        <ItemDetail>
          <UnitPrice><Money currency="USD">20.00</Money></UnitPrice>
          <Description xml:lang="en">Adjustable footrest</Description>
          <UnitOfMeasure>EA</UnitOfMeasure>
          <Classification domain="UNSPSC">56121601</Classification>
          <ManufacturerName>Acme Furniture</ManufacturerName>
        </ItemDetail>
      </ItemIn>
    </PunchOutOrderMessage>
  </Message>
</cXML>

Required vs optional

In the message body: BuyerCookie and PunchOutOrderMessageHeader are required (cardinality 1). ItemIn* is optional but in practice always present — that is the point of the message. An empty cart is theoretically allowed (user leaves without buying) but unusual.

On PunchOutOrderMessageHeader: operationAllowed is #REQUIRED, quoteStatus defaults to "final" (alternative: "pending"). The content requires a Total; ShipTo, Shipping, Tax, SourcingStatus and SupplierOrderInfo are optional.

On each ItemIn: quantity is #REQUIRED, lineNumber is #IMPLIED (but almost always supplied). The content requires ItemID and ItemDetail. ItemDetail requires UnitPrice, at least one Description, UnitOfMeasure and at least one Classification.

Common patterns

The browser-as-courier design is not a detail: the supplier server never sees the final form of the BrowserFormPost URL (it may sit behind an internal buyer load balancer). The supplier also does not sign the request at the HTTP layer — the cXML payload itself carries the credentials, and the ERP authenticates via the shared SharedSecret and the BuyerCookie.

A punchout cart is self-contained: no reference to any prior OrderRequest. Each ItemIn must carry the price, description, unit and classification. The ERP uses that data to build its own OrderRequest after approval.

Implementation tip: also emit a supplier-side identifier in SupplierOrderInfo so you can correlate the later OrderRequest with this punchout cart.

Punchout flow (final leg)

The PunchOutOrderMessage is stage 2 of the full flow:

plaintext punchout-checkout-flow.txt
Buyer (ERP)         User's browser              Supplier (catalog)
      │                          │                                  │
      │                          │   (active web session)           │
      │                          │◄─────────────────────────────────┤
      │                          │                                  │
      │                          │   user clicks "Checkout"         │
      │                          │                                  │
      │                          │   1. generate PunchOutOrderMessage
      │                          │      with BuyerCookie + ItemIn*  │
      │                          │◄─────────────────────────────────┤
      │                          │                                  │
      │  2. HTTP POST from browser ► BrowserFormPost URL (cXML body)│
      │◄═════════════════════════╪                                  │
      │                          │                                  │
      │  3. ERP correlates via BuyerCookie, loads the cart          │
      │  4. internal approval workflow, then...                     │
      │                          │                                  │
      │  5. OrderRequest (server-to-server)                         │
      ├──────────────────────────────────────────────────────────►  │

Documentation