How to Test cXML PunchOut with Postman
Most cXML PunchOut implementations fail not because of bad code, but because they were never properly tested before connecting to a live buyer's procurement system. This guide shows you how to debug 90% of integration issues with just Postman — before your buyer's IT team even gets involved.
Why Test with Postman First
When a buyer's procurement system sends a real cXML PunchOutSetupRequest to your store, you have one shot to respond correctly. If your endpoint returns an error, a misformatted XML, or simply hangs, the buyer's IT team will mark your integration as broken and move on.
Postman lets you simulate that exact request — using the same XML structure, headers, and authentication — without involving the buyer at all. You can run dozens of test cycles in an afternoon and catch every issue before it becomes a production problem.
What You Need Before Starting
- Postman installed — free desktop app from postman.com
- Your PunchOut endpoint URL — e.g.,
https://yourstore.com/module/punchouthub/punchout - A SharedSecret — agreed upon with the buyer (or generated for testing)
- Sample cXML SetupRequest — provided below
Step 1 — Create a New Request in Postman
Open Postman and create a new request:
- Method:
POST - URL: Your PunchOut endpoint URL
- Headers:
Content-Type: application/xmlAccept: application/xml
Step 2 — Build the SetupRequest XML
Copy this template into the Postman Body (raw, XML format):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE cXML SYSTEM "http://xml.cxml.org/schemas/cXML/1.2.014/cXML.dtd">
<cXML payloadID="test-001@example.com"
timestamp="2026-06-22T10:00:00+07:00">
<Header>
<From>
<Credential domain="NetworkID">
<Identity>BUYER_ID_HERE</Identity>
</Credential>
</From>
<To>
<Credential domain="NetworkID">
<Identity>SUPPLIER_ID_HERE</Identity>
</Credential>
</To>
<Sender>
<Credential domain="NetworkID">
<Identity>BUYER_ID_HERE</Identity>
<SharedSecret>YOUR_SHARED_SECRET</SharedSecret>
</Credential>
<UserAgent>Postman Test Client</UserAgent>
</Sender>
</Header>
<Request>
<PunchOutSetupRequest operation="create">
<BuyerCookie>test_cookie_001</BuyerCookie>
<Extrinsic name="UserEmail">test@buyer.com</Extrinsic>
<Extrinsic name="User">testuser</Extrinsic>
<BrowserFormPost>
<URL>https://httpbin.org/post</URL>
</BrowserFormPost>
<SupplierSetup>
<URL>https://yourstore.com/</URL>
</SupplierSetup>
</PunchOutSetupRequest>
</Request>
</cXML>
Replace these placeholders with your real values:
BUYER_ID_HERE— your test buyer identifierSUPPLIER_ID_HERE— your supplier identifierYOUR_SHARED_SECRET— the SharedSecret configured in your store
Note the BrowserFormPost URL is set to httpbin.org/post — this is a free service that echoes back whatever you POST to it. Perfect for capturing the return cart later.
Step 3 — Send and Inspect the Response
Click Send. A correctly configured PunchOut endpoint should return:
- Status:
200 OK - Content-Type:
text/xmlorapplication/xml - Body: A valid PunchOutSetupResponse XML with a StartPage URL
Expected response:
<?xml version="1.0" encoding="UTF-8"?>
<cXML payloadID="response-001@yourstore.com"
timestamp="2026-06-22T10:00:01+07:00">
<Response>
<Status code="200" text="OK"/>
<PunchOutSetupResponse>
<StartPage>
<URL>https://yourstore.com/punchout/session/abc123xyz</URL>
</StartPage>
</PunchOutSetupResponse>
</Response>
</cXML>
Step 4 — Test the StartPage URL
Copy the StartPage URL from the response and open it in your browser. You should land directly in your store catalog — logged in as the test buyer, with their negotiated pricing applied.
If you see the homepage instead of the catalog, the session was not properly initialized. Check your store's session handling logic.
Step 5 — Test the Return Cart
Once in the session:
- Browse the catalog
- Add 2-3 items to cart
- Click Checkout or Return to Procurement
The cart should be POSTed to httpbin.org/post (the URL you set in BrowserFormPost). Open the httpbin response and verify:
- The form contains a
cxml-urlencodedorcxml-base64field - The cXML inside contains a valid
PunchOutOrderMessage - The
BuyerCookiematches what you sent (test_cookie_001) - Item quantities, prices, and SKUs are correct
Common Errors and Fixes
| Error | Cause | Fix |
|---|---|---|
| HTTP 401 / Authentication Failed | SharedSecret mismatch | Verify exact character match — check for trailing whitespace, case sensitivity |
| HTTP 500 / Internal Server Error | PHP error parsing cXML | Enable PHP error logging — look for malformed XML, missing namespace, or DTD issues |
| HTTP 400 / Bad Request | Invalid cXML format | Validate XML structure with an online cXML validator before sending |
| Empty response body | Endpoint not returning XML | Check Content-Type header is text/xml or application/xml |
| StartPage URL returns 404 | Session table not created or session expired | Check session storage in database; verify session timeout is more than 30 minutes |
| StartPage opens homepage | Session ID not passed correctly | Verify session ID is in URL path or query string |
| Cart returns to wrong URL | BrowserFormPost URL not saved with session | Check that the return URL is persisted in the session table |
| BuyerCookie missing in response | Cookie not echoed from request | Echo the exact BuyerCookie string into the PunchOutOrderMessage |
Advanced Testing Scenarios
Scenario 1 — Test Multiple Buyers
Create separate Postman requests with different BUYER_ID + SharedSecret combinations. Verify each buyer sees their own pricing and product catalog.
Scenario 2 — Test Session Expiry
Send a SetupRequest, wait 31 minutes, then try to use the StartPage URL. Most procurement systems expect sessions to expire gracefully after 30 minutes.
Scenario 3 — Test Concurrent Sessions
Send 5 SetupRequests in quick succession (different BuyerCookies). Open all 5 StartPage URLs in different browser tabs. Each session should be isolated — adding items in one cart should not affect another.
Scenario 4 — Test the Edit Flow
Some procurement systems send operation="edit" instead of operation="create". This means the buyer is editing an existing requisition. Your store should restore the previous cart and let them modify it.
What Postman Can't Test
Postman handles 90% of testing — but a few scenarios require integration with the actual buyer's system:
- IP whitelist enforcement — if your endpoint restricts source IPs
- Buyer's network firewall rules — sometimes corporate firewalls block external POSTs
- Real procurement workflow — approval routing happens inside the buyer's ERP
- Inbound PO receiver — testing how your store receives the eventual purchase order
For these scenarios, you need either the buyer's sandbox environment or a coordinated test with their IT team.
Saving Your Postman Collection
Once you've built a working test collection, save it. Export the JSON file. This becomes your regression test suite — anytime you update your store, your module, or your server configuration, replay the entire collection to verify nothing broke.
A solid Postman collection for cXML PunchOut should include:
- Valid SetupRequest (happy path)
- Invalid SharedSecret (should return 401)
- Missing required fields (should return 400)
- Edit operation (should restore session)
- Expired session test
- Multiple buyer test (different credentials)
How PunchOutHub Helps
If you're using PunchOutHub, the admin dashboard shows every cXML request in real time — full XML payload, HTTP status, response time, and error details. You can replay requests, compare expected vs actual output, and export logs for buyer review.
This makes Postman testing about 5x faster, because you can see exactly what your endpoint is doing on every request — no need to dig through server logs or enable verbose PHP debugging.
Try cXML in the live demo
Skip the setup. Send a real PunchOutSetupRequest to a live PunchOutHub instance and see how the responses should look.
Open Demo →