This is article five in a series of five articles:
- PunchOut/cXML Process and Design Overview
- PunchOut/cXML Configuration and Data Requirements
- PunchOut Setup Request and Response
- PunchOut Order Message (that is Cart Information)
- Request a purchase order in PunchOut - Current Article
PunchOut transmits purchase orders (POs) to Configured Commerce as your customers place them in their procurement/ERP systems using the cXML-based Order Request message. Your customer's procurement system connects to your integration partner's system.
Your integration partner translates your customer's Order Request message into standard cXML format and sends a POST request to one of the following endpoints, with a separate endpoint available for each domain setup in Configured Commerce SDK:
- 4.4: https://<DOMAIN>/punchout/punchoutorderrequest.isch
- 4.5: https://<DOMAIN>/api/v1/punchout/orderrequest
The PO message should contain all of the necessary data elements to create a single order (such as order header and any line information). Each cXML message should only contain a single order with any number of lines. Each order received can only be shipped to a single location. Each order received will be considered a new order; Configured Commerce does not process order changes/updates.
Configured Commerce uses the cXML standard for the transmission and processing of purchase order (PO) information, specifically using the Order Request format. The PO would be sent from a customer's procurement system/ERP to Configured Commerce via the Integration Partner and Configured Commerce would process the cXML message and submit the order into the client's ERP for fulfillment.
Order request message processing
Order Request cXML data will be composed of both order header and line-level information. Optimizely will translate the cXML into Configured Commerce CustomerOrder & OrderLine records that are used to submit the resulting order into the client's ERP for fulfillment. The following diagram provides a high-level overview of the general steps followed by Configured Commerce:
Identify bill-to
Using the From Identity value found in the cXML (or potentially the BillTo addressID) and the Customer records attached to the PunchOut/cXML Customer User, the corresponding Bill-To will be assigned to the Customer Order. Also, the related CustomerOrder.BT* fields will be populated from the Configured Commerce Customer Bill-To record.
Refer to this article for the Bill-To identification logic: PunchOut configuration and data requirements. It is found under the heading of cXML/PunchOut Users and Address ID Mapping.
Identify ship-to
Using the Ship-To Address ID found in the cXML and the Customer records attached to the PunchOut/cXML Customer User, a Configured Commerce Ship-To record will be attached to the Customer Order. Also, the related CustomerOrder.ST* fields will be populated from the Configured Commerce Customer Ship-To record.
For more information on Ship-To identification logic, reference this article: PunchOut Configuration and Data Requirements. The specific reference is found under the heading of cXML/PunchOut Users and Address ID Mapping.
Identify product
For each <ItemOut> node in the cXML, a separate Configured Commerce OrderLine record will be created. Comparing various data elements in the cXML node and data within the Configured Commerce database, an Configured Commerce Product record will attempt to be attached to the Configured Commerce OrderLine record (that is OrderLine.ProductId). The following sequential logic is applied to determine the Configured Commerce Product, with the next step executing if the previous steps failed in finding a match. A failed match means that zero or 2+ Configured Commerce Product records are matched against a given data element.
- Product Lookup by <SupplierPartID> cXML Field
- Match to Product.ErpNumber (that is ERP Product #)
- Match to CustomerProduct.Name (that is Customer Part #)
The Bill-To Customer determined in the previous step will also be used to locate the Customer Part #.
- Match to Product.ManufacturerItem (that is Manufacturer part #)
- Item Lookup by Alternate cXML Fields
- Match <Extrinsic name="BuyerId"> to CustomerProduct.Name (that is Customer Part #)
The Bill-To Customer determined in the previous step will also be used to locate the Customer Part #.
- Match <Extrinsic name="UPC"> to Product.UPCCode
- Match <ManufacturerPartID> to Product.ManufacturerItem AND
- <ManufacturerName> to Vendor.Name
Product.VendorId joins Product to Vendor table
- Match <ManufacturerPartID> to Product.ManufacturerItem
- Match <Extrinsic name="BuyerId"> to CustomerProduct.Name (that is Customer Part #)
If a single Configured Commerce Product record is not located during the steps above, then the Item Not Found Product record (that is Application Setting: Punchout_NotOnFileProductName; see Section 1.2.4) is attached to the OrderLine record. When this occurs, the following OrderLine fields are still populated with data from the cXML document:
- OrderLine.Line as any other line
- OrderLine.QtyOrdered as any other line
- OrderLine.UnitOfMeasure as any other line
- OrderLine.Description from the <Description> element; usually populated from the Product.ShortDescription
- OrderLine.ActualPrice from the <UnitPrice><Money> element, regardless of the price calculation setting
- OrderLine.Notes populated with a list of cXML fields used for matching to a Configured Commerce Product - the list of cXML fields include supplierId, ManufacturerName, MfgPartNumber, BuyerId, and UPC
Identify unit of measure
Once a given ItemOut Node has been mapped to a Configured Commerce Product record, the <UnitOfMeasure> element is compared against the Configured Commerce Product.UnitOfMeasure and ProductUnitOfMeasure.UnitOfMeasure. If the cXML value does not match a value within Configured Commerce, then the OrderLine will be assigned with the Item Not Found Product.
Identify quantity
The quantity attribute of the <ItemOut> element will be used to determine the OrderLine.QtyOrdered value.
Identify price
Depending on the User Custom Property attached to the PunchOut/cXML Customer User (that is Punchout_AcceptPriceProvided) Application Setting (that is Punchout_DefaultAcceptPriceProvided), the OrderLine price will be set directly from the cXML or will be recalculated within Configured Commerce using the given pricing rules used by the site. See Section 1.2.4 for further details around these settings.
If a PunchOut/cXML Customer User is configured to accept the price submitting in the cXML, then the <UnitPrice><Money> value will be passed into the OrderLine.ActualPrice field.
If a PunchOut/cXML Customer User is configured to recalculate price, and the calculated price differs from the price sent in the cXML, then the cXML price will be written to an OrderLine Custom Property named "Unit Price Submitted".
If a Price cannot be determined, then the OrderLine will be assigned with the Item Not Found Product.
Populate miscellaneous order header fields
In addition to the Bill-To & Ship-To data on the Configured Commerce CustomerOrder record, the following fields are explicitly mapped from the Order Request cXML message to the Configured Commerce CustomerOrder table:
- Order Date
- <OrderRequestHeader orderDate> element & attribute populates Configured Commerce CustomerOrder.OrderDate
- Customer PO
- <OrderRequestHeader><Extrinsic name="CustomerPO"> element populates Configured Commerce CustomerOrder.CustomerPO.
- Requested Ship Date
- <OrderRequestHeader><Extrinsic name="RequestedShipDate"> element populates Configured Commerce
- Ship Via
- <OrderRequestHeader><Extrinsic name="ShipVia"> element ultimately populates Configured Commerce CustomerOrder.ShipViaId, after executing a lookup against the Configured Commerce ShipVia.ERPShipCode field.
- Order Header Notes
- <OrderRequestHeader><Comments> element populates Configured Commerce CustomerOrder.Notes
- PDF Attachment
- <OrderRequestHeader><Extrinsic name="AttachmentFileType">PDF</Extrinsic>
- <OrderRequestHeader><Extrinsic name="Attachment">[BLOB]</Extrinsic>
- The [BLOB] value sent in the cXML should be a base-64 version of the original PDF document. This data will be stored in the PunchOutOrderRequestExtrinsic table with a Name = 'PDFattachment' and the Value = [BLOB], but can be viewed as a PDF through the Configured Commerce Admin Console. See Section 5.4 for detailed screenshots.
To accommodate for any other Order Header fields to be sent into the cXML and passed into the Configured Commerce system, the Application Setting "Punchout_OrderCustomPropertyFields" can be used. This setting will be populated with a comma-separated list of <OrderRequestHeader> level extrinsic field names that will be mapped from the cXML into Configured Commerce Custom Properties of the CustomerOrder.
For example, the following extrinsic fields come over in the cXML:
<OrderRequestHeader> <Extrinsic name="OrderType">Quote</Extrinsic> <Extrinsic name="JobNumber">Job12345</Extrinsic> <Extrinsic name="ShippingLabelComments">Shipping Label Comments Are Populated</Extrinsic></OrderRequestHeader>
To get these fields into a Configured Commerce Custom Property for the CustomerOrder table, the Application Setting "Punchout_OrderCustomPropertyFields" field would be populated with a value of: 'OrderType,JobNumber,ShippingLabelComments'.
Populate miscellaneous order line fields
In addition to the typical Product, QTY, U of M and Price fields on an OrderLine, the following fields are explicitly mapped from the Order Request cXML message to the Configured Commerce OrderLine table:
- Order Line Notes\
- <ItemOut><Comments> element populates Configured Commerce OrderLine.Notes
Successful vs. error processing cXML
The Application Setting "Punchout_RequiredFields" can be used to set a list of required Order Header fields. This setting should contain a comma-separated list of CustomerOrder properties that are required in order to successfully submit an order to the ERP.
If there is an error processing the cXML order (such as due to required field setting, invalid cXML, and so on), then the status of the Order Request response will be reported as a failure.
The detailed data for all cXML Order Request messages are logged into the Configured Commerce Admin Console under Administration > PunchOut > Order Requests. This area of the Admin Console shows a detailed breakdown of the cXML message, including: raw cXML request & response, PDF document (if sent), mapping of extrinsic fields, detailed list of cXML to Configured Commerce mapping results, and the order line results. See Section 5.4 for detailed screenshots of the Order Request message logging. Should an Order Request cXML fail due to some type of setup issue, an admin can attempt to resubmit this order under a specific failed Order Request message.
Order request cXML
<?xml version="1.0"?> <!DOCTYPE cXML SYSTEM "http://xml.cXML.org/schemas/cXML/1.2.011/cXML.dtd"> <cXML payloadID="2016-08-10T16:29:56-05:00@216.25.112.114.cc" timestamp="2016-08-10T16:29:56-05:00" xml:lang="en-US"> <Header> <From> <Credential domain="NetworkId"> <Identity>PunchOutCustomer_ISCUserName</Identity> </Credential> </From> <To> <Credential domain="DUNS"> <Identity>ClientName</Identity> </Credential> </To> <Sender> <Credential domain="UserSiteNetworkUserId"> <Identity>IntegrationPartner_ISCUserName</Identity> <SharedSecret>IntegrationPartner_ISCPassword</SharedSecret> </Credential> <UserAgent>IntegrationPartner</UserAgent> </Sender> </Header> <Request deploymentMode="prod"> <OrderRequest> <OrderRequestHeader type="new" orderID="555666" orderDate="2016-08-29T09:31:48-05:00"> <Total> <Money currency="USD">50.00</Money> </Total> <ShipTo> <Address addressID="102" isoCountryCode="US"> <Name xml:lang="en">Office Supply Inc - Byrdstown</Name> <PostalAddress name="default"> <DeliverTo>Customer 102</DeliverTo> <Street>123 Main St</Street> <City>BYRDSTOWN</City> <State>TN</State> <PostalCode>38549</PostalCode> <Country isoCountryCode="US">United States</Country> </PostalAddress> <Email name="default">test@email.com</Email> <Phone name="work"> <TelephoneNumber> <CountryCode isoCountryCode="US">1</CountryCode> <AreaOrCityCode>555</AreaOrCityCode> <Number>123-4569</Number> </TelephoneNumber> </Phone> <Fax name="work"> <TelephoneNumber> <CountryCode isoCountryCode="US">1</CountryCode> <AreaOrCityCode></AreaOrCityCode> <Number></Number> </TelephoneNumber> </Fax> </Address> </ShipTo> <BillTo> <Address addressID="" isoCountryCode="US"> <Name xml:lang="en">Customer 100</Name> <PostalAddress name="default"> <Street>665 MAINSTREAM DRIVE</Street> <City>NASHVILLE</City> <State>TN</State> <PostalCode>37228</PostalCode> <Country isoCountryCode="US">United States</Country> </PostalAddress> </Address> </BillTo> <Comments></Comments> <Extrinsic name="CustomerPO">Conexiom_QA_TestCase_02a</Extrinsic> <Extrinsic name="RequestedShipDate">9/1/2016</Extrinsic> <Extrinsic name="ShipVia">UPSG</Extrinsic> <Extrinsic name="OrderType">Quote</Extrinsic> <Extrinsic name="JobNumber">Job12345</Extrinsic> <Extrinsic name="ShippingLabelComments">Shipping Label Comments Are Populated</Extrinsic> <Extrinsic name="AttachmentFileType">PDF</Extrinsic> <Extrinsic name="PDFattachment">[BLOB]</Extrinsic> </OrderRequestHeader> <ItemOut lineNumber="1" quantity="2" requestedDeliveryDate=""> <ItemID> <SupplierPartID>ZZZZ</SupplierPartID> <SupplierPartAuxiliaryID></SupplierPartAuxiliaryID> </ItemID> <ItemDetail> <UnitPrice> <Money currency="USD">799</Money> </UnitPrice> <Description xml:lang="en">Sound Board</Description> <UnitOfMeasure>EA</UnitOfMeasure> <Classification domain="UNSPSC"></Classification> <ManufacturerPartID></ManufacturerPartID> <ManufacturerName></ManufacturerName> <Extrinsic name="UPC"></Extrinsic> <Extrinsic name="BuyerId">CUST24612</Extrinsic> </ItemDetail> <Comments>Line 1 Line Notes</Comments> </ItemOut> <ItemOut lineNumber="2" quantity="3" requestedDeliveryDate=""> <ItemID> <SupplierPartID></SupplierPartID> <SupplierPartAuxiliaryID></SupplierPartAuxiliaryID> </ItemID> <ItemDetail> <UnitPrice> <Money currency="USD">450</Money> </UnitPrice> <Description xml:lang="en">Violin Full Size</Description> <UnitOfMeasure>EA</UnitOfMeasure> <Classification domain="UNSPSC"></Classification> <ManufacturerPartID></ManufacturerPartID> <ManufacturerName></ManufacturerName> <Extrinsic name="UPC">888888888888</Extrinsic> <Extrinsic name="BuyerId"></Extrinsic> </ItemDetail> <Comments>Line 2 Line Notes</Comments> </ItemOut> <ItemOut lineNumber="3" quantity="4" requestedDeliveryDate=""> <ItemID> <SupplierPartID>XXXXX</SupplierPartID> <SupplierPartAuxiliaryID></SupplierPartAuxiliaryID> </ItemID> <ItemDetail> <UnitPrice> <Money currency="USD">129</Money> </UnitPrice> <Description xml:lang="en">Database-Manager</Description> <UnitOfMeasure>EA</UnitOfMeasure> <Classification domain="UNSPSC"></Classification> <ManufacturerPartID>MFG2003</ManufacturerPartID> <ManufacturerName>ACME</ManufacturerName> <Extrinsic name="UPC"></Extrinsic> <Extrinsic name="BuyerId"></Extrinsic> </ItemDetail> <Comments>Line 3 Line Notes</Comments> </ItemOut> </OrderRequest> </Request> </cXML>
Order request field mapping
The table below includes some of the most important cXML data elements required to process an order into a client's ERP. However, the sample cXML in the previous section contains additional format and field information.
Field mapping: Purchase order/order request
Field Name |
cXML Element/Attribute |
Destination Commerce Table.Field |
Notes |
---|---|---|---|
Payload ID |
<cXML payloadID> |
Dynamic Unique Value |
Unique value for each cXML document used for locating a particular cXML dataset. |
From Identity |
<Header><From><Credential><Identity> |
Static Value Used to Set: CustomerOrder.CustomerID & CustomerOrder.BT* |
Represents the Customer from which the Order originated. From a business perspective, it will correlate with a client's Bill-To customer. This value will need to tie back to the Username field on a User record in the Configured Commerce platform, which will determine the Bill-To of the order. |
To Identity |
<Header><To><Credential><Identity> |
Static Value |
Represents the Client to which the Setup Request is sent. This will always be the client name, and does NOT tie back to a Configured Commerce Username. |
Sender Identity |
<Header><Sender><Credential><Identity> |
Static Value |
Represents the system sending the message to Configured Commerce. From a process perspective, it will represent the client system sending the message to Configured Commerce (such as Integration Partner). This value will need to tie back to the Username field on a User record in the Configured Commerce platform. |
Sender Shared Secret |
<Header><Sender><Credential> <SharedSecret> |
Static Password |
The Configured Commerce password associated with the Username sent in the <Header><Sender><Credential><Identity> field. Technically used to validate that the Setup Request sent to Configured Commerce is from a valid source. |
Order Date |
<OrderRequestHeader orderDate> |
CustomerOrder.OrderDate |
|
Bill-To Address ID | <BillTo><Address addressID> | CustomerOrder.CustomerId & CustomerOrder.BT* | The BillTo addressID may be optionally used to determine the Customer from which the order originated. This will only be used if a given Username is attached to multiple Bill-To records. |
Ship-To Address ID |
<ShipTo><Address addressID> |
CustomerOrder.ShipToID & CustomerOrder.ST* |
Using the Address ID to Customer Mapping table, locate the client's ERP ship-to and corresponding bill-to. |
Ship-To Address Info |
<ShipTo><Address><...> |
N/A |
The actual ship-to address information submitted in the cXML is only used if an AddressID match is not made. If that is the case, then the cXML address data is submitted into the order notes. |
Customer Purchase Order # |
<OrderRequestHeader> <Extrinsic name="CustomerPO"> |
CustomerOrder.CustomerPO |
|
Requested Ship Date |
<OrderRequestHeader> <Extrinsic name="RequestedShipDate"> |
CustomerOrder. RequestedShipDate |
|
Ship Via |
<OrderRequestHeader> <Extrinsic name="ShipVia"> |
CustomerOrder.ShipViaId |
Using the cXML value, a match to ShipVia.ErpShipCode is made. |
Order Header Notes |
<OrderRequestHeader> <Comments> |
CustomerOrder.Notes |
|
Document Type |
<OrderRequestHeader> <Extrinsic name="AttachmentFileType"> |
N/A |
|
Document BLOB |
<OrderRequestHeader> <Extrinsic name="PDFattachment"> |
PunchOutOrderRequestExtrinsic. Name = ‘PDFattachment' PunchOutOrderRequestExtrinsic. Value = [BLOB] |
Value is a base-64 version of the original PDF. |
Order Line # |
<ItemOut lineNumber> |
OrderLine.Line |
|
Order Quantity |
<ItemOut quantity> |
OrderLine.QtyOrdered |
|
Client's ERP Part # |
<ItemOut><ItemID><SupplierPartID> OR <ItemOut><ItemDetail><Extrinsic name="BuyerId"> OR <ItemOut><ItemDetail>< Extrinsic name="UPC"> OR <ItemOut><ItemDetail><ManufactuerPartID> <ItemOut><ItemDetail><ManufacturerName> OR <ItemOut><ItemDetail><ManufactuerPartID> OR Application Setting "Punchout_NotOnFileProductName" |
OrderLine.ProductId |
See Section 5.1 for further details on the sequencing & logic around Identifying a Configured Commerce Product from the cXML data. |
Unit of Measure |
<ItemDetail><UnitOfMeasure> |
OrderLine.UnitOfMeasure |
|
Unit Price |
<ItemDetail><UnitPrice><Money> OR Configured Commerce Calculated |
OrderLine.ActualPrice |
See Section 5.1 for further details on how Configured Commerce will determine the price. |
Order Line Notes |
<ItemOut><Comments> |
OrderLine.Notes |
|
Please sign in to leave a comment.