[{"data":1,"prerenderedAt":735},["ShallowReactive",2],{"blog-b2b-punchout-cxml-oci-en":3},{"slug":4,"published":5,"minutes":6,"category":7,"tags":8,"keywords":14,"about":25,"sources":34,"cover":67,"og":68,"expertise":69,"locales":70,"lang":71,"title":74,"description":75,"coverAlt":76,"metaTitle":77,"takeaways":78,"faq":84,"toc":100,"blocks":128,"others":462},"b2b-punchout-cxml-oci","2026-10-08",8,"web",[9,10,11,12,13],"Punchout","cXML","SAP OCI","eProcurement","B2B shop",[15,16,17,18,19,20,21,22,23,24],"punchout catalog","cxml punchout","sap oci interface","oci roundtrip","punchout setup request","secure oci","level 2 punchout","eprocurement punchout integration","punchout2go tradecentric","punchout catalog integration",[26,29,31],{"name":27,"url":28},"Procurement","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FProcurement",{"name":10,"url":30},"https:\u002F\u002Fcxml.org\u002F",{"name":32,"url":33},"E-procurement","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FE-procurement",[35,37,40,43,46,49,52,55,58,61,64],{"title":36,"url":30},"cXML.org (cXML 1.2.071)",{"title":38,"url":39},"PunchOutCommerce: cXML PunchOutSetupRequest","https:\u002F\u002Fpunchoutcommerce.com\u002Fguides\u002Fpunchout\u002Fcxml-punchout-setup-request\u002F",{"title":41,"url":42},"PunchOutCommerce: cXML PunchOutOrderMessage","https:\u002F\u002Fpunchoutcommerce.com\u002Fguides\u002Fpunchout\u002Fcxml-punchout-order-message\u002F",{"title":44,"url":45},"PunchOutCommerce: OCI RoundTrip","https:\u002F\u002Fpunchoutcommerce.com\u002Fguides\u002Fpunchout\u002Foci-roundtrip\u002F",{"title":47,"url":48},"SAP: Open Catalog Interface 5.0","https:\u002F\u002Fhelp.sap.com\u002Fdoc\u002Fsrm\u002F1.0\u002Fen-US\u002Fattachments\u002F3362936504\u002FOCI_50_EN20130121.pdf",{"title":50,"url":51},"SAP Help: OCI catalogs in S\u002F4HANA Plant Maintenance","https:\u002F\u002Fhelp.sap.com\u002Fdocs\u002FSAP_S4HANA_ON-PREMISE\u002F79e86803745943368f3beb4a7d0bca2a\u002F1dcfb65334e6b54ce10000000a174cb4.html",{"title":53,"url":54},"Mercateo\u002FUnite: technical information on the OCI interface","https:\u002F\u002Fwww.mercateo.com\u002Fsupport\u002Fwp-content\u002Fuploads\u002F2025\u002F02\u002FTechnical-Information-on-the-OCI-Interface-2.7-EN.pdf",{"title":56,"url":57},"Amazon Business: punchout integration instructions","https:\u002F\u002Fstatic-assets.business.amazon.com\u002Fassets\u002Fglobal\u002Fdocuments\u002Fguides\u002FAmazon-Business-Punchout-Integration-Instructions.pdf",{"title":59,"url":60},"Amazon Business: punchout","https:\u002F\u002Fbusiness.amazon.com\u002Fen\u002Fsolutions\u002Fsystems-integration\u002Fpunchout",{"title":62,"url":63},"TradeCentric: pricing","https:\u002F\u002Ftradecentric.com\u002Fpricing\u002F",{"title":65,"url":66},"OWASP: XML External Entity Prevention Cheat Sheet","https:\u002F\u002Fcheatsheetseries.owasp.org\u002Fcheatsheets\u002FXML_External_Entity_Prevention_Cheat_Sheet.html","\u002Fimages\u002Fblog\u002Fb2b-punchout-cxml-oci\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fb2b-punchout-cxml-oci\u002Fog.jpg","b2b-ecommerce-developer",[71,72,73],"en","de","hu","Punchout catalogs explained: cXML, SAP OCI and the round trip to the buyer’s ERP","How punchout catalogs work: the cXML PunchOut and SAP OCI round trips, Secure OCI, what a supplier shop must implement, and when to buy a gateway.","A cart travels from one building to another and returns filled.","Punchout catalogs: cXML and SAP OCI · Balázs Csorba",[79,80,81,82,83],"A punchout catalog lets a buyer shop on the supplier’s site from inside their procurement system; the cart returns as a requisition, and the purchase order follows only after approval.","In cXML, a PunchOutSetupRequest opens the session, the response returns a StartPage URL, and the cart comes back as a PunchOutOrderMessage posted from the shopper’s browser.","SAP OCI returns the cart as hidden NEW_ITEM fields in an HTML form posted to the HOOK_URL, and covers only catalog and shopping, not orders or invoices.","The supplier shop must bind sessions, validate and harden XML parsing against external entities, return proper status codes, and round-trip identifiers such as SupplierPartAuxiliaryID.","As of October 2026, TradeCentric publishes supplier pricing starting at $15,000 to $50,000 a year with a three-year minimum, the benchmark for a build-versus-buy decision.",[85,88,91,94,97],{"q":86,"a":87},"What is a punchout catalog?","A punchout catalog is a supplier web shop opened from inside a buyer’s procurement system. The buyer shops with the supplier’s search, configuration and contract prices, then returns the cart to the procurement system, where it becomes a requisition, goes through approval and is sent back to the supplier as a purchase order.",{"q":89,"a":90},"What is the difference between cXML punchout and SAP OCI?","cXML punchout uses XML documents: a server-to-server setup request and response, then a cart returned as a PunchOutOrderMessage through the browser. SAP OCI uses HTML forms: the catalog is called with URL or form parameters and the cart returns as hidden NEW_ITEM fields. cXML also covers orders and invoices; OCI covers only shopping.",{"q":92,"a":93},"What is Secure OCI?","Secure OCI is a variant described in SAP’s OCI 5.0 specification where the procurement system first calls the catalog backend server to server to initialize a session, receiving a session id, and the browser launch then carries only that session id instead of the user name and password.",{"q":95,"a":96},"What does a supplier need to implement for cXML punchout?","A setup endpoint that authenticates the sender, stores the request under a short-lived session id and returns a StartPage URL; a shop session bound to that request; a cart return that posts a PunchOutOrderMessage with the original BuyerCookie; hardened XML parsing; proper status codes; and an order endpoint that accepts the later OrderRequest.",{"q":98,"a":99},"Should a B2B shop build punchout itself or use a gateway?","Use a gateway when many buyers on different procurement systems need connecting quickly, or when certification and support matter more than cost. Build when you have a few large buyers on known systems and an engineering team that can own XML security, testing and per-buyer quirks. Compare against published gateway pricing.",[101,104,107,110,113,116,119,122,125],{"id":102,"title":103},"what-punchout-solves","What problem does punchout solve?",{"id":105,"title":106},"the-cxml-punchout-round-trip","How does the cXML PunchOut round trip work?",{"id":108,"title":109},"sap-oci-plain-and-secure","How does SAP OCI work, plain and secure?",{"id":111,"title":112},"what-your-shop-must-implement","What must the supplier shop implement?",{"id":114,"title":115},"who-asks-for-punchout","Who asks for punchout?",{"id":117,"title":118},"build-vs-buy-gateways","Should you build punchout or buy a gateway?",{"id":120,"title":121},"when-punchout-is-wrong","When is punchout the wrong tool?",{"id":123,"title":124},"punchout-go-live-checklist","A punchout go-live checklist",{"id":126,"title":127},"sources","Sources",[129,137,140,143,146,149,150,158,164,167,207,210,211,220,224,226,237,248,303,304,307,334,344,358,359,365,372,373,379,382,385,386,389,402,403,419,426,427],{"type":130,"content":131},"paragraph",[132,133,136],"A ",{"tag":134,"children":135},"strong",[15]," is a supplier’s web shop opened from inside a buyer’s procurement system. The buyer uses the supplier’s search, configuration and contract prices, then sends the cart back to their own system, where it becomes a requisition, goes through approval and returns to the supplier as a purchase order. Buying happens in the shop; control, budgets and approvals stay with the buyer.",{"type":130,"content":138},[139],"This article explains the two protocols that carry this round trip, cXML PunchOut and SAP’s Open Catalog Interface, including Secure OCI, what a supplier shop has to implement and harden, who asks for punchout, what a gateway costs compared with building it, when punchout is the wrong tool, and a go-live checklist.",{"type":141,"level":142,"id":102,"text":103},"heading",2,{"type":130,"content":144},[145],"It lets large buyers keep their purchasing rules while using the supplier’s shop. Procurement departments want every purchase to pass through their own system for budgets, cost centers and approvals, but they do not want to maintain the supplier’s catalog, configurator and contract prices themselves. Punchout splits the job: the supplier runs the shopping experience, the buyer’s system owns the decision.",{"type":130,"content":147},[148],"That is why punchout often appears as a contract condition in enterprise and public-sector deals. For the supplier it changes what “done” means: the shop is no longer the end of the purchase, it is a stop in the middle of someone else’s process, and every line in the returned cart has to be something the buyer’s ERP can post.",{"type":141,"level":142,"id":105,"text":106},{"type":130,"content":151},[152,153,157],"Three cXML messages carry it: a PunchOutSetupRequest and its response open the session server to server, and a PunchOutOrderMessage brings the cart back through the shopper’s browser. cXML is maintained at cxml.org, current version 1.2.071 as of August 2026, and also covers catalogs, orders, confirmations, ship notices and invoices (",{"tag":154,"href":30,"children":155},"a",[156],"cXML.org",").",{"type":159,"src":160,"alt":161,"wide":162,"caption":163},"image","\u002Fimages\u002Fblog\u002Fb2b-punchout-cxml-oci\u002Fdiagram-7.webp","cXML PunchOut round trip Six steps from left to right: the buyer’s procurement system sends a PunchOutSetupRequest with a BuyerCookie; the supplier shop answers with a PunchOutSetupResponse containing a StartPage URL; the shopper browses in a shop session; the cart returns as a PunchOutOrderMessage posted by the shopper’s browser to the BrowserFormPost URL; the requisition goes through approval in the buyer’s system; and only then does an OrderRequest reach the supplier. The returned cart is a quote, not an order.",true,"The cXML PunchOut round trip: the cart comes back through the shopper’s browser as a quote, and the purchase order arrives later as a separate OrderRequest after the buyer’s approval.",{"type":165,"code":166},"code","\u003CcXML payloadID=\"1760600000.4711@buyer.example\" timestamp=\"2026-10-08T09:12:00+02:00\">\n  \u003CHeader>\n    \u003CFrom>\u003CCredential domain=\"NetworkID\">\u003CIdentity>BUYER-123\u003C\u002FIdentity>\u003C\u002FCredential>\u003C\u002FFrom>\n    \u003CTo>\u003CCredential domain=\"DUNS\">\u003CIdentity>SUPPLIER-456\u003C\u002FIdentity>\u003C\u002FCredential>\u003C\u002FTo>\n    \u003CSender>\n      \u003CCredential domain=\"NetworkID\">\n        \u003CIdentity>BUYER-123\u003C\u002FIdentity>\n        \u003CSharedSecret>…\u003C\u002FSharedSecret>\n      \u003C\u002FCredential>\n      \u003CUserAgent>Procurement 2026\u003C\u002FUserAgent>\n    \u003C\u002FSender>\n  \u003C\u002FHeader>\n  \u003CRequest>\n    \u003CPunchOutSetupRequest operation=\"create\">\n      \u003CBuyerCookie>8f3c1a…\u003C\u002FBuyerCookie>\n      \u003CExtrinsic name=\"UserEmail\">p.huber@buyer.example\u003C\u002FExtrinsic>\n      \u003CBrowserFormPost>\u003CURL>https:\u002F\u002Fprocurement.buyer.example\u002Fpunchout\u002Freturn\u003C\u002FURL>\u003C\u002FBrowserFormPost>\n    \u003C\u002FPunchOutSetupRequest>\n  \u003C\u002FRequest>\n\u003C\u002FcXML>",{"type":168,"ordered":169,"items":170},"list",false,[171,191,196],[172,175,176,179,180,183,184,187,188,157],{"tag":134,"children":173},[174],"Setup request:"," carries ",{"tag":165,"children":177},[178],"operation=\"create\"",", ",{"tag":165,"children":181},[182],"inspect"," or ",{"tag":165,"children":185},[186],"edit",", a BuyerCookie the buyer uses to match the returned cart to the user, and the BrowserFormPost URL where the cart must go; user details arrive as Extrinsic elements or a Contact, and vary per procurement system (",{"tag":154,"href":39,"children":189},[190],"PunchOutCommerce",[192,195],{"tag":134,"children":193},[194],"Setup response:"," a Status of 200 and a StartPage URL that logs the shopper in. A sound pattern is to store the request under a random session id, validate it when the shopper arrives, and expire unused ids after about five minutes.",[197,200,201,204,205,157],{"tag":134,"children":198},[199],"Cart return:"," an HTML form posted by the browser to the BrowserFormPost URL with the cXML in a hidden field named ",{"tag":165,"children":202},[203],"cXML-urlencoded",". The PunchOutOrderMessage must echo the BuyerCookie, and each ItemIn carries quantity, SupplierPartID, unit price, description and unit of measure (",{"tag":154,"href":42,"children":206},[190],{"type":130,"content":208},[209],"Two details cause most production bugs. The returned cart is a quote, not an order; the real order arrives later as a cXML OrderRequest, and the SupplierPartAuxiliaryID you put on each line must come back on that order unchanged, because it is often the only link to a configured item or a contract price. And the BuyerCookie is not authentication: it passes through the supplier, so buyers should not trust it alone on return, and suppliers must never put secrets in it.",{"type":141,"level":142,"id":108,"text":109},{"type":130,"content":212},[213,214,217,218,157],"OCI is an HTML-form protocol: SAP launches the catalog URL with parameters, and the catalog returns the cart as hidden form fields posted to a return address. The launch typically carries USERNAME and PASSWORD, the required HOOK_URL where the cart must go, and ",{"tag":165,"children":215},[216],"~TARGET"," for the form target in framed sessions; credentials belong in a POST body, because a GET exposes them in URLs and logs (",{"tag":154,"href":45,"children":219},[190],{"type":159,"src":221,"alt":222,"wide":162,"caption":223},"\u002Fimages\u002Fblog\u002Fb2b-punchout-cxml-oci\u002Fdiagram-13.webp","SAP OCI RoundTrip Four steps from left to right: a button in SAP launches the catalog URL with parameters such as USERNAME, PASSWORD and HOOK_URL; the shopper browses in a catalog session; the cart is built as an HTML form with hidden NEW_ITEM fields; and the browser posts that form to the HOOK_URL, back into SAP. In Secure OCI, SAP first calls the catalog backend server to server with an INITIALIZE function to obtain a session id, and the browser launch carries only that id.","The OCI RoundTrip: credentials and the return address travel as form parameters, and the cart returns as hidden fields; Secure OCI replaces the credentials with a server-issued session id.",{"type":165,"code":225},"\u003Cform method=\"post\" action=\"{HOOK_URL from the launch request}\" target=\"{~TARGET}\">\n  \u003Cinput type=\"hidden\" name=\"NEW_ITEM-DESCRIPTION[1]\" value=\"Cable gland M20x1.5 IP68\">\n  \u003Cinput type=\"hidden\" name=\"NEW_ITEM-QUANTITY[1]\"    value=\"50\">\n  \u003Cinput type=\"hidden\" name=\"NEW_ITEM-UNIT[1]\"        value=\"PCE\">\n  \u003Cinput type=\"hidden\" name=\"NEW_ITEM-PRICE[1]\"       value=\"1.84\">\n  \u003Cinput type=\"hidden\" name=\"NEW_ITEM-CURRENCY[1]\"    value=\"EUR\">\n  \u003Cinput type=\"hidden\" name=\"NEW_ITEM-VENDORMAT[1]\"   value=\"70.112.04\">\n  \u003Cbutton type=\"submit\">Transfer cart\u003C\u002Fbutton>\n\u003C\u002Fform>",{"type":130,"content":227},[228,229,232,233,236],"Fields are named ",{"tag":165,"children":230},[231],"NEW_ITEM-*",", such as DESCRIPTION, QUANTITY, UNIT, PRICE, CURRENCY, VENDORMAT and MANUFACTMAT, limited to 255 characters each, with custom fields up to 1,000 according to Unite’s technical documentation (",{"tag":154,"href":54,"children":234},[235],"Mercateo\u002FUnite","). The scope matters: the OCI RoundTrip covers only catalog and shopping. Electronic orders, confirmations, ship notices and invoices are not part of the specification and travel over other channels such as IDocs or EDI.",{"type":130,"content":238},[239,240,243,244,247],"Secure OCI removes credentials from the browser. In SAP’s OCI 5.0 specification, the procurement system first calls the catalog backend server to server, using parameters such as SECURE_AUTH_URL and the function INITIALIZE, which returns a SessionId and a SessionTransmissionId; the browser launch then carries only the session id (",{"tag":154,"href":48,"children":241},[242],"SAP OCI 5.0","). Two caveats: OCI 5.0 is a 2012 SRM document and the latest SAP OCI specification found, and current S\u002F4HANA documentation for the Plant Maintenance catalog scenario still says it supports only OCI 3.0 and below (",{"tag":154,"href":51,"children":245},[246],"SAP Help","). Ask each buyer which version their system calls.",{"type":249,"head":250,"rows":259},"table",[251,253,255,257],[252],"Aspect",[254],"cXML PunchOut",[256],"OCI RoundTrip",[258],"Secure OCI",[260,269,278,286,294],[261,263,265,267],[262],"Transport",[264],"XML over HTTPS, server to server, then browser",[266],"HTML forms through the browser",[268],"server-to-server init, then browser",[270,272,274,276],[271],"Authentication",[273],"shared secret or certificate in the header",[275],"USERNAME, PASSWORD parameters",[277],"session id from INITIALIZE",[279,281,283,285],[280],"Cart return",[282],"PunchOutOrderMessage in a hidden field",[284],"hidden NEW_ITEM-* fields",[284],[287,289,291,293],[288],"Orders, invoices",[290],"covered by cXML",[292],"not covered",[292],[295,297,299,301],[296],"Typical buyers",[298],"SAP Ariba, Coupa, Jaggaer, Oracle",[300],"SAP SRM and S\u002F4HANA",[302],"SAP systems on OCI 5.0",{"type":141,"level":142,"id":111,"text":112},{"type":130,"content":305},[306],"A setup endpoint, a session that is bound to the setup request, a cart return in both formats if you serve both kinds of buyers, an order endpoint for cXML, and the discipline around them: validation, error codes, logging and data quality. Most of the work is in the details buyers notice only when they fail.",{"type":168,"ordered":169,"items":308},[309,314,319,324,329],[310,313],{"tag":134,"children":311},[312],"Status codes:"," answer 400 for a missing or unparsable body, 401 for an invalid sender or shared secret, and 500 for unhandled errors, as a cXML Status element.",[315,318],{"tag":134,"children":316},[317],"Session binding:"," one setup request, one session, short expiry, and the BuyerCookie stored server side so the cart returns to the right requisition.",[320,323],{"tag":134,"children":321},[322],"Identifiers:"," unique payloadIDs on every message, and SupplierPartAuxiliaryID or VENDORMAT values that your order import can resolve later.",[325,328],{"tag":134,"children":326},[327],"Item data quality:"," units of measure, classification codes and contract SKUs that the buyer’s ERP accepts. A line the ERP cannot post becomes a support call.",[330,333],{"tag":134,"children":331},[332],"Logging:"," keep every inbound and outbound document per session, so a failed requisition can be replayed and explained.",{"type":335,"variant":336,"title":337,"body":338},"callout","warn","Harden the XML parser",[339],[340,341,157],"cXML endpoints parse XML from outside your company, which makes them a classic target for external entity attacks. Follow the OWASP guidance: disable DTDs or reject any DOCTYPE, disable external entity resolution and external DTD loading, and treat a parser that cannot be configured this way as a failed deployment (",{"tag":154,"href":66,"children":342},[343],"OWASP",{"type":130,"content":345},[346,347,352,353,357],"In more than ten years of B2B commerce and PIM work with Spryker and Pimcore, I have found that punchout turns catalog data quality, units, part numbers, contract SKUs and classification codes, into a failure the customer sees inside their own ERP. It is as much a PIM conversation as a protocol one; the data side is covered in ",{"tag":348,"to":349,"children":350},"link","\u002Fblog\u002Fpimcore-erp-delta-sync",[351],"the Pimcore ERP delta sync",". Configured products are a common punchout use case too, and the configurator rules are their own problem, see ",{"tag":348,"to":354,"children":355},"\u002Fblog\u002Fheadless-product-configurator-b2b",[356],"headless product configurators for B2B",".",{"type":141,"level":142,"id":114,"text":115},{"type":130,"content":360},[361,362,157],"Enterprise buyers on SAP Ariba, Coupa, Jaggaer or Oracle procurement, SAP customers with SRM or S\u002F4HANA catalogs, and public-sector buyers through marketplaces. Amazon Business is a useful indicator of how standard this is: it integrates with more than 200 e-procurement systems, describes punchout as typically the first integration, and runs both cXML and OCI endpoints (",{"tag":154,"href":60,"children":363},[364],"Amazon Business",{"type":130,"content":366},[367,368,371],"Its supplier-facing rules are a good model for your own: a user email is mandatory in the setup request, the returned Supplier Part Auxiliary ID must come back on the purchase order, payload IDs must be unique, only new orders are supported, and orders run in a test mode before going live (",{"tag":154,"href":57,"children":369},[370],"Amazon Business integration guide","). “Level 2” punchout, where the buyer’s system holds a searchable index of your items and the setup request lands the shopper directly on a product page, is Ariba and marketplace terminology rather than part of the OCI specification.",{"type":141,"level":142,"id":117,"text":118},{"type":130,"content":374},[375,376,157],"Buy when you need many buyers on many procurement systems quickly; build when you have a few large buyers on known systems and a team that can own the protocol. A gateway sells pre-built connections and the per-buyer quirks. TradeCentric, formerly PunchOut2Go, publishes supplier pricing starting at $15,000 to $50,000 a year for its mid-market tier with a minimum three-year contract, enterprise by quote, and claims more than 220 ERP and e-procurement integrations as of October 2026 (",{"tag":154,"href":63,"children":377},[378],"TradeCentric",{"type":130,"content":380},[381],"A do-it-yourself layer honestly requires a setup endpoint per protocol, session handling, cart serialization in two formats, an order importer, hardened XML parsing, per-buyer test accounts, and someone who answers when a buyer’s procurement team changes a field mapping. Compare that ongoing ownership with the gateway price for the number of buyers you expect in three years, not this year.",{"type":130,"content":383},[384],"Whichever way you choose, keep the protocol layer separate from the shop core. The shop should expose a clean internal API for “start a session for this buyer user”, “serialize this cart” and “import this order”, and the cXML or OCI adapters, or the gateway, should sit outside it. That keeps a change in one buyer’s procurement system from reaching your checkout code, and it makes a later switch between building and buying a contained project rather than a rewrite.",{"type":141,"level":142,"id":120,"text":121},{"type":130,"content":387},[388],"When the buyer only needs your items and prices inside their system, a hosted catalog file may be enough; when you already exchange orders with a known partner, an API or EDI link is simpler. Punchout is a session and user-experience protocol, not a data model, so it does not fix product data and adds a browser step that has to work in the buyer’s environment, including framed sessions and their cookie behavior in current browsers.",{"type":130,"content":390},[391,392,396,397,401],"Agent protocols are the other boundary. UCP, ACP and AP2 assume a software agent buying on someone’s behalf, with different payloads and governance; punchout assumes a person in the buyer’s ERP. Both can coexist, and the comparison is in ",{"tag":348,"to":393,"children":394},"\u002Fblog\u002Fagentic-commerce-protocols-ucp-acp-guide",[395],"the UCP, ACP and AP2 guide"," and in ",{"tag":348,"to":398,"children":399},"\u002Fblog\u002Fprocurement-agent-buyer-side",[400],"agentic commerce readiness for B2B shops",", which treats punchout as the supported enterprise path today.",{"type":141,"level":142,"id":123,"text":124},{"type":168,"ordered":162,"items":404},[405,407,409,411,413,415,417],[406],"Get a test account in the buyer’s procurement system and per-buyer credentials.",[408],"Collect sample payloads for create, edit and inspect, and for every buyer-specific Extrinsic.",[410],"Test the cart return end to end in a real browser; I script this round trip with Playwright MCP, because the browser form post is the part unit tests cannot cover.",[412],"Verify that SupplierPartAuxiliaryID or VENDORMAT survives into the purchase order and your order import.",[414],"Run failure drills: wrong shared secret, expired session, malformed XML, a DOCTYPE in the payload.",[416],"Monitor setup latency, cart-return failures and orders that reference unknown items.",[418],"Finish with a buyer acceptance test that posts a real requisition through approval.",{"type":130,"content":420},[421,422,357],"If you are adding punchout to a B2B shop or deciding between a gateway and your own layer, see my ",{"tag":348,"to":423,"children":424},"\u002Fexpertise\u002Fb2b-ecommerce-developer",[425],"B2B e-commerce work",{"type":141,"level":142,"id":126,"text":127},{"type":168,"ordered":162,"items":428},[429,432,435,438,441,444,447,450,453,456,459],[430],{"tag":154,"href":30,"children":431},[36],[433],{"tag":154,"href":39,"children":434},[38],[436],{"tag":154,"href":42,"children":437},[41],[439],{"tag":154,"href":45,"children":440},[44],[442],{"tag":154,"href":48,"children":443},[47],[445],{"tag":154,"href":51,"children":446},[50],[448],{"tag":154,"href":54,"children":449},[53],[451],{"tag":154,"href":57,"children":452},[56],[454],{"tag":154,"href":60,"children":455},[59],[457],{"tag":154,"href":63,"children":458},[62],[460],{"tag":154,"href":66,"children":461},[65],[463,537,593,667],{"slug":464,"published":465,"minutes":466,"category":7,"tags":467,"keywords":473,"about":485,"sources":494,"cover":531,"og":532,"expertise":69,"locales":533,"lang":71,"title":534,"description":535,"coverAlt":536},"schema-org-structured-data-b2b-shop","2026-10-17",10,[468,469,470,471,472],"Schema.org","Structured data","B2B e-commerce","Technical SEO","Nuxt",[474,475,476,477,478,479,480,481,482,483,484],"schema.org b2b shop","product structured data b2b","merchant listing structured data","product snippet vs merchant listing","unitpricespecification referencequantity","productgroup variants structured data","organization schema vatid","b2b prices behind login seo","json-ld nuxt schema org","merchant return policy structured data","mpn gtin structured data",[486,488,491],{"name":468,"url":487},"https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FSchema.org",{"name":489,"url":490},"JSON-LD","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FJSON-LD",{"name":492,"url":493},"Business-to-business","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FBusiness-to-business",[495,498,501,504,507,510,513,516,519,522,525,528],{"title":496,"url":497},"Google Search Central: Introduction to Product structured data","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Fproduct",{"title":499,"url":500},"Google Search Central: Merchant listing (Product, Offer) structured data","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Fmerchant-listing",{"title":502,"url":503},"Google Search Central: Product snippet structured data","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Fproduct-snippet",{"title":505,"url":506},"Google Search Central: Product variant structured data","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Fproduct-variants",{"title":508,"url":509},"Google Search Central: Organization structured data","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Forganization",{"title":511,"url":512},"Google Search Central: Merchant return policy structured data","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Freturn-policy",{"title":514,"url":515},"Google Search Central: General structured data guidelines","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Fsd-policies",{"title":517,"url":518},"Google Search Central: Generate structured data with JavaScript","https:\u002F\u002Fdevelopers.google.com\u002Fsearch\u002Fdocs\u002Fappearance\u002Fstructured-data\u002Fgenerate-structured-data-with-javascript",{"title":520,"url":521},"Schema.org: Offer","https:\u002F\u002Fschema.org\u002FOffer",{"title":523,"url":524},"Schema.org: UnitPriceSpecification","https:\u002F\u002Fschema.org\u002FUnitPriceSpecification",{"title":526,"url":527},"Unhead: Product schema (defineProduct)","https:\u002F\u002Funhead.unjs.io\u002Fdocs\u002Fschema-org\u002Fapi\u002Fschema\u002Fproduct",{"title":529,"url":530},"Nuxt SEO: Schema.org identity setup","https:\u002F\u002Fnuxtseo.com\u002Fdocs\u002Fschema-org\u002Fguides\u002Fsetup-identity","\u002Fimages\u002Fblog\u002Fschema-org-structured-data-b2b-shop\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fschema-org-structured-data-b2b-shop\u002Fog.jpg",[71,72,73],"Schema.org structured data for B2B shops: prices behind logins, units and variants","Product markup for B2B shops: snippet or merchant listing, which price to publish, part numbers, unit pricing, variants, Organization and SSR in Nuxt.","A product rectangle with a framed outline and a small price slot hidden behind a low wall.",{"slug":538,"published":465,"minutes":539,"category":7,"tags":540,"keywords":545,"about":557,"sources":565,"cover":587,"og":588,"expertise":69,"locales":589,"lang":71,"title":590,"description":591,"coverAlt":592},"ai-assistant-b2b-shop-customer-support",9,[470,541,542,543,544],"AI assistant","Customer support","LLM agents","EU AI Act",[546,547,548,549,550,551,552,553,554,555,556],"ai assistant b2b shop","ai customer support b2b ecommerce","llm chatbot order status","ai agent customer service tools","chatbot liability air canada","klarna ai assistant results","human handoff chatbot design","eu ai act chatbot disclosure","owasp excessive agency","ai support resolution rate","b2b customer portal chatbot",[558,561,564],{"name":559,"url":560},"Customer service","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FCustomer_service",{"name":562,"url":563},"Chatbot","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FChatbot",{"name":492,"url":493},[566,569,572,575,578,581,584],{"title":567,"url":568},"Klarna: AI assistant handles two-thirds of customer service chats in its first month (press release, 2024)","https:\u002F\u002Fwww.klarna.com\u002Finternational\u002Fpress\u002Fklarna-ai-assistant-handles-two-thirds-of-customer-service-chats-in-its-first-month\u002F",{"title":570,"url":571},"Entrepreneur: Klarna is hiring customer service agents again, according to its CEO (May 2025)","https:\u002F\u002Fwww.entrepreneur.com\u002Fbusiness-news\u002Fklarna-ceo-reverses-course-by-hiring-more-humans-not-ai\u002F491396",{"title":573,"url":574},"ABA Business Law Today: BC tribunal confirms companies remain liable for information provided by AI chatbot","https:\u002F\u002Fwww.americanbar.org\u002Fgroups\u002Fbusiness_law\u002Fresources\u002Fbusiness-law-today\u002F2024-february\u002Fbc-tribunal-confirms-companies-remain-liable-information-provided-ai-chatbot\u002F",{"title":576,"url":577},"OWASP GenAI Security Project: LLM06:2025 Excessive Agency","https:\u002F\u002Fgenai.owasp.org\u002Fllmrisk\u002Fllm062025-excessive-agency\u002F",{"title":579,"url":580},"OWASP GenAI Security Project: LLM05:2025 Improper Output Handling","https:\u002F\u002Fgenai.owasp.org\u002Fllmrisk\u002Fllm052025-improper-output-handling\u002F",{"title":582,"url":583},"EU AI Act, Article 50: Transparency obligations","https:\u002F\u002Fartificialintelligenceact.eu\u002Farticle\u002F50\u002F",{"title":585,"url":586},"Intercom: Fin pricing and billable outcomes","https:\u002F\u002Ffin.ai\u002Fpricing","\u002Fimages\u002Fblog\u002Fai-assistant-b2b-shop-customer-support\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fai-assistant-b2b-shop-customer-support\u002Fog.jpg",[71,72,73],"An AI assistant for B2B shop support: tools, permissions and the human handoff","How to build an AI support assistant for a B2B shop: which requests to automate, tools that run in the customer context, handoff, AI Act and metrics.","A tall wall with one narrow gap; an arrow passes through it into a boxed enclosure of three squares, and another leads down to a tray.",{"slug":594,"published":465,"minutes":595,"category":7,"tags":596,"keywords":601,"about":613,"sources":623,"cover":660,"og":661,"expertise":662,"locales":663,"lang":71,"title":664,"description":665,"coverAlt":666},"vue-ai-chat-ui-streaming-accessibility",11,[597,472,598,599,600],"Vue","Accessibility","Streaming","AI chat",[602,603,604,605,606,607,608,609,610,611,612],"vue ai chat ui","nuxt llm streaming","sse vs fetch streaming","aria-live streaming text","accessible chat interface","abort fetch stream vue","dompurify markdown llm","role log chat","reduced motion chat ui","wcag 2.2 chat","screen reader streaming",[614,617,620],{"name":615,"url":616},"Web accessibility","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FWeb_accessibility",{"name":618,"url":619},"Server-sent events","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FServer-sent_events",{"name":621,"url":622},"Vue.js","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FVue.js",[624,627,630,633,636,639,642,645,648,651,654,657],{"title":625,"url":626},"MDN: Using server-sent events","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FServer-sent_events\u002FUsing_server-sent_events",{"title":628,"url":629},"MDN: AbortController","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FAbortController",{"title":631,"url":632},"MDN: ReadableStream","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FReadableStream",{"title":634,"url":635},"MDN: TextDecoderStream","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAPI\u002FTextDecoderStream",{"title":637,"url":638},"MDN: ARIA log role","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FAccessibility\u002FARIA\u002FReference\u002FRoles\u002Flog_role",{"title":640,"url":641},"W3C: Understanding SC 4.1.3 Status Messages","https:\u002F\u002Fwww.w3.org\u002FWAI\u002FWCAG22\u002FUnderstanding\u002Fstatus-messages.html",{"title":643,"url":644},"W3C WAI: What's new in WCAG 2.2","https:\u002F\u002Fwww.w3.org\u002FWAI\u002Fstandards-guidelines\u002Fwcag\u002Fnew-in-22\u002F",{"title":646,"url":647},"MDN: prefers-reduced-motion","https:\u002F\u002Fdeveloper.mozilla.org\u002Fen-US\u002Fdocs\u002FWeb\u002FCSS\u002F@media\u002Fprefers-reduced-motion",{"title":649,"url":650},"DOMPurify README","https:\u002F\u002Fgithub.com\u002Fcure53\u002FDOMPurify",{"title":652,"url":653},"markdown-it README","https:\u002F\u002Fgithub.com\u002Fmarkdown-it\u002Fmarkdown-it",{"title":655,"url":656},"AI SDK docs: useChat","https:\u002F\u002Fai-sdk.dev\u002Fdocs\u002Fai-sdk-ui\u002Fchatbot",{"title":658,"url":659},"Vue docs: nextTick","https:\u002F\u002Fvuejs.org\u002Fapi\u002Fgeneral.html#nexttick","\u002Fimages\u002Fblog\u002Fvue-ai-chat-ui-streaming-accessibility\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fvue-ai-chat-ui-streaming-accessibility\u002Fog.jpg","vue-nuxt-developer",[71,72,73],"Streaming AI chat in Vue and Nuxt: accessible by design","How to build a Vue or Nuxt AI chat UI: fetch streams, abort and retry, safe markdown rendering, aria-live announcements, keyboard support and reduced motion.","A message card with a careful caret, a dotted line opening into ripples and a check.",{"slug":668,"published":465,"minutes":539,"category":7,"tags":669,"keywords":674,"about":686,"sources":696,"cover":729,"og":730,"expertise":662,"locales":731,"lang":71,"title":732,"description":733,"coverAlt":734},"llm-translation-pipeline-i18n",[670,671,672,597,673],"Translation","i18n","LLM","Localization",[675,676,677,678,679,680,681,682,683,684,685],"llm translation pipeline","icu messageformat placeholders","vue i18n llm translation","translation memory llm","glossary enforcement translation","german informal sie du","hungarian translation quality llm","structured output json translation","machine translation post-editing","locale file validation","cldr plural categories",[687,690,693],{"name":688,"url":689},"Internationalization and localization","https:\u002F\u002Fen.wikipedia.org\u002Fwiki\u002FInternationalization_and_localization",{"name":691,"url":692},"ICU MessageFormat","https:\u002F\u002Funicode-org.github.io\u002Ficu\u002Fuserguide\u002Fformat_parse\u002Fmessages\u002F",{"name":694,"url":695},"Vue I18n","https:\u002F\u002Fvue-i18n.intlify.dev\u002F",[697,699,702,705,708,711,714,717,720,723,726],{"title":698,"url":692},"Unicode ICU User Guide: Formatting Messages",{"title":700,"url":701},"Vue I18n: Message Format Syntax","https:\u002F\u002Fvue-i18n.intlify.dev\u002Fguide\u002Fessentials\u002Fsyntax",{"title":703,"url":704},"Nuxt i18n: Getting started","https:\u002F\u002Fi18n.nuxtjs.org\u002Fdocs\u002Fgetting-started",{"title":706,"url":707},"Unicode CLDR: Plural rules","https:\u002F\u002Fcldr.unicode.org\u002Findex\u002Fcldr-spec\u002Fplural-rules",{"title":709,"url":710},"OpenAI: Structured outputs","https:\u002F\u002Fplatform.openai.com\u002Fdocs\u002Fguides\u002Fstructured-outputs",{"title":712,"url":713},"DeepL API: Glossaries","https:\u002F\u002Fdevelopers.deepl.com\u002Fdocs\u002Fapi-reference\u002Fglossaries",{"title":715,"url":716},"W3C: Localization vs. internationalization","https:\u002F\u002Fwww.w3.org\u002FInternational\u002Fquestions\u002Fqa-i18n",{"title":718,"url":719},"GNU gettext manual","https:\u002F\u002Fwww.gnu.org\u002Fsoftware\u002Fgettext\u002Fmanual\u002Fgettext.html",{"title":721,"url":722},"RFC 5646: Tags for Identifying Languages","https:\u002F\u002Fwww.rfc-editor.org\u002Frfc\u002Frfc5646",{"title":724,"url":725},"Rat für deutsche Rechtschreibung","https:\u002F\u002Fwww.rechtschreibrat.com\u002F",{"title":727,"url":728},"Microsoft Writing Style Guide","https:\u002F\u002Flearn.microsoft.com\u002Fen-us\u002Fstyle-guide\u002Fwelcome\u002F","\u002Fimages\u002Fblog\u002Fllm-translation-pipeline-i18n\u002Fcover.webp","\u002Fimages\u002Fblog\u002Fllm-translation-pipeline-i18n\u002Fog.jpg",[71,72,73],"An LLM translation pipeline for i18n: glossary, placeholders and review","How to translate product and website strings with LLMs without breaking placeholders, plurals or tone: glossary, ICU messages, QA checks and review gates.","Three source cards, one translated card with a glossary ribbon, then a checked clipboard.",1792337027507]