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 PunchOutSetupRequest

Punchout session opener. The buyer ERP sends it to the supplier site to obtain a short-lived URL that takes the user into the hosted catalog, pre-authenticated and tied to a session cookie.

Purpose

Punchout lets a buyer shop inside the supplier's hosted web catalog — rich UI, negotiated prices, real-time stock — while staying inside their ERP's approval workflow. The PunchOutSetupRequest is the technical opener: it identifies the buyer, carries a BuyerCookie that will be echoed back unchanged at the end of the session, and provides the BrowserFormPost URL where the supplier must post the returned cart.

The response contains a StartPage: a one-time, short-lived URL toward which the ERP redirects the user's browser. That URL effectively acts as an authentication token — anyone holding it enters the supplier session.

XML structure

PunchOutSetupRequest

The DTD declares: PunchOutSetupRequest (BuyerCookie, Extrinsic*, BrowserFormPost?, Contact*, SupplierSetup?, ShipTo?, SelectedItem?, ItemOut*). The operation attribute is #REQUIRED and takes four values: create (new cart), inspect (read-only revisit of a previous cart), edit (modify an existing cart), source (build an RFQ for a sourcing tool).

xml punchout-setup-request.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.143000.punchout@buyer.example"
      timestamp="2026-05-13T14:30:00+00:00"
      version="1.2.069">
  <Header>
    <From>
      <Credential domain="DUNS"><Identity>123456789</Identity></Credential>
    </From>
    <To>
      <Credential domain="DUNS"><Identity>987654321</Identity></Credential>
    </To>
    <Sender>
      <Credential domain="DUNS">
        <Identity>123456789</Identity>
        <SharedSecret>shared-secret-here</SharedSecret>
      </Credential>
      <UserAgent>ediverse-buyer/1.0</UserAgent>
    </Sender>
  </Header>
  <Request>
    <PunchOutSetupRequest operation="create">
      <BuyerCookie>session-abc-12345</BuyerCookie>
      <BrowserFormPost>
        <URL>https://buyer.example/cxml/punchout/callback</URL>
      </BrowserFormPost>
      <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>
    </PunchOutSetupRequest>
  </Request>
</cXML>

PunchOutSetupResponse

The DTD is minimal: PunchOutSetupResponse (StartPage). The only payload is the URL toward which to redirect the user, wrapped in StartPage > URL.

xml punchout-setup-response.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.143002.punchout-resp@supplier.example"
      timestamp="2026-05-13T14:30:02+00:00"
      version="1.2.069">
  <Response>
    <Status code="200" text="OK"/>
    <PunchOutSetupResponse>
      <StartPage>
        <URL>https://supplier.example/catalog/session/abc-12345</URL>
      </StartPage>
    </PunchOutSetupResponse>
  </Response>
</cXML>

Required vs optional

The only required element inside the request body is BuyerCookie (the DTD declares it ANY but with cardinality 1). The operation attribute is also #REQUIRED.

Everything else is optional: Extrinsic*, BrowserFormPost?, Contact*, SupplierSetup?, ShipTo?, SelectedItem?, ItemOut*. In practice BrowserFormPost is never omitted — without it the supplier has nowhere to post the cart. And ShipTo is very common so the catalog can show appropriate stock and lead times.

On the response side, StartPage > URL is the entire content, hence strictly mandatory.

Common patterns

The BuyerCookie is opaque to the supplier — it must be stored as-is and echoed back unchanged in the eventual PunchOutOrderMessage. It is the key that lets the buyer ERP correlate the returned cart with the original cart request. The DTD states "BuyerCookie is unique per PunchOut session".

SelectedItem enables item-level punchout: instead of landing on the catalog home, the user is taken straight to a given product page (identified by its ItemID). Useful from an ERP cart that wants to "configure" a punchout item.

For operation="edit" or "inspect", the ERP sends the original ItemOut* elements so the catalog can reconstruct the previous cart state.

Punchout flow

A full punchout is a two-stage HTTP choreography. Stage 1 (synchronous): the PunchOutSetupRequest/Response server-to-server over HTTPS. Stage 2 (asynchronous): the user's web session, ending with a PunchOutOrderMessage posted from the user's browser to the BrowserFormPost URL.

plaintext punchout-flow.txt
Buyer (ERP)                Network hub          Supplier (catalog)
      │                          │                          │
      │  1. PunchOutSetupRequest │                          │
      │  (operation=create)      │                          │
      ├─────────────────────────►│                          │
      │                          │  2. HTTPS POST relay     │
      │                          ├─────────────────────────►│
      │                          │                          │
      │                          │  3. PunchOutSetupResponse│
      │                          │     <StartPage><URL/>    │
      │                          │◄─────────────────────────┤
      │  4. HTTP 200 relayed     │                          │
      │◄─────────────────────────┤                          │
      │                          │                          │
      │  5. redirect user's browser to StartPage             │
      │═══════════════════════════════════════════════════►│
      │                                                     │
      │           (user browses the hosted catalog)         │
      │                                                     │
      │  6. PunchOutOrderMessage (browser POST → BrowserFormPost URL)
      │◄════════════════════════════════════════════════════┤

Documentation