Punchout is an e-procurement integration protocol that connects buyer procurement systems with supplier e-commerce catalogs. It allows users to "punch out" from their procurement application to a supplier's website, browse products, add items to a shopping cart, and then "punch in" back to their procurement system with the shopping cart data for purchase order creation and processing.
This documentation is designed to provide comprehensive information about punchout functionality to different stakeholders:
Punchout is a procurement method that allows buyers to access and shop a supplier's catalog from within their procurement system. The term "punch out" describes the process of a user exiting (or "punching out" from) their company's procurement application to shop on a supplier's website and then returning (or "punching in") with their shopping cart contents.
Commerce eXtensible Markup Language (cXML) is the most common protocol used for punchout integration. cXML was developed by Ariba and is now an open standard used by many e-procurement systems.
cXML defines:
cXML is based on XML (eXtensible Markup Language) and uses HTTP as its transport protocol. The punchout process involves exchanging several types of cXML documents:
Document Type | Description | Direction |
---|---|---|
PunchOutSetupRequest | Request to initiate a punchout session | Procurement → Supplier |
PunchOutSetupResponse | Response containing URL for punchout session | Supplier → Procurement |
PunchOutOrderMessage | Shopping cart contents being returned | Supplier → Procurement |
PunchOutOrderRequest | Final purchase order information | Procurement → Supplier |
For Buyers:
For Suppliers:
The standard punchout flow consists of the following steps:
Note: The PunchOutOrderRequest step is optional in some implementations. Many procurement systems send purchase orders through other channels such as EDI, email, or API integrations.
The Kodaris Commerce platform implements punchout functionality through a modular architecture that handles all aspects of the punchout process, from initial authentication to order processing.
The implementation follows the standard cXML punchout model with additional features for address mapping, invoice generation, and customizable XML transformations.
The Kodaris implementation includes several controllers that handle different aspects of the punchout process:
Controller | Path | Description |
---|---|---|
PunchOutPublicController | /api/user/punchOut | Handles incoming punchout requests from procurement systems |
CustomerPunchOutController | /api/account/punchOut | Manages customer-facing punchout functionality |
PunchOutIntegrationController | /api/system/integration/punchOut | Admin-level configuration of punchout integrations |
The core business logic for punchout is implemented in the following services:
The system includes several JavaScript interceptors that customize the punchout flow:
Full details on these interceptors, including implementation examples, can be found in the Customization Guide.
The system includes comprehensive DTO (Data Transfer Object) classes for handling cXML:
The Kodaris implementation uses a secure, multi-step authentication process:
/api/user/punchOut/setup
endpointSecurity Best Practice: The shared secret should be a complex password known only to both systems. It should never be transmitted as plain text in the URL or query parameters.
The Kodaris implementation supports both round-trip punchout (cart transfer) and order processing:
/api/user/punchOut/order
Note: The order processing step is often handled through alternative channels (e.g., EDI, email) instead of the cXML PunchOutOrderRequest.
Before setting up punchout in Kodaris Commerce, ensure you have:
To set up a company for punchout integration:
Tip: It's recommended to use a strong, unique shared secret for each punchout integration to maintain security.
Punchout users can be handled in two ways:
Users can be automatically created during the punchout process:
Users can be created in advance and mapped to procurement system identities:
The Kodaris Commerce platform uses the following settings for punchout:
Setting | Description | Default |
---|---|---|
INTEGRATION_CODE | Integration type identifier | "PUNCHOUT" |
SETUP_REQUEST_SETTING | Setting key for setup request configuration | "punchOutSetupRequest" |
ORDER_REQUEST_SETTING | Setting key for order request configuration | "punchOutOrderRequest" |
TRACKING_ID_SETTING | Setting key for punchout session tracking | "punchOutTrackingID" |
ORDER_STATUS_CART_TRANSFERRED | Status applied to carts after transmission | "PunchOut Cart Transferred" |
Additional configurable settings include:
The PunchOutSetupRequest is sent from the procurement system to initiate a punchout session:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cXML.org/schemas/cXML/1.2.014/cXML.dtd">
<cXML payloadID="[unique ID]" timestamp="YYYY-MM-DDThh:mm:ssZ">
<Header>
<From>
<Credential domain="[buyer domain]">
<Identity>[buyer identity]</Identity>
</Credential>
</From>
<To>
<Credential domain="[supplier domain]">
<Identity>[supplier identity]</Identity>
</Credential>
</To>
<Sender>
<Credential domain="[buyer domain]">
<Identity>[buyer identity]</Identity>
<SharedSecret>[shared secret]</SharedSecret>
</Credential>
<UserAgent>[procurement system name]</UserAgent>
</Sender>
</Header>
<Request deploymentMode="[production/test]">
<PunchOutSetupRequest operation="create">
<BuyerCookie>[buyer session ID]</BuyerCookie>
<Extrinsic name="User">[username]</Extrinsic>
<Extrinsic name="UniqueUsername">[unique username]</Extrinsic>
<Extrinsic name="Department">[department]</Extrinsic>
<BrowserFormPost>
<URL>[return URL]</URL>
</BrowserFormPost>
<Contact>
<Name xml:lang="en">[user name]</Name>
<Email>[user email]</Email>
</Contact>
<SupplierSetup>
<URL>[supplier website URL]</URL>
</SupplierSetup>
<ShipTo>
<Address>
<Name xml:lang="en">[shipping name]</Name>
<PostalAddress>
<Street>[street address]</Street>
<City>[city]</City>
<State>[state]</State>
<PostalCode>[postal code]</PostalCode>
<Country isoCountryCode="US">United States</Country>
</PostalAddress>
</Address>
</ShipTo>
</PunchOutSetupRequest>
</Request>
</cXML>
Note: The PunchOutSetupRequest may also include operation="edit"
with an ItemOut
section if it's used to edit an existing cart.
The PunchOutSetupResponse is sent from the supplier system in response to a setup request:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cXML.org/schemas/cXML/1.2.014/cXML.dtd">
<cXML payloadID="[unique ID]" timestamp="YYYY-MM-DDThh:mm:ssZ">
<Response>
<Status code="200" text="OK">
<!-- Success -->
</Status>
<PunchOutSetupResponse>
<StartPage>
<URL>https://supplier.com/punchout?token=abc123</URL>
</StartPage>
</PunchOutSetupResponse>
</Response>
</cXML>
Error response example:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cXML.org/schemas/cXML/1.2.014/cXML.dtd">
<cXML payloadID="[unique ID]" timestamp="YYYY-MM-DDThh:mm:ssZ">
<Response>
<Status code="401" text="Unauthorized">
<!-- Authentication failure -->
Invalid credentials
</Status>
</Response>
</cXML>
The PunchOutOrderMessage contains cart data sent back to the procurement system:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cXML.org/schemas/cXML/1.2.014/cXML.dtd">
<cXML payloadID="[unique ID]" timestamp="YYYY-MM-DDThh:mm:ssZ">
<Header>
<From>
<Credential domain="[supplier domain]">
<Identity>[supplier identity]</Identity>
</Credential>
</From>
<To>
<Credential domain="[buyer domain]">
<Identity>[buyer identity]</Identity>
</Credential>
</To>
<Sender>
<Credential domain="[supplier domain]">
<Identity>[supplier identity]</Identity>
<SharedSecret>[shared secret]</SharedSecret>
</Credential>
<UserAgent>Kodaris Commerce</UserAgent>
</Sender>
</Header>
<Message>
<PunchOutOrderMessage>
<BuyerCookie>[buyer session ID]</BuyerCookie>
<PunchOutOrderMessageHeader operationAllowed="create">
<Total>
<Money currency="USD">123.45</Money>
</Total>
</PunchOutOrderMessageHeader>
<ItemIn quantity="2">
<ItemID>
<SupplierPartID>ABC123</SupplierPartID>
<SupplierPartAuxiliaryID>987ZYX</SupplierPartAuxiliaryID>
</ItemID>
<ItemDetail>
<UnitPrice>
<Money currency="USD">45.67</Money>
</UnitPrice>
<Description xml:lang="en">Widget A</Description>
<UnitOfMeasure>EA</UnitOfMeasure>
<Classification domain="UNSPSC">12345678</Classification>
<ManufacturerPartID>MFG123</ManufacturerPartID>
<ManufacturerName>Acme Corp</ManufacturerName>
</ItemDetail>
</ItemIn>
<!-- Additional items -->
</PunchOutOrderMessage>
</Message>
</cXML>
The PunchOutOrderRequest contains purchase order information sent to the supplier:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cXML.org/schemas/cXML/1.2.014/cXML.dtd">
<cXML payloadID="[unique ID]" timestamp="YYYY-MM-DDThh:mm:ssZ">
<Header>
<From>
<Credential domain="[buyer domain]">
<Identity>[buyer identity]</Identity>
</Credential>
</From>
<To>
<Credential domain="[supplier domain]">
<Identity>[supplier identity]</Identity>
</Credential>
</To>
<Sender>
<Credential domain="[buyer domain]">
<Identity>[buyer identity]</Identity>
<SharedSecret>[shared secret]</SharedSecret>
</Credential>
<UserAgent>[procurement system name]</UserAgent>
</Sender>
</Header>
<Request deploymentMode="[production/test]">
<OrderRequest>
<OrderRequestHeader orderID="PO12345" orderDate="YYYY-MM-DD" type="regular">
<Total>
<Money currency="USD">123.45</Money>
</Total>
<ShipTo>
<Address addressID="ShipTo123">
<Name xml:lang="en">[shipping name]</Name>
<PostalAddress>
<Street>[street address]</Street>
<City>[city]</City>
<State>[state]</State>
<PostalCode>[postal code]</PostalCode>
<Country isoCountryCode="US">United States</Country>
</PostalAddress>
</Address>
</ShipTo>
<BillTo>
<Address addressID="BillTo123">
<Name xml:lang="en">[billing name]</Name>
<PostalAddress>
<Street>[street address]</Street>
<City>[city]</City>
<State>[state]</State>
<PostalCode>[postal code]</PostalCode>
<Country isoCountryCode="US">United States</Country>
</PostalAddress>
</Address>
</BillTo>
</OrderRequestHeader>
<ItemOut quantity="2" lineNumber="1">
<ItemID>
<SupplierPartID>ABC123</SupplierPartID>
</ItemID>
<ItemDetail>
<UnitPrice>
<Money currency="USD">45.67</Money>
</UnitPrice>
<Description xml:lang="en">Widget A</Description>
<UnitOfMeasure>EA</UnitOfMeasure>
</ItemDetail>
</ItemOut>
<!-- Additional items -->
</OrderRequest>
</Request>
</cXML>
This example demonstrates how to set up a new punchout integration with a customer using Ariba:
/api/user/punchOut/setup
Follow these steps to test a punchout integration:
/api/user/punchOut/setup
Issue | Possible Causes | Solutions |
---|---|---|
Authentication Failure | • Incorrect shared secret • Incorrect domain/identity values • Company integration not configured | • Verify shared secret in company integration settings • Confirm domain and identity values match PunchOutSetupRequest • Check that company has active punchout integration |
Redirect URL Not Working | • URL formatting issues • Token expiration • Cross-domain cookies blocked | • Check URL encoding • Verify token hasn't expired (default 30 minutes) • Check browser settings for third-party cookies |
Cart Transmission Failure | • Incorrect return URL • XML formatting issues • Browser form submission blocked | • Verify return URL in PunchOutSetupRequest • Check XML format for compliance with cXML standard • Check for browser pop-up blockers |
Order Processing Errors | • Missing or invalid address mapping • Product SKU not found • Quantity or pricing issues | • Configure address mapping for the company • Verify product SKUs exist in both systems • Check quantity and pricing rules |
The Kodaris punchout implementation includes extensive logging:
To access logs:
Tip: Always reference the tracking ID when communicating with customers about punchout issues. This unique identifier helps quickly locate the relevant transaction logs..
Kodaris Commerce can integrate with the following common punchout providers: