Punchout errors: what failed and what to check

A failing punchout test, sorted by what you see: the setup is refused, the catalog stays blank, the cart never arrives or arrives wrong, or the purchase order is rejected.

Published
Referenced documents
2

A failing punchout test breaks at one of five points: the setup request, the catalog opening, the cart transfer, the cart contents, or the purchase order. cXML answers setup requests and purchase orders with a status code that names the problem. OCI has no status document, so the HTTP status and the page the user sees carry it.

This page goes symptom by symptom. For each one it lists the likely causes, what to check, and the status codes involved, with the exact messages PunchRelay returns where that helps. For the documents themselves, see the cXML message reference and the OCI field reference.

Where do you look first?

Start with the response the buyer's system received, not with what the user saw. A cXML answer carries a Status element whose code and text say what happened, and whose content can describe the error in words. Ask the buyer's team for that status, then compare it with the supplier's own log of the same request.

The cXML User's Guide treats any HTTP reply without valid cXML content, such as a 404 or a 500 error page, as a transport error that the client should retry. So a proxy page or a wrong URL looks like a temporary outage to the buyer's system. If the buyer reports retries and nothing arrives in your log, check the URL they configured before anything else.

For OCI, the buyer's SAP team can switch on an application log for the catalog in SAP SRM and read it in transaction SLG1 with the object BBP_OCI, as SAP's OCI specification describes.

PunchRelay connects your Shopify B2B store to your buyers' procurement systems: contract prices go out in the punchout catalog, and purchase orders come back to your inbox for review.

Install on ShopifyWatch the 78-second demo

30-day free trial, billed through Shopify

Which cXML status codes will you see?

The cXML User's Guide splits codes by range: 2xx is success, 4xx is a permanent error the client should not retry, and 5xx is a transient error to retry later. A client that gets a code it does not know must treat it by its class. The table gives the guide's meaning and when PunchRelay answers with each code.

CodeMeaning in the cXML User's GuideWhen PunchRelay uses it
200 OKThe server executed the request or delivered it.Session opened, or purchase order accepted for review.
204 No ContentIn a PunchOutOrderMessage: the session ended without changing the cart.The user cancels an edit session.
400 Bad RequestRequest unacceptable to the server, although it parsed correctly.A required element is missing, the return URL is unusable, the operation or order type is unknown.
401 UnauthorizedThe credentials in the Sender element were not recognized.The From identity and shared secret match no enabled connection.
403 ForbiddenThe user has insufficient privileges for this request.Not used in cXML answers.
406 Not AcceptableRequest unacceptable, likely due to a parsing failure.Not used: a document that cannot be parsed is answered 400.
409 ConflictThe current state of the server prevented the operation.A purchase order number arrives again with different contents.
450 Not ImplementedThe server does not implement this request or operation.A purchase order update or delete.
500 Internal Server ErrorThe server was unable to complete the request.A temporary failure on PunchRelay's side.

PunchRelay also answers 405 when a setup request or purchase order arrives by anything other than HTTP POST, and 429 or 503 when it is rate limiting or busy. The guide's table does not define these three, so a buyer's system reads them by class: 405 and 429 as permanent, 503 as transient.

Why is the setup request rejected?

Check credentials and required elements first. A cXML 401 means the identity and shared secret the buyer sent match no connection; a 400 means the document lacks something the session needs, such as the BuyerCookie or the BrowserFormPost URL. In OCI, the same two failures come back as an error page with HTTP 401 or 400.

  • 401 with "Authentication failed: the From identity and Sender SharedSecret do not match an enabled connection". Compare the From identity character by character with the one on the connection, check the shared secret in the Sender element, and check that the connection is enabled.
  • 400 with "missing <BuyerCookie>" or "missing <BrowserFormPost><URL>". The buyer's setup template is incomplete.
  • 400 with "Invalid <BrowserFormPost><URL>". PunchRelay accepts only absolute https return URLs in production.
  • 400 with "missing <PunchOutSetupRequest>". The buyer sent another document, for example a purchase order, to the setup URL. The reverse, a setup request sent to the order URL, comes back as "missing <OrderRequest>".
  • 405. The request came by GET or another method; cXML setup requests are POSTed.
  • OCI 400 with "Missing HOOK_URL" or "Invalid HOOK_URL", or 401 with "Sign-in failed: USERNAME or PASSWORD is not valid". PunchRelay checks the return URL first, so a bad URL hides a bad password until the URL is fixed.

Why does the catalog not open?

The setup succeeded, but the browser lands on an error page or an empty catalog. With cXML, one cause is a start URL opened too late or twice. In either protocol, the catalog can also open with nothing to buy because the buyer's company location has no products published to it.

  • "This punchout start link has already been used" or "has expired". PunchRelay's start link works once and for 15 minutes. A test tool that replays an old start URL, or a browser that opens it twice, hits this page. Start a new session from the procurement system.
  • The catalog opens but shows nothing to order. In Shopify, publish a catalog with priced products to the company location the connection uses.
  • "Too many punchout requests came from your network" (HTTP 429). Too many calls came from one network address within a minute; wait a minute and start again.

Why does the cart not come back?

The cart travels as a form that the user's browser posts to the return address from the setup: the BrowserFormPost URL in cXML, the HOOK_URL in OCI. If nothing arrives, either the catalog refused to send it, or the browser posted it somewhere the buyer's system does not read.

  • The catalog refused. PunchRelay shows the user why before it posts anything: an empty cart, lines that can no longer be ordered, or contract prices or quantity rules that changed since the line was added. The user fixes the cart and transfers again.
  • The post went to the wrong place. Check in your log which URL the transfer was sent to, and compare it with the address the buyer expects.
  • OCI frames. SAP sends returntarget so the form posts into the right window or frame, and the specification warns that renaming SAP's window breaks the link back to the SAP application.

In OCI the buyer's system sends no answer to the catalog after the post. The supplier's log can show that the cart left; only the buyer's shopping cart, or the SRM application log, shows whether it arrived.

Why is the cart empty or wrong?

An empty cart in cXML points first to the form field. The guide allows two field names, cxml-urlencoded and cxml-base64, and a buyer's system that reads the other one can show an empty requisition instead of an error. Wrong units and prices come from data, not transport.

  • Empty cart. Ask the buyer which field their system reads and switch the connection's cart transfer field to match. A cXML status 204 is different: it means the user left an edit session without changes.
  • Units refused or wrong. cXML units must be UN/CEFACT codes; OCI units must be ISO codes maintained in the buyer's SAP system. PunchRelay sends EA when a product has no unit set. For Coupa, PunchRelay's setup guidance is to send your unit list before the first test, because Coupa can refuse to import a cart with a unit it does not know (see the Coupa steps on our procurement systems page).
  • Wrong prices. The catalog shows the contract prices of the company location the connection is bound to, and list prices when that location has no catalog. Check the location first, then the currency.
  • OCI text cut short or garbled. DESCRIPTION holds 40 characters, so PunchRelay sends the full text in LONGTEXT. Umlauts that arrive broken point to a character set mismatch: SAP names its set in http_content_charset, and the catalog must build the page in it.

Why is the purchase order rejected?

A cXML purchase order gets its own status. A 401 means the credentials in the order match no connection; the order carries its own Sender shared secret, so this can happen even when punchout works. A 400 points to a missing element, 450 to an update or delete, and 409 to a reused order number with different contents.

  • 401. Check the identity and shared secret in the buyer's purchase order configuration, not only in the punchout settings.
  • 400 with "missing <Money> under <Total>". PunchRelay needs the order total.
  • 450 with "This release does not support purchase order updates or deletions". Agree with the buyer how changes reach you.
  • 409. The same order number came with different contents. Sending an identical order again is answered 200 and creates no second order.
  • 5xx. The guide recommends retrying transient errors, up to 10 times an hour apart.

A 200 from PunchRelay means the order was accepted for review: it waits in the merchant's purchase orders inbox, and a Shopify order exists only after the merchant approves it. OCI has no purchase order at all; see why OCI returns only a cart.

Debugging with PunchRelay

PunchRelay keeps the evidence for each step. The self-test on a connection runs the round trip for cXML or OCI and says which step failed and what to change. The Activity page lists every document of a session with its direction, HTTP status and note, and keeps documents for 90 days.

The "Recent errors and support codes" card on the app's home page lists failures from the last 30 days with a support code. A request with a known identity but a wrong secret or password shows up there. A request with an identity no connection has is filed under no shop, so if the buyer sees a 401 and you see nothing, the identity or username is the first thing to compare.

What you check: credentials, the company location and its catalog, units and the cart transfer field. What the buyer checks: the URLs and credentials in their system, their own log of our answers, and for SAP the SRM application log. The setup guide covers the connection itself, the cXML punchout guide the protocol, and the procurement systems page the steps per buyer system.

Referenced documents

Ref.DocumentNotes
[1]cXML User's Guide 1.2.037 (cxml.org)The status code table and ranges, retry advice, handling of unknown codes, the cxml-urlencoded and cxml-base64 form fields, 204 for an unchanged cart, UN/CEFACT units.
[2]SAP, Open Catalog Interface (OCI) Release 5.0HOOK_URL and the return form, http_content_charset and returntarget, ISO unit and currency codes, price format, the 40-character description, the SRM application log (SLG1, BBP_OCI).

Install PunchRelay from the Shopify App Store

Start the 30-day free trial from the listing. Pricing is $349/month with two punchout connections included, billed through Shopify.

Talk to us about your buyer's system

Questions about your buyer's procurement system, or want help with setup? Leave your email and we will reply personally.

Install the app if you know which procurement system your buyer uses. If you don't know yet, talk to us first.

No spam. We reply personally.