Work with the Punchout Server-Side Extension
Retail Digital Commerce punchout functionality is provided
through SSEs that can run on the Node.js server
associated with your Commerce environment.
![]()
This section applies to Open Storefront Framework
(OSF).
To use the punchout features, you must download the extensions
from the Retail Digital Commerce administration server. You then customize
the extension and upload it to your Node.js server. The punchout server-side extensions implement
custom REST endpoints, which have the prefix /ccstorex/custom.
Retail Digital Commerce includes punchout server-side extensions that you can download and customize for your environment. This section describes the punchout extensions that are included with Retail Digital Commerce. See in Use developer tools to customize your store for details about how to download and customize server-side extensions.
The following table describes the punchout server-side extensions.
| Server-side extension | Description |
|---|---|
punchout-app.zip |
Includes functionality that enables the punchout
flow between the procurement system and
Retail Digital Commerce. Use this sample application to customize
the default functionality provided in
the punchout-lib library.
|
punchout-lib.zip |
Supports setup, edit and complete flows for punchout in cXML standard with Retail Digital Commerce. Do not make any changes to this library. |
purchase-order-app.zip |
Includes functionality that enables the purchase
order flow between the procurement system
and Retail Digital Commerce. Use this sample application to customize
the default functionality provided in
the purchase-order-lib library.
|
purchase-order-lib.zip |
Supports submitted orders in Retail Digital Commerce from procurement system’s purchase order in cXML format. Do not make any changes to this library. |
Each ZIP file includes a readme.md file that
describes classes and endpoints and includes information about how
to install and extend the extension.
The server-side extensions provide the core punchout functionality with the following JavaScript classes. You can extend these classes, for example, to customize mappings or make additional Commerce REST API requests.
| Class Name | Description |
|---|---|
PunchOutSetup |
Provides methods to authenticate, create the shopper token, and create the shopping cart in Retail Digital Commerce if re-punchout is required. |
PunchOutComplete |
Provides methods that convert the order request
body JSON to the cXML PunchOutOrderMessage, which is sent to the procurement system.
|
PurchaseOrder |
Provides methods that call the store priceOrder endpoint, check if
prices are within tolerance limit, and create the order.
|
PunchOutUtils |
Provides utilities for functionality such as fetching SKU prices, calling Retail Digital Commerce APIs, and parsing XML. |
Work with the Punchout Endpoints
This section describes the endpoints included in the punchout server-side extension. All the endpoints are public URLs and all requests must be sent via HTTPS.
punchoutSetUp and punchoutRedirection endpoints
Issue a POST request to the /ccstorex/custom/v1/punchOut/punchOutSetUp endpoint to establish
a punchout (or re-punchout) session from the procurement system.
The request includes organization details, the shared secret key, and other relevant information. It generates the OAuth token for logging in the punchout shopper, caches the token, and generates a unique ID against it.
The GET /ccstorex/custom/v1/punchOut/punchOutRedirection/{sessionId} endpoint handles the redirection to the Retail Digital Commerce
storefront page from the procurement system. Using the uniqueID from the URL, this endpoint fetches the actual OAuth token from
the cache. A form, which has the OAuth token as the input, is automatically
submitted to the storefront home page. On submission, the storefront
extracts the OAuth token from the request body and logs the punchout
shopper into the system. The cache entry is then deleted.
Note:
For storefronts built with Open Storefront Framework, this configuration happens at the framework level at runtime.
The following example shows a sample cXML request body. In the
header, Identity is the Organization
ID and SharedSecret is the organization’s
authorization code.
<cXML>
<Header>
<Sender>
<Credential domain='organizationId'>
<Identity>or-10001</Identity>
<SharedSecret>authorization_code</SharedSecret>
</Credential>
</Sender>
</Header>
<Request>
<PunchOutSetupRequest operation='create'>
<BuyerCookie>1CX3L4843PPZO</BuyerCookie>
<BrowserFormPost>
<URL>http://localhost:1616/punchoutexit</URL>
</BrowserFormPost>
<Contact>
<Name>buyer_name</Name>
<Email>buyer_email</Email>
<Extrinsic name='lastName'>punchout</Extrinsic>
</Contact>
</PunchOutSetupRequest>
</Request>
</cXML>The following example shows a sample cXML
response, which returns the Commerce storefront URL returned by the punchoutRedirection endpoint, suffixed with the unique ID:
as form-url-encoded values:
<cXML>
<PunchOutSetupResponse>
<StartPage>
<URL>http://admin-server-hostname/ccstorex/custom/v1/punchout/punchoutRedirection/d5a3990d-1d47-4b8d-9e27-5a4d269e3efe</URL>
</StartPage>
</PunchOutSetupResponse>/
</cXML>punchoutComplete endpoint
When the punchout shopper has finished adding items to their cart and wants to return to their
procurement system, issue a POST request to the
/ccstorex/custom/v1/punchOut/punchoutComplete endpoint to
convert the order JSON to PunchOutOrderMessage cXML.
The request body is a JSON representation of the punchout shopper’s order and the response body is a cXML representation of the order. See Order submit webhook for a sample JSON representation of an order.
purchaseOrder endpoint
Issue a POST request to the
/ccstorex/custom/v1/punchOut/purchaseOrder endpoint
to convert the procurement system’s purchase order
cXML to JSON and create an order in Commerce.
By default, this server side extension supports invoice payment only, but. you can customize the extension to support other payment methods.
The following example shows a sample cXML request body.
<cXML>
<Header>
<Sender>
<Credential domain='organizationId'>
<Identity>or-100001</Identity>
<SharedSecret>key</SharedSecret>
</Credential>
</Sender>
</Header>
<Request>
<OrderRequest>
<OrderRequestHeader orderID="DO102880" orderDate="2012-08-03T08:49:09+07:00" type="new">
<Contact>
<Name>First Name</Name>
<Email>Email@example.com</Email>
<Extrinsic name='lastName'>John_Smith</Extrinsic>
<Extrinsic name='parentOrganization'>or-100001</Extrinsic>
</Contact>
<Total>
<Money currency="USD">86.50</Money>
</Total>
<ShipTo>
<Address isoCountryCode="US" addressID="1000467">
<Name xml:lang="en">Acme, Inc.</Name>
<PostalAddress name="default">
<DeliverTo>John Q. Smith</DeliverTo>
<DeliverTo>Buyers Headquarters</DeliverTo>
<Street>123 Main Street</Street>
<City>Mountain View</City>
<State>CA</State>
<PostalCode>94089</PostalCode>
<Country isoCountryCode='US'>United States</Country>
</PostalAddress>
<Email name="default">john_smith@example.com</Email>
<Phone name="work">
<TelephoneNumber>
<CountryCode isoCountryCode="United States">1</CountryCode>
<AreaOrCityCode>800</AreaOrCityCode>
<Number>5555555</Number>
</TelephoneNumber>
</Phone>
</Address>
</ShipTo>
<BillTo>
<Address isoCountryCode="US" addressID="12">
<Name xml:lang="en">Acme Accounts Payable</Name>
<PostalAddress name="default">
<Street>124 Union Street</Street>
<City>San Francisco</City>
<State>CA</State>
<PostalCode>94128</PostalCode>
<Country isoCountryCode="US">United States</Country>
</PostalAddress>
<Phone name="work">
<TelephoneNumber>
<CountryCode isoCountryCode="US">1</CountryCode>
<AreaOrCityCode>415</AreaOrCityCode>
<Number>6666666</Number>
</TelephoneNumber>
</Phone>
</Address>
</BillTo>
<Shipping>
<Money currency="USD">10.00</Money>
<Description xml:lang="en-US">FedEx 2-day</Description>
</Shipping>
<Tax>
<Money currency="USD">1.5</Money>
<Description xml:lang="en">CA State Tax</Description>
</Tax>
</OrderRequestHeader>
<ItemOut quantity="2" lineNumber="1">
<ItemID>
<SupplierPartID>Camera_1002</SupplierPartID>
<SupplierPartAuxiliaryID>SKU_3005A</SupplierPartAuxiliaryID>
</ItemID>
<ItemDetail>
<UnitPrice>
<Money currency="USD">10</Money>
</UnitPrice>
<Description xml:lang="en">Laptop Notebook, 300 MHz</Description>
<UnitOfMeasure>EA</UnitOfMeasure>
<Classification domain="UNSPSC">43171801</Classification>
<URL>http://www.example.com/Punchout.asp</URL>
<Extrinsic name="ExtDescription">Enhanced keyboard</Extrinsic>
</ItemDetail>
<Shipping>
<Money currency="USD">10.00</Money>
<Description xml:lang="en-US">standardShippingMethod</Description>
</Shipping>
<ShipTo>
<Address isoCountryCode="US" addressID="1000467">
<Name xml:lang="en">Acme, Inc.</Name>
<Email name="default">john_smith@exmaple.com</Email>
<Phone name="work">
<TelephoneNumber>
<CountryCode isoCountryCode="United States">1</CountryCode>
<AreaOrCityCode>800</AreaOrCityCode>
<Number>5555555</Number>
</TelephoneNumber>
</Phone>
<PostalAddress name="default">
<DeliverTo>John Q. Smith</DeliverTo>
<DeliverTo>Buyers Headquarters</DeliverTo>
<Street>123 Main Street</Street>
<City>Mountain View</City>
<State>CA</State>
<PostalCode>94089</PostalCode>
<Country isoCountryCode="US">United States</Country>
</PostalAddress>
</Address>
</ShipTo>
<Distribution>
<Accounting name="DistributionCharge">
<AccountingSegment id="7720">
<Name xml:lang="en-US">Account</Name>
<Description xml:lang="en-US">Office Supplies</Description>
</AccountingSegment>
<AccountingSegment id="610">
<Name xml:lang="en-US">Cost Center</Name>
<Description xml:lang="en-US">Engineering Mgt</Description>
</AccountingSegment>
</Accounting>
<Charge>
<Money currency="USD">20.00</Money>
<!--<Percentage percent="20"/>
<Money currency="USD">0.00</Money>-->
</Charge>
</Distribution>
<Tolerances>
<PriceTolerance>
<Money currency="USD">100.00</Money>
</PriceTolerance>
</Tolerances>
</ItemOut>
</OrderRequest>
</Request>
</cXML>
The following example shows a sample cXML response body for the previous request.
<cXML>
<Response>
<Status code="200" text="OK. Order ID: o30630"/>
</Response>
</cXML>