Skip to content
SyncMyShop

PunchOut

Magento PunchOut

Magento and Adobe Commerce have no PunchOut of their own: no endpoint for a setup request, no cXML or OCI cart and no order intake from a procurement system. They do have what a PunchOut session needs underneath: shared catalogs per company in Adobe Commerce B2B, a cart API and a purchase order payment method. We build the PunchOut side on your existing Magento store and run it.

What moves between the procurement system and Magento

A PunchOut connection on Magento has the same flows as on any store. Magento carries the catalog, the prices and the order; the PunchOut documents run in the integration next to it.

Flow Direction Where it runs
Setup request and response procurement system to the integration outside Magento, in the integration
Sign-in as the buyer's company integration to the storefront a storefront controller with a one-time identifier
Shopping at contract prices in the storefront shared catalog (B2B) or customer group prices
Cart transfer storefront to the procurement system, through the browser a checkout replacement and the integration
Purchase order procurement system to the integration to Magento REST API, order with payment method purchaseorder
Confirmation, ship notice, invoice Magento or your ERP to the procurement system the integration, as cXML

Facts on this page were checked against Adobe's Commerce documentation and the Magento source on October 3, 2026. The documents themselves are explained on cXML PunchOut and OCI PunchOut.

What Magento offers and what is built around it

Need What Magento has What is built
Endpoint for a setup request nothing the integration receives and answers it
Sign-in without a form customer tokens for the API only a controller that turns the start URL into a storefront session
Prices per buying organization custom shared catalogs (Adobe Commerce B2B); tier prices per customer group the company or group per buyer, filled from the ERP
Display in a frame X-Frame-Options: SAMEORIGIN by default redirect, or a frame-ancestors rule per buyer
Cart data the quote, with sku, qty, name and price per item a checkout replacement that sends the cart to the integration
Cart in cXML or OCI nothing the integration builds the PunchOutOrderMessage or the NEW_ITEM form
Order with a PO number payment method purchaseorder with po_number the integration maps the OrderRequest to it

Signing the buyer in

The start URL in the setup response has to open the store with the buyer already signed in as their company. Magento's REST API issues customer tokens through POST /V1/integration/customer/token, valid for 1 hour by default, but a token authorizes API calls, not the storefront. The browser needs Magento's session cookie.

The integration therefore adds a storefront route. The setup request for customer 10432 arrives, the integration stores the session with its return URL and BuyerCookie, and returns a start URL with a one-time identifier. The route checks the identifier, signs in the customer that belongs to it and opens the catalog. A used or expired identifier opens nothing. Regular customers keep the normal login page; nothing changes for them.

Prices per buying organization

In Adobe Commerce B2B, prices per company come from shared catalogs. Adobe's documentation describes two kinds:

Shared catalog Who sees it How many
Public guests and signed-in customers without a company one at a time
Custom signed-in users of the companies assigned to it as many as needed

Customer 10432 is a company in Magento with a custom shared catalog that holds item 10482 at 9.60 USD where the list price is 12.50. When the Shared Catalog feature is on, it controls all category permissions, and the existing customer group permissions are ignored. Tier prices can be set per customer group or per shared catalog, so a quantity price for this buyer sits in the same catalog.

Without B2B the same result comes from one customer group per buying organization with tier prices for that group. A store with 40 PunchOut buyers then has 40 customer groups, each filled from the ERP's price agreements by the integration.

Session lifetime and frames

Magento's default cookie lifetime is 3,600 seconds, renewed on every request, so the session ends one hour after the buyer's last click. SAP Ariba keeps a PunchOut session open for six hours. When the buyer's PHP session ends inside that window, everything stored in it is gone, including the return URL and the BuyerCookie.

A PunchOut session from SAP Ariba outlives Magento's default cookie The buyer starts at 09:03, clicks last at 09:20 and returns at 10:35. Magento's cookie of 3,600 seconds expired at 10:20. The Ariba session runs until 15:03. The integration keeps the session data for the full six hours. Buyer meeting start 09:03 back 10:35, sends cart Magento cookie, 3,600 seconds after the last click valid expired 10:20 SAP Ariba session, 6 hours open until 15:03 PunchOut session in the integration return URL and BuyerCookie kept 09:00 10:00 11:00 12:00 13:00 14:00 15:00 16:00
The PunchOut session outlives Magento's default cookie. Its data is kept outside the PHP session.

A buyer starts at 09:03, clicks for the last time at 09:20 and comes back from a 75-minute meeting at 10:35. The cookie expired at 09:20 + 60 minutes = 10:20; Ariba's session runs until 09:03 + 6 hours = 15:03. Because the integration keeps the PunchOut session in its own table, keyed to the one-time identifier and the Magento quote, the buyer signs in again through the same session and sends the cart to the right return URL.

Frames are the second point. Magento sends X-Frame-Options: SAMEORIGIN by default, set in app/etc/env.php. The ALLOW-FROM option is deprecated because the browsers Magento supports no longer honor it, and Adobe's documentation advises against running the storefront in a frame at all. The procurement system opens the store by redirect. For a buyer that only supports a frame, Magento's CSP module has a frame-ancestors directive that names the hosts allowed to embed the PunchOut pages; since 2.4.7, CSP runs in restrict mode by default only on payment pages and in report-only mode elsewhere, so the rule has to be set to enforce on these pages as well. A second obstacle sits in the session cookie: Magento sets it with SameSite=Lax by default, and a browser does not send a Lax cookie to a page framed by another site. Inside a frame on the buyer's procurement host the browser does not send the session cookie back, so the store does not keep the sign-in from one page to the next. The redirect avoids both problems.

From the Magento cart to the PunchOut cart

The checkout button is replaced by a transfer button in a PunchOut session. The integration reads the quote, here one line of the cart of Bakker Installatie B.V.:

{
  "item_id": 7,
  "sku": "10482",
  "qty": 120,
  "name": "Duplex receptacle 20 A, white",
  "price": 9.6,
  "product_type": "simple",
  "quote_id": "4"
}

What the integration does with it:

  1. price is a decimal number, not cents. 9.6 is written as 9.60 in cXML and OCI; 120 x 9.60 = 1,152.00 for the line.
  2. sku becomes SupplierPartID or NEW_ITEM-VENDORMAT. A Magento SKU can be 64 characters, OCI takes 40, so a longer SKU is caught before the cart is sent.
  3. name becomes Description; for OCI it has to fit 40 characters. This one has 29.
  4. Magento has no unit code on a product. UnitOfMeasure and the classification come from a product attribute, filled once per product.

The purchase order back into Magento

The OrderRequest arrives at the integration, which answers it and places the order through the REST API with the payment method purchaseorder. That method ships with Magento as an offline payment method and is inactive by default, so it is switched on for the store and limited to PunchOut customers.

OrderRequest Magento
orderID 4500001234 paymentMethod.po_number
buyer identity in From the customer of company 10432
ItemOut lines cart items by SKU, at the price from the cart
ShipTo shipping address
BillTo billing_address

Adobe Commerce B2B has its own purchase orders: with Enable Purchase Orders on for a company, every order becomes a purchase order that runs through that company's approval rules. In PunchOut the approval already happened in the buyer's system. The integration places the order through the API, and the setting stays off for PunchOut companies, so the order is not approved twice. For PO 4500001234 that is 3 calls to add the lines, one for the shipping information and one for the payment information that carries the PO number and returns the Magento order ID.

When it goes wrong

What happens Cause Handling
Blank frame in the procurement system X-Frame-Options: SAMEORIGIN redirect, or frame-ancestors per buyer
Cart goes to the wrong place or nowhere session data kept in the PHP session, expired after 3,600 seconds PunchOut session in the integration's own table
List price 12.50 in the cart the customer is not in the company of its shared catalog company and catalog per buying organization
Cart refused for its unit no unit attribute on the product fixed unit code per product
Order waits for approval in Magento Enable Purchase Orders on for a PunchOut company setting off; order placed through the API
Order without a PO number placed with another payment method purchaseorder with po_number

The same pieces on other platforms: Shopify, WooCommerce and BigCommerce. The Ariba session rules are on PunchOut for Ariba, and what a store needs in full is on the PunchOut hub. Tell us which procurement system your customer uses.

Frequently asked questions

Do I need Adobe Commerce for PunchOut, or does Magento Open Source work?

Both work for the session and the cart. Contract prices per company are easiest with Adobe Commerce B2B, where a custom shared catalog holds the prices for the companies assigned to it. Without B2B, prices per buyer come from customer groups with tier prices, one customer group per buying organization.

Can the procurement system show my Magento store in a frame?

Not with the default settings. Magento sends X-Frame-Options: SAMEORIGIN, set in app/etc/env.php, and the ALLOW-FROM option is deprecated. Adobe advises against running the storefront in a frame. The buyer's administrator opens the store by redirect; where a buyer only supports frames, the PunchOut pages get a frame-ancestors policy for that buyer's host.

Can I use the customer token of the REST API to sign the buyer in?

No. POST /V1/integration/customer/token gives a bearer token for API calls, valid for 1 hour by default, not a storefront session. The browser needs a session cookie, so the start URL leads to a controller that checks the one-time identifier and signs the customer in on the storefront.

Does B2B purchase order approval in Adobe Commerce get in the way?

It can. With Enable Purchase Orders on for a company, every order from that company becomes a Magento purchase order that runs through its approval rules. In PunchOut the approval happens in the buyer's procurement system, so the setting stays off for companies that buy through PunchOut, or the order from the OrderRequest is created through the API outside the storefront checkout.

How does the PO number get onto the Magento order?

Through the Purchase Order payment method, code purchaseorder, which ships with Magento and is inactive by default. The integration sets it with the po_number from the OrderRequest when it places the order through the cart's payment-information endpoint, so the number is stored with the order.

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