Skip to content
SyncMyShop

PunchOut

cXML PunchOut explained: the documents, in the order they travel

A cXML PunchOut session is three XML documents: a setup request from the procurement system to your store, a setup response with a start URL, and an order message that carries the cart back through the buyer's browser. The purchase order, the confirmation, the ship notice and the invoice follow as four more.

Updated

What cXML is

cXML, commerce XML, is an XML vocabulary for procurement documents between a buying organization and a supplier. The procurement system of the buyer sends the session request and the purchase order; the supplier sends the cart, the confirmation, the ship notice and the invoice. The format is published at cxml.org. The current reference guide is version 1.2.071 of August 14, 2026, published by SAP; the facts on this page were checked against it on October 3, 2026.

Every document has the same envelope:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.071/cXML.dtd">
<cXML payloadID="1791032580.7731.41893@procure.bakker.example"
      timestamp="2026-10-03T09:03:00-04:00">
  <Header>...</Header>
  <Request deploymentMode="production">...</Request>
</cXML>
  • payloadID is unique per document and stays the same when the document is sent again. The recommended form is date and time, process id and a random number, then @ and the host name.
  • timestamp is ISO 8601 with a UTC offset. The Z designator is not allowed.
  • deploymentMode is test or production. Production is the default.
  • The body is a Request, a Response or a Message. A request is posted from server to server and answered with a response in the same HTTP connection. A message is one-way and gets no answer.

The documents, in the order they travel

# Document From To Transport
1 PunchOutSetupRequest procurement system your endpoint HTTPS POST
2 PunchOutSetupResponse your endpoint procurement system the answer to 1
3 PunchOutOrderMessage your store procurement system form POST by the browser
4 OrderRequest procurement system your order endpoint HTTPS POST
5 ConfirmationRequest you procurement system HTTPS POST
6 ShipNoticeRequest you procurement system HTTPS POST
7 InvoiceDetailRequest you procurement system HTTPS POST
The cXML documents of a PunchOut order, in the order they travel The procurement system posts a PunchOutSetupRequest to the supplier endpoint and gets a PunchOutSetupResponse with a start URL. The buyer's browser opens that URL and later posts the PunchOutOrderMessage back to the procurement system as a form. After approval the OrderRequest goes from server to server and is answered with status 200. ConfirmationRequest, ShipNoticeRequest and InvoiceDetailRequest go back from the supplier. Procurement system at the buyer Browser of the buyer Your endpoint and store 1. PunchOutSetupRequest 2. PunchOutSetupResponse, StartPage/URL redirect to the start URL opens the start URL, logged in The buyer shops at contract prices. No cXML moves during the session. page with a form field cXML-base64 3. PunchOutOrderMessage, form POST approval at the buyer 4. OrderRequest Response, Status 200 5. ConfirmationRequest 6. ShipNoticeRequest 7. InvoiceDetailRequest The cart is the only document that travels through the browser. Every other document is a POST from server to server and is answered with a Response that holds a Status.
Seven documents for one order. Only the cart travels through the browser.

Documents 1 to 3 are the session. The reference states that the session produces a quote, not a purchase order: the order exists once document 4 arrives. With SAP Ariba, documents 1, 2 and 4 pass through SAP Business Network, which authenticates the buyer and forwards them. Coupa sends the setup request straight to your endpoint. What the store has to do at each step is on the supplier checklist.

The setup request

A buyer at Bakker Installatie B.V. clicks your tile at 9:03 AM. The procurement system posts this:

<Header>
  <From><Credential domain="NetworkId">
    <Identity>bakker-installatie</Identity></Credential></From>
  <To><Credential domain="NetworkId"><Identity>your-store</Identity></Credential></To>
  <Sender>
    <Credential domain="NetworkId"><Identity>bakker-installatie</Identity>
      <SharedSecret>the-agreed-secret</SharedSecret></Credential>
    <UserAgent>Procurement System 4.2</UserAgent>
  </Sender>
</Header>
<Request deploymentMode="production">
  <PunchOutSetupRequest operation="create">
    <BuyerCookie>1CX3L4843PPZO</BuyerCookie>
    <Extrinsic name="UserEmail">j.devries@bakker.example</Extrinsic>
    <BrowserFormPost><URL>https://procure.bakker.example/return</URL></BrowserFormPost>
  </PunchOutSetupRequest>
</Request>
Part What it is What to do with it
operation create for a new cart, edit to change an earlier one, inspect to view it, source for a request for quote On edit and inspect the earlier lines arrive as ItemOut elements; rebuild the cart from them
BuyerCookie The only required element. Opaque, new in every session per the cXML reference; Coupa keeps one per user (see PunchOut for Coupa) Store it and return it unchanged in the cart
BrowserFormPost/URL Where the cart has to go Store it with the session
Contact, Extrinsic User name, email, cost center. Each buying organization configures its own Use them when present; never depend on them
ShipTo An address for delivery and price estimates The delivery address that counts is on the purchase order
SelectedItem The item the buyer clicked in its own search Open that product. See Level 2 PunchOut

Each element is walked through in the PunchOutSetupRequest.

The setup response

The answer holds a status and one URL:

<Response>
  <Status code="200" text="OK"/>
  <PunchOutSetupResponse>
    <StartPage>
      <URL>https://store.example.com/punchout/start?sid=9f2c41d8a07b</URL>
    </StartPage>
  </PunchOutSetupResponse>
</Response>

The procurement system sends the buyer's browser to that URL. It has to log the buyer in without a form and show the catalog and contract prices of that organization. The reference asks for a unique, temporary URL that refers to the session state and does not contain it, because many applications limit the length of a URL. An identifier that is not used expires fast, for example after five minutes, so a copied link opens nothing.

When the request cannot be accepted, the response holds a status and no PunchOutSetupResponse:

Status Text When Sent again by the buyer
200 OK accepted
400 Bad Request the document parses and cannot be accepted no
401 Unauthorized the credentials in Sender are not recognized no
406 Not Acceptable the XML does not validate no
450 Not Implemented the requested operation is not supported, for example edit no
500 Internal Server Error the request could not be completed yes

The 400 range is permanent. The 500 range, and any answer that is not valid cXML, is transient: the reference recommends 10 retries, one per hour.

The order message (the cart)

The cart is the one document that travels through the buyer's browser. The store renders a page with a form whose action is the BrowserFormPost URL and whose single hidden field holds the whole document:

<form method="post" action="https://procure.bakker.example/return">
  <input type="hidden" name="cXML-base64"
         value="PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4K...">
</form>

The field is named cXML-urlencoded or cXML-base64. The reference calls base64 the best choice, since the browser then has no quotes or ampersands to interpret. Inside the document:

  • The Header carries no shared secret, because the buyer can read the page source. The procurement system matches the cart to the session by the BuyerCookie.
  • PunchOutOrderMessageHeader has an operationAllowed attribute. create means the cart cannot be reopened, inspect allows viewing, edit allows changes. Its Total excludes tax and shipping.
  • Each ItemIn needs a quantity, a SupplierPartID, a UnitPrice, a Description, a UnitOfMeasure and a Classification. The unit is a UN/CEFACT code such as EA. A store that sends "each" gets its cart refused by systems that check the code list.
  • SupplierPartAuxiliaryID is yours to fill, for example with a cart reference. It comes back in an edit session and in the purchase order.
  • A message without any ItemIn cancels the session. A cancel button in the store sends it.

A full ItemIn and the totals of a three-line cart are on the PunchOut hub.

The order request (the purchase order)

After approval the procurement system posts an OrderRequest to your order endpoint. Its header carries:

Attribute or element Content
orderID The purchase order number of the buyer
orderDate Date and time, ISO 8601
type new, update or delete. An update or delete points to the original through DocumentReference
orderVersion 1 for the original, plus 1 per change order
requestedDeliveryDate When the buyer wants to receive the goods
Total, BillTo Required. ShipTo, Shipping, Tax and Payment are optional

The answer is a Response with a status and nothing else. A 200 says the order was received and parsed. It does not say which lines can ship; that is document 5.

The retry rule sets the time you have. The procurement system posts PO 4500001234 at 2:10 AM while your endpoint is down for maintenance. A system that follows the recommendation tries again at 3:10, 4:10 and so on. With the endpoint back at 5:30, the fourth retry at 6:10 delivers the order, 4 hours late. An endpoint that stays down longer than 10 retries of 1 hour, 10 hours, no longer receives the order from such a system until someone at the buyer sends it again by hand.

The reverse case is the duplicate. Your endpoint stores the order and the answer is lost on the way. The retry carries the same payloadID and the same orderID. An endpoint that keeps both answers the repeat with 200 and creates nothing. An update that the state of the order no longer allows, because it has shipped, gets 409 Conflict.

Confirmations, ship notices and invoices

Document Key content Without it
ConfirmationRequest A type such as accept, reject, backordered or detail, and a reference to the order The buyer assumes every line ships as ordered
ShipNoticeRequest shipmentID, shipmentDate, deliveryDate, carrier and the lines in the shipment The buyer has no shipment to receive against
InvoiceDetailRequest invoiceID, invoiceDate, the order it bills and a summary that equals the sum of the lines The invoice arrives on paper or as a PDF and is keyed in by hand

Confirmations and ship notices validate against Fulfill.dtd, invoices against InvoiceDetail.dtd, so the DOCTYPE line of these documents differs from the one above. cxml.org describes the confirmation and the ship notice as the cXML analogues of the EDI 855 and 856. These three are your documents: you post them to an address of the buyer, with your identity in From and Sender and the buyer's in To.

Credentials: identity, domain, shared secret

Element Who it names Used for
From The buying organization Finding the customer account
To You Routing by a network hub
Sender The party that opened the HTTP connection, with the SharedSecret Authentication

The domain attribute says which kind of identity it is. The reference names DUNS for a D-U-N-S number, NetworkId for an ID assigned by the network and AribaNetworkUserId for an email address. On SAP Business Network the assigned IDs in the reference's examples read like AN01000000001.

Sender is where direct and routed requests differ. Sent directly, From and Sender are both the buyer. Through a network hub, the hub verifies the buyer, replaces Sender with itself and inserts your own shared secret. A store that looks up the customer by the identity in Sender works with a direct buyer and fails with a routed one. The match that holds in both cases: check the secret in Sender, find the customer by From.

cXML next to OCI

OCI is SAP's protocol for the same session. The login travels through the browser as parameters, the cart returns as form fields named NEW_ITEM-<field>[n] with fixed lengths, and the order and the documents after it are not in the specification. A buyer on SAP asks for OCI; a buyer on Coupa or SAP Ariba asks for cXML. The two are compared part by part in cXML vs OCI, and the OCI fields are on the OCI page.

What this means for your store

A cXML connection is an endpoint, a session and four document types, each with rules that fail without a message on your side when they are missed. We build them on your existing store, host the endpoints and monitor every document: a 401 on a setup request, a cart without a purchase order and an order that was retried are all in the log.

The whole flow, including prices and the order in your ERP, is on the PunchOut hub. Tell us which procurement system your customer uses.

Frequently asked questions

What is the difference between cXML and XML?

XML is the syntax: elements, attributes and a document type definition. cXML is one vocabulary written in that syntax, for procurement documents. Its DTDs define which elements exist, in which order and with which attributes, so an OrderRequest from any procurement system has the same structure.

What is the difference between cXML and EDI?

Both carry orders, confirmations, ship notices and invoices between a buyer and a supplier. EDI X12 uses numbered transaction sets in a segment format, the 850, 855, 856 and 810. cXML uses XML documents over HTTPS, and it adds the PunchOut session, which EDI does not have. See PunchOut vs EDI.

Which procurement systems use cXML?

Coupa and SAP Ariba use cXML for PunchOut. SAP Ariba also routes purchase orders, confirmations, ship notices and invoices as cXML through SAP Business Network. SAP SRM uses its own protocol, OCI, for the session; the order that follows can still be a cXML document. For another system, ask the administrator at the buyer for a sample setup request: it shows the protocol and the fields at once.

Which cXML version does my endpoint have to support?

The version the buyer sends. Every document names its DTD in the DOCTYPE line, for example cXML/1.2.071/cXML.dtd, and the DTDs of all versions are published on cxml.org. The endpoint reads the elements listed on this page and passes over the ones it does not use, so a buyer on another 1.2 version is handled the same way.

Is the shared secret safe in an XML document?

It travels in documents that go from server to server over HTTPS, so the buyer's browser never sees it. The one document that passes through the browser, the PunchOutOrderMessage, is sent without it. On your side the secret is stored as a hash, like a password.

Tell us what you need

Tell us which systems you use and what needs to work better. We reply personally within one working day. We help you define the work, then agree the price and timing before you commit.

  • You know the price and the timeline before you commit to anything
  • We work out the connection that takes the work off your hands
  • We handle the build, hosting, monitoring and maintenance
  • Your team has less information to retype and fewer discrepancies to chase

Suppliers, products, orders per day, a rough estimate is fine.

Or email directly: carsten@syncmyshop.com