Skip to main content

Punchout and EDI

Both flows hang off a trading partner record (Settings → Integrations, or POST /admin/trading-partners): a protocol (cxml, edi_x12 or edifact), a transport, the partner's identity, a shared secret, and the customer company the partner acts for. Buyers with a company admin role can also generate their own cXML credentials from the storefront under Settings → Procurement integration.

cXML punchout​

Punchout lets a buyer in Ariba, Coupa, SAP or a similar system open your storefront inside their procurement session, fill a cart, and return it as a requisition.

1. Setup​

The procurement system posts a PunchOutSetupRequest:

POST /punchout/setup
Content-Type: text/xml
  • The sender identity is read from Header/Sender/Credential/Identity and must match a trading partner; the SharedSecret in that credential must match the partner's secret (compared in constant time, and an empty stored secret never matches).
  • BrowserFormPost/URL is required — it is where the cart is returned.
  • BuyerCookie and the operation attribute are stored on the session.

The response is a PunchOutSetupResponse whose StartPage/URL is https://<api host>/punchout/start/{session}. Sessions expire after PUNCHOUT_TTL (default one hour).

2. Shopping​

The procurement system opens the start URL in the buyer's browser. Sokisoko creates or reuses a cart for the partner's customer, issues a storefront session bound to that customer, and redirects to the storefront in punchout mode — the buyer sees their contract pricing and catalog visibility exactly as a signed-in buyer would. Append ?format=json to the start URL to receive { "token", "cart_id", "cart_public_id", "session" } instead of a redirect if you drive the storefront yourself.

3. Transfer​

When the buyer checks out in punchout mode, the storefront calls:

POST /punchout/transfer/{session}

which returns an HTML form that auto-posts a PunchOutOrderMessage to the BrowserFormPost URL. Each cart line becomes an item with SupplierPartID (the SKU), description, unit of measure, quantity and unit price. The procurement system turns that into a purchase order, which typically comes back as an EDI 850 (below) or a cXML OrderRequest.

X12 EDI​

Inbound purchase orders (850)​

POST /edi/inbound/{partnerID}
X-EDI-Secret: <the partner's shared secret>
Content-Type: text/plain

ISA*00*…~GS*PO*…~ST*850*0001~BEG*00*SA*PO-2026-0142**20260905~…
  • Authentication is the partner's shared secret in X-EDI-Secret; a partner with no secret cannot ingest (fail closed). Inactive partners are refused.
  • Segments end with ~, elements are separated by *.
  • The raw document is stored first and deduplicated on the PO number — a second delivery of the same PO answers 409 duplicate.
  • Every line's part number must match a product SKU. If any line does not, nothing is created and the response is 422 unknown_sku naming the SKU — all or nothing.
  • On success an order is created for the partner's customer with the PO number, and the response body is an 855 acknowledgement.

Outbound documents​

Staff (or an integration with the right scopes) generate outbound documents from an order or invoice:

  • POST /admin/edi/856 — an ASN (ship notice) from a shipment
  • POST /admin/edi/810 — an invoice

Both are returned as X12 text and recorded. GET /admin/edi/documents lists every inbound and outbound document with its direction, type, control number and status; the console shows the same log under Settings → Integrations. Our sender id on outbound documents is EDI_SENDER_ID.