Work with the punchout server-side extension
Commerce punchout functionality is provided through SSEs that can run on the Node.js
server associated with your Commerce environment.
To use the punchout features, you must download the extensions from the 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
.
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 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 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 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 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 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 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 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 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. See Add a punchout checkout button to the Order Summary widget
for a sample widget that implements this endpoint.
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>